Merge branch 'main' of gitlab.com:bashrc2/epicyon

merge-requests/30/head
Bob Mottram 2022-03-02 14:32:47 +00:00
commit 1565cc8856
22 changed files with 218 additions and 34 deletions

View File

@ -9,6 +9,7 @@ __module_group__ = "ActivityPub"
from utils import has_object_string_object from utils import has_object_string_object
from utils import has_group_type from utils import has_group_type
from utils import has_object_dict
from utils import remove_domain_port from utils import remove_domain_port
from utils import remove_id_ending from utils import remove_id_ending
from utils import has_users_path from utils import has_users_path
@ -33,6 +34,22 @@ from webfinger import webfinger_handle
from auth import create_basic_auth_header from auth import create_basic_auth_header
def no_of_announces(post_json_object: {}) -> int:
"""Returns the number of announces on a given post
"""
obj = post_json_object
if has_object_dict(post_json_object):
obj = post_json_object['object']
if not obj.get('shares'):
return 0
if not isinstance(obj['shares'], dict):
return 0
if not obj['shares'].get('items'):
obj['shares']['items'] = []
obj['shares']['totalItems'] = 0
return len(obj['shares']['items'])
def is_self_announce(post_json_object: {}) -> bool: def is_self_announce(post_json_object: {}) -> bool:
"""Is the given post a self announce? """Is the given post a self announce?
""" """

View File

@ -34,18 +34,18 @@ def _remove_person_from_cache(base_dir: str, person_url: str,
def check_for_changed_actor(session, base_dir: str, def check_for_changed_actor(session, base_dir: str,
http_prefix: str, domain_full: str, http_prefix: str, domain_full: str,
person_url: str, avatarUrl: str, person_cache: {}, person_url: str, avatar_url: str, person_cache: {},
timeout_sec: int): timeout_sec: int):
"""Checks if the avatar url exists and if not then """Checks if the avatar url exists and if not then
the actor has probably changed without receiving an actor/Person Update. the actor has probably changed without receiving an actor/Person Update.
So clear the actor from the cache and it will be refreshed when the next So clear the actor from the cache and it will be refreshed when the next
post from them is sent post from them is sent
""" """
if not session or not avatarUrl: if not session or not avatar_url:
return return
if domain_full in avatarUrl: if domain_full in avatar_url:
return return
if url_exists(session, avatarUrl, timeout_sec, http_prefix, domain_full): if url_exists(session, avatar_url, timeout_sec, http_prefix, domain_full):
return return
_remove_person_from_cache(base_dir, person_url, person_cache) _remove_person_from_cache(base_dir, person_url, person_cache)

View File

@ -7427,8 +7427,12 @@ class PubServer(BaseHTTPRequestHandler):
page_number = 1 page_number = 1
options_list = options_str.split(';') options_list = options_str.split(';')
options_actor = options_list[0] options_actor = options_list[0]
options_page_number = options_list[1] options_page_number = 1
options_profile_url = options_list[2] if len(options_list) > 1:
options_page_number = options_list[1]
options_profile_url = ''
if len(options_list) > 2:
options_profile_url = options_list[2]
if '.' in options_profile_url and \ if '.' in options_profile_url and \
options_profile_url.startswith('/members/'): options_profile_url.startswith('/members/'):
ext = options_profile_url.split('.')[-1] ext = options_profile_url.split('.')[-1]
@ -10482,6 +10486,68 @@ class PubServer(BaseHTTPRequestHandler):
self.server.debug) self.server.debug)
return True return True
def _show_announcers_of_post(self, authorized: bool,
calling_domain: str, path: str,
base_dir: str, http_prefix: str,
domain: str, domain_full: str, port: int,
onion_domain: str, i2p_domain: str,
getreq_start_time,
proxy_type: str, cookie: str,
debug: str) -> bool:
"""Show the announcers of a post
"""
if not authorized:
return False
if '?announcers=' not in path:
return False
if '/users/' not in path:
return False
nickname = path.split('/users/')[1]
if '?' in nickname:
nickname = nickname.split('?')[0]
post_url = path.split('?announcers=')[1]
if '?' in post_url:
post_url = post_url.split('?')[0]
post_url = post_url.replace('--', '/')
# note that the likers function is reused, but with 'shares'
msg = \
html_likers_of_post(base_dir, nickname, domain, port,
post_url, self.server.translate,
http_prefix,
self.server.theme_name,
self.server.access_keys,
self.server.recent_posts_cache,
self.server.max_recent_posts,
self.server.session,
self.server.cached_webfingers,
self.server.person_cache,
self.server.project_version,
self.server.yt_replace_domain,
self.server.twitter_replacement_domain,
self.server.show_published_date_only,
self.server.peertube_instances,
self.server.allow_local_network_access,
self.server.system_language,
self.server.max_like_count,
self.server.signing_priv_key_pem,
self.server.cw_lists,
self.server.lists_enabled,
'inbox', self.server.default_timeline,
'shares')
if not msg:
self._404()
return True
msg = msg.encode('utf-8')
msglen = len(msg)
self._set_headers('text/html', msglen,
cookie, calling_domain, False)
self._write(msg)
fitness_performance(getreq_start_time, self.server.fitness,
'_GET', '_show_announcers_of_post',
self.server.debug)
return True
def _show_post_from_file(self, post_filename: str, liked_by: str, def _show_post_from_file(self, post_filename: str, liked_by: str,
react_by: str, react_emoji: str, react_by: str, react_emoji: str,
authorized: bool, authorized: bool,
@ -16564,6 +16630,22 @@ class PubServer(BaseHTTPRequestHandler):
self.server.getreq_busy = False self.server.getreq_busy = False
return return
# show the announcers/repeaters of a post
if self._show_announcers_of_post(authorized,
calling_domain, self.path,
self.server.base_dir,
self.server.http_prefix,
self.server.domain,
self.server.domain_full,
self.server.port,
self.server.onion_domain,
self.server.i2p_domain,
getreq_start_time,
self.server.proxy_type,
cookie, self.server.debug):
self.server.getreq_busy = False
return
fitness_performance(getreq_start_time, self.server.fitness, fitness_performance(getreq_start_time, self.server.fitness,
'_GET', 'individual post done', '_GET', 'individual post done',
self.server.debug) self.server.debug)

View File

@ -512,5 +512,7 @@
"Created": "مخلوق", "Created": "مخلوق",
"It is done": "تم", "It is done": "تم",
"Time Zone": "وحدة زمنية", "Time Zone": "وحدة زمنية",
"Show who liked this post": "أظهر من أحب هذا المنشور" "Show who liked this post": "أظهر من أحب هذا المنشور",
"Show who repeated this post": "أظهر من كرر هذا المنصب",
"Repeated by": "يتكرر بواسطة"
} }

View File

@ -512,5 +512,7 @@
"Created": "Creat", "Created": "Creat",
"It is done": "Esta fet", "It is done": "Esta fet",
"Time Zone": "Fus horari", "Time Zone": "Fus horari",
"Show who liked this post": "Mostra a qui li agrada aquesta publicació" "Show who liked this post": "Mostra a qui li agrada aquesta publicació",
"Show who repeated this post": "Mostra qui ha repetit aquesta publicació",
"Repeated by": "Repetit per"
} }

View File

@ -512,5 +512,7 @@
"Created": "Wedi creu", "Created": "Wedi creu",
"It is done": "Mae'n cael ei wneud", "It is done": "Mae'n cael ei wneud",
"Time Zone": "Parth Amser", "Time Zone": "Parth Amser",
"Show who liked this post": "Dangoswch pwy oedd yn hoffi'r post hwn" "Show who liked this post": "Dangoswch pwy oedd yn hoffi'r post hwn",
"Show who repeated this post": "Dangoswch pwy ailadroddodd y post hwn",
"Repeated by": "Ailadrodd gan"
} }

View File

@ -512,5 +512,7 @@
"Created": "Erstellt", "Created": "Erstellt",
"It is done": "Es ist vollbracht", "It is done": "Es ist vollbracht",
"Time Zone": "Zeitzone", "Time Zone": "Zeitzone",
"Show who liked this post": "Zeigen, wem dieser Beitrag gefallen hat" "Show who liked this post": "Zeigen, wem dieser Beitrag gefallen hat",
"Show who repeated this post": "Zeigen Sie, wer diesen Beitrag wiederholt hat",
"Repeated by": "Wiederholt von"
} }

View File

@ -512,5 +512,7 @@
"Created": "Created", "Created": "Created",
"It is done": "It is done", "It is done": "It is done",
"Time Zone": "Time Zone", "Time Zone": "Time Zone",
"Show who liked this post": "Show who liked this post" "Show who liked this post": "Show who liked this post",
"Show who repeated this post": "Show who repeated this post",
"Repeated by": "Repeated by"
} }

View File

@ -512,5 +512,7 @@
"Created": "Creada", "Created": "Creada",
"It is done": "Se hace", "It is done": "Se hace",
"Time Zone": "Zona horaria", "Time Zone": "Zona horaria",
"Show who liked this post": "Mostrar a quién le gustó esta publicación" "Show who liked this post": "Mostrar a quién le gustó esta publicación",
"Show who repeated this post": "Mostrar quién repitió esta publicación",
"Repeated by": "Repetido por"
} }

View File

@ -512,5 +512,7 @@
"Created": "Créé", "Created": "Créé",
"It is done": "C'est fait", "It is done": "C'est fait",
"Time Zone": "Fuseau horaire", "Time Zone": "Fuseau horaire",
"Show who liked this post": "Montrer qui a aimé ce post" "Show who liked this post": "Montrer qui a aimé ce post",
"Show who repeated this post": "Montrer qui a répété ce post",
"Repeated by": "Répété par"
} }

View File

@ -512,5 +512,7 @@
"Created": "Cruthaithe", "Created": "Cruthaithe",
"It is done": "Déantar é", "It is done": "Déantar é",
"Time Zone": "Crios Ama", "Time Zone": "Crios Ama",
"Show who liked this post": "Taispeáin cé a thaitin an postáil seo" "Show who liked this post": "Taispeáin cé a thaitin an postáil seo",
"Show who repeated this post": "Taispeáin cé a rinne an postáil seo arís",
"Repeated by": "Arís agus arís eile ag"
} }

View File

@ -512,5 +512,7 @@
"Created": "बनाया था", "Created": "बनाया था",
"It is done": "हो गया है", "It is done": "हो गया है",
"Time Zone": "समय क्षेत्र", "Time Zone": "समय क्षेत्र",
"Show who liked this post": "दिखाएँ कि इस पोस्ट को किसने पसंद किया" "Show who liked this post": "दिखाएँ कि इस पोस्ट को किसने पसंद किया",
"Show who repeated this post": "दिखाएं कि इस पोस्ट को किसने दोहराया",
"Repeated by": "द्वारा दोहराया गया"
} }

View File

@ -512,5 +512,7 @@
"Created": "Creata", "Created": "Creata",
"It is done": "È fatta", "It is done": "È fatta",
"Time Zone": "Fuso orario", "Time Zone": "Fuso orario",
"Show who liked this post": "Mostra a chi è piaciuto questo post" "Show who liked this post": "Mostra a chi è piaciuto questo post",
"Show who repeated this post": "Mostra chi ha ripetuto questo post",
"Repeated by": "Ripetuto da"
} }

View File

@ -512,5 +512,7 @@
"Created": "作成した", "Created": "作成した",
"It is done": "されております", "It is done": "されております",
"Time Zone": "タイムゾーン", "Time Zone": "タイムゾーン",
"Show who liked this post": "この投稿を高く評価した人を表示する" "Show who liked this post": "この投稿を高く評価した人を表示する",
"Show who repeated this post": "この投稿を繰り返した人を表示する",
"Repeated by": "によって繰り返される"
} }

View File

@ -512,5 +512,7 @@
"Created": "Afirandin", "Created": "Afirandin",
"It is done": "Tê kirin", "It is done": "Tê kirin",
"Time Zone": "Qada demê", "Time Zone": "Qada demê",
"Show who liked this post": "Nîşan bide kê ev post eciband" "Show who liked this post": "Nîşan bide kê ev post eciband",
"Show who repeated this post": "Nîşan bide kê ev post dubare kiriye",
"Repeated by": "Ji hêla dubare kirin"
} }

View File

@ -508,5 +508,7 @@
"Created": "Created", "Created": "Created",
"It is done": "It is done", "It is done": "It is done",
"Time Zone": "Time Zone", "Time Zone": "Time Zone",
"Show who liked this post": "Show who liked this post" "Show who liked this post": "Show who liked this post",
"Show who repeated this post": "Show who repeated this post",
"Repeated by": "Repeated by"
} }

View File

@ -512,5 +512,7 @@
"Created": "Criada", "Created": "Criada",
"It is done": "Está feito", "It is done": "Está feito",
"Time Zone": "Fuso horário", "Time Zone": "Fuso horário",
"Show who liked this post": "Mostrar quem gostou deste post" "Show who liked this post": "Mostrar quem gostou deste post",
"Show who repeated this post": "Mostrar quem repetiu esta postagem",
"Repeated by": "Repetido por"
} }

View File

@ -512,5 +512,7 @@
"Created": "Созданный", "Created": "Созданный",
"It is done": "Сделано", "It is done": "Сделано",
"Time Zone": "Часовой пояс", "Time Zone": "Часовой пояс",
"Show who liked this post": "Показать, кому понравился этот пост" "Show who liked this post": "Показать, кому понравился этот пост",
"Show who repeated this post": "Показать, кто повторил этот пост",
"Repeated by": "Повторено"
} }

