2022-11-08 12:19:05 -06:00
# -*- coding: utf-8 -*-
import re
import arrow
import languageHandler
from string import Template
2022-11-12 11:20:16 -06:00
from . import utils , compose
2022-11-08 12:19:05 -06:00
# Define variables that would be available for all template objects.
# This will be used for the edit template dialog.
2022-11-16 13:28:45 -06:00
# Available variables for post objects.
# safe_text will be the content warning in case a post contains one, text will always be the full text, no matter if has a content warning or not.
post_variables = [ " date " , " display_name " , " screen_name " , " source " , " lang " , " safe_text " , " text " , " image_descriptions " , " visibility " ]
person_variables = [ " display_name " , " screen_name " , " description " , " followers " , " following " , " favorites " , " posts " , " created_at " ]
conversation_variables = [ " users " , " last_post " ]
2022-12-14 12:12:05 -06:00
notification_variables = [ " display_name " , " screen_name " , " text " , " date " ]
2022-11-08 12:19:05 -06:00
# Default, translatable templates.
2022-11-16 13:28:45 -06:00
post_default_template = _ ( " $display_name, $text $image_descriptions $date. $source " )
2022-11-08 12:19:05 -06:00
dm_sent_default_template = _ ( " Dm to $recipient_display_name, $text $date " )
2022-11-16 13:28:45 -06:00
person_default_template = _ ( " $display_name (@$screen_name). $followers followers, $following following, $posts posts. Joined $created_at. " )
2022-12-14 12:12:05 -06:00
notification_default_template = _ ( " $display_name $text, $date " )
2022-11-08 12:19:05 -06:00
def process_date ( field , relative_times = True , offset_hours = 0 ) :
original_date = arrow . get ( field )
if relative_times == True :
ts = original_date . humanize ( locale = languageHandler . curLang [ : 2 ] )
else :
ts = original_date . shift ( hours = offset_hours ) . format ( _ ( " dddd, MMMM D, YYYY H:m:s " ) , locale = languageHandler . curLang [ : 2 ] )
return ts
2022-11-16 13:28:45 -06:00
def process_text ( post , safe = True ) :
2022-11-08 12:19:05 -06:00
# text = utils.clean_mentions(utils.StripChars(text))
2022-11-16 13:28:45 -06:00
if safe == True and post . sensitive == True and post . spoiler_text != " " :
return _ ( " Content warning: {} " ) . format ( post . spoiler_text )
return utils . html_filter ( post . content )
2022-11-08 12:19:05 -06:00
2022-11-09 08:54:47 -06:00
def process_image_descriptions ( media_attachments ) :
""" Attempt to extract information for image descriptions. """
image_descriptions = [ ]
for media in media_attachments :
2022-11-11 15:51:16 -06:00
if media . get ( " description " ) != None and media . get ( " description " ) != " " :
2022-11-09 08:54:47 -06:00
image_descriptions . append ( media . get ( " description " ) )
idescriptions = " "
for image in image_descriptions :
2022-11-16 12:40:52 -06:00
idescriptions = idescriptions + _ ( " Image description: {} " ) . format ( image ) + " \n "
2022-11-09 08:54:47 -06:00
return idescriptions
2022-11-08 12:19:05 -06:00
def remove_unneeded_variables ( template , variables ) :
for variable in variables :
template = re . sub ( " \ $ " + variable , " " , template )
return template
2022-11-16 13:28:45 -06:00
def render_post ( post , template , relative_times = False , offset_hours = 0 ) :
""" Renders any given post according to the passed template.
Available data for posts will be stored in the following variables :
2022-11-08 12:19:05 -06:00
$ date : Creation date .
$ display_name : User profile name .
$ screen_name : User screen name , this is the same name used to reference the user in Twitter .
$ source : Source client from where the current tweet was sent .
$ lang : Two letter code for the automatically detected language for the tweet . This detection is performed by Twitter .
2022-11-16 13:28:45 -06:00
$ safe_text : Safe text to display . If a content warning is applied in posts , display those instead of the whole post .
2022-11-10 15:32:49 -06:00
$ text : Toot text . This always displays the full text , even if there is a content warning present .
2022-11-08 12:19:05 -06:00
$ image_descriptions : Information regarding image descriptions added by twitter users .
2022-11-16 13:28:45 -06:00
$ visibility : post ' s visibility: public, not listed, followers only or direct.
2022-11-08 12:19:05 -06:00
"""
2022-11-16 13:28:45 -06:00
global post_variables
2022-11-08 12:19:05 -06:00
available_data = dict ( )
2022-11-16 13:28:45 -06:00
created_at = process_date ( post . created_at , relative_times , offset_hours )
2022-11-08 12:19:05 -06:00
available_data . update ( date = created_at )
# user.
2022-11-16 13:28:45 -06:00
display_name = post . account . display_name
2022-11-08 15:46:16 -06:00
if display_name == " " :
2022-11-16 13:28:45 -06:00
display_name = post . account . username
available_data . update ( display_name = display_name , screen_name = post . account . acct )
2022-11-08 12:19:05 -06:00
# Source client from where tweet was originated.
source = " "
2022-11-16 13:28:45 -06:00
if hasattr ( post , " application " ) and post . application != None :
available_data . update ( source = post . application . get ( " name " ) )
if post . reblog != None :
text = _ ( " Boosted from @ {} : {} " ) . format ( post . reblog . account . acct , process_text ( post . reblog , safe = False ) , )
safe_text = _ ( " Boosted from @ {} : {} " ) . format ( post . reblog . account . acct , process_text ( post . reblog ) , )
2022-11-08 12:19:05 -06:00
else :
2022-11-16 13:28:45 -06:00
text = process_text ( post , safe = False )
safe_text = process_text ( post )
2022-11-12 15:16:20 -06:00
visibility_settings = dict ( public = _ ( " Public " ) , unlisted = _ ( " Not listed " ) , private = _ ( " Followers only " ) , direct = _ ( " Direct " ) )
2022-11-16 13:28:45 -06:00
visibility = visibility_settings . get ( post . visibility )
available_data . update ( lang = post . language , text = text , safe_text = safe_text , visibility = visibility )
2022-11-08 12:19:05 -06:00
# process image descriptions
image_descriptions = " "
2022-11-16 13:28:45 -06:00
if post . reblog != None :
image_descriptions = process_image_descriptions ( post . reblog . media_attachments )
2022-11-09 08:54:47 -06:00
else :
2022-11-16 13:28:45 -06:00
image_descriptions = process_image_descriptions ( post . media_attachments )
2022-11-09 08:54:47 -06:00
if image_descriptions != " " :
available_data . update ( image_descriptions = image_descriptions )
2022-11-08 12:19:05 -06:00
result = Template ( _ ( template ) ) . safe_substitute ( * * available_data )
2022-11-16 13:28:45 -06:00
result = remove_unneeded_variables ( result , post_variables )
2022-11-08 12:19:05 -06:00
return result
2022-11-13 22:17:28 -06:00
def render_user ( user , template , relative_times = True , offset_hours = 0 ) :
2022-11-08 12:19:05 -06:00
""" Renders persons by using the provided template.
Available data will be stored in the following variables :
$ display_name : The name of the user , as they ’ ve defined it . Not necessarily a person ’ s name . Typically capped at 50 characters , but subject to change .
$ screen_name : The screen name , handle , or alias that this user identifies themselves with .
$ description : The user - defined UTF - 8 string describing their account .
$ followers : The number of followers this account currently has . This value might be inaccurate .
$ following : The number of users this account is following ( AKA their “ followings ” ) . This value might be inaccurate .
2022-11-16 13:28:45 -06:00
$ posts : The number of Tweets ( including retweets ) issued by the user . This value might be inaccurate .
2022-11-08 12:19:05 -06:00
$ created_at : The date and time that the user account was created on Twitter .
"""
global person_variables
2022-11-08 15:46:16 -06:00
display_name = user . display_name
if display_name == " " :
display_name = user . username
2022-11-16 13:28:45 -06:00
available_data = dict ( display_name = display_name , screen_name = user . acct , followers = user . followers_count , following = user . following_count , posts = user . statuses_count )
2022-11-08 12:19:05 -06:00
# Nullable values.
nullables = [ " description " ]
for nullable in nullables :
if hasattr ( user , nullable ) and getattr ( user , nullable ) != None :
available_data [ nullable ] = getattr ( user , nullable )
created_at = process_date ( user . created_at , relative_times = relative_times , offset_hours = offset_hours )
available_data . update ( created_at = created_at )
result = Template ( _ ( template ) ) . safe_substitute ( * * available_data )
result = remove_unneeded_variables ( result , person_variables )
2022-11-12 11:20:16 -06:00
return result
2022-11-16 13:28:45 -06:00
def render_conversation ( conversation , template , post_template , relative_times = False , offset_hours = 0 ) :
2022-11-12 11:20:16 -06:00
users = [ ]
for account in conversation . accounts :
if account . display_name != " " :
users . append ( account . display_name )
else :
users . append ( account . username )
users = " , " . join ( users )
2022-11-16 13:28:45 -06:00
last_post = render_post ( conversation . last_status , post_template , relative_times = relative_times , offset_hours = offset_hours )
available_data = dict ( users = users , last_post = last_post )
2022-11-12 11:20:16 -06:00
result = Template ( _ ( template ) ) . safe_substitute ( * * available_data )
result = remove_unneeded_variables ( result , conversation_variables )
2022-12-14 12:12:05 -06:00
return result
def render_notification ( notification , template , post_template , relative_times = False , offset_hours = 0 ) :
""" Renders any given notification according to the passed template.
Available data for notifications will be stored in the following variables :
$ date : Creation date .
$ display_name : User profile name .
$ screen_name : User screen name , this is the same name used to reference the user in Twitter .
$ text : Notification text , describing the action .
"""
global notification_variables
available_data = dict ( )
created_at = process_date ( notification . created_at , relative_times , offset_hours )
available_data . update ( date = created_at )
# user.
display_name = notification . account . display_name
if display_name == " " :
display_name = notification . account . username
available_data . update ( display_name = display_name , screen_name = notification . account . acct )
text = " Unknown: %r " % ( notification )
# Remove date from status, so it won't be rendered twice.
post_template = post_template . replace ( " $date " , " " )
2023-01-29 11:39:52 -06:00
if notification . type == " status " :
text = _ ( " has posted: {status} " ) . format ( status = render_post ( notification . status , post_template , relative_times , offset_hours ) )
elif notification . type == " mention " :
2022-12-14 12:12:05 -06:00
text = _ ( " has mentionned you: {status} " ) . format ( status = render_post ( notification . status , post_template , relative_times , offset_hours ) )
elif notification . type == " reblog " :
text = _ ( " has boosted: {status} " ) . format ( status = render_post ( notification . status , post_template , relative_times , offset_hours ) )
elif notification . type == " favourite " :
text = _ ( " has added to favorites: {status} " ) . format ( status = render_post ( notification . status , post_template , relative_times , offset_hours ) )
elif notification . type == " update " :
text = _ ( " has updated a status: {status} " ) . format ( status = render_post ( notification . status , post_template , relative_times , offset_hours ) )
elif notification . type == " follow " :
text = _ ( " has followed you. " )
elif notification . type == " poll " :
text = _ ( " A poll in which you have voted has expired: {status} " ) . format ( status = render_post ( notification . status , post_template , relative_times , offset_hours ) )
elif notification . type == " follow_request " :
text = _ ( " wants to follow you. " )
available_data . update ( text = text )
result = Template ( _ ( template ) ) . safe_substitute ( * * available_data )
result = remove_unneeded_variables ( result , post_variables )
result = result . replace ( " . " , " " )
return result