162 lines
5.9 KiB
Python
162 lines
5.9 KiB
Python
|
|
from dotenv import load_dotenv
|
|
from PIL import Image, ImageFile
|
|
from common import get_api, get_new_notifications, has_user_posted, mark_user_posted, unmark_user_posted, db_close
|
|
import datetime
|
|
import gettext
|
|
import requests
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
|
|
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
|
|
|
load_dotenv()
|
|
|
|
bot_name = "faggotree"
|
|
|
|
coordinates = [
|
|
(350,200),
|
|
(275,350),
|
|
(425,350),
|
|
(200,500),
|
|
(350,500),
|
|
(500,500),
|
|
(125,650),
|
|
(275,650),
|
|
(425,650),
|
|
(575,650),
|
|
]
|
|
|
|
temp_image_name = (tempfile.NamedTemporaryFile(suffix='.png', delete=False)).name
|
|
|
|
def get_ordered_accounts_ids(account_id):
|
|
current_year = datetime.date.today().year
|
|
accounts = {}
|
|
stop = False
|
|
max_id=None
|
|
loops = 0
|
|
while stop == False:
|
|
statuses = api.account_statuses(account_id, exclude_reblogs=True, max_id=max_id, limit=50)
|
|
for status in statuses:
|
|
if(status.created_at.year < current_year):
|
|
stop = True
|
|
break
|
|
for mention in status.mentions:
|
|
if mention.username == bot_name or mention.username == status.account.username:
|
|
pass
|
|
else:
|
|
if mention.id not in accounts:
|
|
accounts[mention.id] = 1
|
|
else:
|
|
accounts[mention.id] = accounts[mention.id] + 1
|
|
max_id=status.id
|
|
loops = loops + 1
|
|
if loops > 10 :
|
|
stop = True
|
|
accounts_list = sorted(accounts, key=accounts.get, reverse=True)
|
|
accounts_list.insert(0,account_id)
|
|
accounts_list.pop
|
|
return accounts_list
|
|
|
|
def get_accounts(accounts_ids):
|
|
accounts = []
|
|
for i in range(len(accounts_ids)):
|
|
try:
|
|
account = api.account(accounts_ids[i])
|
|
accounts.append(account)
|
|
if len(accounts) == len(coordinates):
|
|
break
|
|
except Exception as e:
|
|
print(e)
|
|
print("Failed to get account id: " + accounts_ids[i])
|
|
return accounts
|
|
|
|
def get_avatar():
|
|
try:
|
|
with Image.open(temp_image_name) as avatar:
|
|
avatar.load()
|
|
return avatar
|
|
except:
|
|
with Image.open('feditree/default.png') as avatar:
|
|
avatar.load()
|
|
return avatar
|
|
|
|
def create_image(accounts):
|
|
with Image.open("feditree/fediverse-christmas-tree.png") as feditree:
|
|
feditree.load()
|
|
with Image.open("feditree/bola_radio.png") as bola_radio:
|
|
bola_radio.load()
|
|
with Image.open("feditree/bola_mask.png") as bola_mask:
|
|
bola_mask.load()
|
|
for i in range(min(len(accounts),len(coordinates))):
|
|
account = api.account(accounts[i])
|
|
avatar_url = account.avatar_static
|
|
avatar_data = requests.get(avatar_url).content
|
|
with open(temp_image_name, 'wb') as handler:
|
|
handler.write(avatar_data)
|
|
avatar = get_avatar()
|
|
avatar = avatar.resize((100,100)).convert("RGB")
|
|
avatar.paste(bola_radio, (0,0), bola_radio)
|
|
feditree.paste(avatar, coordinates[i], bola_mask)
|
|
tmp_file = (tempfile.NamedTemporaryFile(suffix='.png', delete=False)).name
|
|
feditree.save(tmp_file)
|
|
bola_radio.close()
|
|
bola_mask.close()
|
|
avatar.close()
|
|
feditree.close()
|
|
description = _("A simple drawing of a fir tree, crowned with the pentagon symbolizing the Fediverse.")
|
|
description = description + " " + _("There are some christmas bulbs hanging in the tree, which have the avatars of the mentioned accounts inside.")
|
|
description = description + " " + _("The accounts appear in the tree in the same order as the mentions, from top to bottom and from left to right.")
|
|
description = description + " " + _("The order symbolizes the number of interactions, from most to least.")
|
|
description = description + "\n\n" + _("The Fediverse logo was created by @eudaimon@fe.disroot.org and the tree design was obtained from https://freesvgdesigns.com")
|
|
ret = api.media_post(tmp_file, description=description)
|
|
try:
|
|
os.remove(tmp_file)
|
|
except Exception:
|
|
pass
|
|
return ret
|
|
|
|
def get_filtered_notifications():
|
|
return [n for n in get_new_notifications(api, bot_name, ["mention"]) if n.status.visibility in ["public", "unlisted"]]
|
|
|
|
|
|
localedir = './locales'
|
|
api = get_api(os.getenv("FEDI_DOMAIN"), bot_name)
|
|
notifications = get_filtered_notifications()
|
|
i18n = gettext.translation(bot_name, localedir, fallback=True, languages=['en'])
|
|
i18n.install()
|
|
|
|
for notification in notifications:
|
|
try:
|
|
if has_user_posted(bot_name, notification.account.id):
|
|
status = "@" + notification.account.acct + " "
|
|
status += _("I have already generated a faggotree for you this year. Try again next year!")
|
|
api.status_post(status, visibility="direct", in_reply_to_id=notification.status.id)
|
|
continue
|
|
else:
|
|
mark_user_posted(bot_name, notification.account.id)
|
|
accounts_ids = get_ordered_accounts_ids(notification.account.id)
|
|
accounts = get_accounts(accounts_ids)
|
|
image = create_image(accounts)
|
|
status = _("These are the fags who have adorned the #FaggoTree of") + " @" + notification.account.acct + ":\n\n"
|
|
for account in accounts:
|
|
if account.username != notification.account.username:
|
|
status += " - " + account.acct + "\n"
|
|
api.status_post(status, media_ids=image, visibility="unlisted", in_reply_to_id=notification.status.id)
|
|
except Exception as e:
|
|
unmark_user_posted(bot_name, notification.account.id)
|
|
exc_type, exc_obj, exc_tb = sys.exc_info()
|
|
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
|
|
print(exc_type, fname, exc_tb.tb_lineno)
|
|
print(e)
|
|
api.status_post(_("An error ocurred. Please try again or contact my creator"), visibility="direct", in_reply_to_id=notification.status.id)
|
|
|
|
|
|
if os.path.exists(temp_image_name):
|
|
try:
|
|
os.remove(temp_image_name)
|
|
except Exception:
|
|
pass
|
|
|
|
db_close() |