varuious lol
parent
60d12267f3
commit
db5972f1d0
|
@ -47,11 +47,6 @@ class Comment(Base):
|
||||||
id = Column(Integer, primary_key = True)
|
id = Column(Integer, primary_key = True)
|
||||||
user_comment_id = Column(Integer)
|
user_comment_id = Column(Integer)
|
||||||
bbbb_comment_id = Column(Integer)
|
bbbb_comment_id = Column(Integer)
|
||||||
comment_string = Column(String)
|
|
||||||
|
|
||||||
def get_past_comments(session : Session) -> 'list[str]':
|
|
||||||
stmt = sqlalchemy.select(Comment)
|
|
||||||
return [i.comment_string for i in session.execute(stmt).scalars().fetchall()[0:100]]
|
|
||||||
|
|
||||||
def get_user_comment(user_comment_id:int, session : Session):
|
def get_user_comment(user_comment_id:int, session : Session):
|
||||||
stmt = sqlalchemy.select(Comment).where(Comment.user_comment_id == user_comment_id)
|
stmt = sqlalchemy.select(Comment).where(Comment.user_comment_id == user_comment_id)
|
||||||
|
@ -81,8 +76,8 @@ class Comment(Base):
|
||||||
def has_replied_to_comment(comment_id : int, session : Session):
|
def has_replied_to_comment(comment_id : int, session : Session):
|
||||||
return Comment.get_comment(comment_id, session) == None
|
return Comment.get_comment(comment_id, session) == None
|
||||||
|
|
||||||
def create_new_comment(user_comment_id : int, bbbb_comment_id : int, comment_string : str, session : Session):
|
def create_new_comment(user_comment_id : int, bbbb_comment_id : int, session : Session):
|
||||||
comment = Comment(user_comment_id = user_comment_id, bbbb_comment_id = bbbb_comment_id, comment_string = comment_string)
|
comment = Comment(user_comment_id = user_comment_id, bbbb_comment_id = bbbb_comment_id)
|
||||||
session.add(comment)
|
session.add(comment)
|
||||||
|
|
||||||
class Post(Base):
|
class Post(Base):
|
||||||
|
|
225
automeme.py
225
automeme.py
|
@ -2,7 +2,9 @@ import base64
|
||||||
import io
|
import io
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
from typing import Callable, TypeVar
|
||||||
import meme_generator
|
import meme_generator
|
||||||
|
from meme_generator import WebcomicPanel, OneCharacterWebcomicPanel, TwoCharacterWebcomicPanel, TitleCardWebcomicPanel, add_watermark, create_webcomic
|
||||||
from RDramaAPIInterface import RDramaAPIInterface
|
from RDramaAPIInterface import RDramaAPIInterface
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from os.path import exists, join, realpath, split
|
from os.path import exists, join, realpath, split
|
||||||
|
@ -13,21 +15,21 @@ from sqlalchemy.orm import Session
|
||||||
import os
|
import os
|
||||||
from markdown import markdown
|
from markdown import markdown
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
from utils import get_real_filename
|
||||||
|
|
||||||
TEST_MODE = True
|
TEST_MODE = True
|
||||||
TEST_AUTH_TOKEN = "ED3eURMKP9FKBFbi-JUxo8MPGWkEihuyIlAUGtVL7xwx0NEy4Nf6J_mxWYTPgAQx1iy1X91hx7PPHyEBS79hvKVIy5DMEzOyAe9PAc5pmqSJlLGq_-ROewMwFzGrqer4"
|
TEST_AUTH_TOKEN = "ED3eURMKP9FKBFbi-JUxo8MPGWkEihuyIlAUGtVL7xwx0NEy4Nf6J_mxWYTPgAQx1iy1X91hx7PPHyEBS79hvKVIy5DMEzOyAe9PAc5pmqSJlLGq_-ROewMwFzGrqer4"
|
||||||
MINUTES_BEFORE_FORCED_SHUTDOWN = 10
|
MINUTES_BEFORE_FORCED_SHUTDOWN = 10
|
||||||
DB_FILENAME = "automeme_database.db"
|
DB_FILENAME = "automeme_database.db"
|
||||||
PAGES_TO_SCAN = 5
|
PAGES_TO_SCAN = 5
|
||||||
AUTOMEME_ID = 3 #TODO
|
AUTOMEME_ID = 13427
|
||||||
ALLOWED_COMMENTS_PER_POST = 20
|
ALLOWED_COMMENTS_PER_POST = 20
|
||||||
ALLOWED_COMMENTS_PER_USER_PER_DAY = 20
|
ALLOWED_COMMENTS_PER_USER_PER_DAY = 20
|
||||||
|
|
||||||
def get_real_filename(filename : str):
|
EMOJI_REGEX = r":[^ ]*:"
|
||||||
path_to_script = realpath(__file__)
|
IMAGE_REGEX = r"!\[\]\(/images/([1234567890]*)\.webp\)"
|
||||||
path_to_script_directory, _ = split(path_to_script)
|
PARSED_IMAGE_REGEX = r"IMAGE:/images/[1234567890]*\.webp"
|
||||||
return join(path_to_script_directory, filename)
|
INJECTABLE_IMAGE_REGEX = r"IMAGE:/images/\1\.webp"
|
||||||
|
|
||||||
# rdrama = RDramaAPIInterface(TEST_AUTH_TOKEN, "localhost", sleep=5, https=False)
|
# rdrama = RDramaAPIInterface(TEST_AUTH_TOKEN, "localhost", sleep=5, https=False)
|
||||||
# print(open('emoji_cache/klanjak.webp', 'rb'))
|
# print(open('emoji_cache/klanjak.webp', 'rb'))
|
||||||
|
@ -38,11 +40,52 @@ def get_real_filename(filename : str):
|
||||||
# file = {'file': ('based.webp', output.getvalue(), 'image/webp')}
|
# file = {'file': ('based.webp', output.getvalue(), 'image/webp')}
|
||||||
# rdrama.reply_to_comment_easy(175, 1, "assddsfssdssdsd", file=file)
|
# rdrama.reply_to_comment_easy(175, 1, "assddsfssdssdsd", file=file)
|
||||||
|
|
||||||
def comment_with_image(image, comment_id, post_id):
|
def comment_with_image(message, image, comment_id, post_id):
|
||||||
output = io.BytesIO()
|
output = io.BytesIO()
|
||||||
image.save(output, format="webp")
|
image.save(output, format="webp")
|
||||||
file = {'file': ('based.webp', output.getvalue(), 'image/webp')}
|
file = {'file': ('based.webp', output.getvalue(), 'image/webp')}
|
||||||
rdrama.reply_to_comment_easy(comment_id, post_id, "ffffff", file=file)
|
return rdrama.reply_to_comment_easy(comment_id, post_id, message, file=file)['id']
|
||||||
|
|
||||||
|
class TextLine:
|
||||||
|
def __init__(self, string):
|
||||||
|
self.line = text_elements(string)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def text(self) -> str:
|
||||||
|
text = [i.text for i in self.line if isinstance(i, Text)]
|
||||||
|
return " ".join(text)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def captions(self) -> 'list[Text]':
|
||||||
|
return [i for i in self.line if isinstance(i, Text)]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def images(self) -> 'list[Image]':
|
||||||
|
return [i for i in self.line if isinstance(i, Image)]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def emojis(self) -> 'list[Emoji]':
|
||||||
|
return [i for i in self.line if isinstance(i, Emoji)]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_dialogue_line(self):
|
||||||
|
return len(self.emojis) == 1 and len(self.captions) == 1
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_argument_line(self):
|
||||||
|
return len(self.emojis) == 2 and (len(self.captions) == 2 or len(self.captions) == 1)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_pure_text_line(self):
|
||||||
|
return len(self.emojis) == 0 and len(self.images) == 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_big_marsey_line(self):
|
||||||
|
return len(self.emojis) == 1 and self.emojis[0].big and len(self.captions) == 0
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_image_line(self):
|
||||||
|
return len(self.images) == 1 and len(self.captions) == 0
|
||||||
|
|
||||||
class TextElement():
|
class TextElement():
|
||||||
pass
|
pass
|
||||||
|
@ -54,6 +97,13 @@ class Text(TextElement):
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"Text({self.text})"
|
return f"Text({self.text})"
|
||||||
|
|
||||||
|
class Image(TextElement):
|
||||||
|
def __init__(self, link):
|
||||||
|
self.link = link
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"Link({self.link})"
|
||||||
|
|
||||||
class Emoji(TextElement):
|
class Emoji(TextElement):
|
||||||
def __init__(self, emoji, big):
|
def __init__(self, emoji, big):
|
||||||
self.emoji = emoji
|
self.emoji = emoji
|
||||||
|
@ -67,15 +117,15 @@ def get_text_only(text_elements : list[TextElement]) -> str:
|
||||||
return " ".join(text)
|
return " ".join(text)
|
||||||
|
|
||||||
def text_elements(string : str):
|
def text_elements(string : str):
|
||||||
EMOJI_REGEX = r"(:[^ ]*:)"
|
FULL_REGEX = rf"({EMOJI_REGEX})|({PARSED_IMAGE_REGEX})"
|
||||||
elements = re.split(EMOJI_REGEX, string)
|
elements = re.split(FULL_REGEX, string)
|
||||||
to_return = []
|
to_return = []
|
||||||
for element in elements:
|
for element in elements:
|
||||||
if element == "":
|
if element == None:
|
||||||
continue
|
continue
|
||||||
if not re.match(EMOJI_REGEX, element):
|
if element.strip() == "":
|
||||||
to_return.append(Text(element.strip()))
|
continue
|
||||||
else:
|
if re.match(EMOJI_REGEX, element):
|
||||||
if "#" in element:
|
if "#" in element:
|
||||||
big = True
|
big = True
|
||||||
element = element.replace("#","")
|
element = element.replace("#","")
|
||||||
|
@ -83,9 +133,14 @@ def text_elements(string : str):
|
||||||
big = False
|
big = False
|
||||||
element = element.strip(":")
|
element = element.strip(":")
|
||||||
to_return.append(Emoji(element, big))
|
to_return.append(Emoji(element, big))
|
||||||
|
elif re.match(PARSED_IMAGE_REGEX, element):
|
||||||
|
to_return.append(Image(element.strip()[6:]))
|
||||||
|
else:
|
||||||
|
to_return.append(Text(element.strip()))
|
||||||
return to_return
|
return to_return
|
||||||
|
|
||||||
def strip_markdown(markdown_string):
|
def strip_markdown(markdown_string):
|
||||||
|
markdown_string = re.sub(IMAGE_REGEX, INJECTABLE_IMAGE_REGEX, markdown_string)
|
||||||
markdown_string = re.sub(">.*\n", "", markdown_string)
|
markdown_string = re.sub(">.*\n", "", markdown_string)
|
||||||
try:
|
try:
|
||||||
html = markdown(markdown_string)
|
html = markdown(markdown_string)
|
||||||
|
@ -116,21 +171,31 @@ def remove_duplicates(list):
|
||||||
def get_eligible_comments(rdrama : RDramaAPIInterface, session : Session):
|
def get_eligible_comments(rdrama : RDramaAPIInterface, session : Session):
|
||||||
comments = rdrama.get_comments(number_of_pages=PAGES_TO_SCAN)['data']
|
comments = rdrama.get_comments(number_of_pages=PAGES_TO_SCAN)['data']
|
||||||
comments = [comment for comment in comments if not comment['is_bot']] #No bots
|
comments = [comment for comment in comments if not comment['is_bot']] #No bots
|
||||||
comments = [comment for comment in comments if not comment['author']['id'] == BBBB_ID] #Don't reply to self
|
comments = [comment for comment in comments if not comment['author']['id'] == AUTOMEME_ID] #Don't reply to self
|
||||||
comments = [comment for comment in comments if Post.get_number_of_replies(comment['post_id'], session) < ALLOWED_COMMENTS_PER_POST] #Don't spam posts
|
comments = [comment for comment in comments if Post.get_number_of_replies(comment['post_id'], session) < ALLOWED_COMMENTS_PER_POST] #Don't spam posts
|
||||||
comments = [comment for comment in comments if User.get_number_of_comments(comment['author']['id'], session) < ALLOWED_COMMENTS_PER_USER_PER_DAY] #Don't spam users
|
comments = [comment for comment in comments if User.get_number_of_comments(comment['author']['id'], session) < ALLOWED_COMMENTS_PER_USER_PER_DAY] #Don't spam users
|
||||||
comments = [comment for comment in comments if Comment.get_comment(comment['id'], session) is None] #Double check that we haven't replied to the comment
|
comments = [comment for comment in comments if Comment.get_comment(comment['id'], session) is None] #Double check that we haven't replied to the comment
|
||||||
comments = remove_duplicates(comments) #Remove the duplicates
|
comments = remove_duplicates(comments) #Remove the duplicates
|
||||||
return comments
|
return comments
|
||||||
|
|
||||||
|
T = TypeVar('T')
|
||||||
|
def lambda_count(list : list[T], predicate : 'Callable[[T], bool]' ):
|
||||||
|
return sum(1 for i in list if predicate(i))
|
||||||
|
|
||||||
|
def get_full_rdrama_image_url(partial_url) -> str:
|
||||||
|
if (TEST_MODE):
|
||||||
|
return f"http://localhost{partial_url}"
|
||||||
|
else:
|
||||||
|
return f"https://rdrama.net{partial_url}"
|
||||||
|
|
||||||
def main_processing_task(rdrama : RDramaAPIInterface, session : Session):
|
def main_processing_task(rdrama : RDramaAPIInterface, session : Session):
|
||||||
is_chudded = False #Do we have the chud award?
|
is_chudded = False #Do we have the chud award?
|
||||||
can_communicate = True #Can we send any message at all?
|
can_communicate = True #Can we send any message at all?
|
||||||
is_pizzad = False
|
is_pizzad = False
|
||||||
rdrama.get_front_page()
|
rdrama.get_front_page()
|
||||||
bbbb_information = rdrama.get_user_information(BBBB_ID)
|
automeme_information = rdrama.get_user_information(AUTOMEME_ID)
|
||||||
print(f"coins: {bbbb_information['coins']} comments: {bbbb_information['comment_count']}")
|
print(f"coins: {automeme_information['coins']} comments: {automeme_information['comment_count']}")
|
||||||
for badge in bbbb_information['badges']:
|
for badge in automeme_information['badges']:
|
||||||
if (badge['name'] == "Marsey Award"):
|
if (badge['name'] == "Marsey Award"):
|
||||||
print("We have the marsey award. STOP.")
|
print("We have the marsey award. STOP.")
|
||||||
can_communicate = False
|
can_communicate = False
|
||||||
|
@ -144,32 +209,130 @@ def main_processing_task(rdrama : RDramaAPIInterface, session : Session):
|
||||||
print("We have the Pizzashill Award. CONTINUE.")
|
print("We have the Pizzashill Award. CONTINUE.")
|
||||||
is_pizzad = True
|
is_pizzad = True
|
||||||
|
|
||||||
if bbbb_information['is_banned']:
|
if automeme_information['is_banned']:
|
||||||
print("We are banned. STOP.")
|
print("We are banned. STOP.")
|
||||||
can_communicate = False
|
can_communicate = False
|
||||||
|
|
||||||
if can_communicate:
|
if can_communicate:
|
||||||
eligible_comments = get_eligible_comments(rdrama, session)
|
eligible_comments = get_eligible_comments(rdrama, session)
|
||||||
for eligible_comment in eligible_comments:
|
for eligible_comment in eligible_comments:
|
||||||
|
under_post_limit = Post.get_number_of_replies(eligible_comment['post_id'], session) < ALLOWED_COMMENTS_PER_POST
|
||||||
|
under_user_limit = User.get_number_of_comments(eligible_comment['author']['id'], session) < ALLOWED_COMMENTS_PER_USER_PER_DAY
|
||||||
|
has_not_replied_to_comment = Comment.get_comment(eligible_comment['id'], session) is None
|
||||||
|
|
||||||
|
if (not (under_post_limit and under_user_limit and has_not_replied_to_comment)):
|
||||||
|
continue
|
||||||
|
|
||||||
comment_text = eligible_comment['body']
|
comment_text = eligible_comment['body']
|
||||||
cleaned_comment_text = strip_markdown(comment_text)
|
cleaned_comment_text = strip_markdown(comment_text)
|
||||||
|
|
||||||
comment_lines = cleaned_comment_text.split("\n")
|
comment_lines = cleaned_comment_text.split("\n")
|
||||||
comment_lines = [comment_line for comment_line in comment_lines if comment_line != ""]
|
comment_lines = [comment_line for comment_line in comment_lines if comment_line != ""]
|
||||||
element_lines = [text_elements(line) for line in comment_lines]
|
element_lines = [TextLine(line) for line in comment_lines]
|
||||||
|
|
||||||
image = None
|
argument_lines_count, dialog_lines_count, text_lines_count, big_marsey_lines_count = 0,0,0,0
|
||||||
if (len(element_lines) == 2):
|
|
||||||
if isinstance(element_lines[0][0], Emoji) and isinstance(element_lines[1][0], Emoji):
|
dialog_lines = list(filter(lambda a : a.is_dialogue_line, element_lines))
|
||||||
emoji1 = element_lines[0][0].emoji
|
argument_lines = list(filter(lambda a : a.is_argument_line, element_lines))
|
||||||
emoji2 = element_lines[1][0].emoji
|
pure_text_lines = list(filter(lambda a : a.is_pure_text_line, element_lines))
|
||||||
caption1 = get_text_only(element_lines[0][1:])
|
big_marsey_lines = list(filter(lambda a : a.is_big_marsey_line, element_lines))
|
||||||
caption2 = get_text_only(element_lines[1][1:])
|
image_lines = list(filter(lambda a : a.is_image_line, element_lines))
|
||||||
|
|
||||||
|
argument_lines_count = len(argument_lines)
|
||||||
|
dialog_lines_count = len(dialog_lines)
|
||||||
|
pure_text_lines_count = len(pure_text_lines)
|
||||||
|
big_marsey_lines_count = len(big_marsey_lines)
|
||||||
|
image_lines_count = len(image_lines)
|
||||||
|
|
||||||
image = meme_generator.create_soy_vs_chad_meme(emoji1, emoji2, caption1, caption2)
|
image = None
|
||||||
|
if (dialog_lines_count == 2):
|
||||||
|
#Soy vs Chad
|
||||||
|
line1 = dialog_lines[0]
|
||||||
|
line2 = dialog_lines[1]
|
||||||
|
|
||||||
|
emoji1 = line1.emojis[0].emoji
|
||||||
|
emoji2 = line2.emojis[0].emoji
|
||||||
|
caption1 = line1.text
|
||||||
|
caption2 = line2.text
|
||||||
|
|
||||||
|
image = meme_generator.create_soy_vs_chad_meme(emoji1, emoji2, caption1, caption2)
|
||||||
|
elif (big_marsey_lines_count == 1 and pure_text_lines_count == 1):
|
||||||
|
# Modern Meme with Marsey
|
||||||
|
text_line = pure_text_lines[0]
|
||||||
|
marsey_line = big_marsey_lines[0]
|
||||||
|
|
||||||
|
marsey = marsey_line.emojis[0].emoji
|
||||||
|
caption = text_line.text
|
||||||
|
|
||||||
|
image = meme_generator.create_modern_meme_from_emoji(marsey, caption)
|
||||||
|
elif (image_lines_count == 1 and pure_text_lines_count == 1):
|
||||||
|
# Modern Meme with Image
|
||||||
|
text_line = pure_text_lines[0]
|
||||||
|
image_line = image_lines[0]
|
||||||
|
|
||||||
|
image = image_line.images[0].link
|
||||||
|
full_image_url = get_full_rdrama_image_url(image)
|
||||||
|
caption = text_line.text
|
||||||
|
|
||||||
|
image = meme_generator.create_modern_meme_from_url(full_image_url, caption)
|
||||||
|
elif (big_marsey_lines_count == 1 and pure_text_lines_count == 2):
|
||||||
|
# Classic Meme with big marsey
|
||||||
|
top_text_line = pure_text_lines[0]
|
||||||
|
bottom_text_line = pure_text_lines[1]
|
||||||
|
marsey_line = big_marsey_lines[0]
|
||||||
|
|
||||||
|
emoji = marsey_line.emojis[0].emoji
|
||||||
|
top_caption = top_text_line.text
|
||||||
|
bottom_caption = bottom_text_line.text
|
||||||
|
image = meme_generator.create_classic_meme_from_emoji(emoji, top_caption, bottom_caption)
|
||||||
|
elif (image_lines_count == 1 and pure_text_lines_count == 2):
|
||||||
|
# Classic Meme with Image
|
||||||
|
top_text_line = pure_text_lines[0]
|
||||||
|
bottom_text_line = pure_text_lines[1]
|
||||||
|
image_line = image_lines[0]
|
||||||
|
|
||||||
|
image = image_line.images[0].link
|
||||||
|
full_image_url = get_full_rdrama_image_url(image)
|
||||||
|
top_caption = top_text_line.text
|
||||||
|
bottom_caption = bottom_text_line.text
|
||||||
|
|
||||||
|
image = meme_generator.create_classic_meme_from_url(full_image_url, top_caption, bottom_caption)
|
||||||
|
elif (argument_lines_count >= 1 or dialog_lines_count >= 1):
|
||||||
|
panels : 'list[WebcomicPanel]' = []
|
||||||
|
|
||||||
|
for element_line in element_lines:
|
||||||
|
if element_line.is_dialogue_line:
|
||||||
|
caption = element_line.text
|
||||||
|
emoji = element_line.emojis[0].emoji
|
||||||
|
if len(caption) > 100:
|
||||||
|
in_background = True
|
||||||
|
else:
|
||||||
|
in_background = False
|
||||||
|
oneCharacterWebcomicPanel = OneCharacterWebcomicPanel(emoji, caption, in_background)
|
||||||
|
panels.append(oneCharacterWebcomicPanel)
|
||||||
|
elif element_line.is_argument_line:
|
||||||
|
left_caption = element_line.captions[0].text
|
||||||
|
if len(element_line.captions) == 2:
|
||||||
|
right_caption = element_line.captions[1].text
|
||||||
|
else:
|
||||||
|
right_caption = ""
|
||||||
|
left_emoji = element_line.emojis[0].emoji
|
||||||
|
right_emoji = element_line.emojis[1].emoji
|
||||||
|
twoCharacterWebcomicPanel = TwoCharacterWebcomicPanel(left_emoji, left_caption, right_emoji, right_caption)
|
||||||
|
panels.append(twoCharacterWebcomicPanel)
|
||||||
|
elif element_line.is_pure_text_line:
|
||||||
|
panels.append(TitleCardWebcomicPanel(element_line.text))
|
||||||
|
|
||||||
|
image = create_webcomic(panels)
|
||||||
if image != None:
|
if image != None:
|
||||||
comment_with_image(image, eligible_comment['id'], eligible_comment['post_id'])
|
image = add_watermark(image, eligible_comment['author']['username'])
|
||||||
|
user_id = eligible_comment['author']['id']
|
||||||
|
parent_comment_id = eligible_comment['id']
|
||||||
|
post_id = eligible_comment['post_id']
|
||||||
|
automeme_comment_id = comment_with_image("yo got a meme for ya nigga", image, eligible_comment['id'], eligible_comment['post_id'])
|
||||||
|
Comment.create_new_comment(parent_comment_id, automeme_comment_id, session)
|
||||||
|
Post.increment_replies(post_id, session)
|
||||||
|
User.increase_number_of_comments(user_id, session)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
TEST_AUTH_TOKEN = "ED3eURMKP9FKBFbi-JUxo8MPGWkEihuyIlAUGtVL7xwx0NEy4Nf6J_mxWYTPgAQx1iy1X91hx7PPHyEBS79hvKVIy5DMEzOyAe9PAc5pmqSJlLGq_-ROewMwFzGrqer4"
|
TEST_AUTH_TOKEN = "ED3eURMKP9FKBFbi-JUxo8MPGWkEihuyIlAUGtVL7xwx0NEy4Nf6J_mxWYTPgAQx1iy1X91hx7PPHyEBS79hvKVIy5DMEzOyAe9PAc5pmqSJlLGq_-ROewMwFzGrqer4"
|
||||||
|
@ -179,7 +342,7 @@ if __name__ == "__main__":
|
||||||
auth = TEST_AUTH_TOKEN
|
auth = TEST_AUTH_TOKEN
|
||||||
https = False
|
https = False
|
||||||
timeout = 1
|
timeout = 1
|
||||||
BBBB_ID = 6
|
AUTOMEME_ID = 7
|
||||||
OPERATOR_ID = 9
|
OPERATOR_ID = 9
|
||||||
ACTUALLY_CALL_OPEN_AI = False
|
ACTUALLY_CALL_OPEN_AI = False
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
from sqlalchemy.orm import Session
|
||||||
|
from sqlalchemy import create_engine
|
||||||
|
from automeme import get_real_filename
|
||||||
|
from BotModels import Base, User
|
||||||
|
import sys
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
db_filename = "automeme_database.db"
|
||||||
|
engine = create_engine(f"sqlite:///{get_real_filename(db_filename)}")
|
||||||
|
Base.metadata.create_all(engine)
|
||||||
|
|
||||||
|
with Session(engine) as session:
|
||||||
|
command = sys.argv[1]
|
||||||
|
if (command == "reset_users"):
|
||||||
|
User.reset_all_comments(session)
|
||||||
|
print("Reset the users!")
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,15 @@ from PIL import ImageFont
|
||||||
from PIL import ImageOps
|
from PIL import ImageOps
|
||||||
import requests
|
import requests
|
||||||
import io
|
import io
|
||||||
|
from utils import get_real_filename
|
||||||
from image_utils import ImageText
|
from image_utils import ImageText
|
||||||
from os.path import exists
|
from os.path import exists
|
||||||
|
from random import choice
|
||||||
|
|
||||||
HIGHLIGHT_MODE = False
|
HIGHLIGHT_MODE = False
|
||||||
|
CAPTION_FILENAME = "watermark_captions.txt"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ColorScheme:
|
class ColorScheme:
|
||||||
BLACK = 0
|
BLACK = 0
|
||||||
|
@ -25,7 +30,7 @@ def create_soy_vs_chad_meme(emoji1, emoji2, caption1, caption2):
|
||||||
IMAGE_ROW = 300
|
IMAGE_ROW = 300
|
||||||
MIDDLE_MARGIN_ROW = 20
|
MIDDLE_MARGIN_ROW = 20
|
||||||
TEXT_ROW = 100
|
TEXT_ROW = 100
|
||||||
BOTTOM_MARGIN_ROW = 200
|
BOTTOM_MARGIN_ROW = 80
|
||||||
|
|
||||||
total_image_size_x = 2*CONTENT_COLUMN + LEFT_MARGIN_COLUMN + RIGHT_MARGIN_COLUMN + MIDDLE_MARGIN_COLUMN
|
total_image_size_x = 2*CONTENT_COLUMN + LEFT_MARGIN_COLUMN + RIGHT_MARGIN_COLUMN + MIDDLE_MARGIN_COLUMN
|
||||||
total_image_size_y = TOP_MARGIN_ROW + IMAGE_ROW + MIDDLE_MARGIN_ROW + TEXT_ROW + BOTTOM_MARGIN_ROW
|
total_image_size_y = TOP_MARGIN_ROW + IMAGE_ROW + MIDDLE_MARGIN_ROW + TEXT_ROW + BOTTOM_MARGIN_ROW
|
||||||
|
@ -63,7 +68,7 @@ def create_soy_vs_chad_meme(emoji1, emoji2, caption1, caption2):
|
||||||
align="cht",
|
align="cht",
|
||||||
font="impact.ttf",
|
font="impact.ttf",
|
||||||
color=ColorScheme.WHITE_WITH_BLACK_BORDER)
|
color=ColorScheme.WHITE_WITH_BLACK_BORDER)
|
||||||
return add_watermark(base)
|
return base
|
||||||
|
|
||||||
def create_classic_meme(image: Image, top_caption : str, bottom_caption : str):
|
def create_classic_meme(image: Image, top_caption : str, bottom_caption : str):
|
||||||
image_x_size, image_y_size = image.size
|
image_x_size, image_y_size = image.size
|
||||||
|
@ -115,7 +120,8 @@ def create_modern_meme_from_emoji(emoji: str, caption: str):
|
||||||
|
|
||||||
class WebcomicPanel():
|
class WebcomicPanel():
|
||||||
PANEL_SIZE = 400
|
PANEL_SIZE = 400
|
||||||
FONT = "Little Story.ttf"
|
FONT = "Impact.ttf"
|
||||||
|
COLOR = ColorScheme.WHITE_WITH_BLACK_BORDER
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
@ -123,6 +129,9 @@ class WebcomicPanel():
|
||||||
def create_image(self) -> Image:
|
def create_image(self) -> Image:
|
||||||
return Image.new(mode="RGB", size=(self.PANEL_SIZE,self.PANEL_SIZE), color=(255,255,255))
|
return Image.new(mode="RGB", size=(self.PANEL_SIZE,self.PANEL_SIZE), color=(255,255,255))
|
||||||
|
|
||||||
|
def add_text_box(self, base : Image, caption : str, region_size : tuple[int, int], coordinates : tuple[int, int], align=""):
|
||||||
|
add_text_box(base, caption, region_size, coordinates, align=align, font=self.FONT, color=self.COLOR, init_font_size=int(self.PANEL_SIZE/10))
|
||||||
|
|
||||||
class OneCharacterWebcomicPanel(WebcomicPanel):
|
class OneCharacterWebcomicPanel(WebcomicPanel):
|
||||||
def __init__(self, emoji, caption, words_in_background):
|
def __init__(self, emoji, caption, words_in_background):
|
||||||
self.emoji = emoji
|
self.emoji = emoji
|
||||||
|
@ -136,7 +145,7 @@ class OneCharacterWebcomicPanel(WebcomicPanel):
|
||||||
# We put the text in the background of the panel.
|
# We put the text in the background of the panel.
|
||||||
text_region_x_size = int(panel_size_x)
|
text_region_x_size = int(panel_size_x)
|
||||||
text_region_y_size = int(panel_size_y if self.words_in_background else panel_size_y/2)
|
text_region_y_size = int(panel_size_y if self.words_in_background else panel_size_y/2)
|
||||||
add_text(base, self.caption, (text_region_x_size, text_region_y_size), (0,0), font=super().FONT)
|
self.add_text_box(base, self.caption, (text_region_x_size, text_region_y_size), (0,0))
|
||||||
|
|
||||||
# We put marsey in the bottom left quadrant
|
# We put marsey in the bottom left quadrant
|
||||||
emoji_region_x_size = int(panel_size_x)
|
emoji_region_x_size = int(panel_size_x)
|
||||||
|
@ -186,14 +195,14 @@ class TwoCharacterWebcomicPanel(WebcomicPanel):
|
||||||
left_text_region_y_size = int(panel_size_y/4)
|
left_text_region_y_size = int(panel_size_y/4)
|
||||||
left_text_region_x_position = 0
|
left_text_region_x_position = 0
|
||||||
left_text_region_y_position = 0
|
left_text_region_y_position = 0
|
||||||
add_text_box(base, self.left_caption, (left_text_region_x_size, left_text_region_y_size), (left_text_region_x_position,left_text_region_y_position), font=super().FONT, align="bl")
|
self.add_text_box(base, self.left_caption, (left_text_region_x_size, left_text_region_y_size), (left_text_region_x_position,left_text_region_y_position), align="bl")
|
||||||
|
|
||||||
# We put the text in the top half of the panel.
|
# We put the text in the top half of the panel.
|
||||||
right_text_region_x_size = int(CAPTION_UNITS*(panel_size_x/CAPTION_DIVISOR))
|
right_text_region_x_size = int(CAPTION_UNITS*(panel_size_x/CAPTION_DIVISOR))
|
||||||
right_text_region_y_size = int(panel_size_y/4)
|
right_text_region_y_size = int(panel_size_y/4)
|
||||||
right_text_region_x_position = int((CAPTION_DIVISOR-CAPTION_UNITS)*(panel_size_x/8))
|
right_text_region_x_position = int((CAPTION_DIVISOR-CAPTION_UNITS)*(panel_size_x/8))
|
||||||
right_text_region_y_position = int(panel_size_y/4)
|
right_text_region_y_position = int(panel_size_y/4)
|
||||||
add_text_box(base, self.right_caption, (right_text_region_x_size, right_text_region_y_size), (right_text_region_x_position,right_text_region_y_position), font=super().FONT, align="br")
|
self.add_text_box(base, self.right_caption, (right_text_region_x_size, right_text_region_y_size), (right_text_region_x_position,right_text_region_y_position), align="br")
|
||||||
|
|
||||||
return add_border_to_image(base)
|
return add_border_to_image(base)
|
||||||
|
|
||||||
|
@ -204,7 +213,7 @@ class TitleCardWebcomicPanel(WebcomicPanel):
|
||||||
def create_image(self) -> Image:
|
def create_image(self) -> Image:
|
||||||
base = super().create_image()
|
base = super().create_image()
|
||||||
|
|
||||||
add_text_box(base, self.caption, base.size, (0,0), font=super().FONT, init_font_size=90, align="cvch")
|
self.add_text_box(base, self.caption, base.size, (0,0), align="cvch")
|
||||||
|
|
||||||
return add_border_to_image(base)
|
return add_border_to_image(base)
|
||||||
|
|
||||||
|
@ -219,7 +228,7 @@ def create_webcomic(layout : 'list[WebcomicPanel]'):
|
||||||
x = i%2
|
x = i%2
|
||||||
y = math.floor(i/2)
|
y = math.floor(i/2)
|
||||||
image.paste(panel.create_image(), (x*assumed_panel_x_size, y*assumed_panel_y_size))
|
image.paste(panel.create_image(), (x*assumed_panel_x_size, y*assumed_panel_y_size))
|
||||||
return add_watermark(image)
|
return image
|
||||||
|
|
||||||
def add_text_box(base : Image, caption : str, region_size : tuple[int, int], coordinates : tuple[int, int], font : str= "arial.ttf", init_font_size = 45, align :str = "", color = ColorScheme.BLACK):
|
def add_text_box(base : Image, caption : str, region_size : tuple[int, int], coordinates : tuple[int, int], font : str= "arial.ttf", init_font_size = 45, align :str = "", color = ColorScheme.BLACK):
|
||||||
if caption == "":
|
if caption == "":
|
||||||
|
@ -242,7 +251,7 @@ def add_text_box(base : Image, caption : str, region_size : tuple[int, int], coo
|
||||||
if "ch" in align:
|
if "ch" in align:
|
||||||
place = "center"
|
place = "center"
|
||||||
|
|
||||||
actual_text_box_size = line_image.write_text_box((0,0), caption, region_x_size, font_size=init_font_size, font_filename=font, color=fill_color, stroke_color=stroke, stroke_size=stroke_size, place=place)
|
actual_text_box_size = line_image.write_text_box((stroke_size,0), caption, region_x_size, font_size=init_font_size, font_filename=font, color=fill_color, stroke_color=stroke, stroke_size=stroke_size, place=place)
|
||||||
_, actual_text_box_y_size, input_text_block_x_size, actual_text_box_x_size = actual_text_box_size
|
_, actual_text_box_y_size, input_text_block_x_size, actual_text_box_x_size = actual_text_box_size
|
||||||
if actual_text_box_y_size <= region_y_size:
|
if actual_text_box_y_size <= region_y_size:
|
||||||
actual_paste_x_coordinates, actual_paste_y_coordinates = coordinates
|
actual_paste_x_coordinates, actual_paste_y_coordinates = coordinates
|
||||||
|
@ -284,7 +293,8 @@ def add_text(base : Image, caption : str, region_size : tuple[int, int], coordin
|
||||||
line_image.fill_text_box((0,0), caption, region_x_size, region_y_size, font_filename=font)
|
line_image.fill_text_box((0,0), caption, region_x_size, region_y_size, font_filename=font)
|
||||||
base.paste(line_image.image, coordinates, line_image.image)
|
base.paste(line_image.image, coordinates, line_image.image)
|
||||||
|
|
||||||
def add_watermark(image : Image):
|
def add_watermark(image : Image, name_of_other_creator):
|
||||||
|
global watermark_captions
|
||||||
WATERMARK_HEIGHT = 30
|
WATERMARK_HEIGHT = 30
|
||||||
image_size_x, image_size_y = image.size
|
image_size_x, image_size_y = image.size
|
||||||
base = Image.new(mode="RGB", size=(image_size_x, image_size_y + WATERMARK_HEIGHT), color=(255,255,255))
|
base = Image.new(mode="RGB", size=(image_size_x, image_size_y + WATERMARK_HEIGHT), color=(255,255,255))
|
||||||
|
@ -296,8 +306,9 @@ def add_watermark(image : Image):
|
||||||
|
|
||||||
text_line_size = int(WATERMARK_HEIGHT/2)
|
text_line_size = int(WATERMARK_HEIGHT/2)
|
||||||
|
|
||||||
add_text(base, "A meme by HeyMoon and Foo", (image_size_x, text_line_size), (WATERMARK_HEIGHT, image_size_y))
|
caption = choice(watermark_captions)
|
||||||
add_text(base, "For instructions on how to legally build a pipe bomb, go to rdrama.net", (image_size_x, text_line_size), (WATERMARK_HEIGHT, image_size_y+text_line_size))
|
add_text(base, f"A meme by {name_of_other_creator} and automeme", (image_size_x, text_line_size), (WATERMARK_HEIGHT, image_size_y))
|
||||||
|
add_text(base, f"{caption}, go to rdrama.net", (image_size_x, text_line_size), (WATERMARK_HEIGHT, image_size_y+text_line_size))
|
||||||
|
|
||||||
return base
|
return base
|
||||||
|
|
||||||
|
@ -349,6 +360,17 @@ def get_image_file_from_url(url):
|
||||||
im = Image.open(image_file)
|
im = Image.open(image_file)
|
||||||
return im
|
return im
|
||||||
|
|
||||||
|
def parse_caption_file(filename):
|
||||||
|
if not exists(filename):
|
||||||
|
return []
|
||||||
|
to_return = []
|
||||||
|
with open(get_real_filename(filename), "r") as f:
|
||||||
|
for id in f.readlines():
|
||||||
|
to_return.append(id.strip())
|
||||||
|
return to_return
|
||||||
|
|
||||||
|
watermark_captions = parse_caption_file(CAPTION_FILENAME)
|
||||||
|
|
||||||
#create_soy_vs_chad_meme("bigsmilesoyjak", "!marseyshooting", "I have fun new toys and games for your children", "Die").show()
|
#create_soy_vs_chad_meme("bigsmilesoyjak", "!marseyshooting", "I have fun new toys and games for your children", "Die").show()
|
||||||
|
|
||||||
# create_webcomic([
|
# create_webcomic([
|
||||||
|
|
Loading…
Reference in New Issue