Show labels on profiles

main
bashrc 2026-08-21 13:20:03 +01:00
parent 02b1df6f73
commit bd39240b87
5 changed files with 106 additions and 7 deletions

View File

@ -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)

View File

@ -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

View File

@ -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 += \
' <p class="imText">' + status_str + ': ' + \
remove_html(status) + '</p>\n'
options_str += labels_list_html(labels_list)
if pronouns:
options_str += \
' <p class="imText">' + translate['Pronouns'] + \

View File

@ -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 += \
' <b>' + occupation_name + '</b><br>\n'
labels_str = labels_list_html(labels_list)
html_str += ' <h1>' + display_name + '\n</h1>\n'
if premium:
@ -821,7 +828,7 @@ def _get_profile_header(base_dir: str, http_prefix: str, nickname: str,
if pronouns:
html_str += ' ' + pronouns + '<br><br>\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 += '</p>\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

View File

@ -2563,3 +2563,25 @@ def get_display_name_prefix(actor_type: str,
nickname in chatbot_nicknames()):
display_name_prefix = '<b>[' + translate['Bot'] + ']</b> '
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 += '<mark>' + label + '</mark>'
else:
labels_str += '<mark><a href="' + label_url + \
'" target="_blank" rel="nofollow noopener noreferrer">' + \
label + '</a></mark>'
if labels_str:
labels_str = '<p>' + labels_str + '</p>\n'
return labels_str