mirror of https://gitlab.com/bashrc2/epicyon
				
				
				
			Merge branch 'main' of gitlab.com:bashrc2/epicyon
						commit
						9cf69b1911
					
				
							
								
								
									
										23
									
								
								daemon.py
								
								
								
								
							
							
						
						
									
										23
									
								
								daemon.py
								
								
								
								
							|  | @ -8,6 +8,7 @@ __status__ = "Production" | |||
| __module_group__ = "Core" | ||||
| 
 | ||||
| from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer, HTTPServer | ||||
| import copy | ||||
| import sys | ||||
| import json | ||||
| import time | ||||
|  | @ -2362,7 +2363,8 @@ class PubServer(BaseHTTPRequestHandler): | |||
|                                             nickname, domain, | ||||
|                                             post_filename, | ||||
|                                             debug, | ||||
|                                             self.server.recent_posts_cache) | ||||
|                                             self.server.recent_posts_cache, | ||||
|                                             True) | ||||
|                         if nickname != 'news': | ||||
|                             # if this is a local blog post then also remove it | ||||
|                             # from the news actor | ||||
|  | @ -2378,7 +2380,8 @@ class PubServer(BaseHTTPRequestHandler): | |||
|                                                 'news', domain, | ||||
|                                                 post_filename, | ||||
|                                                 debug, | ||||
|                                                 self.server.recent_posts_cache) | ||||
|                                                 self.server.recent_posts_cache, | ||||
|                                                 True) | ||||
| 
 | ||||
|         self._redirect_headers(actor_str + '/moderation', | ||||
|                                cookie, calling_domain) | ||||
|  | @ -8654,7 +8657,7 @@ class PubServer(BaseHTTPRequestHandler): | |||
|         if self.server.iconsCache.get('repeat_inactive.png'): | ||||
|             del self.server.iconsCache['repeat_inactive.png'] | ||||
| 
 | ||||
|         # delete  the announce post | ||||
|         # delete the announce post | ||||
|         if '?unannounce=' in path: | ||||
|             announce_url = path.split('?unannounce=')[1] | ||||
|             if '?' in announce_url: | ||||
|  | @ -8668,7 +8671,7 @@ class PubServer(BaseHTTPRequestHandler): | |||
|             if post_filename: | ||||
|                 delete_post(base_dir, http_prefix, | ||||
|                             nickname, domain, post_filename, | ||||
|                             debug, recent_posts_cache) | ||||
|                             debug, recent_posts_cache, True) | ||||
| 
 | ||||
