From b8aa529adce7117fb391cfe3526165d7bdb20a54 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 23 Mar 2022 22:43:19 +0000 Subject: [PATCH 01/24] Only show follows status if authorized --- webapp_person_options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp_person_options.py b/webapp_person_options.py index 90867b033..9c2797b55 100644 --- a/webapp_person_options.py +++ b/webapp_person_options.py @@ -151,7 +151,7 @@ def html_person_options(default_timeline: str, options_str += \ '

' + translate['Options for'] + \ ' @' + handle_shown + '

\n' - if follows_you: + if follows_you and authorized: options_str += \ '

' + translate['Follows you'] + '

\n' if moved_to: From aab90e75da469a326a6547a96bfba92055bca86b Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 23 Mar 2022 22:49:37 +0000 Subject: [PATCH 02/24] Check for no domain --- daemon.py | 15 +++++++++------ webapp_person_options.py | 2 ++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/daemon.py b/daemon.py index 1c3d22acb..6c09e26cc 100644 --- a/daemon.py +++ b/daemon.py @@ -7765,12 +7765,15 @@ class PubServer(BaseHTTPRequestHandler): self.server.news_instance, authorized, access_keys, is_group).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_person_options', debug) + if msg: + 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_person_options', debug) + else: + self._404() return if '/users/news/' in path: diff --git a/webapp_person_options.py b/webapp_person_options.py index 9c2797b55..4a78d3a5d 100644 --- a/webapp_person_options.py +++ b/webapp_person_options.py @@ -66,6 +66,8 @@ def html_person_options(default_timeline: str, """Show options for a person: view/follow/block/report """ options_domain, options_port = get_domain_from_actor(options_actor) + if not options_domain: + return None options_domain_full = get_full_domain(options_domain, options_port) if os.path.isfile(base_dir + '/accounts/options-background-custom.jpg'): From f55f7a258f784d5b9e5c4b283f0d4c7c1bf15ebb Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 23 Mar 2022 23:59:29 +0000 Subject: [PATCH 03/24] Handle none return valued from nickname --- announce.py | 15 +-- availability.py | 2 + bookmarks.py | 4 + daemon.py | 215 +++++++++++++++++++++++++++++---------- inbox.py | 18 +++- posts.py | 3 + reaction.py | 2 + skills.py | 2 + utils.py | 6 ++ webapp_calendar.py | 4 + webapp_confirm.py | 30 ++++-- webapp_hashtagswarm.py | 2 + webapp_likers.py | 2 + webapp_moderation.py | 10 ++ webapp_person_options.py | 7 +- webapp_post.py | 17 +++- webapp_profile.py | 2 + webapp_search.py | 2 + webapp_utils.py | 4 + 19 files changed, 266 insertions(+), 81 deletions(-) diff --git a/announce.py b/announce.py index f4c041f93..228295042 100644 --- a/announce.py +++ b/announce.py @@ -187,13 +187,14 @@ def create_announce(session, base_dir: str, federation_list: [], group_account = False if has_users_path(object_url): announce_nickname = get_nickname_from_actor(object_url) - announce_domain, announce_port = get_domain_from_actor(object_url) - if '/' + str(announce_nickname) + '/' in object_url: - announce_actor = \ - object_url.split('/' + announce_nickname + '/')[0] + \ - '/' + announce_nickname - if has_group_type(base_dir, announce_actor, person_cache): - group_account = True + if announce_nickname: + announce_domain, announce_port = get_domain_from_actor(object_url) + if '/' + str(announce_nickname) + '/' in object_url: + announce_actor = \ + object_url.split('/' + announce_nickname + '/')[0] + \ + '/' + announce_nickname + if has_group_type(base_dir, announce_actor, person_cache): + group_account = True if announce_nickname and announce_domain: send_signed_json(new_announce, session, base_dir, diff --git a/availability.py b/availability.py index 4c2528505..fdb913749 100644 --- a/availability.py +++ b/availability.py @@ -68,6 +68,8 @@ def outbox_availability(base_dir: str, nickname: str, message_json: {}, return False actor_nickname = get_nickname_from_actor(message_json['actor']) + if not actor_nickname: + return False if actor_nickname != nickname: return False domain, _ = get_domain_from_actor(message_json['actor']) diff --git a/bookmarks.py b/bookmarks.py index b2399c8d2..5ee5478d9 100644 --- a/bookmarks.py +++ b/bookmarks.py @@ -46,6 +46,8 @@ def undo_bookmarks_collection_entry(recent_posts_cache: {}, # remove any cached version of this post so that the # bookmark icon is changed nickname = get_nickname_from_actor(actor) + if not nickname: + return cached_post_filename = \ get_cached_post_filename(base_dir, nickname, domain, post_json_object) @@ -166,6 +168,8 @@ def update_bookmarks_collection(recent_posts_cache: {}, # remove any cached version of this post so that the # bookmark icon is changed nickname = get_nickname_from_actor(actor) + if not nickname: + return cached_post_filename = \ get_cached_post_filename(base_dir, nickname, domain, post_json_object) diff --git a/daemon.py b/daemon.py index 6c09e26cc..68a00c0dc 100644 --- a/daemon.py +++ b/daemon.py @@ -2195,18 +2195,24 @@ class PubServer(BaseHTTPRequestHandler): if '/@' in search_handle: search_nickname = \ get_nickname_from_actor(search_handle) - search_domain, _ = \ - get_domain_from_actor(search_handle) - search_handle = \ - search_nickname + '@' + search_domain - if '@' not in search_handle: - if search_handle.startswith('http'): - search_nickname = \ - get_nickname_from_actor(search_handle) + if search_nickname: search_domain, _ = \ get_domain_from_actor(search_handle) search_handle = \ search_nickname + '@' + search_domain + else: + search_handle = None + if '@' not in search_handle: + if search_handle.startswith('http'): + search_nickname = \ + get_nickname_from_actor(search_handle) + if search_nickname: + search_domain, _ = \ + get_domain_from_actor(search_handle) + search_handle = \ + search_nickname + '@' + search_domain + else: + search_handle = None if '@' not in search_handle: # is this a local nickname on this instance? local_handle = \ @@ -2234,11 +2240,12 @@ class PubServer(BaseHTTPRequestHandler): self.server.translate, base_dir, http_prefix, nickname) - msg = msg.encode('utf-8') - msglen = len(msg) - self._login_headers('text/html', - msglen, calling_domain) - self._write(msg) + if msg: + msg = msg.encode('utf-8') + msglen = len(msg) + self._login_headers('text/html', + msglen, calling_domain) + self._write(msg) self.server.postreq_busy = False return elif moderation_str.startswith('submitBlock'): @@ -3088,11 +3095,13 @@ class PubServer(BaseHTTPRequestHandler): options_actor, self.server.debug, self.server.system_language, - signing_priv_key_pem).encode('utf-8') - msglen = len(msg) - self._set_headers('text/html', msglen, - cookie, calling_domain, False) - self._write(msg) + signing_priv_key_pem) + if msg: + msg = msg.encode('utf-8') + msglen = len(msg) + self._set_headers('text/html', msglen, + cookie, calling_domain, False) + self._write(msg) self.server.postreq_busy = False return else: @@ -3227,6 +3236,11 @@ class PubServer(BaseHTTPRequestHandler): users_path = path.split('/unfollowconfirm')[0] origin_path_str = http_prefix + '://' + domain_full + users_path follower_nickname = get_nickname_from_actor(origin_path_str) + if not follower_nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return length = int(self.headers['Content-length']) @@ -3257,6 +3271,11 @@ class PubServer(BaseHTTPRequestHandler): if '&' in following_actor: following_actor = following_actor.split('&')[0] following_nickname = get_nickname_from_actor(following_actor) + if not following_nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return following_domain, following_port = \ get_domain_from_actor(following_actor) following_domain_full = \ @@ -3318,6 +3337,11 @@ class PubServer(BaseHTTPRequestHandler): users_path = path.split('/followconfirm')[0] origin_path_str = http_prefix + '://' + domain_full + users_path follower_nickname = get_nickname_from_actor(origin_path_str) + if not follower_nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return length = int(self.headers['Content-length']) @@ -3358,6 +3382,11 @@ class PubServer(BaseHTTPRequestHandler): if '&' in following_actor: following_actor = following_actor.split('&')[0] following_nickname = get_nickname_from_actor(following_actor) + if not following_nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return following_domain, following_port = \ get_domain_from_actor(following_actor) if follower_nickname == following_nickname and \ @@ -3664,6 +3693,12 @@ class PubServer(BaseHTTPRequestHandler): search_str = ':' + search_str + ':' if search_str.startswith('#'): nickname = get_nickname_from_actor(actor_str) + if not nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return + # hashtag search timezone = None if self.server.account_timezone.get(nickname): @@ -3761,6 +3796,11 @@ class PubServer(BaseHTTPRequestHandler): break # your post history search nickname = get_nickname_from_actor(actor_str) + if not nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return search_str = search_str.replace("'", '', 1).strip() timezone = None if self.server.account_timezone.get(nickname): @@ -3834,6 +3874,11 @@ class PubServer(BaseHTTPRequestHandler): break # bookmark search nickname = get_nickname_from_actor(actor_str) + if not nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return search_str = search_str.replace('-', '', 1).strip() timezone = None if self.server.account_timezone.get(nickname): @@ -3890,6 +3935,11 @@ class PubServer(BaseHTTPRequestHandler): return # profile search nickname = get_nickname_from_actor(actor_str) + if not nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return profile_path_str = path.replace('/searchhandle', '') # are we already following the searched for handle? @@ -3897,6 +3947,11 @@ class PubServer(BaseHTTPRequestHandler): # get the actor if not has_users_path(search_str): search_nickname = get_nickname_from_actor(search_str) + if not search_nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return search_domain, search_port = \ get_domain_from_actor(search_str) search_domain_full = \ @@ -4310,6 +4365,11 @@ class PubServer(BaseHTTPRequestHandler): local_actor_url(http_prefix, admin_nickname, domain_full) actor = origin_path_str actor_nickname = get_nickname_from_actor(actor) + if not actor_nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return if actor == share_actor or actor == admin_actor or \ is_moderator(base_dir, actor_nickname): item_id = remove_share_confirm_params.split('itemID=')[1] @@ -4378,6 +4438,11 @@ class PubServer(BaseHTTPRequestHandler): local_actor_url(http_prefix, admin_nickname, domain_full) actor = origin_path_str actor_nickname = get_nickname_from_actor(actor) + if not actor_nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return if actor == share_actor or actor == admin_actor or \ is_moderator(base_dir, actor_nickname): item_id = remove_share_confirm_params.split('itemID=')[1] @@ -4921,6 +4986,9 @@ class PubServer(BaseHTTPRequestHandler): users_path = path.replace('/citationsdata', '') actor_str = self._get_instance_url(calling_domain) + users_path nickname = get_nickname_from_actor(actor_str) + if not nickname: + self.server.postreq_busy = False + return citations_filename = \ acct_dir(base_dir, nickname, domain) + '/.citations.txt' @@ -7764,8 +7832,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.text_mode_banner, self.server.news_instance, authorized, - access_keys, is_group).encode('utf-8') + access_keys, is_group) if msg: + msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, cookie, calling_domain, False) @@ -8547,6 +8616,9 @@ class PubServer(BaseHTTPRequestHandler): following_handle = path.split('/followapprove=')[1] if '://' in following_handle: handle_nickname = get_nickname_from_actor(following_handle) + if not handle_nickname: + self._404() + return handle_domain, handle_port = \ get_domain_from_actor(following_handle) following_handle = \ @@ -8733,6 +8805,9 @@ class PubServer(BaseHTTPRequestHandler): following_handle = path.split('/followdeny=')[1] if '://' in following_handle: handle_nickname = get_nickname_from_actor(following_handle) + if not handle_nickname: + self._404() + return handle_domain, handle_port = \ get_domain_from_actor(following_handle) following_handle = \ @@ -10105,6 +10180,9 @@ class PubServer(BaseHTTPRequestHandler): actor = \ http_prefix + '://' + domain_full + path.split('?mute=')[0] nickname = get_nickname_from_actor(actor) + if not nickname: + self._404() + return mute_post(base_dir, nickname, domain, port, http_prefix, mute_url, self.server.recent_posts_cache, debug) @@ -10226,6 +10304,9 @@ class PubServer(BaseHTTPRequestHandler): actor = \ http_prefix + '://' + domain_full + path.split('?unmute=')[0] nickname = get_nickname_from_actor(actor) + if not nickname: + self._404() + return unmute_post(base_dir, nickname, domain, port, http_prefix, mute_url, self.server.recent_posts_cache, debug) @@ -13817,6 +13898,9 @@ class PubServer(BaseHTTPRequestHandler): """Shows a QR code for an account """ nickname = get_nickname_from_actor(path) + if not nickname: + self._404() + return True if onion_domain: qrcode_domain = onion_domain port = 80 @@ -13866,6 +13950,9 @@ class PubServer(BaseHTTPRequestHandler): """Shows a banner image on the search screen """ nickname = get_nickname_from_actor(path) + if not nickname: + self._404() + return True banner_filename = \ acct_dir(base_dir, nickname, domain) + '/search_banner.png' if not os.path.isfile(banner_filename): @@ -14256,7 +14343,9 @@ class PubServer(BaseHTTPRequestHandler): break if is_new_post_endpoint: nickname = get_nickname_from_actor(path) - + if not nickname: + self._404() + return True if in_reply_to_url: reply_interval_hours = self.server.default_reply_interval_hrs if not can_reply_to(base_dir, nickname, domain, @@ -14403,8 +14492,9 @@ class PubServer(BaseHTTPRequestHandler): access_keys, default_reply_interval_hrs, self.server.cw_lists, - self.server.lists_enabled).encode('utf-8') + self.server.lists_enabled) if msg: + msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, cookie, calling_domain, False) @@ -14436,8 +14526,9 @@ class PubServer(BaseHTTPRequestHandler): port, http_prefix, self.server.default_timeline, - theme, access_keys).encode('utf-8') + theme, access_keys) if msg: + msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, cookie, calling_domain, False) @@ -14470,8 +14561,9 @@ class PubServer(BaseHTTPRequestHandler): http_prefix, self.server.default_timeline, self.server.theme_name, - access_keys).encode('utf-8') + access_keys) if msg: + msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, cookie, calling_domain, False) @@ -15810,6 +15902,9 @@ class PubServer(BaseHTTPRequestHandler): if html_getreq and authorized and users_in_path and \ self.path.endswith('/followingaccounts'): nickname = get_nickname_from_actor(self.path) + if not nickname: + self._404() + return following_filename = \ acct_dir(self.server.base_dir, nickname, self.server.domain) + '/following.txt' @@ -16574,14 +16669,16 @@ class PubServer(BaseHTTPRequestHandler): self.server.default_timeline, self.server.theme_name, self.server.text_mode_banner, - access_keys).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', 'search screen shown', - self.server.debug) + access_keys) + if msg: + 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', 'search screen shown', + self.server.debug) self.server.getreq_busy = False return @@ -16628,20 +16725,24 @@ class PubServer(BaseHTTPRequestHandler): self.server.domain_full, self.server.text_mode_banner, access_keys, - False).encode('utf-8') - msglen = len(msg) - if 'ical=true' in self.path: - self._set_headers('text/calendar', - msglen, cookie, calling_domain, - False) + False) + if msg: + msg = msg.encode('utf-8') + msglen = len(msg) + if 'ical=true' in self.path: + self._set_headers('text/calendar', + msglen, cookie, calling_domain, + False) + else: + self._set_headers('text/html', + msglen, cookie, calling_domain, + False) + self._write(msg) + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', 'calendar shown', + self.server.debug) else: - self._set_headers('text/html', - msglen, cookie, calling_domain, - False) - self._write(msg) - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', 'calendar shown', - self.server.debug) + self._404() self.server.getreq_busy = False return @@ -17213,6 +17314,10 @@ class PubServer(BaseHTTPRequestHandler): if ';' in actor: actor = actor.split(';')[0] nickname = get_nickname_from_actor(self.path.split('?')[0]) + if not nickname: + self._404() + self.server.getreq_busy = False + return if nickname == actor: post_url = \ local_actor_url(self.server.http_prefix, nickname, @@ -17715,11 +17820,12 @@ class PubServer(BaseHTTPRequestHandler): self.server.debug, self.server.system_language, self.server.signing_priv_key_pem) - msg = msg.encode('utf-8') - msglen = len(msg) - self._login_headers('text/html', - msglen, calling_domain) - self._write(msg) + if msg: + msg = msg.encode('utf-8') + msglen = len(msg) + self._login_headers('text/html', + msglen, calling_domain) + self._write(msg) self.server.getreq_busy = False return @@ -17752,11 +17858,12 @@ class PubServer(BaseHTTPRequestHandler): self.server.debug, self.server.system_language, self.server.signing_priv_key_pem) - msg = msg.encode('utf-8') - msglen = len(msg) - self._login_headers('text/html', - msglen, calling_domain) - self._write(msg) + if msg: + msg = msg.encode('utf-8') + msglen = len(msg) + self._login_headers('text/html', + msglen, calling_domain) + self._write(msg) self.server.getreq_busy = False return diff --git a/inbox.py b/inbox.py index 2aeb4df21..b02514e0e 100644 --- a/inbox.py +++ b/inbox.py @@ -1941,6 +1941,9 @@ def _receive_announce(recent_posts_cache: {}, # is the announce actor blocked? nickname = handle.split('@')[0] actor_nickname = get_nickname_from_actor(message_json['actor']) + if not actor_nickname: + print('WARN: _receive_announce no actor_nickname') + return False actor_domain, _ = get_domain_from_actor(message_json['actor']) if is_blocked(base_dir, nickname, domain, actor_nickname, actor_domain): print('Receive announce blocked for actor: ' + @@ -1948,13 +1951,16 @@ def _receive_announce(recent_posts_cache: {}, return False # also check the actor for the url being announced - announcedActorNickname = get_nickname_from_actor(message_json['object']) + announced_actor_nickname = get_nickname_from_actor(message_json['object']) + if not announced_actor_nickname: + print('WARN: _receive_announce no announced_actor_nickname') + return False announcedActorDomain, announcedActorPort = \ get_domain_from_actor(message_json['object']) if is_blocked(base_dir, nickname, domain, - announcedActorNickname, announcedActorDomain): + announced_actor_nickname, announcedActorDomain): print('Receive announce object blocked for actor: ' + - announcedActorNickname + '@' + announcedActorDomain) + announced_actor_nickname + '@' + announcedActorDomain) return False # is this post in the outbox of the person? @@ -2788,6 +2794,8 @@ def _inbox_update_calendar(base_dir: str, handle: str, actor = post_json_object['actor'] actor_nickname = get_nickname_from_actor(actor) + if not actor_nickname: + return actor_domain, _ = get_domain_from_actor(actor) handle_nickname = handle.split('@')[0] handle_domain = handle.split('@')[1] @@ -3254,6 +3262,8 @@ def _low_frequency_post_notification(base_dir: str, http_prefix: str, if not isinstance(attributed_to, str): return from_nickname = get_nickname_from_actor(attributed_to) + if not from_nickname: + return from_domain, from_port = get_domain_from_actor(attributed_to) from_domain_full = get_full_domain(from_domain, from_port) if notify_when_person_posts(base_dir, nickname, domain, @@ -3282,6 +3292,8 @@ def _check_for_git_patches(base_dir: str, nickname: str, domain: str, if not isinstance(attributed_to, str): return 0 from_nickname = get_nickname_from_actor(attributed_to) + if not from_nickname: + return 0 from_domain, from_port = get_domain_from_actor(attributed_to) from_domain_full = get_full_domain(from_domain, from_port) if receive_git_patch(base_dir, nickname, domain, diff --git a/posts.py b/posts.py index 9d43ae88a..18445b70a 100644 --- a/posts.py +++ b/posts.py @@ -4815,6 +4815,9 @@ def download_announce(session, base_dir: str, http_prefix: str, 'Accept': accept_str } actor_nickname = get_nickname_from_actor(post_json_object['actor']) + if not actor_nickname: + print('WARN: download_announce no actor_nickname') + return None actor_domain, actor_port = \ get_domain_from_actor(post_json_object['actor']) if not actor_domain: diff --git a/reaction.py b/reaction.py index e2804c61f..7dc2439b1 100644 --- a/reaction.py +++ b/reaction.py @@ -541,6 +541,8 @@ def html_emoji_reactions(post_json_object: {}, interactive: bool, emoji_content = item['content'] emoji_actor = item['actor'] emoji_nickname = get_nickname_from_actor(emoji_actor) + if not emoji_nickname: + return '' emoji_domain, _ = get_domain_from_actor(emoji_actor) emoji_handle = emoji_nickname + '@' + emoji_domain if emoji_actor == actor: diff --git a/skills.py b/skills.py index b1ac666b1..f7ce6e14e 100644 --- a/skills.py +++ b/skills.py @@ -158,6 +158,8 @@ def outbox_skills(base_dir: str, nickname: str, message_json: {}, return False actor_nickname = get_nickname_from_actor(message_json['actor']) + if not actor_nickname: + return False if actor_nickname != nickname: return False domain, _ = get_domain_from_actor(message_json['actor']) diff --git a/utils.py b/utils.py index 5158ae9b1..1cd72cbe7 100644 --- a/utils.py +++ b/utils.py @@ -2343,6 +2343,8 @@ def undo_likes_collection_entry(recent_posts_cache: {}, # remove any cached version of this post so that the # like icon is changed nickname = get_nickname_from_actor(actor) + if not nickname: + return cached_post_filename = \ get_cached_post_filename(base_dir, nickname, domain, post_json_object) @@ -2409,6 +2411,8 @@ def undo_reaction_collection_entry(recent_posts_cache: {}, # remove any cached version of this post so that the # like icon is changed nickname = get_nickname_from_actor(actor) + if not nickname: + return cached_post_filename = \ get_cached_post_filename(base_dir, nickname, domain, post_json_object) @@ -2476,6 +2480,8 @@ def undo_announce_collection_entry(recent_posts_cache: {}, # remove any cached version of this announce so that the announce # icon is changed nickname = get_nickname_from_actor(actor) + if not nickname: + return cached_post_filename = \ get_cached_post_filename(base_dir, nickname, domain, post_json_object) diff --git a/webapp_calendar.py b/webapp_calendar.py index 576fae8e3..d0901bad9 100644 --- a/webapp_calendar.py +++ b/webapp_calendar.py @@ -42,6 +42,8 @@ def html_calendar_delete_confirm(css_cache: {}, translate: {}, base_dir: str, """Shows a screen asking to confirm the deletion of a calendar event """ nickname = get_nickname_from_actor(path) + if not nickname: + return None actor = local_actor_url(http_prefix, nickname, domain_full) domain, _ = get_domain_from_actor(actor) message_id = actor + '/statuses/' + post_id @@ -304,6 +306,8 @@ def html_calendar(person_cache: {}, css_cache: {}, translate: {}, month_number = curr_date.month nickname = get_nickname_from_actor(actor) + if not nickname: + return '' set_custom_background(base_dir, 'calendar-background', 'calendar-background') diff --git a/webapp_confirm.py b/webapp_confirm.py index 12e32c64e..7b574ae6f 100644 --- a/webapp_confirm.py +++ b/webapp_confirm.py @@ -45,6 +45,8 @@ def html_confirm_delete(css_cache: {}, return None actor = message_id.split('/statuses/')[0] nickname = get_nickname_from_actor(actor) + if not nickname: + return None domain, port = get_domain_from_actor(actor) domain_full = get_full_domain(domain, port) @@ -119,6 +121,8 @@ def html_confirm_remove_shared_item(css_cache: {}, translate: {}, """Shows a screen asking to confirm the removal of a shared item """ nickname = get_nickname_from_actor(actor) + if not nickname: + return None domain, port = get_domain_from_actor(actor) domain_full = get_full_domain(domain, port) shares_file = \ @@ -207,10 +211,11 @@ def html_confirm_follow(css_cache: {}, translate: {}, base_dir: str, follow_str += ' \n' follow_str += \ ' \n' - follow_str += \ - '

