diff --git a/src/daemon_utils.py b/src/daemon_utils.py index 4e4f4755c..2e718cb85 100644 --- a/src/daemon_utils.py +++ b/src/daemon_utils.py @@ -28,6 +28,7 @@ from src.posts import add_to_field from src.status import actor_status_expired from src.status import get_actor_status from src.mitm import detect_mitm +from src.utils import get_labels_from_json from src.utils import valid_nickname from src.utils import is_yggdrasil_url from src.utils import data_dir @@ -723,6 +724,7 @@ def show_person_options(self, calling_domain: str, path: str, moved_to: str = '' repo_url = None status = None + labels_list: list[str] = [] actor_json = \ get_person_from_cache(base_dir, options_actor, @@ -775,6 +777,7 @@ def show_person_options(self, calling_domain: str, path: str, also_known_as = remove_html(actor_json['alsoKnownAs']) repo_url = get_repo_url(actor_json) status = get_actor_status(actor_json) + labels_list = get_labels_from_json(actor_json) if status: if actor_status_expired(actor_json['sm:status']): status: str = '' @@ -846,7 +849,8 @@ def show_person_options(self, calling_domain: str, path: str, art_site_url, self.server.mitm_servers, status, - self.server.system_language) + self.server.system_language, + labels_list) if msg: msg = msg.encode('utf-8') msglen = len(msg) diff --git a/src/utils.py b/src/utils.py index a3cdd1acc..68ca0918c 100644 --- a/src/utils.py +++ b/src/utils.py @@ -4454,3 +4454,61 @@ def url_text_to_number(url: str) -> str: """ hash_result = get_sha_256(url) return base64.b64encode(hash_result).decode('utf-8') + + +def get_labels_from_json(json_object: {}) -> []: + """Returns labels attached to an actor or post + """ + tags_list: list[dict] = [] + if 'attachment' in json_object: + if isinstance(json_object['attachment'], list): + tags_list = json_object['attachment'] + obj: dict = json_object + if has_object_dict(json_object): + obj = json_object['object'] + if 'tag' in obj: + if isinstance(obj['tag'], list): + tags_list = obj['tag'] + if not tags_list: + return [] + labels: list[str] = [] + for tag_dict in tags_list: + if not isinstance(tag_dict, dict): + continue + if 'type' not in tag_dict or 'name' not in tag_dict: + continue + if 'value' not in tag_dict or 'href' not in tag_dict: + continue + if not isinstance(tag_dict['type'], str): + continue + if not isinstance(tag_dict['name'], str): + continue + if tag_dict['type'] == 'PropertyValue' and \ + 'value' in tag_dict: + if not isinstance(tag_dict['value'], str): + continue + if tag_dict['name'] == 'Labels': + labels_list = tag_dict['value'].split(',') + for label_str in labels_list: + label_str = label_str.strip() + label_str = remove_html(label_str) + if label_str: + labels.append(label_str) + elif tag_dict['name'] == 'Label': + label_str = tag_dict['value'].strip() + label_str = remove_html(label_str) + if label_str: + if 'href' in tag_dict: + if isinstance(tag_dict['href'], str): + if resembles_url(tag_dict['href']): + label_str += '###' + tag_dict['href'] + labels.append(label_str) + elif tag_dict['type'] == 'Label': + label_str = remove_html(tag_dict['name']) + if label_str: + if 'href' in tag_dict: + if isinstance(tag_dict['href'], str): + if resembles_url(tag_dict['href']): + label_str += '###' + tag_dict['href'] + labels.append(label_str) + return labels diff --git a/src/webapp_person_options.py b/src/webapp_person_options.py index 1dbb43162..142e05b10 100644 --- a/src/webapp_person_options.py +++ b/src/webapp_person_options.py @@ -30,6 +30,7 @@ from src.follow import is_following_actor from src.followingCalendar import receiving_calendar_events from src.notifyOnPost import notify_when_person_posts from src.person import get_person_notes +from src.webapp_utils import labels_list_html from src.webapp_utils import mitm_warning_html from src.webapp_utils import html_header_with_external_style from src.webapp_utils import html_footer @@ -178,7 +179,8 @@ def html_person_options(default_timeline: str, art_site_url: str, mitm_servers: [], status: str, - system_language: str) -> str: + system_language: str, + labels_list: []) -> str: """Show options for a person: view/follow/block/report """ options_link_str: str = '' @@ -414,6 +416,7 @@ def html_person_options(default_timeline: str, options_str += \ '

' + status_str + ': ' + \ remove_html(status) + '

\n' + options_str += labels_list_html(labels_list) if pronouns: options_str += \ '

' + translate['Pronouns'] + \ diff --git a/src/webapp_profile.py b/src/webapp_profile.py index c50ae2f4c..995e94da4 100644 --- a/src/webapp_profile.py +++ b/src/webapp_profile.py @@ -22,6 +22,7 @@ from src.textmode import text_mode_removals from src.unicodetext import uninvert_text from src.unicodetext import standardize_text from src.occupation import get_occupation_name +from src.utils import get_labels_from_json from src.utils import get_preferred_username from src.utils import is_private_browser from src.utils import replace_embedded_map_with_link @@ -103,6 +104,7 @@ from src.follow import get_follower_domains from src.follow import is_following_actor from src.webapp_frontscreen import html_front_screen from src.textmode import text_mode_browser +from src.webapp_utils import labels_list_html from src.webapp_utils import get_display_name_prefix from src.webapp_utils import html_following_dropdown from src.webapp_utils import edit_number_field @@ -397,6 +399,7 @@ def html_profile_after_search(authorized: bool, ricochet_address: str = get_ricochet_address(profile_json) briar_address: str = get_briar_address(profile_json) xmpp_address: str = get_xmpp_address(profile_json) + labels_list: list[str] = get_labels_from_json(profile_json) moved_to: str = '' if profile_json.get('movedTo') or profile_json.get('copiedTo'): @@ -568,7 +571,8 @@ def html_profile_after_search(authorized: bool, youtube, peertube, loops, pixelfed, discord, music_site_url, art_site_url, - donate_url) + donate_url, + labels_list) follow_is_permitted: bool = True if not profile_json.get('followers'): @@ -785,7 +789,8 @@ def _get_profile_header(base_dir: str, http_prefix: str, nickname: str, no_of_books: int, authorized: bool, birth_date: str, - premium: bool) -> str: + premium: bool, + labels_list: []) -> str: """The header of the profile screen, containing background image and avatar """ @@ -812,6 +817,8 @@ def _get_profile_header(base_dir: str, http_prefix: str, nickname: str, occupation_str += \ ' ' + occupation_name + '
\n' + labels_str = labels_list_html(labels_list) + html_str += '

' + display_name + '\n

\n' if premium: @@ -821,7 +828,7 @@ def _get_profile_header(base_dir: str, http_prefix: str, nickname: str, if pronouns: html_str += ' ' + pronouns + '

\n' - html_str += occupation_str + html_str += occupation_str + labels_str # show if the actor is proxied if not actor_proxied: @@ -991,7 +998,8 @@ def _get_profile_header_after_search(base_dir: str, discord: str, music_site_url: str, art_site_url: str, - donate_url: str) -> str: + donate_url: str, + labels_list: []) -> str: """The header of a searched for handle, containing background image and avatar """ @@ -1098,6 +1106,7 @@ def _get_profile_header_after_search(base_dir: str, other_accounts_html += '

\n' if ctr > 0: html_str += other_accounts_html + html_str += labels_list_html(labels_list) if is_valid_date(birth_date): birth_date: str = remove_html(birth_date) html_str += \ @@ -1761,6 +1770,8 @@ def html_profile(signing_priv_key_pem: str, if profile_json.get('vcard:bday'): birth_date = profile_json['vcard:bday'] + labels_list: list[str] = get_labels_from_json(profile_json) + profile_header_str: str = \ _get_profile_header(base_dir, http_prefix, nickname, @@ -1777,7 +1788,8 @@ def html_profile(signing_priv_key_pem: str, occupation_name, actor_proxied, actor, no_of_books, authorized, - birth_date, premium) + birth_date, premium, + labels_list) # keyboard navigation user_path_str: str = '/users/' + nickname diff --git a/src/webapp_utils.py b/src/webapp_utils.py index cbc435ad7..0e4273aa5 100644 --- a/src/webapp_utils.py +++ b/src/webapp_utils.py @@ -2563,3 +2563,25 @@ def get_display_name_prefix(actor_type: str, nickname in chatbot_nicknames()): display_name_prefix = '[' + translate['Bot'] + '] ' return display_name_prefix + + +def labels_list_html(labels_list: []) -> str: + """Returns html for a list of labels for an actor or post + """ + labels_str = '' + for label in labels_list: + label_url = '' + if '###' in label: + label_url = label.split('###')[1] + label = label.split('###')[0] + if labels_str: + labels_str += ' ' + if not label_url: + labels_str += '' + label + '' + else: + labels_str += '' + \ + label + '' + if labels_str: + labels_str = '

' + labels_str + '

\n' + return labels_str