Variable types

main
bashrc 2026-05-05 19:14:59 +01:00
parent b7f6f4b7a7
commit c12c28dd76
1 changed files with 130 additions and 119 deletions

View File

@ -1442,7 +1442,7 @@ def _get_blog_citations_html(box_name: str,
'<cite>' + citation_name + '</cite></a></li>\n' '<cite>' + citation_name + '</cite></a></li>\n'
if citations_str: if citations_str:
translated_citations_str = 'Citations' translated_citations_str: str = 'Citations'
if translate.get(translated_citations_str): if translate.get(translated_citations_str):
translated_citations_str = translate[translated_citations_str] translated_citations_str = translate[translated_citations_str]
citations_str = '<p><b>' + translated_citations_str + ':</b></p>' + \ citations_str = '<p><b>' + translated_citations_str + ':</b></p>' + \
@ -1453,7 +1453,7 @@ def _get_blog_citations_html(box_name: str,
def _boost_own_post_html(translate: {}) -> str: def _boost_own_post_html(translate: {}) -> str:
"""The html title for announcing your own post """The html title for announcing your own post
""" """
announces_str = 'announces' announces_str: str = 'announces'
if translate.get(announces_str): if translate.get(announces_str):
announces_str = translate[announces_str] announces_str = translate[announces_str]
return ' <img loading="lazy" decoding="async" title="' + \ return ' <img loading="lazy" decoding="async" title="' + \
@ -1469,12 +1469,12 @@ def _announce_unattributed_html(translate: {},
"""Returns the html for an announce title where there """Returns the html for an announce title where there
is no attribution on the announced post is no attribution on the announced post
""" """
announces_str = 'announces' announces_str: str = 'announces'
if translate.get(announces_str): if translate.get(announces_str):
announces_str = translate[announces_str] announces_str = translate[announces_str]
post_id = remove_id_ending(post_json_object['object']['id']) post_id: str = remove_id_ending(post_json_object['object']['id'])
post_bookmark = '#' + bookmark_from_id(post_id) post_bookmark: str = '#' + bookmark_from_id(post_id)
post_link = '/users/' + nickname + '?convthread=' + \ post_link: str = '/users/' + nickname + '?convthread=' + \
post_id.replace('--', '/') + post_bookmark post_id.replace('--', '/') + post_bookmark
return ' <img loading="lazy" decoding="async" title="' + \ return ' <img loading="lazy" decoding="async" title="' + \
announces_str + '" alt="' + \ announces_str + '" alt="' + \
@ -1492,12 +1492,12 @@ def _announce_with_display_name_html(translate: {},
announce_handle: str) -> str: announce_handle: str) -> str:
"""Returns html for an announce having a display name """Returns html for an announce having a display name
""" """
announces_str = 'announces' announces_str: str = 'announces'
if translate.get(announces_str): if translate.get(announces_str):
announces_str = translate[announces_str] announces_str = translate[announces_str]
post_id = remove_id_ending(post_json_object['object']['id']) post_id: str = remove_id_ending(post_json_object['object']['id'])
post_bookmark = '#' + bookmark_from_id(post_id) post_bookmark: str = '#' + bookmark_from_id(post_id)
post_link = '/users/' + nickname + '?convthread=' + \ post_link: str = '/users/' + nickname + '?convthread=' + \
post_id.replace('--', '/') + post_bookmark post_id.replace('--', '/') + post_bookmark
return ' <img loading="lazy" decoding="async" title="' + \ return ' <img loading="lazy" decoding="async" title="' + \
announces_str + '" alt="' + \ announces_str + '" alt="' + \
@ -1533,7 +1533,7 @@ def _get_post_title_announce_html(base_dir: str,
""" """
title_str: str = '' title_str: str = ''
reply_avatar_image_in_post: str = '' reply_avatar_image_in_post: str = ''
obj_json = post_json_object['object'] obj_json: dict = post_json_object['object']
# has no attribution # has no attribution
if not obj_json.get('attributedTo'): if not obj_json.get('attributedTo'):
@ -1542,9 +1542,9 @@ def _get_post_title_announce_html(base_dir: str,
return (title_str, reply_avatar_image_in_post, return (title_str, reply_avatar_image_in_post,
container_class_icons, container_class) container_class_icons, container_class)
attributed_to = get_attributed_to(obj_json['attributedTo']) attributed_to: str = get_attributed_to(obj_json['attributedTo'])
if attributed_to is None: if attributed_to is None:
attributed_to: str = '' attributed_to = ''
# boosting your own post # boosting your own post
if attributed_to.startswith(post_actor): if attributed_to.startswith(post_actor):
@ -1554,7 +1554,7 @@ def _get_post_title_announce_html(base_dir: str,
# boosting another person's post # boosting another person's post
_log_post_timing(enable_timing_log, post_start_time, '13.2') _log_post_timing(enable_timing_log, post_start_time, '13.2')
announce_nickname = None announce_nickname: str = None
if attributed_to: if attributed_to:
announce_nickname = get_nickname_from_actor(attributed_to) announce_nickname = get_nickname_from_actor(attributed_to)
if not announce_nickname: if not announce_nickname:
@ -1568,7 +1568,7 @@ def _get_post_title_announce_html(base_dir: str,
announce_handle: str = '' announce_handle: str = ''
if announce_nickname and announce_domain: if announce_nickname and announce_domain:
announce_handle = announce_nickname + '@' + announce_domain announce_handle = announce_nickname + '@' + announce_domain
announce_display_name = \ announce_display_name: str = \
get_display_name(base_dir, attributed_to, person_cache) get_display_name(base_dir, attributed_to, person_cache)
if announce_display_name: if announce_display_name:
if len(announce_display_name) < 2 or \ if len(announce_display_name) < 2 or \
@ -1595,12 +1595,12 @@ def _get_post_title_announce_html(base_dir: str,
if announce_handle in mutuals_list: if announce_handle in mutuals_list:
mutual_prefix = '' mutual_prefix = ''
actor_type = get_actor_type(base_dir, attributed_to, person_cache) actor_type: str = get_actor_type(base_dir, attributed_to, person_cache)
bot_prefix = get_display_name_prefix(actor_type, announce_nickname, bot_prefix: str = \
translate) get_display_name_prefix(actor_type, announce_nickname, translate)
_log_post_timing(enable_timing_log, post_start_time, '13.3.1') _log_post_timing(enable_timing_log, post_start_time, '13.3.1')
announce_display_name2 = \ announce_display_name2: str = \
mutual_prefix + bot_prefix + announce_display_name mutual_prefix + bot_prefix + announce_display_name
title_str += \ title_str += \
_announce_with_display_name_html(translate, post_json_object, _announce_with_display_name_html(translate, post_json_object,
@ -1613,8 +1613,8 @@ def _get_post_title_announce_html(base_dir: str,
title_str += _get_instance_software_html(title_str, software_name) title_str += _get_instance_software_html(title_str, software_name)
# show avatar of person replied to # show avatar of person replied to
announce_actor = attributed_to announce_actor: str = attributed_to
announce_avatar_url = \ announce_avatar_url: str = \
get_person_avatar_url(base_dir, announce_actor, person_cache) get_person_avatar_url(base_dir, announce_actor, person_cache)
_log_post_timing(enable_timing_log, post_start_time, '13.4') _log_post_timing(enable_timing_log, post_start_time, '13.4')
@ -1622,9 +1622,9 @@ def _get_post_title_announce_html(base_dir: str,
if not announce_avatar_url: if not announce_avatar_url:
announce_avatar_url: str = '' announce_avatar_url: str = ''
idx = 'Show options for this person' idx: str = 'Show options for this person'
if '/users/news/' not in announce_avatar_url: if '/users/news/' not in announce_avatar_url:
show_options_for_this_person_str = idx show_options_for_this_person_str: str = idx
if translate.get(idx): if translate.get(idx):
show_options_for_this_person_str = translate[idx] show_options_for_this_person_str = translate[idx]
reply_avatar_image_in_post = \ reply_avatar_image_in_post = \
@ -1647,10 +1647,10 @@ def _get_post_title_announce_html(base_dir: str,
def _reply_to_yourself_html(translate: {}, software_name: str) -> str: def _reply_to_yourself_html(translate: {}, software_name: str) -> str:
"""Returns html for a title which is a reply to yourself """Returns html for a title which is a reply to yourself
""" """
replying_to_themselves_str = 'replying to themselves' replying_to_themselves_str: str = 'replying to themselves'
if translate.get(replying_to_themselves_str): if translate.get(replying_to_themselves_str):
replying_to_themselves_str = translate[replying_to_themselves_str] replying_to_themselves_str = translate[replying_to_themselves_str]
title_str = \ title_str: str = \
' <img loading="lazy" decoding="async" title="' + \ ' <img loading="lazy" decoding="async" title="' + \
replying_to_themselves_str + \ replying_to_themselves_str + \
'" alt="' + replying_to_themselves_str + \ '" alt="' + replying_to_themselves_str + \
@ -1664,7 +1664,7 @@ def _reply_to_yourself_html(translate: {}, software_name: str) -> str:
def _replying_to_with_scope(post_json_object: {}, translate: {}) -> str: def _replying_to_with_scope(post_json_object: {}, translate: {}) -> str:
"""Returns the replying to string """Returns the replying to string
""" """
replying_to_str = 'replying to' replying_to_str: str = 'replying to'
if is_followers_post(post_json_object): if is_followers_post(post_json_object):
replying_to_str = 'replying to followers' replying_to_str = 'replying to followers'
elif is_public_post(post_json_object): elif is_public_post(post_json_object):
@ -1682,12 +1682,12 @@ def _reply_to_unknown_html(translate: {},
software_name: str) -> str: software_name: str) -> str:
"""Returns the html title for a reply to an unknown handle """Returns the html title for a reply to an unknown handle
""" """
replying_to_str = _replying_to_with_scope(post_json_object, translate) replying_to_str: str = _replying_to_with_scope(post_json_object, translate)
post_id = get_reply_to(post_json_object['object']) post_id: str = get_reply_to(post_json_object['object'])
post_bookmark = '#' + bookmark_from_id(post_id) post_bookmark: str = '#' + bookmark_from_id(post_id)
post_link = '/users/' + nickname + '?convthread=' + \ post_link: str = '/users/' + nickname + '?convthread=' + \
post_id.replace('--', '/') + post_bookmark post_id.replace('--', '/') + post_bookmark
title_str = \ title_str: str = \
' <img loading="lazy" decoding="async" title="' + \ ' <img loading="lazy" decoding="async" title="' + \
replying_to_str + '" alt="' + \ replying_to_str + '" alt="' + \
replying_to_str + '" src="/icons' + \ replying_to_str + '" src="/icons' + \
@ -1709,15 +1709,15 @@ def _reply_with_unknown_path_html(translate: {},
"""Returns html title for a reply with an unknown path """Returns html title for a reply with an unknown path
eg. does not contain /statuses/ or an equivalent separator eg. does not contain /statuses/ or an equivalent separator
""" """
replying_to_str = _replying_to_with_scope(post_json_object, translate) replying_to_str: str = _replying_to_with_scope(post_json_object, translate)
post_id = get_reply_to(post_json_object['object']) post_id: str = get_reply_to(post_json_object['object'])
post_bookmark = '#' + bookmark_from_id(post_id) post_bookmark: str = '#' + bookmark_from_id(post_id)
post_link = '/users/' + nickname + '?convthread=' + \ post_link: str = '/users/' + nickname + '?convthread=' + \
post_id.replace('--', '/') + post_bookmark post_id.replace('--', '/') + post_bookmark
mitm_str: str = '' mitm_str: str = ''
if post_domain in mitm_servers: if post_domain in mitm_servers:
mitm_str = ' ' + mitm_warning_html(translate) mitm_str = ' ' + mitm_warning_html(translate)
title_str = \ title_str: str = \
' <img loading="lazy" decoding="async" title="' + \ ' <img loading="lazy" decoding="async" title="' + \
replying_to_str + \ replying_to_str + \
'" alt="' + replying_to_str + \ '" alt="' + replying_to_str + \
@ -1749,14 +1749,14 @@ def _get_reply_html(translate: {},
reply_nickname: str = '' reply_nickname: str = ''
if '@' in reply_nickname: if '@' in reply_nickname:
reply_nickname = reply_handle.split('@')[0] reply_nickname = reply_handle.split('@')[0]
bot_prefix = get_display_name_prefix(actor_type, reply_nickname, bot_prefix: str = \
translate) get_display_name_prefix(actor_type, reply_nickname, translate)
replying_to_str = _replying_to_with_scope(post_json_object, translate) replying_to_str: str = _replying_to_with_scope(post_json_object, translate)
post_bookmark = '#' + bookmark_from_id(in_reply_to) post_bookmark: str = '#' + bookmark_from_id(in_reply_to)
post_link = '/users/' + nickname + '?convthread=' + \ post_link: str = '/users/' + nickname + '?convthread=' + \
in_reply_to.replace('--', '/') + post_bookmark in_reply_to.replace('--', '/') + post_bookmark
title_str = \ title_str: str = \
' ' + \ ' ' + \
'<img loading="lazy" decoding="async" title="' + \ '<img loading="lazy" decoding="async" title="' + \
replying_to_str + '" alt="' + \ replying_to_str + '" alt="' + \
@ -1797,17 +1797,17 @@ def _get_post_title_reply_html(base_dir: str,
""" """
title_str: str = '' title_str: str = ''
reply_avatar_image_in_post: str = '' reply_avatar_image_in_post: str = ''
obj_json = post_json_object['object'] obj_json: dict = post_json_object['object']
# not a reply # not a reply
reply_id = get_reply_to(obj_json) reply_id: str = get_reply_to(obj_json)
if not reply_id: if not reply_id:
title_str += _get_instance_software_html(title_str, software_name) title_str += _get_instance_software_html(title_str, software_name)
return (title_str, reply_avatar_image_in_post, return (title_str, reply_avatar_image_in_post,
container_class_icons, container_class) container_class_icons, container_class)
container_class_icons = 'containericons darker' container_class_icons: str = 'containericons darker'
container_class = 'container darker' container_class: str = 'container darker'
# reply to self # reply to self
if reply_id.startswith(post_actor): if reply_id.startswith(post_actor):
@ -1816,22 +1816,22 @@ def _get_post_title_reply_html(base_dir: str,
container_class_icons, container_class) container_class_icons, container_class)
# has a reply # has a reply
reply_actor = None reply_actor: str = None
in_reply_to = None in_reply_to: str = None
if contains_statuses(reply_id): if contains_statuses(reply_id):
reply_url = reply_id reply_url: str = reply_id
post_domain = reply_url post_domain: str = reply_url
prefixes = get_protocol_prefixes() prefixes: list[str] = get_protocol_prefixes()
for prefix in prefixes: for prefix in prefixes:
post_domain = post_domain.replace(prefix, '') post_domain = post_domain.replace(prefix, '')
if '/' in post_domain: if '/' in post_domain:
post_domain = post_domain.split('/', 1)[0] post_domain = post_domain.split('/', 1)[0]
# resolve inReplyTo to obtain attributedTo # resolve inReplyTo to obtain attributedTo
profile_str = 'https://www.w3.org/ns/activitystreams' profile_str: str = 'https://www.w3.org/ns/activitystreams'
headers = { headers: dict = {
'Accept': 'application/ld+json; profile="' + profile_str + '"' 'Accept': 'application/ld+json; profile="' + profile_str + '"'
} }
reply_post_json = \ reply_post_json: dict = \
get_json(signing_priv_key_pem, get_json(signing_priv_key_pem,
session, reply_url, session, reply_url,
headers, None, debug, mitm_servers, headers, None, debug, mitm_servers,
@ -1939,7 +1939,7 @@ def _get_post_title_reply_html(base_dir: str,
_log_post_timing(enable_timing_log, post_start_time, '13.8') _log_post_timing(enable_timing_log, post_start_time, '13.8')
if reply_avatar_url: if reply_avatar_url:
show_profile_str = 'Show profile' show_profile_str: str = 'Show profile'
if translate.get(show_profile_str): if translate.get(show_profile_str):
show_profile_str = translate[show_profile_str] show_profile_str = translate[show_profile_str]
reply_avatar_image_in_post = \ reply_avatar_image_in_post = \
@ -1987,7 +1987,7 @@ def _get_post_title_html(base_dir: str,
if not is_announced and box_name == 'search' and \ if not is_announced and box_name == 'search' and \
post_json_object.get('object'): post_json_object.get('object'):
if post_json_object['object'].get('attributedTo'): if post_json_object['object'].get('attributedTo'):
attrib = \ attrib: str = \
get_attributed_to(post_json_object['object']['attributedTo']) get_attributed_to(post_json_object['object']['attributedTo'])
if attrib != post_actor: if attrib != post_actor:
is_announced = True is_announced = True
@ -2048,7 +2048,7 @@ def _get_footer_with_icons(show_icons: bool,
if not show_icons: if not show_icons:
return None return None
footer_str = '\n <nav>\n' footer_str: str = '\n <nav>\n'
footer_str += ' <div class="' + container_class_icons + '">\n' footer_str += ' <div class="' + container_class_icons + '">\n'
footer_str += \ footer_str += \
reply_str + announce_str + like_str + bookmark_str + reaction_str reply_str + announce_str + like_str + bookmark_str + reaction_str
@ -2059,8 +2059,8 @@ def _get_footer_with_icons(show_icons: bool,
footer_str += _get_copyright_footer(content_license_url, footer_str += _get_copyright_footer(content_license_url,
translate) translate)
# show the date # show the date
post_bookmark = '#' + bookmark_from_id(published_link) post_bookmark: str = '#' + bookmark_from_id(published_link)
date_link = '/users/' + nickname + '?convthread=' + \ date_link: str = '/users/' + nickname + '?convthread=' + \
published_link.replace('--', '/') + post_bookmark published_link.replace('--', '/') + post_bookmark
footer_str += '<a href="' + date_link + '" class="' + \ footer_str += '<a href="' + date_link + '" class="' + \
time_class + '" tabindex="10"><span itemprop="datePublished">' + \ time_class + '" tabindex="10"><span itemprop="datePublished">' + \
@ -2080,32 +2080,32 @@ def _substitute_onion_domains(base_dir: str, content: str) -> str:
"""Replace clearnet domains with onion domains """Replace clearnet domains with onion domains
""" """
# any common sites which have onion equivalents # any common sites which have onion equivalents
bbc_onion = \ bbc_onion: str = \
'bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion' 'bbcweb3hytmzhn5d532owbu6oqadra5z3ar726vq5kgwwn6aucdccrad.onion'
ddg_onion = \ ddg_onion: str = \
'duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion' 'duckduckgogg42xjoc72x3sjasowoarfbgcmvfimaftt6twagswzczad.onion'
guardian_onion = \ guardian_onion: str = \
'guardian2zotagl6tmjucg3lrhxdk4dw3lhbqnkvvkywawy3oqfoprid.onion' 'guardian2zotagl6tmjucg3lrhxdk4dw3lhbqnkvvkywawy3oqfoprid.onion'
propublica_onion = \ propublica_onion: str = \
'p53lf57qovyuvwsc6xnrppyply3vtqm7l6pcobkmyqsiofyeznfu5uqd.onion' 'p53lf57qovyuvwsc6xnrppyply3vtqm7l6pcobkmyqsiofyeznfu5uqd.onion'
# woe betide anyone following a facebook link, but if you must # woe betide anyone following a facebook link, but if you must
# then do it safely # then do it safely
facebook_onion = \ facebook_onion: str = \
'facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion' 'facebookwkhpilnemxj7asaniu7vnjjbiltxjqhye3mhbshg7kx5tfyd.onion'
protonmail_onion = \ protonmail_onion: str = \
'protonmailrmez3lotccipshtkleegetolb73fuirgj7r4o4vfu7ozyd.onion' 'protonmailrmez3lotccipshtkleegetolb73fuirgj7r4o4vfu7ozyd.onion'
riseup_onion = \ riseup_onion: str = \
'vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd.onion' 'vww6ybal4bd7szmgncyruucpgfkqahzddi37ktceo3ah7ngmcopnpyyd.onion'
keybase_onion = \ keybase_onion: str = \
'keybase5wmilwokqirssclfnsqrjdsi7jdir5wy7y7iu3tanwmtp6oid.onion' 'keybase5wmilwokqirssclfnsqrjdsi7jdir5wy7y7iu3tanwmtp6oid.onion'
zerobin_onion = \ zerobin_onion: str = \
'zerobinftagjpeeebbvyzjcqyjpmjvynj5qlexwyxe7l3vqejxnqv5qd.onion' 'zerobinftagjpeeebbvyzjcqyjpmjvynj5qlexwyxe7l3vqejxnqv5qd.onion'
securedrop_onion = \ securedrop_onion: str = \
'sdolvtfhatvsysc6l34d65ymdwxcujausv7k5jk4cy5ttzhjoi6fzvyd.onion' 'sdolvtfhatvsysc6l34d65ymdwxcujausv7k5jk4cy5ttzhjoi6fzvyd.onion'
# the hell site 🔥 # the hell site 🔥
twitter_onion = \ twitter_onion: str = \
'twitter3e4tixl4xyajtrzo62zg5vztmjuricljdp2c5kshju4avyoid.onion' 'twitter3e4tixl4xyajtrzo62zg5vztmjuricljdp2c5kshju4avyoid.onion'
onion_domains = { onion_domains: dict = {
"bbc.com": bbc_onion, "bbc.com": bbc_onion,
"bbc.co.uk": bbc_onion, "bbc.co.uk": bbc_onion,
"theguardian.com": guardian_onion, "theguardian.com": guardian_onion,
@ -2122,7 +2122,7 @@ def _substitute_onion_domains(base_dir: str, content: str) -> str:
"twitter.com": twitter_onion "twitter.com": twitter_onion
} }
onion_domains_filename = data_dir(base_dir) + '/onion_domains.txt' onion_domains_filename: str = data_dir(base_dir) + '/onion_domains.txt'
if is_a_file(onion_domains_filename): if is_a_file(onion_domains_filename):
onion_domains_list: list[str] = \ onion_domains_list: list[str] = \
load_list(onion_domains_filename, load_list(onion_domains_filename,
@ -2130,17 +2130,17 @@ def _substitute_onion_domains(base_dir: str, content: str) -> str:
onion_domains_filename) onion_domains_filename)
if onion_domains_list: if onion_domains_list:
onion_domains = {} onion_domains = {}
separators = (' ', ',', '->') separators: list[str] = (' ', ',', '->')
for line in onion_domains_list: for line in onion_domains_list:
line = line.strip() line: str = line.strip()
if line.startswith('#'): if line.startswith('#'):
continue continue
for sep in separators: for sep in separators:
if sep not in line: if sep not in line:
continue continue
clearnet = line.split(sep, 1)[0].strip() clearnet: str = line.split(sep, 1)[0].strip()
onion1 = line.split(sep, 1)[1].strip() onion1: str = line.split(sep, 1)[1].strip()
onion = remove_eol(onion1) onion: str = remove_eol(onion1)
if clearnet and onion: if clearnet and onion:
onion_domains[clearnet] = onion onion_domains[clearnet] = onion
break break
@ -2157,15 +2157,15 @@ def _add_dogwhistle_warnings(summary: str, content: str,
""" """
if not dogwhistles: if not dogwhistles:
return summary return summary
content_str = str(summary) + ' ' + content content_str: str = str(summary) + ' ' + content
detected = detect_dogwhistles(content_str, dogwhistles) detected: dict = detect_dogwhistles(content_str, dogwhistles)
if not detected: if not detected:
return summary return summary
for _, item in detected.items(): for _, item in detected.items():
if not item.get('category'): if not item.get('category'):
continue continue
whistle_str = item['category'] whistle_str: str = item['category']
if translate.get(whistle_str): if translate.get(whistle_str):
whistle_str = translate[whistle_str] whistle_str = translate[whistle_str]
if summary: if summary:
@ -2185,13 +2185,15 @@ def _get_content_license(post_json_object: {}) -> str:
return None return None
if post_json_object['object'].get('schema:license'): if post_json_object['object'].get('schema:license'):
value = post_json_object['object']['schema:license'] value: str = post_json_object['object']['schema:license']
if isinstance(value, str):
if '://' not in value: if '://' not in value:
value = license_link_from_name(value) value = license_link_from_name(value)
return value return value
if post_json_object['object'].get('license'): if post_json_object['object'].get('license'):
value = post_json_object['object']['license'] value: str = post_json_object['object']['license']
if isinstance(value, str):
if '://' not in value: if '://' not in value:
value = license_link_from_name(value) value = license_link_from_name(value)
return value return value
@ -2200,16 +2202,21 @@ def _get_content_license(post_json_object: {}) -> str:
for item in post_attachments: for item in post_attachments:
if not item.get('name'): if not item.get('name'):
continue continue
if not isinstance(item['name'], str):
continue
name_lower = item['name'].lower() name_lower = item['name'].lower()
if 'license' not in name_lower and \ if 'license' not in name_lower and \
'copyright' not in name_lower and \ 'copyright' not in name_lower and \
'licence' not in name_lower: 'licence' not in name_lower:
continue continue
value: str = None
if item.get('value'): if item.get('value'):
if isinstance(item['value'], str):
value = remove_html(item['value']) value = remove_html(item['value'])
elif item.get('href'): elif item.get('href'):
if isinstance(item['href'], str):
value = remove_html(item['href']) value = remove_html(item['href'])
else: if not value:
continue continue
if '://' not in value: if '://' not in value:
value = license_link_from_name(value) value = license_link_from_name(value)
@ -2222,7 +2229,7 @@ def _get_copyright_footer(content_license_url: str,
"""Returns the footer copyright link """Returns the footer copyright link
""" """
# show the CC symbol # show the CC symbol
icon_filename = 'license_cc.png' icon_filename: str = 'license_cc.png'
if '/zero/' in content_license_url: if '/zero/' in content_license_url:
icon_filename = 'license_cc0.png' icon_filename = 'license_cc0.png'
elif 'unlicense' in content_license_url: elif 'unlicense' in content_license_url:
@ -2232,10 +2239,11 @@ def _get_copyright_footer(content_license_url: str,
elif '/fdl' in content_license_url: elif '/fdl' in content_license_url:
icon_filename = 'license_fdl.png' icon_filename = 'license_fdl.png'
description = 'Content License' description: str = 'Content License'
if translate.get('Content License'): if translate.get('Content License'):
description = translate['Content License'] description = translate['Content License']
copyright_str = \
copyright_str: str = \
' ' + \ ' ' + \
'<a class="imageAnchor" href="' + content_license_url + \ '<a class="imageAnchor" href="' + content_license_url + \
'" title="' + description + '" tabindex="10" rel="license">' + \ '" title="' + description + '" tabindex="10" rel="license">' + \
@ -2251,8 +2259,8 @@ def _get_buy_footer(buy_links: {}, translate: {}) -> str:
""" """
if not buy_links: if not buy_links:
return '' return ''
icon_filename = 'buy.png' icon_filename: str = 'buy.png'
description = translate['Buy'] description: str = translate['Buy']
buy_str: str = '' buy_str: str = ''
for _, buy_url in buy_links.items(): for _, buy_url in buy_links.items():
buy_str = \ buy_str = \
@ -2269,7 +2277,7 @@ def _get_buy_footer(buy_links: {}, translate: {}) -> str:
def remove_incomplete_code_tags(content: str) -> str: def remove_incomplete_code_tags(content: str) -> str:
"""Remove any uncompleted code tags """Remove any uncompleted code tags
""" """
tags = ('code', 'pre') tags: list[str] = ('code', 'pre')
for tag_name in tags: for tag_name in tags:
if '<' + tag_name not in content and \ if '<' + tag_name not in content and \
'</' + tag_name not in content: '</' + tag_name not in content:
@ -3516,7 +3524,7 @@ def html_individual_post(recent_posts_cache: {}, max_recent_posts: int,
block_nostr: {}) -> str: block_nostr: {}) -> str:
"""Show an individual post as html """Show an individual post as html
""" """
original_post_json = post_json_object original_post_json: dict = post_json_object
post_str: str = '' post_str: str = ''
by_str: str = '' by_str: str = ''
by_text: str = '' by_text: str = ''
@ -3616,10 +3624,10 @@ def html_individual_post(recent_posts_cache: {}, max_recent_posts: int,
block_government, block_government,
block_bluesky, block_bluesky,
block_nostr) block_nostr)
message_id = remove_id_ending(post_json_object['id']) message_id: str = remove_id_ending(post_json_object['id'])
# show the previous posts # show the previous posts
obj = post_json_object obj: dict = post_json_object
if has_object_dict(post_json_object): if has_object_dict(post_json_object):
obj = post_json_object['object'] obj = post_json_object['object']
post_id = True post_id = True
@ -3722,13 +3730,14 @@ def html_individual_post(recent_posts_cache: {}, max_recent_posts: int,
block_government, block_government,
block_bluesky, block_bluesky,
block_nostr) block_nostr)
css_filename = base_dir + '/epicyon-profile.css' css_filename: str = base_dir + '/epicyon-profile.css'
if is_a_file(base_dir + '/epicyon.css'): if is_a_file(base_dir + '/epicyon.css'):
css_filename = base_dir + '/epicyon.css' css_filename = base_dir + '/epicyon.css'
instance_title = \ instance_title: str = \
get_config_param(base_dir, 'instanceTitle') get_config_param(base_dir, 'instanceTitle')
metadata_str = _html_post_metadata_open_graph(domain, original_post_json, metadata_str: str = \
_html_post_metadata_open_graph(domain, original_post_json,
system_language) system_language)
if post_json_object.get('id'): if post_json_object.get('id'):
# https://swicg.github.io/activitypub-html-discovery/#html-link-element # https://swicg.github.io/activitypub-html-discovery/#html-link-element
@ -3741,7 +3750,7 @@ def html_individual_post(recent_posts_cache: {}, max_recent_posts: int,
# activitypub-html-discovery/#discovering-author-html # activitypub-html-discovery/#discovering-author-html
# link to the author's actor # link to the author's actor
if obj.get('attributedTo'): if obj.get('attributedTo'):
actor = get_attributed_to(obj['attributedTo']) actor: str = get_attributed_to(obj['attributedTo'])
if actor: if actor:
metadata_str += \ metadata_str += \
' <link rel="author" ' + \ ' <link rel="author" ' + \
@ -3821,14 +3830,14 @@ def html_post_replies(recent_posts_cache: {}, max_recent_posts: int,
block_bluesky, block_bluesky,
block_nostr) block_nostr)
css_filename = base_dir + '/epicyon-profile.css' css_filename: str = base_dir + '/epicyon-profile.css'
if is_a_file(base_dir + '/epicyon.css'): if is_a_file(base_dir + '/epicyon.css'):
css_filename = base_dir + '/epicyon.css' css_filename = base_dir + '/epicyon.css'
instance_title = get_config_param(base_dir, 'instanceTitle') instance_title: str = get_config_param(base_dir, 'instanceTitle')
metadata: str = '' metadata: str = ''
preload_images: list[str] = [] preload_images: list[str] = []
header_str = \ header_str: str = \
html_header_with_external_style(css_filename, instance_title, metadata, html_header_with_external_style(css_filename, instance_title, metadata,
preload_images) preload_images)
return header_str + replies_str + html_footer() return header_str + replies_str + html_footer()
@ -3867,7 +3876,8 @@ def html_emoji_reaction_picker(recent_posts_cache: {}, max_recent_posts: int,
if nickname in min_images_for_accounts: if nickname in min_images_for_accounts:
minimize_all_images = True minimize_all_images = True
# get the list of mutuals for the current account # get the list of mutuals for the current account
mutuals_list = get_mutuals_of_person(base_dir, nickname, domain) mutuals_list: list[str] = \
get_mutuals_of_person(base_dir, nickname, domain)
reacted_to_post_str = \ reacted_to_post_str = \
'<br><center><label class="followText">' + \ '<br><center><label class="followText">' + \
translate['Select reaction'].title() + '</label></center>\n' + \ translate['Select reaction'].title() + '</label></center>\n' + \
@ -3898,31 +3908,32 @@ def html_emoji_reaction_picker(recent_posts_cache: {}, max_recent_posts: int,
block_bluesky, block_bluesky,
block_nostr) block_nostr)
reactions_filename = base_dir + '/emoji/reactions.json' reactions_filename: str = base_dir + '/emoji/reactions.json'
if not is_a_file(reactions_filename): if not is_a_file(reactions_filename):
reactions_filename = base_dir + '/emoji/default_reactions.json' reactions_filename = base_dir + '/emoji/default_reactions.json'
reactions_json = load_json(reactions_filename) reactions_json: dict = load_json(reactions_filename)
emoji_picks_str: str = '' emoji_picks_str: str = ''
base_url = '/users/' + nickname base_url: str = '/users/' + nickname
post_id = remove_id_ending(post_json_object['id']) post_id: str = remove_id_ending(post_json_object['id'])
actor_url = get_actor_from_post(post_json_object) actor_url: str = get_actor_from_post(post_json_object)
for _, item in reactions_json.items(): for _, item in reactions_json.items():
emoji_picks_str += '<div class="container">\n' emoji_picks_str += '<div class="container">\n'
for emoji_content in item: for emoji_content in item:
emoji_content_encoded = urllib.parse.quote_plus(emoji_content) emoji_content_encoded = urllib.parse.quote_plus(emoji_content)
emoji_url = \ emoji_url: str = \
base_url + '?react=' + post_id + \ base_url + '?react=' + post_id + \
'?actor=' + actor_url + \ '?actor=' + actor_url + \
'?tl=' + box_name + \ '?tl=' + box_name + \
'?page=' + str(page_number) + \ '?page=' + str(page_number) + \
'?emojreact=' + emoji_content_encoded '?emojreact=' + emoji_content_encoded
emoji_label = '<label class="rlab">' + emoji_content + '</label>' emoji_label: str = \
'<label class="rlab">' + emoji_content + '</label>'
emoji_picks_str += \ emoji_picks_str += \
' <a href="' + emoji_url + '" tabindex="10">' + \ ' <a href="' + emoji_url + '" tabindex="10">' + \
emoji_label + '</a>\n' emoji_label + '</a>\n'
emoji_picks_str += '</div>\n' emoji_picks_str += '</div>\n'
css_filename = base_dir + '/epicyon-profile.css' css_filename: str = base_dir + '/epicyon-profile.css'
if is_a_file(base_dir + '/epicyon.css'): if is_a_file(base_dir + '/epicyon.css'):
css_filename = base_dir + '/epicyon.css' css_filename = base_dir + '/epicyon.css'
@ -3930,10 +3941,10 @@ def html_emoji_reaction_picker(recent_posts_cache: {}, max_recent_posts: int,
banner_file, _ = \ banner_file, _ = \
get_banner_file(base_dir, nickname, domain, theme_name) get_banner_file(base_dir, nickname, domain, theme_name)
instance_title = get_config_param(base_dir, 'instanceTitle') instance_title: str = get_config_param(base_dir, 'instanceTitle')
metadata: str = '' metadata: str = ''
preload_images: list[str] = [] preload_images: list[str] = []
header_str = \ header_str: str = \
html_header_with_external_style(css_filename, instance_title, metadata, html_header_with_external_style(css_filename, instance_title, metadata,
preload_images) preload_images)