|         self._post_to_outbox(new_undo_announce, | ||||
|                              self.server.project_version, | ||||
|  | @ -19398,12 +19401,12 @@ class PubServer(BaseHTTPRequestHandler): | |||
|                 np_thread.kill() | ||||
| 
 | ||||
|         # make a copy of self.headers | ||||
|         headers = {} | ||||
|         headers_without_cookie = {} | ||||
|         for dict_entry_name, header_line in self.headers.items(): | ||||
|             headers[dict_entry_name] = header_line | ||||
|             if dict_entry_name.lower() != 'cookie': | ||||
|                 headers_without_cookie[dict_entry_name] = header_line | ||||
|         headers = copy.deepcopy(self.headers) | ||||
|         headers_without_cookie = copy.deepcopy(headers) | ||||
|         if 'cookie' in headers_without_cookie: | ||||
|             del headers_without_cookie['cookie'] | ||||
|         if 'Cookie' in headers_without_cookie: | ||||
|             del headers_without_cookie['Cookie'] | ||||
|         print('New post headers: ' + str(headers_without_cookie)) | ||||
| 
 | ||||
|         length = int(headers['Content-Length']) | ||||
|  |  | |||
|  | @ -170,7 +170,7 @@ def outbox_delete(base_dir: str, http_prefix: str, | |||
|             print(message_id) | ||||
|         return True | ||||
|     delete_post(base_dir, http_prefix, delete_nickname, delete_domain, | ||||
|                 post_filename, debug, recent_posts_cache) | ||||
|                 post_filename, debug, recent_posts_cache, True) | ||||
|     if debug: | ||||
|         print('DEBUG: post deleted via c2s - ' + post_filename) | ||||
| 
 | ||||
|  |  | |||
|  | @ -581,13 +581,16 @@ input[type=submit]:hover { | |||
| } | ||||
| 
 | ||||
| .timeline-avatar { | ||||
|     margin: 10px auto; | ||||
|     margin: 0px 0px; | ||||
|     padding: 0px 0px; | ||||
|     width: 8%; | ||||
|     float: left; | ||||
| } | ||||
| 
 | ||||
| .timeline-avatar-reply { | ||||
|     padding: 0px 0px; | ||||
|     width: 80%; | ||||
|     width: 6%; | ||||
|     float: left; | ||||
| } | ||||
| 
 | ||||
| .search-result-text { | ||||
|  | @ -795,11 +798,15 @@ div.gallery img { | |||
|     } | ||||
|     .timeline-avatar img { | ||||
|         opacity: 1.0; | ||||
|         width: 8%; | ||||
|         height: 8%; | ||||
|         width: 100%; | ||||
|         padding: 0px 0px; | ||||
|         -ms-transform: translateY(-10%); | ||||
|         transform: translateY(-10%); | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .timeline-avatar-reply img { | ||||
|         opacity: 1.0; | ||||
|         width: 80%; | ||||
|         padding: 0px 0px; | ||||
| 	margin: 0px 10%; | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .cwButton { | ||||
|  | @ -1149,13 +1156,28 @@ div.gallery img { | |||
|         margin: 1% 3%; | ||||
|         border-radius: 0%; | ||||
|     } | ||||
|     .timeline-avatar { | ||||
|         margin: 0px 0px; | ||||
|         padding: 0px 0px; | ||||
|         width: 15%; | ||||
|         float: left; | ||||
|     } | ||||
|     .timeline-avatar-reply { | ||||
|         padding: 0px 0px; | ||||
|         width: 12%; | ||||
|         float: left; | ||||
|     } | ||||
|     .timeline-avatar img { | ||||
|         opacity: 1.0; | ||||
|         width: 15%; | ||||
|         height: 15%; | ||||
|         width: 100%; | ||||
|         padding: 0px 0px; | ||||
|         -ms-transform: translateY(-10%); | ||||
|         transform: translateY(-10%); | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .timeline-avatar-reply img { | ||||
|         opacity: 1.0; | ||||
|         width: 80%; | ||||
|         padding: 0px 0px; | ||||
| 	margin: 0px 10%; | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .cwButton { | ||||
|  | @ -1496,13 +1518,28 @@ div.gallery img { | |||
|         margin: 1% 3%; | ||||
|         border-radius: 0%; | ||||
|     } | ||||
|     .timeline-avatar { | ||||
|         margin: 0px 0px; | ||||
|         padding: 0px 0px; | ||||
|         width: 15%; | ||||
|         float: left; | ||||
|     } | ||||
|     .timeline-avatar-reply { | ||||
|         padding: 0px 0px; | ||||
|         width: 12%; | ||||
|         float: left; | ||||
|     } | ||||
|     .timeline-avatar img { | ||||
|         opacity: 1.0; | ||||
|         width: 15%; | ||||
|         height: 15%; | ||||
|         width: 100%; | ||||
|         padding: 0px 0px; | ||||
|         -ms-transform: translateY(-10%); | ||||
|         transform: translateY(-10%); | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .timeline-avatar-reply img { | ||||
|         opacity: 1.0; | ||||
|         width: 80%; | ||||
|         padding: 0px 0px; | ||||
| 	margin: 0px 10%; | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .cwButton { | ||||
|  |  | |||
|  | @ -582,8 +582,10 @@ input[type=submit]:hover { | |||
| } | ||||
| 
 | ||||
| .timeline-avatar { | ||||
|     margin: 10px auto; | ||||
|     margin: 0px 0px; | ||||
|     padding: 0px 0px; | ||||
|     width: 8%; | ||||
|     float: left; | ||||
| } | ||||
| 
 | ||||
| .timeline-avatar:hover { | ||||
|  | @ -592,7 +594,8 @@ input[type=submit]:hover { | |||
| 
 | ||||
| .timeline-avatar-reply { | ||||
|     padding: 0px 0px; | ||||
|     width: 80%; | ||||
|     width: 6%; | ||||
|     float: left; | ||||
| } | ||||
| 
 | ||||
| .search-result-text { | ||||
|  | @ -1054,11 +1057,15 @@ aside .toggle-inside li { | |||
|     } | ||||
|     .timeline-avatar img { | ||||
|         opacity: 1.0; | ||||
|         width: 8%; | ||||
|         height: 8%; | ||||
|         width: 100%; | ||||
|         padding: 0px 0px; | ||||
|         -ms-transform: translateY(-10%); | ||||
|         transform: translateY(-10%); | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .timeline-avatar-reply img { | ||||
|         opacity: 1.0; | ||||
|         width: 80%; | ||||
|         padding: 0px 0px; | ||||
| 	margin: 0px 10%; | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .buttonevent { | ||||
|  | @ -1523,13 +1530,28 @@ aside .toggle-inside li { | |||
|         margin: 1% 3%; | ||||
|         border-radius: 0%; | ||||
|     } | ||||
|     .timeline-avatar { | ||||
|         margin: 0px 0px; | ||||
|         padding: 0px 0px; | ||||
|         width: 15%; | ||||
|         float: left; | ||||
|     } | ||||
|     .timeline-avatar-reply { | ||||
|         padding: 0px 0px; | ||||
|         width: 12%; | ||||
|         float: left; | ||||
|     } | ||||
|     .timeline-avatar img { | ||||
|         opacity: 1.0; | ||||
|         width: 15%; | ||||
|         height: 15%; | ||||
|         width: 100%; | ||||
|         padding: 0px 0px; | ||||
|         -ms-transform: translateY(-10%); | ||||
|         transform: translateY(-10%); | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .timeline-avatar-reply img { | ||||
|         opacity: 1.0; | ||||
|         width: 80%; | ||||
|         padding: 0px 0px; | ||||
| 	margin: 0px 10%; | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .buttonevent { | ||||
|  | @ -1986,13 +2008,28 @@ aside .toggle-inside li { | |||
|         margin: 1% 3%; | ||||
|         border-radius: 0%; | ||||
|     } | ||||
|     .timeline-avatar { | ||||
|         margin: 0px 0px; | ||||
|         padding: 0px 0px; | ||||
|         width: 15%; | ||||
|         float: left; | ||||
|     } | ||||
|     .timeline-avatar-reply { | ||||
|         padding: 0px 0px; | ||||
|         width: 12%; | ||||
|         float: left; | ||||
|     } | ||||
|     .timeline-avatar img { | ||||
|         opacity: 1.0; | ||||
|         width: 15%; | ||||
|         height: 15%; | ||||
|         width: 100%; | ||||
|         padding: 0px 0px; | ||||
|         -ms-transform: translateY(-10%); | ||||
|         transform: translateY(-10%); | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .timeline-avatar-reply img { | ||||
|         opacity: 1.0; | ||||
|         width: 80%; | ||||
|         padding: 0px 0px; | ||||
| 	margin: 0px 10%; | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .buttonevent { | ||||
|  |  | |||
|  | @ -885,8 +885,10 @@ input[type=submit]:hover { | |||
| } | ||||
| 
 | ||||
| .timeline-avatar { | ||||
|     margin: 10px auto; | ||||
|     margin: 0px 0px; | ||||
|     padding: 0px 0px; | ||||
|     width: 8%; | ||||
|     float: left; | ||||
| } | ||||
| 
 | ||||
| .timeline-avatar:hover { | ||||
|  | @ -895,7 +897,8 @@ input[type=submit]:hover { | |||
| 
 | ||||
| .timeline-avatar-reply { | ||||
|     padding: 0px 0px; | ||||
|     width: 80%; | ||||
|     width: 6%; | ||||
|     float: left; | ||||
| } | ||||
| 
 | ||||
| .search-result-text { | ||||
|  | @ -1473,11 +1476,15 @@ h3 { | |||
|     } | ||||
|     .timeline-avatar img { | ||||
|         opacity: 1.0; | ||||
|         width: 8%; | ||||
|         height: 8%; | ||||
|         width: 100%; | ||||
|         padding: 0px 0px; | ||||
|         -ms-transform: translateY(-10%); | ||||
|         transform: translateY(-10%); | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .timeline-avatar-reply img { | ||||
|         opacity: 1.0; | ||||
|         width: 80%; | ||||
|         padding: 0px 0px; | ||||
| 	margin: 0px 10%; | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .buttonevent { | ||||
|  | @ -2228,13 +2235,28 @@ h3 { | |||
|         margin-right: 0px; | ||||
|         border-radius: 0%; | ||||
|     } | ||||
|     .timeline-avatar { | ||||
|         margin: 0px 0px; | ||||
|         padding: 0px 0px; | ||||
|         width: 15%; | ||||
|         float: left; | ||||
|     } | ||||
|     .timeline-avatar-reply { | ||||
|         padding: 0px 0px; | ||||
|         width: 12%; | ||||
|         float: left; | ||||
|     } | ||||
|     .timeline-avatar img { | ||||
|         opacity: 1.0; | ||||
|         width: 15%; | ||||
|         height: 15%; | ||||
|         width: 100%; | ||||
|         padding: 0px 0px; | ||||
|         -ms-transform: translateY(-10%); | ||||
|         transform: translateY(-10%); | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .timeline-avatar-reply img { | ||||
|         opacity: 1.0; | ||||
|         width: 80%; | ||||
|         padding: 0px 0px; | ||||
| 	margin: 0px 10%; | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .buttonevent { | ||||
|  | @ -2988,13 +3010,28 @@ h3 { | |||
|         margin-right: 0px; | ||||
|         border-radius: 0%; | ||||
|     } | ||||
|     .timeline-avatar { | ||||
|         margin: 0px 0px; | ||||
|         padding: 0px 0px; | ||||
|         width: 15%; | ||||
|         float: left; | ||||
|     } | ||||
|     .timeline-avatar-reply { | ||||
|         padding: 0px 0px; | ||||
|         width: 12%; | ||||
|         float: left; | ||||
|     } | ||||
|     .timeline-avatar img { | ||||
|         opacity: 1.0; | ||||
|         width: 15%; | ||||
|         height: 15%; | ||||
|         width: 100%; | ||||
|         padding: 0px 0px; | ||||
|         -ms-transform: translateY(-10%); | ||||
|         transform: translateY(-10%); | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .timeline-avatar-reply img { | ||||
|         opacity: 1.0; | ||||
|         width: 80%; | ||||
|         padding: 0px 0px; | ||||
| 	margin: 0px 10%; | ||||
|         border-radius: var(--avatar-rounding); | ||||
|     } | ||||
|     .buttonevent { | ||||
|  |  | |||
|  | @ -1276,7 +1276,7 @@ def dav_delete_response(base_dir: str, nickname: str, domain: str, | |||
|                           token_post_id) | ||||
|     delete_post(base_dir, http_prefix, | ||||
|                 nickname, domain, post_filename, | ||||
|                 debug, recent_posts_cache) | ||||
|                 debug, recent_posts_cache, True) | ||||
|     return 'Ok' | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										6
									
								
								inbox.py
								
								
								
								
							
							
						
						
									
										6
									
								
								inbox.py
								
								
								
								
							|  | @ -2058,7 +2058,7 @@ def _receive_delete(session, handle: str, is_group: bool, base_dir: str, | |||
|         return True | ||||
|     delete_post(base_dir, http_prefix, handle_nickname, | ||||
|                 handle_domain, post_filename, debug, | ||||
|                 recent_posts_cache) | ||||
|                 recent_posts_cache, True) | ||||
|     if debug: | ||||
|         print('DEBUG: post deleted - ' + post_filename) | ||||
| 
 | ||||
|  | @ -2069,7 +2069,7 @@ def _receive_delete(session, handle: str, is_group: bool, base_dir: str, | |||
|         if post_filename: | ||||
|             delete_post(base_dir, http_prefix, 'news', | ||||
|                         handle_domain, post_filename, debug, | ||||
|                         recent_posts_cache) | ||||
|                         recent_posts_cache, True) | ||||
|             if debug: | ||||
|                 print('DEBUG: blog post deleted - ' + post_filename) | ||||
|     return True | ||||
|  | @ -4094,7 +4094,7 @@ def _inbox_after_initial(server, inbox_start_time, | |||
|                 if edited_filename != destination_filename: | ||||
|                     delete_post(base_dir, http_prefix, | ||||
|                                 nickname, domain, edited_filename, | ||||
|                                 debug, recent_posts_cache) | ||||
|                                 debug, recent_posts_cache, True) | ||||
| 
 | ||||
|             # update the indexes for different timelines | ||||
|             for boxname in update_index_list: | ||||
|  |  | |||
							
								
								
									
										2
									
								
								posts.py
								
								
								
								
							
							
						
						
									
										2
									
								
								posts.py
								
								
								
								
							|  | @ -4294,7 +4294,7 @@ def archive_posts_for_person(http_prefix: str, nickname: str, domain: str, | |||
|                                                        '.json.' + ext)) | ||||
|         else: | ||||
|             delete_post(base_dir, http_prefix, nickname, domain, | ||||
|                         file_path, False, recent_posts_cache) | ||||
|                         file_path, False, recent_posts_cache, False) | ||||
| 
 | ||||
|         # remove cached html posts | ||||
|         post_cache_filename = \ | ||||
|  |  | |||
							
								
								
									
										19
									
								
								tests.py
								
								
								
								
							
							
						
						
									
										19
									
								
								tests.py
								
								
								
								
							|  | @ -3393,11 +3393,14 @@ def test_client_to_server(base_dir: str): | |||
| 
 | ||||
|     inbox_path = bob_dir + '/accounts/bob@' + bob_domain + '/inbox' | ||||
|     outbox_path = alice_dir + '/accounts/alice@' + alice_domain + '/outbox' | ||||
|     posts_before = \ | ||||
|     bob_posts_before = \ | ||||
|         len([name for name in os.listdir(inbox_path) | ||||
|              if os.path.isfile(os.path.join(inbox_path, name))]) | ||||
|     alice_posts_before = \ | ||||
|         len([name for name in os.listdir(outbox_path) | ||||
|              if os.path.isfile(os.path.join(outbox_path, name))]) | ||||
|     print('\n\nEVENT: Alice deletes her post: ' + outbox_post_id + ' ' + | ||||
|           str(posts_before)) | ||||
|           str(alice_posts_before)) | ||||
|     password = 'alicepass' | ||||
|     send_delete_via_server(alice_dir, session_alice, 'alice', password, | ||||
|                            alice_domain, alice_port, | ||||
|  | @ -3408,14 +3411,20 @@ def test_client_to_server(base_dir: str): | |||
|         if os.path.isdir(inbox_path): | ||||
|             test = len([name for name in os.listdir(inbox_path) | ||||
|                         if os.path.isfile(os.path.join(inbox_path, name))]) | ||||
|             if test == posts_before-1: | ||||
|             if test == bob_posts_before-1: | ||||
|                 break | ||||
|         time.sleep(1) | ||||
| 
 | ||||
|     test = len([name for name in os.listdir(inbox_path) | ||||
|                 if os.path.isfile(os.path.join(inbox_path, name))]) | ||||
|     assert test == posts_before - 1 | ||||
|     print(">>> post deleted from Alice's outbox and Bob's inbox") | ||||
|     assert test == bob_posts_before - 1 | ||||
|     print(">>> post was deleted from Bob's inbox") | ||||
|     test = len([name for name in os.listdir(outbox_path) | ||||
|                 if os.path.isfile(os.path.join(outbox_path, name))]) | ||||
|     # this should be unchanged because a delete post was added | ||||
|     # at the outbox and one was removed | ||||
|     assert test == alice_posts_before | ||||
|     print(">>> post deleted from Alice's outbox") | ||||
|     assert valid_inbox(bob_dir, 'bob', bob_domain) | ||||
|     assert valid_inbox_filenames(bob_dir, 'bob', bob_domain, | ||||
|                                  alice_domain, alice_port) | ||||
|  |  | |||
							
								
								
									
										108
									
								
								utils.py
								
								
								
								
							
							
						
						
									
										108
									
								
								utils.py
								
								
								
								
							|  | @ -91,6 +91,15 @@ def get_actor_languages_list(actor_json: {}) -> []: | |||
|     return [] | ||||
| 
 | ||||
| 
 | ||||
| def has_object_dict(post_json_object: {}) -> bool: | ||||
|     """Returns true if the given post has an object dict | ||||
|     """ | ||||
|     if post_json_object.get('object'): | ||||
|         if isinstance(post_json_object['object'], dict): | ||||
|             return True | ||||
|     return False | ||||
| 
 | ||||
| 
 | ||||
| def get_content_from_post(post_json_object: {}, system_language: str, | ||||
|                           languages_understood: [], | ||||
|                           contentType: str = "content") -> str: | ||||
|  | @ -1610,7 +1619,8 @@ def _is_reply_to_blog_post(base_dir: str, nickname: str, domain: str, | |||
| 
 | ||||
| def _delete_post_remove_replies(base_dir: str, nickname: str, domain: str, | ||||
|                                 http_prefix: str, post_filename: str, | ||||
|                                 recent_posts_cache: {}, debug: bool) -> None: | ||||
|                                 recent_posts_cache: {}, debug: bool, | ||||
|                                 manual: bool) -> None: | ||||
|     """Removes replies when deleting a post | ||||
|     """ | ||||
|     replies_filename = post_filename.replace('.json', '.replies') | ||||
|  | @ -1626,7 +1636,7 @@ def _delete_post_remove_replies(base_dir: str, nickname: str, domain: str, | |||
|             if os.path.isfile(reply_file): | ||||
|                 delete_post(base_dir, http_prefix, | ||||
|                             nickname, domain, reply_file, debug, | ||||
|                             recent_posts_cache) | ||||
|                             recent_posts_cache, manual) | ||||
|     # remove the replies file | ||||
|     try: | ||||
|         os.remove(replies_filename) | ||||
|  | @ -1794,9 +1804,53 @@ def _delete_conversation_post(base_dir: str, nickname: str, domain: str, | |||
|                   str(conversation_filename)) | ||||
| 
 | ||||
| 
 | ||||
| def is_dm(post_json_object: {}) -> bool: | ||||
|     """Returns true if the given post is a DM | ||||
|     """ | ||||
|     if post_json_object['type'] != 'Create': | ||||
|         return False | ||||
|     if not has_object_dict(post_json_object): | ||||
|         return False | ||||
|     if post_json_object['object']['type'] != 'ChatMessage': | ||||
|         if post_json_object['object']['type'] != 'Note' and \ | ||||
|            post_json_object['object']['type'] != 'Page' and \ | ||||
|            post_json_object['object']['type'] != 'Patch' and \ | ||||
|            post_json_object['object']['type'] != 'EncryptedMessage' and \ | ||||
|            post_json_object['object']['type'] != 'Article': | ||||
|             return False | ||||
|     if post_json_object['object'].get('moderationStatus'): | ||||
|         return False | ||||
|     fields = ('to', 'cc') | ||||
|     for field_name in fields: | ||||
|         if not post_json_object['object'].get(field_name): | ||||
|             continue | ||||
|         for to_address in post_json_object['object'][field_name]: | ||||
|             if to_address.endswith('#Public'): | ||||
|                 return False | ||||
|             if to_address.endswith('followers'): | ||||
|                 return False | ||||
|     return True | ||||
| 
 | ||||
| 
 | ||||
| def _is_remote_dm(domain_full: str, post_json_object: {}) -> bool: | ||||
|     """Is the given post a DM from a different domain? | ||||
|     """ | ||||
|     if not is_dm(post_json_object): | ||||
|         return False | ||||
|     this_post_json = post_json_object | ||||
|     if has_object_dict(post_json_object): | ||||
|         this_post_json = post_json_object['object'] | ||||
|     if this_post_json.get('attributedTo'): | ||||
|         if isinstance(this_post_json['attributedTo'], str): | ||||
|             if '://' + domain_full not in this_post_json['attributedTo']: | ||||
|                 return True | ||||
|     return False | ||||
| 
 | ||||
| 
 | ||||
| def delete_post(base_dir: str, http_prefix: str, | ||||
|                 nickname: str, domain: str, post_filename: str, | ||||
|                 debug: bool, recent_posts_cache: {}) -> None: | ||||
|                 debug: bool, recent_posts_cache: {}, | ||||
|                 manual: bool) -> None: | ||||
|     """Recursively deletes a post and its replies and attachments | ||||
|     """ | ||||
|     post_json_object = load_json(post_filename, 1) | ||||
|  | @ -1804,7 +1858,7 @@ def delete_post(base_dir: str, http_prefix: str, | |||
|         # remove any replies | ||||
|         _delete_post_remove_replies(base_dir, nickname, domain, | ||||
|                                     http_prefix, post_filename, | ||||
|                                     recent_posts_cache, debug) | ||||
|                                     recent_posts_cache, debug, manual) | ||||
|         # finally, remove the post itself | ||||
|         try: | ||||
|             os.remove(post_filename) | ||||
|  | @ -1814,6 +1868,13 @@ def delete_post(base_dir: str, http_prefix: str, | |||
|                       str(post_filename)) | ||||
|         return | ||||
| 
 | ||||
|     # don't allow DMs to be deleted if they came from a different instance | ||||
|     # otherwise this breaks expectations about how DMs should operate | ||||
|     # i.e. DMs should only be removed if they are manually deleted | ||||
|     if not manual: | ||||
|         if _is_remote_dm(domain, post_json_object): | ||||
|             return | ||||
| 
 | ||||
|     # don't allow deletion of bookmarked posts | ||||
|     if _is_bookmarked(base_dir, nickname, domain, post_filename): | ||||
|         return | ||||
|  | @ -1874,7 +1935,7 @@ def delete_post(base_dir: str, http_prefix: str, | |||
|     # remove any replies | ||||
|     _delete_post_remove_replies(base_dir, nickname, domain, | ||||
|                                 http_prefix, post_filename, | ||||
|                                 recent_posts_cache, debug) | ||||
|                                 recent_posts_cache, debug, manual) | ||||
|     # finally, remove the post itself | ||||
|     try: | ||||
|         os.remove(post_filename) | ||||
|  | @ -2769,34 +2830,6 @@ def is_chat_message(post_json_object: {}) -> bool: | |||
|     return True | ||||
| 
 | ||||
| 
 | ||||
| def is_dm(post_json_object: {}) -> bool: | ||||
|     """Returns true if the given post is a DM | ||||
|     """ | ||||
|     if post_json_object['type'] != 'Create': | ||||
|         return False | ||||
|     if not has_object_dict(post_json_object): | ||||
|         return False | ||||
|     if post_json_object['object']['type'] != 'ChatMessage': | ||||
|         if post_json_object['object']['type'] != 'Note' and \ | ||||
|            post_json_object['object']['type'] != 'Page' and \ | ||||
|            post_json_object['object']['type'] != 'Patch' and \ | ||||
|            post_json_object['object']['type'] != 'EncryptedMessage' and \ | ||||
|            post_json_object['object']['type'] != 'Article': | ||||
|             return False | ||||
|     if post_json_object['object'].get('moderationStatus'): | ||||
|         return False | ||||
|     fields = ('to', 'cc') | ||||
|     for field_name in fields: | ||||
|         if not post_json_object['object'].get(field_name): | ||||
|             continue | ||||
|         for to_address in post_json_object['object'][field_name]: | ||||
|             if to_address.endswith('#Public'): | ||||
|                 return False | ||||
|             if to_address.endswith('followers'): | ||||
|                 return False | ||||
|     return True | ||||
| 
 | ||||
| 
 | ||||
| def is_reply(post_json_object: {}, actor: str) -> bool: | ||||
|     """Returns true if the given post is a reply to the given actor | ||||
|     """ | ||||
|  | @ -3037,15 +3070,6 @@ def user_agent_domain(user_agent: str, debug: bool) -> str: | |||
|     return agent_domain | ||||
| 
 | ||||
| 
 | ||||
| def has_object_dict(post_json_object: {}) -> bool: | ||||
|     """Returns true if the given post has an object dict | ||||
|     """ | ||||
|     if post_json_object.get('object'): | ||||
|         if isinstance(post_json_object['object'], dict): | ||||
|             return True | ||||
|     return False | ||||
| 
 | ||||
| 
 | ||||
| def get_alt_path(actor: str, domain_full: str, calling_domain: str) -> str: | ||||
|     """Returns alternate path from the actor | ||||
|     eg. https://clearnetdomain/path becomes http://oniondomain/path | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue