From de123048f4b06f01231391a923833f54e5f9a629 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Sun, 6 Oct 2024 17:22:13 +0100 Subject: [PATCH] Support for thread id --- blocking.py | 12 ++--- conversation.py | 6 +-- daemon_get.py | 6 +++ daemon_get_post.py | 3 +- daemon_post_person_options.py | 6 ++- daemon_post_question.py | 3 +- daemon_post_receive.py | 35 ++++++++++++--- desktop_client.py | 18 +++++--- epicyon.py | 16 ++++++- inbox.py | 6 ++- metadata.py | 3 +- newsdaemon.py | 3 +- posts.py | 85 +++++++++++++++++++++-------------- tests.py | 25 ++++++++++- utils.py | 6 +-- webapp_create_post.py | 14 ++++-- webapp_post.py | 14 +++--- 17 files changed, 183 insertions(+), 78 deletions(-) diff --git a/blocking.py b/blocking.py index 95b91d8fd..08a9591e1 100644 --- a/blocking.py +++ b/blocking.py @@ -1241,12 +1241,12 @@ def mute_post(base_dir: str, nickname: str, domain: str, port: int, if post_json_obj.get('conversation'): mute_conversation(base_dir, nickname, domain, post_json_obj['conversation']) - elif post_json_obj.get('thread'): - mute_conversation(base_dir, nickname, domain, - post_json_obj['thread']) elif post_json_obj.get('context'): mute_conversation(base_dir, nickname, domain, post_json_obj['context']) + elif post_json_obj.get('thread'): + mute_conversation(base_dir, nickname, domain, + post_json_obj['thread']) # does this post have ignores on it from differenent actors? if not post_json_obj.get('ignores'): @@ -1390,12 +1390,12 @@ def unmute_post(base_dir: str, nickname: str, domain: str, port: int, if post_json_obj.get('conversation'): unmute_conversation(base_dir, nickname, domain, post_json_obj['conversation']) - elif post_json_obj.get('thread'): - unmute_conversation(base_dir, nickname, domain, - post_json_obj['thread']) elif post_json_obj.get('context'): unmute_conversation(base_dir, nickname, domain, post_json_obj['context']) + elif post_json_obj.get('thread'): + unmute_conversation(base_dir, nickname, domain, + post_json_obj['thread']) if post_json_obj.get('ignores'): domain_full = get_full_domain(domain, port) diff --git a/conversation.py b/conversation.py index 55e2cd981..623038e2c 100644 --- a/conversation.py +++ b/conversation.py @@ -42,10 +42,10 @@ def _get_conversation_filename(base_dir: str, nickname: str, domain: str, os.mkdir(conversation_dir) if post_json_object['object'].get('conversation'): conversation_id = post_json_object['object']['conversation'] - elif post_json_object['object'].get('thread'): - conversation_id = post_json_object['object']['thread'] - else: + elif post_json_object['object'].get('context'): conversation_id = post_json_object['object']['context'] + else: + conversation_id = post_json_object['object']['thread'] if not isinstance(conversation_id, str): return None conversation_id = conversation_id.replace('/', '#') diff --git a/daemon_get.py b/daemon_get.py index 15f428559..ec78ad90e 100644 --- a/daemon_get.py +++ b/daemon_get.py @@ -4011,11 +4011,16 @@ def daemon_http_get(self) -> None: reply_category = '' share_description = None conversation_id = None + convthread_id = None if html_getreq: if '?conversationId=' in self.path: conversation_id = self.path.split('?conversationId=')[1] if '?' in conversation_id: conversation_id = conversation_id.split('?')[0] + if '?convthreadId=' in self.path: + convthread_id = self.path.split('?convthreadId=')[1] + if '?' in convthread_id: + convthread_id = convthread_id.split('?')[0] # public reply if '?replyto=' in self.path: in_reply_to_url = self.path.split('?replyto=')[1] @@ -4306,6 +4311,7 @@ def daemon_http_get(self) -> None: self.server.domain_full, getreq_start_time, cookie, no_drop_down, conversation_id, + convthread_id, curr_session, self.server.default_reply_interval_hrs, self.server.debug, diff --git a/daemon_get_post.py b/daemon_get_post.py index 07082e0fc..ac6efd10f 100644 --- a/daemon_get_post.py +++ b/daemon_get_post.py @@ -360,6 +360,7 @@ def show_new_post(self, edit_post_params: {}, domain: str, domain_full: str, getreq_start_time, cookie, no_drop_down: bool, conversation_id: str, + convthread_id: str, curr_session, default_reply_interval_hrs: int, debug: bool, access_keys: {}, key_shortcuts: {}, system_language: str, @@ -480,7 +481,7 @@ def show_new_post(self, edit_post_params: {}, theme_name, no_drop_down, access_keys, custom_submit_text, - conversation_id, + conversation_id, convthread_id, recent_posts_cache, max_recent_posts, curr_session, diff --git a/daemon_post_person_options.py b/daemon_post_person_options.py index 15a47389c..4caf594fc 100644 --- a/daemon_post_person_options.py +++ b/daemon_post_person_options.py @@ -932,6 +932,7 @@ def _person_options_dm(self, options_confirm_params: str, custom_submit_text = get_config_param(base_dir, 'customSubmitText') conversation_id = None + convthread_id = None reply_is_chat = False bold_reading = False @@ -964,7 +965,7 @@ def _person_options_dm(self, options_confirm_params: str, theme_name, True, access_keys, custom_submit_text, - conversation_id, + conversation_id, convthread_id, recent_posts_cache, max_recent_posts, curr_session, @@ -1165,6 +1166,7 @@ def _person_options_report(self, options_confirm_params: str, custom_submit_text = get_config_param(base_dir, 'customSubmitText') conversation_id = None + convthread_id = None reply_is_chat = False bold_reading = False @@ -1196,7 +1198,7 @@ def _person_options_report(self, options_confirm_params: str, theme_name, True, access_keys, custom_submit_text, - conversation_id, + conversation_id, convthread_id, recent_posts_cache, max_recent_posts, curr_session, diff --git a/daemon_post_question.py b/daemon_post_question.py index 274feec6d..2537254fc 100644 --- a/daemon_post_question.py +++ b/daemon_post_question.py @@ -220,6 +220,7 @@ def _send_reply_to_question(self, base_dir: str, event_end_time = None location = None conversation_id = None + convthread_id = None buy_url = '' chat_url = '' city = get_spoofed_city(city_name, base_dir, nickname, domain) @@ -251,7 +252,7 @@ def _send_reply_to_question(self, base_dir: str, event_end_time, location, system_language, - conversation_id, + conversation_id, convthread_id, low_bandwidth, dm_license_url, content_license_url, '', diff --git a/daemon_post_receive.py b/daemon_post_receive.py index 59960d2aa..45300d134 100644 --- a/daemon_post_receive.py +++ b/daemon_post_receive.py @@ -130,6 +130,10 @@ def _receive_new_post_process_newpost(self, fields: {}, if fields.get('conversationId'): conversation_id = fields['conversationId'] + convthread_id = None + if fields.get('convthreadId'): + convthread_id = fields['convthreadId'] + languages_understood = \ get_understood_languages(base_dir, http_prefix, nickname, domain_full, @@ -165,7 +169,7 @@ def _receive_new_post_process_newpost(self, fields: {}, fields['eventEndTime'], fields['location'], False, fields['languagesDropdown'], - conversation_id, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, @@ -286,6 +290,9 @@ def _receive_new_post_process_newblog(self, fields: {}, conversation_id = None if fields.get('conversationId'): conversation_id = fields['conversationId'] + convthread_id = None + if fields.get('convthreadId'): + convthread_id = fields['convthreadId'] languages_understood = \ get_understood_languages(base_dir, http_prefix, nickname, domain_full, @@ -318,7 +325,7 @@ def _receive_new_post_process_newblog(self, fields: {}, fields['eventEndTime'], fields['location'], fields['languagesDropdown'], - conversation_id, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, @@ -518,6 +525,10 @@ def _receive_new_post_process_newunlisted(self, fields: {}, if fields.get('conversationId'): conversation_id = fields['conversationId'] + convthread_id = None + if fields.get('convthreadId'): + convthread_id = fields['convthreadId'] + languages_understood = \ get_understood_languages(base_dir, http_prefix, nickname, domain_full, person_cache) @@ -552,7 +563,7 @@ def _receive_new_post_process_newunlisted(self, fields: {}, fields['eventEndTime'], fields['location'], fields['languagesDropdown'], - conversation_id, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, @@ -668,6 +679,10 @@ def _receive_new_post_process_newfollowers(self, fields: {}, if fields.get('conversationId'): conversation_id = fields['conversationId'] + convthread_id = None + if fields.get('convthreadId'): + convthread_id = fields['convthreadId'] + mentions_message = mentions_str + fields['message'] languages_understood = \ get_understood_languages(base_dir, http_prefix, @@ -705,7 +720,7 @@ def _receive_new_post_process_newfollowers(self, fields: {}, fields['eventEndTime'], fields['location'], fields['languagesDropdown'], - conversation_id, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, @@ -827,6 +842,10 @@ def _receive_new_post_process_newdm(self, fields: {}, if fields.get('conversationId'): conversation_id = fields['conversationId'] + convthread_id = None + if fields.get('convthreadId'): + convthread_id = fields['convthreadId'] + languages_understood = \ get_understood_languages(base_dir, http_prefix, nickname, domain_full, @@ -871,7 +890,7 @@ def _receive_new_post_process_newdm(self, fields: {}, fields['eventEndTime'], fields['location'], fields['languagesDropdown'], - conversation_id, + conversation_id, convthread_id, low_bandwidth, dm_license_url, media_license_url, @@ -993,6 +1012,7 @@ def _receive_new_post_process_newreminder(self, fields: {}, nickname: str, client_to_server = False comments_enabled = False conversation_id = None + convthread_id = None mentions_message = mentions_str + fields['message'] languages_understood = \ get_understood_languages(base_dir, http_prefix, @@ -1024,7 +1044,7 @@ def _receive_new_post_process_newreminder(self, fields: {}, nickname: str, fields['eventEndTime'], fields['location'], fields['languagesDropdown'], - conversation_id, + conversation_id, convthread_id, low_bandwidth, dm_license_url, media_license_url, @@ -1314,6 +1334,7 @@ def _receive_new_post_process_newreading(self, fields: {}, if fields.get('videoTranscript'): video_transcript = fields['videoTranscript'] conversation_id = None + convthread_id = None languages_understood = \ get_understood_languages(base_dir, http_prefix, nickname, domain_full, @@ -1341,7 +1362,7 @@ def _receive_new_post_process_newreading(self, fields: {}, fields['eventEndTime'], fields['location'], False, fields['languagesDropdown'], - conversation_id, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, diff --git a/desktop_client.py b/desktop_client.py index 15d10882f..8e099fc07 100644 --- a/desktop_client.py +++ b/desktop_client.py @@ -516,7 +516,7 @@ def _desktop_reply_to_post(session, post_id: str, debug: bool, subject: str, screenreader: str, system_language: str, languages_understood: [], - espeak, conversation_id: str, + espeak, conversation_id: str, convthread_id: str, low_bandwidth: bool, content_license_url: str, media_license_url: str, media_creator: str, @@ -592,7 +592,7 @@ def _desktop_reply_to_post(session, post_id: str, event_date, event_time, event_end_time, location, translate, buy_url, chat_url, auto_cw_cache, debug, post_id, post_id, - conversation_id, subject) == 0: + conversation_id, convthread_id, subject) == 0: say_str = translate['Sent'] else: say_str = translate['Post failed'] @@ -614,6 +614,7 @@ def _desktop_new_post(session, """Use the desktop client to create a new post """ conversation_id = None + convthread_id = None say_str = translate['Create a new post'] _say_command(say_str, say_str, screenreader, system_language, espeak) say_str = translate['Type your post, then press Enter'] + '.' @@ -673,7 +674,7 @@ def _desktop_new_post(session, event_date, event_time, event_end_time, location, translate, buy_url, chat_url, auto_cw_cache, debug, None, None, - conversation_id, subject) == 0: + conversation_id, convthread_id, subject) == 0: say_str = translate['Sent'] else: say_str = translate['Post failed'] @@ -1378,6 +1379,7 @@ def _desktop_new_dm_base(session, to_handle: str, """Use the desktop client to create a new direct message """ conversation_id = None + convthread_id = None to_port = port if '://' in to_handle: to_nickname = get_nickname_from_actor(to_handle) @@ -1489,7 +1491,7 @@ def _desktop_new_dm_base(session, to_handle: str, event_date, event_time, event_end_time, location, translate, buy_url, chat_url, auto_cw_cache, debug, None, None, - conversation_id, subject) == 0: + conversation_id, convthread_id, subject) == 0: say_str = translate['Sent'] else: say_str = translate['Post failed'] @@ -1964,18 +1966,19 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, if post_json_object['object'].get('summary'): subject = post_json_object['object']['summary'] conversation_id = None + convthread_id = None # Due to lack of AP specification maintenance, # a conversation can also be referred to as a # thread or (confusingly) "context" if post_json_object['object'].get('conversation'): conversation_id = \ post_json_object['object']['conversation'] - elif post_json_object['object'].get('thread'): - conversation_id = \ - post_json_object['object']['thread'] elif post_json_object['object'].get('context'): conversation_id = \ post_json_object['object']['context'] + if post_json_object['object'].get('thread'): + convthread_id = \ + post_json_object['object']['thread'] session_reply = create_session(proxy_type) _desktop_reply_to_post(session_reply, post_id, base_dir, nickname, @@ -1988,6 +1991,7 @@ def run_desktop_client(base_dir: str, proxy_type: str, http_prefix: str, system_language, languages_understood, espeak, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, diff --git a/epicyon.py b/epicyon.py index c507a773c..8679e42a2 100644 --- a/epicyon.py +++ b/epicyon.py @@ -203,6 +203,10 @@ def _command_options() -> None: default=None, help='Conversation Id which can be added ' + 'when sending a post') + parser.add_argument('--convthreadId', dest='convthreadId', type=str, + default=None, + help='Conversation thread Id which can be added ' + + 'when sending a post') parser.add_argument('--libretranslateApiKey', dest='libretranslateApiKey', type=str, default=None, @@ -1866,7 +1870,8 @@ def _command_options() -> None: argb.eventDate, argb.eventTime, argb.eventEndTime, argb.eventLocation, translate, argb.buyUrl, argb.chatUrl, auto_cw_cache, argb.debug, - reply_to, reply_to, argb.conversationId, subject) + reply_to, reply_to, argb.conversationId, + argb.convthreadId, subject) for _ in range(10): # TODO detect send success/fail time.sleep(1) @@ -3635,6 +3640,7 @@ def _command_options() -> None: test_location = None test_is_article = False conversation_id = None + convthread_id = None low_bandwidth = False languages_understood = [argb.language] translate = {} @@ -3656,6 +3662,7 @@ def _command_options() -> None: test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, argb.language, conversation_id, + convthread_id, low_bandwidth, argb.content_license_url, argb.media_license_url, argb.media_creator, languages_understood, translate, buy_url, chat_url, @@ -3673,6 +3680,7 @@ def _command_options() -> None: test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, argb.language, conversation_id, + convthread_id, low_bandwidth, argb.content_license_url, argb.media_license_url, argb.media_creator, languages_understood, translate, buy_url, chat_url, @@ -3690,6 +3698,7 @@ def _command_options() -> None: test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, argb.language, conversation_id, + convthread_id, low_bandwidth, argb.content_license_url, argb.media_license_url, argb.media_creator, languages_understood, translate, buy_url, chat_url, @@ -3707,6 +3716,7 @@ def _command_options() -> None: test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, argb.language, conversation_id, + convthread_id, low_bandwidth, argb.content_license_url, argb.media_license_url, argb.media_creator, languages_understood, translate, buy_url, chat_url, @@ -3725,6 +3735,7 @@ def _command_options() -> None: test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, argb.language, conversation_id, + convthread_id, low_bandwidth, argb.content_license_url, argb.media_license_url, argb.media_creator, languages_understood, translate, buy_url, chat_url, @@ -3742,6 +3753,7 @@ def _command_options() -> None: test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, argb.language, conversation_id, + convthread_id, low_bandwidth, argb.content_license_url, argb.media_license_url, argb.media_creator, languages_understood, translate, buy_url, chat_url, @@ -3759,6 +3771,7 @@ def _command_options() -> None: test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, argb.language, conversation_id, + convthread_id, low_bandwidth, argb.content_license_url, argb.media_license_url, argb.media_creator, languages_understood, translate, buy_url, chat_url, @@ -3776,6 +3789,7 @@ def _command_options() -> None: test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, argb.language, conversation_id, + convthread_id, low_bandwidth, argb.content_license_url, argb.media_license_url, argb.media_creator, languages_understood, translate, buy_url, chat_url, diff --git a/inbox.py b/inbox.py index 0f0e04754..3eabc4e5f 100644 --- a/inbox.py +++ b/inbox.py @@ -1346,6 +1346,7 @@ def _bounce_dm(sender_post_id: str, session, http_prefix: str, event_end_time = None location = None conversation_id = None + convthread_id = None low_bandwidth = False buy_url = '' chat_url = '' @@ -1361,6 +1362,7 @@ def _bounce_dm(sender_post_id: str, session, http_prefix: str, subject, debug, schedule_post, event_date, event_time, event_end_time, location, system_language, conversation_id, + convthread_id, low_bandwidth, dm_license_url, dm_license_url, '', languages_understood, bounce_is_chat, @@ -1537,10 +1539,10 @@ def _create_reply_notification_file(base_dir: str, nickname: str, domain: str, conversation_id = None if post_json_object['object'].get('conversation'): conversation_id = post_json_object['object']['conversation'] - elif post_json_object['object'].get('thread'): - conversation_id = post_json_object['object']['thread'] elif post_json_object['object'].get('context'): conversation_id = post_json_object['object']['context'] + elif post_json_object['object'].get('thread'): + conversation_id = post_json_object['object']['thread'] in_reply_to = get_reply_to(post_json_object['object']) if not in_reply_to: diff --git a/metadata.py b/metadata.py index 792f88645..371868b04 100644 --- a/metadata.py +++ b/metadata.py @@ -96,7 +96,8 @@ def meta_data_node_info(base_dir: str, "postFormats": ["text/plain", "text/html", "text/markdown", "text/x.misskeymarkdown"], "FEPs": ["c648", "521a", "8fcf", "4ccd", "c118", "fffd", - "1970", "0837", "7628", "2677", "5e53", "c16b"] + "1970", "0837", "7628", "2677", "5e53", "c16b", + "5e53"] } } return nodeinfo diff --git a/newsdaemon.py b/newsdaemon.py index 8014f6580..182fbab47 100644 --- a/newsdaemon.py +++ b/newsdaemon.py @@ -660,6 +660,7 @@ def _convert_rss_to_activitypub(base_dir: str, http_prefix: str, video_transcript = None city = 'London, England' conversation_id = None + convthread_id = None languages_understood = [system_language] buy_url = '' chat_url = '' @@ -670,7 +671,7 @@ def _convert_rss_to_activitypub(base_dir: str, http_prefix: str, attach_image_filename, media_type, image_description, video_transcript, city, rss_title, system_language, - conversation_id, low_bandwidth, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, diff --git a/posts.py b/posts.py index 6e4cebdf3..1f1212d65 100644 --- a/posts.py +++ b/posts.py @@ -1265,8 +1265,8 @@ def _create_post_s2s(base_dir: str, nickname: str, domain: str, port: int, video_transcript: str, city: str, post_object_type: str, summary: str, in_reply_to_atom_uri: str, system_language: str, - conversation_id: str, low_bandwidth: bool, - content_license_url: str, + conversation_id: str, convthread_id: str, + low_bandwidth: bool, content_license_url: str, media_license_url: str, media_creator: str, buy_url: str, chat_url: str, translate: {}) -> {}: """Creates a new server-to-server post @@ -1335,6 +1335,11 @@ def _create_post_s2s(base_dir: str, nickname: str, domain: str, port: int, } } + # https://codeberg.org/fediverse/fep/src/branch/main/fep/76ea/fep-76ea.md + if convthread_id: + if isinstance(convthread_id, str): + new_post['object']['thread'] = convthread_id + # pixelfed/friendica style location representation location = get_location_dict_from_tags(tags) if location: @@ -1376,7 +1381,8 @@ def _create_post_c2s(base_dir: str, nickname: str, domain: str, port: int, video_transcript: str, city: str, post_object_type: str, summary: str, in_reply_to_atom_uri: str, system_language: str, - conversation_id: str, low_bandwidth: str, + conversation_id: str, convthread_id: str, + low_bandwidth: str, content_license_url: str, media_license_url: str, media_creator: str, buy_url: str, chat_url: str, translate: {}) -> {}: @@ -1400,6 +1406,7 @@ def _create_post_c2s(base_dir: str, nickname: str, domain: str, port: int, 'secGPC': '1', 'id': new_post_id, 'conversation': conversation_id, + 'thread': convthread_id, 'context': conversation_id, 'type': post_object_type, 'summary': summary, @@ -1434,6 +1441,11 @@ def _create_post_c2s(base_dir: str, nickname: str, domain: str, port: int, "crawlable": False } + # https://codeberg.org/fediverse/fep/src/branch/main/fep/76ea/fep-76ea.md + if convthread_id: + if isinstance(convthread_id, str): + new_post['thread'] = convthread_id + # pixelfed/friendica style location representation location = get_location_dict_from_tags(tags) if location: @@ -1690,8 +1702,8 @@ def _create_post_base(base_dir: str, anonymous_participation_enabled: bool, event_status: str, ticket_url: str, system_language: str, - conversation_id: str, low_bandwidth: bool, - content_license_url: str, + conversation_id: str, convthread_id: str, + low_bandwidth: bool, content_license_url: str, media_license_url: str, media_creator: str, languages_understood: [], translate: {}, buy_url: str, chat_url: str, @@ -1856,7 +1868,7 @@ def _create_post_base(base_dir: str, video_transcript, city, post_object_type, summary, in_reply_to_atom_uri, system_language, - conversation_id, low_bandwidth, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, buy_url, chat_url, translate) @@ -1872,7 +1884,7 @@ def _create_post_base(base_dir: str, video_transcript, city, post_object_type, summary, in_reply_to_atom_uri, system_language, - conversation_id, low_bandwidth, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, buy_url, chat_url, translate) @@ -2133,8 +2145,8 @@ def create_public_post(base_dir: str, schedule_post: bool, event_date: str, event_time: str, event_end_time: str, location: str, is_article: bool, system_language: str, - conversation_id: str, low_bandwidth: bool, - content_license_url: str, + conversation_id: str, convthread_id: str, + low_bandwidth: bool, content_license_url: str, media_license_url: str, media_creator: str, languages_understood: [], translate: {}, buy_url: str, chat_url: str, @@ -2170,7 +2182,7 @@ def create_public_post(base_dir: str, replies_moderation_option, anonymous_participation_enabled, event_status, ticket_url, system_language, - conversation_id, low_bandwidth, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, @@ -2191,8 +2203,8 @@ def create_reading_post(base_dir: str, schedule_post: bool, event_date: str, event_time: str, event_end_time: str, location: str, is_article: bool, system_language: str, - conversation_id: str, low_bandwidth: bool, - content_license_url: str, + conversation_id: str, convthread_id: str, + low_bandwidth: bool, content_license_url: str, media_license_url: str, media_creator: str, languages_understood: [], translate: {}, buy_url: str, chat_url: str, @@ -2232,7 +2244,7 @@ def create_reading_post(base_dir: str, schedule_post, event_date, event_time, event_end_time, location, is_article, system_language, - conversation_id, low_bandwidth, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, @@ -2291,8 +2303,8 @@ def create_blog_post(base_dir: str, subject: str, schedule_post: bool, event_date: str, event_time: str, event_end_time: str, location: str, system_language: str, - conversation_id: str, low_bandwidth: bool, - content_license_url: str, + conversation_id: str, convthread_id: str, + low_bandwidth: bool, content_license_url: str, media_license_url: str, media_creator: str, languages_understood: [], translate: {}, buy_url: str, chat_url: str) -> {}: @@ -2307,7 +2319,8 @@ def create_blog_post(base_dir: str, in_reply_to, in_reply_to_atom_uri, subject, schedule_post, event_date, event_time, event_end_time, location, - True, system_language, conversation_id, + True, system_language, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -2327,8 +2340,8 @@ def create_news_post(base_dir: str, attach_image_filename: str, media_type: str, image_description: str, video_transcript: str, city: str, subject: str, system_language: str, - conversation_id: str, low_bandwidth: bool, - content_license_url: str, + conversation_id: str, convthread_id: str, + low_bandwidth: bool, content_license_url: str, media_license_url: str, media_creator: str, languages_understood: [], translate: {}, buy_url: str, chat_url: str) -> {}: @@ -2351,7 +2364,8 @@ def create_news_post(base_dir: str, in_reply_to, in_reply_to_atom_uri, subject, schedule_post, event_date, event_time, event_end_time, location, - True, system_language, conversation_id, + True, system_language, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -2389,6 +2403,7 @@ def create_question_post(base_dir: str, maximum_attendee_capacity = replies_moderation_option = None anonymous_participation_enabled = event_status = ticket_url = None conversation_id = None + convthread_id = None message_json = \ _create_post_base(base_dir, nickname, domain, port, 'https://www.w3.org/ns/activitystreams#Public', @@ -2406,7 +2421,8 @@ def create_question_post(base_dir: str, replies_moderation_option, anonymous_participation_enabled, event_status, ticket_url, system_language, - conversation_id, low_bandwidth, content_license_url, + conversation_id, convthread_id, low_bandwidth, + content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, auto_cw_cache) @@ -2443,8 +2459,8 @@ def create_unlisted_post(base_dir: str, subject: str, schedule_post: bool, event_date: str, event_time: str, event_end_time: str, location: str, system_language: str, - conversation_id: str, low_bandwidth: bool, - content_license_url: str, + conversation_id: str, convthread_id: str, + low_bandwidth: bool, content_license_url: str, media_license_url: str, media_creator: str, languages_understood: [], translate: {}, buy_url: str, chat_url: str, @@ -2479,7 +2495,7 @@ def create_unlisted_post(base_dir: str, anonymous_participation_enabled, event_status, ticket_url, system_language, - conversation_id, low_bandwidth, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, @@ -2499,8 +2515,8 @@ def create_followers_only_post(base_dir: str, event_date: str, event_time: str, event_end_time: str, location: str, system_language: str, - conversation_id: str, low_bandwidth: bool, - content_license_url: str, + conversation_id: str, convthread_id: str, + low_bandwidth: bool, content_license_url: str, media_license_url: str, media_creator: str, languages_understood: [], translate: {}, buy_url: str, @@ -2533,7 +2549,7 @@ def create_followers_only_post(base_dir: str, replies_moderation_option, anonymous_participation_enabled, event_status, ticket_url, system_language, - conversation_id, low_bandwidth, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, @@ -2591,8 +2607,8 @@ def create_direct_message_post(base_dir: str, event_date: str, event_time: str, event_end_time: str, location: str, system_language: str, - conversation_id: str, low_bandwidth: bool, - content_license_url: str, + conversation_id: str, convthread_id: str, + low_bandwidth: bool, content_license_url: str, media_license_url: str, media_creator: str, languages_understood: [], dm_is_chat: bool, translate: {}, @@ -2633,7 +2649,7 @@ def create_direct_message_post(base_dir: str, replies_moderation_option, anonymous_participation_enabled, event_status, ticket_url, system_language, - conversation_id, low_bandwidth, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -2750,6 +2766,7 @@ def create_report_post(base_dir: str, event_status = None ticket_url = None conversation_id = None + convthread_id = None for to_url in post_to: # who is this report going to? to_nickname = to_url.split('/users/')[1] @@ -2770,7 +2787,7 @@ def create_report_post(base_dir: str, replies_moderation_option, anonymous_participation_enabled, event_status, ticket_url, system_language, - conversation_id, low_bandwidth, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, @@ -3004,6 +3021,7 @@ def send_post(signing_priv_key_pem: str, project_version: str, """ with_digest = True conversation_id = None + convthread_id = None if to_nickname == 'inbox': # shared inbox actor on @domain@domain @@ -3080,7 +3098,7 @@ def send_post(signing_priv_key_pem: str, project_version: str, replies_moderation_option, anonymous_participation_enabled, event_status, ticket_url, system_language, - conversation_id, low_bandwidth, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, @@ -3206,7 +3224,8 @@ def send_post_via_server(signing_priv_key_pem: str, project_version: str, buy_url: str, chat_url: str, auto_cw_cache: {}, debug: bool, in_reply_to: str, in_reply_to_atom_uri: str, - conversation_id: str, subject: str) -> int: + conversation_id: str, convthread_id: str, + subject: str) -> int: """Send a post via a proxy (c2s) """ if not session: @@ -3301,7 +3320,7 @@ def send_post_via_server(signing_priv_key_pem: str, project_version: str, replies_moderation_option, anonymous_participation_enabled, event_status, ticket_url, system_language, - conversation_id, low_bandwidth, + conversation_id, convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, diff --git a/tests.py b/tests.py index d285299b0..4df2ad4bc 100644 --- a/tests.py +++ b/tests.py @@ -799,6 +799,7 @@ def create_server_alice(path: str, domain: str, port: int, test_location = None test_is_article = False conversation_id = None + convthread_id = None translate = {} content_license_url = 'https://creativecommons.org/licenses/by-nc/4.0' media_license_url = 'https://creativecommons.org/licenses/by-nc/4.0' @@ -821,6 +822,7 @@ def create_server_alice(path: str, domain: str, port: int, test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, system_language, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -839,6 +841,7 @@ def create_server_alice(path: str, domain: str, port: int, test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, system_language, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -858,6 +861,7 @@ def create_server_alice(path: str, domain: str, port: int, test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, system_language, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -990,6 +994,7 @@ def create_server_bob(path: str, domain: str, port: int, test_location = None test_is_article = False conversation_id = None + convthread_id = None content_license_url = 'https://creativecommons.org/licenses/by-nc/4.0' media_license_url = 'https://creativecommons.org/licenses/by-nc/4.0' media_creator = 'Hamster' @@ -1012,6 +1017,7 @@ def create_server_bob(path: str, domain: str, port: int, test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, system_language, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -1031,6 +1037,7 @@ def create_server_bob(path: str, domain: str, port: int, test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, system_language, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -1049,6 +1056,7 @@ def create_server_bob(path: str, domain: str, port: int, test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, system_language, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -3080,6 +3088,7 @@ def _test_create_person_account(base_dir: str): attach_image_filename = None media_type = None conversation_id = None + convthread_id = None low_bandwidth = True translate = {} content_license_url = 'https://creativecommons.org/licenses/by-nc/4.0' @@ -3104,6 +3113,7 @@ def _test_create_person_account(base_dir: str): test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, system_language, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -3132,6 +3142,7 @@ def _test_create_person_account(base_dir: str): test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, system_language, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -3309,6 +3320,7 @@ def test_client_to_server(base_dir: str): person_cache = {} password = 'alicepass' conversation_id = None + convthread_id = None alice_inbox_path = \ data_dir(alice_dir) + '/alice@' + alice_domain + '/inbox' @@ -3358,7 +3370,8 @@ def test_client_to_server(base_dir: str): media_license_url, media_creator, event_date, event_time, event_end_time, location, translate, buy_url, chat_url, auto_cw_cache, - True, None, None, conversation_id, None) + True, None, None, conversation_id, convthread_id, + None) print('send_result: ' + str(send_result)) for _ in range(30): @@ -4982,6 +4995,7 @@ def _test_reply_to_public_post(base_dir: str) -> None: test_location = None test_is_article = False conversation_id = None + convthread_id = None low_bandwidth = True content_license_url = 'https://creativecommons.org/licenses/by-nc/4.0' media_license_url = 'https://creativecommons.org/licenses/by-nc/4.0' @@ -5003,6 +5017,7 @@ def _test_reply_to_public_post(base_dir: str) -> None: test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, system_language, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -6026,6 +6041,7 @@ def _test_links_within_post(base_dir: str) -> None: test_location = None test_is_article = False conversation_id = None + convthread_id = None low_bandwidth = True content_license_url = 'https://creativecommons.org/licenses/by-nc/4.0' media_license_url = 'https://creativecommons.org/licenses/by-nc/4.0' @@ -6047,6 +6063,7 @@ def _test_links_within_post(base_dir: str) -> None: test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, system_language, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -6093,6 +6110,7 @@ def _test_links_within_post(base_dir: str) -> None: test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, system_language, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -6117,6 +6135,7 @@ def _test_links_within_post(base_dir: str) -> None: test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, system_language, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -7212,6 +7231,7 @@ def _test_can_replyto(base_dir: str) -> None: test_location = None test_is_article = False conversation_id = None + convthread_id = None low_bandwidth = True content_license_url = 'https://creativecommons.org/licenses/by-nc/4.0' media_license_url = 'https://creativecommons.org/licenses/by-nc/4.0' @@ -7233,6 +7253,7 @@ def _test_can_replyto(base_dir: str) -> None: test_event_date, test_event_time, test_event_end_time, test_location, test_is_article, system_language, conversation_id, + convthread_id, low_bandwidth, content_license_url, media_license_url, media_creator, languages_understood, translate, buy_url, chat_url, @@ -9044,7 +9065,7 @@ def _test_bridgy() -> None: def _test_conversation_to_convthread() -> None: - print('conversation to thread') + print('conversation to convthread') domain = 'the.domain.of.last.resort' conversation_id = \ 'tag:' + domain + \ diff --git a/utils.py b/utils.py index 1eb2b42fa..41012c335 100644 --- a/utils.py +++ b/utils.py @@ -2493,10 +2493,10 @@ def _delete_conversation_post(base_dir: str, nickname: str, domain: str, acct_dir(base_dir, nickname, domain) + '/conversation' if post_json_object['object'].get('conversation'): conversation_id = post_json_object['object']['conversation'] - elif post_json_object['object'].get('thread'): - conversation_id = post_json_object['object']['thread'] - else: + elif post_json_object['object'].get('context'): conversation_id = post_json_object['object']['context'] + else: + conversation_id = post_json_object['object']['thread'] if not isinstance(conversation_id, str): return False conversation_id = conversation_id.replace('/', '#') diff --git a/webapp_create_post.py b/webapp_create_post.py index dd9239a2a..7128fe8d5 100644 --- a/webapp_create_post.py +++ b/webapp_create_post.py @@ -249,7 +249,7 @@ def html_new_post(edit_post_params: {}, default_timeline: str, newswire: {}, theme: str, no_drop_down: bool, access_keys: {}, custom_submit_text: str, - conversation_id: str, + conversation_id: str, convthread_id: str, recent_posts_cache: {}, max_recent_posts: int, session, cached_webfingers: {}, person_cache: {}, port: int, @@ -300,11 +300,12 @@ def html_new_post(edit_post_params: {}, # be referred to as a thread or (confusingly) "context" if edited_post_json['object'].get('conversation'): conversation_id = edited_post_json['object']['conversation'] - elif edited_post_json['object'].get('thread'): - conversation_id = edited_post_json['object']['thread'] elif edited_post_json['object'].get('context'): conversation_id = edited_post_json['object']['context'] + if edited_post_json['object'].get('thread'): + convthread_id = edited_post_json['object']['thread'] + if edit_post_params.get('replyTo'): in_reply_to = edit_post_params['replyTo'] if edit_post_params['scope'] == 'dm': @@ -1125,6 +1126,13 @@ def html_new_post(edit_post_params: {}, dropdown_unlisted_suffix += '?conversationId=' + conversation_id dropdown_followers_suffix += '?conversationId=' + conversation_id dropdown_dm_suffix += '?conversationId=' + conversation_id + if convthread_id and in_reply_to: + if isinstance(convthread_id, str): + dropdown_new_post_suffix += '?convthreadId=' + convthread_id + dropdown_new_blog_suffix += '?convthreadId=' + convthread_id + dropdown_unlisted_suffix += '?convthreadId=' + convthread_id + dropdown_followers_suffix += '?convthreadId=' + convthread_id + dropdown_dm_suffix += '?convthreadId=' + convthread_id drop_down_content = '' if not report_url and not share_description: diff --git a/webapp_post.py b/webapp_post.py index c23d4e855..fcb4d5391 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -605,7 +605,7 @@ def _get_reply_icon_html(base_dir: str, nickname: str, domain: str, show_icons: bool, comments_enabled: bool, post_json_object: {}, page_number_param: str, translate: {}, system_language: str, - conversation_id: str) -> str: + conversation_id: str, convthread_id: str) -> str: """Returns html for the reply icon/button """ reply_str = '' @@ -655,6 +655,9 @@ def _get_reply_icon_html(base_dir: str, nickname: str, domain: str, if conversation_id: if isinstance(conversation_id, str): conversation_str = '?conversationId=' + conversation_id + if convthread_id: + if isinstance(convthread_id, str): + conversation_str = '?convthreadId=' + convthread_id if is_public_reply: actor_url = get_actor_from_post(post_json_object) reply_str += \ @@ -2500,18 +2503,19 @@ def individual_post_as_html(signing_priv_key_pem: str, comments_enabled = False conversation_id = None + convthread_id = None if isinstance(post_json_object['object'], dict): # Due to lack of AP specification maintenance, a conversation can also # be referred to as a thread or (confusingly) "context" if 'conversation' in post_json_object['object']: if post_json_object['object']['conversation']: conversation_id = post_json_object['object']['conversation'] - elif 'thread' in post_json_object['object']: - if post_json_object['object']['thread']: - conversation_id = post_json_object['object']['thread'] elif 'context' in post_json_object['object']: if post_json_object['object']['context']: conversation_id = post_json_object['object']['context'] + if 'thread' in post_json_object['object']: + if post_json_object['object']['thread']: + convthread_id = post_json_object['object']['thread'] public_reply = False unlisted_reply = False @@ -2525,7 +2529,7 @@ def individual_post_as_html(signing_priv_key_pem: str, show_icons, comments_enabled, post_json_object, page_number_param, translate, system_language, - conversation_id) + conversation_id, convthread_id) _log_post_timing(enable_timing_log, post_start_time, '10')