| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | __filename__ = "follow.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							| 
									
										
										
										
											2024-12-22 23:37:30 +00:00
										 |  |  | __version__ = "1.6.0" | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							| 
									
										
										
										
											2021-09-10 16:14:50 +00:00
										 |  |  | __email__ = "bob@libreserver.org" | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | __status__ = "Production" | 
					
						
							| 
									
										
										
										
											2021-06-15 15:08:12 +00:00
										 |  |  | __module_group__ = "ActivityPub" | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-29 18:23:13 +00:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2023-03-17 21:13:43 +00:00
										 |  |  | from pprint import pprint | 
					
						
							| 
									
										
										
										
											2024-09-13 13:58:14 +00:00
										 |  |  | from flags import has_group_type | 
					
						
							| 
									
										
										
										
											2023-03-15 23:11:40 +00:00
										 |  |  | from utils import get_user_paths | 
					
						
							| 
									
										
										
										
											2022-12-18 15:29:54 +00:00
										 |  |  | from utils import acct_handle_dir | 
					
						
							| 
									
										
										
										
											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 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-28 14:41:10 +00:00
										 |  |  | from utils import valid_nickname | 
					
						
							| 
									
										
										
										
											2021-12-27 18:28:26 +00:00
										 |  |  | from utils import domain_permitted | 
					
						
							| 
									
										
										
										
											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-27 17:42:35 +00:00
										 |  |  | from utils import get_status_number | 
					
						
							| 
									
										
										
										
											2021-12-27 17:08:19 +00:00
										 |  |  | from utils import follow_person | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | from posts import send_signed_json | 
					
						
							|  |  |  | from posts import get_person_box | 
					
						
							| 
									
										
										
										
											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-26 18:46:43 +00:00
										 |  |  | from utils import is_account_dir | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2022-06-10 11:43:33 +00:00
										 |  |  | from utils import text_in_file | 
					
						
							| 
									
										
										
										
											2022-06-21 11:58:50 +00:00
										 |  |  | from utils import remove_eol | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  | from utils import get_actor_from_post | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  | from utils import data_dir | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | from acceptreject import create_accept | 
					
						
							|  |  |  | from acceptreject import create_reject | 
					
						
							|  |  |  | from webfinger import webfinger_handle | 
					
						
							| 
									
										
										
										
											2021-12-28 21:36:27 +00:00
										 |  |  | from auth import create_basic_auth_header | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | from session import get_json | 
					
						
							| 
									
										
										
										
											2023-08-13 09:58:02 +00:00
										 |  |  | from session import get_json_valid | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | from session import post_json | 
					
						
							| 
									
										
										
										
											2023-03-18 21:06:10 +00:00
										 |  |  | from followerSync import remove_followers_sync | 
					
						
							| 
									
										
										
										
											2019-06-29 18:23:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  | def create_initial_last_seen(base_dir: str, http_prefix: str) -> None: | 
					
						
							| 
									
										
										
										
											2021-06-07 08:59:43 +00:00
										 |  |  |     """Creates initial lastseen files for all follows.
 | 
					
						
							|  |  |  |     The lastseen files are used to generate the Zzz icons on | 
					
						
							|  |  |  |     follows/following lists on the profile screen. | 
					
						
							| 
									
										
										
										
											2020-12-13 22:01:10 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     dir_str = data_dir(base_dir) | 
					
						
							|  |  |  |     for _, dirs, _ in os.walk(dir_str): | 
					
						
							| 
									
										
										
										
											2020-12-13 22:01:10 +00:00
										 |  |  |         for acct in dirs: | 
					
						
							| 
									
										
										
										
											2021-12-26 18:46:43 +00:00
										 |  |  |             if not is_account_dir(acct): | 
					
						
							| 
									
										
										
										
											2020-12-13 22:01:10 +00:00
										 |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |             account_dir = os.path.join(dir_str, acct) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             following_filename = account_dir + '/following.txt' | 
					
						
							|  |  |  |             if not os.path.isfile(following_filename): | 
					
						
							| 
									
										
										
										
											2020-12-13 22:01:10 +00:00
										 |  |  |                 continue | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             last_seen_dir = account_dir + '/lastseen' | 
					
						
							|  |  |  |             if not os.path.isdir(last_seen_dir): | 
					
						
							|  |  |  |                 os.mkdir(last_seen_dir) | 
					
						
							| 
									
										
										
										
											2024-12-23 17:45:20 +00:00
										 |  |  |             following_handles: list[str] = [] | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |                 with open(following_filename, 'r', | 
					
						
							|  |  |  |                           encoding='utf-8') as fp_foll: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                     following_handles = fp_foll.readlines() | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 print('EX: create_initial_last_seen ' + following_filename) | 
					
						
							|  |  |  |             for handle in following_handles: | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |                 if '#' in handle: | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 if '@' not in handle: | 
					
						
							|  |  |  |                     continue | 
					
						
							| 
									
										
										
										
											2022-06-21 11:58:50 +00:00
										 |  |  |                 handle = remove_eol(handle) | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |                 nickname = handle.split('@')[0] | 
					
						
							|  |  |  |                 domain = handle.split('@')[1] | 
					
						
							|  |  |  |                 if nickname.startswith('!'): | 
					
						
							|  |  |  |                     nickname = nickname[1:] | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  |                 actor = local_actor_url(http_prefix, nickname, domain) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 last_seen_filename = \ | 
					
						
							|  |  |  |                     last_seen_dir + '/' + actor.replace('/', '#') + '.txt' | 
					
						
							| 
									
										
										
										
											2024-07-11 14:02:03 +00:00
										 |  |  |                 if os.path.isfile(last_seen_filename): | 
					
						
							|  |  |  |                     continue | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     with open(last_seen_filename, 'w+', | 
					
						
							|  |  |  |                               encoding='utf-8') as fp_last: | 
					
						
							|  |  |  |                         fp_last.write(str(100)) | 
					
						
							|  |  |  |                 except OSError: | 
					
						
							|  |  |  |                     print('EX: create_initial_last_seen 2 ' + | 
					
						
							|  |  |  |                           last_seen_filename) | 
					
						
							| 
									
										
										
										
											2020-12-13 22:01:10 +00:00
										 |  |  |         break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def _pre_approved_follower(base_dir: str, | 
					
						
							|  |  |  |                            nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                            approve_handle: str) -> bool: | 
					
						
							| 
									
										
										
										
											2019-12-31 09:23:41 +00:00
										 |  |  |     """Is the given handle an already manually approved follower?
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-09-10 09:24:13 +00:00
										 |  |  |     account_dir = acct_dir(base_dir, nickname, domain) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     approved_filename = account_dir + '/approved.txt' | 
					
						
							|  |  |  |     if os.path.isfile(approved_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 13:01:39 +00:00
										 |  |  |         if text_in_file(approve_handle, approved_filename): | 
					
						
							| 
									
										
										
										
											2019-12-31 09:23:41 +00:00
										 |  |  |             return True | 
					
						
							|  |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def _remove_from_follow_base(base_dir: str, | 
					
						
							|  |  |  |                              nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                              accept_or_deny_handle: str, follow_file: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                              debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2021-03-12 10:44:37 +00:00
										 |  |  |     """Removes a handle/actor from follow requests or rejects file
 | 
					
						
							| 
									
										
										
										
											2019-09-18 17:04:19 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-09-10 09:24:13 +00:00
										 |  |  |     accounts_dir = acct_dir(base_dir, nickname, domain) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     approve_follows_filename = accounts_dir + '/' + follow_file + '.txt' | 
					
						
							|  |  |  |     if not os.path.isfile(approve_follows_filename): | 
					
						
							| 
									
										
										
										
											2019-09-18 17:04:19 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2022-03-13 12:09:52 +00:00
										 |  |  |             print('There is no ' + follow_file + | 
					
						
							| 
									
										
										
										
											2022-09-10 09:24:13 +00:00
										 |  |  |                   ' to remove ' + nickname + '@' + domain + ' from') | 
					
						
							| 
									
										
										
										
											2019-09-18 17:04:19 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     accept_deny_actor = None | 
					
						
							| 
									
										
										
										
											2022-06-10 11:43:33 +00:00
										 |  |  |     if not text_in_file(accept_or_deny_handle, approve_follows_filename): | 
					
						
							| 
									
										
										
										
											2021-03-12 10:44:37 +00:00
										 |  |  |         # is this stored in the file as an actor rather than a handle? | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         accept_deny_nickname = accept_or_deny_handle.split('@')[0] | 
					
						
							|  |  |  |         accept_deny_domain = accept_or_deny_handle.split('@')[1] | 
					
						
							| 
									
										
										
										
											2021-03-12 10:44:37 +00:00
										 |  |  |         # for each possible users path construct an actor and | 
					
						
							| 
									
										
										
										
											2024-02-27 11:38:09 +00:00
										 |  |  |         # check if it exists in the file | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         users_paths = get_user_paths() | 
					
						
							|  |  |  |         actor_found = False | 
					
						
							|  |  |  |         for users_name in users_paths: | 
					
						
							|  |  |  |             accept_deny_actor = \ | 
					
						
							|  |  |  |                 '://' + accept_deny_domain + users_name + accept_deny_nickname | 
					
						
							| 
									
										
										
										
											2022-06-10 13:01:39 +00:00
										 |  |  |             if text_in_file(accept_deny_actor, approve_follows_filename): | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 actor_found = True | 
					
						
							| 
									
										
										
										
											2021-03-12 10:44:37 +00:00
										 |  |  |                 break | 
					
						
							| 
									
										
										
										
											2023-05-10 11:53:38 +00:00
										 |  |  |         if not actor_found: | 
					
						
							|  |  |  |             accept_deny_actor = \ | 
					
						
							|  |  |  |                 '://' + accept_deny_domain + '/' + accept_deny_nickname | 
					
						
							|  |  |  |             if text_in_file(accept_deny_actor, approve_follows_filename): | 
					
						
							|  |  |  |                 actor_found = True | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         if not actor_found: | 
					
						
							| 
									
										
										
										
											2021-03-12 10:44:37 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |         with open(approve_follows_filename + '.new', 'w+', | 
					
						
							| 
									
										
										
										
											2024-07-16 12:20:58 +00:00
										 |  |  |                   encoding='utf-8') as fp_approve_new: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |             with open(approve_follows_filename, 'r', | 
					
						
							| 
									
										
										
										
											2024-07-16 11:21:28 +00:00
										 |  |  |                       encoding='utf-8') as fp_approve: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 if not accept_deny_actor: | 
					
						
							| 
									
										
										
										
											2024-07-16 11:21:28 +00:00
										 |  |  |                     for approve_handle in fp_approve: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                         accept_deny_handle = accept_or_deny_handle | 
					
						
							|  |  |  |                         if not approve_handle.startswith(accept_deny_handle): | 
					
						
							| 
									
										
										
										
											2024-07-16 12:20:58 +00:00
										 |  |  |                             fp_approve_new.write(approve_handle) | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2024-07-16 11:21:28 +00:00
										 |  |  |                     for approve_handle in fp_approve: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                         if accept_deny_actor not in approve_handle: | 
					
						
							| 
									
										
										
										
											2024-07-16 12:20:58 +00:00
										 |  |  |                             fp_approve_new.write(approve_handle) | 
					
						
							| 
									
										
										
										
											2021-12-25 15:28:52 +00:00
										 |  |  |     except OSError as ex: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('EX: _remove_from_follow_base ' + | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |               approve_follows_filename + ' ' + str(ex)) | 
					
						
							| 
									
										
										
										
											2021-06-22 12:27:10 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     os.rename(approve_follows_filename + '.new', approve_follows_filename) | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-18 17:04:19 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def remove_from_follow_requests(base_dir: str, | 
					
						
							|  |  |  |                                 nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                                 deny_handle: str, debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2019-10-06 09:48:37 +00:00
										 |  |  |     """Removes a handle from follow requests
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |     _remove_from_follow_base(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                              deny_handle, 'followrequests', debug) | 
					
						
							| 
									
										
										
										
											2019-10-06 09:48:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def _remove_from_follow_rejects(base_dir: str, | 
					
						
							|  |  |  |                                 nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                                 accept_handle: str, debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2019-10-06 09:48:37 +00:00
										 |  |  |     """Removes a handle from follow rejects
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |     _remove_from_follow_base(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                              accept_handle, 'followrejects', debug) | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-06 09:48:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  | def is_following_actor(base_dir: str, | 
					
						
							|  |  |  |                        nickname: str, domain: str, actor: str) -> bool: | 
					
						
							| 
									
										
										
										
											2020-07-14 09:09:33 +00:00
										 |  |  |     """Is the given nickname following the given actor?
 | 
					
						
							| 
									
										
										
										
											2021-02-24 09:54:37 +00:00
										 |  |  |     The actor can also be a handle: nickname@domain | 
					
						
							| 
									
										
										
										
											2019-07-29 19:46:30 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2022-09-10 09:24:13 +00:00
										 |  |  |     accounts_dir = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     if not os.path.isdir(accounts_dir): | 
					
						
							| 
									
										
										
										
											2019-07-29 19:46:30 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-09-10 09:24:13 +00:00
										 |  |  |     following_file = accounts_dir + '/following.txt' | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not os.path.isfile(following_file): | 
					
						
							| 
									
										
										
										
											2019-07-29 19:46:30 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-02-13 10:55:01 +00:00
										 |  |  |     if actor.startswith('@'): | 
					
						
							|  |  |  |         actor = actor[1:] | 
					
						
							| 
									
										
										
										
											2022-06-10 13:01:39 +00:00
										 |  |  |     if text_in_file(actor, following_file, False): | 
					
						
							| 
									
										
										
										
											2019-07-29 19:46:30 +00:00
										 |  |  |         return True | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     following_nickname = get_nickname_from_actor(actor) | 
					
						
							|  |  |  |     if not following_nickname: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         print('WARN: unable to find nickname in ' + actor) | 
					
						
							| 
									
										
										
										
											2019-09-02 09:43:43 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     following_domain, following_port = get_domain_from_actor(actor) | 
					
						
							| 
									
										
										
										
											2023-01-15 14:33:18 +00:00
										 |  |  |     if not following_domain: | 
					
						
							|  |  |  |         print('WARN: unable to find domain in ' + actor) | 
					
						
							|  |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     following_handle = \ | 
					
						
							|  |  |  |         get_full_domain(following_nickname + '@' + following_domain, | 
					
						
							|  |  |  |                         following_port) | 
					
						
							| 
									
										
										
										
											2022-06-10 13:01:39 +00:00
										 |  |  |     if text_in_file(following_handle, following_file, False): | 
					
						
							| 
									
										
										
										
											2019-07-29 19:46:30 +00:00
										 |  |  |         return True | 
					
						
							|  |  |  |     return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def add_follower_of_person(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                            follower_nickname: str, follower_domain: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                            federation_list: [], debug: bool, | 
					
						
							|  |  |  |                            group_account: bool) -> bool: | 
					
						
							| 
									
										
										
										
											2019-06-29 21:13:44 +00:00
										 |  |  |     """Adds a follower of the given person
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-27 17:08:19 +00:00
										 |  |  |     return follow_person(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                          follower_nickname, follower_domain, | 
					
						
							| 
									
										
										
										
											2021-12-27 17:08:19 +00:00
										 |  |  |                          federation_list, debug, group_account, | 
					
						
							|  |  |  |                          'followers.txt') | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-29 18:23:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def get_follower_domains(base_dir: str, nickname: str, domain: str) -> []: | 
					
						
							| 
									
										
										
										
											2021-11-08 14:49:18 +00:00
										 |  |  |     """Returns a list of domains for followers
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     followers_file = acct_dir(base_dir, nickname, domain) + '/followers.txt' | 
					
						
							|  |  |  |     if not os.path.isfile(followers_file): | 
					
						
							| 
									
										
										
										
											2021-11-08 14:49:18 +00:00
										 |  |  |         return [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 17:45:20 +00:00
										 |  |  |     lines: list[str] = [] | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |         with open(followers_file, 'r', encoding='utf-8') as fp_foll: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             lines = fp_foll.readlines() | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         print('EX: get_follower_domains ' + followers_file) | 
					
						
							| 
									
										
										
										
											2021-11-08 14:49:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-23 17:45:20 +00:00
										 |  |  |     domains_list: list[str] = [] | 
					
						
							| 
									
										
										
										
											2021-11-08 14:49:18 +00:00
										 |  |  |     for handle in lines: | 
					
						
							| 
									
										
										
										
											2022-06-21 11:58:50 +00:00
										 |  |  |         handle = remove_eol(handle) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         follower_domain, _ = get_domain_from_actor(handle) | 
					
						
							|  |  |  |         if not follower_domain: | 
					
						
							| 
									
										
										
										
											2021-11-08 14:49:18 +00:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         if follower_domain not in domains_list: | 
					
						
							|  |  |  |             domains_list.append(follower_domain) | 
					
						
							|  |  |  |     return domains_list | 
					
						
							| 
									
										
										
										
											2021-11-08 14:49:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def is_follower_of_person(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                           follower_nickname: str, | 
					
						
							|  |  |  |                           follower_domain: str) -> bool: | 
					
						
							|  |  |  |     """is the given nickname a follower of follower_nickname?
 | 
					
						
							| 
									
										
										
										
											2019-08-31 15:17:07 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not follower_domain: | 
					
						
							|  |  |  |         print('No follower_domain') | 
					
						
							| 
									
										
										
										
											2021-09-13 13:41:29 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not follower_nickname: | 
					
						
							|  |  |  |         print('No follower_nickname for ' + follower_domain) | 
					
						
							| 
									
										
										
										
											2021-09-13 13:41:29 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     followers_file = acct_dir(base_dir, nickname, domain) + '/followers.txt' | 
					
						
							|  |  |  |     if not os.path.isfile(followers_file): | 
					
						
							| 
									
										
										
										
											2019-08-31 15:17:07 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     handle = follower_nickname + '@' + follower_domain | 
					
						
							| 
									
										
										
										
											2020-10-24 09:58:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     already_following = False | 
					
						
							| 
									
										
										
										
											2020-10-24 09:58:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     followers_str = '' | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |         with open(followers_file, 'r', encoding='utf-8') as fp_foll: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             followers_str = fp_foll.read() | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         print('EX: is_follower_of_person ' + followers_file) | 
					
						
							| 
									
										
										
										
											2020-10-24 09:58:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if handle in followers_str: | 
					
						
							|  |  |  |         already_following = True | 
					
						
							| 
									
										
										
										
											2021-07-03 17:51:58 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2021-12-26 12:24:40 +00:00
										 |  |  |         paths = get_user_paths() | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         for user_path in paths: | 
					
						
							|  |  |  |             url = '://' + follower_domain + user_path + follower_nickname | 
					
						
							|  |  |  |             if url in followers_str: | 
					
						
							|  |  |  |                 already_following = True | 
					
						
							| 
									
										
										
										
											2021-07-03 17:51:58 +00:00
										 |  |  |                 break | 
					
						
							| 
									
										
										
										
											2023-05-10 11:53:38 +00:00
										 |  |  |         if not already_following: | 
					
						
							|  |  |  |             url = '://' + follower_domain + '/' + follower_nickname | 
					
						
							|  |  |  |             if url in followers_str: | 
					
						
							|  |  |  |                 already_following = True | 
					
						
							| 
									
										
										
										
											2020-10-24 09:58:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     return already_following | 
					
						
							| 
									
										
										
										
											2019-08-31 15:17:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  | def unfollow_account(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                      follow_nickname: str, follow_domain: str, | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  |                      debug: bool, group_account: bool, | 
					
						
							| 
									
										
										
										
											2024-02-19 15:38:08 +00:00
										 |  |  |                      follow_file: str) -> bool: | 
					
						
							| 
									
										
										
										
											2019-06-29 18:23:13 +00:00
										 |  |  |     """Removes a person to the follow list
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |     handle = nickname + '@' + domain | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     handle_to_unfollow = follow_nickname + '@' + follow_domain | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |     if group_account: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         handle_to_unfollow = '!' + handle_to_unfollow | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     dir_str = data_dir(base_dir) | 
					
						
							|  |  |  |     if not os.path.isdir(dir_str): | 
					
						
							|  |  |  |         os.mkdir(dir_str) | 
					
						
							| 
									
										
										
										
											2022-12-18 15:29:54 +00:00
										 |  |  |     handle_dir = acct_handle_dir(base_dir, handle) | 
					
						
							|  |  |  |     if not os.path.isdir(handle_dir): | 
					
						
							|  |  |  |         os.mkdir(handle_dir) | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-10 09:24:13 +00:00
										 |  |  |     accounts_dir = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     filename = accounts_dir + '/' + follow_file | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |     if not os.path.isfile(filename): | 
					
						
							| 
									
										
										
										
											2019-07-17 11:54:13 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |             print('DEBUG: follow file ' + filename + ' was not found') | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     handle_to_unfollow_lower = handle_to_unfollow.lower() | 
					
						
							| 
									
										
										
										
											2022-06-10 11:43:33 +00:00
										 |  |  |     if not text_in_file(handle_to_unfollow_lower, filename, False): | 
					
						
							| 
									
										
										
										
											2019-07-17 11:54:13 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             print('DEBUG: handle to unfollow ' + handle_to_unfollow + | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |                   ' is not in ' + filename) | 
					
						
							| 
									
										
										
										
											2024-05-24 12:50:11 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2024-12-23 17:45:20 +00:00
										 |  |  |     lines: list[str] = [] | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |         with open(filename, 'r', encoding='utf-8') as fp_unfoll: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             lines = fp_unfoll.readlines() | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  |         print('EX: unfollow_account ' + filename) | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     if lines: | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |             with open(filename, 'w+', encoding='utf-8') as fp_unfoll: | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |                 for line in lines: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                     check_handle = line.strip("\n").strip("\r").lower() | 
					
						
							|  |  |  |                     if check_handle not in (handle_to_unfollow_lower, | 
					
						
							|  |  |  |                                             '!' + handle_to_unfollow_lower): | 
					
						
							|  |  |  |                         fp_unfoll.write(line) | 
					
						
							| 
									
										
										
										
											2021-12-25 15:28:52 +00:00
										 |  |  |         except OSError as ex: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |             print('EX: unfollow_account unable to write ' + | 
					
						
							|  |  |  |                   filename + ' ' + str(ex)) | 
					
						
							| 
									
										
										
										
											2020-02-22 10:50:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # write to an unfollowed file so that if a follow accept | 
					
						
							|  |  |  |     # later arrives then it can be ignored | 
					
						
							| 
									
										
										
										
											2022-09-10 09:24:13 +00:00
										 |  |  |     unfollowed_filename = accounts_dir + '/unfollowed.txt' | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if os.path.isfile(unfollowed_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 13:29:51 +00:00
										 |  |  |         if not text_in_file(handle_to_unfollow_lower, | 
					
						
							|  |  |  |                             unfollowed_filename, False): | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |                 with open(unfollowed_filename, 'a+', | 
					
						
							|  |  |  |                           encoding='utf-8') as fp_unfoll: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                     fp_unfoll.write(handle_to_unfollow + '\n') | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |                 print('EX: unfollow_account unable to append ' + | 
					
						
							|  |  |  |                       unfollowed_filename) | 
					
						
							| 
									
										
										
										
											2020-02-22 10:50:07 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |             with open(unfollowed_filename, 'w+', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_unfoll: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 fp_unfoll.write(handle_to_unfollow + '\n') | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |             print('EX: unfollow_account unable to write ' + | 
					
						
							|  |  |  |                   unfollowed_filename) | 
					
						
							| 
									
										
										
										
											2020-02-22 10:50:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-30 21:44:16 +00:00
										 |  |  |     return True | 
					
						
							| 
									
										
										
										
											2019-06-29 18:23:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def unfollower_of_account(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                           follower_nickname: str, follower_domain: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                           debug: bool, group_account: bool) -> bool: | 
					
						
							| 
									
										
										
										
											2019-06-29 21:13:44 +00:00
										 |  |  |     """Remove a follower of a person
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  |     return unfollow_account(base_dir, nickname, domain, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                             follower_nickname, follower_domain, | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  |                             debug, group_account, 'followers.txt') | 
					
						
							| 
									
										
										
										
											2019-06-29 18:23:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def clear_follows(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2024-02-19 15:38:08 +00:00
										 |  |  |                   follow_file: str) -> None: | 
					
						
							| 
									
										
										
										
											2019-06-29 18:23:13 +00:00
										 |  |  |     """Removes all follows
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     dir_str = data_dir(base_dir) | 
					
						
							|  |  |  |     if not os.path.isdir(dir_str): | 
					
						
							|  |  |  |         os.mkdir(dir_str) | 
					
						
							| 
									
										
										
										
											2022-09-10 09:24:13 +00:00
										 |  |  |     accounts_dir = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     if not os.path.isdir(accounts_dir): | 
					
						
							|  |  |  |         os.mkdir(accounts_dir) | 
					
						
							|  |  |  |     filename = accounts_dir + '/' + follow_file | 
					
						
							| 
									
										
										
										
											2019-06-29 18:23:13 +00:00
										 |  |  |     if os.path.isfile(filename): | 
					
						
							| 
									
										
										
										
											2021-09-05 10:17:43 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             os.remove(filename) | 
					
						
							| 
									
										
										
										
											2021-11-25 18:42:38 +00:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |             print('EX: clear_follows unable to delete ' + filename) | 
					
						
							| 
									
										
										
										
											2019-06-29 18:23:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def clear_followers(base_dir: str, nickname: str, domain: str) -> None: | 
					
						
							| 
									
										
										
										
											2019-06-29 21:13:44 +00:00
										 |  |  |     """Removes all followers
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |     clear_follows(base_dir, nickname, domain, 'followers.txt') | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def _get_no_of_follows(base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                        follow_file='following.txt') -> int: | 
					
						
							| 
									
										
										
										
											2019-06-29 21:13:44 +00:00
										 |  |  |     """Returns the number of follows or followers
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2019-07-19 08:40:51 +00:00
										 |  |  |     # only show number of followers to authenticated | 
					
						
							|  |  |  |     # account holders | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |     # if not authenticated: | 
					
						
							|  |  |  |     #     return 9999 | 
					
						
							| 
									
										
										
										
											2022-09-10 09:24:13 +00:00
										 |  |  |     accounts_dir = acct_dir(base_dir, nickname, domain) | 
					
						
							|  |  |  |     filename = accounts_dir + '/' + follow_file | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |     if not os.path.isfile(filename): | 
					
						
							|  |  |  |         return 0 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |     ctr = 0 | 
					
						
							| 
									
										
										
										
											2024-12-23 17:45:20 +00:00
										 |  |  |     lines: list[str] = [] | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |         with open(filename, 'r', encoding='utf-8') as fp_foll: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             lines = fp_foll.readlines() | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('EX: _get_no_of_follows ' + filename) | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     if lines: | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |         for line in lines: | 
					
						
							| 
									
										
										
										
											2020-10-23 19:48:59 +00:00
										 |  |  |             if '#' in line: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if '@' in line and \ | 
					
						
							|  |  |  |                '.' in line and \ | 
					
						
							|  |  |  |                not line.startswith('http'): | 
					
						
							|  |  |  |                 ctr += 1 | 
					
						
							| 
									
										
										
										
											2020-10-24 11:07:22 +00:00
										 |  |  |             elif ((line.startswith('http') or | 
					
						
							| 
									
										
										
										
											2022-04-29 13:54:13 +00:00
										 |  |  |                    line.startswith('ipfs') or | 
					
						
							|  |  |  |                    line.startswith('ipns') or | 
					
						
							| 
									
										
										
										
											2021-07-01 17:59:24 +00:00
										 |  |  |                    line.startswith('hyper')) and | 
					
						
							| 
									
										
										
										
											2021-12-26 12:19:00 +00:00
										 |  |  |                   has_users_path(line)): | 
					
						
							| 
									
										
										
										
											2020-10-23 19:48:59 +00:00
										 |  |  |                 ctr += 1 | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |     return ctr | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-01 14:26:50 +00:00
										 |  |  | def get_no_of_followers(base_dir: str, nickname: str, domain: str) -> int: | 
					
						
							| 
									
										
										
										
											2019-06-29 21:13:44 +00:00
										 |  |  |     """Returns the number of followers of the given person
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-06-01 14:26:50 +00:00
										 |  |  |     return _get_no_of_follows(base_dir, nickname, domain, 'followers.txt') | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  | def get_following_feed(base_dir: str, domain: str, port: int, path: str, | 
					
						
							|  |  |  |                        http_prefix: str, authorized: bool, | 
					
						
							|  |  |  |                        follows_per_page=12, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                        follow_file='following') -> {}: | 
					
						
							| 
									
										
										
										
											2020-10-24 09:28:21 +00:00
										 |  |  |     """Returns the following and followers feeds from GET requests.
 | 
					
						
							|  |  |  |     This accesses the following.txt or followers.txt and builds a collection. | 
					
						
							| 
									
										
										
										
											2019-06-29 21:13:44 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-03-24 13:15:43 +00:00
										 |  |  |     # Show a small number of follows to non-authorized viewers | 
					
						
							|  |  |  |     if not authorized: | 
					
						
							| 
									
										
										
										
											2021-12-28 16:00:24 +00:00
										 |  |  |         follows_per_page = 6 | 
					
						
							| 
									
										
										
										
											2019-07-19 08:40:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if '/' + follow_file not in path: | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |         return None | 
					
						
							|  |  |  |     # handle page numbers | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     header_only = True | 
					
						
							|  |  |  |     page_number = None | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |     if '?page=' in path: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         page_number = path.split('?page=')[1] | 
					
						
							| 
									
										
										
										
											2022-09-08 10:34:12 +00:00
										 |  |  |         if len(page_number) > 5: | 
					
						
							|  |  |  |             page_number = "1" | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         if page_number == 'true' or not authorized: | 
					
						
							|  |  |  |             page_number = 1 | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             try: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 page_number = int(page_number) | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |             except BaseException: | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  |                 print('EX: get_following_feed unable to convert to int ' + | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                       str(page_number)) | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         path = path.split('?page=')[0] | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         header_only = False | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not path.endswith('/' + follow_file): | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |     nickname = None | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |     if path.startswith('/users/'): | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         nickname = \ | 
					
						
							|  |  |  |             path.replace('/users/', '', 1).replace('/' + follow_file, '') | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |     if path.startswith('/@'): | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         nickname = path.replace('/@', '', 1).replace('/' + follow_file, '') | 
					
						
							| 
									
										
										
										
											2019-07-03 09:40:27 +00:00
										 |  |  |     if not nickname: | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-12-28 14:41:10 +00:00
										 |  |  |     if not valid_nickname(domain, nickname): | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2019-08-16 20:35:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |     domain = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2019-06-30 19:01:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if header_only: | 
					
						
							|  |  |  |         first_str = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  |             local_actor_url(http_prefix, nickname, domain) + \ | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             '/' + follow_file + '?page=1' | 
					
						
							|  |  |  |         id_str = \ | 
					
						
							|  |  |  |             local_actor_url(http_prefix, nickname, domain) + '/' + follow_file | 
					
						
							|  |  |  |         total_str = \ | 
					
						
							| 
									
										
										
										
											2022-06-01 14:26:50 +00:00
										 |  |  |             _get_no_of_follows(base_dir, nickname, domain) | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         following = { | 
					
						
							| 
									
										
										
										
											2024-09-14 16:40:11 +00:00
										 |  |  |             "@context": [ | 
					
						
							|  |  |  |                 'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |                 'https://w3id.org/security/v1' | 
					
						
							|  |  |  |             ], | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             'first': first_str, | 
					
						
							|  |  |  |             'id': id_str, | 
					
						
							|  |  |  |             'totalItems': total_str, | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |             'type': 'OrderedCollection' | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |         return following | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not page_number: | 
					
						
							|  |  |  |         page_number = 1 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     next_page_number = int(page_number + 1) | 
					
						
							|  |  |  |     id_str = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  |         local_actor_url(http_prefix, nickname, domain) + \ | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         '/' + follow_file + '?page=' + str(page_number) | 
					
						
							|  |  |  |     part_of_str = \ | 
					
						
							|  |  |  |         local_actor_url(http_prefix, nickname, domain) + '/' + follow_file | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |     following = { | 
					
						
							| 
									
										
										
										
											2024-09-14 16:40:11 +00:00
										 |  |  |         "@context": [ | 
					
						
							|  |  |  |             'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |             'https://w3id.org/security/v1' | 
					
						
							|  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'id': id_str, | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |         'orderedItems': [], | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'partOf': part_of_str, | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |         'totalItems': 0, | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |         'type': 'OrderedCollectionPage' | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     handle_domain = domain | 
					
						
							|  |  |  |     handle_domain = remove_domain_port(handle_domain) | 
					
						
							| 
									
										
										
										
											2022-09-10 09:24:13 +00:00
										 |  |  |     accounts_dir = acct_dir(base_dir, nickname, handle_domain) | 
					
						
							|  |  |  |     filename = accounts_dir + '/' + follow_file + '.txt' | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |     if not os.path.isfile(filename): | 
					
						
							|  |  |  |         return following | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     curr_page = 1 | 
					
						
							|  |  |  |     page_ctr = 0 | 
					
						
							|  |  |  |     total_ctr = 0 | 
					
						
							| 
									
										
										
										
											2024-12-23 17:45:20 +00:00
										 |  |  |     lines: list[str] = [] | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |         with open(filename, 'r', encoding='utf-8') as fp_foll: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             lines = fp_foll.readlines() | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  |         print('EX: get_following_feed ' + filename) | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     for line in lines: | 
					
						
							|  |  |  |         if '#' not in line: | 
					
						
							|  |  |  |             if '@' in line and not line.startswith('http'): | 
					
						
							|  |  |  |                 # nickname@domain | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 page_ctr += 1 | 
					
						
							|  |  |  |                 total_ctr += 1 | 
					
						
							|  |  |  |                 if curr_page == page_number: | 
					
						
							| 
									
										
										
										
											2022-06-21 11:58:50 +00:00
										 |  |  |                     line2_lower = line.lower() | 
					
						
							|  |  |  |                     line2 = remove_eol(line2_lower) | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |                     nick = line2.split('@')[0] | 
					
						
							|  |  |  |                     dom = line2.split('@')[1] | 
					
						
							|  |  |  |                     if not nick.startswith('!'): | 
					
						
							|  |  |  |                         # person actor | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  |                         url = local_actor_url(http_prefix, nick, dom) | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |                     else: | 
					
						
							|  |  |  |                         # group actor | 
					
						
							| 
									
										
										
										
											2021-12-25 17:09:22 +00:00
										 |  |  |                         url = http_prefix + '://' + dom + '/c/' + nick | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |                     following['orderedItems'].append(url) | 
					
						
							|  |  |  |             elif ((line.startswith('http') or | 
					
						
							| 
									
										
										
										
											2022-04-29 13:54:13 +00:00
										 |  |  |                    line.startswith('ipfs') or | 
					
						
							|  |  |  |                    line.startswith('ipns') or | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |                    line.startswith('hyper')) and | 
					
						
							| 
									
										
										
										
											2021-12-26 12:19:00 +00:00
										 |  |  |                   has_users_path(line)): | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |                 # https://domain/users/nickname | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 page_ctr += 1 | 
					
						
							|  |  |  |                 total_ctr += 1 | 
					
						
							|  |  |  |                 if curr_page == page_number: | 
					
						
							| 
									
										
										
										
											2022-06-21 11:58:50 +00:00
										 |  |  |                     append_str1 = line.lower() | 
					
						
							|  |  |  |                     append_str = remove_eol(append_str1) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                     following['orderedItems'].append(append_str) | 
					
						
							|  |  |  |         if page_ctr >= follows_per_page: | 
					
						
							|  |  |  |             page_ctr = 0 | 
					
						
							|  |  |  |             curr_page += 1 | 
					
						
							|  |  |  |     following['totalItems'] = total_ctr | 
					
						
							|  |  |  |     last_page = int(total_ctr / follows_per_page) | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |     last_page = max(last_page, 1) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if next_page_number > last_page: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         following['next'] = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  |             local_actor_url(http_prefix, nickname, domain) + \ | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             '/' + follow_file + '?page=' + str(last_page) | 
					
						
							| 
									
										
										
										
											2019-06-29 20:21:37 +00:00
										 |  |  |     return following | 
					
						
							| 
									
										
										
										
											2019-07-02 18:17:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  | def follow_approval_required(base_dir: str, nickname_to_follow: str, | 
					
						
							|  |  |  |                              domain_to_follow: str, debug: bool, | 
					
						
							|  |  |  |                              follow_request_handle: str) -> bool: | 
					
						
							| 
									
										
										
										
											2019-07-19 20:03:50 +00:00
										 |  |  |     """ Returns the policy for follower approvals
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2020-01-02 22:42:06 +00:00
										 |  |  |     # has this handle already been manually approved? | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if _pre_approved_follower(base_dir, nickname_to_follow, domain_to_follow, | 
					
						
							|  |  |  |                               follow_request_handle): | 
					
						
							| 
									
										
										
										
											2019-12-31 09:23:41 +00:00
										 |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     manually_approve_follows = False | 
					
						
							|  |  |  |     domain_to_follow = remove_domain_port(domain_to_follow) | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     actor_filename = data_dir(base_dir) + '/' + \ | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         nickname_to_follow + '@' + domain_to_follow + '.json' | 
					
						
							|  |  |  |     if os.path.isfile(actor_filename): | 
					
						
							|  |  |  |         actor = load_json(actor_filename) | 
					
						
							| 
									
										
										
										
											2019-09-30 22:39:02 +00:00
										 |  |  |         if actor: | 
					
						
							| 
									
										
										
										
											2022-02-28 19:37:33 +00:00
										 |  |  |             if 'manuallyApprovesFollowers' in actor: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 manually_approve_follows = actor['manuallyApprovesFollowers'] | 
					
						
							| 
									
										
										
										
											2019-07-19 20:03:50 +00:00
										 |  |  |             else: | 
					
						
							|  |  |  |                 if debug: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                     print(nickname_to_follow + '@' + domain_to_follow + | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |                           ' automatically approves followers') | 
					
						
							| 
									
										
										
										
											2019-07-19 20:03:50 +00:00
										 |  |  |     else: | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             print('DEBUG: Actor file not found: ' + actor_filename) | 
					
						
							|  |  |  |     return manually_approve_follows | 
					
						
							| 
									
										
										
										
											2019-07-20 13:31:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def no_of_follow_requests(base_dir: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                           nickname_to_follow: str, domain_to_follow: str, | 
					
						
							|  |  |  |                           follow_type: str) -> int: | 
					
						
							| 
									
										
										
										
											2020-01-03 16:52:31 +00:00
										 |  |  |     """Returns the current number of follow requests
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-09-10 09:24:13 +00:00
										 |  |  |     accounts_dir = acct_dir(base_dir, nickname_to_follow, domain_to_follow) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     approve_follows_filename = accounts_dir + '/followrequests.txt' | 
					
						
							|  |  |  |     if not os.path.isfile(approve_follows_filename): | 
					
						
							| 
									
										
										
										
											2020-01-03 16:52:31 +00:00
										 |  |  |         return 0 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |     ctr = 0 | 
					
						
							| 
									
										
										
										
											2024-12-23 17:45:20 +00:00
										 |  |  |     lines: list[str] = [] | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |         with open(approve_follows_filename, 'r', | 
					
						
							|  |  |  |                   encoding='utf-8') as fp_approve: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             lines = fp_approve.readlines() | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         print('EX: no_of_follow_requests ' + approve_follows_filename) | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |     if lines: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         if follow_type == "onion": | 
					
						
							|  |  |  |             for file_line in lines: | 
					
						
							|  |  |  |                 if '.onion' in file_line: | 
					
						
							| 
									
										
										
										
											2020-06-03 20:21:44 +00:00
										 |  |  |                     ctr += 1 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         elif follow_type == "i2p": | 
					
						
							|  |  |  |             for file_line in lines: | 
					
						
							|  |  |  |                 if '.i2p' in file_line: | 
					
						
							| 
									
										
										
										
											2020-06-03 20:21:44 +00:00
										 |  |  |                     ctr += 1 | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2020-01-03 16:52:31 +00:00
										 |  |  |             return len(lines) | 
					
						
							|  |  |  |     return ctr | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def store_follow_request(base_dir: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                          nickname_to_follow: str, | 
					
						
							|  |  |  |                          domain_to_follow: str, port: int, | 
					
						
							|  |  |  |                          nickname: str, domain: str, from_port: int, | 
					
						
							|  |  |  |                          follow_json: {}, | 
					
						
							|  |  |  |                          debug: bool, person_url: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                          group_account: bool) -> bool: | 
					
						
							| 
									
										
										
										
											2019-07-20 13:31:20 +00:00
										 |  |  |     """Stores the follow request for later use
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-09-10 09:24:13 +00:00
										 |  |  |     accounts_dir = acct_dir(base_dir, nickname_to_follow, domain_to_follow) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not os.path.isdir(accounts_dir): | 
					
						
							| 
									
										
										
										
											2019-07-20 13:31:20 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2019-08-16 20:35:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     domain_full = get_full_domain(domain, from_port) | 
					
						
							|  |  |  |     approve_handle = get_full_domain(nickname + '@' + domain, from_port) | 
					
						
							| 
									
										
										
										
											2019-07-20 13:31:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |     if group_account: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         approve_handle = '!' + approve_handle | 
					
						
							| 
									
										
										
										
											2021-07-31 12:24:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     followers_filename = accounts_dir + '/followers.txt' | 
					
						
							|  |  |  |     if os.path.isfile(followers_filename): | 
					
						
							|  |  |  |         already_following = False | 
					
						
							| 
									
										
										
										
											2020-10-24 09:52:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         followers_str = '' | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |             with open(followers_filename, 'r', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_foll: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 followers_str = fp_foll.read() | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             print('EX: store_follow_request ' + followers_filename) | 
					
						
							| 
									
										
										
										
											2020-10-24 09:52:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         if approve_handle in followers_str: | 
					
						
							|  |  |  |             already_following = True | 
					
						
							| 
									
										
										
										
											2021-07-30 19:20:49 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             users_paths = get_user_paths() | 
					
						
							|  |  |  |             for possible_users_path in users_paths: | 
					
						
							|  |  |  |                 url = '://' + domain_full + possible_users_path + nickname | 
					
						
							|  |  |  |                 if url in followers_str: | 
					
						
							|  |  |  |                     already_following = True | 
					
						
							| 
									
										
										
										
											2021-07-30 19:20:49 +00:00
										 |  |  |                     break | 
					
						
							| 
									
										
										
										
											2023-05-10 11:53:38 +00:00
										 |  |  |             if not already_following: | 
					
						
							|  |  |  |                 url = '://' + domain_full + '/' + nickname | 
					
						
							|  |  |  |                 if url in followers_str: | 
					
						
							|  |  |  |                     already_following = True | 
					
						
							| 
									
										
										
										
											2020-10-24 09:52:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         if already_following: | 
					
						
							| 
									
										
										
										
											2019-08-26 22:38:09 +00:00
										 |  |  |             if debug: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |                 print('DEBUG: ' + | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                       nickname_to_follow + '@' + domain_to_follow + | 
					
						
							|  |  |  |                       ' already following ' + approve_handle) | 
					
						
							| 
									
										
										
										
											2019-08-26 22:38:09 +00:00
										 |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-18 19:01:07 +00:00
										 |  |  |     # should this follow be denied? | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     deny_follows_filename = accounts_dir + '/followrejects.txt' | 
					
						
							|  |  |  |     if os.path.isfile(deny_follows_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 13:01:39 +00:00
										 |  |  |         if text_in_file(approve_handle, deny_follows_filename): | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             remove_from_follow_requests(base_dir, nickname_to_follow, | 
					
						
							|  |  |  |                                         domain_to_follow, approve_handle, | 
					
						
							|  |  |  |                                         debug) | 
					
						
							|  |  |  |             print(approve_handle + ' was already denied as a follower of ' + | 
					
						
							|  |  |  |                   nickname_to_follow) | 
					
						
							| 
									
										
										
										
											2019-09-18 19:01:07 +00:00
										 |  |  |             return True | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 13:31:20 +00:00
										 |  |  |     # add to a file which contains a list of requests | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     approve_follows_filename = accounts_dir + '/followrequests.txt' | 
					
						
							| 
									
										
										
										
											2020-10-24 11:07:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # store either nick@domain or the full person/actor url | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     approve_handle_stored = approve_handle | 
					
						
							|  |  |  |     if '/users/' not in person_url: | 
					
						
							|  |  |  |         approve_handle_stored = person_url | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |         if group_account: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             approve_handle = '!' + approve_handle | 
					
						
							| 
									
										
										
										
											2020-10-24 11:07:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if os.path.isfile(approve_follows_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 11:43:33 +00:00
										 |  |  |         if not text_in_file(approve_handle, approve_follows_filename): | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |                 with open(approve_follows_filename, 'a+', | 
					
						
							|  |  |  |                           encoding='utf-8') as fp_approve: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                     fp_approve.write(approve_handle_stored + '\n') | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 print('EX: store_follow_request 2 ' + approve_follows_filename) | 
					
						
							| 
									
										
										
										
											2019-07-20 13:31:20 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             if debug: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 print('DEBUG: ' + approve_handle_stored + | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |                       ' is already awaiting approval') | 
					
						
							| 
									
										
										
										
											2019-07-20 13:31:20 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |             with open(approve_follows_filename, 'w+', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_approve: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 fp_approve.write(approve_handle_stored + '\n') | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             print('EX: store_follow_request 3 ' + approve_follows_filename) | 
					
						
							| 
									
										
										
										
											2019-07-20 13:31:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # store the follow request in its own directory | 
					
						
							|  |  |  |     # We don't rely upon the inbox because items in there could expire | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     requests_dir = accounts_dir + '/requests' | 
					
						
							|  |  |  |     if not os.path.isdir(requests_dir): | 
					
						
							|  |  |  |         os.mkdir(requests_dir) | 
					
						
							|  |  |  |     follow_activity_filename = requests_dir + '/' + approve_handle + '.follow' | 
					
						
							|  |  |  |     return save_json(follow_json, follow_activity_filename) | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def followed_account_accepts(session, base_dir: str, http_prefix: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                              nickname_to_follow: str, domain_to_follow: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                              port: int, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                              nickname: str, domain: str, from_port: int, | 
					
						
							|  |  |  |                              person_url: str, federation_list: [], | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |                              follow_json: {}, send_threads: [], post_log: [], | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                              cached_webfingers: {}, person_cache: {}, | 
					
						
							|  |  |  |                              debug: bool, project_version: str, | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |                              remove_follow_activity: bool, | 
					
						
							| 
									
										
										
										
											2022-03-13 20:16:39 +00:00
										 |  |  |                              signing_priv_key_pem: str, | 
					
						
							|  |  |  |                              curr_domain: str, | 
					
						
							| 
									
										
										
										
											2023-03-18 21:06:10 +00:00
										 |  |  |                              onion_domain: str, i2p_domain: str, | 
					
						
							| 
									
										
										
										
											2023-09-15 21:04:31 +00:00
										 |  |  |                              followers_sync_cache: {}, | 
					
						
							| 
									
										
										
										
											2023-10-25 19:55:40 +00:00
										 |  |  |                              sites_unavailable: [], | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                              system_language: str, | 
					
						
							|  |  |  |                              mitm_servers: []): | 
					
						
							| 
									
										
										
										
											2019-07-20 08:33:18 +00:00
										 |  |  |     """The person receiving a follow request accepts the new follower
 | 
					
						
							|  |  |  |     and sends back an Accept activity | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     accept_handle = nickname + '@' + domain | 
					
						
							| 
									
										
										
										
											2019-10-06 09:57:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-05 18:57:19 +00:00
										 |  |  |     # send accept back | 
					
						
							| 
									
										
										
										
											2022-02-28 16:19:26 +00:00
										 |  |  |     print('Sending follow Accept activity for ' + | 
					
						
							|  |  |  |           'follow request which arrived at ' + | 
					
						
							|  |  |  |           nickname_to_follow + '@' + domain_to_follow + | 
					
						
							|  |  |  |           ' back to ' + accept_handle) | 
					
						
							| 
									
										
										
										
											2024-05-08 10:44:38 +00:00
										 |  |  |     accept_json = create_accept(federation_list, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                                 nickname_to_follow, domain_to_follow, port, | 
					
						
							|  |  |  |                                 person_url, '', http_prefix, | 
					
						
							|  |  |  |                                 follow_json) | 
					
						
							| 
									
										
										
										
											2022-02-28 16:19:26 +00:00
										 |  |  |     pprint(accept_json) | 
					
						
							|  |  |  |     print('DEBUG: sending follow Accept from ' + | 
					
						
							|  |  |  |           nickname_to_follow + '@' + domain_to_follow + | 
					
						
							|  |  |  |           ' port ' + str(port) + ' to ' + | 
					
						
							|  |  |  |           accept_handle + ' port ' + str(from_port)) | 
					
						
							| 
									
										
										
										
											2021-12-25 20:39:35 +00:00
										 |  |  |     client_to_server = False | 
					
						
							| 
									
										
										
										
											2019-12-16 10:19:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |     if remove_follow_activity: | 
					
						
							| 
									
										
										
										
											2019-12-29 13:19:51 +00:00
										 |  |  |         # remove the follow request json | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         follow_activity_filename = \ | 
					
						
							|  |  |  |             acct_dir(base_dir, nickname_to_follow, domain_to_follow) + \ | 
					
						
							| 
									
										
										
										
											2022-02-28 19:37:33 +00:00
										 |  |  |             '/requests/' + nickname + '@' + domain + '.follow' | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         if os.path.isfile(follow_activity_filename): | 
					
						
							| 
									
										
										
										
											2019-12-29 13:19:51 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 os.remove(follow_activity_filename) | 
					
						
							| 
									
										
										
										
											2021-11-25 18:42:38 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2022-02-28 16:19:26 +00:00
										 |  |  |                 print('EX: follow Accept ' + | 
					
						
							|  |  |  |                       'followed_account_accepts unable to delete ' + | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                       follow_activity_filename) | 
					
						
							| 
									
										
										
										
											2019-12-16 10:19:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |     group_account = False | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if follow_json: | 
					
						
							|  |  |  |         if follow_json.get('actor'): | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |             actor_url = get_actor_from_post(follow_json) | 
					
						
							|  |  |  |             if has_group_type(base_dir, actor_url, person_cache): | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |                 group_account = True | 
					
						
							| 
									
										
										
										
											2021-07-31 13:19:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-17 21:13:43 +00:00
										 |  |  |     extra_headers = {} | 
					
						
							| 
									
										
										
										
											2023-03-18 21:06:10 +00:00
										 |  |  |     domain_full = get_full_domain(domain, from_port) | 
					
						
							|  |  |  |     remove_followers_sync(followers_sync_cache, | 
					
						
							|  |  |  |                           nickname_to_follow, | 
					
						
							|  |  |  |                           domain_full) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     return send_signed_json(accept_json, session, base_dir, | 
					
						
							|  |  |  |                             nickname_to_follow, domain_to_follow, port, | 
					
						
							| 
									
										
										
										
											2022-05-31 13:34:29 +00:00
										 |  |  |                             nickname, domain, from_port, | 
					
						
							|  |  |  |                             http_prefix, client_to_server, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                             federation_list, | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |                             send_threads, post_log, cached_webfingers, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                             person_cache, debug, project_version, None, | 
					
						
							|  |  |  |                             group_account, signing_priv_key_pem, | 
					
						
							| 
									
										
										
										
											2023-03-17 21:13:43 +00:00
										 |  |  |                             7856837, curr_domain, onion_domain, i2p_domain, | 
					
						
							| 
									
										
										
										
											2023-10-25 19:55:40 +00:00
										 |  |  |                             extra_headers, sites_unavailable, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                             system_language, mitm_servers) | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-13 20:16:39 +00:00
										 |  |  | def followed_account_rejects(session, session_onion, session_i2p, | 
					
						
							|  |  |  |                              onion_domain: str, i2p_domain: str, | 
					
						
							|  |  |  |                              base_dir: str, http_prefix: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                              nickname_to_follow: str, domain_to_follow: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                              port: int, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                              nickname: str, domain: str, from_port: int, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                              federation_list: [], | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |                              send_threads: [], post_log: [], | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                              cached_webfingers: {}, person_cache: {}, | 
					
						
							|  |  |  |                              debug: bool, project_version: str, | 
					
						
							| 
									
										
										
										
											2023-03-18 21:06:10 +00:00
										 |  |  |                              signing_priv_key_pem: str, | 
					
						
							| 
									
										
										
										
											2023-09-15 21:04:31 +00:00
										 |  |  |                              followers_sync_cache: {}, | 
					
						
							| 
									
										
										
										
											2023-10-25 19:55:40 +00:00
										 |  |  |                              sites_unavailable: [], | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                              system_language: str, | 
					
						
							|  |  |  |                              mitm_servers: []): | 
					
						
							| 
									
										
										
										
											2019-09-09 12:19:00 +00:00
										 |  |  |     """The person receiving a follow request rejects the new follower
 | 
					
						
							|  |  |  |     and sends back a Reject activity | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     # send reject back | 
					
						
							|  |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         print('DEBUG: sending Reject activity for ' + | 
					
						
							|  |  |  |               'follow request which arrived at ' + | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |               nickname_to_follow + '@' + domain_to_follow + | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |               ' back to ' + nickname + '@' + domain) | 
					
						
							| 
									
										
										
										
											2019-12-16 10:01:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-16 10:12:44 +00:00
										 |  |  |     # get the json for the original follow request | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     follow_activity_filename = \ | 
					
						
							|  |  |  |         acct_dir(base_dir, nickname_to_follow, domain_to_follow) + \ | 
					
						
							|  |  |  |         '/requests/' + nickname + '@' + domain + '.follow' | 
					
						
							|  |  |  |     follow_json = load_json(follow_activity_filename) | 
					
						
							|  |  |  |     if not follow_json: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         print('No follow request json was found for ' + | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |               follow_activity_filename) | 
					
						
							| 
									
										
										
										
											2019-12-16 10:01:57 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2019-12-16 10:12:44 +00:00
										 |  |  |     # actor who made the follow request | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |     person_url = get_actor_from_post(follow_json) | 
					
						
							| 
									
										
										
										
											2019-12-16 10:01:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-16 10:12:44 +00:00
										 |  |  |     # create the reject activity | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     reject_json = \ | 
					
						
							| 
									
										
										
										
											2024-05-08 10:44:38 +00:00
										 |  |  |         create_reject(federation_list, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                       nickname_to_follow, domain_to_follow, port, | 
					
						
							|  |  |  |                       person_url, '', http_prefix, follow_json) | 
					
						
							| 
									
										
										
										
											2019-09-09 12:19:00 +00:00
										 |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         pprint(reject_json) | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         print('DEBUG: sending follow Reject from ' + | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |               nickname_to_follow + '@' + domain_to_follow + | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |               ' port ' + str(port) + ' to ' + | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |               nickname + '@' + domain + ' port ' + str(from_port)) | 
					
						
							| 
									
										
										
										
											2021-12-25 20:39:35 +00:00
										 |  |  |     client_to_server = False | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     deny_handle = get_full_domain(nickname + '@' + domain, from_port) | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |     group_account = False | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if has_group_type(base_dir, person_url, person_cache): | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |         group_account = True | 
					
						
							| 
									
										
										
										
											2019-12-16 10:12:44 +00:00
										 |  |  |     # remove from the follow requests file | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     remove_from_follow_requests(base_dir, nickname_to_follow, domain_to_follow, | 
					
						
							|  |  |  |                                 deny_handle, debug) | 
					
						
							| 
									
										
										
										
											2019-12-16 10:12:44 +00:00
										 |  |  |     # remove the follow request json | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         os.remove(follow_activity_filename) | 
					
						
							| 
									
										
										
										
											2021-11-25 18:42:38 +00:00
										 |  |  |     except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('EX: followed_account_rejects unable to delete ' + | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |               follow_activity_filename) | 
					
						
							| 
									
										
										
										
											2022-06-01 14:26:50 +00:00
										 |  |  |     curr_session = session | 
					
						
							|  |  |  |     if domain.endswith('.onion') and session_onion: | 
					
						
							|  |  |  |         curr_session = session_onion | 
					
						
							|  |  |  |     elif domain.endswith('.i2p') and session_i2p: | 
					
						
							|  |  |  |         curr_session = session_i2p | 
					
						
							| 
									
										
										
										
											2023-03-17 21:13:43 +00:00
										 |  |  |     extra_headers = {} | 
					
						
							| 
									
										
										
										
											2023-03-18 21:06:10 +00:00
										 |  |  |     domain_full = get_full_domain(domain, from_port) | 
					
						
							|  |  |  |     remove_followers_sync(followers_sync_cache, | 
					
						
							|  |  |  |                           nickname_to_follow, | 
					
						
							|  |  |  |                           domain_full) | 
					
						
							| 
									
										
										
										
											2019-12-16 10:12:44 +00:00
										 |  |  |     # send the reject activity | 
					
						
							| 
									
										
										
										
											2022-06-01 14:26:50 +00:00
										 |  |  |     return send_signed_json(reject_json, curr_session, base_dir, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                             nickname_to_follow, domain_to_follow, port, | 
					
						
							| 
									
										
										
										
											2022-05-31 13:34:29 +00:00
										 |  |  |                             nickname, domain, from_port, | 
					
						
							|  |  |  |                             http_prefix, client_to_server, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                             federation_list, | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |                             send_threads, post_log, cached_webfingers, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                             person_cache, debug, project_version, None, | 
					
						
							|  |  |  |                             group_account, signing_priv_key_pem, | 
					
						
							| 
									
										
										
										
											2022-03-13 20:16:39 +00:00
										 |  |  |                             6393063, | 
					
						
							| 
									
										
										
										
											2023-03-17 21:13:43 +00:00
										 |  |  |                             domain, onion_domain, i2p_domain, | 
					
						
							| 
									
										
										
										
											2023-10-25 19:55:40 +00:00
										 |  |  |                             extra_headers, sites_unavailable, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                             system_language, mitm_servers) | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  | def send_follow_request(session, base_dir: str, | 
					
						
							| 
									
										
										
										
											2022-03-11 22:59:15 +00:00
										 |  |  |                         nickname: str, domain: str, | 
					
						
							|  |  |  |                         sender_domain: str, sender_port: int, | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  |                         http_prefix: str, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                         follow_nickname: str, follow_domain: str, | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |                         followed_actor: str, | 
					
						
							|  |  |  |                         follow_port: int, follow_http_prefix: str, | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  |                         client_to_server: bool, federation_list: [], | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |                         send_threads: [], post_log: [], cached_webfingers: {}, | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  |                         person_cache: {}, debug: bool, | 
					
						
							| 
									
										
										
										
											2022-03-13 20:16:39 +00:00
										 |  |  |                         project_version: str, signing_priv_key_pem: str, | 
					
						
							|  |  |  |                         curr_domain: str, | 
					
						
							| 
									
										
										
										
											2023-09-15 21:04:31 +00:00
										 |  |  |                         onion_domain: str, i2p_domain: str, | 
					
						
							| 
									
										
										
										
											2023-10-25 19:55:40 +00:00
										 |  |  |                         sites_unavailable: [], | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                         system_language: str, | 
					
						
							|  |  |  |                         mitm_servers: []) -> {}: | 
					
						
							| 
									
										
										
										
											2019-07-02 20:54:22 +00:00
										 |  |  |     """Gets the json object for sending a follow request
 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-25 23:03:28 +00:00
										 |  |  |     if not signing_priv_key_pem: | 
					
						
							| 
									
										
										
										
											2021-09-20 16:14:24 +00:00
										 |  |  |         print('WARN: follow request without signing key') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not domain_permitted(follow_domain, federation_list): | 
					
						
							|  |  |  |         print('You are not permitted to follow the domain ' + follow_domain) | 
					
						
							| 
									
										
										
										
											2019-07-02 18:38:51 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-11 22:59:15 +00:00
										 |  |  |     full_domain = get_full_domain(sender_domain, sender_port) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     follow_actor = local_actor_url(http_prefix, nickname, full_domain) | 
					
						
							| 
									
										
										
										
											2019-07-02 18:38:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |     request_domain = get_full_domain(follow_domain, follow_port) | 
					
						
							| 
									
										
										
										
											2019-07-06 10:33:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     status_number, _ = get_status_number() | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |     group_account = False | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if follow_nickname: | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |         followed_id = followed_actor | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         follow_handle = follow_nickname + '@' + request_domain | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |         group_account = has_group_type(base_dir, followed_actor, person_cache) | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |         if group_account: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             follow_handle = '!' + follow_handle | 
					
						
							| 
									
										
										
										
											2021-08-02 20:57:44 +00:00
										 |  |  |             print('Follow request being sent to group account') | 
					
						
							| 
									
										
										
										
											2019-10-21 14:12:22 +00:00
										 |  |  |     else: | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  |             print('DEBUG: send_follow_request - assuming single user instance') | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |         followed_id = follow_http_prefix + '://' + request_domain | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         single_user_nickname = 'dev' | 
					
						
							|  |  |  |         follow_handle = single_user_nickname + '@' + request_domain | 
					
						
							| 
									
										
										
										
											2019-07-06 19:24:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-17 17:45:49 +00:00
										 |  |  |     # remove follow handle from unfollowed.txt | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     unfollowed_filename = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 12:02:29 +00:00
										 |  |  |         acct_dir(base_dir, nickname, domain) + '/unfollowed.txt' | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if os.path.isfile(unfollowed_filename): | 
					
						
							| 
									
										
										
										
											2022-06-10 13:01:39 +00:00
										 |  |  |         if text_in_file(follow_handle, unfollowed_filename): | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             unfollowed_file = None | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |                 with open(unfollowed_filename, 'r', | 
					
						
							|  |  |  |                           encoding='utf-8') as fp_unfoll: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                     unfollowed_file = fp_unfoll.read() | 
					
						
							| 
									
										
										
										
											2021-11-26 14:35:26 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 print('EX: send_follow_request ' + unfollowed_filename) | 
					
						
							|  |  |  |             if unfollowed_file: | 
					
						
							|  |  |  |                 unfollowed_file = \ | 
					
						
							|  |  |  |                     unfollowed_file.replace(follow_handle + '\n', '') | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |                     with open(unfollowed_filename, 'w+', | 
					
						
							|  |  |  |                               encoding='utf-8') as fp_unfoll: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                         fp_unfoll.write(unfollowed_file) | 
					
						
							| 
									
										
										
										
											2021-11-25 21:18:53 +00:00
										 |  |  |                 except OSError: | 
					
						
							| 
									
										
										
										
											2024-07-02 22:16:13 +00:00
										 |  |  |                     print('EX: send_follow_request unable to write ' + | 
					
						
							|  |  |  |                           unfollowed_filename) | 
					
						
							| 
									
										
										
										
											2021-10-17 17:45:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     new_follow_json = { | 
					
						
							| 
									
										
										
										
											2024-09-14 16:40:11 +00:00
										 |  |  |         "@context": [ | 
					
						
							|  |  |  |             'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |             'https://w3id.org/security/v1' | 
					
						
							|  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'id': follow_actor + '/statuses/' + str(status_number), | 
					
						
							| 
									
										
										
										
											2019-07-02 18:38:51 +00:00
										 |  |  |         'type': 'Follow', | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'actor': follow_actor, | 
					
						
							|  |  |  |         'object': followed_id | 
					
						
							| 
									
										
										
										
											2019-07-02 18:38:51 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |     if group_account: | 
					
						
							| 
									
										
										
										
											2024-03-29 15:33:37 +00:00
										 |  |  |         new_follow_json['to'] = [followed_id] | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         print('Follow request: ' + str(new_follow_json)) | 
					
						
							| 
									
										
										
										
											2019-07-02 19:05:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |     if follow_approval_required(base_dir, nickname, domain, debug, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                                 follow_handle): | 
					
						
							| 
									
										
										
										
											2020-02-19 12:51:14 +00:00
										 |  |  |         # Remove any follow requests rejected for the account being followed. | 
					
						
							|  |  |  |         # It's assumed that if you are following someone then you are | 
					
						
							|  |  |  |         # ok with them following back. If this isn't the case then a rejected | 
					
						
							|  |  |  |         # follow request will block them again. | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         _remove_from_follow_rejects(base_dir, | 
					
						
							|  |  |  |                                     nickname, domain, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                                     follow_handle, debug) | 
					
						
							| 
									
										
										
										
											2023-03-17 21:13:43 +00:00
										 |  |  |     extra_headers = {} | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     send_signed_json(new_follow_json, session, base_dir, | 
					
						
							| 
									
										
										
										
											2022-03-11 22:59:15 +00:00
										 |  |  |                      nickname, sender_domain, sender_port, | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |                      follow_nickname, follow_domain, follow_port, | 
					
						
							| 
									
										
										
										
											2022-05-31 13:34:29 +00:00
										 |  |  |                      http_prefix, client_to_server, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                      federation_list, | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |                      send_threads, post_log, cached_webfingers, person_cache, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                      debug, project_version, None, group_account, | 
					
						
							| 
									
										
										
										
											2022-03-13 20:16:39 +00:00
										 |  |  |                      signing_priv_key_pem, 8234389, | 
					
						
							| 
									
										
										
										
											2023-03-17 21:13:43 +00:00
										 |  |  |                      curr_domain, onion_domain, i2p_domain, | 
					
						
							| 
									
										
										
										
											2023-10-25 19:55:40 +00:00
										 |  |  |                      extra_headers, sites_unavailable, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                      system_language, mitm_servers) | 
					
						
							| 
									
										
										
										
											2019-07-05 20:32:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     return new_follow_json | 
					
						
							| 
									
										
										
										
											2019-07-08 16:49:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-13 12:15:52 +00:00
										 |  |  | def send_follow_request_via_server(base_dir: str, session, | 
					
						
							|  |  |  |                                    from_nickname: str, password: str, | 
					
						
							|  |  |  |                                    from_domain: str, from_port: int, | 
					
						
							|  |  |  |                                    follow_nickname: str, follow_domain: str, | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |                                    follow_port: int, | 
					
						
							| 
									
										
										
										
											2022-03-13 12:15:52 +00:00
										 |  |  |                                    http_prefix: str, | 
					
						
							|  |  |  |                                    cached_webfingers: {}, person_cache: {}, | 
					
						
							|  |  |  |                                    debug: bool, project_version: str, | 
					
						
							| 
									
										
										
										
											2023-10-25 19:55:40 +00:00
										 |  |  |                                    signing_priv_key_pem: str, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                                    system_language: str, | 
					
						
							|  |  |  |                                    mitm_servers: []) -> {}: | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  |     """Creates a follow request via c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							| 
									
										
										
										
											2022-03-13 12:15:52 +00:00
										 |  |  |         print('WARN: No session for send_follow_request_via_server') | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     from_domain_full = get_full_domain(from_domain, from_port) | 
					
						
							| 
									
										
										
										
											2019-07-18 11:35:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |     follow_domain_full = get_full_domain(follow_domain, follow_port) | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     follow_actor = \ | 
					
						
							|  |  |  |         local_actor_url(http_prefix, from_nickname, from_domain_full) | 
					
						
							|  |  |  |     followed_id = \ | 
					
						
							|  |  |  |         http_prefix + '://' + follow_domain_full + '/@' + follow_nickname | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-01 14:26:50 +00:00
										 |  |  |     status_number, _ = get_status_number() | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     new_follow_json = { | 
					
						
							| 
									
										
										
										
											2024-09-14 16:40:11 +00:00
										 |  |  |         "@context": [ | 
					
						
							|  |  |  |             'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |             'https://w3id.org/security/v1' | 
					
						
							|  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'id': follow_actor + '/statuses/' + str(status_number), | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  |         'type': 'Follow', | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'actor': follow_actor, | 
					
						
							|  |  |  |         'object': followed_id | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     handle = http_prefix + '://' + from_domain_full + '/@' + from_nickname | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # lookup the inbox for the To handle | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     wf_request = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         webfinger_handle(session, handle, http_prefix, cached_webfingers, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                          from_domain, project_version, debug, False, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                          signing_priv_key_pem, mitm_servers) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not wf_request: | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-03-18 10:01:01 +00:00
										 |  |  |             print('DEBUG: follow request webfinger failed for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not isinstance(wf_request, dict): | 
					
						
							| 
									
										
										
										
											2021-03-18 10:01:01 +00:00
										 |  |  |         print('WARN: follow request Webfinger for ' + handle + | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |               ' did not return a dict. ' + str(wf_request)) | 
					
						
							| 
									
										
										
										
											2020-06-23 10:41:12 +00:00
										 |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     post_to_box = 'outbox' | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get the actor inbox for the To handle | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     origin_domain = from_domain | 
					
						
							| 
									
										
										
										
											2022-01-14 12:53:29 +00:00
										 |  |  |     (inbox_url, _, _, from_person_id, _, _, | 
					
						
							|  |  |  |      _, _) = get_person_box(signing_priv_key_pem, origin_domain, | 
					
						
							|  |  |  |                             base_dir, session, wf_request, | 
					
						
							|  |  |  |                             person_cache, | 
					
						
							|  |  |  |                             project_version, http_prefix, | 
					
						
							|  |  |  |                             from_nickname, | 
					
						
							| 
									
										
										
										
											2023-10-25 19:55:40 +00:00
										 |  |  |                             from_domain, post_to_box, 52025, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                             system_language, mitm_servers) | 
					
						
							| 
									
										
										
										
											2022-01-14 12:53:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not inbox_url: | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             print('DEBUG: follow request no ' + post_to_box + | 
					
						
							| 
									
										
										
										
											2021-03-18 10:01:01 +00:00
										 |  |  |                   ' was found for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  |         return 3 | 
					
						
							| 
									
										
										
										
											2022-01-14 12:53:29 +00:00
										 |  |  |     if not from_person_id: | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-03-18 10:01:01 +00:00
										 |  |  |             print('DEBUG: follow request no actor was found for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  |         return 4 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     auth_header = create_basic_auth_header(from_nickname, password) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |     headers = { | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'host': from_domain, | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         'Content-type': 'application/json', | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'Authorization': auth_header | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     post_result = \ | 
					
						
							|  |  |  |         post_json(http_prefix, from_domain_full, | 
					
						
							| 
									
										
										
										
											2022-01-14 12:53:29 +00:00
										 |  |  |                   session, new_follow_json, [], inbox_url, headers, 3, True) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not post_result: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2022-01-14 12:53:29 +00:00
										 |  |  |             print('DEBUG: POST follow request failed for c2s to ' + inbox_url) | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         return 5 | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2021-03-18 10:01:01 +00:00
										 |  |  |         print('DEBUG: c2s POST follow request success') | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     return new_follow_json | 
					
						
							| 
									
										
										
										
											2019-07-16 21:38:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def send_unfollow_request_via_server(base_dir: str, session, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                                      from_nickname: str, password: str, | 
					
						
							|  |  |  |                                      from_domain: str, from_port: int, | 
					
						
							|  |  |  |                                      follow_nickname: str, follow_domain: str, | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |                                      follow_port: int, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                                      http_prefix: str, | 
					
						
							|  |  |  |                                      cached_webfingers: {}, person_cache: {}, | 
					
						
							|  |  |  |                                      debug: bool, project_version: str, | 
					
						
							| 
									
										
										
										
											2023-10-25 19:55:40 +00:00
										 |  |  |                                      signing_priv_key_pem: str, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                                      system_language: str, | 
					
						
							|  |  |  |                                      mitm_servers: []) -> {}: | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |     """Creates a unfollow request via c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('WARN: No session for send_unfollow_request_via_server') | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     from_domain_full = get_full_domain(from_domain, from_port) | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |     follow_domain_full = get_full_domain(follow_domain, follow_port) | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     follow_actor = \ | 
					
						
							|  |  |  |         local_actor_url(http_prefix, from_nickname, from_domain_full) | 
					
						
							|  |  |  |     followed_id = \ | 
					
						
							|  |  |  |         http_prefix + '://' + follow_domain_full + '/@' + follow_nickname | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |     status_number, _ = get_status_number() | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     unfollow_json = { | 
					
						
							| 
									
										
										
										
											2024-09-14 16:40:11 +00:00
										 |  |  |         "@context": [ | 
					
						
							|  |  |  |             'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |             'https://w3id.org/security/v1' | 
					
						
							|  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'id': follow_actor + '/statuses/' + str(status_number) + '/undo', | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         'type': 'Undo', | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'actor': follow_actor, | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         'object': { | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             'id': follow_actor + '/statuses/' + str(status_number), | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |             'type': 'Follow', | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             'actor': follow_actor, | 
					
						
							|  |  |  |             'object': followed_id | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     handle = http_prefix + '://' + from_domain_full + '/@' + from_nickname | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # lookup the inbox for the To handle | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     wf_request = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         webfinger_handle(session, handle, http_prefix, cached_webfingers, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                          from_domain, project_version, debug, False, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                          signing_priv_key_pem, mitm_servers) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not wf_request: | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-03-18 10:01:01 +00:00
										 |  |  |             print('DEBUG: unfollow webfinger failed for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not isinstance(wf_request, dict): | 
					
						
							| 
									
										
										
										
											2021-03-18 10:01:01 +00:00
										 |  |  |         print('WARN: unfollow webfinger for ' + handle + | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |               ' did not return a dict. ' + str(wf_request)) | 
					
						
							| 
									
										
										
										
											2020-06-23 10:41:12 +00:00
										 |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     post_to_box = 'outbox' | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get the actor inbox for the To handle | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     origin_domain = from_domain | 
					
						
							| 
									
										
										
										
											2022-01-14 12:53:29 +00:00
										 |  |  |     (inbox_url, _, _, from_person_id, _, _, | 
					
						
							|  |  |  |      _, _) = get_person_box(signing_priv_key_pem, | 
					
						
							|  |  |  |                             origin_domain, | 
					
						
							|  |  |  |                             base_dir, session, | 
					
						
							|  |  |  |                             wf_request, person_cache, | 
					
						
							|  |  |  |                             project_version, http_prefix, | 
					
						
							|  |  |  |                             from_nickname, | 
					
						
							|  |  |  |                             from_domain, post_to_box, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                             76536, system_language, | 
					
						
							|  |  |  |                             mitm_servers) | 
					
						
							| 
									
										
										
										
											2022-01-14 12:53:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not inbox_url: | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             print('DEBUG: unfollow no ' + post_to_box + | 
					
						
							| 
									
										
										
										
											2021-03-18 10:01:01 +00:00
										 |  |  |                   ' was found for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         return 3 | 
					
						
							| 
									
										
										
										
											2022-01-14 12:53:29 +00:00
										 |  |  |     if not from_person_id: | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-03-18 10:01:01 +00:00
										 |  |  |             print('DEBUG: unfollow no actor was found for ' + handle) | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         return 4 | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     auth_header = create_basic_auth_header(from_nickname, password) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |     headers = { | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'host': from_domain, | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         'Content-type': 'application/json', | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'Authorization': auth_header | 
					
						
							| 
									
										
										
										
											2020-03-22 20:36:19 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     post_result = \ | 
					
						
							|  |  |  |         post_json(http_prefix, from_domain_full, | 
					
						
							| 
									
										
										
										
											2022-01-14 12:53:29 +00:00
										 |  |  |                   session, unfollow_json, [], inbox_url, headers, 3, True) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not post_result: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2022-01-14 12:53:29 +00:00
										 |  |  |             print('DEBUG: POST unfollow failed for c2s to ' + inbox_url) | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         return 5 | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s POST unfollow success') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     return unfollow_json | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-01 15:54:28 +00:00
										 |  |  | def get_following_via_server(session, nickname: str, password: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                              domain: str, port: int, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                              http_prefix: str, page_number: int, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                              debug: bool, project_version: str, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                              signing_priv_key_pem: str, | 
					
						
							|  |  |  |                              mitm_servers: []) -> {}: | 
					
						
							| 
									
										
										
										
											2021-03-24 12:43:24 +00:00
										 |  |  |     """Gets a page from the following collection as json
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('WARN: No session for get_following_via_server') | 
					
						
							| 
									
										
										
										
											2021-03-24 12:43:24 +00:00
										 |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |     domain_full = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     follow_actor = local_actor_url(http_prefix, nickname, domain_full) | 
					
						
							| 
									
										
										
										
											2021-03-24 12:43:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     auth_header = create_basic_auth_header(nickname, password) | 
					
						
							| 
									
										
										
										
											2021-03-24 12:43:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     headers = { | 
					
						
							|  |  |  |         'host': domain, | 
					
						
							|  |  |  |         'Content-type': 'application/json', | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'Authorization': auth_header | 
					
						
							| 
									
										
										
										
											2021-03-24 12:43:24 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |     page_number = max(page_number, 1) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     url = follow_actor + '/following?page=' + str(page_number) | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |     following_json = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         get_json(signing_priv_key_pem, session, url, headers, {}, debug, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                  mitm_servers, project_version, http_prefix, domain, 10, True) | 
					
						
							| 
									
										
										
										
											2023-08-13 09:58:02 +00:00
										 |  |  |     if not get_json_valid(following_json): | 
					
						
							| 
									
										
										
										
											2021-03-24 12:43:24 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: GET following list failed for c2s to ' + url) | 
					
						
							|  |  |  |         return 5 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s GET following list request success') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |     return following_json | 
					
						
							| 
									
										
										
										
											2021-03-24 12:43:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-01 15:54:28 +00:00
										 |  |  | def get_followers_via_server(session, nickname: str, password: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                              domain: str, port: int, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                              http_prefix: str, page_number: int, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                              debug: bool, project_version: str, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                              signing_priv_key_pem: str, | 
					
						
							|  |  |  |                              mitm_servers: []) -> {}: | 
					
						
							| 
									
										
										
										
											2021-03-24 13:52:20 +00:00
										 |  |  |     """Gets a page from the followers collection as json
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('WARN: No session for get_followers_via_server') | 
					
						
							| 
									
										
										
										
											2021-03-24 13:52:20 +00:00
										 |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |     domain_full = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     follow_actor = local_actor_url(http_prefix, nickname, domain_full) | 
					
						
							| 
									
										
										
										
											2021-03-24 13:52:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     auth_header = create_basic_auth_header(nickname, password) | 
					
						
							| 
									
										
										
										
											2021-03-24 13:52:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     headers = { | 
					
						
							|  |  |  |         'host': domain, | 
					
						
							|  |  |  |         'Content-type': 'application/json', | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'Authorization': auth_header | 
					
						
							| 
									
										
										
										
											2021-03-24 13:52:20 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-01 15:54:28 +00:00
										 |  |  |     page_number = max(page_number, 1) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     url = follow_actor + '/followers?page=' + str(page_number) | 
					
						
							|  |  |  |     followers_json = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         get_json(signing_priv_key_pem, session, url, headers, {}, debug, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                  mitm_servers, project_version, http_prefix, domain, 10, True) | 
					
						
							| 
									
										
										
										
											2023-08-13 09:58:02 +00:00
										 |  |  |     if not get_json_valid(followers_json): | 
					
						
							| 
									
										
										
										
											2021-03-24 13:52:20 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: GET followers list failed for c2s to ' + url) | 
					
						
							|  |  |  |         return 5 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s GET followers list request success') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     return followers_json | 
					
						
							| 
									
										
										
										
											2021-03-24 13:52:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-01 15:54:28 +00:00
										 |  |  | def get_follow_requests_via_server(session, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                                    nickname: str, password: str, | 
					
						
							|  |  |  |                                    domain: str, port: int, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                                    http_prefix: str, page_number: int, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                                    debug: bool, project_version: str, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                                    signing_priv_key_pem: str, | 
					
						
							|  |  |  |                                    mitm_servers: []) -> {}: | 
					
						
							| 
									
										
										
										
											2021-03-24 15:07:17 +00:00
										 |  |  |     """Gets a page from the follow requests collection as json
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('WARN: No session for get_follow_requests_via_server') | 
					
						
							| 
									
										
										
										
											2021-03-24 15:07:17 +00:00
										 |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  |     domain_full = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2021-03-24 15:07:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     follow_actor = local_actor_url(http_prefix, nickname, domain_full) | 
					
						
							|  |  |  |     auth_header = create_basic_auth_header(nickname, password) | 
					
						
							| 
									
										
										
										
											2021-03-24 15:07:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     headers = { | 
					
						
							|  |  |  |         'host': domain, | 
					
						
							|  |  |  |         'Content-type': 'application/json', | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'Authorization': auth_header | 
					
						
							| 
									
										
										
										
											2021-03-24 15:07:17 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |     page_number = max(page_number, 1) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     url = follow_actor + '/followrequests?page=' + str(page_number) | 
					
						
							|  |  |  |     followers_json = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         get_json(signing_priv_key_pem, session, url, headers, {}, debug, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                  mitm_servers, project_version, http_prefix, domain, 10, True) | 
					
						
							| 
									
										
										
										
											2023-08-13 09:58:02 +00:00
										 |  |  |     if not get_json_valid(followers_json): | 
					
						
							| 
									
										
										
										
											2021-03-24 15:07:17 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: GET follow requests list failed for c2s to ' + url) | 
					
						
							|  |  |  |         return 5 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s GET follow requests list request success') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     return followers_json | 
					
						
							| 
									
										
										
										
											2021-03-24 15:07:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-01 15:54:28 +00:00
										 |  |  | def approve_follow_request_via_server(session, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                                       nickname: str, password: str, | 
					
						
							|  |  |  |                                       domain: str, port: int, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                                       http_prefix: str, approve_handle: int, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                                       debug: bool, project_version: str, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                                       signing_priv_key_pem: str, | 
					
						
							|  |  |  |                                       mitm_servers: []) -> str: | 
					
						
							| 
									
										
										
										
											2021-03-25 12:07:44 +00:00
										 |  |  |     """Approves a follow request
 | 
					
						
							|  |  |  |     This is not exactly via c2s though. It simulates pressing the Approve | 
					
						
							|  |  |  |     button on the web interface | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('WARN: No session for approve_follow_request_via_server') | 
					
						
							| 
									
										
										
										
											2021-03-25 12:07:44 +00:00
										 |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-03-25 12:07:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     auth_header = create_basic_auth_header(nickname, password) | 
					
						
							| 
									
										
										
										
											2021-03-25 12:07:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     headers = { | 
					
						
							|  |  |  |         'host': domain, | 
					
						
							|  |  |  |         'Content-type': 'text/html; charset=utf-8', | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'Authorization': auth_header | 
					
						
							| 
									
										
										
										
											2021-03-25 12:07:44 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     url = actor + '/followapprove=' + approve_handle | 
					
						
							|  |  |  |     approve_html = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         get_json(signing_priv_key_pem, session, url, headers, {}, debug, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                  mitm_servers, project_version, http_prefix, domain, 10, True) | 
					
						
							| 
									
										
										
										
											2023-08-13 09:58:02 +00:00
										 |  |  |     if not get_json_valid(approve_html): | 
					
						
							| 
									
										
										
										
											2021-03-25 12:07:44 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: GET approve follow request failed for c2s to ' + url) | 
					
						
							|  |  |  |         return 5 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s GET approve follow request request success') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     return approve_html | 
					
						
							| 
									
										
										
										
											2021-03-25 12:07:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-01 15:54:28 +00:00
										 |  |  | def deny_follow_request_via_server(session, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                                    nickname: str, password: str, | 
					
						
							|  |  |  |                                    domain: str, port: int, | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                                    http_prefix: str, deny_handle: int, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                                    debug: bool, project_version: str, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                                    signing_priv_key_pem: str, | 
					
						
							|  |  |  |                                    mitm_servers: []) -> str: | 
					
						
							| 
									
										
										
										
											2021-03-25 12:07:44 +00:00
										 |  |  |     """Denies a follow request
 | 
					
						
							|  |  |  |     This is not exactly via c2s though. It simulates pressing the Deny | 
					
						
							|  |  |  |     button on the web interface | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('WARN: No session for deny_follow_request_via_server') | 
					
						
							| 
									
										
										
										
											2021-03-25 12:07:44 +00:00
										 |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-03-25 12:07:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     auth_header = create_basic_auth_header(nickname, password) | 
					
						
							| 
									
										
										
										
											2021-03-25 12:07:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     headers = { | 
					
						
							|  |  |  |         'host': domain, | 
					
						
							|  |  |  |         'Content-type': 'text/html; charset=utf-8', | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         'Authorization': auth_header | 
					
						
							| 
									
										
										
										
											2021-03-25 12:07:44 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     url = actor + '/followdeny=' + deny_handle | 
					
						
							|  |  |  |     deny_html = \ | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         get_json(signing_priv_key_pem, session, url, headers, {}, debug, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                  mitm_servers, project_version, http_prefix, domain, 10, True) | 
					
						
							| 
									
										
										
										
											2023-08-13 09:58:02 +00:00
										 |  |  |     if not get_json_valid(deny_html): | 
					
						
							| 
									
										
										
										
											2021-03-25 12:07:44 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: GET deny follow request failed for c2s to ' + url) | 
					
						
							|  |  |  |         return 5 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s GET deny follow request request success') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     return deny_html | 
					
						
							| 
									
										
										
										
											2021-03-25 12:07:44 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def get_followers_of_actor(base_dir: str, actor: str, debug: bool) -> {}: | 
					
						
							| 
									
										
										
										
											2019-07-08 16:49:12 +00:00
										 |  |  |     """In a shared inbox if we receive a post we know who it's from
 | 
					
						
							| 
									
										
										
										
											2019-07-08 17:15:55 +00:00
										 |  |  |     and if it's addressed to followers then we need to get a list of those. | 
					
						
							|  |  |  |     This returns a list of account handles which follow the given actor | 
					
						
							| 
									
										
										
										
											2019-07-08 16:49:12 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         print('DEBUG: getting followers of ' + actor) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     recipients_dict = {} | 
					
						
							| 
									
										
										
										
											2019-07-08 17:15:55 +00:00
										 |  |  |     if ':' not in actor: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         return recipients_dict | 
					
						
							| 
									
										
										
										
											2021-12-27 22:19:18 +00:00
										 |  |  |     nickname = get_nickname_from_actor(actor) | 
					
						
							| 
									
										
										
										
											2019-07-08 16:49:12 +00:00
										 |  |  |     if not nickname: | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |             print('DEBUG: no nickname found in ' + actor) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         return recipients_dict | 
					
						
							|  |  |  |     domain, _ = get_domain_from_actor(actor) | 
					
						
							| 
									
										
										
										
											2019-07-08 16:49:12 +00:00
										 |  |  |     if not domain: | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |             print('DEBUG: no domain found in ' + actor) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         return recipients_dict | 
					
						
							|  |  |  |     actor_handle = nickname + '@' + domain | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |         print('DEBUG: searching for handle ' + actor_handle) | 
					
						
							| 
									
										
										
										
											2019-07-08 16:49:12 +00:00
										 |  |  |     # for each of the accounts | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     dir_str = data_dir(base_dir) | 
					
						
							|  |  |  |     for subdir, dirs, _ in os.walk(dir_str): | 
					
						
							| 
									
										
										
										
											2019-07-08 16:49:12 +00:00
										 |  |  |         for account in dirs: | 
					
						
							| 
									
										
										
										
											2022-06-01 15:54:28 +00:00
										 |  |  |             if '@' not in account: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if account.startswith('inbox@'): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             if account.startswith('Actor@'): | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             following_filename = \ | 
					
						
							|  |  |  |                 os.path.join(subdir, account) + '/following.txt' | 
					
						
							|  |  |  |             if debug: | 
					
						
							|  |  |  |                 print('DEBUG: examining follows of ' + account) | 
					
						
							|  |  |  |                 print(following_filename) | 
					
						
							|  |  |  |             if os.path.isfile(following_filename): | 
					
						
							|  |  |  |                 # does this account follow the given actor? | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  |                 if debug: | 
					
						
							| 
									
										
										
										
											2022-06-01 15:54:28 +00:00
										 |  |  |                     print('DEBUG: checking if ' + actor_handle + | 
					
						
							|  |  |  |                           ' in ' + following_filename) | 
					
						
							| 
									
										
										
										
											2022-06-10 13:01:39 +00:00
										 |  |  |                 if text_in_file(actor_handle, following_filename): | 
					
						
							| 
									
										
										
										
											2019-07-11 12:29:31 +00:00
										 |  |  |                     if debug: | 
					
						
							| 
									
										
										
										
											2022-06-01 15:54:28 +00:00
										 |  |  |                         print('DEBUG: ' + account + | 
					
						
							|  |  |  |                               ' follows ' + actor_handle) | 
					
						
							|  |  |  |                     recipients_dict[account] = None | 
					
						
							| 
									
										
										
										
											2020-12-13 22:13:45 +00:00
										 |  |  |         break | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     return recipients_dict | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def outbox_undo_follow(base_dir: str, message_json: {}, debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |     """When an unfollow request is received by the outbox from c2s
 | 
					
						
							|  |  |  |     This removes the followed handle from the following.txt file | 
					
						
							|  |  |  |     of the relevant account | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json.get('type'): | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['type'] == 'Undo': | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2022-04-09 15:11:22 +00:00
										 |  |  |     if not has_object_string_type(message_json, debug): | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['object']['type'] == 'Follow': | 
					
						
							|  |  |  |         if not message_json['object']['type'] == 'Join': | 
					
						
							| 
									
										
										
										
											2021-02-08 14:48:37 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2021-12-26 15:54:46 +00:00
										 |  |  |     if not has_object_string_object(message_json, debug): | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['object'].get('actor'): | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         return | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: undo follow arrived in outbox') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |     actor_url = get_actor_from_post(message_json['object']) | 
					
						
							|  |  |  |     nickname_follower = get_nickname_from_actor(actor_url) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not nickname_follower: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         print('WARN: unable to find nickname in ' + | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |               actor_url) | 
					
						
							| 
									
										
										
										
											2019-09-02 09:43:43 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |     domain_follower, port_follower = get_domain_from_actor(actor_url) | 
					
						
							| 
									
										
										
										
											2023-01-15 14:33:18 +00:00
										 |  |  |     if not domain_follower: | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |         print('WARN: unable to find domain in ' + actor_url) | 
					
						
							| 
									
										
										
										
											2023-01-15 14:33:18 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     domain_follower_full = get_full_domain(domain_follower, port_follower) | 
					
						
							| 
									
										
										
										
											2020-03-22 21:16:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     nickname_following = \ | 
					
						
							| 
									
										
										
										
											2021-12-27 22:19:18 +00:00
										 |  |  |         get_nickname_from_actor(message_json['object']['object']) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if not nickname_following: | 
					
						
							| 
									
										
										
										
											2020-04-03 11:38:44 +00:00
										 |  |  |         print('WARN: 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 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     domain_following, port_following = \ | 
					
						
							| 
									
										
										
										
											2021-12-27 19:05:25 +00:00
										 |  |  |         get_domain_from_actor(message_json['object']['object']) | 
					
						
							| 
									
										
										
										
											2023-01-15 14:33:18 +00:00
										 |  |  |     if not domain_following: | 
					
						
							|  |  |  |         print('WARN: unable to find domain in ' + | 
					
						
							|  |  |  |               message_json['object']['object']) | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     domain_following_full = get_full_domain(domain_following, port_following) | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |     group_account = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 17:53:07 +00:00
										 |  |  |         has_group_type(base_dir, message_json['object']['object'], None) | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     if unfollow_account(base_dir, nickname_follower, domain_follower_full, | 
					
						
							|  |  |  |                         nickname_following, domain_following_full, | 
					
						
							| 
									
										
										
										
											2024-02-19 15:38:08 +00:00
										 |  |  |                         debug, group_account, 'following.txt'): | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             print('DEBUG: ' + nickname_follower + ' unfollowed ' + | 
					
						
							|  |  |  |                   nickname_following + '@' + domain_following_full) | 
					
						
							| 
									
										
										
										
											2019-07-17 10:34:00 +00:00
										 |  |  |     else: | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |             print('WARN: ' + nickname_follower + ' could not unfollow ' + | 
					
						
							|  |  |  |                   nickname_following + '@' + domain_following_full) | 
					
						
							| 
									
										
										
										
											2020-11-09 15:40:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-28 20:32:11 +00:00
										 |  |  | def follower_approval_active(base_dir: str, | 
					
						
							|  |  |  |                              nickname: str, domain: str) -> bool: | 
					
						
							| 
									
										
										
										
											2020-11-09 15:40:24 +00:00
										 |  |  |     """Returns true if the given account requires follower approval
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     manually_approves_followers = False | 
					
						
							|  |  |  |     actor_filename = acct_dir(base_dir, nickname, domain) + '.json' | 
					
						
							|  |  |  |     if os.path.isfile(actor_filename): | 
					
						
							|  |  |  |         actor_json = load_json(actor_filename) | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |         if actor_json: | 
					
						
							| 
									
										
										
										
											2022-02-28 19:37:33 +00:00
										 |  |  |             if 'manuallyApprovesFollowers' in actor_json: | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |                 manually_approves_followers = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 10:29:52 +00:00
										 |  |  |                     actor_json['manuallyApprovesFollowers'] | 
					
						
							| 
									
										
										
										
											2022-01-02 14:51:02 +00:00
										 |  |  |     return manually_approves_followers | 
					
						
							| 
									
										
										
										
											2022-12-01 23:00:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def remove_follower(base_dir: str, | 
					
						
							|  |  |  |                     nickname: str, domain: str, | 
					
						
							|  |  |  |                     remove_nickname: str, remove_domain: str) -> bool: | 
					
						
							|  |  |  |     """Removes a follower
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     followers_filename = \ | 
					
						
							|  |  |  |         acct_dir(base_dir, nickname, domain) + '/followers.txt' | 
					
						
							|  |  |  |     if not os.path.isfile(followers_filename): | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  |     followers_str = '' | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         with open(followers_filename, 'r', encoding='utf-8') as fp_foll: | 
					
						
							|  |  |  |             followers_str = fp_foll.read() | 
					
						
							|  |  |  |     except OSError: | 
					
						
							|  |  |  |         print('EX: remove_follower unable to read followers ' + | 
					
						
							|  |  |  |               followers_filename) | 
					
						
							| 
									
										
										
										
											2022-12-01 23:26:56 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2022-12-01 23:19:34 +00:00
										 |  |  |     followers_list = followers_str.split('\n') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     handle = remove_nickname + '@' + remove_domain | 
					
						
							|  |  |  |     handle = handle.lower() | 
					
						
							|  |  |  |     new_followers_str = '' | 
					
						
							|  |  |  |     found = False | 
					
						
							|  |  |  |     for handle2 in followers_list: | 
					
						
							|  |  |  |         if handle2.lower() != handle: | 
					
						
							|  |  |  |             new_followers_str += handle2 + '\n' | 
					
						
							|  |  |  |         else: | 
					
						
							| 
									
										
										
										
											2022-12-01 23:36:14 +00:00
										 |  |  |             found = True | 
					
						
							| 
									
										
										
										
											2022-12-01 23:19:34 +00:00
										 |  |  |     if not found: | 
					
						
							| 
									
										
										
										
											2022-12-01 23:00:30 +00:00
										 |  |  |         return False | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         with open(followers_filename, 'w+', encoding='utf-8') as fp_foll: | 
					
						
							| 
									
										
										
										
											2022-12-01 23:26:56 +00:00
										 |  |  |             fp_foll.write(new_followers_str) | 
					
						
							| 
									
										
										
										
											2022-12-01 23:00:30 +00:00
										 |  |  |     except OSError: | 
					
						
							|  |  |  |         print('EX: remove_follower unable to write followers ' + | 
					
						
							|  |  |  |               followers_filename) | 
					
						
							|  |  |  |     return True | 
					
						
							| 
									
										
										
										
											2023-07-11 11:15:27 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def pending_followers_timeline_json(actor: str, base_dir: str, | 
					
						
							|  |  |  |                                     nickname: str, domain: str) -> {}: | 
					
						
							|  |  |  |     """Returns pending followers collection for an account
 | 
					
						
							|  |  |  |     https://codeberg.org/fediverse/fep/src/branch/main/fep/4ccd/fep-4ccd.md | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     result_json = { | 
					
						
							|  |  |  |         "@context": [ | 
					
						
							| 
									
										
										
										
											2024-09-14 16:40:11 +00:00
										 |  |  |             'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |             'https://w3id.org/security/v1' | 
					
						
							| 
									
										
										
										
											2023-07-11 11:15:27 +00:00
										 |  |  |         ], | 
					
						
							|  |  |  |         "id": actor, | 
					
						
							|  |  |  |         "type": "OrderedCollection", | 
					
						
							|  |  |  |         "name": nickname + "'s Pending Followers", | 
					
						
							|  |  |  |         "orderedItems": [] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     follow_requests_filename = \ | 
					
						
							|  |  |  |         acct_dir(base_dir, nickname, domain) + '/followrequests.txt' | 
					
						
							|  |  |  |     if os.path.isfile(follow_requests_filename): | 
					
						
							| 
									
										
										
										
											2024-07-13 14:38:11 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             with open(follow_requests_filename, 'r', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_req: | 
					
						
							|  |  |  |                 for follower_handle in fp_req: | 
					
						
							|  |  |  |                     if len(follower_handle) == 0: | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  |                     follower_handle = remove_eol(follower_handle) | 
					
						
							|  |  |  |                     foll_domain, _ = get_domain_from_actor(follower_handle) | 
					
						
							|  |  |  |                     if not foll_domain: | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  |                     foll_nickname = get_nickname_from_actor(follower_handle) | 
					
						
							|  |  |  |                     if not foll_nickname: | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  |                     follow_activity_filename = \ | 
					
						
							|  |  |  |                         acct_dir(base_dir, nickname, domain) + \ | 
					
						
							|  |  |  |                         '/requests/' + \ | 
					
						
							|  |  |  |                         foll_nickname + '@' + foll_domain + '.follow' | 
					
						
							|  |  |  |                     if not os.path.isfile(follow_activity_filename): | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  |                     follow_json = load_json(follow_activity_filename) | 
					
						
							|  |  |  |                     if not follow_json: | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  |                     result_json['orderedItems'].append(follow_json) | 
					
						
							|  |  |  |         except OSError as exc: | 
					
						
							|  |  |  |             print('EX: unable to read follow requests ' + | 
					
						
							|  |  |  |                   follow_requests_filename + ' ' + str(exc)) | 
					
						
							| 
									
										
										
										
											2023-07-11 11:15:27 +00:00
										 |  |  |     return result_json |