2024-12-16 12:59:26 +00:00
from dotenv import load_dotenv
2024-12-14 23:42:47 +00:00
from PIL import Image , ImageFile
2024-12-13 21:09:22 +00:00
from common import get_api , get_new_notifications , list_read , list_append
import datetime
import gettext
import requests
2024-12-14 23:42:47 +00:00
import os
import sys
2024-12-16 12:59:26 +00:00
import tempfile
2024-12-14 23:42:47 +00:00
ImageFile . LOAD_TRUNCATED_IMAGES = True
2024-12-16 12:59:26 +00:00
load_dotenv ( )
2024-12-14 23:42:47 +00:00
bot_name = " faggotree "
2024-12-13 21:09:22 +00:00
coordinates = [
( 350 , 200 ) ,
( 275 , 350 ) ,
( 425 , 350 ) ,
( 200 , 500 ) ,
( 350 , 500 ) ,
( 500 , 500 ) ,
( 125 , 650 ) ,
( 275 , 650 ) ,
( 425 , 650 ) ,
( 575 , 650 ) ,
]
2024-12-16 12:59:26 +00:00
temp_image_name = ( tempfile . NamedTemporaryFile ( suffix = ' .png ' , delete = False ) ) . name
2024-12-14 23:42:47 +00:00
2024-12-13 21:09:22 +00:00
def get_ordered_accounts_ids ( account_id ) :
current_year = datetime . date . today ( ) . year
accounts = { }
stop = False
max_id = None
loops = 0
while stop == False :
2024-12-14 23:42:47 +00:00
statuses = api . account_statuses ( account_id , exclude_reblogs = True , max_id = max_id , limit = 40 )
2024-12-13 21:09:22 +00:00
for status in statuses :
if ( status . created_at . year < current_year ) :
stop = True
break
for mention in status . mentions :
2024-12-14 23:42:47 +00:00
if mention . username == bot_name or mention . username == status . account . username :
print ( " skipping: " + mention . username )
2024-12-13 21:09:22 +00:00
else :
2024-12-14 23:42:47 +00:00
if mention . id not in accounts :
accounts [ mention . id ] = 1
else :
accounts [ mention . id ] = accounts [ mention . id ] + 1
2024-12-13 21:09:22 +00:00
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 ) ) :
account = api . account ( accounts_ids [ i ] )
2024-12-14 23:42:47 +00:00
accounts . append ( account )
2024-12-13 21:09:22 +00:00
if len ( accounts ) == len ( coordinates ) :
break
return accounts
2024-12-14 23:42:47 +00:00
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
2024-12-13 21:09:22 +00:00
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
2024-12-14 23:42:47 +00:00
with open ( temp_image_name , ' wb ' ) as handler :
2024-12-13 21:09:22 +00:00
handler . write ( avatar_data )
2024-12-14 23:42:47 +00:00
avatar = get_avatar ( )
2024-12-13 21:09:22 +00:00
avatar = avatar . resize ( ( 100 , 100 ) ) . convert ( " RGB " )
avatar . paste ( bola_radio , ( 0 , 0 ) , bola_radio )
feditree . paste ( avatar , coordinates [ i ] , bola_mask )
2024-12-16 12:59:26 +00:00
tmp_file = ( tempfile . NamedTemporaryFile ( suffix = ' .png ' , delete = False ) ) . name
feditree . save ( tmp_file )
2024-12-13 21:09:22 +00:00
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 " )
2024-12-16 12:59:26 +00:00
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 " ] ]
2024-12-13 21:09:22 +00:00
localedir = ' ./locales '
2024-12-16 12:59:26 +00:00
api = get_api ( os . getenv ( " FEDI_DOMAIN " ) , bot_name )
notifications = get_filtered_notifications ( )
2024-12-13 21:09:22 +00:00
previous_ids = list_read ( bot_name + " _previous_ids " )
2024-12-16 12:59:26 +00:00
i18n = gettext . translation ( bot_name , localedir , fallback = True , languages = [ ' en ' ] )
i18n . install ( )
2024-12-13 21:09:22 +00:00
for notification in notifications :
2024-12-13 21:20:12 +00:00
try :
if str ( notification . account . id ) in previous_ids :
status = " @ " + notification . account . acct + " "
2024-12-14 23:42:47 +00:00
status + = _ ( " I have already generated a faggotree for you this year. Try again next year! " )
2024-12-13 21:20:12 +00:00
api . status_post ( status , visibility = " direct " , in_reply_to_id = notification . status . id )
2024-12-13 21:09:22 +00:00
continue
2024-12-13 21:20:12 +00:00
else :
2024-12-14 23:42:47 +00:00
list_append ( bot_name + " _previous_ids " , str ( notification . account . id ) )
2024-12-13 21:20:12 +00:00
accounts_ids = get_ordered_accounts_ids ( notification . account . id )
accounts = get_accounts ( accounts_ids )
image = create_image ( accounts )
2024-12-14 23:42:47 +00:00
status = _ ( " These are the fags who have adorned the #FaggoTree of " ) + " @ " + notification . account . acct + " : \n \n "
2024-12-13 21:20:12 +00:00
for account in accounts :
2024-12-16 12:59:26 +00:00
if account . username != notification . account . username :
status + = " - " + account . acct + " \n "
2024-12-13 21:20:12 +00:00
api . status_post ( status , media_ids = image , visibility = " unlisted " , in_reply_to_id = notification . status . id )
previous_ids . append ( notification . account . id )
2024-12-14 23:42:47 +00:00
except Exception as e :
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 )
2024-12-13 21:20:12 +00:00
api . status_post ( _ ( " An error ocurred. Please try again or contact my creator " ) , visibility = " direct " , in_reply_to_id = notification . status . id )
2024-12-14 23:42:47 +00:00
2024-12-16 12:59:26 +00:00
if os . path . exists ( temp_image_name ) :
try :
os . remove ( temp_image_name )
except Exception :
pass