| 
									
										
										
										
											2020-04-01 20:06:27 +00:00
										 |  |  | __filename__ = "blocking.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							| 
									
										
										
										
											2024-12-22 23:37:30 +00:00
										 |  |  | __version__ = "1.6.0" | 
					
						
							| 
									
										
										
										
											2020-04-01 20:06:27 +00:00
										 |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							| 
									
										
										
										
											2021-09-10 16:14:50 +00:00
										 |  |  | __email__ = "bob@libreserver.org" | 
					
						
							| 
									
										
										
										
											2020-04-01 20:06:27 +00:00
										 |  |  | __status__ = "Production" | 
					
						
							| 
									
										
										
										
											2021-06-25 16:10:09 +00:00
										 |  |  | __module_group__ = "Core" | 
					
						
							| 
									
										
										
										
											2019-07-14 19:27:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | import os | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  | import json | 
					
						
							| 
									
										
										
										
											2021-06-21 09:22:24 +00:00
										 |  |  | import time | 
					
						
							| 
									
										
										
										
											2023-08-13 09:58:02 +00:00
										 |  |  | from session import get_json_valid | 
					
						
							| 
									
										
										
										
											2024-02-09 21:00:12 +00:00
										 |  |  | from session import create_session | 
					
						
							| 
									
										
										
										
											2024-09-13 13:58:14 +00:00
										 |  |  | from flags import is_evil | 
					
						
							| 
									
										
										
										
											2025-02-23 14:52:50 +00:00
										 |  |  | from flags import is_quote_toot | 
					
						
							|  |  |  | from utils import get_quote_toot_url | 
					
						
							| 
									
										
										
										
											2024-05-27 12:45:01 +00:00
										 |  |  | from utils import get_user_paths | 
					
						
							|  |  |  | from utils import contains_statuses | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  | from utils import data_dir | 
					
						
							| 
									
										
										
										
											2024-04-10 12:59:57 +00:00
										 |  |  | from utils import string_contains | 
					
						
							| 
									
										
										
										
											2023-11-20 22:27:58 +00:00
										 |  |  | from utils import date_from_string_format | 
					
						
							|  |  |  | from utils import date_utcnow | 
					
						
							| 
									
										
										
										
											2022-06-21 11:58:50 +00:00
										 |  |  | from utils import remove_eol | 
					
						
							| 
									
										
										
										
											2021-12-26 17:12:07 +00:00
										 |  |  | from utils import has_object_string | 
					
						
							| 
									
										
										
										
											2021-12-26 15:54:46 +00:00
										 |  |  | from utils import has_object_string_object | 
					
						
							| 
									
										
										
										
											2022-04-09 15:11:22 +00:00
										 |  |  | from utils import has_object_string_type | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  | from utils import remove_domain_port | 
					
						
							| 
									
										
										
										
											2021-12-26 10:57:03 +00:00
										 |  |  | from utils import has_object_dict | 
					
						
							| 
									
										
										
										
											2021-12-26 18:46:43 +00:00
										 |  |  | from utils import is_account_dir | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  | from utils import get_cached_post_filename | 
					
						
							| 
									
										
										
										
											2021-12-26 15:13:34 +00:00
										 |  |  | from utils import load_json | 
					
						
							| 
									
										
										
										
											2021-12-26 14:47:21 +00:00
										 |  |  | from utils import save_json | 
					
						
							| 
									
										
										
										
											2021-12-28 14:01:37 +00:00
										 |  |  | from utils import file_last_modified | 
					
						
							| 
									
										
										
										
											2021-12-27 20:38:02 +00:00
										 |  |  | from utils import set_config_param | 
					
						
							| 
									
										
										
										
											2021-12-26 12:19:00 +00:00
										 |  |  | from utils import has_users_path | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  | from utils import get_full_domain | 
					
						
							| 
									
										
										
										
											2021-12-27 11:20:57 +00:00
										 |  |  | from utils import remove_id_ending | 
					
						
							| 
									
										
										
										
											2021-12-26 20:36:08 +00:00
										 |  |  | from utils import locate_post | 
					
						
							| 
									
										
										
										
											2021-12-27 17:46:27 +00:00
										 |  |  | from utils import evil_incarnate | 
					
						
							| 
									
										
										
										
											2021-12-27 19:05:25 +00:00
										 |  |  | from utils import get_domain_from_actor | 
					
						
							| 
									
										
										
										
											2021-12-27 22:19:18 +00:00
										 |  |  | from utils import get_nickname_from_actor | 
					
						
							| 
									
										
										
										
											2021-12-26 12:02:29 +00:00
										 |  |  | from utils import acct_dir | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  | from utils import local_actor_url | 
					
						
							| 
									
										
										
										
											2021-12-26 17:15:04 +00:00
										 |  |  | from utils import has_actor | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  | from utils import text_in_file | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  | from utils import get_actor_from_post | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | from conversation import mute_conversation | 
					
						
							|  |  |  | from conversation import unmute_conversation | 
					
						
							| 
									
										
										
										
											2023-07-05 11:56:02 +00:00
										 |  |  | from auth import create_basic_auth_header | 
					
						
							|  |  |  | from session import get_json | 
					
						
							| 
									
										
										
										
											2019-07-14 19:27:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 20:06:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-23 18:40:45 +00:00
										 |  |  | def get_global_block_reason(search_text: str, | 
					
						
							|  |  |  |                             blocking_reasons_filename: str) -> str: | 
					
						
							|  |  |  |     """Returns the reason why a domain was globally blocked
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not text_in_file(search_text, blocking_reasons_filename): | 
					
						
							|  |  |  |         return '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reasons_str = '' | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         with open(blocking_reasons_filename, 'r', | 
					
						
							|  |  |  |                   encoding='utf-8') as fp_reas: | 
					
						
							|  |  |  |             reasons_str = fp_reas.read() | 
					
						
							|  |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2024-07-13 11:59:31 +00:00
										 |  |  |         print('WARN: Failed to read blocking reasons ' + | 
					
						
							| 
									
										
										
										
											2022-11-23 18:40:45 +00:00
										 |  |  |               blocking_reasons_filename) | 
					
						
							|  |  |  |     if not reasons_str: | 
					
						
							|  |  |  |         return '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reasons_lines = reasons_str.split('\n') | 
					
						
							|  |  |  |     for line in reasons_lines: | 
					
						
							|  |  |  |         if line.startswith(search_text): | 
					
						
							|  |  |  |             if ' ' in line: | 
					
						
							|  |  |  |                 return line.split(' ', 1)[1] | 
					
						
							|  |  |  |     return '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def get_account_blocks(base_dir: str, | 
					
						
							|  |  |  |                        nickname: str, domain: str) -> str: | 
					
						
							| 
									
										
										
										
											2024-08-25 08:56:23 +00:00
										 |  |  |     """Return the text for the textarea for "blocked accounts"
 | 
					
						
							| 
									
										
										
										
											2022-11-23 18:40:45 +00:00
										 |  |  |     when editing profile | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     account_directory = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     blocking_filename = \ | 
					
						
							|  |  |  |         account_directory + '/blocking.txt' | 
					
						
							|  |  |  |     blocking_reasons_filename = \ | 
					
						
							|  |  |  |         account_directory + '/blocking_reasons.txt' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not os.path.isfile(blocking_filename): | 
					
						
							|  |  |  |         return '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     blocked_accounts_textarea = '' | 
					
						
							|  |  |  |     blocking_file_text = '' | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         with open(blocking_filename, 'r', encoding='utf-8') as fp_block: | 
					
						
							|  |  |  |             blocking_file_text = fp_block.read() | 
					
						
							|  |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2024-07-13 12:02:54 +00:00
										 |  |  |         print('EX: Failed to read account blocks ' + blocking_filename) | 
					
						
							| 
									
										
										
										
											2022-11-23 18:40:45 +00:00
										 |  |  |         return '' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     blocklist = blocking_file_text.split('\n') | 
					
						
							|  |  |  |     for handle in blocklist: | 
					
						
							|  |  |  |         handle = handle.strip() | 
					
						
							| 
									
										
										
										
											2022-11-23 19:00:59 +00:00
										 |  |  |         if not handle: | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2022-11-23 18:40:45 +00:00
										 |  |  |         reason = \ | 
					
						
							|  |  |  |             get_global_block_reason(handle, | 
					
						
							|  |  |  |                                     blocking_reasons_filename) | 
					
						
							|  |  |  |         if reason: | 
					
						
							|  |  |  |             blocked_accounts_textarea += \ | 
					
						
							|  |  |  |                 handle + ' - ' + reason + '\n' | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         blocked_accounts_textarea += handle + '\n' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return blocked_accounts_textarea | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-05 11:16:23 +00:00
										 |  |  | def blocked_timeline_json(actor: str, page_number: int, items_per_page: int, | 
					
						
							|  |  |  |                           base_dir: str, | 
					
						
							|  |  |  |                           nickname: str, domain: str) -> {}: | 
					
						
							|  |  |  |     """Returns blocked collection for an account
 | 
					
						
							|  |  |  |     https://codeberg.org/fediverse/fep/src/branch/main/fep/c648/fep-c648.md | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     blocked_accounts_textarea = \ | 
					
						
							|  |  |  |         get_account_blocks(base_dir, nickname, domain) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |     blocked_list: list[str] = [] | 
					
						
							| 
									
										
										
										
											2023-07-05 11:16:23 +00:00
										 |  |  |     if blocked_accounts_textarea: | 
					
						
							|  |  |  |         blocked_list = blocked_accounts_textarea.split('\n') | 
					
						
							|  |  |  |     start_index = (page_number - 1) * items_per_page | 
					
						
							|  |  |  |     if start_index >= len(blocked_list): | 
					
						
							|  |  |  |         start_index = 0 | 
					
						
							| 
									
										
										
										
											2023-07-05 17:49:34 +00:00
										 |  |  |     last_page_number = (len(blocked_list) / items_per_page) + 1 | 
					
						
							| 
									
										
										
										
											2023-07-05 11:16:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     result_json = { | 
					
						
							|  |  |  |         "@context": [ | 
					
						
							| 
									
										
										
										
											2024-09-14 16:40:11 +00:00
										 |  |  |             'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |             'https://w3id.org/security/v1', | 
					
						
							| 
									
										
										
										
											2023-07-05 11:16:23 +00:00
										 |  |  |             "https://purl.archive.org/socialweb/blocked" | 
					
						
							|  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2023-07-05 17:49:34 +00:00
										 |  |  |         "id": actor + '?page=' + str(page_number), | 
					
						
							|  |  |  |         "first": actor + '?page=1', | 
					
						
							|  |  |  |         "last": actor + '?page=' + str(last_page_number), | 
					
						
							| 
									
										
										
										
											2023-07-05 11:16:23 +00:00
										 |  |  |         "type": "OrderedCollection", | 
					
						
							|  |  |  |         "name": nickname + "'s Blocked Collection", | 
					
						
							|  |  |  |         "orderedItems": [] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     index = start_index | 
					
						
							|  |  |  |     for _ in range(items_per_page): | 
					
						
							|  |  |  |         if index >= len(blocked_list): | 
					
						
							|  |  |  |             break | 
					
						
							|  |  |  |         block_handle = blocked_list[index] | 
					
						
							|  |  |  |         block_reason = '' | 
					
						
							|  |  |  |         if ' - ' in block_handle: | 
					
						
							|  |  |  |             block_reason = block_handle.split(' - ')[1] | 
					
						
							|  |  |  |             block_handle = block_handle.split(' - ')[0] | 
					
						
							|  |  |  |         block_type = "Person" | 
					
						
							|  |  |  |         if block_handle.startswith('*@'): | 
					
						
							|  |  |  |             block_type = "Application" | 
					
						
							|  |  |  |             block_handle = block_handle.split('*@', 1)[1] | 
					
						
							|  |  |  |         block_json = { | 
					
						
							|  |  |  |             "type": "Block", | 
					
						
							|  |  |  |             "id": actor + '/' + str(index), | 
					
						
							|  |  |  |             "object": { | 
					
						
							|  |  |  |                 "type": block_type, | 
					
						
							|  |  |  |                 "id": block_handle | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if block_reason: | 
					
						
							|  |  |  |             block_json["object"]["name"] = block_reason | 
					
						
							|  |  |  |         result_json["orderedItems"].append(block_json) | 
					
						
							|  |  |  |         index += 1 | 
					
						
							|  |  |  |     return result_json | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-23 18:14:46 +00:00
										 |  |  | def add_account_blocks(base_dir: str, | 
					
						
							|  |  |  |                        nickname: str, domain: str, | 
					
						
							|  |  |  |                        blocked_accounts_textarea: str) -> bool: | 
					
						
							|  |  |  |     """Update the blockfile for an account after editing their
 | 
					
						
							|  |  |  |     profile and changing "blocked accounts" | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if blocked_accounts_textarea is None: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     blocklist = blocked_accounts_textarea.split('\n') | 
					
						
							|  |  |  |     blocking_file_text = '' | 
					
						
							|  |  |  |     blocking_reasons_file_text = '' | 
					
						
							|  |  |  |     for line in blocklist: | 
					
						
							|  |  |  |         line = line.strip() | 
					
						
							|  |  |  |         reason = None | 
					
						
							| 
									
										
										
										
											2022-11-23 18:40:45 +00:00
										 |  |  |         if ' - ' in line: | 
					
						
							|  |  |  |             block_id = line.split(' - ', 1)[0] | 
					
						
							|  |  |  |             reason = line.split(' - ', 1)[1] | 
					
						
							|  |  |  |             blocking_reasons_file_text += block_id + ' ' + reason + '\n' | 
					
						
							|  |  |  |         elif ' ' in line: | 
					
						
							| 
									
										
										
										
											2022-11-23 18:14:46 +00:00
										 |  |  |             block_id = line.split(' ', 1)[0] | 
					
						
							|  |  |  |             reason = line.split(' ', 1)[1] | 
					
						
							|  |  |  |             blocking_reasons_file_text += block_id + ' ' + reason + '\n' | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             block_id = line | 
					
						
							|  |  |  |         blocking_file_text += block_id + '\n' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     account_directory = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     blocking_filename = \ | 
					
						
							|  |  |  |         account_directory + '/blocking.txt' | 
					
						
							|  |  |  |     blocking_reasons_filename = \ | 
					
						
							|  |  |  |         account_directory + '/blocking_reasons.txt' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not blocking_file_text: | 
					
						
							|  |  |  |         if os.path.isfile(blocking_filename): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 os.remove(blocking_filename) | 
					
						
							|  |  |  |             except OSError: | 
					
						
							|  |  |  |                 print('EX: _profile_edit unable to delete  blocking ' + | 
					
						
							|  |  |  |                       blocking_filename) | 
					
						
							|  |  |  |         if os.path.isfile(blocking_reasons_filename): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 os.remove(blocking_reasons_filename) | 
					
						
							|  |  |  |             except OSError: | 
					
						
							|  |  |  |                 print('EX: _profile_edit unable to delete blocking reasons' + | 
					
						
							|  |  |  |                       blocking_reasons_filename) | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         with open(blocking_filename, 'w+', encoding='utf-8') as fp_block: | 
					
						
							|  |  |  |             fp_block.write(blocking_file_text) | 
					
						
							|  |  |  |     except OSError: | 
					
						
							|  |  |  |         print('EX: Failed to write ' + blocking_filename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         with open(blocking_reasons_filename, 'w+', | 
					
						
							|  |  |  |                   encoding='utf-8') as fp_block: | 
					
						
							|  |  |  |             fp_block.write(blocking_reasons_file_text) | 
					
						
							|  |  |  |     except OSError: | 
					
						
							|  |  |  |         print('EX: Failed to write ' + blocking_reasons_filename) | 
					
						
							|  |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-23 13:57:38 +00:00
										 |  |  | def _add_global_block_reason(base_dir: str, | 
					
						
							|  |  |  |                              block_nickname: str, block_domain: str, | 
					
						
							|  |  |  |                              reason: str) -> bool: | 
					
						
							|  |  |  |     """Store a global block reason
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not reason: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     blocking_reasons_filename = \ | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |         data_dir(base_dir) + '/blocking_reasons.txt' | 
					
						
							| 
									
										
										
										
											2022-11-23 13:57:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not block_nickname.startswith('#'): | 
					
						
							|  |  |  |         # is the handle already blocked? | 
					
						
							|  |  |  |         block_id = block_nickname + '@' + block_domain | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         block_id = block_nickname | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reason = reason.replace('\n', '').strip() | 
					
						
							|  |  |  |     reason_line = block_id + ' ' + reason + '\n' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if os.path.isfile(blocking_reasons_filename): | 
					
						
							|  |  |  |         if not text_in_file(block_id, | 
					
						
							|  |  |  |                             blocking_reasons_filename): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 with open(blocking_reasons_filename, 'a+', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                           encoding='utf-8') as fp_reas: | 
					
						
							|  |  |  |                     fp_reas.write(reason_line) | 
					
						
							| 
									
										
										
										
											2022-11-23 13:57:38 +00:00
										 |  |  |             except OSError: | 
					
						
							|  |  |  |                 print('EX: unable to add blocking reason ' + | 
					
						
							|  |  |  |                       block_id) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             reasons_str = '' | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 with open(blocking_reasons_filename, 'r', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                           encoding='utf-8') as fp_reas: | 
					
						
							|  |  |  |                     reasons_str = fp_reas.read() | 
					
						
							| 
									
										
										
										
											2022-11-23 13:57:38 +00:00
										 |  |  |             except OSError: | 
					
						
							|  |  |  |                 print('EX: unable to read blocking reasons') | 
					
						
							|  |  |  |             reasons_lines = reasons_str.split('\n') | 
					
						
							|  |  |  |             new_reasons_str = '' | 
					
						
							|  |  |  |             for line in reasons_lines: | 
					
						
							|  |  |  |                 if not line.startswith(block_id + ' '): | 
					
						
							|  |  |  |                     new_reasons_str += line + '\n' | 
					
						
							|  |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2022-11-23 14:32:11 +00:00
										 |  |  |                 new_reasons_str += reason_line | 
					
						
							| 
									
										
										
										
											2022-11-23 13:57:38 +00:00
										 |  |  |             try: | 
					
						
							|  |  |  |                 with open(blocking_reasons_filename, 'w+', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                           encoding='utf-8') as fp_reas: | 
					
						
							|  |  |  |                     fp_reas.write(new_reasons_str) | 
					
						
							| 
									
										
										
										
											2022-11-23 13:57:38 +00:00
										 |  |  |             except OSError: | 
					
						
							|  |  |  |                 print('EX: unable to save blocking reasons' + | 
					
						
							|  |  |  |                       blocking_reasons_filename) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_reasons_filename, 'w+', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                       encoding='utf-8') as fp_reas: | 
					
						
							|  |  |  |                 fp_reas.write(reason_line) | 
					
						
							| 
									
										
										
										
											2022-11-23 13:57:38 +00:00
										 |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: unable to save blocking reason ' + | 
					
						
							|  |  |  |                   block_id + ' ' + blocking_reasons_filename) | 
					
						
							| 
									
										
										
										
											2024-05-18 18:38:41 +00:00
										 |  |  |     return True | 
					
						
							| 
									
										
										
										
											2022-11-23 13:57:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  | def add_global_block(base_dir: str, | 
					
						
							| 
									
										
										
										
											2022-11-23 13:57:38 +00:00
										 |  |  |                      block_nickname: str, block_domain: str, | 
					
						
							|  |  |  |                      reason: str) -> bool: | 
					
						
							| 
									
										
										
										
											2019-08-13 15:45:47 +00:00
										 |  |  |     """Global block which applies to all accounts
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-11-23 13:57:38 +00:00
										 |  |  |     _add_global_block_reason(base_dir, | 
					
						
							|  |  |  |                              block_nickname, block_domain, | 
					
						
							|  |  |  |                              reason) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     blocking_filename = data_dir(base_dir) + '/blocking.txt' | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if not block_nickname.startswith('#'): | 
					
						
							| 
									
										
										
										
											2020-09-05 09:41:09 +00:00
										 |  |  |         # is the handle already blocked? | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         block_handle = block_nickname + '@' + block_domain | 
					
						
							|  |  |  |         if os.path.isfile(blocking_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |             if text_in_file(block_handle, blocking_filename): | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2020-09-05 09:41:09 +00:00
										 |  |  |         # block an account handle or domain | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |             with open(blocking_filename, 'a+', encoding='utf-8') as fp_block: | 
					
						
							|  |  |  |                 fp_block.write(block_handle + '\n') | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             print('EX: unable to save blocked handle ' + block_handle) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         block_hashtag = block_nickname | 
					
						
							| 
									
										
										
										
											2020-09-05 09:41:09 +00:00
										 |  |  |         # is the hashtag already blocked? | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         if os.path.isfile(blocking_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 13:29:51 +00:00
										 |  |  |             if text_in_file(block_hashtag + '\n', blocking_filename): | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2020-09-05 09:41:09 +00:00
										 |  |  |         # block a hashtag | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |             with open(blocking_filename, 'a+', encoding='utf-8') as fp_block: | 
					
						
							|  |  |  |                 fp_block.write(block_hashtag + '\n') | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             print('EX: unable to save blocked hashtag ' + block_hashtag) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2019-08-13 15:45:47 +00:00
										 |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 20:06:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-08 10:44:54 +00:00
										 |  |  | def _add_block_reason(base_dir: str, | 
					
						
							|  |  |  |                       nickname: str, domain: str, | 
					
						
							|  |  |  |                       block_nickname: str, block_domain: str, | 
					
						
							|  |  |  |                       reason: str) -> bool: | 
					
						
							| 
									
										
										
										
											2023-09-03 19:18:03 +00:00
										 |  |  |     """Store an account level block reason
 | 
					
						
							| 
									
										
										
										
											2023-07-08 10:44:54 +00:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     if not reason: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     domain = remove_domain_port(domain) | 
					
						
							|  |  |  |     blocking_reasons_filename = \ | 
					
						
							| 
									
										
										
										
											2023-09-03 19:07:22 +00:00
										 |  |  |         acct_dir(base_dir, nickname, domain) + '/blocking_reasons.txt' | 
					
						
							| 
									
										
										
										
											2023-07-08 10:44:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not block_nickname.startswith('#'): | 
					
						
							|  |  |  |         # is the handle already blocked? | 
					
						
							|  |  |  |         block_id = block_nickname + '@' + block_domain | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         block_id = block_nickname | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reason = reason.replace('\n', '').strip() | 
					
						
							|  |  |  |     reason_line = block_id + ' ' + reason + '\n' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if os.path.isfile(blocking_reasons_filename): | 
					
						
							|  |  |  |         if not text_in_file(block_id, | 
					
						
							|  |  |  |                             blocking_reasons_filename): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 with open(blocking_reasons_filename, 'a+', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                           encoding='utf-8') as fp_reas: | 
					
						
							|  |  |  |                     fp_reas.write(reason_line) | 
					
						
							| 
									
										
										
										
											2023-07-08 10:44:54 +00:00
										 |  |  |             except OSError: | 
					
						
							|  |  |  |                 print('EX: unable to add blocking reason 2 ' + | 
					
						
							|  |  |  |                       block_id) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             reasons_str = '' | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 with open(blocking_reasons_filename, 'r', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                           encoding='utf-8') as fp_reas: | 
					
						
							|  |  |  |                     reasons_str = fp_reas.read() | 
					
						
							| 
									
										
										
										
											2023-07-08 10:44:54 +00:00
										 |  |  |             except OSError: | 
					
						
							|  |  |  |                 print('EX: unable to read blocking reasons 2') | 
					
						
							|  |  |  |             reasons_lines = reasons_str.split('\n') | 
					
						
							|  |  |  |             new_reasons_str = '' | 
					
						
							|  |  |  |             for line in reasons_lines: | 
					
						
							|  |  |  |                 if not line.startswith(block_id + ' '): | 
					
						
							|  |  |  |                     new_reasons_str += line + '\n' | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 new_reasons_str += reason_line | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 with open(blocking_reasons_filename, 'w+', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                           encoding='utf-8') as fp_reas: | 
					
						
							|  |  |  |                     fp_reas.write(new_reasons_str) | 
					
						
							| 
									
										
										
										
											2023-07-08 10:44:54 +00:00
										 |  |  |             except OSError: | 
					
						
							|  |  |  |                 print('EX: unable to save blocking reasons 2' + | 
					
						
							|  |  |  |                       blocking_reasons_filename) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_reasons_filename, 'w+', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                       encoding='utf-8') as fp_reas: | 
					
						
							|  |  |  |                 fp_reas.write(reason_line) | 
					
						
							| 
									
										
										
										
											2023-07-08 10:44:54 +00:00
										 |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: unable to save blocking reason 2 ' + | 
					
						
							|  |  |  |                   block_id + ' ' + blocking_reasons_filename) | 
					
						
							| 
									
										
										
										
											2024-05-18 18:39:17 +00:00
										 |  |  |     return True | 
					
						
							| 
									
										
										
										
											2023-07-08 10:44:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  | def add_block(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2023-07-08 10:44:54 +00:00
										 |  |  |               block_nickname: str, block_domain: str, | 
					
						
							|  |  |  |               reason: str) -> bool: | 
					
						
							| 
									
										
										
										
											2019-07-14 19:27:13 +00:00
										 |  |  |     """Block the given account
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if block_domain.startswith(domain) and nickname == block_nickname: | 
					
						
							| 
									
										
										
										
											2021-08-11 21:21:56 +00:00
										 |  |  |         # don't block self | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     blocking_filename = acct_dir(base_dir, nickname, domain) + '/blocking.txt' | 
					
						
							|  |  |  |     block_handle = block_nickname + '@' + block_domain | 
					
						
							|  |  |  |     if os.path.isfile(blocking_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |         if text_in_file(block_handle + '\n', blocking_filename): | 
					
						
							| 
									
										
										
										
											2019-07-14 19:57:05 +00:00
										 |  |  |             return False | 
					
						
							| 
									
										
										
										
											2021-08-11 21:00:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # if we are following then unfollow | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     following_filename = \ | 
					
						
							|  |  |  |         acct_dir(base_dir, nickname, domain) + '/following.txt' | 
					
						
							|  |  |  |     if os.path.isfile(following_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |         if text_in_file(block_handle + '\n', following_filename): | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             following_str = '' | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |                 with open(following_filename, 'r', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                           encoding='utf-8') as fp_foll: | 
					
						
							|  |  |  |                     following_str = fp_foll.read() | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 print('EX: Unable to read following ' + following_filename) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |                 return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             if following_str: | 
					
						
							|  |  |  |                 following_str = following_str.replace(block_handle + '\n', '') | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |                 with open(following_filename, 'w+', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                           encoding='utf-8') as fp_foll: | 
					
						
							|  |  |  |                     fp_foll.write(following_str) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 print('EX: Unable to write following ' + following_str) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2021-08-11 21:00:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # if they are a follower then remove them | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     followers_filename = \ | 
					
						
							|  |  |  |         acct_dir(base_dir, nickname, domain) + '/followers.txt' | 
					
						
							|  |  |  |     if os.path.isfile(followers_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |         if text_in_file(block_handle + '\n', followers_filename): | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             followers_str = '' | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |                 with open(followers_filename, 'r', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                           encoding='utf-8') as fp_foll: | 
					
						
							|  |  |  |                     followers_str = fp_foll.read() | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 print('EX: Unable to read followers ' + followers_filename) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |                 return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             if followers_str: | 
					
						
							|  |  |  |                 followers_str = followers_str.replace(block_handle + '\n', '') | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |                 with open(followers_filename, 'w+', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                           encoding='utf-8') as fp_foll: | 
					
						
							|  |  |  |                     fp_foll.write(followers_str) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 print('EX: Unable to write followers ' + followers_str) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |                 return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |         with open(blocking_filename, 'a+', encoding='utf-8') as fp_block: | 
					
						
							|  |  |  |             fp_block.write(block_handle + '\n') | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         print('EX: unable to append block handle ' + block_handle) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2023-07-08 10:44:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if reason: | 
					
						
							|  |  |  |         _add_block_reason(base_dir, nickname, domain, | 
					
						
							|  |  |  |                           block_nickname, block_domain, reason) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-14 19:57:05 +00:00
										 |  |  |     return True | 
					
						
							| 
									
										
										
										
											2019-07-14 19:27:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 20:06:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-23 14:32:11 +00:00
										 |  |  | def _remove_global_block_reason(base_dir: str, | 
					
						
							|  |  |  |                                 unblock_nickname: str, | 
					
						
							|  |  |  |                                 unblock_domain: str) -> bool: | 
					
						
							|  |  |  |     """Remove a globla block reason
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     unblocking_filename = data_dir(base_dir) + '/blocking_reasons.txt' | 
					
						
							| 
									
										
										
										
											2022-11-23 14:32:11 +00:00
										 |  |  |     if not os.path.isfile(unblocking_filename): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not unblock_nickname.startswith('#'): | 
					
						
							|  |  |  |         unblock_id = unblock_nickname + '@' + unblock_domain | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         unblock_id = unblock_nickname | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not text_in_file(unblock_id + ' ', unblocking_filename): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     reasons_str = '' | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         with open(unblocking_filename, 'r', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                   encoding='utf-8') as fp_reas: | 
					
						
							|  |  |  |             reasons_str = fp_reas.read() | 
					
						
							| 
									
										
										
										
											2022-11-23 14:32:11 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2024-07-13 12:02:54 +00:00
										 |  |  |         print('EX: unable to read blocking reasons 3') | 
					
						
							| 
									
										
										
										
											2022-11-23 14:32:11 +00:00
										 |  |  |     reasons_lines = reasons_str.split('\n') | 
					
						
							|  |  |  |     new_reasons_str = '' | 
					
						
							|  |  |  |     for line in reasons_lines: | 
					
						
							|  |  |  |         if line.startswith(unblock_id + ' '): | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         new_reasons_str += line + '\n' | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         with open(unblocking_filename, 'w+', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                   encoding='utf-8') as fp_reas: | 
					
						
							|  |  |  |             fp_reas.write(new_reasons_str) | 
					
						
							| 
									
										
										
										
											2022-11-23 14:32:11 +00:00
										 |  |  |     except OSError: | 
					
						
							|  |  |  |         print('EX: unable to save blocking reasons 2' + | 
					
						
							|  |  |  |               unblocking_filename) | 
					
						
							| 
									
										
										
										
											2024-05-18 18:39:52 +00:00
										 |  |  |     return True | 
					
						
							| 
									
										
										
										
											2022-11-23 14:32:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  | def remove_global_block(base_dir: str, | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                         unblock_nickname: str, | 
					
						
							|  |  |  |                         unblock_domain: str) -> bool: | 
					
						
							| 
									
										
										
										
											2019-08-13 15:45:47 +00:00
										 |  |  |     """Unblock the given global block
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-11-23 14:32:11 +00:00
										 |  |  |     _remove_global_block_reason(base_dir, | 
					
						
							|  |  |  |                                 unblock_nickname, | 
					
						
							|  |  |  |                                 unblock_domain) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     unblocking_filename = data_dir(base_dir) + '/blocking.txt' | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if not unblock_nickname.startswith('#'): | 
					
						
							|  |  |  |         unblock_handle = unblock_nickname + '@' + unblock_domain | 
					
						
							|  |  |  |         if os.path.isfile(unblocking_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |             if text_in_file(unblock_handle, unblocking_filename): | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |                     with open(unblocking_filename, 'r', | 
					
						
							|  |  |  |                               encoding='utf-8') as fp_unblock: | 
					
						
							|  |  |  |                         with open(unblocking_filename + '.new', 'w+', | 
					
						
							|  |  |  |                                   encoding='utf-8') as fpnew: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                             for line in fp_unblock: | 
					
						
							| 
									
										
										
										
											2022-06-21 11:58:50 +00:00
										 |  |  |                                 handle = remove_eol(line) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                                 if unblock_handle not in line: | 
					
						
							| 
									
										
										
										
											2021-11-25 18:42:38 +00:00
										 |  |  |                                     fpnew.write(handle + '\n') | 
					
						
							| 
									
										
										
										
											2021-12-25 15:28:52 +00:00
										 |  |  |                 except OSError as ex: | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                     print('EX: failed to remove global block ' + | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                           unblocking_filename + ' ' + str(ex)) | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                     return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 if os.path.isfile(unblocking_filename + '.new'): | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                     try: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                         os.rename(unblocking_filename + '.new', | 
					
						
							|  |  |  |                                   unblocking_filename) | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                     except OSError: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |                         print('EX: remove_global_block unable to rename ' + | 
					
						
							|  |  |  |                               unblocking_filename) | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                         return False | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  |                     return True | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         unblock_hashtag = unblock_nickname | 
					
						
							|  |  |  |         if os.path.isfile(unblocking_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |             if text_in_file(unblock_hashtag + '\n', unblocking_filename): | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |                     with open(unblocking_filename, 'r', | 
					
						
							|  |  |  |                               encoding='utf-8') as fp_unblock: | 
					
						
							|  |  |  |                         with open(unblocking_filename + '.new', 'w+', | 
					
						
							|  |  |  |                                   encoding='utf-8') as fpnew: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                             for line in fp_unblock: | 
					
						
							| 
									
										
										
										
											2022-06-21 11:58:50 +00:00
										 |  |  |                                 block_line = remove_eol(line) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                                 if unblock_hashtag not in line: | 
					
						
							|  |  |  |                                     fpnew.write(block_line + '\n') | 
					
						
							| 
									
										
										
										
											2021-12-25 15:28:52 +00:00
										 |  |  |                 except OSError as ex: | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                     print('EX: failed to remove global hashtag block ' + | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                           unblocking_filename + ' ' + str(ex)) | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                     return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 if os.path.isfile(unblocking_filename + '.new'): | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                     try: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                         os.rename(unblocking_filename + '.new', | 
					
						
							|  |  |  |                                   unblocking_filename) | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                     except OSError: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |                         print('EX: remove_global_block unable to rename 2 ' + | 
					
						
							|  |  |  |                               unblocking_filename) | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                         return False | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  |                     return True | 
					
						
							| 
									
										
										
										
											2019-08-13 15:45:47 +00:00
										 |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 20:06:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  | def remove_block(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                  unblock_nickname: str, unblock_domain: str) -> bool: | 
					
						
							| 
									
										
										
										
											2019-07-14 19:27:13 +00:00
										 |  |  |     """Unblock the given account
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     unblocking_filename = \ | 
					
						
							|  |  |  |         acct_dir(base_dir, nickname, domain) + '/blocking.txt' | 
					
						
							|  |  |  |     unblock_handle = unblock_nickname + '@' + unblock_domain | 
					
						
							|  |  |  |     if os.path.isfile(unblocking_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |         if text_in_file(unblock_handle, unblocking_filename): | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |                 with open(unblocking_filename, 'r', | 
					
						
							|  |  |  |                           encoding='utf-8') as fp_unblock: | 
					
						
							|  |  |  |                     with open(unblocking_filename + '.new', 'w+', | 
					
						
							|  |  |  |                               encoding='utf-8') as fpnew: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                         for line in fp_unblock: | 
					
						
							| 
									
										
										
										
											2022-06-21 11:58:50 +00:00
										 |  |  |                             handle = remove_eol(line) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                             if unblock_handle not in line: | 
					
						
							| 
									
										
										
										
											2021-11-25 18:42:38 +00:00
										 |  |  |                                 fpnew.write(handle + '\n') | 
					
						
							| 
									
										
										
										
											2021-12-25 15:28:52 +00:00
										 |  |  |             except OSError as ex: | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                 print('EX: failed to remove block ' + | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                       unblocking_filename + ' ' + str(ex)) | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                 return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             if os.path.isfile(unblocking_filename + '.new'): | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                     os.rename(unblocking_filename + '.new', | 
					
						
							|  |  |  |                               unblocking_filename) | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                 except OSError: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |                     print('EX: remove_block unable to rename 3 ' + | 
					
						
							|  |  |  |                           unblocking_filename) | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                     return False | 
					
						
							| 
									
										
										
										
											2019-07-14 19:57:05 +00:00
										 |  |  |                 return True | 
					
						
							|  |  |  |     return False | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 20:06:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  | def is_blocked_hashtag(base_dir: str, hashtag: str) -> bool: | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  |     """Is the given hashtag blocked?
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-08-07 20:40:53 +00:00
										 |  |  |     # avoid very long hashtags | 
					
						
							|  |  |  |     if len(hashtag) > 32: | 
					
						
							|  |  |  |         return True | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     global_blocking_filename = data_dir(base_dir) + '/blocking.txt' | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if os.path.isfile(global_blocking_filename): | 
					
						
							| 
									
										
										
										
											2020-05-22 11:32:38 +00:00
										 |  |  |         hashtag = hashtag.strip('\n').strip('\r') | 
					
						
							| 
									
										
										
										
											2020-12-03 19:51:47 +00:00
										 |  |  |         if not hashtag.startswith('#'): | 
					
						
							|  |  |  |             hashtag = '#' + hashtag | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |         if text_in_file(hashtag + '\n', global_blocking_filename): | 
					
						
							| 
									
										
										
										
											2019-08-14 10:32:15 +00:00
										 |  |  |             return True | 
					
						
							|  |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 20:06:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  | def get_domain_blocklist(base_dir: str) -> str: | 
					
						
							| 
									
										
										
										
											2020-03-28 10:33:04 +00:00
										 |  |  |     """Returns all globally blocked domains as a string
 | 
					
						
							|  |  |  |     This can be used for fast matching to mitigate flooding | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     blocked_str = '' | 
					
						
							| 
									
										
										
										
											2020-03-28 10:33:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     evil_domains = evil_incarnate() | 
					
						
							|  |  |  |     for evil in evil_domains: | 
					
						
							|  |  |  |         blocked_str += evil + '\n' | 
					
						
							| 
									
										
										
										
											2020-03-28 10:33:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     global_blocking_filename = data_dir(base_dir) + '/blocking.txt' | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if not os.path.isfile(global_blocking_filename): | 
					
						
							|  |  |  |         return blocked_str | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |         with open(global_blocking_filename, 'r', | 
					
						
							|  |  |  |                   encoding='utf-8') as fp_blocked: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             blocked_str += fp_blocked.read() | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |         print('EX: get_domain_blocklist unable to read ' + | 
					
						
							|  |  |  |               global_blocking_filename) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     return blocked_str | 
					
						
							| 
									
										
										
										
											2020-03-28 10:33:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 20:06:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  | def update_blocked_cache(base_dir: str, | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                          blocked_cache: [], | 
					
						
							|  |  |  |                          blocked_cache_last_updated: int, | 
					
						
							|  |  |  |                          blocked_cache_update_secs: int) -> int: | 
					
						
							| 
									
										
										
										
											2021-06-21 09:22:24 +00:00
										 |  |  |     """Updates the cache of globally blocked domains held in memory
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 13:17:46 +00:00
										 |  |  |     curr_time = int(time.time()) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if blocked_cache_last_updated > curr_time: | 
					
						
							| 
									
										
										
										
											2021-06-21 09:40:43 +00:00
										 |  |  |         print('WARN: Cache updated in the future') | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         blocked_cache_last_updated = 0 | 
					
						
							|  |  |  |     seconds_since_last_update = curr_time - blocked_cache_last_updated | 
					
						
							|  |  |  |     if seconds_since_last_update < blocked_cache_update_secs: | 
					
						
							|  |  |  |         return blocked_cache_last_updated | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     global_blocking_filename = data_dir(base_dir) + '/blocking.txt' | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if not os.path.isfile(global_blocking_filename): | 
					
						
							|  |  |  |         return blocked_cache_last_updated | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |         with open(global_blocking_filename, 'r', | 
					
						
							|  |  |  |                   encoding='utf-8') as fp_blocked: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             blocked_lines = fp_blocked.readlines() | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |             # remove newlines | 
					
						
							| 
									
										
										
										
											2022-01-08 10:58:54 +00:00
										 |  |  |             for index, _ in enumerate(blocked_lines): | 
					
						
							| 
									
										
										
										
											2022-06-21 11:58:50 +00:00
										 |  |  |                 blocked_lines[index] = remove_eol(blocked_lines[index]) | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |             # update the cache | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             blocked_cache.clear() | 
					
						
							|  |  |  |             blocked_cache += blocked_lines | 
					
						
							| 
									
										
										
										
											2021-12-25 15:28:52 +00:00
										 |  |  |     except OSError as ex: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |         print('EX: update_blocked_cache unable to read ' + | 
					
						
							|  |  |  |               global_blocking_filename + ' ' + str(ex)) | 
					
						
							| 
									
										
										
										
											2021-12-26 13:17:46 +00:00
										 |  |  |     return curr_time | 
					
						
							| 
									
										
										
										
											2021-06-21 09:22:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def _get_short_domain(domain: str) -> str: | 
					
						
							| 
									
										
										
										
											2021-06-21 15:56:55 +00:00
										 |  |  |     """ by checking a shorter version we can thwart adversaries
 | 
					
						
							|  |  |  |     who constantly change their subdomain | 
					
						
							|  |  |  |     e.g. subdomain123.mydomain.com becomes mydomain.com | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     sections = domain.split('.') | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     no_of_sections = len(sections) | 
					
						
							|  |  |  |     if no_of_sections > 2: | 
					
						
							|  |  |  |         return sections[no_of_sections-2] + '.' + sections[-1] | 
					
						
							| 
									
										
										
										
											2021-06-21 15:56:55 +00:00
										 |  |  |     return None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  | def is_blocked_domain(base_dir: str, domain: str, | 
					
						
							| 
									
										
										
										
											2024-02-11 13:42:15 +00:00
										 |  |  |                       blocked_cache: [], | 
					
						
							|  |  |  |                       block_federated: []) -> bool: | 
					
						
							| 
									
										
										
										
											2019-09-09 16:02:14 +00:00
										 |  |  |     """Is the given domain blocked?
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-10-29 10:36:38 +00:00
										 |  |  |     if '.' not in domain: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-27 17:49:35 +00:00
										 |  |  |     if is_evil(domain): | 
					
						
							| 
									
										
										
										
											2019-09-09 16:02:14 +00:00
										 |  |  |         return True | 
					
						
							| 
									
										
										
										
											2020-10-29 10:36:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     short_domain = _get_short_domain(domain) | 
					
						
							| 
									
										
										
										
											2020-10-29 10:36:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 09:54:29 +00:00
										 |  |  |     search_str = '*@' + domain | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |     if not broch_mode_is_active(base_dir): | 
					
						
							| 
									
										
										
										
											2024-02-09 21:25:40 +00:00
										 |  |  |         if block_federated: | 
					
						
							|  |  |  |             if domain in block_federated: | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         if blocked_cache: | 
					
						
							|  |  |  |             for blocked_str in blocked_cache: | 
					
						
							| 
									
										
										
										
											2023-04-29 09:54:29 +00:00
										 |  |  |                 if blocked_str == search_str: | 
					
						
							| 
									
										
										
										
											2020-10-29 10:36:38 +00:00
										 |  |  |                     return True | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 if short_domain: | 
					
						
							| 
									
										
										
										
											2022-03-31 16:14:19 +00:00
										 |  |  |                     if blocked_str == '*@' + short_domain: | 
					
						
							| 
									
										
										
										
											2021-02-15 21:14:05 +00:00
										 |  |  |                         return True | 
					
						
							| 
									
										
										
										
											2021-06-21 09:22:24 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             # instance block list | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |             global_blocking_filename = data_dir(base_dir) + '/blocking.txt' | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             if os.path.isfile(global_blocking_filename): | 
					
						
							| 
									
										
										
										
											2023-04-29 09:54:29 +00:00
										 |  |  |                 search_str += '\n' | 
					
						
							|  |  |  |                 search_str_short = None | 
					
						
							|  |  |  |                 if short_domain: | 
					
						
							|  |  |  |                     search_str_short = '*@' + short_domain + '\n' | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2022-06-09 16:05:42 +00:00
										 |  |  |                     with open(global_blocking_filename, 'r', | 
					
						
							|  |  |  |                               encoding='utf-8') as fp_blocked: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                         blocked_str = fp_blocked.read() | 
					
						
							| 
									
										
										
										
											2023-04-29 09:54:29 +00:00
										 |  |  |                         if search_str in blocked_str: | 
					
						
							| 
									
										
										
										
											2021-06-21 09:22:24 +00:00
										 |  |  |                             return True | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                         if short_domain: | 
					
						
							| 
									
										
										
										
											2023-04-29 09:54:29 +00:00
										 |  |  |                             if search_str_short in blocked_str: | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                                 return True | 
					
						
							| 
									
										
										
										
											2021-12-25 15:28:52 +00:00
										 |  |  |                 except OSError as ex: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |                     print('EX: is_blocked_domain unable to read ' + | 
					
						
							|  |  |  |                           global_blocking_filename + ' ' + str(ex)) | 
					
						
							| 
									
										
										
										
											2021-02-15 21:14:05 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |         allow_filename = data_dir(base_dir) + '/allowedinstances.txt' | 
					
						
							| 
									
										
										
										
											2021-02-15 21:14:05 +00:00
										 |  |  |         # instance allow list | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         if not short_domain: | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |             if not text_in_file(domain, allow_filename): | 
					
						
							| 
									
										
										
										
											2021-02-15 21:14:05 +00:00
										 |  |  |                 return True | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |             if not text_in_file(short_domain, allow_filename): | 
					
						
							| 
									
										
										
										
											2021-02-15 21:14:05 +00:00
										 |  |  |                 return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-09 16:02:14 +00:00
										 |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 20:06:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 09:54:29 +00:00
										 |  |  | def is_blocked_nickname(base_dir: str, nickname: str, | 
					
						
							|  |  |  |                         blocked_cache: [] = None) -> bool: | 
					
						
							|  |  |  |     """Is the given nickname blocked?
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     search_str = nickname + '@*' | 
					
						
							|  |  |  |     if blocked_cache: | 
					
						
							|  |  |  |         for blocked_str in blocked_cache: | 
					
						
							|  |  |  |             if blocked_str == search_str: | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         # instance-wide block list | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |         global_blocking_filename = data_dir(base_dir) + '/blocking.txt' | 
					
						
							| 
									
										
										
										
											2023-04-29 09:54:29 +00:00
										 |  |  |         if os.path.isfile(global_blocking_filename): | 
					
						
							|  |  |  |             search_str += '\n' | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 with open(global_blocking_filename, 'r', | 
					
						
							|  |  |  |                           encoding='utf-8') as fp_blocked: | 
					
						
							|  |  |  |                     blocked_str = fp_blocked.read() | 
					
						
							|  |  |  |                     if search_str in blocked_str: | 
					
						
							|  |  |  |                         return True | 
					
						
							|  |  |  |             except OSError as ex: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |                 print('EX: is_blocked_nickname unable to read ' + | 
					
						
							|  |  |  |                       global_blocking_filename + ' ' + str(ex)) | 
					
						
							| 
									
										
										
										
											2023-04-29 09:54:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def is_blocked(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                block_nickname: str, block_domain: str, | 
					
						
							| 
									
										
										
										
											2024-02-11 13:27:52 +00:00
										 |  |  |                blocked_cache: [], | 
					
						
							|  |  |  |                block_federated: []) -> bool: | 
					
						
							| 
									
										
										
										
											2023-04-29 11:15:07 +00:00
										 |  |  |     """Is the given account blocked?
 | 
					
						
							| 
									
										
										
										
											2019-07-14 19:27:13 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if is_evil(block_domain): | 
					
						
							| 
									
										
										
										
											2019-09-09 15:53:23 +00:00
										 |  |  |         return True | 
					
						
							| 
									
										
										
										
											2021-06-21 14:32:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     block_handle = None | 
					
						
							|  |  |  |     if block_nickname and block_domain: | 
					
						
							|  |  |  |         block_handle = block_nickname + '@' + block_domain | 
					
						
							| 
									
										
										
										
											2021-06-21 14:32:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |     if not broch_mode_is_active(base_dir): | 
					
						
							| 
									
										
										
										
											2021-06-21 15:56:55 +00:00
										 |  |  |         # instance level block list | 
					
						
							| 
									
										
										
										
											2024-02-09 21:25:40 +00:00
										 |  |  |         if block_federated: | 
					
						
							|  |  |  |             for blocked_str in block_federated: | 
					
						
							| 
									
										
										
										
											2024-02-11 17:50:27 +00:00
										 |  |  |                 if '@' in blocked_str or '://' in blocked_str: | 
					
						
							| 
									
										
										
										
											2024-02-09 21:25:40 +00:00
										 |  |  |                     if block_handle: | 
					
						
							|  |  |  |                         if blocked_str == block_handle: | 
					
						
							|  |  |  |                             return True | 
					
						
							|  |  |  |                 elif blocked_str == block_domain: | 
					
						
							|  |  |  |                     return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         if blocked_cache: | 
					
						
							|  |  |  |             for blocked_str in blocked_cache: | 
					
						
							| 
									
										
										
										
											2023-04-30 09:38:20 +00:00
										 |  |  |                 if block_nickname: | 
					
						
							|  |  |  |                     if block_nickname + '@*' in blocked_str: | 
					
						
							|  |  |  |                         return True | 
					
						
							| 
									
										
										
										
											2023-04-30 09:46:57 +00:00
										 |  |  |                 if block_domain: | 
					
						
							|  |  |  |                     if '*@' + block_domain in blocked_str: | 
					
						
							|  |  |  |                         return True | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 if block_handle: | 
					
						
							| 
									
										
										
										
											2022-03-31 16:33:21 +00:00
										 |  |  |                     if blocked_str == block_handle: | 
					
						
							| 
									
										
										
										
											2021-06-21 15:56:55 +00:00
										 |  |  |                         return True | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |             global_blocks_filename = data_dir(base_dir) + '/blocking.txt' | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             if os.path.isfile(global_blocks_filename): | 
					
						
							| 
									
										
										
										
											2023-04-30 09:38:20 +00:00
										 |  |  |                 if block_nickname: | 
					
						
							|  |  |  |                     if text_in_file(block_nickname + '@*\n', | 
					
						
							|  |  |  |                                     global_blocks_filename): | 
					
						
							|  |  |  |                         return True | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |                 if text_in_file('*@' + block_domain, global_blocks_filename): | 
					
						
							| 
									
										
										
										
											2021-06-21 14:32:17 +00:00
										 |  |  |                     return True | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 if block_handle: | 
					
						
							| 
									
										
										
										
											2022-03-31 16:33:21 +00:00
										 |  |  |                     block_str = block_handle + '\n' | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |                     if text_in_file(block_str, global_blocks_filename): | 
					
						
							| 
									
										
										
										
											2021-06-21 15:56:55 +00:00
										 |  |  |                         return True | 
					
						
							| 
									
										
										
										
											2024-02-09 22:23:17 +00:00
										 |  |  |             if not block_federated: | 
					
						
							|  |  |  |                 federated_blocks_filename = \ | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |                     data_dir(base_dir) + '/block_api.txt' | 
					
						
							| 
									
										
										
										
											2024-02-09 22:23:17 +00:00
										 |  |  |                 if os.path.isfile(federated_blocks_filename): | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |                     block_federated: list[str] = [] | 
					
						
							| 
									
										
										
										
											2024-02-09 22:23:17 +00:00
										 |  |  |                     try: | 
					
						
							|  |  |  |                         with open(federated_blocks_filename, 'r', | 
					
						
							|  |  |  |                                   encoding='utf-8') as fp_fed: | 
					
						
							|  |  |  |                             block_federated = fp_fed.read().split('\n') | 
					
						
							|  |  |  |                     except OSError: | 
					
						
							|  |  |  |                         print('EX: is_blocked unable to load ' + | 
					
						
							|  |  |  |                               federated_blocks_filename) | 
					
						
							|  |  |  |                     if block_domain in block_federated: | 
					
						
							|  |  |  |                         return True | 
					
						
							|  |  |  |                     if block_handle: | 
					
						
							|  |  |  |                         if block_handle in block_federated: | 
					
						
							|  |  |  |                             return True | 
					
						
							| 
									
										
										
										
											2021-06-21 14:32:17 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2021-06-21 15:56:55 +00:00
										 |  |  |         # instance allow list | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |         allow_filename = data_dir(base_dir) + '/allowedinstances.txt' | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         short_domain = _get_short_domain(block_domain) | 
					
						
							| 
									
										
										
										
											2023-04-30 09:46:57 +00:00
										 |  |  |         if not short_domain and block_domain: | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |             if not text_in_file(block_domain + '\n', allow_filename): | 
					
						
							| 
									
										
										
										
											2021-06-21 15:56:55 +00:00
										 |  |  |                 return True | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |             if not text_in_file(short_domain + '\n', allow_filename): | 
					
						
							| 
									
										
										
										
											2021-06-21 14:32:17 +00:00
										 |  |  |                 return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-21 15:56:55 +00:00
										 |  |  |     # account level allow list | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     account_dir = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     allow_filename = account_dir + '/allowedinstances.txt' | 
					
						
							| 
									
										
										
										
											2023-04-30 09:46:57 +00:00
										 |  |  |     if block_domain and os.path.isfile(allow_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |         if not text_in_file(block_domain + '\n', allow_filename): | 
					
						
							| 
									
										
										
										
											2019-08-02 12:11:32 +00:00
										 |  |  |             return True | 
					
						
							| 
									
										
										
										
											2021-06-21 15:56:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # account level block list | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     blocking_filename = account_dir + '/blocking.txt' | 
					
						
							|  |  |  |     if os.path.isfile(blocking_filename): | 
					
						
							| 
									
										
										
										
											2023-04-29 20:39:32 +00:00
										 |  |  |         if block_nickname: | 
					
						
							|  |  |  |             if text_in_file(block_nickname + '@*\n', blocking_filename): | 
					
						
							|  |  |  |                 return True | 
					
						
							| 
									
										
										
										
											2023-04-30 09:46:57 +00:00
										 |  |  |         if block_domain: | 
					
						
							|  |  |  |             if text_in_file('*@' + block_domain + '\n', blocking_filename): | 
					
						
							|  |  |  |                 return True | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         if block_handle: | 
					
						
							| 
									
										
										
										
											2022-06-10 09:24:11 +00:00
										 |  |  |             if text_in_file(block_handle + '\n', blocking_filename): | 
					
						
							| 
									
										
										
										
											2020-02-05 17:39:41 +00:00
										 |  |  |                 return True | 
					
						
							| 
									
										
										
										
											2019-07-14 19:27:13 +00:00
										 |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-01 20:06:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-08 14:16:19 +00:00
										 |  |  | def allowed_announce(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |                      block_nickname: str, block_domain: str, | 
					
						
							|  |  |  |                      announce_blocked_cache: [] = None) -> bool: | 
					
						
							|  |  |  |     """Is the given nickname allowed to send announces?
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     block_handle = None | 
					
						
							|  |  |  |     if block_nickname and block_domain: | 
					
						
							|  |  |  |         block_handle = block_nickname + '@' + block_domain | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # cached announce blocks | 
					
						
							|  |  |  |     if announce_blocked_cache: | 
					
						
							|  |  |  |         for blocked_str in announce_blocked_cache: | 
					
						
							| 
									
										
										
										
											2023-04-30 09:52:29 +00:00
										 |  |  |             if block_nickname: | 
					
						
							|  |  |  |                 if block_nickname + '@*' in blocked_str: | 
					
						
							|  |  |  |                     return False | 
					
						
							|  |  |  |             if block_domain: | 
					
						
							|  |  |  |                 if '*@' + block_domain in blocked_str: | 
					
						
							|  |  |  |                     return False | 
					
						
							| 
									
										
										
										
											2022-11-08 14:16:19 +00:00
										 |  |  |             if block_handle: | 
					
						
							|  |  |  |                 if blocked_str == block_handle: | 
					
						
							|  |  |  |                     return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # non-cached instance level announce blocks | 
					
						
							|  |  |  |     global_announce_blocks_filename = \ | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |         data_dir(base_dir) + '/noannounce.txt' | 
					
						
							| 
									
										
										
										
											2022-11-08 14:16:19 +00:00
										 |  |  |     if os.path.isfile(global_announce_blocks_filename): | 
					
						
							| 
									
										
										
										
											2023-04-30 09:52:29 +00:00
										 |  |  |         if block_nickname: | 
					
						
							|  |  |  |             if text_in_file(block_nickname + '@*', | 
					
						
							|  |  |  |                             global_announce_blocks_filename, False): | 
					
						
							|  |  |  |                 return False | 
					
						
							|  |  |  |         if block_domain: | 
					
						
							|  |  |  |             if text_in_file('*@' + block_domain, | 
					
						
							|  |  |  |                             global_announce_blocks_filename, False): | 
					
						
							|  |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2022-11-08 14:16:19 +00:00
										 |  |  |         if block_handle: | 
					
						
							|  |  |  |             block_str = block_handle + '\n' | 
					
						
							|  |  |  |             if text_in_file(block_str, | 
					
						
							| 
									
										
										
										
											2022-12-30 21:07:19 +00:00
										 |  |  |                             global_announce_blocks_filename, False): | 
					
						
							| 
									
										
										
										
											2022-11-08 14:16:19 +00:00
										 |  |  |                 return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # non-cached account level announce blocks | 
					
						
							|  |  |  |     account_dir = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     blocking_filename = account_dir + '/noannounce.txt' | 
					
						
							|  |  |  |     if os.path.isfile(blocking_filename): | 
					
						
							| 
									
										
										
										
											2023-04-30 09:52:29 +00:00
										 |  |  |         if block_nickname: | 
					
						
							|  |  |  |             if text_in_file(block_nickname + '@*\n', | 
					
						
							|  |  |  |                             blocking_filename, False): | 
					
						
							|  |  |  |                 return False | 
					
						
							|  |  |  |         if block_domain: | 
					
						
							|  |  |  |             if text_in_file('*@' + block_domain + '\n', | 
					
						
							|  |  |  |                             blocking_filename, False): | 
					
						
							|  |  |  |                 return False | 
					
						
							| 
									
										
										
										
											2022-11-08 14:16:19 +00:00
										 |  |  |         if block_handle: | 
					
						
							| 
									
										
										
										
											2022-12-30 21:07:19 +00:00
										 |  |  |             if text_in_file(block_handle + '\n', blocking_filename, False): | 
					
						
							| 
									
										
										
										
											2022-11-08 14:16:19 +00:00
										 |  |  |                 return False | 
					
						
							|  |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-08 15:43:26 +00:00
										 |  |  | def allowed_announce_add(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |                          following_nickname: str, | 
					
						
							|  |  |  |                          following_domain: str) -> None: | 
					
						
							|  |  |  |     """Allow announces for a handle
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     account_dir = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     blocking_filename = account_dir + '/noannounce.txt' | 
					
						
							| 
									
										
										
										
											2023-03-17 10:18:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # if the noannounce.txt file doesn't yet exist | 
					
						
							|  |  |  |     if not os.path.isfile(blocking_filename): | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-08 15:43:26 +00:00
										 |  |  |     handle = following_nickname + '@' + following_domain | 
					
						
							| 
									
										
										
										
											2022-12-30 21:07:19 +00:00
										 |  |  |     if text_in_file(handle + '\n', blocking_filename, False): | 
					
						
							| 
									
										
										
										
											2022-11-08 15:43:26 +00:00
										 |  |  |         file_text = '' | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_filename, 'r', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_noannounce: | 
					
						
							|  |  |  |                 file_text = fp_noannounce.read() | 
					
						
							|  |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2024-04-20 13:27:06 +00:00
										 |  |  |             print('EX: unable to read noannounce add: ' + | 
					
						
							| 
									
										
										
										
											2022-11-08 15:43:26 +00:00
										 |  |  |                   blocking_filename + ' ' + handle) | 
					
						
							| 
									
										
										
										
											2022-12-30 21:33:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         new_file_text = '' | 
					
						
							|  |  |  |         file_text_list = file_text.split('\n') | 
					
						
							|  |  |  |         handle_lower = handle.lower() | 
					
						
							|  |  |  |         for allowed in file_text_list: | 
					
						
							|  |  |  |             if allowed.lower() != handle_lower: | 
					
						
							|  |  |  |                 new_file_text += allowed + '\n' | 
					
						
							|  |  |  |         file_text = new_file_text | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-08 15:43:26 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_filename, 'w+', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_noannounce: | 
					
						
							|  |  |  |                 fp_noannounce.write(file_text) | 
					
						
							|  |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2024-04-20 13:27:06 +00:00
										 |  |  |             print('EX: unable to write noannounce add: ' + | 
					
						
							| 
									
										
										
										
											2022-11-08 15:43:26 +00:00
										 |  |  |                   blocking_filename + ' ' + handle) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def allowed_announce_remove(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |                             following_nickname: str, | 
					
						
							|  |  |  |                             following_domain: str) -> None: | 
					
						
							|  |  |  |     """Don't allow announces from a handle
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     account_dir = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     blocking_filename = account_dir + '/noannounce.txt' | 
					
						
							|  |  |  |     handle = following_nickname + '@' + following_domain | 
					
						
							| 
									
										
										
										
											2023-03-17 10:18:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # if the noannounce.txt file doesn't yet exist | 
					
						
							|  |  |  |     if not os.path.isfile(blocking_filename): | 
					
						
							|  |  |  |         file_text = handle + '\n' | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_filename, 'w+', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_noannounce: | 
					
						
							|  |  |  |                 fp_noannounce.write(file_text) | 
					
						
							|  |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2024-04-20 13:27:06 +00:00
										 |  |  |             print('EX: unable to write initial noannounce remove: ' + | 
					
						
							| 
									
										
										
										
											2023-03-17 10:18:17 +00:00
										 |  |  |                   blocking_filename + ' ' + handle) | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-08 15:43:26 +00:00
										 |  |  |     file_text = '' | 
					
						
							| 
									
										
										
										
											2022-12-30 21:07:19 +00:00
										 |  |  |     if not text_in_file(handle + '\n', blocking_filename, False): | 
					
						
							| 
									
										
										
										
											2022-11-08 15:43:26 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_filename, 'r', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_noannounce: | 
					
						
							|  |  |  |                 file_text = fp_noannounce.read() | 
					
						
							|  |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2024-04-20 13:27:06 +00:00
										 |  |  |             print('EX: unable to read noannounce remove: ' + | 
					
						
							| 
									
										
										
										
											2022-11-08 15:43:26 +00:00
										 |  |  |                   blocking_filename + ' ' + handle) | 
					
						
							|  |  |  |         file_text += handle + '\n' | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_filename, 'w+', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_noannounce: | 
					
						
							|  |  |  |                 fp_noannounce.write(file_text) | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: unable to write noannounce: ' + | 
					
						
							|  |  |  |                   blocking_filename + ' ' + handle) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-20 13:27:06 +00:00
										 |  |  | def blocked_quote_toots_add(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |                             following_nickname: str, | 
					
						
							|  |  |  |                             following_domain: str) -> None: | 
					
						
							|  |  |  |     """Block quote toots for a handle
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     account_dir = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     blocking_filename = account_dir + '/quotesblocked.txt' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # if the quotesblocked.txt file doesn't yet exist | 
					
						
							|  |  |  |     if os.path.isfile(blocking_filename): | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     handle = following_nickname + '@' + following_domain | 
					
						
							|  |  |  |     if not text_in_file(handle + '\n', blocking_filename, False): | 
					
						
							|  |  |  |         file_text = '' | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_filename, 'r', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_quotes: | 
					
						
							|  |  |  |                 file_text = fp_quotes.read() | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: unable to read quotesblocked add: ' + | 
					
						
							|  |  |  |                   blocking_filename + ' ' + handle) | 
					
						
							|  |  |  |         file_text += handle + '\n' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_filename, 'w+', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_quotes: | 
					
						
							|  |  |  |                 fp_quotes.write(file_text) | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: unable to write quotesblocked add: ' + | 
					
						
							|  |  |  |                   blocking_filename + ' ' + handle) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def blocked_quote_toots_remove(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |                                following_nickname: str, | 
					
						
							|  |  |  |                                following_domain: str) -> None: | 
					
						
							|  |  |  |     """allow quote toots from a handle
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     account_dir = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     blocking_filename = account_dir + '/quotesblocked.txt' | 
					
						
							|  |  |  |     handle = following_nickname + '@' + following_domain | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # if the quotesblocked.txt file doesn't yet exist | 
					
						
							|  |  |  |     if not os.path.isfile(blocking_filename): | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     file_text = '' | 
					
						
							|  |  |  |     if text_in_file(handle + '\n', blocking_filename, False): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_filename, 'r', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_quotes: | 
					
						
							|  |  |  |                 file_text = fp_quotes.read() | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: unable to read quotesblocked remove: ' + | 
					
						
							|  |  |  |                   blocking_filename + ' ' + handle) | 
					
						
							|  |  |  |         file_text = file_text.replace(handle + '\n', '') | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_filename, 'w+', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_quotes: | 
					
						
							|  |  |  |                 fp_quotes.write(file_text) | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: unable to write quotesblocked remove: ' + | 
					
						
							|  |  |  |                   blocking_filename + ' ' + handle) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-09 16:13:16 +00:00
										 |  |  | def outbox_block(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                  message_json: {}, debug: bool) -> bool: | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |     """ When a block request is received by the outbox from c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json.get('type'): | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: block - no type') | 
					
						
							| 
									
										
										
										
											2021-08-11 21:10:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['type'] == 'Block': | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: not a block') | 
					
						
							| 
									
										
										
										
											2021-08-11 21:10:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-26 17:12:07 +00:00
										 |  |  |     if not has_object_string(message_json, debug): | 
					
						
							| 
									
										
										
										
											2021-08-11 21:10:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s block request arrived in outbox') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     message_id = remove_id_ending(message_json['object']) | 
					
						
							|  |  |  |     if '/statuses/' not in message_id: | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s block object is not a status') | 
					
						
							| 
									
										
										
										
											2021-08-11 21:10:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if not has_users_path(message_id): | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s block object has no nickname') | 
					
						
							| 
									
										
										
										
											2021-08-11 21:10:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     post_filename = locate_post(base_dir, nickname, domain, message_id) | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     if not post_filename: | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s block post not found in inbox or outbox') | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             print(message_id) | 
					
						
							| 
									
										
										
										
											2021-08-11 21:10:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     nickname_blocked = get_nickname_from_actor(message_json['object']) | 
					
						
							|  |  |  |     if not nickname_blocked: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |         print('WARN: outbox_block unable to find nickname in ' + | 
					
						
							|  |  |  |               message_json['object']) | 
					
						
							| 
									
										
										
										
											2021-08-11 21:10:26 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     domain_blocked, port_blocked = \ | 
					
						
							|  |  |  |         get_domain_from_actor(message_json['object']) | 
					
						
							| 
									
										
										
										
											2023-01-15 14:33:18 +00:00
										 |  |  |     if not domain_blocked: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |         print('WARN: outbox_block unable to find domain in ' + | 
					
						
							|  |  |  |               message_json['object']) | 
					
						
							| 
									
										
										
										
											2023-01-15 14:33:18 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     domain_blocked_full = get_full_domain(domain_blocked, port_blocked) | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |     add_block(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2023-07-08 10:44:54 +00:00
										 |  |  |               nickname_blocked, domain_blocked_full, '') | 
					
						
							| 
									
										
										
										
											2020-03-22 20:59:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         print('DEBUG: post blocked via c2s - ' + post_filename) | 
					
						
							| 
									
										
										
										
											2021-08-11 21:10:26 +00:00
										 |  |  |     return True | 
					
						
							| 
									
										
										
										
											2020-04-01 20:06:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-01 14:26:50 +00:00
										 |  |  | def outbox_undo_block(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                       message_json: {}, debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |     """ When an undo block request is received by the outbox from c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json.get('type'): | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: undo block - no type') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['type'] == 'Undo': | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: not an undo block') | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-09 15:11:22 +00:00
										 |  |  |     if not has_object_string_type(message_json, debug): | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['object']['type'] == 'Block': | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: not an undo block') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 15:54:46 +00:00
										 |  |  |     if not has_object_string_object(message_json, debug): | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         return | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s undo block request arrived in outbox') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     message_id = remove_id_ending(message_json['object']['object']) | 
					
						
							|  |  |  |     if '/statuses/' not in message_id: | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s undo block object is not a status') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if not has_users_path(message_id): | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s undo block object has no nickname') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     post_filename = locate_post(base_dir, nickname, domain, message_id) | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     if not post_filename: | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s undo block post not found in inbox or outbox') | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             print(message_id) | 
					
						
							| 
									
										
										
										
											2019-09-02 09:43:43 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     nickname_blocked = \ | 
					
						
							|  |  |  |         get_nickname_from_actor(message_json['object']['object']) | 
					
						
							|  |  |  |     if not nickname_blocked: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |         print('WARN: outbox_undo_block unable to find nickname in ' + | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |               message_json['object']['object']) | 
					
						
							| 
									
										
										
										
											2019-09-02 09:43:43 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     domain_object = message_json['object']['object'] | 
					
						
							|  |  |  |     domain_blocked, port_blocked = get_domain_from_actor(domain_object) | 
					
						
							| 
									
										
										
										
											2023-01-15 14:33:18 +00:00
										 |  |  |     if not domain_blocked: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |         print('WARN: outbox_undo_block unable to find domain in ' + | 
					
						
							| 
									
										
										
										
											2023-01-15 14:33:18 +00:00
										 |  |  |               message_json['object']['object']) | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     domain_blocked_full = get_full_domain(domain_blocked, port_blocked) | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |     remove_block(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                  nickname_blocked, domain_blocked_full) | 
					
						
							| 
									
										
										
										
											2019-07-17 21:40:56 +00:00
										 |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         print('DEBUG: post undo blocked via c2s - ' + post_filename) | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  | def mute_post(base_dir: str, nickname: str, domain: str, port: int, | 
					
						
							|  |  |  |               http_prefix: str, post_id: str, recent_posts_cache: {}, | 
					
						
							|  |  |  |               debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |     """ Mutes the given post
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |     print('mute_post: post_id ' + post_id) | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     post_filename = locate_post(base_dir, nickname, domain, post_id) | 
					
						
							|  |  |  |     if not post_filename: | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |         print('mute_post: file not found ' + post_id) | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     post_json_object = load_json(post_filename) | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not post_json_object: | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |         print('mute_post: object not loaded ' + post_id) | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |     print('mute_post: ' + str(post_json_object)) | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     post_json_obj = post_json_object | 
					
						
							|  |  |  |     also_update_post_id = None | 
					
						
							| 
									
										
										
										
											2021-12-26 10:57:03 +00:00
										 |  |  |     if has_object_dict(post_json_object): | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         post_json_obj = post_json_object['object'] | 
					
						
							| 
									
										
										
										
											2021-09-28 15:15:13 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2021-12-26 17:12:07 +00:00
										 |  |  |         if has_object_string(post_json_object, debug): | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             also_update_post_id = remove_id_ending(post_json_object['object']) | 
					
						
							| 
									
										
										
										
											2025-02-23 14:52:50 +00:00
										 |  |  |         elif is_quote_toot(post_json_object, ''): | 
					
						
							|  |  |  |             also_update_post_id = get_quote_toot_url(post_json_object) | 
					
						
							|  |  |  |             also_update_post_id = remove_id_ending(also_update_post_id) | 
					
						
							| 
									
										
										
										
											2021-09-28 15:15:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |     domain_full = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  |     actor = local_actor_url(http_prefix, nickname, domain_full) | 
					
						
							| 
									
										
										
										
											2021-08-12 10:22:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-06 09:41:21 +00:00
										 |  |  |     # Due to lack of AP specification maintenance, a conversation can also be | 
					
						
							|  |  |  |     # referred to as a thread or (confusingly) "context" | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if post_json_obj.get('conversation'): | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         mute_conversation(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                           post_json_obj['conversation']) | 
					
						
							| 
									
										
										
										
											2023-01-09 11:38:05 +00:00
										 |  |  |     elif post_json_obj.get('context'): | 
					
						
							|  |  |  |         mute_conversation(base_dir, nickname, domain, | 
					
						
							|  |  |  |                           post_json_obj['context']) | 
					
						
							| 
									
										
										
										
											2024-10-06 16:22:13 +00:00
										 |  |  |     elif post_json_obj.get('thread'): | 
					
						
							|  |  |  |         mute_conversation(base_dir, nickname, domain, | 
					
						
							|  |  |  |                           post_json_obj['thread']) | 
					
						
							| 
									
										
										
										
											2021-08-12 10:22:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-28 11:20:14 +00:00
										 |  |  |     # does this post have ignores on it from differenent actors? | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if not post_json_obj.get('ignores'): | 
					
						
							| 
									
										
										
										
											2021-09-28 11:20:14 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |             print('DEBUG: Adding initial mute to ' + post_id) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         ignores_json = { | 
					
						
							| 
									
										
										
										
											2024-09-14 16:40:11 +00:00
										 |  |  |             "@context": [ | 
					
						
							|  |  |  |                 'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |                 'https://w3id.org/security/v1' | 
					
						
							|  |  |  |             ], | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |             'id': post_id, | 
					
						
							| 
									
										
										
										
											2021-09-28 11:20:14 +00:00
										 |  |  |             'type': 'Collection', | 
					
						
							|  |  |  |             "totalItems": 1, | 
					
						
							|  |  |  |             'items': [{ | 
					
						
							| 
									
										
										
										
											2021-06-22 15:45:59 +00:00
										 |  |  |                 'type': 'Ignore', | 
					
						
							|  |  |  |                 'actor': actor | 
					
						
							| 
									
										
										
										
											2021-09-28 11:20:14 +00:00
										 |  |  |             }] | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         post_json_obj['ignores'] = ignores_json | 
					
						
							| 
									
										
										
										
											2021-09-28 11:20:14 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         if not post_json_obj['ignores'].get('items'): | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |             post_json_obj['ignores']['items']: list[dict] = [] | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         items_list = post_json_obj['ignores']['items'] | 
					
						
							|  |  |  |         for ignores_item in items_list: | 
					
						
							|  |  |  |             if ignores_item.get('actor'): | 
					
						
							|  |  |  |                 if ignores_item['actor'] == actor: | 
					
						
							| 
									
										
										
										
											2021-09-28 11:20:14 +00:00
										 |  |  |                     return | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         new_ignore = { | 
					
						
							| 
									
										
										
										
											2021-09-28 11:20:14 +00:00
										 |  |  |             'type': 'Ignore', | 
					
						
							|  |  |  |             'actor': actor | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         ig_it = len(items_list) | 
					
						
							|  |  |  |         items_list.append(new_ignore) | 
					
						
							|  |  |  |         post_json_obj['ignores']['totalItems'] = ig_it | 
					
						
							|  |  |  |     post_json_obj['muted'] = True | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     if save_json(post_json_object, post_filename): | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |         print('mute_post: saved ' + post_filename) | 
					
						
							| 
									
										
										
										
											2021-03-21 10:45:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |     # remove cached post so that the muted version gets recreated | 
					
						
							|  |  |  |     # without its content text and/or image | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     cached_post_filename = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         get_cached_post_filename(base_dir, nickname, domain, post_json_object) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if cached_post_filename: | 
					
						
							|  |  |  |         if os.path.isfile(cached_post_filename): | 
					
						
							| 
									
										
										
										
											2021-09-05 10:17:43 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 os.remove(cached_post_filename) | 
					
						
							|  |  |  |                 print('MUTE: cached post removed ' + cached_post_filename) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2021-10-29 16:31:20 +00:00
										 |  |  |                 print('EX: MUTE cached post not removed ' + | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                       cached_post_filename) | 
					
						
							| 
									
										
										
										
											2021-09-28 11:52:25 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             print('MUTE: cached post not found ' + cached_post_filename) | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-25 18:42:38 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |         with open(post_filename + '.muted', 'w+', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                   encoding='utf-8') as fp_mute: | 
					
						
							|  |  |  |             fp_mute.write('\n') | 
					
						
							| 
									
										
										
										
											2021-11-25 18:42:38 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         print('EX: Failed to save mute file ' + post_filename + '.muted') | 
					
						
							| 
									
										
										
										
											2021-11-25 18:42:38 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     print('MUTE: ' + post_filename + '.muted file added') | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # if the post is in the recent posts cache then mark it as muted | 
					
						
							| 
									
										
										
										
											2021-12-26 20:01:37 +00:00
										 |  |  |     if recent_posts_cache.get('index'): | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |         post_id = \ | 
					
						
							| 
									
										
										
										
											2021-12-27 11:20:57 +00:00
										 |  |  |             remove_id_ending(post_json_object['id']).replace('/', '#') | 
					
						
							| 
									
										
										
										
											2021-12-26 20:01:37 +00:00
										 |  |  |         if post_id in recent_posts_cache['index']: | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |             print('MUTE: ' + post_id + ' is in recent posts cache') | 
					
						
							| 
									
										
										
										
											2021-12-26 20:01:37 +00:00
										 |  |  |         if recent_posts_cache.get('json'): | 
					
						
							|  |  |  |             recent_posts_cache['json'][post_id] = json.dumps(post_json_object) | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |             print('MUTE: ' + post_id + | 
					
						
							| 
									
										
										
										
											2021-09-28 13:24:57 +00:00
										 |  |  |                   ' marked as muted in recent posts memory cache') | 
					
						
							| 
									
										
										
										
											2021-12-26 20:01:37 +00:00
										 |  |  |         if recent_posts_cache.get('html'): | 
					
						
							|  |  |  |             if recent_posts_cache['html'].get(post_id): | 
					
						
							|  |  |  |                 del recent_posts_cache['html'][post_id] | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |                 print('MUTE: ' + post_id + ' removed cached html') | 
					
						
							| 
									
										
										
										
											2021-09-28 15:48:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if also_update_post_id: | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         post_filename = locate_post(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                                     also_update_post_id) | 
					
						
							| 
									
										
										
										
											2024-10-27 10:29:14 +00:00
										 |  |  |         if post_filename: | 
					
						
							|  |  |  |             if os.path.isfile(post_filename): | 
					
						
							|  |  |  |                 post_json_obj = load_json(post_filename) | 
					
						
							|  |  |  |                 cached_post_filename = \ | 
					
						
							|  |  |  |                     get_cached_post_filename(base_dir, nickname, domain, | 
					
						
							|  |  |  |                                              post_json_obj) | 
					
						
							|  |  |  |                 if cached_post_filename: | 
					
						
							|  |  |  |                     if os.path.isfile(cached_post_filename): | 
					
						
							|  |  |  |                         try: | 
					
						
							|  |  |  |                             os.remove(cached_post_filename) | 
					
						
							|  |  |  |                             print('MUTE: cached referenced post removed ' + | 
					
						
							|  |  |  |                                   cached_post_filename) | 
					
						
							|  |  |  |                         except OSError: | 
					
						
							|  |  |  |                             print('EX: ' + | 
					
						
							|  |  |  |                                   'MUTE cached referenced post not removed ' + | 
					
						
							|  |  |  |                                   cached_post_filename) | 
					
						
							| 
									
										
										
										
											2021-09-28 16:32:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 20:01:37 +00:00
										 |  |  |         if recent_posts_cache.get('json'): | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             if recent_posts_cache['json'].get(also_update_post_id): | 
					
						
							|  |  |  |                 del recent_posts_cache['json'][also_update_post_id] | 
					
						
							|  |  |  |                 print('MUTE: ' + also_update_post_id + | 
					
						
							|  |  |  |                       ' removed referenced json') | 
					
						
							| 
									
										
										
										
											2021-12-26 20:01:37 +00:00
										 |  |  |         if recent_posts_cache.get('html'): | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             if recent_posts_cache['html'].get(also_update_post_id): | 
					
						
							|  |  |  |                 del recent_posts_cache['html'][also_update_post_id] | 
					
						
							|  |  |  |                 print('MUTE: ' + also_update_post_id + | 
					
						
							|  |  |  |                       ' removed referenced html') | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  | def unmute_post(base_dir: str, nickname: str, domain: str, port: int, | 
					
						
							|  |  |  |                 http_prefix: str, post_id: str, recent_posts_cache: {}, | 
					
						
							|  |  |  |                 debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |     """ Unmutes the given post
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     post_filename = locate_post(base_dir, nickname, domain, post_id) | 
					
						
							|  |  |  |     if not post_filename: | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     post_json_object = load_json(post_filename) | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not post_json_object: | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     mute_filename = post_filename + '.muted' | 
					
						
							|  |  |  |     if os.path.isfile(mute_filename): | 
					
						
							| 
									
										
										
										
											2021-09-05 10:17:43 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             os.remove(mute_filename) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2021-10-29 14:48:24 +00:00
										 |  |  |             if debug: | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |                 print('EX: unmute_post mute filename not deleted ' + | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                       str(mute_filename)) | 
					
						
							|  |  |  |         print('UNMUTE: ' + mute_filename + ' file removed') | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     post_json_obj = post_json_object | 
					
						
							|  |  |  |     also_update_post_id = None | 
					
						
							| 
									
										
										
										
											2021-12-26 10:57:03 +00:00
										 |  |  |     if has_object_dict(post_json_object): | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         post_json_obj = post_json_object['object'] | 
					
						
							| 
									
										
										
										
											2021-09-28 15:15:13 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2021-12-26 17:12:07 +00:00
										 |  |  |         if has_object_string(post_json_object, debug): | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             also_update_post_id = remove_id_ending(post_json_object['object']) | 
					
						
							| 
									
										
										
										
											2025-02-23 14:52:50 +00:00
										 |  |  |         elif is_quote_toot(post_json_object, ''): | 
					
						
							|  |  |  |             also_update_post_id = get_quote_toot_url(post_json_object) | 
					
						
							|  |  |  |             also_update_post_id = remove_id_ending(also_update_post_id) | 
					
						
							| 
									
										
										
										
											2021-09-28 15:15:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-06 09:41:21 +00:00
										 |  |  |     # Due to lack of AP specification maintenance, a conversation can also be | 
					
						
							|  |  |  |     # referred to as a thread or (confusingly) "context" | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if post_json_obj.get('conversation'): | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         unmute_conversation(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                             post_json_obj['conversation']) | 
					
						
							| 
									
										
										
										
											2023-01-09 11:38:05 +00:00
										 |  |  |     elif post_json_obj.get('context'): | 
					
						
							|  |  |  |         unmute_conversation(base_dir, nickname, domain, | 
					
						
							|  |  |  |                             post_json_obj['context']) | 
					
						
							| 
									
										
										
										
											2024-10-06 16:22:13 +00:00
										 |  |  |     elif post_json_obj.get('thread'): | 
					
						
							|  |  |  |         unmute_conversation(base_dir, nickname, domain, | 
					
						
							|  |  |  |                             post_json_obj['thread']) | 
					
						
							| 
									
										
										
										
											2021-09-28 11:20:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if post_json_obj.get('ignores'): | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |         domain_full = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  |         actor = local_actor_url(http_prefix, nickname, domain_full) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         total_items = 0 | 
					
						
							|  |  |  |         if post_json_obj['ignores'].get('totalItems'): | 
					
						
							|  |  |  |             total_items = post_json_obj['ignores']['totalItems'] | 
					
						
							|  |  |  |         items_list = post_json_obj['ignores']['items'] | 
					
						
							|  |  |  |         for ignores_item in items_list: | 
					
						
							|  |  |  |             if ignores_item.get('actor'): | 
					
						
							|  |  |  |                 if ignores_item['actor'] == actor: | 
					
						
							| 
									
										
										
										
											2021-09-28 11:20:14 +00:00
										 |  |  |                     if debug: | 
					
						
							|  |  |  |                         print('DEBUG: mute was removed for ' + actor) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                     items_list.remove(ignores_item) | 
					
						
							| 
									
										
										
										
											2021-09-28 11:20:14 +00:00
										 |  |  |                     break | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         if total_items == 1: | 
					
						
							| 
									
										
										
										
											2021-09-28 11:20:14 +00:00
										 |  |  |             if debug: | 
					
						
							|  |  |  |                 print('DEBUG: mute was removed from post') | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             del post_json_obj['ignores'] | 
					
						
							| 
									
										
										
										
											2021-09-28 11:20:14 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             ig_it_len = len(post_json_obj['ignores']['items']) | 
					
						
							|  |  |  |             post_json_obj['ignores']['totalItems'] = ig_it_len | 
					
						
							|  |  |  |     post_json_obj['muted'] = False | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     save_json(post_json_object, post_filename) | 
					
						
							| 
									
										
										
										
											2021-03-21 10:45:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |     # remove cached post so that the muted version gets recreated | 
					
						
							|  |  |  |     # with its content text and/or image | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     cached_post_filename = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         get_cached_post_filename(base_dir, nickname, domain, post_json_object) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if cached_post_filename: | 
					
						
							|  |  |  |         if os.path.isfile(cached_post_filename): | 
					
						
							| 
									
										
										
										
											2021-09-05 10:17:43 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 os.remove(cached_post_filename) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2021-10-29 14:48:24 +00:00
										 |  |  |                 if debug: | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |                     print('EX: unmute_post cached post not deleted ' + | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                           str(cached_post_filename)) | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # if the post is in the recent posts cache then mark it as unmuted | 
					
						
							| 
									
										
										
										
											2021-12-26 20:01:37 +00:00
										 |  |  |     if recent_posts_cache.get('index'): | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |         post_id = \ | 
					
						
							| 
									
										
										
										
											2021-12-27 11:20:57 +00:00
										 |  |  |             remove_id_ending(post_json_object['id']).replace('/', '#') | 
					
						
							| 
									
										
										
										
											2021-12-26 20:01:37 +00:00
										 |  |  |         if post_id in recent_posts_cache['index']: | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |             print('UNMUTE: ' + post_id + ' is in recent posts cache') | 
					
						
							| 
									
										
										
										
											2021-12-26 20:01:37 +00:00
										 |  |  |         if recent_posts_cache.get('json'): | 
					
						
							|  |  |  |             recent_posts_cache['json'][post_id] = json.dumps(post_json_object) | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |             print('UNMUTE: ' + post_id + | 
					
						
							| 
									
										
										
										
											2021-09-28 13:24:57 +00:00
										 |  |  |                   ' marked as unmuted in recent posts cache') | 
					
						
							| 
									
										
										
										
											2021-12-26 20:01:37 +00:00
										 |  |  |         if recent_posts_cache.get('html'): | 
					
						
							|  |  |  |             if recent_posts_cache['html'].get(post_id): | 
					
						
							|  |  |  |                 del recent_posts_cache['html'][post_id] | 
					
						
							| 
									
										
										
										
											2021-12-26 19:47:06 +00:00
										 |  |  |                 print('UNMUTE: ' + post_id + ' removed cached html') | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if also_update_post_id: | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         post_filename = locate_post(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                                     also_update_post_id) | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         if os.path.isfile(post_filename): | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             post_json_obj = load_json(post_filename) | 
					
						
							|  |  |  |             cached_post_filename = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |                 get_cached_post_filename(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                                          post_json_obj) | 
					
						
							|  |  |  |             if cached_post_filename: | 
					
						
							|  |  |  |                 if os.path.isfile(cached_post_filename): | 
					
						
							| 
									
										
										
										
											2021-09-28 16:32:54 +00:00
										 |  |  |                     try: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                         os.remove(cached_post_filename) | 
					
						
							| 
									
										
										
										
											2021-09-28 16:32:54 +00:00
										 |  |  |                         print('MUTE: cached referenced post removed ' + | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                               cached_post_filename) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |                     except OSError: | 
					
						
							| 
									
										
										
										
											2021-10-29 14:48:24 +00:00
										 |  |  |                         if debug: | 
					
						
							| 
									
										
										
										
											2021-10-29 16:31:20 +00:00
										 |  |  |                             print('EX: ' + | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |                                   'unmute_post cached ref post not removed ' + | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                                   str(cached_post_filename)) | 
					
						
							| 
									
										
										
										
											2021-09-28 16:32:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 20:01:37 +00:00
										 |  |  |         if recent_posts_cache.get('json'): | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             if recent_posts_cache['json'].get(also_update_post_id): | 
					
						
							|  |  |  |                 del recent_posts_cache['json'][also_update_post_id] | 
					
						
							| 
									
										
										
										
											2021-09-28 15:48:14 +00:00
										 |  |  |                 print('UNMUTE: ' + | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                       also_update_post_id + ' removed referenced json') | 
					
						
							| 
									
										
										
										
											2021-12-26 20:01:37 +00:00
										 |  |  |         if recent_posts_cache.get('html'): | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             if recent_posts_cache['html'].get(also_update_post_id): | 
					
						
							|  |  |  |                 del recent_posts_cache['html'][also_update_post_id] | 
					
						
							| 
									
										
										
										
											2021-09-28 15:48:14 +00:00
										 |  |  |                 print('UNMUTE: ' + | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                       also_update_post_id + ' removed referenced html') | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def outbox_mute(base_dir: str, http_prefix: str, | 
					
						
							|  |  |  |                 nickname: str, domain: str, port: int, | 
					
						
							|  |  |  |                 message_json: {}, debug: bool, | 
					
						
							|  |  |  |                 recent_posts_cache: {}) -> None: | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |     """When a mute is received by the outbox from c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json.get('type'): | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 17:15:04 +00:00
										 |  |  |     if not has_actor(message_json, debug): | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |     domain_full = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |     actor_url = get_actor_from_post(message_json) | 
					
						
							| 
									
										
										
										
											2024-05-27 12:45:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     actor_found = False | 
					
						
							|  |  |  |     users_paths = get_user_paths() | 
					
						
							|  |  |  |     for possible_path in users_paths: | 
					
						
							|  |  |  |         if actor_url.endswith(domain_full + possible_path + nickname): | 
					
						
							|  |  |  |             actor_found = True | 
					
						
							|  |  |  |             break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not actor_found: | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['type'] == 'Ignore': | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 17:12:07 +00:00
										 |  |  |     if not has_object_string(message_json, debug): | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s mute request arrived in outbox') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     message_id = remove_id_ending(message_json['object']) | 
					
						
							| 
									
										
										
										
											2024-05-27 12:45:01 +00:00
										 |  |  |     if not contains_statuses(message_id): | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s mute object is not a status') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if not has_users_path(message_id): | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s mute object has no nickname') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     post_filename = locate_post(base_dir, nickname, domain, message_id) | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     if not post_filename: | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s mute post not found in inbox or outbox') | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             print(message_id) | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     nickname_muted = get_nickname_from_actor(message_json['object']) | 
					
						
							|  |  |  |     if not nickname_muted: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |         print('WARN: outbox_mute unable to find nickname in ' + | 
					
						
							|  |  |  |               message_json['object']) | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |     mute_post(base_dir, nickname, domain, port, | 
					
						
							|  |  |  |               http_prefix, message_json['object'], recent_posts_cache, | 
					
						
							|  |  |  |               debug) | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         print('DEBUG: post muted via c2s - ' + post_filename) | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def outbox_undo_mute(base_dir: str, http_prefix: str, | 
					
						
							|  |  |  |                      nickname: str, domain: str, port: int, | 
					
						
							|  |  |  |                      message_json: {}, debug: bool, | 
					
						
							|  |  |  |                      recent_posts_cache: {}) -> None: | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |     """When an undo mute is received by the outbox from c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json.get('type'): | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 17:15:04 +00:00
										 |  |  |     if not has_actor(message_json, debug): | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |     domain_full = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |     actor_url = get_actor_from_post(message_json) | 
					
						
							| 
									
										
										
										
											2024-05-27 12:45:01 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     actor_found = False | 
					
						
							|  |  |  |     users_paths = get_user_paths() | 
					
						
							|  |  |  |     for possible_path in users_paths: | 
					
						
							|  |  |  |         if actor_url.endswith(domain_full + possible_path + nickname): | 
					
						
							|  |  |  |             actor_found = True | 
					
						
							|  |  |  |             break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not actor_found: | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['type'] == 'Undo': | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2022-04-09 15:11:22 +00:00
										 |  |  |     if not has_object_string_type(message_json, debug): | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if message_json['object']['type'] != 'Ignore': | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not isinstance(message_json['object']['object'], str): | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: undo mute object is not a string') | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s undo mute request arrived in outbox') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     message_id = remove_id_ending(message_json['object']['object']) | 
					
						
							| 
									
										
										
										
											2024-05-27 12:45:01 +00:00
										 |  |  |     if not contains_statuses(message_id): | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s undo mute object is not a status') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if not has_users_path(message_id): | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s undo mute object has no nickname') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     post_filename = locate_post(base_dir, nickname, domain, message_id) | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     if not post_filename: | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s undo mute post not found in inbox or outbox') | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             print(message_id) | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     nickname_muted = get_nickname_from_actor(message_json['object']['object']) | 
					
						
							|  |  |  |     if not nickname_muted: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |         print('WARN: outbox_undo_mute unable to find nickname in ' + | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |               message_json['object']['object']) | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |     unmute_post(base_dir, nickname, domain, port, | 
					
						
							|  |  |  |                 http_prefix, message_json['object']['object'], | 
					
						
							|  |  |  |                 recent_posts_cache, debug) | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         print('DEBUG: post undo mute via c2s - ' + post_filename) | 
					
						
							| 
									
										
										
										
											2021-03-20 21:20:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  | def broch_mode_is_active(base_dir: str) -> bool: | 
					
						
							| 
									
										
										
										
											2021-05-03 10:17:21 +00:00
										 |  |  |     """Returns true if broch mode is active
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     allow_filename = data_dir(base_dir) + '/allowedinstances.txt' | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     return os.path.isfile(allow_filename) | 
					
						
							| 
									
										
										
										
											2021-05-03 10:17:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  | def set_broch_mode(base_dir: str, domain_full: str, enabled: bool) -> None: | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  |     """Broch mode can be used to lock down the instance during
 | 
					
						
							|  |  |  |     a period of time when it is temporarily under attack. | 
					
						
							|  |  |  |     For example, where an adversary is constantly spinning up new | 
					
						
							|  |  |  |     instances. | 
					
						
							|  |  |  |     It surveys the following lists of all accounts and uses that | 
					
						
							|  |  |  |     to construct an instance level allow list. Anything arriving | 
					
						
							|  |  |  |     which is then not from one of the allowed domains will be dropped | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     allow_filename = data_dir(base_dir) + '/allowedinstances.txt' | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not enabled: | 
					
						
							|  |  |  |         # remove instance allow list | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         if os.path.isfile(allow_filename): | 
					
						
							| 
									
										
										
										
											2021-09-05 10:17:43 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 os.remove(allow_filename) | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-28 21:55:38 +00:00
										 |  |  |                 print('EX: set_broch_mode allow file not deleted ' + | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                       str(allow_filename)) | 
					
						
							| 
									
										
										
										
											2021-02-15 22:26:25 +00:00
										 |  |  |             print('Broch mode turned off') | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         if os.path.isfile(allow_filename): | 
					
						
							|  |  |  |             last_modified = file_last_modified(allow_filename) | 
					
						
							|  |  |  |             print('Broch mode already activated ' + last_modified) | 
					
						
							| 
									
										
										
										
											2021-02-16 09:50:50 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  |         # generate instance allow list | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |         allowed_domains = [domain_full] | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  |         follow_files = ('following.txt', 'followers.txt') | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |         dir_str = data_dir(base_dir) | 
					
						
							|  |  |  |         for _, dirs, _ in os.walk(dir_str): | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  |             for acct in dirs: | 
					
						
							| 
									
										
										
										
											2021-12-26 18:46:43 +00:00
										 |  |  |                 if not is_account_dir(acct): | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |                 account_dir = os.path.join(dir_str, acct) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 for follow_file_type in follow_files: | 
					
						
							|  |  |  |                     following_filename = account_dir + '/' + follow_file_type | 
					
						
							|  |  |  |                     if not os.path.isfile(following_filename): | 
					
						
							| 
									
										
										
										
											2021-02-15 22:42:16 +00:00
										 |  |  |                         continue | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                     try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |                         with open(following_filename, 'r', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                                   encoding='utf-8') as fp_foll: | 
					
						
							|  |  |  |                             follow_list = fp_foll.readlines() | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                             for handle in follow_list: | 
					
						
							| 
									
										
										
										
											2021-11-26 12:28:20 +00:00
										 |  |  |                                 if '@' not in handle: | 
					
						
							|  |  |  |                                     continue | 
					
						
							| 
									
										
										
										
											2022-06-21 11:58:50 +00:00
										 |  |  |                                 handle = remove_eol(handle) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                                 handle_domain = handle.split('@')[1] | 
					
						
							|  |  |  |                                 if handle_domain not in allowed_domains: | 
					
						
							|  |  |  |                                     allowed_domains.append(handle_domain) | 
					
						
							| 
									
										
										
										
											2021-12-25 15:28:52 +00:00
										 |  |  |                     except OSError as ex: | 
					
						
							| 
									
										
										
										
											2024-07-13 12:06:28 +00:00
										 |  |  |                         print('EX: set_broch_mode failed to read ' + | 
					
						
							|  |  |  |                               following_filename + ' ' + str(ex)) | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  |             break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # write the allow file | 
					
						
							| 
									
										
										
										
											2021-11-25 18:42:38 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |             with open(allow_filename, 'w+', | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                       encoding='utf-8') as fp_allow: | 
					
						
							|  |  |  |                 fp_allow.write(domain_full + '\n') | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                 for allowed in allowed_domains: | 
					
						
							| 
									
										
										
										
											2024-07-14 13:01:46 +00:00
										 |  |  |                     fp_allow.write(allowed + '\n') | 
					
						
							| 
									
										
										
										
											2021-11-25 18:42:38 +00:00
										 |  |  |                 print('Broch mode enabled') | 
					
						
							| 
									
										
										
										
											2021-12-25 15:28:52 +00:00
										 |  |  |         except OSError as ex: | 
					
						
							|  |  |  |             print('EX: Broch mode not enabled due to file write ' + str(ex)) | 
					
						
							| 
									
										
										
										
											2021-11-25 18:42:38 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2021-02-15 22:06:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-30 13:56:38 +00:00
										 |  |  |     set_config_param(base_dir, "brochMode", enabled) | 
					
						
							| 
									
										
										
										
											2021-02-15 22:26:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-11 18:09:08 +00:00
										 |  |  | def broch_modeLapses(base_dir: str, lapse_days: int) -> bool: | 
					
						
							| 
									
										
										
										
											2021-02-15 22:26:25 +00:00
										 |  |  |     """After broch mode is enabled it automatically
 | 
					
						
							|  |  |  |     elapses after a period of time | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     allow_filename = data_dir(base_dir) + '/allowedinstances.txt' | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if not os.path.isfile(allow_filename): | 
					
						
							| 
									
										
										
										
											2021-02-15 23:01:07 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     last_modified = file_last_modified(allow_filename) | 
					
						
							| 
									
										
										
										
											2023-11-20 22:27:58 +00:00
										 |  |  |     modified_date = \ | 
					
						
							|  |  |  |         date_from_string_format(last_modified, ["%Y-%m-%dT%H:%M:%S%z"]) | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     if not modified_date: | 
					
						
							| 
									
										
										
										
											2023-11-20 22:27:58 +00:00
										 |  |  |         print('EX: broch_modeLapses date not parsed ' + str(last_modified)) | 
					
						
							| 
									
										
										
										
											2021-06-05 13:38:57 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2023-11-20 22:27:58 +00:00
										 |  |  |     curr_time = date_utcnow() | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |     days_since_broch = (curr_time - modified_date).days | 
					
						
							| 
									
										
										
										
											2024-02-11 18:09:08 +00:00
										 |  |  |     if days_since_broch >= lapse_days: | 
					
						
							| 
									
										
										
										
											2021-09-05 10:17:43 +00:00
										 |  |  |         removed = False | 
					
						
							| 
									
										
										
										
											2021-02-15 22:26:25 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |             os.remove(allow_filename) | 
					
						
							| 
									
										
										
										
											2021-09-05 10:17:43 +00:00
										 |  |  |             removed = True | 
					
						
							| 
									
										
										
										
											2021-11-25 17:01:01 +00:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-25 18:38:19 +00:00
										 |  |  |             print('EX: broch_modeLapses allow file not deleted ' + | 
					
						
							| 
									
										
										
										
											2021-12-30 10:16:57 +00:00
										 |  |  |                   str(allow_filename)) | 
					
						
							| 
									
										
										
										
											2021-09-05 10:17:43 +00:00
										 |  |  |         if removed: | 
					
						
							| 
									
										
										
										
											2021-12-30 13:56:38 +00:00
										 |  |  |             set_config_param(base_dir, "brochMode", False) | 
					
						
							| 
									
										
										
										
											2021-02-15 22:26:25 +00:00
										 |  |  |             print('Broch mode has elapsed') | 
					
						
							| 
									
										
										
										
											2021-06-05 13:38:57 +00:00
										 |  |  |             return True | 
					
						
							|  |  |  |     return False | 
					
						
							| 
									
										
										
										
											2021-10-21 11:13:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 18:42:58 +00:00
										 |  |  | def import_blocking_file(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |                          lines: []) -> bool: | 
					
						
							| 
									
										
										
										
											2023-02-10 12:02:10 +00:00
										 |  |  |     """Imports blocked domains for a given account
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not lines: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     if len(lines) < 2: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     if not lines[0].startswith('#domain,#') or \ | 
					
						
							|  |  |  |        'comment' not in lines[0]: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     fieldnames = lines[0].split(',') | 
					
						
							|  |  |  |     comment_field_index = 0 | 
					
						
							|  |  |  |     for field_str in fieldnames: | 
					
						
							|  |  |  |         if 'comment' in field_str: | 
					
						
							|  |  |  |             break | 
					
						
							|  |  |  |         comment_field_index += 1 | 
					
						
							|  |  |  |     if comment_field_index >= len(fieldnames): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     account_directory = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     blocking_filename = \ | 
					
						
							|  |  |  |         account_directory + '/blocking.txt' | 
					
						
							|  |  |  |     blocking_reasons_filename = \ | 
					
						
							|  |  |  |         account_directory + '/blocking_reasons.txt' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |     existing_lines: list[str] = [] | 
					
						
							| 
									
										
										
										
											2023-02-10 12:02:10 +00:00
										 |  |  |     if os.path.isfile(blocking_filename): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_filename, 'r', encoding='utf-8') as fp_blocks: | 
					
						
							|  |  |  |                 existing_lines = fp_blocks.read().splitlines() | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: ' + | 
					
						
							|  |  |  |                   'unable to import existing blocked instances from file ' + | 
					
						
							|  |  |  |                   blocking_filename) | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |     existing_reasons: list[str] = [] | 
					
						
							| 
									
										
										
										
											2023-02-10 12:02:10 +00:00
										 |  |  |     if os.path.isfile(blocking_reasons_filename): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_reasons_filename, | 
					
						
							|  |  |  |                       'r', encoding='utf-8') as fp_blocks: | 
					
						
							|  |  |  |                 existing_reasons = fp_blocks.read().splitlines() | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: ' + | 
					
						
							|  |  |  |                   'unable to import existing ' + | 
					
						
							|  |  |  |                   'blocked instance reasons from file ' + | 
					
						
							|  |  |  |                   blocking_reasons_filename) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |     append_blocks: list[str] = [] | 
					
						
							|  |  |  |     append_reasons: list[str] = [] | 
					
						
							| 
									
										
										
										
											2023-02-10 12:02:10 +00:00
										 |  |  |     for line_str in lines: | 
					
						
							|  |  |  |         if line_str.startswith('#'): | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         block_fields = line_str.split(',') | 
					
						
							|  |  |  |         blocked_domain_name = block_fields[0].strip() | 
					
						
							|  |  |  |         if ' ' in blocked_domain_name or \ | 
					
						
							|  |  |  |            '.' not in blocked_domain_name: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         if blocked_domain_name in existing_lines: | 
					
						
							|  |  |  |             # already blocked | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         append_blocks.append(blocked_domain_name) | 
					
						
							| 
									
										
										
										
											2023-02-10 13:38:29 +00:00
										 |  |  |         blocked_comment = '' | 
					
						
							|  |  |  |         if '"' in line_str: | 
					
						
							|  |  |  |             quote_section = line_str.split('"') | 
					
						
							|  |  |  |             if len(quote_section) > 1: | 
					
						
							|  |  |  |                 blocked_comment = quote_section[1] | 
					
						
							| 
									
										
										
										
											2023-02-10 12:02:10 +00:00
										 |  |  |                 append_reasons.append(blocked_domain_name + ' ' + | 
					
						
							|  |  |  |                                       blocked_comment) | 
					
						
							| 
									
										
										
										
											2023-02-10 13:38:29 +00:00
										 |  |  |         if not blocked_comment: | 
					
						
							|  |  |  |             if len(block_fields) > comment_field_index: | 
					
						
							|  |  |  |                 blocked_comment = block_fields[comment_field_index].strip() | 
					
						
							|  |  |  |                 if blocked_comment: | 
					
						
							|  |  |  |                     if blocked_comment.startswith('"'): | 
					
						
							|  |  |  |                         blocked_comment = blocked_comment.replace('"', '') | 
					
						
							|  |  |  |                     if blocked_comment not in existing_reasons: | 
					
						
							|  |  |  |                         append_reasons.append(blocked_domain_name + ' ' + | 
					
						
							|  |  |  |                                               blocked_comment) | 
					
						
							| 
									
										
										
										
											2023-02-10 12:02:10 +00:00
										 |  |  |     if not append_blocks: | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         with open(blocking_filename, 'a+', encoding='utf-8') as fp_blocks: | 
					
						
							|  |  |  |             for new_block in append_blocks: | 
					
						
							|  |  |  |                 fp_blocks.write(new_block + '\n') | 
					
						
							|  |  |  |     except OSError: | 
					
						
							|  |  |  |         print('EX: ' + | 
					
						
							|  |  |  |               'unable to append imported blocks to ' + | 
					
						
							|  |  |  |               blocking_filename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         with open(blocking_reasons_filename, 'a+', | 
					
						
							|  |  |  |                   encoding='utf-8') as fp_blocks: | 
					
						
							|  |  |  |             for new_reason in append_reasons: | 
					
						
							|  |  |  |                 fp_blocks.write(new_reason + '\n') | 
					
						
							|  |  |  |     except OSError: | 
					
						
							|  |  |  |         print('EX: ' + | 
					
						
							|  |  |  |               'unable to append imported block reasons to ' + | 
					
						
							|  |  |  |               blocking_reasons_filename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return True | 
					
						
							| 
									
										
										
										
											2023-02-10 13:08:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-10 18:42:58 +00:00
										 |  |  | def export_blocking_file(base_dir: str, nickname: str, domain: str) -> str: | 
					
						
							| 
									
										
										
										
											2023-02-10 13:08:41 +00:00
										 |  |  |     """exports account level blocks in a csv format
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     account_directory = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     blocking_filename = \ | 
					
						
							|  |  |  |         account_directory + '/blocking.txt' | 
					
						
							|  |  |  |     blocking_reasons_filename = \ | 
					
						
							|  |  |  |         account_directory + '/blocking_reasons.txt' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     blocks_header = \ | 
					
						
							|  |  |  |         '#domain,#severity,#reject_media,#reject_reports,' + \ | 
					
						
							|  |  |  |         '#public_comment,#obfuscate\n' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not os.path.isfile(blocking_filename): | 
					
						
							|  |  |  |         return blocks_header | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |     blocking_lines: list[str] = [] | 
					
						
							| 
									
										
										
										
											2023-02-10 13:08:41 +00:00
										 |  |  |     if os.path.isfile(blocking_filename): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_filename, 'r', encoding='utf-8') as fp_block: | 
					
						
							|  |  |  |                 blocking_lines = fp_block.read().splitlines() | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: export_blocks failed to read ' + blocking_filename) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |     blocking_reasons: list[str] = [] | 
					
						
							| 
									
										
										
										
											2023-02-10 13:08:41 +00:00
										 |  |  |     if os.path.isfile(blocking_reasons_filename): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(blocking_reasons_filename, 'r', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_block: | 
					
						
							|  |  |  |                 blocking_reasons = fp_block.read().splitlines() | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: export_blocks failed to read ' + | 
					
						
							|  |  |  |                   blocking_reasons_filename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     blocks_str = blocks_header | 
					
						
							|  |  |  |     for blocked_domain in blocking_lines: | 
					
						
							|  |  |  |         blocked_domain = blocked_domain.strip() | 
					
						
							| 
									
										
										
										
											2023-02-10 13:13:05 +00:00
										 |  |  |         if blocked_domain.startswith('#'): | 
					
						
							| 
									
										
										
										
											2023-02-10 13:08:41 +00:00
										 |  |  |             continue | 
					
						
							|  |  |  |         reason_str = '' | 
					
						
							|  |  |  |         for reason_line in blocking_reasons: | 
					
						
							|  |  |  |             if reason_line.startswith(blocked_domain + ' '): | 
					
						
							| 
									
										
										
										
											2023-02-10 13:16:13 +00:00
										 |  |  |                 reason_str = reason_line.split(' ', 1)[1] | 
					
						
							| 
									
										
										
										
											2023-02-10 13:08:41 +00:00
										 |  |  |                 break | 
					
						
							|  |  |  |         blocks_str += \ | 
					
						
							|  |  |  |             blocked_domain + ',suspend,false,false,"' + \ | 
					
						
							|  |  |  |             reason_str + '",false\n' | 
					
						
							|  |  |  |     return blocks_str | 
					
						
							| 
									
										
										
										
											2023-07-05 11:56:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def get_blocks_via_server(session, nickname: str, password: str, | 
					
						
							|  |  |  |                           domain: str, port: int, | 
					
						
							| 
									
										
										
										
											2023-07-05 12:15:00 +00:00
										 |  |  |                           http_prefix: str, page_number: int, debug: bool, | 
					
						
							|  |  |  |                           version: str, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                           signing_priv_key_pem: str, | 
					
						
							|  |  |  |                           mitm_servers: []) -> {}: | 
					
						
							| 
									
										
										
										
											2023-07-05 11:56:02 +00:00
										 |  |  |     """Returns the blocked collection for shared items via c2s
 | 
					
						
							|  |  |  |     https://codeberg.org/fediverse/fep/src/branch/main/fep/c648/fep-c648.md | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							|  |  |  |         print('WARN: No session for get_blocks_via_server') | 
					
						
							|  |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auth_header = create_basic_auth_header(nickname, password) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     headers = { | 
					
						
							|  |  |  |         'host': domain, | 
					
						
							|  |  |  |         'Content-type': 'application/json', | 
					
						
							|  |  |  |         'Authorization': auth_header, | 
					
						
							|  |  |  |         'Accept': 'application/json' | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     domain_full = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2023-07-05 12:15:00 +00:00
										 |  |  |     url = local_actor_url(http_prefix, nickname, domain_full) + \ | 
					
						
							|  |  |  |         '/blocked?page=' + str(page_number) | 
					
						
							| 
									
										
										
										
											2023-07-05 11:56:02 +00:00
										 |  |  |     if debug: | 
					
						
							|  |  |  |         print('Blocked collection request to: ' + url) | 
					
						
							|  |  |  |     blocked_json = get_json(signing_priv_key_pem, session, url, headers, None, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                             debug, mitm_servers, version, http_prefix, None) | 
					
						
							| 
									
										
										
										
											2023-08-13 09:58:02 +00:00
										 |  |  |     if not get_json_valid(blocked_json): | 
					
						
							| 
									
										
										
										
											2023-07-05 11:56:02 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: GET blocked collection failed for c2s to ' + url) | 
					
						
							|  |  |  | #        return 5 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s GET blocked collection success') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return blocked_json | 
					
						
							| 
									
										
										
										
											2023-07-18 14:05:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def load_blocked_military(base_dir: str) -> {}: | 
					
						
							|  |  |  |     """Loads a list of nicknames for accounts which block military instances
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     block_military_filename = data_dir(base_dir) + '/block_military.txt' | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |     nicknames_list: list[str] = [] | 
					
						
							| 
									
										
										
										
											2023-07-18 14:05:54 +00:00
										 |  |  |     if os.path.isfile(block_military_filename): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(block_military_filename, 'r', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_mil: | 
					
						
							|  |  |  |                 nicknames_list = fp_mil.read() | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: error while reading block military file') | 
					
						
							|  |  |  |     if not nicknames_list: | 
					
						
							|  |  |  |         return {} | 
					
						
							|  |  |  |     nicknames_list = nicknames_list.split('\n') | 
					
						
							|  |  |  |     nicknames_dict = {} | 
					
						
							|  |  |  |     for nickname in nicknames_list: | 
					
						
							|  |  |  |         nicknames_dict[nickname] = True | 
					
						
							|  |  |  |     return nicknames_dict | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-15 13:01:26 +00:00
										 |  |  | def load_blocked_government(base_dir: str) -> {}: | 
					
						
							|  |  |  |     """Loads a list of nicknames for accounts which block government instances
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     block_government_filename = data_dir(base_dir) + '/block_government.txt' | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |     nicknames_list: list[str] = [] | 
					
						
							| 
									
										
										
										
											2024-12-15 13:01:26 +00:00
										 |  |  |     if os.path.isfile(block_government_filename): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(block_government_filename, 'r', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_gov: | 
					
						
							|  |  |  |                 nicknames_list = fp_gov.read() | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: error while reading block government file') | 
					
						
							|  |  |  |     if not nicknames_list: | 
					
						
							|  |  |  |         return {} | 
					
						
							|  |  |  |     nicknames_list = nicknames_list.split('\n') | 
					
						
							|  |  |  |     nicknames_dict = {} | 
					
						
							|  |  |  |     for nickname in nicknames_list: | 
					
						
							|  |  |  |         nicknames_dict[nickname] = True | 
					
						
							|  |  |  |     return nicknames_dict | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-14 18:02:43 +00:00
										 |  |  | def load_blocked_bluesky(base_dir: str) -> {}: | 
					
						
							|  |  |  |     """Loads a list of nicknames for accounts which block bluesky bridges
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     block_bluesky_filename = data_dir(base_dir) + '/block_bluesky.txt' | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |     nicknames_list: list[str] = [] | 
					
						
							| 
									
										
										
										
											2024-12-14 18:02:43 +00:00
										 |  |  |     if os.path.isfile(block_bluesky_filename): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(block_bluesky_filename, 'r', | 
					
						
							| 
									
										
										
										
											2024-12-15 13:01:26 +00:00
										 |  |  |                       encoding='utf-8') as fp_bsky: | 
					
						
							|  |  |  |                 nicknames_list = fp_bsky.read() | 
					
						
							| 
									
										
										
										
											2024-12-14 18:02:43 +00:00
										 |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: error while reading block bluesky file') | 
					
						
							|  |  |  |     if not nicknames_list: | 
					
						
							|  |  |  |         return {} | 
					
						
							|  |  |  |     nicknames_list = nicknames_list.split('\n') | 
					
						
							|  |  |  |     nicknames_dict = {} | 
					
						
							|  |  |  |     for nickname in nicknames_list: | 
					
						
							|  |  |  |         nicknames_dict[nickname] = True | 
					
						
							|  |  |  |     return nicknames_dict | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-29 14:17:06 +00:00
										 |  |  | def load_blocked_nostr(base_dir: str) -> {}: | 
					
						
							|  |  |  |     """Loads a list of nicknames for accounts which block nostr bridges
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     block_nostr_filename = data_dir(base_dir) + '/block_nostr.txt' | 
					
						
							|  |  |  |     nicknames_list: list[str] = [] | 
					
						
							|  |  |  |     if os.path.isfile(block_nostr_filename): | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(block_nostr_filename, 'r', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_nostr: | 
					
						
							|  |  |  |                 nicknames_list = fp_nostr.read() | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: error while reading block nostr file') | 
					
						
							|  |  |  |     if not nicknames_list: | 
					
						
							|  |  |  |         return {} | 
					
						
							|  |  |  |     nicknames_list = nicknames_list.split('\n') | 
					
						
							|  |  |  |     nicknames_dict = {} | 
					
						
							|  |  |  |     for nickname in nicknames_list: | 
					
						
							|  |  |  |         nicknames_dict[nickname] = True | 
					
						
							|  |  |  |     return nicknames_dict | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-18 14:05:54 +00:00
										 |  |  | def save_blocked_military(base_dir: str, block_military: {}) -> None: | 
					
						
							|  |  |  |     """Saves a list of nicknames for accounts which block military instances
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     nicknames_str = '' | 
					
						
							|  |  |  |     for nickname, _ in block_military.items(): | 
					
						
							|  |  |  |         nicknames_str += nickname + '\n' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     block_military_filename = data_dir(base_dir) + '/block_military.txt' | 
					
						
							| 
									
										
										
										
											2023-07-18 14:05:54 +00:00
										 |  |  |     try: | 
					
						
							|  |  |  |         with open(block_military_filename, 'w+', | 
					
						
							|  |  |  |                   encoding='utf-8') as fp_mil: | 
					
						
							|  |  |  |             fp_mil.write(nicknames_str) | 
					
						
							|  |  |  |     except OSError: | 
					
						
							|  |  |  |         print('EX: error while saving block military file') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-15 13:01:26 +00:00
										 |  |  | def save_blocked_government(base_dir: str, block_government: {}) -> None: | 
					
						
							|  |  |  |     """Saves a list of nicknames for accounts which block government instances
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     nicknames_str = '' | 
					
						
							|  |  |  |     for nickname, _ in block_government.items(): | 
					
						
							|  |  |  |         nicknames_str += nickname + '\n' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     block_government_filename = data_dir(base_dir) + '/block_government.txt' | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         with open(block_government_filename, 'w+', | 
					
						
							|  |  |  |                   encoding='utf-8') as fp_gov: | 
					
						
							|  |  |  |             fp_gov.write(nicknames_str) | 
					
						
							|  |  |  |     except OSError: | 
					
						
							|  |  |  |         print('EX: error while saving block government file') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-14 18:02:43 +00:00
										 |  |  | def save_blocked_bluesky(base_dir: str, block_bluesky: {}) -> None: | 
					
						
							|  |  |  |     """Saves a list of nicknames for accounts which block bluesky bridges
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     nicknames_str = '' | 
					
						
							|  |  |  |     for nickname, _ in block_bluesky.items(): | 
					
						
							|  |  |  |         nicknames_str += nickname + '\n' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     block_bluesky_filename = data_dir(base_dir) + '/block_bluesky.txt' | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         with open(block_bluesky_filename, 'w+', | 
					
						
							| 
									
										
										
										
											2024-12-15 13:01:26 +00:00
										 |  |  |                   encoding='utf-8') as fp_bsky: | 
					
						
							|  |  |  |             fp_bsky.write(nicknames_str) | 
					
						
							| 
									
										
										
										
											2024-12-14 18:02:43 +00:00
										 |  |  |     except OSError: | 
					
						
							|  |  |  |         print('EX: error while saving block bluesky file') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-29 14:17:06 +00:00
										 |  |  | def save_blocked_nostr(base_dir: str, block_nostr: {}) -> None: | 
					
						
							|  |  |  |     """Saves a list of nicknames for accounts which block nostr bridges
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     nicknames_str = '' | 
					
						
							|  |  |  |     for nickname, _ in block_nostr.items(): | 
					
						
							|  |  |  |         nicknames_str += nickname + '\n' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     block_nostr_filename = data_dir(base_dir) + '/block_nostr.txt' | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         with open(block_nostr_filename, 'w+', | 
					
						
							|  |  |  |                   encoding='utf-8') as fp_nostr: | 
					
						
							|  |  |  |             fp_nostr.write(nicknames_str) | 
					
						
							|  |  |  |     except OSError: | 
					
						
							|  |  |  |         print('EX: error while saving block nostr file') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-18 14:55:26 +00:00
										 |  |  | def get_mil_domains_list() -> []: | 
					
						
							| 
									
										
										
										
											2023-12-12 18:30:31 +00:00
										 |  |  |     """returns a list of military domains
 | 
					
						
							| 
									
										
										
										
											2023-07-18 14:55:26 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-12-12 18:30:31 +00:00
										 |  |  |     return ('army', 'navy', 'airforce', 'mil', | 
					
						
							|  |  |  |             'sncorp.com', 'sierranevadacorp.us', 'ncontext.com') | 
					
						
							| 
									
										
										
										
											2023-07-18 14:55:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-15 13:01:26 +00:00
										 |  |  | def get_gov_domains_list() -> []: | 
					
						
							|  |  |  |     """returns a list of government domains
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     return ('.gov', '.overheid.nl', '.bund.de') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-14 18:02:43 +00:00
										 |  |  | def get_bsky_domains_list() -> []: | 
					
						
							|  |  |  |     """returns a list of bluesky bridges
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-12-14 18:29:30 +00:00
										 |  |  |     return ['brid.gy'] | 
					
						
							| 
									
										
										
										
											2024-12-14 18:02:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-29 14:17:06 +00:00
										 |  |  | def get_nostr_domains_list() -> []: | 
					
						
							|  |  |  |     """returns a list of nostr bridges
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     return ['mostr.pub'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-18 14:05:54 +00:00
										 |  |  | def contains_military_domain(message_str: str) -> bool: | 
					
						
							|  |  |  |     """Returns true if the given string contains a military domain
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-18 14:55:26 +00:00
										 |  |  |     mil_domains = get_mil_domains_list() | 
					
						
							| 
									
										
										
										
											2023-12-12 18:30:31 +00:00
										 |  |  |     for domain_str in mil_domains: | 
					
						
							|  |  |  |         if '.' not in domain_str: | 
					
						
							|  |  |  |             tld = domain_str | 
					
						
							|  |  |  |             if '.' + tld + '"' in message_str or \ | 
					
						
							|  |  |  |                '.' + tld + '/' in message_str: | 
					
						
							|  |  |  |                 return True | 
					
						
							| 
									
										
										
										
											2024-12-14 18:02:43 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             if domain_str + '"' in message_str or \ | 
					
						
							|  |  |  |                domain_str + '/' in message_str: | 
					
						
							|  |  |  |                 return True | 
					
						
							|  |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-15 13:01:26 +00:00
										 |  |  | def contains_government_domain(message_str: str) -> bool: | 
					
						
							|  |  |  |     """Returns true if the given string contains a government domain
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if '.gov.' in message_str: | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  |     gov_domains = get_gov_domains_list() | 
					
						
							|  |  |  |     for domain_str in gov_domains: | 
					
						
							|  |  |  |         if domain_str + '"' in message_str or \ | 
					
						
							|  |  |  |            domain_str + '/' in message_str: | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-14 18:02:43 +00:00
										 |  |  | def contains_bluesky_domain(message_str: str) -> bool: | 
					
						
							|  |  |  |     """Returns true if the given string contains a bluesky bridge domain
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     bsky_domains = get_bsky_domains_list() | 
					
						
							|  |  |  |     for domain_str in bsky_domains: | 
					
						
							| 
									
										
										
										
											2024-12-15 13:01:26 +00:00
										 |  |  |         if domain_str + '"' in message_str or \ | 
					
						
							|  |  |  |            domain_str + '/' in message_str: | 
					
						
							|  |  |  |             return True | 
					
						
							| 
									
										
										
										
											2023-07-18 14:05:54 +00:00
										 |  |  |     return False | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-29 14:17:06 +00:00
										 |  |  | def contains_nostr_domain(message_str: str) -> bool: | 
					
						
							|  |  |  |     """Returns true if the given string contains a nostr bridge domain
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if '.nostr.' in message_str or \ | 
					
						
							|  |  |  |        '/nostr.' in message_str: | 
					
						
							|  |  |  |         return True | 
					
						
							|  |  |  |     nostr_domains = get_nostr_domains_list() | 
					
						
							|  |  |  |     for domain_str in nostr_domains: | 
					
						
							|  |  |  |         if domain_str + '"' in message_str or \ | 
					
						
							|  |  |  |            domain_str + '/' in message_str: | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  | def load_federated_blocks_endpoints(base_dir: str) -> []: | 
					
						
							|  |  |  |     """Loads endpoint urls for federated blocklists
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |     block_federated_endpoints: list[str] = [] | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |     block_api_endpoints_filename = \ | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |         data_dir(base_dir) + '/block_api_endpoints.txt' | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |     if os.path.isfile(block_api_endpoints_filename): | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |         new_block_federated_endpoints: list[str] = [] | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             with open(block_api_endpoints_filename, 'r', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_ep: | 
					
						
							| 
									
										
										
										
											2024-02-09 23:33:13 +00:00
										 |  |  |                 new_block_federated_endpoints = fp_ep.read().split('\n') | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: unable to load block_api_endpoints.txt') | 
					
						
							| 
									
										
										
										
											2024-02-09 23:33:13 +00:00
										 |  |  |         for endpoint in new_block_federated_endpoints: | 
					
						
							|  |  |  |             if endpoint: | 
					
						
							|  |  |  |                 if '#' not in endpoint: | 
					
						
							|  |  |  |                     block_federated_endpoints.append(endpoint) | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |     return block_federated_endpoints | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-10 14:49:15 +00:00
										 |  |  | def _valid_federated_blocklist_entry(text: str, domain: str) -> bool: | 
					
						
							| 
									
										
										
										
											2024-02-10 12:11:30 +00:00
										 |  |  |     """is the given blocklist entry valid?
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if ' ' in text or \ | 
					
						
							|  |  |  |        ',' in text or \ | 
					
						
							|  |  |  |        ';' in text or \ | 
					
						
							|  |  |  |        '.' not in text or \ | 
					
						
							|  |  |  |        '<' in text: | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2024-02-10 14:49:15 +00:00
										 |  |  |     if text == domain: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     if text.endswith('@' + domain) or \ | 
					
						
							|  |  |  |        text.endswith('://' + domain): | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2024-02-10 12:11:30 +00:00
										 |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-09 21:00:12 +00:00
										 |  |  | def _update_federated_blocks(session, base_dir: str, | 
					
						
							|  |  |  |                              http_prefix: str, | 
					
						
							| 
									
										
										
										
											2024-02-10 11:16:06 +00:00
										 |  |  |                              domain: str, | 
					
						
							| 
									
										
										
										
											2024-02-09 21:00:12 +00:00
										 |  |  |                              debug: bool, version: str, | 
					
						
							|  |  |  |                              signing_priv_key_pem: str, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                              max_api_blocks: int, | 
					
						
							|  |  |  |                              mitm_servers: []) -> []: | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |     """Creates block_api.txt
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |     block_federated: list[str] = [] | 
					
						
							| 
									
										
										
										
											2024-02-09 23:33:13 +00:00
										 |  |  |     debug = True | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							| 
									
										
										
										
											2024-02-09 22:59:48 +00:00
										 |  |  |         print('WARN: federated blocklist ' + | 
					
						
							|  |  |  |               'no session for update_federated_blocks') | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |         return block_federated | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     headers = { | 
					
						
							|  |  |  |         'Accept': 'application/json' | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     block_federated_endpoints = load_federated_blocks_endpoints(base_dir) | 
					
						
							| 
									
										
										
										
											2024-02-10 11:27:24 +00:00
										 |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: federated blocklist endpoints: ' + | 
					
						
							|  |  |  |               str(block_federated_endpoints)) | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     new_block_api_str = '' | 
					
						
							|  |  |  |     for endpoint in block_federated_endpoints: | 
					
						
							| 
									
										
										
										
											2024-02-09 23:33:13 +00:00
										 |  |  |         if not endpoint: | 
					
						
							|  |  |  |             continue | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |         url = endpoint.strip() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-10 11:27:24 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('federated blocklist Block API endpoint: ' + url) | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |         blocked_json = get_json(signing_priv_key_pem, session, url, headers, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                                 None, debug, mitm_servers, | 
					
						
							|  |  |  |                                 version, http_prefix, domain) | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |         if not get_json_valid(blocked_json): | 
					
						
							| 
									
										
										
										
											2024-02-09 22:59:48 +00:00
										 |  |  |             print('DEBUG: federated blocklist ' + | 
					
						
							| 
									
										
										
										
											2024-02-09 23:33:13 +00:00
										 |  |  |                   'GET blocked json failed ' + url) | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2024-02-10 11:27:24 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: federated blocklist: ' + str(blocked_json)) | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |         if isinstance(blocked_json, list): | 
					
						
							|  |  |  |             # ensure that the size of the list does not become a form of denial | 
					
						
							|  |  |  |             # of service | 
					
						
							|  |  |  |             if len(blocked_json) < max_api_blocks: | 
					
						
							|  |  |  |                 for block_dict in blocked_json: | 
					
						
							| 
									
										
										
										
											2024-02-10 12:11:30 +00:00
										 |  |  |                     if isinstance(block_dict, str): | 
					
						
							|  |  |  |                         # a simple list of strings containing handles | 
					
						
							|  |  |  |                         # or domains | 
					
						
							|  |  |  |                         handle = block_dict | 
					
						
							| 
									
										
										
										
											2024-02-10 12:21:18 +00:00
										 |  |  |                         if handle.startswith('@'): | 
					
						
							|  |  |  |                             handle = handle[1:] | 
					
						
							| 
									
										
										
										
											2024-02-10 14:49:15 +00:00
										 |  |  |                         if _valid_federated_blocklist_entry(handle, | 
					
						
							|  |  |  |                                                             domain): | 
					
						
							| 
									
										
										
										
											2024-02-10 12:21:18 +00:00
										 |  |  |                             if handle not in new_block_api_str: | 
					
						
							|  |  |  |                                 new_block_api_str += handle + '\n' | 
					
						
							| 
									
										
										
										
											2024-02-10 12:11:30 +00:00
										 |  |  |                             if handle not in block_federated: | 
					
						
							|  |  |  |                                 block_federated.append(handle) | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |                     if not isinstance(block_dict, dict): | 
					
						
							|  |  |  |                         continue | 
					
						
							| 
									
										
										
										
											2024-02-10 12:21:18 +00:00
										 |  |  |                     for block_fieldname in ('username', 'domain'): | 
					
						
							|  |  |  |                         if not block_dict.get(block_fieldname): | 
					
						
							|  |  |  |                             continue | 
					
						
							|  |  |  |                         if not isinstance(block_dict[block_fieldname], str): | 
					
						
							|  |  |  |                             continue | 
					
						
							|  |  |  |                         handle = block_dict[block_fieldname] | 
					
						
							|  |  |  |                         if handle.startswith('@'): | 
					
						
							|  |  |  |                             handle = handle[1:] | 
					
						
							| 
									
										
										
										
											2024-02-10 14:49:15 +00:00
										 |  |  |                         if not _valid_federated_blocklist_entry(handle, | 
					
						
							|  |  |  |                                                                 domain): | 
					
						
							| 
									
										
										
										
											2024-02-10 12:21:18 +00:00
										 |  |  |                             continue | 
					
						
							|  |  |  |                         if handle not in new_block_api_str: | 
					
						
							|  |  |  |                             new_block_api_str += handle + '\n' | 
					
						
							|  |  |  |                         if handle not in block_federated: | 
					
						
							|  |  |  |                             block_federated.append(handle) | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     block_api_filename = \ | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |         data_dir(base_dir) + '/block_api.txt' | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |     if not new_block_api_str: | 
					
						
							| 
									
										
										
										
											2024-02-09 22:52:50 +00:00
										 |  |  |         print('DEBUG: federated blocklist not loaded: ' + block_api_filename) | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |         if os.path.isfile(block_api_filename): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 os.remove(block_api_filename) | 
					
						
							|  |  |  |             except OSError: | 
					
						
							|  |  |  |                 print('EX: unable to remove block api: ' + block_api_filename) | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2024-02-09 22:29:07 +00:00
										 |  |  |         print('DEBUG: federated blocklist loaded: ' + str(block_federated)) | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             with open(block_api_filename, 'w+', encoding='utf-8') as fp_api: | 
					
						
							|  |  |  |                 fp_api.write(new_block_api_str) | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: unable to write block_api.txt') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return block_federated | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def save_block_federated_endpoints(base_dir: str, | 
					
						
							|  |  |  |                                    block_federated_endpoints: []) -> []: | 
					
						
							|  |  |  |     """Saves a list of blocking API endpoints
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     block_api_endpoints_filename = \ | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |         data_dir(base_dir) + '/block_api_endpoints.txt' | 
					
						
							| 
									
										
										
										
											2024-12-23 15:39:55 +00:00
										 |  |  |     result: list[str] = [] | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |     block_federated_endpoints_str = '' | 
					
						
							|  |  |  |     for endpoint in block_federated_endpoints: | 
					
						
							|  |  |  |         if not endpoint: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         if '.' not in endpoint or \ | 
					
						
							| 
									
										
										
										
											2024-04-10 12:59:57 +00:00
										 |  |  |            string_contains(endpoint, (' ', '<', ',', ';')): | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |             continue | 
					
						
							|  |  |  |         if endpoint.startswith('@'): | 
					
						
							|  |  |  |             endpoint = endpoint[1:] | 
					
						
							|  |  |  |         if not endpoint: | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         block_federated_endpoints_str += endpoint.strip() + '\n' | 
					
						
							|  |  |  |         result.append(endpoint) | 
					
						
							| 
									
										
										
										
											2024-02-10 10:58:37 +00:00
										 |  |  |     if not block_federated_endpoints_str: | 
					
						
							|  |  |  |         if os.path.isfile(block_api_endpoints_filename): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 os.remove(block_api_endpoints_filename) | 
					
						
							|  |  |  |             except OSError: | 
					
						
							|  |  |  |                 print('EX: unable to delete block_api_endpoints.txt') | 
					
						
							|  |  |  |         block_api_filename = \ | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |             data_dir(base_dir) + '/block_api.txt' | 
					
						
							| 
									
										
										
										
											2024-02-10 10:58:37 +00:00
										 |  |  |         if os.path.isfile(block_api_filename): | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 os.remove(block_api_filename) | 
					
						
							|  |  |  |             except OSError: | 
					
						
							|  |  |  |                 print('EX: unable to delete block_api.txt') | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             with open(block_api_endpoints_filename, 'w+', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_api: | 
					
						
							|  |  |  |                 fp_api.write(block_federated_endpoints_str) | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: unable to write block_api_endpoints.txt') | 
					
						
							| 
									
										
										
										
											2024-02-09 18:39:44 +00:00
										 |  |  |     return result | 
					
						
							| 
									
										
										
										
											2024-02-09 21:00:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def run_federated_blocks_daemon(base_dir: str, httpd, debug: bool) -> None: | 
					
						
							|  |  |  |     """Runs the daemon used to update federated blocks
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-02-10 11:46:57 +00:00
										 |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: federated blocklist 0') | 
					
						
							| 
									
										
										
										
											2024-02-09 21:00:12 +00:00
										 |  |  |     seconds_per_hour = 60 * 60 | 
					
						
							|  |  |  |     time.sleep(60) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     session = None | 
					
						
							|  |  |  |     while True: | 
					
						
							| 
									
										
										
										
											2024-02-10 11:46:57 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: federated blocklist 1') | 
					
						
							| 
									
										
										
										
											2024-02-09 21:00:12 +00:00
										 |  |  |         if httpd.session: | 
					
						
							|  |  |  |             session = httpd.session | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             session = create_session(httpd.proxy_type) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if session: | 
					
						
							| 
									
										
										
										
											2024-02-10 11:46:57 +00:00
										 |  |  |             if debug: | 
					
						
							|  |  |  |                 print('DEBUG: federated blocklist 2') | 
					
						
							| 
									
										
										
										
											2024-02-09 21:00:12 +00:00
										 |  |  |             httpd.block_federated = \ | 
					
						
							|  |  |  |                 _update_federated_blocks(httpd.session, base_dir, | 
					
						
							|  |  |  |                                          httpd.http_prefix, | 
					
						
							| 
									
										
										
										
											2024-02-10 11:16:06 +00:00
										 |  |  |                                          httpd.domain, | 
					
						
							| 
									
										
										
										
											2024-02-09 21:00:12 +00:00
										 |  |  |                                          debug, httpd.project_version, | 
					
						
							|  |  |  |                                          httpd.signing_priv_key_pem, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                                          httpd.max_api_blocks, | 
					
						
							|  |  |  |                                          httpd.mitm_servers) | 
					
						
							| 
									
										
										
										
											2024-02-09 21:00:12 +00:00
										 |  |  |         time.sleep(seconds_per_hour * 6) | 
					
						
							| 
									
										
										
										
											2024-12-24 18:17:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def sending_is_blocked2(base_dir: str, nickname: str, domain: str, | 
					
						
							|  |  |  |                         to_domain: str, to_actor: str) -> bool: | 
					
						
							|  |  |  |     """is sending to the given actor blocked?
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not to_domain: | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     send_block_filename = \ | 
					
						
							|  |  |  |         acct_dir(base_dir, nickname, domain) + '/send_blocks.txt' | 
					
						
							|  |  |  |     if not os.path.isfile(send_block_filename): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     send_blocked = False | 
					
						
							|  |  |  |     if text_in_file(to_actor, send_block_filename, False): | 
					
						
							|  |  |  |         send_blocked = True | 
					
						
							|  |  |  |     elif text_in_file('://' + to_domain + '\n', send_block_filename, False): | 
					
						
							|  |  |  |         send_blocked = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return send_blocked |