' + translate['Follow'] + ' ' + \ - get_nickname_from_actor(follow_actor) + \ - '@' + follow_domain + ' ?

\n' + follow_actor_nick = get_nickname_from_actor(follow_actor) + if follow_actor_nick: + follow_str += \ + '

' + translate['Follow'] + ' ' + \ + follow_actor_nick + '@' + follow_domain + ' ?

\n' follow_str += '
\n' follow_str += ' \n' follow_str += \ ' \n' - follow_str += \ - '

' + translate['Stop following'] + \ - ' ' + get_nickname_from_actor(follow_actor) + \ - '@' + follow_domain + ' ?

\n' + follow_actor_nick = get_nickname_from_actor(follow_actor) + if follow_actor_nick: + follow_str += \ + '

' + translate['Stop following'] + \ + ' ' + follow_actor_nick + '@' + follow_domain + ' ?

\n' follow_str += ' \n' follow_str += ' \n' block_str += \ ' \n' - block_str += \ - '

' + translate['Stop blocking'] + ' ' + \ - get_nickname_from_actor(block_actor) + '@' + block_domain + ' ?

\n' + block_actor_nick = get_nickname_from_actor(block_actor) + if block_actor_nick: + block_str += \ + '

' + translate['Stop blocking'] + ' ' + \ + block_actor_nick + '@' + block_domain + ' ?

\n' block_str += ' \n' block_str += ' \n' options_str += ' \n' - handle = get_nickname_from_actor(options_actor) + '@' + options_domain + handle_nick = get_nickname_from_actor(options_actor) + if not handle_nick: + return None + handle = handle_nick + '@' + options_domain handle_shown = handle if locked_account: handle_shown += '🔒' diff --git a/webapp_post.py b/webapp_post.py index 7c69692a3..526a2a5ec 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -104,11 +104,12 @@ def _html_post_metadata_open_graph(domain: str, post_json_object: {}) -> str: if isinstance(obj_json['attributedTo'], str): attrib = obj_json['attributedTo'] actor_nick = get_nickname_from_actor(attrib) - actor_domain, _ = get_domain_from_actor(attrib) - actor_handle = actor_nick + '@' + actor_domain - metadata += \ - " \n" + if actor_nick: + actor_domain, _ = get_domain_from_actor(attrib) + actor_handle = actor_nick + '@' + actor_domain + metadata += \ + " \n" if obj_json.get('url'): metadata += \ " Date: Thu, 24 Mar 2022 13:14:41 +0000 Subject: [PATCH 04/24] Bold reading accessibility feature --- content.py | 37 ++++++ daemon.py | 260 +++++++++++++++++++++++++++++++++++------- inbox.py | 87 +++++++++----- outbox.py | 6 +- tests.py | 35 ++++++ translations/ar.json | 3 +- translations/ca.json | 3 +- translations/cy.json | 3 +- translations/de.json | 3 +- translations/en.json | 3 +- translations/es.json | 3 +- translations/fr.json | 3 +- translations/ga.json | 3 +- translations/hi.json | 3 +- translations/it.json | 3 +- translations/ja.json | 3 +- translations/ko.json | 3 +- translations/ku.json | 3 +- translations/oc.json | 3 +- translations/pl.json | 3 +- translations/pt.json | 3 +- translations/ru.json | 3 +- translations/sw.json | 3 +- translations/uk.json | 3 +- translations/zh.json | 3 +- utils.py | 18 +++ webapp_confirm.py | 8 +- webapp_create_post.py | 5 +- webapp_frontscreen.py | 10 +- webapp_likers.py | 3 +- webapp_moderation.py | 4 +- webapp_post.py | 30 +++-- webapp_profile.py | 30 +++-- webapp_search.py | 9 +- webapp_timeline.py | 54 +++++---- 35 files changed, 506 insertions(+), 150 deletions(-) diff --git a/content.py b/content.py index 5bebdb0de..c2aad31ac 100644 --- a/content.py +++ b/content.py @@ -1323,3 +1323,40 @@ def contains_invalid_local_links(content: str) -> bool: if '?' + inv_str + '=' in content: return True return False + + +def bold_reading_string(text: str) -> str: + """Returns bold reading formatted text + """ + add_paragraph_markup = False + if '

' in text: + text = text.replace('

', '\n').replace('

', '') + add_paragraph_markup = True + paragraphs = text.split('\n') + parag_ctr = 0 + new_text = '' + for parag in paragraphs: + words = parag.split(' ') + new_parag = '' + for wrd in words: + if len(wrd) > 1 and '<' not in wrd and '>' not in wrd: + initial_chars = int(len(wrd) / 2) + new_parag += \ + '' + wrd[:initial_chars] + '' + \ + wrd[initial_chars:] + ' ' + else: + new_parag += wrd + ' ' + parag_ctr += 1 + new_parag = new_parag.strip() + if parag_ctr < len(paragraphs): + if not add_paragraph_markup: + new_text += new_parag + '\n' + else: + new_text += '

' + new_parag + '

' + else: + if not add_paragraph_markup: + new_text += new_parag + else: + new_text += '

' + new_parag + '