View File

@ -512,5 +512,7 @@
"Created": "Imeundwa", "Created": "Imeundwa",
"It is done": "Imefanyika", "It is done": "Imefanyika",
"Time Zone": "Eneo la Saa", "Time Zone": "Eneo la Saa",
"Show who liked this post": "Onyesha ni nani aliyependa chapisho hili" "Show who liked this post": "Onyesha ni nani aliyependa chapisho hili",
"Show who repeated this post": "Onyesha ni nani aliyerudia chapisho hili",
"Repeated by": "Imerudiwa na"
} }

View File

@ -512,5 +512,7 @@
"Created": "已创建", "Created": "已创建",
"It is done": "完成了", "It is done": "完成了",
"Time Zone": "时区", "Time Zone": "时区",
"Show who liked this post": "显示谁喜欢这篇文章" "Show who liked this post": "显示谁喜欢这篇文章",
"Show who repeated this post": "显示谁重复了这篇文章",
"Repeated by": "重复"
} }

View File

@ -15,9 +15,11 @@ from utils import get_display_name
from utils import get_nickname_from_actor from utils import get_nickname_from_actor
from utils import has_object_dict from utils import has_object_dict
from utils import load_json from utils import load_json
from person import get_person_avatar_url
from webapp_utils import html_header_with_external_style from webapp_utils import html_header_with_external_style
from webapp_utils import html_footer from webapp_utils import html_footer
from webapp_utils import get_banner_file from webapp_utils import get_banner_file
from webapp_utils import add_emoji_to_display_name
from webapp_post import individual_post_as_html from webapp_post import individual_post_as_html
@ -38,7 +40,8 @@ def html_likers_of_post(base_dir: str, nickname: str,
system_language: str, system_language: str,
max_like_count: int, signing_priv_key_pem: str, max_like_count: int, signing_priv_key_pem: str,
cw_lists: {}, lists_enabled: str, cw_lists: {}, lists_enabled: str,
boxName: str, default_timeline: str) -> str: boxName: str, default_timeline: str,
dict_name: str = 'likes') -> str:
"""Returns html for a screen showing who liked a post """Returns html for a screen showing who liked a post
""" """
css_filename = base_dir + '/epicyon-profile.css' css_filename = base_dir + '/epicyon-profile.css'
@ -105,17 +108,22 @@ def html_likers_of_post(base_dir: str, nickname: str,
obj = post_json_object obj = 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']
if not obj.get('likes'): if not obj.get(dict_name):
return None return None
if not isinstance(obj['likes'], dict): if not isinstance(obj[dict_name], dict):
return None return None
if not obj['likes'].get('items'): if not obj[dict_name].get('items'):
return None return None
html_str += '<center><h2>' + translate['Liked by'] + '</h2></center>\n' if dict_name == 'likes':
html_str += \
'<center><h2>' + translate['Liked by'] + '</h2></center>\n'
else:
html_str += \
'<center><h2>' + translate['Repeated by'] + '</h2></center>\n'
likers_list = '' likers_list = ''
for like_item in obj['likes']['items']: for like_item in obj[dict_name]['items']:
if not like_item.get('actor'): if not like_item.get('actor'):
continue continue
liker_actor = like_item['actor'] liker_actor = like_item['actor']
@ -123,13 +131,29 @@ def html_likers_of_post(base_dir: str, nickname: str,
get_display_name(base_dir, liker_actor, person_cache) get_display_name(base_dir, liker_actor, person_cache)
if liker_display_name: if liker_display_name:
liker_name = liker_display_name liker_name = liker_display_name
if ':' in liker_name:
liker_name = \
add_emoji_to_display_name(session, base_dir,
http_prefix,
nickname, domain,
liker_name, False)
else: else:
liker_name = get_nickname_from_actor(liker_actor) liker_name = get_nickname_from_actor(liker_actor)
if likers_list: if likers_list:
likers_list += ' ' likers_list += ' '
liker_avatar_url = \
get_person_avatar_url(base_dir, liker_actor,
person_cache, False)
if not liker_avatar_url:
liker_avatar_url = ''
else:
liker_avatar_url = ';' + liker_avatar_url
liker_options_link = \
'/users/' + nickname + '?options=' + \
liker_actor + ';1' + liker_avatar_url
likers_list += \ likers_list += \
'<label class="likerNames">' + \ '<label class="likerNames">' + \
'<a href="' + liker_actor + '">' + liker_name + '</a>' + \ '<a href="' + liker_options_link + '">' + liker_name + '</a>' + \
'</label>' '</label>'
html_str += '<center>\n' + likers_list + '\n</center>\n' html_str += '<center>\n' + likers_list + '\n</center>\n'

View File

@ -16,6 +16,8 @@ from git import is_git_patch
from datetime import datetime from datetime import datetime
from cache import get_person_from_cache from cache import get_person_from_cache
from bookmarks import bookmarked_by_person from bookmarks import bookmarked_by_person
from announce import announced_by_person
from announce import no_of_announces
from like import liked_by_person from like import liked_by_person
from like import no_of_likes from like import no_of_likes
from follow import is_following_actor from follow import is_following_actor
@ -65,7 +67,6 @@ from content import get_mentions_from_html
from content import switch_words from content import switch_words
from person import is_person_snoozed from person import is_person_snoozed
from person import get_person_avatar_url from person import get_person_avatar_url
from announce import announced_by_person
from webapp_utils import get_banner_file from webapp_utils import get_banner_file
from webapp_utils import get_avatar_image_url from webapp_utils import get_avatar_image_url
from webapp_utils import update_avatar_image_cache from webapp_utils import update_avatar_image_cache
@ -549,7 +550,8 @@ def _get_announce_icon_html(is_announced: bool,
translate: {}, translate: {},
page_number_param: str, page_number_param: str,
timeline_post_bookmark: str, timeline_post_bookmark: str,
box_name: str) -> str: box_name: str,
max_announce_count: int) -> str:
"""Returns html for announce icon/button """Returns html for announce icon/button
""" """
announce_str = '' announce_str = ''
@ -571,9 +573,19 @@ def _get_announce_icon_html(is_announced: bool,
repeat_this_post_str = translate[repeat_this_post_str] repeat_this_post_str = translate[repeat_this_post_str]
announce_title = repeat_this_post_str announce_title = repeat_this_post_str
unannounce_link_str = '' unannounce_link_str = ''
announce_count = no_of_announces(post_json_object)
announce_count_str = ''
if announce_count > 0:
if announce_count <= max_announce_count:
announce_count_str = ' (' + str(announce_count) + ')'
else:
announce_count_str = ' (' + str(max_announce_count) + '+)'
if announced_by_person(is_announced, if announced_by_person(is_announced,
post_actor, nickname, domain_full): post_actor, nickname, domain_full):
if announce_count == 1:
# announced by the reader only
announce_count_str = ''
announce_icon = 'repeat.png' announce_icon = 'repeat.png'
announce_emoji = '🔁 ' announce_emoji = '🔁 '
announce_link = 'unrepeat' announce_link = 'unrepeat'
@ -590,9 +602,24 @@ def _get_announce_icon_html(is_announced: bool,
announce_post_id = \ announce_post_id = \
remove_hash_from_post_id(post_json_object['object']['id']) remove_hash_from_post_id(post_json_object['object']['id'])
announce_post_id = remove_id_ending(announce_post_id) announce_post_id = remove_id_ending(announce_post_id)
announce_str = ''
if announce_count_str:
announcers_post_id = announce_post_id.replace('/', '--')
announcers_screen_link = \
'/users/' + nickname + '?announcers=' + announcers_post_id
# show the number of announces next to icon
announce_str += '<label class="likesCount">'
announce_str += '<a href="' + announcers_screen_link + '" ' + \
'title="' + translate['Show who repeated this post'] + '">'
announce_str += \
announce_count_str.replace('(', '').replace(')', '').strip()
announce_str += '</a></label>\n'
announce_link_str = '?' + \ announce_link_str = '?' + \
announce_link + '=' + announce_post_id + page_number_param announce_link + '=' + announce_post_id + page_number_param
announce_str = \ announce_str += \
' <a class="imageAnchor" href="/users/' + \ ' <a class="imageAnchor" href="/users/' + \
nickname + announce_link_str + unannounce_link_str + \ nickname + announce_link_str + unannounce_link_str + \
'?actor=' + post_json_object['actor'] + \ '?actor=' + post_json_object['actor'] + \
@ -1700,7 +1727,7 @@ def individual_post_as_html(signing_priv_key_pem: str,
translate, translate,
page_number_param, page_number_param,
timeline_post_bookmark, timeline_post_bookmark,
box_name) box_name, max_like_count)
_log_post_timing(enable_timing_log, post_start_time, '12') _log_post_timing(enable_timing_log, post_start_time, '12')