181 lines
4.8 KiB
Python
181 lines
4.8 KiB
Python
from dataclasses import dataclass
|
|
from mastodon import Mastodon
|
|
from os import environ
|
|
from sys import argv
|
|
|
|
import json
|
|
import pathlib
|
|
import random
|
|
import requests
|
|
|
|
class Config:
|
|
block_tags: list[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):
|
|
with open(f"config/{config_name}.json") as file:
|
|
config = json.load(file)
|
|
|
|
self.block_tags = config["blockTags"]
|
|
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:
|
|
tags = []
|
|
for tag in block_tags:
|
|
tags.append("-" + tag.strip())
|
|
for tag in search_tags:
|
|
tags.append(tag.strip())
|
|
tags = " ".join(tags)
|
|
|
|
params = {
|
|
"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:
|
|
print(resp.json())
|
|
return None
|
|
elif 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:
|
|
print(f"Usage: python3 {argv[0]} <config-name>")
|
|
exit()
|
|
|
|
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()
|
|
|
|
if post == None:
|
|
print("Couldn't get an image")
|
|
exit()
|
|
|
|
match config.type:
|
|
case "danbooru":
|
|
filename = f'{post["md5"]}.{post["file_ext"]}'
|
|
case "gelbooru":
|
|
filename = post["image"]
|
|
case _:
|
|
filename = "img.png"
|
|
|
|
print(post)
|
|
|
|
image = requests.get(post["file_url"])
|
|
|
|
if image.ok == False:
|
|
print("Couldn't download image")
|
|
exit()
|
|
|
|
with open(filename, "wb") as f:
|
|
f.write(image.content)
|
|
|
|
# Image is NSFW if rated Explicit, Sensitive or Unknown
|
|
is_nsfw = post["rating"].startswith("e") or post["rating"].startswith("s") or post["rating"] == None
|
|
|
|
if is_nsfw == False:
|
|
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"] or tag in post["tag_string_general"] or tag in post["tag_string_artist"] or tag in post["tag_string_copyright"] or tag in post["tag_string_character"] or tag in post["tag_string_meta"]:
|
|
is_nsfw = True
|
|
break
|
|
case "gelbooru":
|
|
if tag in post["tags"]:
|
|
is_nsfw = True
|
|
break
|
|
case _:
|
|
is_nsfw = True
|
|
break
|
|
|
|
# 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 "",
|
|
"Score: " + str(post["score"]) + "\n",
|
|
"Source: " + post["source"] + "\n\n" if len(post["source"]) > 0 else "\n",
|
|
]
|
|
|
|
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"
|
|
print(post_content, tags)
|
|
|
|
exit()
|
|
media = mastodon.media_post(
|
|
description="Automatically posted image. Tagged: " + tags,
|
|
media_file=filename
|
|
)
|
|
|
|
status = mastodon.status_post(
|
|
"".join(post_content),
|
|
media_ids=[media["id"]],
|
|
sensitive=is_nsfw,
|
|
spoiler_text="(NSFW) " + config.text_cw if is_nsfw else config.text_cw,
|
|
visibility="unlisted"
|
|
)
|
|
print(status["url"])
|
|
|
|
pathlib.Path(filename).unlink()
|