' + + return new_text diff --git a/daemon.py b/daemon.py index 68a00c0dc..22de6d91b 100644 --- a/daemon.py +++ b/daemon.py @@ -283,6 +283,7 @@ from utils import get_occupation_skills from utils import get_occupation_name from utils import set_occupation_name from utils import load_translations_from_file +from utils import load_bold_reading from utils import get_local_network_addresses from utils import decoded_host from utils import is_public_post @@ -3034,6 +3035,11 @@ class PubServer(BaseHTTPRequestHandler): custom_submit_text = get_config_param(base_dir, 'customSubmitText') conversation_id = None reply_is_chat = False + + bold_reading = False + if self.server.bold_reading(chooser_nickname): + bold_reading = True + msg = html_new_post(self.server.css_cache, False, self.server.translate, base_dir, @@ -3069,7 +3075,8 @@ class PubServer(BaseHTTPRequestHandler): self.server.cw_lists, self.server.lists_enabled, self.server.default_timeline, - reply_is_chat).encode('utf-8') + reply_is_chat, + bold_reading).encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, cookie, calling_domain, False) @@ -3173,6 +3180,11 @@ class PubServer(BaseHTTPRequestHandler): custom_submit_text = get_config_param(base_dir, 'customSubmitText') conversation_id = None reply_is_chat = False + + bold_reading = False + if self.server.bold_reading.get(chooser_nickname): + bold_reading = True + msg = html_new_post(self.server.css_cache, False, self.server.translate, base_dir, @@ -3207,7 +3219,8 @@ class PubServer(BaseHTTPRequestHandler): self.server.cw_lists, self.server.lists_enabled, self.server.default_timeline, - reply_is_chat).encode('utf-8') + reply_is_chat, + bold_reading).encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, cookie, calling_domain, False) @@ -3704,6 +3717,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading(nickname): + bold_reading = True hashtag_str = \ html_hashtag_search(self.server.css_cache, nickname, domain, port, @@ -3729,7 +3745,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) if hashtag_str: msg = hashtag_str.encode('utf-8') msglen = len(msg) @@ -3806,6 +3822,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading(nickname): + bold_reading = True history_str = \ html_history_search(self.server.css_cache, self.server.translate, @@ -3834,7 +3853,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) if history_str: msg = history_str.encode('utf-8') msglen = len(msg) @@ -3884,6 +3903,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True bookmarks_str = \ html_history_search(self.server.css_cache, self.server.translate, @@ -3912,7 +3934,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) if bookmarks_str: msg = bookmarks_str.encode('utf-8') msglen = len(msg) @@ -4046,6 +4068,10 @@ class PubServer(BaseHTTPRequestHandler): self.server.postreq_busy = False return + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True + profile_str = \ html_profile_after_search(self.server.css_cache, recent_posts_cache, @@ -4078,7 +4104,8 @@ class PubServer(BaseHTTPRequestHandler): self.server.lists_enabled, timezone, self.server.onion_domain, - self.server.i2p_domain) + self.server.i2p_domain, + bold_reading) if profile_str: msg = profile_str.encode('utf-8') msglen = len(msg) @@ -6655,6 +6682,33 @@ class PubServer(BaseHTTPRequestHandler): 'unable to delete ' + hide_reaction_button_file) + # bold reading checkbox + bold_reading_filename = \ + acct_dir(base_dir, nickname, domain) + \ + '/.boldReading' + bold_reading = False + if fields.get('boldReading'): + if fields['boldReading'] == 'on': + bold_reading = True + self.server.bold_reading[nickname] = True + try: + with open(bold_reading_filename, + 'w+') as rfile: + rfile.write('\n') + except OSError: + print('EX: unable to write bold reading ' + + bold_reading_filename) + if not bold_reading: + if self.server.bold_reading[nickname]: + del self.server.bold_reading[nickname] + if os.path.isfile(bold_reading_filename): + try: + os.remove(bold_reading_filename) + except OSError: + print('EX: _profile_edit ' + + 'unable to delete ' + + bold_reading_filename) + # notify about new Likes if on_final_welcome_screen: # default setting from welcome screen @@ -8204,6 +8258,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading(nickname): + bold_reading = True hashtag_str = \ html_hashtag_search(self.server.css_cache, nickname, domain, port, @@ -8228,7 +8285,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) if hashtag_str: msg = hashtag_str.encode('utf-8') msglen = len(msg) @@ -8445,6 +8502,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(announce_filename.replace('.json', '') + '.mitm'): mitm = True + bionic_reading = False + if self.server.bionic_reading.get(self.post_to_nickname): + bionic_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, self.server.max_recent_posts, @@ -8473,7 +8533,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm) + timezone, mitm, bionic_reading) actor_absolute = self._get_instance_url(calling_domain) + actor actor_path_str = \ @@ -8986,6 +9046,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(liked_post_filename.replace('.json', '') + '.mitm'): mitm = True + bionic_reading = False + if self.server.bionic_reading.get(self.post_to_nickname): + bionic_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9016,7 +9079,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm) + timezone, mitm, bionic_reading) else: print('WARN: Liked post not found: ' + liked_post_filename) # clear the icon from the cache so that it gets updated @@ -9168,6 +9231,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(liked_post_filename.replace('.json', '') + '.mitm'): mitm = True + bionic_reading = False + if self.server.bionic_reading.get(self.post_to_nickname): + bionic_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9198,7 +9264,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm) + timezone, mitm, bionic_reading) else: print('WARN: Unliked post not found: ' + liked_post_filename) # clear the icon from the cache so that it gets updated @@ -9379,6 +9445,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(reaction_post_filename.replace('.json', '') + '.mitm'): mitm = True + bionic_reading = False + if self.server.bionic_reading.get(self.post_to_nickname): + bionic_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9409,7 +9478,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm) + timezone, mitm, bionic_reading) else: print('WARN: Emoji reaction post not found: ' + reaction_post_filename) @@ -9580,6 +9649,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(reaction_post_filename.replace('.json', '') + '.mitm'): mitm = True + bionic_reading = False + if self.server.bionic_reading.get(self.post_to_nickname): + bionic_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9610,7 +9682,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm) + timezone, mitm, bionic_reading) else: print('WARN: Unreaction post not found: ' + reaction_post_filename) @@ -9687,6 +9759,11 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(self.post_to_nickname): timezone = \ self.server.account_timezone.get(self.post_to_nickname) + + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True + msg = \ html_emoji_reaction_picker(self.server.css_cache, self.server.recent_posts_cache, @@ -9712,7 +9789,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.cw_lists, self.server.lists_enabled, timeline_str, page_number, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -9831,6 +9908,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(bookmark_filename.replace('.json', '') + '.mitm'): mitm = True + bionic_reading = False + if self.server.bionic_reading.get(self.post_to_nickname): + bionic_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9861,7 +9941,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm) + timezone, mitm, bionic_reading) else: print('WARN: Bookmarked post not found: ' + bookmark_filename) # self._post_to_outbox(bookmark_json, @@ -9987,6 +10067,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(bookmark_filename.replace('.json', '') + '.mitm'): mitm = True + bionic_reading = False + if self.server.bionic_reading.get(self.post_to_nickname): + bionic_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -10017,7 +10100,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm) + timezone, mitm, bionic_reading) else: print('WARN: Unbookmarked post not found: ' + bookmark_filename) @@ -10107,7 +10190,8 @@ class PubServer(BaseHTTPRequestHandler): return delete_str = \ - html_confirm_delete(self.server.css_cache, + html_confirm_delete(self.server, + self.server.css_cache, self.server.recent_posts_cache, self.server.max_recent_posts, self.server.translate, page_number, @@ -10219,6 +10303,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(mute_filename.replace('.json', '') + '.mitm'): mitm = True + bionic_reading = False + if self.server.bionic_reading.get(nickname): + bionic_reading = True individual_post_as_html(self.server.signing_priv_key_pem, allow_downloads, self.server.recent_posts_cache, @@ -10250,7 +10337,7 @@ class PubServer(BaseHTTPRequestHandler): use_cache_only, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm) + timezone, mitm, bionic_reading) else: print('WARN: Muted post not found: ' + mute_filename) @@ -10343,6 +10430,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(mute_filename.replace('.json', '') + '.mitm'): mitm = True + bionic_reading = False + if self.server.bionic_reading.get(nickname): + bionic_reading = True individual_post_as_html(self.server.signing_priv_key_pem, allow_downloads, self.server.recent_posts_cache, @@ -10374,7 +10464,7 @@ class PubServer(BaseHTTPRequestHandler): use_cache_only, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm) + timezone, mitm, bionic_reading) else: print('WARN: Unmuted post not found: ' + mute_filename) if calling_domain.endswith('.onion') and onion_domain: @@ -10475,6 +10565,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_post_replies(self.server.css_cache, recent_posts_cache, @@ -10501,7 +10594,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -10577,6 +10670,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_post_replies(self.server.css_cache, recent_posts_cache, @@ -10603,7 +10699,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -10692,6 +10788,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_profile(self.server.signing_priv_key_pem, self.server.rss_icon_at_top, @@ -10725,7 +10824,7 @@ class PubServer(BaseHTTPRequestHandler): None, None, self.server.cw_lists, self.server.lists_enabled, self.server.content_license_url, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -10821,6 +10920,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nick): timezone = \ self.server.account_timezone.get(nick) + bold_reading = False + if self.server.bold_reading.get(nick): + bold_reading = True msg = \ html_profile(signing_priv_key_pem, self.server.rss_icon_at_top, @@ -10855,7 +10957,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.cw_lists, self.server.lists_enabled, content_license_url, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -10995,6 +11097,10 @@ class PubServer(BaseHTTPRequestHandler): post_url = post_url.split('?')[0] post_url = post_url.replace('--', '/') + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True + msg = \ html_likers_of_post(base_dir, nickname, domain, port, post_url, self.server.translate, @@ -11017,7 +11123,8 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - 'inbox', self.server.default_timeline) + 'inbox', self.server.default_timeline, + bold_reading) if not msg: self._404() return True @@ -11056,6 +11163,10 @@ class PubServer(BaseHTTPRequestHandler): post_url = post_url.split('?')[0] post_url = post_url.replace('--', '/') + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True + # note that the likers function is reused, but with 'shares' msg = \ html_likers_of_post(base_dir, nickname, domain, port, @@ -11080,7 +11191,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.cw_lists, self.server.lists_enabled, 'inbox', self.server.default_timeline, - 'shares') + bold_reading, 'shares') if not msg: self._404() return True @@ -11134,10 +11245,16 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + mitm = False if os.path.isfile(post_filename.replace('.json', '') + '.mitm'): mitm = True + + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True + msg = \ html_individual_post(self.server.css_cache, self.server.recent_posts_cache, @@ -11164,7 +11281,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm) + timezone, mitm, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -11408,6 +11525,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = html_inbox(self.server.css_cache, default_timeline, recent_posts_cache, @@ -11448,7 +11568,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) if getreq_start_time: fitness_performance(getreq_start_time, self.server.fitness, @@ -11576,6 +11696,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_inbox_dms(self.server.css_cache, self.server.default_timeline, @@ -11616,7 +11739,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -11733,6 +11856,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_inbox_replies(self.server.css_cache, self.server.default_timeline, @@ -11773,7 +11899,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -11887,6 +12013,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading(nickname): + bold_reading = True msg = \ html_inbox_media(self.server.css_cache, self.server.default_timeline, @@ -11928,7 +12057,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -12042,6 +12171,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_inbox_blogs(self.server.css_cache, self.server.default_timeline, @@ -12083,7 +12215,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -12205,6 +12337,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_inbox_news(self.server.css_cache, self.server.default_timeline, @@ -12247,7 +12382,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -12372,6 +12507,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_inbox_features(self.server.css_cache, self.server.default_timeline, @@ -12414,7 +12552,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -12493,6 +12631,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_shares(self.server.css_cache, self.server.default_timeline, @@ -12530,7 +12671,8 @@ class PubServer(BaseHTTPRequestHandler): self.server.shared_items_federated_domains, self.server.signing_priv_key_pem, self.server.cw_lists, - self.server.lists_enabled, timezone) + self.server.lists_enabled, timezone, + bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -12583,6 +12725,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_wanted(self.server.css_cache, self.server.default_timeline, @@ -12621,7 +12766,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -12714,6 +12859,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_bookmarks(self.server.css_cache, self.server.default_timeline, @@ -12755,7 +12903,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -12864,6 +13012,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_outbox(self.server.css_cache, self.server.default_timeline, @@ -12903,7 +13054,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -13008,6 +13159,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_moderation(self.server.css_cache, self.server.default_timeline, @@ -13048,7 +13202,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.signing_priv_key_pem, self.server.cw_lists, self.server.lists_enabled, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -13151,6 +13305,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading(nickname): + bold_reading = True msg = \ html_profile(self.server.signing_priv_key_pem, self.server.rss_icon_at_top, @@ -13186,7 +13343,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.cw_lists, self.server.lists_enabled, self.server.content_license_url, - timezone) + timezone, bold_reading) msg = msg.encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, @@ -13287,6 +13444,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.content_license_url shared_items_federated_domains = \ self.server.shared_items_federated_domains + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_profile(self.server.signing_priv_key_pem, self.server.rss_icon_at_top, @@ -13323,7 +13483,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.cw_lists, self.server.lists_enabled, content_license_url, - timezone).encode('utf-8') + timezone, bold_reading).encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, cookie, calling_domain, False) @@ -13422,6 +13582,9 @@ class PubServer(BaseHTTPRequestHandler): self.server.content_license_url shared_items_federated_domains = \ self.server.shared_items_federated_domains + bold_reading = False + if self.server.bold_reading(nickname): + bold_reading = True msg = \ html_profile(self.server.signing_priv_key_pem, self.server.rss_icon_at_top, @@ -13459,7 +13622,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.cw_lists, self.server.lists_enabled, content_license_url, - timezone).encode('utf-8') + timezone, bold_reading).encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, cookie, calling_domain, False) @@ -13583,6 +13746,9 @@ class PubServer(BaseHTTPRequestHandler): if self.server.account_timezone.get(nickname): timezone = \ self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True msg = \ html_profile(self.server.signing_priv_key_pem, self.server.rss_icon_at_top, @@ -13615,7 +13781,7 @@ class PubServer(BaseHTTPRequestHandler): self.server.cw_lists, self.server.lists_enabled, self.server.content_license_url, - timezone).encode('utf-8') + timezone, bold_reading).encode('utf-8') msglen = len(msg) self._set_headers('text/html', msglen, cookie, calling_domain, False) @@ -14371,6 +14537,10 @@ class PubServer(BaseHTTPRequestHandler): if reply_post_filename: post_json_object = load_json(reply_post_filename) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True + msg = html_new_post(self.server.css_cache, media_instance, translate, @@ -14408,7 +14578,8 @@ class PubServer(BaseHTTPRequestHandler): self.server.cw_lists, self.server.lists_enabled, self.server.default_timeline, - reply_is_chat).encode('utf-8') + reply_is_chat, + bold_reading).encode('utf-8') if not msg: print('Error replying to ' + in_reply_to_url) self._404() @@ -14476,7 +14647,7 @@ class PubServer(BaseHTTPRequestHandler): access_keys = self.server.key_shortcuts[nickname] default_reply_interval_hrs = self.server.default_reply_interval_hrs - msg = html_edit_profile(self.server.css_cache, + msg = html_edit_profile(self.server, self.server.css_cache, translate, base_dir, path, domain, @@ -20523,6 +20694,9 @@ def run_daemon(crawlers_allowed: [], # scan the theme directory for any svg files containing scripts assert not scan_themes_for_scripts(base_dir) + # for each account, whether bold reading is enabled + httpd.bold_reading = load_bold_reading(base_dir) + httpd.account_timezone = load_account_timezones(base_dir) httpd.post_to_nickname = None diff --git a/inbox.py b/inbox.py index b02514e0e..561a09d80 100644 --- a/inbox.py +++ b/inbox.py @@ -297,7 +297,8 @@ def _inbox_store_post_to_html_cache(recent_posts_cache: {}, cw_lists: {}, lists_enabled: str, timezone: str, - mitm: bool) -> None: + mitm: bool, + bold_reading: bool) -> None: """Converts the json post into html and stores it in a cache This enables the post to be quickly displayed later """ @@ -322,7 +323,8 @@ def _inbox_store_post_to_html_cache(recent_posts_cache: {}, peertube_instances, allow_local_network_access, theme_name, system_language, max_like_count, not_dm, True, True, False, True, False, - cw_lists, lists_enabled, timezone, mitm) + cw_lists, lists_enabled, timezone, mitm, + bold_reading) def valid_inbox(base_dir: str, nickname: str, domain: str) -> bool: @@ -1047,7 +1049,8 @@ def _receive_like(recent_posts_cache: {}, allow_local_network_access: bool, theme_name: str, system_language: str, max_like_count: int, cw_lists: {}, - lists_enabled: str) -> bool: + lists_enabled: str, + bold_reading: bool) -> bool: """Receives a Like activity within the POST section of HTTPServer """ if message_json['type'] != 'Like': @@ -1155,7 +1158,8 @@ def _receive_like(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone, mitm) + lists_enabled, timezone, mitm, + bold_reading) return True @@ -1174,7 +1178,8 @@ def _receive_undo_like(recent_posts_cache: {}, allow_local_network_access: bool, theme_name: str, system_language: str, max_like_count: int, cw_lists: {}, - lists_enabled: str) -> bool: + lists_enabled: str, + bold_reading: bool) -> bool: """Receives an undo like activity within the POST section of HTTPServer """ if message_json['type'] != 'Undo': @@ -1272,7 +1277,8 @@ def _receive_undo_like(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone, mitm) + lists_enabled, timezone, mitm, + bold_reading) return True @@ -1292,7 +1298,7 @@ def _receive_reaction(recent_posts_cache: {}, allow_local_network_access: bool, theme_name: str, system_language: str, max_like_count: int, cw_lists: {}, - lists_enabled: str) -> bool: + lists_enabled: str, bold_reading: bool) -> bool: """Receives an emoji reaction within the POST section of HTTPServer """ if message_json['type'] != 'EmojiReact': @@ -1422,7 +1428,8 @@ def _receive_reaction(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone, mitm) + lists_enabled, timezone, mitm, + bold_reading) return True @@ -1443,7 +1450,8 @@ def _receive_undo_reaction(recent_posts_cache: {}, allow_local_network_access: bool, theme_name: str, system_language: str, max_like_count: int, cw_lists: {}, - lists_enabled: str) -> bool: + lists_enabled: str, + bold_reading: bool) -> bool: """Receives an undo emoji reaction within the POST section of HTTPServer """ if message_json['type'] != 'Undo': @@ -1559,7 +1567,8 @@ def _receive_undo_reaction(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone, mitm) + lists_enabled, timezone, mitm, + bold_reading) return True @@ -1577,7 +1586,7 @@ def _receive_bookmark(recent_posts_cache: {}, allow_local_network_access: bool, theme_name: str, system_language: str, max_like_count: int, cw_lists: {}, - lists_enabled: {}) -> bool: + lists_enabled: {}, bold_reading: bool) -> bool: """Receives a bookmark activity within the POST section of HTTPServer """ if not message_json.get('type'): @@ -1673,7 +1682,8 @@ def _receive_bookmark(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone, mitm) + lists_enabled, timezone, mitm, + bold_reading) return True @@ -1693,7 +1703,7 @@ def _receive_undo_bookmark(recent_posts_cache: {}, allow_local_network_access: bool, theme_name: str, system_language: str, max_like_count: int, cw_lists: {}, - lists_enabled: str) -> bool: + lists_enabled: str, bold_reading: bool) -> bool: """Receives an undo bookmark activity within the POST section of HTTPServer """ if not message_json.get('type'): @@ -1791,7 +1801,7 @@ def _receive_undo_bookmark(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, lists_enabled, - timezone, mitm) + timezone, mitm, bold_reading) return True @@ -1887,7 +1897,7 @@ def _receive_announce(recent_posts_cache: {}, allow_deletion: bool, peertube_instances: [], max_like_count: int, cw_lists: {}, - lists_enabled: str) -> bool: + lists_enabled: str, bold_reading: bool) -> bool: """Receives an announce activity within the POST section of HTTPServer """ if message_json['type'] != 'Announce': @@ -2010,7 +2020,8 @@ def _receive_announce(recent_posts_cache: {}, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone, mitm) + lists_enabled, timezone, mitm, + bold_reading) if not announce_html: print('WARN: Unable to generate html for announce ' + str(message_json)) @@ -3111,7 +3122,8 @@ def _receive_question_vote(server, base_dir: str, nickname: str, domain: str, allow_local_network_access: bool, theme_name: str, system_language: str, max_like_count: int, - cw_lists: {}, lists_enabled: bool) -> None: + cw_lists: {}, lists_enabled: bool, + bold_reading: bool) -> None: """Updates the votes on a Question/poll """ # if this is a reply to a question then update the votes @@ -3163,7 +3175,8 @@ def _receive_question_vote(server, base_dir: str, nickname: str, domain: str, show_individual_post_icons, manually_approve_followers, False, True, False, cw_lists, - lists_enabled, timezone, mitm) + lists_enabled, timezone, mitm, + bold_reading) # add id to inbox index inbox_update_index('inbox', base_dir, handle, @@ -3362,6 +3375,12 @@ def _inbox_after_initial(server, post_is_dm = False is_group = _group_handle(base_dir, handle) + handle_name = handle.split('@')[0] + + bold_reading = False + if server.bold_reading.get(handle_name): + bold_reading = True + if _receive_like(recent_posts_cache, session, handle, is_group, base_dir, http_prefix, @@ -3380,7 +3399,8 @@ def _inbox_after_initial(server, peertube_instances, allow_local_network_access, theme_name, system_language, - max_like_count, cw_lists, lists_enabled): + max_like_count, cw_lists, lists_enabled, + bold_reading): if debug: print('DEBUG: Like accepted from ' + actor) return False @@ -3402,7 +3422,8 @@ def _inbox_after_initial(server, peertube_instances, allow_local_network_access, theme_name, system_language, - max_like_count, cw_lists, lists_enabled): + max_like_count, cw_lists, lists_enabled, + bold_reading): if debug: print('DEBUG: Undo like accepted from ' + actor) return False @@ -3425,7 +3446,8 @@ def _inbox_after_initial(server, peertube_instances, allow_local_network_access, theme_name, system_language, - max_like_count, cw_lists, lists_enabled): + max_like_count, cw_lists, lists_enabled, + bold_reading): if debug: print('DEBUG: Reaction accepted from ' + actor) return False @@ -3447,7 +3469,8 @@ def _inbox_after_initial(server, peertube_instances, allow_local_network_access, theme_name, system_language, - max_like_count, cw_lists, lists_enabled): + max_like_count, cw_lists, lists_enabled, + bold_reading): if debug: print('DEBUG: Undo reaction accepted from ' + actor) return False @@ -3469,7 +3492,8 @@ def _inbox_after_initial(server, peertube_instances, allow_local_network_access, theme_name, system_language, - max_like_count, cw_lists, lists_enabled): + max_like_count, cw_lists, lists_enabled, + bold_reading): if debug: print('DEBUG: Bookmark accepted from ' + actor) return False @@ -3491,7 +3515,8 @@ def _inbox_after_initial(server, peertube_instances, allow_local_network_access, theme_name, system_language, - max_like_count, cw_lists, lists_enabled): + max_like_count, cw_lists, lists_enabled, + bold_reading): if debug: print('DEBUG: Undo bookmark accepted from ' + actor) return False @@ -3517,7 +3542,8 @@ def _inbox_after_initial(server, max_recent_posts, allow_deletion, peertube_instances, - max_like_count, cw_lists, lists_enabled): + max_like_count, cw_lists, lists_enabled, + bold_reading): if debug: print('DEBUG: Announce accepted from ' + actor) @@ -3615,7 +3641,8 @@ def _inbox_after_initial(server, allow_local_network_access, theme_name, system_language, max_like_count, - cw_lists, lists_enabled) + cw_lists, lists_enabled, + bold_reading) is_reply_to_muted_post = False @@ -3718,11 +3745,10 @@ def _inbox_after_initial(server, print('Saving inbox post as html to cache') html_cache_start_time = time.time() - handle_name = handle.split('@')[0] allow_local_net_access = allow_local_network_access show_pub_date_only = show_published_date_only - timezone = get_account_timezone(base_dir, - handle_name, domain) + timezone = \ + get_account_timezone(base_dir, handle_name, domain) _inbox_store_post_to_html_cache(recent_posts_cache, max_recent_posts, translate, base_dir, @@ -3744,7 +3770,8 @@ def _inbox_after_initial(server, signing_priv_key_pem, cw_lists, lists_enabled, - timezone, mitm) + timezone, mitm, + bold_reading) if debug: time_diff = \ str(int((time.time() - html_cache_start_time) * diff --git a/outbox.py b/outbox.py index 3b8215d52..07d321aa8 100644 --- a/outbox.py +++ b/outbox.py @@ -461,6 +461,9 @@ def post_message_to_outbox(session, translate: {}, if os.path.isfile(saved_filename.replace('.json', '') + '.mitm'): mitm = True + bold_reading = False + if server.bold_reading.get(post_to_nickname): + bold_reading = True individual_post_as_html(signing_priv_key_pem, False, recent_posts_cache, max_recent_posts, @@ -485,7 +488,8 @@ def post_message_to_outbox(session, translate: {}, manually_approve_followers, False, True, use_cache_only, cw_lists, lists_enabled, - timezone, mitm) + timezone, mitm, + bold_reading) if outbox_announce(recent_posts_cache, base_dir, message_json, debug): diff --git a/tests.py b/tests.py index d23461a08..838c669d1 100644 --- a/tests.py +++ b/tests.py @@ -129,6 +129,7 @@ from inbox import json_post_allows_comments from inbox import valid_inbox from inbox import valid_inbox_filenames from categories import guess_hashtag_category +from content import bold_reading_string from content import safe_web_text from content import words_similarity from content import get_price_from_string @@ -6687,6 +6688,39 @@ def _test_published_to_local_timezone() -> None: assert local_time_str == 'Sat Feb 26, 05:15' +def _test_bold_reading() -> None: + print('bold_reading') + text = "This is a test of emboldening." + text_bold = bold_reading_string(text) + expected = \ + "This is a test of " + \ + "emboldening." + if text_bold != expected: + print(text_bold) + assert text_bold == expected + + text = "

This is a test of emboldening with paragraph.

" + text_bold = bold_reading_string(text) + expected = \ + "

This is a test of " + \ + "emboldening with paragraph.

" + if text_bold != expected: + print(text_bold) + assert text_bold == expected + + text = \ + "

This is a test of emboldening

" + \ + "

With more than one paragraph.

" + text_bold = bold_reading_string(text) + expected = \ + "

This is a test of " + \ + "emboldening

With more " + \ + "than one paragraph.

" + if text_bold != expected: + print(text_bold) + assert text_bold == expected + + def run_all_tests(): base_dir = os.getcwd() print('Running tests...') @@ -6703,6 +6737,7 @@ def run_all_tests(): 'message_json', 'liked_post_json']) _test_checkbox_names() _test_functions() + _test_bold_reading() _test_published_to_local_timezone() _test_safe_webtext() _test_get_link_from_rss_item() diff --git a/translations/ar.json b/translations/ar.json index 8a4d3c7ee..6f6f4ce23 100644 --- a/translations/ar.json +++ b/translations/ar.json @@ -518,5 +518,6 @@ "Register": "يسجل", "Web Bots Allowed": "مسموح روبوتات الويب", "Known Search Bots": "روبوتات بحث الويب المعروفة", - "mitm": "يمكن قراءة الرسالة أو تعديلها من قبل طرف ثالث" + "mitm": "يمكن قراءة الرسالة أو تعديلها من قبل طرف ثالث", + "Bold reading": "قراءة جريئة" } diff --git a/translations/ca.json b/translations/ca.json index 10dd483f7..86651c8ae 100644 --- a/translations/ca.json +++ b/translations/ca.json @@ -518,5 +518,6 @@ "Register": "Registra't", "Web Bots Allowed": "Bots web permesos", "Known Search Bots": "Bots de cerca web coneguts", - "mitm": "El missatge podria haver estat llegit o modificat per un tercer" + "mitm": "El missatge podria haver estat llegit o modificat per un tercer", + "Bold reading": "Lectura atrevida" } diff --git a/translations/cy.json b/translations/cy.json index eef7ecbd4..8bc01bdec 100644 --- a/translations/cy.json +++ b/translations/cy.json @@ -518,5 +518,6 @@ "Register": "Cofrestrwch", "Web Bots Allowed": "Web Bots a Ganiateir", "Known Search Bots": "Bots Chwilio Gwe Hysbys", - "mitm": "Gallai'r neges fod wedi cael ei darllen neu ei haddasu gan drydydd parti" + "mitm": "Gallai'r neges fod wedi cael ei darllen neu ei haddasu gan drydydd parti", + "Bold reading": "Darllen beiddgar" } diff --git a/translations/de.json b/translations/de.json index a33f20caf..c2fe3ff2d 100644 --- a/translations/de.json +++ b/translations/de.json @@ -518,5 +518,6 @@ "Register": "Registrieren", "Web Bots Allowed": "Webbots erlaubt", "Known Search Bots": "Bekannte Bots für die Websuche", - "mitm": "Die Nachricht könnte von einem Dritten gelesen oder geändert worden sein" + "mitm": "Die Nachricht könnte von einem Dritten gelesen oder geändert worden sein", + "Bold reading": "Mutige Lektüre" } diff --git a/translations/en.json b/translations/en.json index 848aeb093..d70f59477 100644 --- a/translations/en.json +++ b/translations/en.json @@ -518,5 +518,6 @@ "Register": "Register", "Web Bots Allowed": "Web Search Bots Allowed", "Known Search Bots": "Known Web Search Bots", - "mitm": "Message could have been read or modified by a third party" + "mitm": "Message could have been read or modified by a third party", + "Bold reading": "Bold reading" } diff --git a/translations/es.json b/translations/es.json index b611d7366..3c3673ee3 100644 --- a/translations/es.json +++ b/translations/es.json @@ -518,5 +518,6 @@ "Register": "Registrarse", "Web Bots Allowed": "Bots web permitidos", "Known Search Bots": "Bots de búsqueda web conocidos", - "mitm": "El mensaje podría haber sido leído o modificado por un tercero" + "mitm": "El mensaje podría haber sido leído o modificado por un tercero", + "Bold reading": "Lectura en negrita" } diff --git a/translations/fr.json b/translations/fr.json index f50d7a4d4..a553b49b8 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -518,5 +518,6 @@ "Register": "S'inscrire", "Web Bots Allowed": "Robots Web autorisés", "Known Search Bots": "Robots de recherche Web connus", - "mitm": "Le message a pu être lu ou modifié par un tiers" + "mitm": "Le message a pu être lu ou modifié par un tiers", + "Bold reading": "Lecture audacieuse" } diff --git a/translations/ga.json b/translations/ga.json index 7fdcece92..c1f065901 100644 --- a/translations/ga.json +++ b/translations/ga.json @@ -518,5 +518,6 @@ "Register": "Clár", "Web Bots Allowed": "Róbónna Gréasáin Ceadaithe", "Known Search Bots": "Róbónna Cuardach Gréasáin Aitheanta", - "mitm": "D'fhéadfadh tríú páirtí an teachtaireacht a léamh nó a mhodhnú" + "mitm": "D'fhéadfadh tríú páirtí an teachtaireacht a léamh nó a mhodhnú", + "Bold reading": "Léamh trom" } diff --git a/translations/hi.json b/translations/hi.json index 668b8aab6..6845d4d27 100644 --- a/translations/hi.json +++ b/translations/hi.json @@ -518,5 +518,6 @@ "Register": "रजिस्टर करें", "Web Bots Allowed": "वेब बॉट्स की अनुमति है", "Known Search Bots": "ज्ञात वेब खोज बॉट्स", - "mitm": "संदेश किसी तीसरे पक्ष द्वारा पढ़ा या संशोधित किया जा सकता था" + "mitm": "संदेश किसी तीसरे पक्ष द्वारा पढ़ा या संशोधित किया जा सकता था", + "Bold reading": "बोल्ड रीडिंग" } diff --git a/translations/it.json b/translations/it.json index 23e96d921..d6bd3418f 100644 --- a/translations/it.json +++ b/translations/it.json @@ -518,5 +518,6 @@ "Register": "Registrati", "Web Bots Allowed": "Web bot consentiti", "Known Search Bots": "Bot di ricerca Web noti", - "mitm": "Il messaggio potrebbe essere stato letto o modificato da terzi" + "mitm": "Il messaggio potrebbe essere stato letto o modificato da terzi", + "Bold reading": "Lettura audace" } diff --git a/translations/ja.json b/translations/ja.json index e722405f8..0d6fe2b7e 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -518,5 +518,6 @@ "Register": "登録", "Web Bots Allowed": "許可されたWebボット", "Known Search Bots": "既知のWeb検索ボット", - "mitm": "メッセージが第三者によって読み取られたり変更されたりした可能性があります" + "mitm": "メッセージが第三者によって読み取られたり変更されたりした可能性があります", + "Bold reading": "大胆な読書" } diff --git a/translations/ko.json b/translations/ko.json index e9bdb5d38..96b6e038a 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -518,5 +518,6 @@ "Register": "등록", "Web Bots Allowed": "웹 봇 허용", "Known Search Bots": "알려진 웹 검색 봇", - "mitm": "제3자가 메시지를 읽거나 수정했을 수 있습니다." + "mitm": "제3자가 메시지를 읽거나 수정했을 수 있습니다.", + "Bold reading": "굵은 글씨" } diff --git a/translations/ku.json b/translations/ku.json index e491e585c..2aa459238 100644 --- a/translations/ku.json +++ b/translations/ku.json @@ -518,5 +518,6 @@ "Register": "Fêhrist", "Web Bots Allowed": "Web Bots Destûrdar in", "Known Search Bots": "Botên Lêgerîna Webê yên naskirî", - "mitm": "Peyam dikaribû ji hêla aliyek sêyemîn ve were xwendin an guhertin" + "mitm": "Peyam dikaribû ji hêla aliyek sêyemîn ve were xwendin an guhertin", + "Bold reading": "Xwendina qelew" } diff --git a/translations/oc.json b/translations/oc.json index 5c0858299..c6e69765c 100644 --- a/translations/oc.json +++ b/translations/oc.json @@ -514,5 +514,6 @@ "Register": "Register", "Web Bots Allowed": "Web Search Bots Allowed", "Known Search Bots": "Known Web Search Bots", - "mitm": "Message could have been read or modified by a third party" + "mitm": "Message could have been read or modified by a third party", + "Bold reading": "Bold reading" } diff --git a/translations/pl.json b/translations/pl.json index 3184a3a52..fb6e675b1 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -518,5 +518,6 @@ "Register": "Zarejestrować", "Web Bots Allowed": "Dozwolone boty internetowe", "Known Search Bots": "Znane boty wyszukiwania w sieci", - "mitm": "Wiadomość mogła zostać przeczytana lub zmodyfikowana przez osobę trzecią" + "mitm": "Wiadomość mogła zostać przeczytana lub zmodyfikowana przez osobę trzecią", + "Bold reading": "Odważne czytanie" } diff --git a/translations/pt.json b/translations/pt.json index 5a543440b..98a6db584 100644 --- a/translations/pt.json +++ b/translations/pt.json @@ -518,5 +518,6 @@ "Register": "Registro", "Web Bots Allowed": "Webbots permitidos", "Known Search Bots": "Bots de pesquisa na Web conhecidos", - "mitm": "A mensagem pode ter sido lida ou modificada por terceiros" + "mitm": "A mensagem pode ter sido lida ou modificada por terceiros", + "Bold reading": "Leitura em negrito" } diff --git a/translations/ru.json b/translations/ru.json index b9540fc12..e8d906959 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -518,5 +518,6 @@ "Register": "регистр", "Web Bots Allowed": "Веб-боты разрешены", "Known Search Bots": "Известные боты веб-поиска", - "mitm": "Сообщение могло быть прочитано или изменено третьим лицом" + "mitm": "Сообщение могло быть прочитано или изменено третьим лицом", + "Bold reading": "Смелое чтение" } diff --git a/translations/sw.json b/translations/sw.json index 9f047b434..39e466044 100644 --- a/translations/sw.json +++ b/translations/sw.json @@ -518,5 +518,6 @@ "Register": "Sajili", "Web Bots Allowed": "Mtandao wa Boti Unaruhusiwa", "Known Search Bots": "Vijibu vya Utafutaji wa Wavuti vinavyojulikana", - "mitm": "Ujumbe ungeweza kusomwa au kurekebishwa na mtu mwingine" + "mitm": "Ujumbe ungeweza kusomwa au kurekebishwa na mtu mwingine", + "Bold reading": "Kusoma kwa ujasiri" } diff --git a/translations/uk.json b/translations/uk.json index 89e9273bd..009245795 100644 --- a/translations/uk.json +++ b/translations/uk.json @@ -518,5 +518,6 @@ "Register": "Реєстрація", "Web Bots Allowed": "Веб-боти дозволені", "Known Search Bots": "Відомі пошукові роботи в Інтернеті", - "mitm": "Повідомлення могло бути прочитане або змінене третьою стороною" + "mitm": "Повідомлення могло бути прочитане або змінене третьою стороною", + "Bold reading": "Сміливе читання" } diff --git a/translations/zh.json b/translations/zh.json index b0acdfbde..c9624fce1 100644 --- a/translations/zh.json +++ b/translations/zh.json @@ -518,5 +518,6 @@ "Register": "登记", "Web Bots Allowed": "允许网络机器人", "Known Search Bots": "已知的网络搜索机器人", - "mitm": "消息可能已被第三方阅读或修改" + "mitm": "消息可能已被第三方阅读或修改", + "Bold reading": "大胆阅读" } diff --git a/utils.py b/utils.py index 1cd72cbe7..e65cb083e 100644 --- a/utils.py +++ b/utils.py @@ -3480,6 +3480,24 @@ def load_account_timezones(base_dir: str) -> {}: return account_timezone +def load_bold_reading(base_dir: str) -> {}: + """Returns a dictionary containing the bold reading status for each account + """ + bold_reading = {} + for subdir, dirs, files in os.walk(base_dir + '/accounts'): + for acct in dirs: + if '@' not in acct: + continue + if acct.startswith('inbox@') or acct.startswith('Actor@'): + continue + bold_reading_filename = \ + base_dir + '/accounts/' + acct + '/.boldReading' + if os.path.isfile(bold_reading_filename): + nickname = acct.split('@')[0] + bold_reading[nickname] = True + return bold_reading + + def get_account_timezone(base_dir: str, nickname: str, domain: str) -> str: """Returns the timezone for the given account """ diff --git a/webapp_confirm.py b/webapp_confirm.py index 7b574ae6f..d0bcedc6d 100644 --- a/webapp_confirm.py +++ b/webapp_confirm.py @@ -24,7 +24,7 @@ from webapp_utils import html_footer from webapp_post import individual_post_as_html -def html_confirm_delete(css_cache: {}, +def html_confirm_delete(server, css_cache: {}, recent_posts_cache: {}, max_recent_posts: int, translate, page_number: int, session, base_dir: str, message_id: str, @@ -71,6 +71,9 @@ def html_confirm_delete(css_cache: {}, mitm = False if os.path.isfile(post_filename.replace('.json', '') + '.mitm'): mitm = True + bold_reading = False + if server.bold_reading.get(nickname): + bold_reading = True delete_post_str += \ individual_post_as_html(signing_priv_key_pem, True, recent_posts_cache, max_recent_posts, @@ -86,7 +89,8 @@ def html_confirm_delete(css_cache: {}, peertube_instances, allow_local_network_access, theme_name, system_language, max_like_count, False, False, False, False, False, False, - cw_lists, lists_enabled, timezone, mitm) + cw_lists, lists_enabled, timezone, mitm, + bold_reading) delete_post_str += '
' delete_post_str += \ '

' + \ diff --git a/webapp_create_post.py b/webapp_create_post.py index 0812ea207..c81ed2cbe 100644 --- a/webapp_create_post.py +++ b/webapp_create_post.py @@ -212,7 +212,7 @@ def html_new_post(css_cache: {}, media_instance: bool, translate: {}, max_like_count: int, signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, boxName: str, - reply_is_chat: bool) -> str: + reply_is_chat: bool, bold_reading: bool) -> str: """New post screen """ reply_str = '' @@ -286,7 +286,8 @@ def html_new_post(css_cache: {}, media_instance: bool, translate: {}, False, False, False, False, False, False, cw_lists, lists_enabled, - timezone, False) + timezone, False, + bold_reading) reply_str = '\n' diff --git a/webapp_frontscreen.py b/webapp_frontscreen.py index 68df1b6de..791dd1dc2 100644 --- a/webapp_frontscreen.py +++ b/webapp_frontscreen.py @@ -37,7 +37,8 @@ def _html_front_screen_posts(recent_posts_cache: {}, max_recent_posts: int, theme_name: str, system_language: str, max_like_count: int, signing_priv_key_pem: str, cw_lists: {}, - lists_enabled: str) -> str: + lists_enabled: str, + bold_reading: bool) -> str: """Shows posts on the front screen of a news instance These should only be public blog posts from the features timeline which is the blog timeline of the news actor @@ -87,7 +88,8 @@ def _html_front_screen_posts(recent_posts_cache: {}, max_recent_posts: int, False, False, False, True, False, False, cw_lists, lists_enabled, - timezone, False) + timezone, False, + bold_reading) if post_str: profile_str += post_str + separator_str ctr += 1 @@ -121,6 +123,7 @@ def html_front_screen(signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str) -> str: """Show the news instance front screen """ + bold_reading = False nickname = profile_json['preferredUsername'] if not nickname: return "" @@ -191,7 +194,8 @@ def html_front_screen(signing_priv_key_pem: str, theme, system_language, max_like_count, signing_priv_key_pem, - cw_lists, lists_enabled) + license_str + cw_lists, lists_enabled, + bold_reading) + license_str # Footer which is only used for system accounts profile_footer_str = ' \n' diff --git a/webapp_likers.py b/webapp_likers.py index 8e79904c7..563b77d54 100644 --- a/webapp_likers.py +++ b/webapp_likers.py @@ -41,6 +41,7 @@ def html_likers_of_post(base_dir: str, nickname: str, max_like_count: int, signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, boxName: str, default_timeline: str, + bold_reading: bool, dict_name: str = 'likes') -> str: """Returns html for a screen showing who liked a post """ @@ -105,7 +106,7 @@ def html_likers_of_post(base_dir: str, nickname: str, False, False, False, False, False, False, cw_lists, lists_enabled, - timezone, mitm) + timezone, mitm, bold_reading) # show likers beneath the post obj = post_json_object diff --git a/webapp_moderation.py b/webapp_moderation.py index 32c654e9c..490772f7f 100644 --- a/webapp_moderation.py +++ b/webapp_moderation.py @@ -55,7 +55,7 @@ def html_moderation(css_cache: {}, default_timeline: str, shared_items_federated_domains: [], signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the moderation feed as html This is what you see when selecting the "mod" timeline """ @@ -81,7 +81,7 @@ def html_moderation(css_cache: {}, default_timeline: str, text_mode_banner, access_keys, system_language, max_like_count, shared_items_federated_domains, signing_priv_key_pem, cw_lists, lists_enabled, - timezone) + timezone, bold_reading) def html_account_info(css_cache: {}, translate: {}, diff --git a/webapp_post.py b/webapp_post.py index 526a2a5ec..bf10079c0 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -58,6 +58,7 @@ from utils import get_domain_from_actor from utils import acct_dir from utils import local_actor_url from utils import is_unlisted_post +from content import bold_reading_string from content import limit_repeated_words from content import replace_emoji_from_tags from content import html_replace_quote_marks @@ -1439,7 +1440,7 @@ def individual_post_as_html(signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, timezone: str, - mitm: bool) -> str: + mitm: bool, bold_reading: bool) -> str: """ Shows a single post as html """ if not post_json_object: @@ -1952,7 +1953,9 @@ def individual_post_as_html(signing_priv_key_pem: str, system_language: '' } + displaying_ciphertext = False if post_json_object['object'].get('cipherText'): + displaying_ciphertext = True post_json_object['object']['content'] = \ e2e_edecrypt_message_from_device(post_json_object['object']) post_json_object['object']['contentMap'][system_language] = \ @@ -1980,6 +1983,9 @@ def individual_post_as_html(signing_priv_key_pem: str, post_json_object['object']['type'], summary_str, content_str) + if bold_reading and not is_patch and not displaying_ciphertext: + content_str = bold_reading_string(content_str) + _log_post_timing(enable_timing_log, post_start_time, '16') if not is_pgp_encrypted(content_str): @@ -2119,7 +2125,8 @@ def html_individual_post(css_cache: {}, theme_name: str, system_language: str, max_like_count: int, signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str, mitm: bool) -> str: + timezone: str, mitm: bool, + bold_reading: bool) -> str: """Show an individual post as html """ original_post_json = post_json_object @@ -2187,7 +2194,8 @@ def html_individual_post(css_cache: {}, allow_local_network_access, theme_name, system_language, max_like_count, False, authorized, False, False, False, False, - cw_lists, lists_enabled, timezone, mitm) + cw_lists, lists_enabled, timezone, mitm, + bold_reading) message_id = remove_id_ending(post_json_object['id']) # show the previous posts @@ -2227,7 +2235,8 @@ def html_individual_post(css_cache: {}, False, authorized, False, False, False, False, cw_lists, lists_enabled, - timezone, mitm) + post_str + timezone, mitm, + bold_reading) + post_str # show the following posts post_filename = locate_post(base_dir, nickname, domain, message_id) @@ -2265,7 +2274,8 @@ def html_individual_post(css_cache: {}, False, authorized, False, False, False, False, cw_lists, lists_enabled, - timezone, False) + timezone, False, + bold_reading) css_filename = base_dir + '/epicyon-profile.css' if os.path.isfile(base_dir + '/epicyon.css'): css_filename = base_dir + '/epicyon.css' @@ -2293,7 +2303,7 @@ def html_post_replies(css_cache: {}, max_like_count: int, signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the replies to an individual post as html """ replies_str = '' @@ -2319,7 +2329,8 @@ def html_post_replies(css_cache: {}, False, False, False, False, False, False, cw_lists, lists_enabled, - timezone, False) + timezone, False, + bold_reading) css_filename = base_dir + '/epicyon-profile.css' if os.path.isfile(base_dir + '/epicyon.css'): @@ -2349,7 +2360,7 @@ def html_emoji_reaction_picker(css_cache: {}, max_like_count: int, signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, box_name: str, page_number: int, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Returns the emoji picker screen """ reacted_to_post_str = \ @@ -2372,7 +2383,8 @@ def html_emoji_reaction_picker(css_cache: {}, theme_name, system_language, max_like_count, False, False, False, False, False, False, - cw_lists, lists_enabled, timezone, False) + cw_lists, lists_enabled, timezone, False, + bold_reading) reactions_filename = base_dir + '/emoji/reactions.json' if not os.path.isfile(reactions_filename): diff --git a/webapp_profile.py b/webapp_profile.py index e5ee588a2..d10777f82 100644 --- a/webapp_profile.py +++ b/webapp_profile.py @@ -75,6 +75,7 @@ from blog import get_blog_address from webapp_post import individual_post_as_html from webapp_timeline import html_individual_share from blocking import get_cw_list_variable +from content import bold_reading_string THEME_FORMATS = '.zip, .gz' @@ -146,7 +147,8 @@ def html_profile_after_search(css_cache: {}, signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, timezone: str, - onion_domain: str, i2p_domain: str) -> str: + onion_domain: str, i2p_domain: str, + bold_reading: bool) -> str: """Show a profile page after a search for a fediverse address """ http = False @@ -368,7 +370,8 @@ def html_profile_after_search(css_cache: {}, False, False, False, False, False, False, cw_lists, lists_enabled, - timezone, False) + timezone, False, + bold_reading) i += 1 if i >= 8: break @@ -591,7 +594,7 @@ def html_profile(signing_priv_key_pem: str, max_items_per_page: int, cw_lists: {}, lists_enabled: str, content_license_url: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the profile page as html """ nickname = profile_json['preferredUsername'] @@ -1002,7 +1005,7 @@ def html_profile(signing_priv_key_pem: str, max_like_count, signing_priv_key_pem, cw_lists, lists_enabled, - timezone) + license_str + timezone, bold_reading) + license_str if not is_group: if selected == 'following': profile_str += \ @@ -1076,7 +1079,7 @@ def _html_profile_posts(recent_posts_cache: {}, max_recent_posts: int, max_like_count: int, signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Shows posts on the profile screen These should only be public posts """ @@ -1125,7 +1128,8 @@ def _html_profile_posts(recent_posts_cache: {}, max_recent_posts: int, False, False, False, True, False, False, cw_lists, lists_enabled, - timezone, False) + timezone, False, + bold_reading) if post_str: profile_str += post_str + separator_str ctr += 1 @@ -1993,7 +1997,7 @@ def _html_edit_profile_options(is_admin: bool, notify_likes: str, notify_reactions: str, hide_like_button: str, hide_reaction_button: str, - translate: {}) -> str: + translate: {}, bold_reading: bool) -> str: """option checkboxes section of edit profile screen """ edit_profile_form = '

