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
import random
import string
ImageFile . LOAD_TRUNCATED_IMAGES = True
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-14 23:42:47 +00:00
def generate_random_filename ( ) :
length = random . randint ( 10 , 15 ) # Random length between 5-15 characters
chars = string . ascii_lowercase + string . digits
filename = ' ' . join ( random . choice ( chars ) for _ in range ( length ) )
return filename + ' .png '
temp_image_name = generate_random_filename ( )
print ( " generated random image filename: " + temp_image_name )
2024-12-13 21:09:22 +00:00
def get_ordered_accounts_ids ( account_id ) :
2024-12-14 23:42:47 +00:00
print ( " getting ordered accounts ids " )
2024-12-13 21:09:22 +00:00
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
2024-12-14 23:42:47 +00:00
print ( " mentions: " + str ( len ( status . mentions ) ) )
2024-12-13 21:09:22 +00:00
for mention in status . mentions :
2024-12-14 23:42:47 +00:00
print ( mention . username )
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
2024-12-14 23:42:47 +00:00
print ( " stopping loop " )
2024-12-13 21:09:22 +00:00
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 ) :
2024-12-14 23:42:47 +00:00
print ( " getting accounts: " + str ( len ( accounts_ids ) ) )
2024-12-13 21:09:22 +00:00
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 :
print ( " trying to open: " + temp_image_name )
with Image . open ( temp_image_name ) as avatar :
avatar . load ( )
return avatar
except :
print ( " failed to use avatar so using a default " )
with Image . open ( ' feditree/default.png ' ) as avatar :
avatar . load ( )
return avatar
2024-12-13 21:09:22 +00:00
def create_image ( accounts ) :
2024-12-14 23:42:47 +00:00
print ( " Creating image now " )
2024-12-13 21:09:22 +00:00
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 )
feditree . save ( " feditree/feditree.png " )
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 " )
return api . media_post ( " feditree/feditree.png " , description = description )
localedir = ' ./locales '
2024-12-14 23:42:47 +00:00
api = get_api ( ' shitposter.world ' , bot_name )
print ( " getting notifications " )
2024-12-13 21:09:22 +00:00
notifications = get_new_notifications ( api , bot_name , [ " mention " ] )
2024-12-14 23:42:47 +00:00
print ( " getting previous ids " )
2024-12-13 21:09:22 +00:00
previous_ids = list_read ( bot_name + " _previous_ids " )
2024-12-14 23:42:47 +00:00
print ( " to handle: " + str ( len ( notifications ) ) )
2024-12-13 21:09:22 +00:00
for notification in notifications :
2024-12-14 23:42:47 +00:00
i18n = gettext . translation ( bot_name , localedir , fallback = True , languages = [ ' en ' ] )
2024-12-13 21:09:22 +00:00
i18n . install ( )
2024-12-14 23:42:47 +00:00
print ( " handling for: " + notification . account . username )
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-14 23:42:47 +00:00
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
print ( " deleting temp image file " )
try :
os . remove ( temp_image_name )
except Exception :
print ( f " File { temp_image_name } does not exist " )