From ac6695b9f3b93479ffebaa55875919921464de6c Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Tue, 14 Jun 2022 11:24:29 +0100 Subject: [PATCH 1/6] Tidying --- content.py | 4 ++-- inbox.py | 2 +- session.py | 9 ++++----- speaker.py | 11 +++-------- 4 files changed, 10 insertions(+), 16 deletions(-) diff --git a/content.py b/content.py index c7e5a7b43..adfca5b48 100644 --- a/content.py +++ b/content.py @@ -324,7 +324,7 @@ def _save_custom_emoji(session, base_dir: str, emojiName: str, url: str, if not os.path.isdir(custom_emoji_dir): os.mkdir(custom_emoji_dir) emoji_image_filename = custom_emoji_dir + '/' + emojiName + '.' + ext - if not download_image(session, base_dir, url, + if not download_image(session, url, emoji_image_filename, debug, False): if debug: print('EX: custom emoji not downloaded ' + url) @@ -1573,7 +1573,7 @@ def import_emoji(base_dir: str, import_filename: str, session) -> None: emoji_image_filename = base_dir + '/emoji/' + tag + '.png' if os.path.isfile(emoji_image_filename): continue - if download_image(session, base_dir, url, + if download_image(session, url, emoji_image_filename, True, False): emoji_dict[tag] = tag added += 1 diff --git a/inbox.py b/inbox.py index b89f87aee..89eefaa62 100644 --- a/inbox.py +++ b/inbox.py @@ -186,7 +186,7 @@ def cache_svg_images(session, base_dir: str, http_prefix: str, if not test_image_filename: image_filename = \ base_dir + '/media/' + post_id + '_' + filename - if not download_image(session, base_dir, url, + if not download_image(session, url, image_filename, debug): continue else: diff --git a/session.py b/session.py index 35fed4ab6..dfb072b55 100644 --- a/session.py +++ b/session.py @@ -465,7 +465,7 @@ def post_json(http_prefix: str, domain_full: str, return None -def post_json_string(session, post_jsonStr: str, +def post_json_string(session, post_json_str: str, federation_list: [], inbox_url: str, headers: {}, @@ -489,7 +489,7 @@ def post_json_string(session, post_jsonStr: str, try: post_result = \ - session.post(url=inbox_url, data=post_jsonStr, + session.post(url=inbox_url, data=post_json_str, headers=headers, timeout=timeout_sec) except requests.exceptions.RequestException as ex: if not quiet: @@ -500,7 +500,7 @@ def post_json_string(session, post_jsonStr: str, print('EX: connection was reset during post_json_string') if not quiet: print('EX: post_json_string failed ' + inbox_url + ' ' + - post_jsonStr + ' ' + str(headers)) + post_json_str + ' ' + str(headers)) return None, None, 0 except ValueError as ex: if not quiet: @@ -592,8 +592,7 @@ def _looks_like_url(url: str) -> bool: return True -def download_image(session, base_dir: str, url: str, - image_filename: str, debug: bool, +def download_image(session, url: str, image_filename: str, debug: bool, force: bool = False) -> bool: """Downloads an image with an expected mime type """ diff --git a/speaker.py b/speaker.py index 1cb5fcb7c..7b90bd949 100644 --- a/speaker.py +++ b/speaker.py @@ -320,8 +320,7 @@ def _ssml_header(system_language: str, box_name: str, summary: str) -> str: def _speaker_endpoint_ssml(display_name: str, summary: str, - content: str, image_description: str, - links: [], language: str, + content: str, language: str, gender: str, box_name: str) -> str: """Returns an SSML endpoint for the TTS speaker https://en.wikipedia.org/wiki/Speech_Synthesis_Markup_Language @@ -379,8 +378,6 @@ def get_ssml_box(base_dir: str, path: str, return _speaker_endpoint_ssml(speaker_json['name'], speaker_json['summary'], speaker_json['say'], - speaker_json['imageDescription'], - speaker_json['detectedLinks'], system_language, gender, box_name) @@ -411,7 +408,7 @@ def speakable_text(base_dir: str, content: str, translate: {}) -> (str, []): def _post_to_speaker_json(base_dir: str, http_prefix: str, - nickname: str, domain: str, domain_full: str, + nickname: str, domain_full: str, post_json_object: {}, person_cache: {}, translate: {}, announcing_actor: str, theme_name: str) -> {}: @@ -554,7 +551,7 @@ def update_speaker(base_dir: str, http_prefix: str, """ speaker_json = \ _post_to_speaker_json(base_dir, http_prefix, - nickname, domain, domain_full, + nickname, domain_full, post_json_object, person_cache, translate, announcing_actor, theme_name) @@ -581,8 +578,6 @@ def update_speaker(base_dir: str, http_prefix: str, _speaker_endpoint_ssml(speaker_json['name'], speaker_json['summary'], speaker_json['say'], - speaker_json['imageDescription'], - speaker_json['detectedLinks'], system_language, gender, box_name) try: From 448b0e3120c442aae3aac6f4047d07b388534901 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Tue, 14 Jun 2022 11:51:40 +0100 Subject: [PATCH 2/6] Tidying --- inbox.py | 2 +- languages.py | 2 +- like.py | 3 +-- outbox.py | 3 +-- posts.py | 2 +- question.py | 16 ++++++++-------- schedule.py | 2 +- 7 files changed, 14 insertions(+), 16 deletions(-) diff --git a/inbox.py b/inbox.py index 89eefaa62..3ea239f27 100644 --- a/inbox.py +++ b/inbox.py @@ -2686,7 +2686,7 @@ def _valid_post_content(base_dir: str, nickname: str, domain: str, message_json['object']['tag']) return False # check that the post is in a language suitable for this account - if not understood_post_language(base_dir, nickname, domain, + if not understood_post_language(base_dir, nickname, message_json, system_language, http_prefix, domain_full, person_cache): diff --git a/languages.py b/languages.py index 7b4836692..4563cf8ab 100644 --- a/languages.py +++ b/languages.py @@ -99,7 +99,7 @@ def set_actor_languages(actor_json: {}, languages_str: str) -> None: actor_json['attachment'].append(new_languages) -def understood_post_language(base_dir: str, nickname: str, domain: str, +def understood_post_language(base_dir: str, nickname: str, message_json: {}, system_language: str, http_prefix: str, domain_full: str, person_cache: {}) -> bool: diff --git a/like.py b/like.py index 75814e882..ee19e461d 100644 --- a/like.py +++ b/like.py @@ -385,8 +385,7 @@ def outbox_like(recent_posts_cache: {}, def outbox_undo_like(recent_posts_cache: {}, - base_dir: str, http_prefix: str, - nickname: str, domain: str, port: int, + base_dir: str, nickname: str, domain: str, message_json: {}, debug: bool) -> None: """ When an undo like request is received by the outbox from c2s """ diff --git a/outbox.py b/outbox.py index bcd0a072f..878897a0c 100644 --- a/outbox.py +++ b/outbox.py @@ -580,8 +580,7 @@ def post_message_to_outbox(session, translate: {}, if debug: print('DEBUG: handle any undo like requests') outbox_undo_like(recent_posts_cache, - base_dir, http_prefix, - post_to_nickname, domain, port, + base_dir, post_to_nickname, domain, message_json, debug) if debug: diff --git a/posts.py b/posts.py index fb796e159..86ad51444 100644 --- a/posts.py +++ b/posts.py @@ -4998,7 +4998,7 @@ def download_announce(session, base_dir: str, http_prefix: str, base_dir, nickname, domain, post_id, recent_posts_cache) return None - if not understood_post_language(base_dir, nickname, domain, + if not understood_post_language(base_dir, nickname, announced_json, system_language, http_prefix, domain_full, person_cache): diff --git a/question.py b/question.py index 2e36efe36..04b7561c4 100644 --- a/question.py +++ b/question.py @@ -136,20 +136,20 @@ def question_update_votes(base_dir: str, nickname: str, domain: str, return question_json, question_post_filename -def is_question(postObjectJson: {}) -> bool: +def is_question(post_object_json: {}) -> bool: """ is the given post a question? """ - if postObjectJson['type'] != 'Create' and \ - postObjectJson['type'] != 'Update': + if post_object_json['type'] != 'Create' and \ + post_object_json['type'] != 'Update': return False - if not has_object_dict(postObjectJson): + if not has_object_dict(post_object_json): return False - if not postObjectJson['object'].get('type'): + if not post_object_json['object'].get('type'): return False - if postObjectJson['object']['type'] != 'Question': + if post_object_json['object']['type'] != 'Question': return False - if not postObjectJson['object'].get('oneOf'): + if not post_object_json['object'].get('oneOf'): return False - if not isinstance(postObjectJson['object']['oneOf'], list): + if not isinstance(post_object_json['object']['oneOf'], list): return False return True diff --git a/schedule.py b/schedule.py index 810474b08..d8fa45576 100644 --- a/schedule.py +++ b/schedule.py @@ -193,7 +193,7 @@ def run_post_schedule(base_dir: str, httpd, max_scheduled_posts: int): def run_post_schedule_watchdog(project_version: str, httpd) -> None: """This tries to keep the scheduled post thread running even if it dies """ - print('THREAD: Starting scheduled post watchdog') + print('THREAD: Starting scheduled post watchdog ' + project_version) post_schedule_original = \ httpd.thrPostSchedule.clone(run_post_schedule) httpd.thrPostSchedule.start() From 5ece8e80b5f3f4fbe0e778c84022a1ca454f7ea8 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Tue, 14 Jun 2022 12:42:45 +0100 Subject: [PATCH 3/6] Tidying --- inbox.py | 106 ++++++++++++++++++++----------------------------------- tests.py | 2 +- 2 files changed, 39 insertions(+), 69 deletions(-) diff --git a/inbox.py b/inbox.py index 3ea239f27..cad9ebd37 100644 --- a/inbox.py +++ b/inbox.py @@ -884,9 +884,7 @@ def _inbox_post_recipients(base_dir: str, post_json_object: {}, return recipients_dict, recipients_dict_followers -def _receive_undo_follow(session, base_dir: str, http_prefix: str, - port: int, message_json: {}, - federation_list: [], +def _receive_undo_follow(base_dir: str, message_json: {}, debug: bool, domain: str, onion_domain: str, i2p_domain: str) -> bool: if not message_json['object'].get('actor'): @@ -947,12 +945,8 @@ def _receive_undo_follow(session, base_dir: str, http_prefix: str, return False -def _receive_undo(session, base_dir: str, http_prefix: str, - port: int, send_threads: [], post_log: [], - cached_webfingers: {}, person_cache: {}, - message_json: {}, federation_list: [], - debug: bool, domain: str, - onion_domain: str, i2p_domain: str) -> bool: +def _receive_undo(base_dir: str, message_json: {}, debug: bool, + domain: str, onion_domain: str, i2p_domain: str) -> bool: """Receives an undo request within the POST section of HTTPServer """ if not message_json['type'].startswith('Undo'): @@ -971,10 +965,8 @@ def _receive_undo(session, base_dir: str, http_prefix: str, return False if message_json['object']['type'] == 'Follow' or \ message_json['object']['type'] == 'Join': - return _receive_undo_follow(session, base_dir, http_prefix, - port, message_json, - federation_list, debug, - domain, onion_domain, i2p_domain) + return _receive_undo_follow(base_dir, message_json, + debug, domain, onion_domain, i2p_domain) return False @@ -1242,10 +1234,8 @@ def _receive_edit_to_post(recent_posts_cache: {}, message_json: {}, def _receive_update_activity(recent_posts_cache: {}, session, base_dir: str, http_prefix: str, domain: str, port: int, - send_threads: [], post_log: [], cached_webfingers: {}, person_cache: {}, message_json: {}, - federation_list: [], nickname: str, debug: bool, max_mentions: int, max_emoji: int, allow_local_network_access: bool, @@ -1332,11 +1322,11 @@ def _receive_update_activity(recent_posts_cache: {}, session, base_dir: str, def _receive_like(recent_posts_cache: {}, - session, handle: str, is_group: bool, base_dir: str, + session, handle: str, base_dir: str, http_prefix: str, domain: str, port: int, onion_domain: str, i2p_domain: str, - send_threads: [], post_log: [], cached_webfingers: {}, - person_cache: {}, message_json: {}, federation_list: [], + cached_webfingers: {}, + person_cache: {}, message_json: {}, debug: bool, signing_priv_key_pem: str, max_recent_posts: int, translate: {}, @@ -1394,7 +1384,7 @@ def _receive_like(recent_posts_cache: {}, handle_name, handle_dom, post_liked_id, like_actor): - _like_notify(base_dir, domain, onion_domain, handle, + _like_notify(base_dir, domain, onion_domain, i2p_domain, handle, like_actor, post_liked_id) update_likes_collection(recent_posts_cache, base_dir, post_filename, post_liked_id, like_actor, @@ -1462,10 +1452,10 @@ def _receive_like(recent_posts_cache: {}, def _receive_undo_like(recent_posts_cache: {}, - session, handle: str, is_group: bool, base_dir: str, + session, handle: str, base_dir: str, http_prefix: str, domain: str, port: int, - send_threads: [], post_log: [], cached_webfingers: {}, - person_cache: {}, message_json: {}, federation_list: [], + cached_webfingers: {}, + person_cache: {}, message_json: {}, debug: bool, signing_priv_key_pem: str, max_recent_posts: int, translate: {}, @@ -1581,11 +1571,11 @@ def _receive_undo_like(recent_posts_cache: {}, def _receive_reaction(recent_posts_cache: {}, - session, handle: str, is_group: bool, base_dir: str, + session, handle: str, base_dir: str, http_prefix: str, domain: str, port: int, onion_domain: str, - send_threads: [], post_log: [], cached_webfingers: {}, - person_cache: {}, message_json: {}, federation_list: [], + cached_webfingers: {}, + person_cache: {}, message_json: {}, debug: bool, signing_priv_key_pem: str, max_recent_posts: int, translate: {}, @@ -2850,7 +2840,8 @@ def _already_reacted(base_dir: str, nickname: str, domain: str, return False -def _like_notify(base_dir: str, domain: str, onion_domain: str, +def _like_notify(base_dir: str, domain: str, + onion_domain: str, i2p_domain: str, handle: str, actor: str, url: str) -> None: """Creates a notification that a like has arrived """ @@ -2861,9 +2852,13 @@ def _like_notify(base_dir: str, domain: str, onion_domain: str, # check that the liked post was by this handle nickname = handle.split('@')[0] if '/' + domain + '/users/' + nickname not in url: - if not onion_domain: - return - if '/' + onion_domain + '/users/' + nickname not in url: + if onion_domain: + if '/' + onion_domain + '/users/' + nickname not in url: + return + if i2p_domain: + if '/' + i2p_domain + '/users/' + nickname not in url: + return + if not i2p_domain and not onion_domain: return account_dir = base_dir + '/accounts/' + handle @@ -3012,8 +3007,7 @@ def _reply_notify(base_dir: str, handle: str, url: str) -> None: print('EX: unable to write ' + reply_file) -def _git_patch_notify(base_dir: str, handle: str, - subject: str, content: str, +def _git_patch_notify(base_dir: str, handle: str, subject: str, from_nickname: str, from_domain: str) -> None: """Creates a notification that a new git patch has arrived """ @@ -3051,7 +3045,6 @@ def _send_to_group_members(server, session, session_onion, session_i2p, send_threads: [], post_log: [], cached_webfingers: {}, person_cache: {}, debug: bool, - system_language: str, curr_domain: str, onion_domain: str, i2p_domain: str, signing_priv_key_pem: str) -> None: @@ -3238,7 +3231,7 @@ def _update_last_seen(base_dir: str, handle: str, actor: str) -> None: print('EX: unable to write ' + last_seen_filename) -def _bounce_dm(senderPostId: str, session, http_prefix: str, +def _bounce_dm(sender_post_id: str, session, http_prefix: str, base_dir: str, nickname: str, domain: str, port: int, sending_handle: str, federation_list: [], send_threads: [], post_log: [], @@ -3288,7 +3281,7 @@ def _bounce_dm(senderPostId: str, session, http_prefix: str, media_type = None image_description = '' city = 'London, England' - in_reply_to = remove_id_ending(senderPostId) + in_reply_to = remove_id_ending(sender_post_id) in_reply_to_atom_uri = None schedule_post = False event_date = None @@ -3646,8 +3639,7 @@ def _check_for_git_patches(base_dir: str, nickname: str, domain: str, json_obj['type'], json_obj['summary'], json_obj['content'], from_nickname, from_domain_full): - _git_patch_notify(base_dir, handle, - json_obj['summary'], json_obj['content'], + _git_patch_notify(base_dir, handle, json_obj['summary'], from_nickname, from_domain_full) return 1 if '[PATCH]' in json_obj['content']: @@ -3662,10 +3654,8 @@ def _inbox_after_initial(server, inbox_start_time, key_id: str, handle: str, message_json: {}, base_dir: str, http_prefix: str, send_threads: [], post_log: [], cached_webfingers: {}, person_cache: {}, - queue: [], domain: str, - onion_domain: str, i2p_domain: str, - port: int, proxy_type: str, - federation_list: [], debug: bool, + domain: str, onion_domain: str, i2p_domain: str, + port: int, federation_list: [], debug: bool, queue_filename: str, destination_filename: str, max_replies: int, allow_deletion: bool, max_mentions: int, max_emoji: int, translate: {}, @@ -3715,15 +3705,13 @@ def _inbox_after_initial(server, inbox_start_time, handle_name = handle.split('@')[0] if _receive_like(recent_posts_cache, - session, handle, is_group, + session, handle, base_dir, http_prefix, domain, port, onion_domain, i2p_domain, - send_threads, post_log, cached_webfingers, person_cache, message_json, - federation_list, debug, signing_priv_key_pem, max_recent_posts, translate, allow_deletion, @@ -3743,14 +3731,12 @@ def _inbox_after_initial(server, inbox_start_time, return False if _receive_undo_like(recent_posts_cache, - session, handle, is_group, + session, handle, base_dir, http_prefix, domain, port, - send_threads, post_log, cached_webfingers, person_cache, message_json, - federation_list, debug, signing_priv_key_pem, max_recent_posts, translate, allow_deletion, @@ -3770,15 +3756,13 @@ def _inbox_after_initial(server, inbox_start_time, return False if _receive_reaction(recent_posts_cache, - session, handle, is_group, + session, handle, base_dir, http_prefix, domain, port, onion_domain, - send_threads, post_log, cached_webfingers, person_cache, message_json, - federation_list, debug, signing_priv_key_pem, max_recent_posts, translate, allow_deletion, @@ -4346,8 +4330,7 @@ def _inbox_after_initial(server, inbox_start_time, http_prefix, federation_list, send_threads, post_log, cached_webfingers, - person_cache, - debug, system_language, + person_cache, debug, domain, onion_domain, i2p_domain, signing_priv_key_pem) fitness_performance(inbox_start_time, @@ -4422,7 +4405,7 @@ def _restore_queue_items(base_dir: str, queue: []) -> None: def run_inbox_queue_watchdog(project_version: str, httpd) -> None: """This tries to keep the inbox thread running even if it dies """ - print('THREAD: Starting inbox queue watchdog') + print('THREAD: Starting inbox queue watchdog ' + project_version) inbox_queue_original = httpd.thrInboxQueue.clone(run_inbox_queue) httpd.thrInboxQueue.start() while True: @@ -5089,17 +5072,14 @@ def run_inbox_queue(server, inbox_start_time = time.time() curr_session = session - curr_proxy_type = proxy_type if queue_json.get('actor'): if isinstance(queue_json['actor'], str): sender_domain, _ = get_domain_from_actor(queue_json['actor']) if sender_domain.endswith('.onion') and \ session_onion and proxy_type != 'tor': - curr_proxy_type = 'tor' curr_session = session_onion elif (sender_domain.endswith('.i2p') and session_i2p and proxy_type != 'i2p'): - curr_proxy_type = 'i2p' curr_session = session_i2p if debug and queue_json.get('actor'): @@ -5259,13 +5239,7 @@ def run_inbox_queue(server, # if queue_json['post'].get('id'): # queue_json['post']['id'] = queue_json['id'] - if _receive_undo(curr_session, - base_dir, http_prefix, port, - send_threads, post_log, - cached_webfingers, - person_cache, - queue_json['post'], - federation_list, + if _receive_undo(base_dir, queue_json['post'], debug, domain, onion_domain, i2p_domain): print('Queue: Undo accepted from ' + key_id) if os.path.isfile(queue_filename): @@ -5335,11 +5309,9 @@ def run_inbox_queue(server, if _receive_update_activity(recent_posts_cache, curr_session, base_dir, http_prefix, domain, port, - send_threads, post_log, cached_webfingers, person_cache, queue_json['post'], - federation_list, queue_json['postNickname'], debug, max_mentions, max_emoji, @@ -5460,11 +5432,9 @@ def run_inbox_queue(server, base_dir, http_prefix, send_threads, post_log, cached_webfingers, - person_cache, queue, - domain, + person_cache, domain, onion_domain, i2p_domain, - port, curr_proxy_type, - federation_list, + port, federation_list, debug, queue_filename, destination, max_replies, allow_deletion, diff --git a/tests.py b/tests.py index b1cb3618e..a42b3294c 100644 --- a/tests.py +++ b/tests.py @@ -3208,7 +3208,7 @@ def test_client_to_server(base_dir: str): http_prefix, cached_webfingers, person_cache, True, __version__, signing_priv_key_pem) - for _ in range(10): + for _ in range(20): if os.path.isfile(alice_dir + '/accounts/alice@' + alice_domain + '/followers.txt'): test_str = 'bob@' + bob_domain + ':' + str(bob_port) From 2371e20541210138b73f5d2def2b521ed5b669c2 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Tue, 14 Jun 2022 12:52:43 +0100 Subject: [PATCH 4/6] Tidying --- happening.py | 17 +++++------------ webapp_calendar.py | 3 +-- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/happening.py b/happening.py index 890c100e2..ad7bace4e 100644 --- a/happening.py +++ b/happening.py @@ -353,8 +353,7 @@ def _dav_encode_token(year: int, month_number: int, def _icalendar_day(base_dir: str, nickname: str, domain: str, - day_events: [], person_cache: {}, - http_prefix: str) -> str: + day_events: [], person_cache: {}) -> str: """Returns a day's events in icalendar format """ ical_str = '' @@ -478,7 +477,6 @@ def _icalendar_day(base_dir: str, nickname: str, domain: str, def get_todays_events_icalendar(base_dir: str, nickname: str, domain: str, year: int, month_number: int, day_number: int, person_cache: {}, - http_prefix: str, text_match: str, system_language: str) -> str: """Returns today's events in icalendar format """ @@ -503,8 +501,7 @@ def get_todays_events_icalendar(base_dir: str, nickname: str, domain: str, return ical_str ical_str += \ - _icalendar_day(base_dir, nickname, domain, day_events, person_cache, - http_prefix) + _icalendar_day(base_dir, nickname, domain, day_events, person_cache) ical_str += 'END:VCALENDAR\n' return ical_str @@ -514,7 +511,6 @@ def get_month_events_icalendar(base_dir: str, nickname: str, domain: str, year: int, month_number: int, person_cache: {}, - http_prefix: str, text_match: str) -> str: """Returns today's events in icalendar format """ @@ -537,8 +533,7 @@ def get_month_events_icalendar(base_dir: str, nickname: str, domain: str, day_events = month_events[str(day_of_month)] ical_str += \ _icalendar_day(base_dir, nickname, domain, - day_events, person_cache, - http_prefix) + day_events, person_cache) ical_str += 'END:VCALENDAR\n' return ical_str @@ -1098,7 +1093,7 @@ def dav_report_response(base_dir: str, nickname: str, domain: str, search_date.year, search_date.month, search_date.day, person_cache, - http_prefix, text_match, + text_match, system_language) events_href = \ http_prefix + '://' + domain_full + '/users/' + \ @@ -1132,7 +1127,6 @@ def dav_report_response(base_dir: str, nickname: str, domain: str, query_start_year, query_start_month, person_cache, - http_prefix, text_match) events_href = \ http_prefix + '://' + domain_full + '/users/' + \ @@ -1180,7 +1174,6 @@ def dav_report_response(base_dir: str, nickname: str, domain: str, nickname, domain, year, month, person_cache, - http_prefix, text_match) events_href = \ http_prefix + '://' + domain_full + '/users/' + \ @@ -1217,7 +1210,7 @@ def dav_report_response(base_dir: str, nickname: str, domain: str, get_todays_events_icalendar(base_dir, nickname, domain, search_date.year, search_date.month, search_date.day, person_cache, - http_prefix, text_match, + text_match, system_language) events_href = \ http_prefix + '://' + domain_full + '/users/' + \ diff --git a/webapp_calendar.py b/webapp_calendar.py index 05128ed7f..45af8b33a 100644 --- a/webapp_calendar.py +++ b/webapp_calendar.py @@ -383,7 +383,6 @@ def html_calendar(person_cache: {}, css_cache: {}, translate: {}, year, month_number, day_number, person_cache, - http_prefix, text_match, system_language) day_events = None @@ -404,7 +403,7 @@ def html_calendar(person_cache: {}, css_cache: {}, translate: {}, if icalendar: return get_month_events_icalendar(base_dir, nickname, domain, year, month_number, person_cache, - http_prefix, text_match) + text_match) events = \ get_calendar_events(base_dir, nickname, domain, year, month_number, From d0a6c58e785177bbf494fec09f545aa2afa43184 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Tue, 14 Jun 2022 14:52:33 +0100 Subject: [PATCH 5/6] Tidying --- desktop_client.py | 71 ++++++++++++----------------------------------- 1 file changed, 18 insertions(+), 53 deletions(-) diff --git a/desktop_client.py b/desktop_client.py index 2de71cf0a..40c2e80f2 100644 --- a/desktop_client.py +++ b/desktop_client.py @@ -852,12 +852,10 @@ def _desktop_show_actor(base_dir: str, actor_json: {}, translate: {}, def _desktop_show_profile(session, nickname: str, domain: str, - http_prefix: str, base_dir: str, box_name: str, - page_number: int, index: int, box_json: {}, + base_dir: str, index: int, box_json: {}, system_language: str, screenreader: str, espeak, - translate: {}, your_actor: str, - post_json_object: {}, + translate: {}, post_json_object: {}, signing_priv_key_pem: str) -> {}: """Shows the profile of the actor for the given post Returns the actor json @@ -901,13 +899,10 @@ def _desktop_show_profile(session, nickname: str, domain: str, return actor_json -def _desktop_show_profile_from_handle(session, nickname: str, domain: str, - http_prefix: str, base_dir: str, - box_name: str, handle: str, - system_language: str, +def _desktop_show_profile_from_handle(session, domain: str, base_dir: str, + handle: str, system_language: str, screenreader: str, espeak, - translate: {}, your_actor: str, - post_json_object: {}, + translate: {}, signing_priv_key_pem: str) -> {}: """Shows the profile for a handle Returns the actor json @@ -985,9 +980,7 @@ def _desktop_show_box(indent: str, your_actor: str, box_name: str, box_json: {}, translate: {}, screenreader: str, system_language: str, espeak, - page_number: int, - new_replies: bool, - new_dms: bool) -> bool: + page_number: int) -> bool: """Shows online timeline """ number_width = 2 @@ -1429,8 +1422,6 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, content = None cached_webfingers = {} person_cache = {} - new_replies_exist = False - new_dms_exist = False pgp_key_upload = False say_str = indent + 'Loading translations file' @@ -1502,12 +1493,9 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, signing_priv_key_pem) else: inbox_json = box_json - new_dms_exist = False - new_replies_exist = False if inbox_json: _new_desktop_notifications(your_actor, inbox_json, notify_json) if notify_json.get('dmNotify'): - new_dms_exist = True if notify_json.get('dmNotifyChanged'): _desktop_notification(notification_type, "Epicyon", @@ -1515,7 +1503,6 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, if notification_sounds: _play_notification_sound(dm_sound_filename, player) if notify_json.get('repliesNotify'): - new_replies_exist = True if notify_json.get('repliesNotifyChanged'): _desktop_notification(notification_type, "Epicyon", @@ -1532,9 +1519,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, your_actor, curr_timeline, box_json, translate, None, system_language, espeak, - page_number, - new_replies_exist, - new_dms_exist) + page_number) desktop_shown = True prev_timeline_first_id = timeline_first_id else: @@ -1580,9 +1565,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, your_actor, curr_timeline, box_json, translate, screenreader, system_language, espeak, - page_number, - new_replies_exist, new_dms_exist) - new_dms_exist = False + page_number) elif command_str.startswith('show rep'): page_number = 1 prev_timeline_first_id = '' @@ -1596,10 +1579,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, your_actor, curr_timeline, box_json, translate, screenreader, system_language, espeak, - page_number, - new_replies_exist, new_dms_exist) - # Turn off the replies indicator - new_replies_exist = False + page_number) elif command_str.startswith('show b'): page_number = 1 prev_timeline_first_id = '' @@ -1613,10 +1593,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, your_actor, curr_timeline, box_json, translate, screenreader, system_language, espeak, - page_number, - new_replies_exist, new_dms_exist) - # Turn off the replies indicator - new_replies_exist = False + page_number) elif (command_str.startswith('show sen') or command_str.startswith('show out')): page_number = 1 @@ -1631,8 +1608,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, your_actor, curr_timeline, box_json, translate, screenreader, system_language, espeak, - page_number, - new_replies_exist, new_dms_exist) + page_number) elif (command_str == 'show' or command_str.startswith('show in') or command_str == 'clear'): page_number = 1 @@ -1656,8 +1632,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, your_actor, curr_timeline, box_json, translate, screenreader, system_language, espeak, - page_number, - new_replies_exist, new_dms_exist) + page_number) elif (command_str.startswith('read ') or command_str.startswith('show ') or command_str == 'read' or @@ -1699,14 +1674,11 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, if post_json_object: actor_json = \ _desktop_show_profile(session, nickname, domain, - http_prefix, base_dir, - curr_timeline, - page_number, post_index, + base_dir, post_index, box_json, system_language, screenreader, espeak, translate, - your_actor, post_json_object, signing_priv_key_pem) else: @@ -1718,16 +1690,12 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, profile_handle = post_index_str _desktop_clear_screen() _desktop_show_banner() - _desktop_show_profile_from_handle(session, - nickname, domain, - http_prefix, base_dir, - curr_timeline, + _desktop_show_profile_from_handle(session, domain, + base_dir, profile_handle, system_language, screenreader, espeak, translate, - your_actor, - None, signing_priv_key_pem) say_str = 'Press Enter to continue...' say_str2 = _highlight_text(say_str) @@ -1742,12 +1710,10 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, post_index = int(post_index_str) actor_json = \ _desktop_show_profile(session, nickname, domain, - http_prefix, base_dir, - curr_timeline, - page_number, post_index, + base_dir, post_index, box_json, system_language, screenreader, - espeak, translate, your_actor, + espeak, translate, None, signing_priv_key_pem) say_str = 'Press Enter to continue...' say_str2 = _highlight_text(say_str) @@ -2581,5 +2547,4 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, your_actor, curr_timeline, box_json, translate, screenreader, system_language, - espeak, page_number, - new_replies_exist, new_dms_exist) + espeak, page_number) From e143f2ae45242a99c893ad059ac9026620387d68 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Tue, 14 Jun 2022 16:51:52 +0100 Subject: [PATCH 6/6] Extra logo formats --- img/logo.svg | 484 +++++++++++++++++++++++++++++++++++++++++++++++ img/logo2048.png | Bin 0 -> 24768 bytes 2 files changed, 484 insertions(+) create mode 100644 img/logo.svg create mode 100644 img/logo2048.png diff --git a/img/logo.svg b/img/logo.svg new file mode 100644 index 000000000..5afa93189 --- /dev/null +++ b/img/logo.svg @@ -0,0 +1,484 @@ + + + + + + + + + + diff --git a/img/logo2048.png b/img/logo2048.png new file mode 100644 index 0000000000000000000000000000000000000000..2ec977c5a84d7199a2088644a483270507231fbf GIT binary patch literal 24768 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