\n' @@ -2025,6 +2029,9 @@ def _html_edit_profile_options(is_admin: bool, edit_profile_form += \ edit_check_box(translate["Don't show the Reaction button"], 'hideReactionButton', hide_reaction_button) + bold_str = bold_reading_string(translate['Bold reading']) + edit_profile_form += \ + edit_check_box(bold_str, 'boldReading', bold_reading) edit_profile_form += '
\n' return edit_profile_form @@ -2158,7 +2165,8 @@ def _html_edit_profile_top_banner(base_dir: str, return edit_profile_form -def html_edit_profile(css_cache: {}, translate: {}, base_dir: str, path: str, +def html_edit_profile(server, css_cache: {}, translate: {}, + base_dir: str, path: str, domain: str, port: int, http_prefix: str, default_timeline: str, theme: str, peertube_instances: [], @@ -2177,6 +2185,10 @@ def html_edit_profile(css_cache: {}, translate: {}, base_dir: str, path: str, return '' domain_full = get_full_domain(domain, port) + bold_reading = False + if server.bold_reading(nickname): + bold_reading = True + actor_filename = acct_dir(base_dir, nickname, domain) + '.json' if not os.path.isfile(actor_filename): return '' @@ -2346,7 +2358,7 @@ def html_edit_profile(css_cache: {}, translate: {}, base_dir: str, path: str, remove_twitter, notify_likes, notify_reactions, hide_like_button, hide_reaction_button, - translate) + translate, bold_reading) # Contact information edit_profile_form += \ diff --git a/webapp_search.py b/webapp_search.py index b84955068..5d543e733 100644 --- a/webapp_search.py +++ b/webapp_search.py @@ -613,7 +613,7 @@ def html_history_search(css_cache: {}, translate: {}, base_dir: str, signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show a page containing search results for your post history """ if historysearch.startswith("'"): @@ -701,7 +701,7 @@ def html_history_search(css_cache: {}, translate: {}, base_dir: str, show_individual_post_icons, False, False, False, False, cw_lists, lists_enabled, - timezone, False) + timezone, False, bold_reading) if post_str: history_search_form += separator_str + post_str index += 1 @@ -727,7 +727,7 @@ def html_hashtag_search(css_cache: {}, max_like_count: int, signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show a page containing search results for a hashtag or after selecting a hashtag from the swarm """ @@ -887,7 +887,8 @@ def html_hashtag_search(css_cache: {}, manually_approves_followers, show_public_only, store_to_sache, False, cw_lists, - lists_enabled, timezone, False) + lists_enabled, timezone, False, + bold_reading) if post_str: hashtag_search_form += separator_str + post_str index += 1 diff --git a/webapp_timeline.py b/webapp_timeline.py index 6da01cf05..ccabb2f73 100644 --- a/webapp_timeline.py +++ b/webapp_timeline.py @@ -455,7 +455,7 @@ def html_timeline(css_cache: {}, default_timeline: str, shared_items_federated_domains: [], signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the timeline as html """ enable_timing_log = False @@ -935,7 +935,8 @@ def html_timeline(css_cache: {}, default_timeline: str, manually_approve_followers, False, True, use_cache_only, cw_lists, lists_enabled, - timezone, mitm) + timezone, mitm, + bold_reading) _log_timeline_timing(enable_timing_log, timeline_start_time, box_name, '12') @@ -1164,7 +1165,7 @@ def html_shares(css_cache: {}, default_timeline: str, shared_items_federated_domains: [], signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the shares timeline as html """ manually_approve_followers = \ @@ -1194,7 +1195,8 @@ def html_shares(css_cache: {}, default_timeline: str, access_keys, system_language, max_like_count, shared_items_federated_domains, signing_priv_key_pem, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, + bold_reading) def html_wanted(css_cache: {}, default_timeline: str, @@ -1223,7 +1225,7 @@ def html_wanted(css_cache: {}, default_timeline: str, shared_items_federated_domains: [], signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the wanted timeline as html """ manually_approve_followers = \ @@ -1253,7 +1255,8 @@ def html_wanted(css_cache: {}, default_timeline: str, access_keys, system_language, max_like_count, shared_items_federated_domains, signing_priv_key_pem, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, + bold_reading) def html_inbox(css_cache: {}, default_timeline: str, @@ -1283,7 +1286,7 @@ def html_inbox(css_cache: {}, default_timeline: str, shared_items_federated_domains: [], signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the inbox as html """ manually_approve_followers = \ @@ -1313,7 +1316,8 @@ def html_inbox(css_cache: {}, default_timeline: str, access_keys, system_language, max_like_count, shared_items_federated_domains, signing_priv_key_pem, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, + bold_reading) def html_bookmarks(css_cache: {}, default_timeline: str, @@ -1343,7 +1347,7 @@ def html_bookmarks(css_cache: {}, default_timeline: str, shared_items_federated_domains: [], signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the bookmarks as html """ manually_approve_followers = \ @@ -1372,7 +1376,8 @@ def html_bookmarks(css_cache: {}, default_timeline: str, allow_local_network_access, text_mode_banner, access_keys, system_language, max_like_count, shared_items_federated_domains, signing_priv_key_pem, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, + bold_reading) def html_inbox_dms(css_cache: {}, default_timeline: str, @@ -1402,7 +1407,7 @@ def html_inbox_dms(css_cache: {}, default_timeline: str, shared_items_federated_domains: [], signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the DM timeline as html """ artist = is_artist(base_dir, nickname) @@ -1427,7 +1432,8 @@ def html_inbox_dms(css_cache: {}, default_timeline: str, access_keys, system_language, max_like_count, shared_items_federated_domains, signing_priv_key_pem, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, + bold_reading) def html_inbox_replies(css_cache: {}, default_timeline: str, @@ -1457,7 +1463,7 @@ def html_inbox_replies(css_cache: {}, default_timeline: str, shared_items_federated_domains: [], signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the replies timeline as html """ artist = is_artist(base_dir, nickname) @@ -1481,7 +1487,7 @@ def html_inbox_replies(css_cache: {}, default_timeline: str, allow_local_network_access, text_mode_banner, access_keys, system_language, max_like_count, shared_items_federated_domains, signing_priv_key_pem, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, bold_reading) def html_inbox_media(css_cache: {}, default_timeline: str, @@ -1511,7 +1517,7 @@ def html_inbox_media(css_cache: {}, default_timeline: str, shared_items_federated_domains: [], signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the media timeline as html """ artist = is_artist(base_dir, nickname) @@ -1535,7 +1541,7 @@ def html_inbox_media(css_cache: {}, default_timeline: str, allow_local_network_access, text_mode_banner, access_keys, system_language, max_like_count, shared_items_federated_domains, signing_priv_key_pem, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, bold_reading) def html_inbox_blogs(css_cache: {}, default_timeline: str, @@ -1565,7 +1571,7 @@ def html_inbox_blogs(css_cache: {}, default_timeline: str, shared_items_federated_domains: [], signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the blogs timeline as html """ artist = is_artist(base_dir, nickname) @@ -1589,7 +1595,7 @@ def html_inbox_blogs(css_cache: {}, default_timeline: str, allow_local_network_access, text_mode_banner, access_keys, system_language, max_like_count, shared_items_federated_domains, signing_priv_key_pem, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, bold_reading) def html_inbox_features(css_cache: {}, default_timeline: str, @@ -1620,7 +1626,7 @@ def html_inbox_features(css_cache: {}, default_timeline: str, shared_items_federated_domains: [], signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the features timeline as html """ return html_timeline(css_cache, default_timeline, @@ -1643,7 +1649,7 @@ def html_inbox_features(css_cache: {}, default_timeline: str, allow_local_network_access, text_mode_banner, access_keys, system_language, max_like_count, shared_items_federated_domains, signing_priv_key_pem, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, bold_reading) def html_inbox_news(css_cache: {}, default_timeline: str, @@ -1673,7 +1679,7 @@ def html_inbox_news(css_cache: {}, default_timeline: str, shared_items_federated_domains: [], signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the news timeline as html """ return html_timeline(css_cache, default_timeline, @@ -1696,7 +1702,7 @@ def html_inbox_news(css_cache: {}, default_timeline: str, allow_local_network_access, text_mode_banner, access_keys, system_language, max_like_count, shared_items_federated_domains, signing_priv_key_pem, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, bold_reading) def html_outbox(css_cache: {}, default_timeline: str, @@ -1726,7 +1732,7 @@ def html_outbox(css_cache: {}, default_timeline: str, shared_items_federated_domains: [], signing_priv_key_pem: str, cw_lists: {}, lists_enabled: str, - timezone: str) -> str: + timezone: str, bold_reading: bool) -> str: """Show the Outbox as html """ manually_approve_followers = \ @@ -1752,4 +1758,4 @@ def html_outbox(css_cache: {}, default_timeline: str, allow_local_network_access, text_mode_banner, access_keys, system_language, max_like_count, shared_items_federated_domains, signing_priv_key_pem, - cw_lists, lists_enabled, timezone) + cw_lists, lists_enabled, timezone, bold_reading) From 8d3ec4a0ccf3033c05075257c0a04d187dd0b632 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 13:19:19 +0000 Subject: [PATCH 05/24] Missing get --- daemon.py | 14 +++++++------- webapp_profile.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/daemon.py b/daemon.py index 22de6d91b..b961ccecc 100644 --- a/daemon.py +++ b/daemon.py @@ -3037,7 +3037,7 @@ class PubServer(BaseHTTPRequestHandler): reply_is_chat = False bold_reading = False - if self.server.bold_reading(chooser_nickname): + if self.server.bold_reading.get(chooser_nickname): bold_reading = True msg = html_new_post(self.server.css_cache, @@ -3718,7 +3718,7 @@ class PubServer(BaseHTTPRequestHandler): timezone = \ self.server.account_timezone.get(nickname) bold_reading = False - if self.server.bold_reading(nickname): + if self.server.bold_reading.get(nickname): bold_reading = True hashtag_str = \ html_hashtag_search(self.server.css_cache, @@ -3823,7 +3823,7 @@ class PubServer(BaseHTTPRequestHandler): timezone = \ self.server.account_timezone.get(nickname) bold_reading = False - if self.server.bold_reading(nickname): + if self.server.bold_reading.get(nickname): bold_reading = True history_str = \ html_history_search(self.server.css_cache, @@ -8259,7 +8259,7 @@ class PubServer(BaseHTTPRequestHandler): timezone = \ self.server.account_timezone.get(nickname) bold_reading = False - if self.server.bold_reading(nickname): + if self.server.bold_reading.get(nickname): bold_reading = True hashtag_str = \ html_hashtag_search(self.server.css_cache, @@ -12014,7 +12014,7 @@ class PubServer(BaseHTTPRequestHandler): timezone = \ self.server.account_timezone.get(nickname) bold_reading = False - if self.server.bold_reading(nickname): + if self.server.bold_reading.get(nickname): bold_reading = True msg = \ html_inbox_media(self.server.css_cache, @@ -13306,7 +13306,7 @@ class PubServer(BaseHTTPRequestHandler): timezone = \ self.server.account_timezone.get(nickname) bold_reading = False - if self.server.bold_reading(nickname): + if self.server.bold_reading.get(nickname): bold_reading = True msg = \ html_profile(self.server.signing_priv_key_pem, @@ -13583,7 +13583,7 @@ class PubServer(BaseHTTPRequestHandler): shared_items_federated_domains = \ self.server.shared_items_federated_domains bold_reading = False - if self.server.bold_reading(nickname): + if self.server.bold_reading.get(nickname): bold_reading = True msg = \ html_profile(self.server.signing_priv_key_pem, diff --git a/webapp_profile.py b/webapp_profile.py index d10777f82..c4f507d08 100644 --- a/webapp_profile.py +++ b/webapp_profile.py @@ -2186,7 +2186,7 @@ def html_edit_profile(server, css_cache: {}, translate: {}, domain_full = get_full_domain(domain, port) bold_reading = False - if server.bold_reading(nickname): + if server.bold_reading[nickname]: bold_reading = True actor_filename = acct_dir(base_dir, nickname, domain) + '.json' From a421e78b744736d683a34aeb70276cdab3e999d0 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 13:21:40 +0000 Subject: [PATCH 06/24] Missing get --- daemon.py | 2 +- webapp_profile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/daemon.py b/daemon.py index b961ccecc..ff455f827 100644 --- a/daemon.py +++ b/daemon.py @@ -6699,7 +6699,7 @@ class PubServer(BaseHTTPRequestHandler): print('EX: unable to write bold reading ' + bold_reading_filename) if not bold_reading: - if self.server.bold_reading[nickname]: + if self.server.bold_reading.get(nickname): del self.server.bold_reading[nickname] if os.path.isfile(bold_reading_filename): try: diff --git a/webapp_profile.py b/webapp_profile.py index c4f507d08..62579c754 100644 --- a/webapp_profile.py +++ b/webapp_profile.py @@ -2186,7 +2186,7 @@ def html_edit_profile(server, css_cache: {}, translate: {}, domain_full = get_full_domain(domain, port) bold_reading = False - if server.bold_reading[nickname]: + if server.bold_reading.get(nickname): bold_reading = True actor_filename = acct_dir(base_dir, nickname, domain) + '.json' From 5373160fbfcf76fa71205d7937a442aed8014eb2 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 13:27:07 +0000 Subject: [PATCH 07/24] Change terminology --- daemon.py | 72 +++++++++++++++++++++++++++---------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/daemon.py b/daemon.py index ff455f827..018dd4a3a 100644 --- a/daemon.py +++ b/daemon.py @@ -8502,9 +8502,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(announce_filename.replace('.json', '') + '.mitm'): mitm = True - bionic_reading = False - if self.server.bionic_reading.get(self.post_to_nickname): - bionic_reading = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, self.server.max_recent_posts, @@ -8533,7 +8533,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm, bionic_reading) + timezone, mitm, bold_reading) actor_absolute = self._get_instance_url(calling_domain) + actor actor_path_str = \ @@ -9046,9 +9046,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(liked_post_filename.replace('.json', '') + '.mitm'): mitm = True - bionic_reading = False - if self.server.bionic_reading.get(self.post_to_nickname): - bionic_reading = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9079,7 +9079,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm, bionic_reading) + timezone, mitm, bold_reading) else: print('WARN: Liked post not found: ' + liked_post_filename) # clear the icon from the cache so that it gets updated @@ -9231,9 +9231,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(liked_post_filename.replace('.json', '') + '.mitm'): mitm = True - bionic_reading = False - if self.server.bionic_reading.get(self.post_to_nickname): - bionic_reading = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9264,7 +9264,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm, bionic_reading) + timezone, mitm, bold_reading) else: print('WARN: Unliked post not found: ' + liked_post_filename) # clear the icon from the cache so that it gets updated @@ -9445,9 +9445,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(reaction_post_filename.replace('.json', '') + '.mitm'): mitm = True - bionic_reading = False - if self.server.bionic_reading.get(self.post_to_nickname): - bionic_reading = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9478,7 +9478,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm, bionic_reading) + timezone, mitm, bold_reading) else: print('WARN: Emoji reaction post not found: ' + reaction_post_filename) @@ -9649,9 +9649,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(reaction_post_filename.replace('.json', '') + '.mitm'): mitm = True - bionic_reading = False - if self.server.bionic_reading.get(self.post_to_nickname): - bionic_reading = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9682,7 +9682,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm, bionic_reading) + timezone, mitm, bold_reading) else: print('WARN: Unreaction post not found: ' + reaction_post_filename) @@ -9908,9 +9908,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(bookmark_filename.replace('.json', '') + '.mitm'): mitm = True - bionic_reading = False - if self.server.bionic_reading.get(self.post_to_nickname): - bionic_reading = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -9941,7 +9941,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm, bionic_reading) + timezone, mitm, bold_reading) else: print('WARN: Bookmarked post not found: ' + bookmark_filename) # self._post_to_outbox(bookmark_json, @@ -10067,9 +10067,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(bookmark_filename.replace('.json', '') + '.mitm'): mitm = True - bionic_reading = False - if self.server.bionic_reading.get(self.post_to_nickname): - bionic_reading = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True individual_post_as_html(self.server.signing_priv_key_pem, False, self.server.recent_posts_cache, @@ -10100,7 +10100,7 @@ class PubServer(BaseHTTPRequestHandler): False, True, False, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm, bionic_reading) + timezone, mitm, bold_reading) else: print('WARN: Unbookmarked post not found: ' + bookmark_filename) @@ -10303,9 +10303,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(mute_filename.replace('.json', '') + '.mitm'): mitm = True - bionic_reading = False - if self.server.bionic_reading.get(nickname): - bionic_reading = True + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True individual_post_as_html(self.server.signing_priv_key_pem, allow_downloads, self.server.recent_posts_cache, @@ -10337,7 +10337,7 @@ class PubServer(BaseHTTPRequestHandler): use_cache_only, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm, bionic_reading) + timezone, mitm, bold_reading) else: print('WARN: Muted post not found: ' + mute_filename) @@ -10430,9 +10430,9 @@ class PubServer(BaseHTTPRequestHandler): if os.path.isfile(mute_filename.replace('.json', '') + '.mitm'): mitm = True - bionic_reading = False - if self.server.bionic_reading.get(nickname): - bionic_reading = True + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True individual_post_as_html(self.server.signing_priv_key_pem, allow_downloads, self.server.recent_posts_cache, @@ -10464,7 +10464,7 @@ class PubServer(BaseHTTPRequestHandler): use_cache_only, self.server.cw_lists, self.server.lists_enabled, - timezone, mitm, bionic_reading) + timezone, mitm, bold_reading) else: print('WARN: Unmuted post not found: ' + mute_filename) if calling_domain.endswith('.onion') and onion_domain: From 7816f2883345984e5dac74df1ec83324584e01f3 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 13:35:12 +0000 Subject: [PATCH 08/24] Add bold later after pgp check --- webapp_post.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/webapp_post.py b/webapp_post.py index bf10079c0..abddedb6a 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -1983,13 +1983,14 @@ def individual_post_as_html(signing_priv_key_pem: str, post_json_object['object']['type'], summary_str, content_str) - if bold_reading and not is_patch and not displaying_ciphertext: - content_str = bold_reading_string(content_str) - _log_post_timing(enable_timing_log, post_start_time, '16') if not is_pgp_encrypted(content_str): if not is_patch: + # Add bold text + if bold_reading and not displaying_ciphertext: + content_str = bold_reading_string(content_str) + object_content = \ remove_long_words(content_str, 40, []) object_content = remove_text_formatting(object_content) From d0f6ddd296298e026dacac3d4effdefbdbe2eeb4 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 13:38:10 +0000 Subject: [PATCH 09/24] Don't embolden emoji strings --- content.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content.py b/content.py index c2aad31ac..02f666159 100644 --- a/content.py +++ b/content.py @@ -1339,7 +1339,9 @@ def bold_reading_string(text: str) -> str: words = parag.split(' ') new_parag = '' for wrd in words: - if len(wrd) > 1 and '<' not in wrd and '>' not in wrd: + if len(wrd) > 1 and \ + '<' not in wrd and '>' not in wrd and \ + not wrd.startswith(':'): initial_chars = int(len(wrd) / 2) new_parag += \ '' + wrd[:initial_chars] + '' + \ From a1f20969003ef63662f0a4a719f1e73e83573c58 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 13:45:55 +0000 Subject: [PATCH 10/24] Handle emboldened text with quotes --- content.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/content.py b/content.py index 02f666159..c8000411a 100644 --- a/content.py +++ b/content.py @@ -1342,10 +1342,20 @@ def bold_reading_string(text: str) -> str: if len(wrd) > 1 and \ '<' not in wrd and '>' not in wrd and \ not wrd.startswith(':'): + + prefix = '' + postfix = '' + if wrd.startswith('"'): + prefix = '"' + wrd = wrd[1:] + if wrd.endswith('"'): + postfix = '"' + wrd = wrd[:len(wrd) - 1] + initial_chars = int(len(wrd) / 2) new_parag += \ - '' + wrd[:initial_chars] + '' + \ - wrd[initial_chars:] + ' ' + prefix + '' + wrd[:initial_chars] + '' + \ + wrd[initial_chars:] + postfix + ' ' else: new_parag += wrd + ' ' parag_ctr += 1 From 15795248d746af20fecab892c5d70bde8868ce62 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 13:48:42 +0000 Subject: [PATCH 11/24] Tidying --- inbox.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/inbox.py b/inbox.py index 561a09d80..fd6d1bb83 100644 --- a/inbox.py +++ b/inbox.py @@ -3780,8 +3780,6 @@ def _inbox_after_initial(server, boxname + ' post as html to cache in ' + time_diff + ' mS') - handle_name = handle.split('@')[0] - # is this an edit of a previous post? # in Mastodon "delete and redraft" # NOTE: this must be done before update_conversation is called From 4ea1f7e1bde1e8b64879573d6a92e3657fe66a9f Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 13:53:56 +0000 Subject: [PATCH 12/24] More robust bold reading detection --- inbox.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/inbox.py b/inbox.py index fd6d1bb83..ef3e2de02 100644 --- a/inbox.py +++ b/inbox.py @@ -3350,7 +3350,7 @@ def _inbox_after_initial(server, cw_lists: {}, lists_enabled: str, content_license_url: str, languages_understood: [], - mitm: bool) -> bool: + mitm: bool, bold_reading: bool) -> bool: """ Anything which needs to be done after initial checks have passed """ # if this is a clearnet instance then replace any onion/i2p @@ -3377,10 +3377,6 @@ def _inbox_after_initial(server, handle_name = handle.split('@')[0] - bold_reading = False - if server.bold_reading.get(handle_name): - bold_reading = True - if _receive_like(recent_posts_cache, session, handle, is_group, base_dir, http_prefix, @@ -4807,6 +4803,11 @@ def run_inbox_queue(server, mitm = False if queue_json.get('mitm'): mitm = True + bold_reading = False + bold_reading_filename = \ + base_dir + '/accounts/' + handle + '/.boldReading' + if os.path.isfile(bold_reading_filename): + bold_reading = True _inbox_after_initial(server, recent_posts_cache, max_recent_posts, @@ -4838,7 +4839,8 @@ def run_inbox_queue(server, default_reply_interval_hrs, cw_lists, lists_enabled, content_license_url, - languages_understood, mitm) + languages_understood, mitm, + bold_reading) if debug: pprint(queue_json['post']) print('Queue: Queue post accepted') From ea6520c7fbb12219ac7d635ec4177674fc0b222f Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 14:08:07 +0000 Subject: [PATCH 13/24] Avoid emboldening spaces within markup --- content.py | 9 +++++++-- tests.py | 11 +++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/content.py b/content.py index c8000411a..77391ce5a 100644 --- a/content.py +++ b/content.py @@ -1334,12 +1334,17 @@ def bold_reading_string(text: str) -> str: add_paragraph_markup = True paragraphs = text.split('\n') parag_ctr = 0 - new_text = '' + new_text = '' for parag in paragraphs: words = parag.split(' ') new_parag = '' + reading_markup = False for wrd in words: - if len(wrd) > 1 and \ + if '<' in wrd and '>' not in wrd: + reading_markup = True + if reading_markup and '>' in wrd and '<' not in wrd: + reading_markup = False + if not reading_markup and len(wrd) > 1 and \ '<' not in wrd and '>' not in wrd and \ not wrd.startswith(':'): diff --git a/tests.py b/tests.py index 838c669d1..fb4ef453c 100644 --- a/tests.py +++ b/tests.py @@ -6720,6 +6720,17 @@ def _test_bold_reading() -> None: print(text_bold) assert text_bold == expected + text = '

This is a test with markup containing spaces

' + text_bold = bold_reading_string(text) + expected = \ + '

This is a test ' + \ + 'with ' + \ + 'markup containing spaces

' + if text_bold != expected: + print(text_bold) + assert text_bold == expected + def run_all_tests(): base_dir = os.getcwd() From ddbe5bfc5c65804a3162a4e7e7797458ded24e70 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 14:22:12 +0000 Subject: [PATCH 14/24] Don't embolden blog posts --- webapp_post.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/webapp_post.py b/webapp_post.py index abddedb6a..f49bed27a 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -1890,7 +1890,9 @@ def individual_post_as_html(signing_priv_key_pem: str, published_link = message_id # blog posts should have no /statuses/ in their link + post_is_blog = False if is_blog_post(post_json_object): + post_is_blog = True # is this a post to the local domain? if '://' + domain in message_id: published_link = message_id.replace('/statuses/', '/') @@ -1988,7 +1990,9 @@ def individual_post_as_html(signing_priv_key_pem: str, if not is_pgp_encrypted(content_str): if not is_patch: # Add bold text - if bold_reading and not displaying_ciphertext: + if bold_reading and \ + not displaying_ciphertext and \ + not post_is_blog: content_str = bold_reading_string(content_str) object_content = \ From fd072faee7a1dc2bca4b591761527c8c589b148f Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 14:23:34 +0000 Subject: [PATCH 15/24] Debug --- webapp_post.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/webapp_post.py b/webapp_post.py index f49bed27a..7b2038f04 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -1987,13 +1987,16 @@ def individual_post_as_html(signing_priv_key_pem: str, _log_post_timing(enable_timing_log, post_start_time, '16') + print('Test bold_reading 1 ' + str(bold_reading)) if not is_pgp_encrypted(content_str): if not is_patch: # Add bold text + print('Test bold_reading 2 ' + str(bold_reading)) if bold_reading and \ not displaying_ciphertext and \ not post_is_blog: content_str = bold_reading_string(content_str) + print('Test bold_reading 3 ' + content_str) object_content = \ remove_long_words(content_str, 40, []) From 5320e7ed7b6a1e10840a1810abbd761aa091f83a Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 14:40:28 +0000 Subject: [PATCH 16/24] Allow bold markup for bold reading --- content.py | 7 +++++-- desktop_client.py | 11 +++++++---- inbox.py | 5 +++-- outbox.py | 10 ++++++---- posts.py | 9 +++++---- tests.py | 4 ++-- webapp_post.py | 8 +++----- 7 files changed, 31 insertions(+), 23 deletions(-) diff --git a/content.py b/content.py index 77391ce5a..64da22c89 100644 --- a/content.py +++ b/content.py @@ -701,7 +701,7 @@ def replace_content_duplicates(content: str) -> str: return content -def remove_text_formatting(content: str) -> str: +def remove_text_formatting(content: str, bold_reading: bool) -> str: """Removes markup for bold, italics, etc """ if is_pgp_encrypted(content) or contains_pgp_public_key(content): @@ -709,6 +709,9 @@ def remove_text_formatting(content: str) -> str: if '<' not in content: return content for markup in REMOVE_MARKUP: + if bold_reading: + if markup == 'b': + continue content = content.replace('<' + markup + '>', '') content = content.replace('', '') content = content.replace('<' + markup.upper() + '>', '') @@ -1334,7 +1337,7 @@ def bold_reading_string(text: str) -> str: add_paragraph_markup = True paragraphs = text.split('\n') parag_ctr = 0 - new_text = '' + new_text = '' for parag in paragraphs: words = parag.split(' ') new_parag = '' diff --git a/desktop_client.py b/desktop_client.py index 35d83f535..acd8dc95d 100644 --- a/desktop_client.py +++ b/desktop_client.py @@ -683,7 +683,7 @@ def _read_local_box_post(session, nickname: str, domain: str, translate: {}, your_actor: str, domain_full: str, person_cache: {}, signing_priv_key_pem: str, - blocked_cache: {}) -> {}: + blocked_cache: {}, bold_reading: bool) -> {}: """Reads a post from the given timeline Returns the post json """ @@ -724,7 +724,7 @@ def _read_local_box_post(session, nickname: str, domain: str, system_language, domain_full, person_cache, signing_priv_key_pem, - blocked_cache) + blocked_cache, bold_reading) if post_json_object2: if has_object_dict(post_json_object2): if post_json_object2['object'].get('attributedTo') and \ @@ -1356,6 +1356,8 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, """Runs the desktop and screen reader client, which announces new inbox items """ + bold_reading = False + # TODO: this should probably be retrieved somehow from the server signing_priv_key_pem = None @@ -1674,7 +1676,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, espeak, translate, your_actor, domain_full, person_cache, signing_priv_key_pem, - blocked_cache) + blocked_cache, bold_reading) print('') say_str = 'Press Enter to continue...' say_str2 = _highlight_text(say_str) @@ -2464,7 +2466,8 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, system_language, domain_full, person_cache, signing_priv_key_pem, - blocked_cache) + blocked_cache, + bold_reading) if post_json_object2: post_json_object = post_json_object2 if post_json_object: diff --git a/inbox.py b/inbox.py index ef3e2de02..87a6f16f3 100644 --- a/inbox.py +++ b/inbox.py @@ -2041,7 +2041,7 @@ def _receive_announce(recent_posts_cache: {}, system_language, domain_full, person_cache, signing_priv_key_pem, - blocked_cache) + blocked_cache, bold_reading) if not post_json_object: print('WARN: unable to download announce: ' + str(message_json)) not_in_onion = True @@ -3681,7 +3681,8 @@ def _inbox_after_initial(server, twitter_replacement_domain, allow_local_network_access, recent_posts_cache, debug, system_language, - domain_full, person_cache, signing_priv_key_pem): + domain_full, person_cache, signing_priv_key_pem, + bold_reading): # media index will be updated update_index_list.append('tlmedia') if is_blog_post(post_json_object): diff --git a/outbox.py b/outbox.py index 07d321aa8..db2f8877e 100644 --- a/outbox.py +++ b/outbox.py @@ -219,6 +219,10 @@ def post_message_to_outbox(session, translate: {}, domain, port, message_json) + bold_reading = False + if server.bold_reading.get(post_to_nickname): + bold_reading = True + # check that the outgoing post doesn't contain any markup # which can be used to implement exploits if has_object_dict(message_json): @@ -430,7 +434,8 @@ def post_message_to_outbox(session, translate: {}, recent_posts_cache, debug, system_language, domain_full, person_cache, - signing_priv_key_pem): + signing_priv_key_pem, + bold_reading): inbox_update_index('tlmedia', base_dir, post_to_nickname + '@' + domain, saved_filename, debug) @@ -461,9 +466,6 @@ def post_message_to_outbox(session, translate: {}, if os.path.isfile(saved_filename.replace('.json', '') + '.mitm'): mitm = True - bold_reading = False - if server.bold_reading.get(post_to_nickname): - bold_reading = True individual_post_as_html(signing_priv_key_pem, False, recent_posts_cache, max_recent_posts, diff --git a/posts.py b/posts.py index 18445b70a..f587f5d3d 100644 --- a/posts.py +++ b/posts.py @@ -3683,7 +3683,8 @@ def is_image_media(session, base_dir: str, http_prefix: str, recent_posts_cache: {}, debug: bool, system_language: str, domain_full: str, person_cache: {}, - signing_priv_key_pem: str) -> bool: + signing_priv_key_pem: str, + bold_reading: bool) -> bool: """Returns true if the given post has attached image media """ if post_json_object['type'] == 'Announce': @@ -3699,7 +3700,7 @@ def is_image_media(session, base_dir: str, http_prefix: str, system_language, domain_full, person_cache, signing_priv_key_pem, - blocked_cache) + blocked_cache, bold_reading) if post_json_announce: post_json_object = post_json_announce if post_json_object['type'] != 'Create': @@ -4765,7 +4766,7 @@ def download_announce(session, base_dir: str, http_prefix: str, system_language: str, domain_full: str, person_cache: {}, signing_priv_key_pem: str, - blocked_cache: {}) -> {}: + blocked_cache: {}, bold_reading: bool) -> {}: """Download the post referenced by an announce """ if not post_json_object.get('object'): @@ -4972,7 +4973,7 @@ def download_announce(session, base_dir: str, http_prefix: str, content_str = limit_repeated_words(content_str, 6) # remove text formatting, such as bold/italics - content_str = remove_text_formatting(content_str) + content_str = remove_text_formatting(content_str, bold_reading) # set the content after santitization announced_json['content'] = content_str diff --git a/tests.py b/tests.py index fb4ef453c..d377161d7 100644 --- a/tests.py +++ b/tests.py @@ -3728,10 +3728,10 @@ def _test_recent_posts_cache(): def _test_remove_txt_formatting(): print('test_remove_txt_formatting') test_str = '

Text without formatting

' - result_str = remove_text_formatting(test_str) + result_str = remove_text_formatting(test_str, False) assert result_str == test_str test_str = '

Text with

formatting

' - result_str = remove_text_formatting(test_str) + result_str = remove_text_formatting(test_str, False) assert result_str == '

Text with formatting

' diff --git a/webapp_post.py b/webapp_post.py index 7b2038f04..567bdf322 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -1604,7 +1604,7 @@ def individual_post_as_html(signing_priv_key_pem: str, system_language, domain_full, person_cache, signing_priv_key_pem, - blocked_cache) + blocked_cache, bold_reading) if not post_json_announce: # if the announce could not be downloaded then mark it as rejected announced_post_id = remove_id_ending(post_json_object['id']) @@ -1987,20 +1987,18 @@ def individual_post_as_html(signing_priv_key_pem: str, _log_post_timing(enable_timing_log, post_start_time, '16') - print('Test bold_reading 1 ' + str(bold_reading)) if not is_pgp_encrypted(content_str): if not is_patch: # Add bold text - print('Test bold_reading 2 ' + str(bold_reading)) if bold_reading and \ not displaying_ciphertext and \ not post_is_blog: content_str = bold_reading_string(content_str) - print('Test bold_reading 3 ' + content_str) object_content = \ remove_long_words(content_str, 40, []) - object_content = remove_text_formatting(object_content) + object_content = \ + remove_text_formatting(object_content, bold_reading) object_content = limit_repeated_words(object_content, 6) object_content = \ switch_words(base_dir, nickname, domain, object_content) From 65f26f4046ed27f4c3c7930db92a7865066cdf3c Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 14:45:13 +0000 Subject: [PATCH 17/24] Simplify --- inbox.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/inbox.py b/inbox.py index 87a6f16f3..09bafacfa 100644 --- a/inbox.py +++ b/inbox.py @@ -3350,7 +3350,7 @@ def _inbox_after_initial(server, cw_lists: {}, lists_enabled: str, content_license_url: str, languages_understood: [], - mitm: bool, bold_reading: bool) -> bool: + mitm: bool) -> bool: """ Anything which needs to be done after initial checks have passed """ # if this is a clearnet instance then replace any onion/i2p @@ -3377,6 +3377,10 @@ def _inbox_after_initial(server, handle_name = handle.split('@')[0] + bold_reading = False + if server.bold_reading.get(handle_name): + bold_reading = True + if _receive_like(recent_posts_cache, session, handle, is_group, base_dir, http_prefix, @@ -4804,11 +4808,6 @@ def run_inbox_queue(server, mitm = False if queue_json.get('mitm'): mitm = True - bold_reading = False - bold_reading_filename = \ - base_dir + '/accounts/' + handle + '/.boldReading' - if os.path.isfile(bold_reading_filename): - bold_reading = True _inbox_after_initial(server, recent_posts_cache, max_recent_posts, @@ -4840,8 +4839,7 @@ def run_inbox_queue(server, default_reply_interval_hrs, cw_lists, lists_enabled, content_license_url, - languages_understood, mitm, - bold_reading) + languages_understood, mitm) if debug: pprint(queue_json['post']) print('Queue: Queue post accepted') From c7ed2626913f8bc7e0d463a6fe11da19fff78290 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 14:46:22 +0000 Subject: [PATCH 18/24] Avoid emboldening words containing and --- content.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content.py b/content.py index 64da22c89..de7838e39 100644 --- a/content.py +++ b/content.py @@ -1349,7 +1349,7 @@ def bold_reading_string(text: str) -> str: reading_markup = False if not reading_markup and len(wrd) > 1 and \ '<' not in wrd and '>' not in wrd and \ - not wrd.startswith(':'): + '&' not in wrd and not wrd.startswith(':'): prefix = '' postfix = '' From f6da511dbf9a23c0f858fb07c65c54f439774677 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 14:49:44 +0000 Subject: [PATCH 19/24] Revert "Simplify" This reverts commit 65f26f4046ed27f4c3c7930db92a7865066cdf3c. --- inbox.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/inbox.py b/inbox.py index 09bafacfa..87a6f16f3 100644 --- a/inbox.py +++ b/inbox.py @@ -3350,7 +3350,7 @@ def _inbox_after_initial(server, cw_lists: {}, lists_enabled: str, content_license_url: str, languages_understood: [], - mitm: bool) -> bool: + mitm: bool, bold_reading: bool) -> bool: """ Anything which needs to be done after initial checks have passed """ # if this is a clearnet instance then replace any onion/i2p @@ -3377,10 +3377,6 @@ def _inbox_after_initial(server, handle_name = handle.split('@')[0] - bold_reading = False - if server.bold_reading.get(handle_name): - bold_reading = True - if _receive_like(recent_posts_cache, session, handle, is_group, base_dir, http_prefix, @@ -4808,6 +4804,11 @@ def run_inbox_queue(server, mitm = False if queue_json.get('mitm'): mitm = True + bold_reading = False + bold_reading_filename = \ + base_dir + '/accounts/' + handle + '/.boldReading' + if os.path.isfile(bold_reading_filename): + bold_reading = True _inbox_after_initial(server, recent_posts_cache, max_recent_posts, @@ -4839,7 +4840,8 @@ def run_inbox_queue(server, default_reply_interval_hrs, cw_lists, lists_enabled, content_license_url, - languages_understood, mitm) + languages_understood, mitm, + bold_reading) if debug: pprint(queue_json['post']) print('Queue: Queue post accepted') From 0f2b28ed1fce516d1bf3aecd03b478b3db9efc73 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 14:59:41 +0000 Subject: [PATCH 20/24] Unquote text --- content.py | 1 + 1 file changed, 1 insertion(+) diff --git a/content.py b/content.py index de7838e39..81b8d107e 100644 --- a/content.py +++ b/content.py @@ -1331,6 +1331,7 @@ def contains_invalid_local_links(content: str) -> bool: def bold_reading_string(text: str) -> str: """Returns bold reading formatted text """ + text = urllib.parse.unquote(text) add_paragraph_markup = False if '

' in text: text = text.replace('

', '\n').replace('

', '') From bca1f1c5b703d527c119185ae9c7ab643b60ca88 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 15:15:53 +0000 Subject: [PATCH 21/24] Unescape before adding bold --- content.py | 3 ++- tests.py | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/content.py b/content.py index 81b8d107e..c649e7fa8 100644 --- a/content.py +++ b/content.py @@ -7,6 +7,7 @@ __email__ = "bob@libreserver.org" __status__ = "Production" __module_group__ = "Core" +import html import os import email.parser import urllib.parse @@ -1331,7 +1332,7 @@ def contains_invalid_local_links(content: str) -> bool: def bold_reading_string(text: str) -> str: """Returns bold reading formatted text """ - text = urllib.parse.unquote(text) + text = html.unescape(text) add_paragraph_markup = False if '

' in text: text = text.replace('

', '\n').replace('

', '') diff --git a/tests.py b/tests.py index d377161d7..7cc08206a 100644 --- a/tests.py +++ b/tests.py @@ -6731,6 +6731,14 @@ def _test_bold_reading() -> None: print(text_bold) assert text_bold == expected + text = "There's some quoted text here" + text_bold = bold_reading_string(text) + expected = \ + "There's some quoted text here" + if text_bold != expected: + print(text_bold) + assert text_bold == expected + def run_all_tests(): base_dir = os.getcwd() From 9fdca7919c9fd1d035117c60d1b713ae5f07a061 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 15:32:37 +0000 Subject: [PATCH 22/24] Improve handling of markup while emboldening text --- content.py | 4 ++-- tests.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/content.py b/content.py index c649e7fa8..0bf1f9273 100644 --- a/content.py +++ b/content.py @@ -1345,9 +1345,9 @@ def bold_reading_string(text: str) -> str: new_parag = '' reading_markup = False for wrd in words: - if '<' in wrd and '>' not in wrd: + if '<' in wrd: reading_markup = True - if reading_markup and '>' in wrd and '<' not in wrd: + if reading_markup and '>' in wrd: reading_markup = False if not reading_markup and len(wrd) > 1 and \ '<' not in wrd and '>' not in wrd and \ diff --git a/tests.py b/tests.py index 7cc08206a..98d4e4d4a 100644 --- a/tests.py +++ b/tests.py @@ -6721,12 +6721,12 @@ def _test_bold_reading() -> None: assert text_bold == expected text = '

This is a test with markup containing spaces

' + 'href="some_url">

' text_bold = bold_reading_string(text) expected = \ '

This is a test ' + \ - 'with ' + \ - 'markup containing spaces

' + '

' if text_bold != expected: print(text_bold) assert text_bold == expected From 2c087d5e2aed61300bc04ed2627355ba9a05a0ee Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 15:57:44 +0000 Subject: [PATCH 23/24] Another unit test for markup with bold reading --- content.py | 5 ++++- tests.py | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/content.py b/content.py index 0bf1f9273..387ec7b59 100644 --- a/content.py +++ b/content.py @@ -1351,7 +1351,8 @@ def bold_reading_string(text: str) -> str: reading_markup = False if not reading_markup and len(wrd) > 1 and \ '<' not in wrd and '>' not in wrd and \ - '&' not in wrd and not wrd.startswith(':'): + '&' not in wrd and '=' not in wrd and \ + not wrd.startswith(':'): prefix = '' postfix = '' @@ -1370,6 +1371,8 @@ def bold_reading_string(text: str) -> str: new_parag += wrd + ' ' parag_ctr += 1 new_parag = new_parag.strip() + if not new_parag: + continue if parag_ctr < len(paragraphs): if not add_paragraph_markup: new_text += new_parag + '\n' diff --git a/tests.py b/tests.py index 98d4e4d4a..5bdbb364e 100644 --- a/tests.py +++ b/tests.py @@ -6739,6 +6739,20 @@ def _test_bold_reading() -> None: print(text_bold) assert text_bold == expected + text = '

@Someone or other' + \ + ' some text

' + text_bold = bold_reading_string(text) + expected = \ + '

' + \ + '@Someone or other' + \ + ' some text

' + if text_bold != expected: + print(text_bold) + assert text_bold == expected + def run_all_tests(): base_dir = os.getcwd() From 5b480dd815429592af2b25a52df49e27c9d7d98c Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 24 Mar 2022 16:16:36 +0000 Subject: [PATCH 24/24] Round up word division for bold reading --- content.py | 8 +++++--- tests.py | 10 +++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/content.py b/content.py index 387ec7b59..134d32619 100644 --- a/content.py +++ b/content.py @@ -7,6 +7,7 @@ __email__ = "bob@libreserver.org" __status__ = "Production" __module_group__ = "Core" +import math import html import os import email.parser @@ -1349,7 +1350,8 @@ def bold_reading_string(text: str) -> str: reading_markup = True if reading_markup and '>' in wrd: reading_markup = False - if not reading_markup and len(wrd) > 1 and \ + wrd_len = len(wrd) + if not reading_markup and wrd_len > 1 and \ '<' not in wrd and '>' not in wrd and \ '&' not in wrd and '=' not in wrd and \ not wrd.startswith(':'): @@ -1361,9 +1363,9 @@ def bold_reading_string(text: str) -> str: wrd = wrd[1:] if wrd.endswith('"'): postfix = '"' - wrd = wrd[:len(wrd) - 1] + wrd = wrd[:wrd_len - 1] - initial_chars = int(len(wrd) / 2) + initial_chars = int(math.ceil(wrd_len / 2.0)) new_parag += \ prefix + '' + wrd[:initial_chars] + '' + \ wrd[initial_chars:] + postfix + ' ' diff --git a/tests.py b/tests.py index 5bdbb364e..53f197d1c 100644 --- a/tests.py +++ b/tests.py @@ -6703,7 +6703,7 @@ def _test_bold_reading() -> None: text_bold = bold_reading_string(text) expected = \ "

This is a test of " + \ - "emboldening with paragraph.

" + "emboldening with paragraph.

" if text_bold != expected: print(text_bold) assert text_bold == expected @@ -6714,8 +6714,8 @@ def _test_bold_reading() -> None: text_bold = bold_reading_string(text) expected = \ "

This is a test of " + \ - "emboldening

With more " + \ - "than one paragraph.

" + "emboldening

With more " + \ + "than one paragraph.

" if text_bold != expected: print(text_bold) assert text_bold == expected @@ -6731,10 +6731,10 @@ def _test_bold_reading() -> None: print(text_bold) assert text_bold == expected - text = "There's some quoted text here" + text = "There's the quoted text here" text_bold = bold_reading_string(text) expected = \ - "There's some quoted text here" + "There's the quoted text here" if text_bold != expected: print(text_bold) assert text_bold == expected