commit 2cf9b0456d347dfdb355916af89dd532862bbce1 Author: NaiJi Date: Thu Mar 24 04:51:03 2022 +0300 Init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4b8a393 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/token.dat +/venv +/urls +/sources +/arts \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..fdddb29 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/README.md b/README.md new file mode 100644 index 0000000..3b83e6d --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +# udonge-bot + +Another bot for posting arts to your timeline. + +Currently posting on: https://social.inex.rocks/@ReisenBot + +### Initial setup + +We support you to create a virtualenv to not pollute your system with modules: + +```shell +python3 -m venv venv +source venv/bin/activate +pip install -r requirements.txt +``` + +Once it's done, you have to create a file `token.dat` in put in the account authorization's key. (no instruction given, it changes between your fediverse software). + +Edit the `api_base_url` variable in `post-local.py` and `post-danbooru.py` sources. It must contain the url of the instance your bot is going to post on. + +#### `post-local.py` + +Allows you to post random arts from your local `/source` folder. + +* Create `source` folder in the same location with the `post-local.py` script. +* If you want to download a huge chunk of arts to your folder first, in `download.py` edit global variable `TAGS`, write in there 2 tags you need. Now run +```bash +python3 download.py +``` +* In `post-local.py` edit `toot` variable, write in there a string you want the bot to write with any post. Hastags, for example. +* To make a single post, now run +```bash +python3 post-local.py +``` + +#### `post-danbooru.py` + +Allows you to repost random arts from danbooru.donmai.us + +* Edit `tags.dat` file. You can look at already defined tags and use it as example + +``` +#first line is for tags you want to search the arts with (must be exactly 2) +#second line is for tags you decline from posting completely (as many as you want) +#third line is for tags you want mastodon to mark as sensitive (as many as you want) +``` +* To make a single post, now run +```bash +python3 post-danbooru.py +``` diff --git a/download.py b/download.py new file mode 100644 index 0000000..ba4d236 --- /dev/null +++ b/download.py @@ -0,0 +1,60 @@ +import requests +import sys + +import os.path as op + +TAGS = '1girl reisen_udongein_inaba' + +def main(): + + PAGE = 0 + rejected_once = False + + while True: + + URL = "https://danbooru.donmai.us/posts.json" + PARAMS = { 'tags': TAGS, + 'page': PAGE } + + r = requests.get(url = URL, params = PARAMS) + data = r.json() + + # If didn't receive a single entity, we should try again. + # If failed another time, shutdown! + if data.count == 0: + if rejected_once == True: + return + rejected_once = True + continue + rejected_once = False + + for entity in data: + if entity['rating'] != 's': + continue + + file_tags = entity['tag_string'] + + # we don't want comics + if 'comic' in file_tags: + continue + + try: + file_url = entity['file_url'] + except: + continue + + # write the art + img_data = requests.get(file_url).content + with open('source/' + file_url[file_url.rfind("/")+1:], 'wb') as handler: + handler.write(img_data) + + # save its url separately into a file + with open('urls', 'a', encoding='utf-8') as file: + print(file_url, file=file) + + PAGE += 1 + + # end while True + +if __name__ == '__main__': + sys.exit(main()) diff --git a/post-danbooru.py b/post-danbooru.py new file mode 100644 index 0000000..0e89f98 --- /dev/null +++ b/post-danbooru.py @@ -0,0 +1,82 @@ +import requests +import sys + +import os.path as op +from mastodon import Mastodon + +# -------------------------------------------------- + +def main(): + + mastodon = Mastodon( + access_token = 'token.dat', + api_base_url = 'https://udongein.xyz/' + ) + + with open('tags.dat', 'r') as dat: + tags = dat.readlines() + + URL = "https://danbooru.donmai.us/posts.json" + LIMIT = 10 + MIN_SCORE = 25 + SAFETY = 's' + TAGS_POST = tags[0].strip() + TAGS_FORBID = tags[1].strip().split() + TAGS_SENSITIVE = tags[2].strip().split() + + PARAMS = { 'tags': TAGS_POST, + 'limit': LIMIT, + 'random': True } + + print('[start] Settings:') + print('LIMIT = ' + str(LIMIT) + ' | MIN_SCORE = ' + str(MIN_SCORE) + ' | SAFETY = ' + SAFETY) + print('TAGS_POST=' + str(TAGS_POST)) + print('TAGS_FORBID=' + str(TAGS_FORBID)) + print('TAGS_SENSITIVE=' + str(TAGS_SENSITIVE) + '\n') + +# -------------------------------------------------- + + counter = 1 + b_search = True + while b_search: + r = requests.get(url = URL, params = PARAMS) + print('[get] Attempt N' + str(counter) + '.') + data = r.json() + for i in range(0, LIMIT): + fileurl = data[i]['file_url'] + print('url ', fileurl) + fileid = data[i]['id'] + print('id ', fileid) + filescore = data[i]['fav_count'] + print('score ', filescore) + filesafe = data[i]['rating'] + print('rating ', filesafe) + filetagstring = data[i]['tag_string'] + print('tags ', filetagstring) + pulledtags = filetagstring.split() + + if (filesafe == SAFETY and filescore >= MIN_SCORE + and not set(pulledtags).intersection(TAGS_FORBID)): + print('[success] Found!') + b_search = False + break + +# -------------------------------------------------- + + fformat = op.splitext(fileurl)[1][1:] + if (fformat == 'jpg'): + fformat = 'jpeg' + + media = mastodon.media_post(requests.get(fileurl).content, f'image/{fformat}') + toot = f'This is just a test post nevermind thisjksajskkj.... https://danbooru.donmai.us/posts/{fileid}' + + b_sensetive = bool(set(pulledtags).intersection(TAGS_SENSITIVE)) + + if (b_sensetive): + print('[success] Marked as sensitive.') + + mastodon.status_post(toot, media_ids=[media], visibility='unlisted', sensitive=b_sensetive) + print('[success] Posted!\n----------------------------------\n') + +if __name__ == '__main__': + sys.exit(main()) diff --git a/post-local.py b/post-local.py new file mode 100755 index 0000000..c190710 --- /dev/null +++ b/post-local.py @@ -0,0 +1,53 @@ +#!/home/naiji/mastodon/udonge-bot/venv/bin/python +import requests +import sys +import random +import os +import os.path as op + +from mastodon import Mastodon +from datetime import datetime + +# -------------------------------------------------- + +DIR_SFW = 'sfw/' +DIR_NSFW = 'nsfw/' + +def main(): + + mastodon = Mastodon( + access_token = 'token.dat', + api_base_url = 'https://udongein.xyz/' + ) + + sfwcount = len([name for name in os.listdir(DIR_SFW) if os.path.isfile(os.path.join(DIR_SFW, name))]) + nsfwcount = len([name for name in os.listdir(DIR_NSFW) if os.path.isfile(os.path.join(DIR_NSFW, name))]) + + random_choice = random.randint(1, sfwcount + nsfwcount) + print('\ns:' + str(sfwcount) + ' n:' + str(nsfwcount) + ' r:' + str(random_choice)) + + is_safe = False if random_choice < nsfwcount else True + art = "" + + if is_safe: + files = [f for f in os.listdir(DIR_SFW) if op.isfile(op.join(DIR_SFW, f))] + art = DIR_SFW + random.choice(files) + else: + files = [f for f in os.listdir(DIR_NSFW) if op.isfile(op.join(DIR_NSFW, f))] + art = DIR_NSFW + random.choice(files) + + fformat = op.splitext(art)[1][1:] + if (fformat == 'jpg'): + fformat = 'jpeg' + + with open(art, 'rb') as picture: + data = picture.read() + + media = mastodon.media_post(data, f'image/{fformat}') + toot = f':gyate_reisen_love:' + + mastodon.status_post(toot, media_ids=[media], visibility='unlisted', sensitive=not is_safe) + print(str(datetime.now()) + ': ' + art) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..383d5ff --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +mastodon.py \ No newline at end of file diff --git a/runner b/runner new file mode 100644 index 0000000..eb55319 --- /dev/null +++ b/runner @@ -0,0 +1,2 @@ +#!/home/naiji/mastodon/udonge-bot/venv/bin/python +python3 post-local.py diff --git a/tags.dat b/tags.dat new file mode 100644 index 0000000..2228bce --- /dev/null +++ b/tags.dat @@ -0,0 +1,3 @@ +reisen_udongein_inaba 1girl +blood nazi unhappy comic +swimsuit ass large_breasts underwear \ No newline at end of file