From 98bc58c5d93c16a8cd71b9622dde9a88f84b7d8b Mon Sep 17 00:00:00 2001 From: jwansek Date: Tue, 25 Aug 2020 18:06:19 +0100 Subject: added tweeting, pretty much done --- .gitignore | 5 ++++ bot.py | 62 ++++++++-------------------------------------- exampleconfig.json | 13 ++++++++++ get_images.py | 73 +++++++++++++++++++++++++++++++++++++++++++++++------- requirements.txt | 9 +++---- utils.py | 7 +++--- 6 files changed, 99 insertions(+), 70 deletions(-) create mode 100644 exampleconfig.json diff --git a/.gitignore b/.gitignore index 744f495..460b6bd 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,8 @@ pics/*[.png,.jpg,.jpeg] __pycache__/ api.py .ipynb_checkpoints/ +posted_images.csv +*.png +*.jpg +*.log +config.json \ No newline at end of file diff --git a/bot.py b/bot.py index ff27cda..0935879 100644 --- a/bot.py +++ b/bot.py @@ -1,58 +1,16 @@ -from utils import ( - draw_with_border, - get_colors, - get_quote, - messages_multiline, - randomize_location, - set_font, -) -from PIL import Image, ImageDraw from twython import Twython -import csv -import random -import os -from api import consumer_key, consumer_secret, access_token, access_token_secret -from datetime import datetime - -twitter = Twython(consumer_key, consumer_secret, access_token, access_token_secret) +import get_images +twitter = Twython(*get_images.CONFIG["twitterapi"].values()) def post(): - with open("files.csv") as f: - reader = csv.reader(f) - chosen_row = random.choice(list(reader)) - source = chosen_row[1] - file_extension = chosen_row[2].split(".")[1] - filename = "pics/" + chosen_row[2] - - text = get_quote("texts/quotes.txt") - image = Image.open(filename) - font = set_font(image, text) # get font size based on image size - draw = ImageDraw.Draw(image) - lines = messages_multiline(text, font, image) # split up lines for text wrapping - colors = get_colors(image.filename) # get colors - - (x, y, faces) = randomize_location( - image, lines, font - ) # where to start drawing text - - for line in lines: - height = font.getsize(line[1])[1] - draw_with_border(x, y, line, colors[0], colors[1], font, draw) - y = y + height - - image.save(f"to_tweet.{file_extension}") - photo = open(f"to_tweet.{file_extension}", "rb") - response = twitter.upload_media(media=photo) - message = f"{text} ({source})" - print(filename, message) - twitter.update_status(status=message, media_ids=[response["media_id"]]) - photo.close() - os.remove(photo.name) - with open("log", "a") as f: - f.write( - f"{datetime.now().strftime('%d-%m-%Y %H:%M:%S')}\t{filename}\t({image.size[0]} {image.size[1]})\t{font.size} ({max((font.size // 25), 2)})\t{text}\n" - ) + impath, source, text = get_images.main() + with open(impath, "rb") as img: + response = twitter.upload_media(media = img) + message = f"{text} ({source})" + out = twitter.update_status(status=message, media_ids=[response["media_id"]]) + get_images.logging.info("Posted to twitter.") -post() +if __name__ == "__main__": + post() diff --git a/exampleconfig.json b/exampleconfig.json new file mode 100644 index 0000000..31418ce --- /dev/null +++ b/exampleconfig.json @@ -0,0 +1,13 @@ +{ + "logpath": "yc.log", + "blacklist": "posted_images.csv", + "texts": "texts/quotes.txt", + "base_tags": ["yaoi", "-muscle", "-comic", "-text"], + "search_tags": ["looking_at_another", "kiss", "trap", "2boys", "promare"], + "twitterapi":{ + "consumer_key": "xxxxxxxxxxxxxxxxxxx", + "consumer_secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "access_token": "xxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxx", + "access_token_secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + } +} \ No newline at end of file diff --git a/get_images.py b/get_images.py index b4fef24..37becdd 100644 --- a/get_images.py +++ b/get_images.py @@ -1,17 +1,32 @@ from dataclasses import dataclass +from PIL import Image, ImageDraw from io import StringIO from lxml import etree import requests +import logging import urllib import random +import utils import time +import json import cv2 import os +with open("config.json", "r") as f: + CONFIG = json.load(f) + +logging.basicConfig( + format = "%(levelname)s\t[%(asctime)s]\t%(message)s", + level = logging.INFO, + handlers=[ + logging.FileHandler(CONFIG["logpath"]), + logging.StreamHandler() + ]) + # all of these tags are added to all queries. Preceded with '-' to blacklist -base_tags = ["yaoi", "-muscle", "-comic"] +base_tags = CONFIG["base_tags"] # one of these will be added -search_tags = ["looking_at_another", "kiss", "trap", "2boys", "promare"] +search_tags = CONFIG["search_tags"] def get_random_searchtag(): return [random.choice(search_tags)] @@ -30,7 +45,10 @@ def get_image(tags): search_url = "https://safebooru.org/index.php?page=post&s=list&tags=%s&pid=%i" % ("+".join(base_tags+tags), (random.randint(1, get_num_pages(tags))-1)*5*8) tree = etree.parse(StringIO(requests.get(search_url).text), etree.HTMLParser()) elements = [e for e in tree.xpath("/html/body/div[6]/div/div[2]/div[1]")[0].iter(tag = "a")] - element = random.choice(elements) + try: + element = random.choice(elements) + except IndexError: + raise ConnectionError("Couldn't find any images") simg = SafebooruImage( id = get_id_from_url(element.get("href")), tags = element.find("img").get("alt").split(), @@ -67,6 +85,16 @@ def get_num_pages(tags): else: return int(int(urllib.parse.parse_qs(page_element.get("href"))["pid"][0]) / (5*8)) +def append_blacklisted(id_): + with open(CONFIG["blacklist"], "a") as f: + f.write(str(id_) + "\n") + +def id_is_blacklisted(id_): + if not os.path.exists(CONFIG["blacklist"]): + return False + with open(CONFIG["blacklist"], "r") as f: + return str(id_) in f.read().splitlines() + @dataclass class DownloadedImage: imurl: str @@ -83,11 +111,20 @@ class DownloadedImage: def __exit__(self, type, value, traceback): os.remove(self.filename) -def main(): +def main(draw_faces = False): try: simg = get_image(get_random_searchtag()) except ConnectionError: + logging.warning("Retried since couldn't get source...") main() + return + + if id_is_blacklisted(simg.id): + logging.info("Retried, already posted image...") + main() + return + + append_blacklisted(simg.id) with DownloadedImage(simg.imurl) as impath: img = cv2.imread(impath) @@ -101,14 +138,32 @@ def main(): scaleFactor = 1.1, minNeighbors = 5, minSize = (24, 24)) - for (x, y, w, h) in faces: - cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2) + if draw_faces: + for (x, y, w, h) in faces: + cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2) + + logging.info("Found image %i faces, id: %i" % (len(faces), simg.id)) + + pilimg = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) + text = utils.get_quote(CONFIG["texts"]) + logging.info(text) + font = utils.set_font(pilimg, text) + draw = ImageDraw.Draw(pilimg) + lines = utils.messages_multiline(text, font, pilimg) + colours = utils.get_colors(impath) + + (x, y, faces) = utils.randomize_location(pilimg, lines, font, faces) + for line in lines: + height = font.getsize(line[1])[1] + utils.draw_with_border(x, y, line, colours[0], colours[1], font, draw) + y = y + height + + pilimg.save("img.png") + return "img.png", simg.source, text - cv2.imshow("Press to exit", img) - cv2.waitKey(0) if __name__ == "__main__": - main() + print(main()) diff --git a/requirements.txt b/requirements.txt index 5f0fb97..48f6f9e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,7 @@ -lxml==4.5.2 +Shapely==1.7.1 requests==2.21.0 -opencv_python==4.4.0.42 -api==0.0.7 colorthief==0.2.1 +lxml==4.5.2 +dataclasses==0.7 Pillow==7.2.0 -Shapely==1.7.1 -twython==3.8.2 +TwitterAPI==2.5.13 diff --git a/utils.py b/utils.py index 2e0e7f3..bdb9eb2 100644 --- a/utils.py +++ b/utils.py @@ -7,6 +7,7 @@ import random import subprocess import json from colorthief import ColorThief +import get_images def draw_with_border(x, y, message, color_fill, color_border, font, draw): @@ -95,7 +96,7 @@ def get_colors(file_name): return color_thief.get_palette(color_count=2, quality=1) -def randomize_location(image, messages, font): +def randomize_location(image, messages, font, faces): image_size = image.size x_coordinate = 0 y_coordinate = 0 @@ -110,8 +111,6 @@ def randomize_location(image, messages, font): # randomize locations that still fit placed = False tries = 0 - faces = detect(image.filename) - print("faces found:", len(faces)) while placed is False and tries < 20: placed = True x = random.randrange(0, image_size[0] - x_coordinate) @@ -120,7 +119,7 @@ def randomize_location(image, messages, font): if is_intersected(face, (x, y, x + x_coordinate, y + y_coordinate)): placed = False tries = tries + 1 - print("tried:", tries) + get_images.logging.info("tried: %i" % tries) return (x, y, len(faces)) -- cgit v1.2.3