diff --git a/.gitignore b/.gitignore index 34d56ed..6801c4b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ **/**.png .venv/ auth/*.secret -config/*.json \ No newline at end of file +config/*.json +download/ \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/fedi-board-bot.iml b/.idea/fedi-board-bot.iml new file mode 100644 index 0000000..ed0a51c --- /dev/null +++ b/.idea/fedi-board-bot.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..608a9ae --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,21 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..2808b4c --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..85f6605 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 19978c2..17ae5ef 100644 --- a/README.md +++ b/README.md @@ -27,5 +27,3 @@ Run the bot by running ```sh python3 bot.py ``` - -Use the environment variables `BOARD_API_KEY` and `BOARD_USERNAME` to login with danbooru. diff --git a/bot.py b/bot.py index b325e5c..0a102ce 100644 --- a/bot.py +++ b/bot.py @@ -1,6 +1,6 @@ -from dataclasses import dataclass +import base64 +import os.path from mastodon import Mastodon -from os import environ from sys import argv import json @@ -8,13 +8,16 @@ import pathlib import random import requests + class Config: + auth: str block_tags: list[str] + danbooru_api_key: str + danbooru_username: str nsfw_tags: list[str] search_tags: list[str] text_cw: str text_filler: list[str] - type: str url: str def __init__(self, config_name: str): @@ -22,18 +25,23 @@ class Config: config = json.load(file) self.block_tags = config["blockTags"] + self.danbooru_api_key = config["danbooruApiKey"] + self.danbooru_username = config["danbooruUsername"] self.nsfw_tags = config["nsfwTags"] self.search_tags = config["searchTags"] self.text_cw = config["textCW"] self.text_filler = config["textFiller"] - self.type = config["type"] self.url = config["url"] -def random_image_danbooru(block_tags: list[str], search_tags: list[str], url: str) -> dict | None: + self.auth = "Basic " + base64.b64encode( + bytes(self.danbooru_username + ":" + self.danbooru_api_key, "utf-8")).decode("utf-8") + + +def random_image(config: Config) -> dict | None: tags = [] - for tag in block_tags: + for tag in config.block_tags: tags.append("-" + tag.strip()) - for tag in search_tags: + for tag in config.search_tags: tags.append(tag.strip()) tags = " ".join(tags) @@ -41,49 +49,17 @@ def random_image_danbooru(block_tags: list[str], search_tags: list[str], url: st "random": "1", "tags": tags } - if environ.get("BOARD_API_KEY") and environ.get("BOARD_USERNAME"): - params["api_key"] = environ.get("BOARD_API_KEY") - params["login"] = environ.get("BOARD_USERNAME") - resp = requests.get(url + "/posts.json", params=params) - if resp.ok == False: + resp = requests.get(config.url + "/posts.json", params=params, headers={"Authorization": config.auth}) + + if not resp.ok: print(resp.json()) return None - elif resp.json() == []: + elif not resp.json(): return None return random.choice(resp.json()) -def random_image_gelbooru(block_tags: list[str], search_tags: list[str]) -> dict | None: - tags = ["sort:random"] - for tag in block_tags: - tags.append("-" + tag.strip()) - for tag in search_tags: - tags.append(tag.strip()) - tags = " ".join(tags) - - params = { - "page": "dapi", - "s": "post", - "q": "index", - "pid": 0, - "json": "1", - "limit": "1", - "tags": tags - } - resp = requests.get("https://gelbooru.com/index.php", params=params) - - if resp.ok == False: - print(resp.json()) - return None - - post = resp.json() - - if len(post["post"]) > 0: - return random.choice(resp.json()["post"]) - - return None - # Exit if config isn't specified if len(argv) < 2: @@ -92,87 +68,69 @@ if len(argv) < 2: config = Config(argv[1]) -match config.type: - case "danbooru": - post = random_image_danbooru(config.block_tags, config.search_tags, config.url) - case "gelbooru": - post = random_image_gelbooru(config.block_tags, config.search_tags) - case _: - print("'type' in config must be 'danbooru' or 'gelbooru'") - exit() +# Check auth +auth = requests.get(config.url + "/profile.json", headers={"Authorization": config.auth}) -if post == None: +print(auth.status_code) +print(auth.json()) +if not auth.ok or auth.json()["id"] is None: + print("Authentication failed") + exit() + +post = random_image(config) + +if post is None: print("Couldn't get an image") exit() -match config.type: - case "danbooru": - characters = post.get("tag_string_character") or "" - filename = f'image.{post["file_ext"]}' - post_url = config.url + "/posts/" + str(post["id"]) - case "gelbooru": - characters = "" - filename = post["image"] - post_url = "https://gelbooru.com/index.php?page=post&s=view&id=" + str(post["id"]) - case _: - characters = "" - filename = "img.png" - post_url = "" +filename = f'download/image.{post["file_ext"]}' +post_url = config.url + "/posts/" + str(post["id"]) print(post) image = requests.get(post["file_url"]) -if image.ok == False: +if not image.ok: print("Couldn't download image") exit() +if not os.path.isdir("download"): + if not os.path.exists("download"): + os.makedirs("download") + else: + print("\"download\" exists but isn't a directory") + exit() + with open(filename, "wb") as f: f.write(image.content) # Image is NSFW if rated Explicit, Sensitive or Unknown is_nsfw = not post["rating"].startswith("g") or post["rating"] == None -if is_nsfw == False: +if not is_nsfw: for tag in config.nsfw_tags: # Check if any config defined NSFW tags are present - match config.type: - case "danbooru": - if tag in post["tag_string"].split(): - print(tag) - is_nsfw = True - break - case "gelbooru": - if tag in post["tags"].split(): - print(tag) - is_nsfw = True - break - case _: - is_nsfw = True - break + if tag in post["tag_string"].split(): + is_nsfw = True # This sucks but it works :3 post_content = [ random.choice(config.text_filler), "\n\n", - "Artist: " + post["tag_string_artist"] + "\n" if config.type == "danbooru" and len(post["tag_string_artist"]) > 0 else "", - "Characters: " + characters + "\n" if characters != "" else "", + "Artist: " + post["tag_string_artist"] + "\n" if len(post["tag_string_artist"]) > 0 else "", + "Characters: " + post["tag_string_character"] + "\n" if len( + post["tag_string_character"]) > 0 else "", "Source: " + post["source"] if len(post["source"]) > 0 else "", "\n\n" + post_url if post_url != "" else "" ] +print("".join(post_content)) + +exit() + mastodon = Mastodon(access_token=f"auth/{argv[1]}.auth.secret") -match config.type: - case "danbooru": - tags = post["tag_string"] - case "gelbooru": - tags = post["tags"] - case _: - tags = "unknown" - media = mastodon.media_post( - description="Automatically posted image. Tagged: " + tags, media_file=filename ) diff --git a/config/example.json.example b/config/example.json.example index 8ead393..f689f16 100644 --- a/config/example.json.example +++ b/config/example.json.example @@ -2,6 +2,8 @@ "blockTags": [ "List of tags that should be ignored by the bot." ], + "danbooruApiKey": "", + "danbooruUsername": "", "nsfwTags": [ "If these tags are present the post will be marked as sensitive" ], @@ -12,6 +14,5 @@ "textFiller": [ "Flavor text for posts" ], - "type": "danbooru or gelbooru", - "url": "https://" + "url": "https://safebooru.donmai.us" } \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index b033626..2cf6a63 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ -Mastodon.py \ No newline at end of file +Mastodon.py +requests \ No newline at end of file