| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | __filename__ = "reaction.py" | 
					
						
							|  |  |  | __author__ = "Bob Mottram" | 
					
						
							|  |  |  | __license__ = "AGPL3+" | 
					
						
							| 
									
										
										
										
											2024-12-22 23:37:30 +00:00
										 |  |  | __version__ = "1.6.0" | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | __maintainer__ = "Bob Mottram" | 
					
						
							|  |  |  | __email__ = "bob@libreserver.org" | 
					
						
							|  |  |  | __status__ = "Production" | 
					
						
							|  |  |  | __module_group__ = "ActivityPub" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import os | 
					
						
							| 
									
										
										
										
											2021-11-10 13:10:02 +00:00
										 |  |  | import re | 
					
						
							| 
									
										
										
										
											2021-11-10 21:43:48 +00:00
										 |  |  | import urllib.parse | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | from pprint import pprint | 
					
						
							| 
									
										
										
										
											2024-09-13 13:58:14 +00:00
										 |  |  | from flags import has_group_type | 
					
						
							|  |  |  | from flags import url_permitted | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  | from utils import data_dir | 
					
						
							| 
									
										
										
										
											2021-12-26 17:12:07 +00:00
										 |  |  | from utils import has_object_string | 
					
						
							| 
									
										
										
										
											2021-12-26 15:54:46 +00:00
										 |  |  | from utils import has_object_string_object | 
					
						
							| 
									
										
										
										
											2022-04-09 15:11:22 +00:00
										 |  |  | from utils import has_object_string_type | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  | from utils import remove_domain_port | 
					
						
							| 
									
										
										
										
											2021-12-26 10:57:03 +00:00
										 |  |  | from utils import has_object_dict | 
					
						
							| 
									
										
										
										
											2021-12-26 12:19:00 +00:00
										 |  |  | from utils import has_users_path | 
					
						
							| 
									
										
										
										
											2021-12-26 12:45:03 +00:00
										 |  |  | from utils import get_full_domain | 
					
						
							| 
									
										
										
										
											2021-12-27 11:20:57 +00:00
										 |  |  | from utils import remove_id_ending | 
					
						
							| 
									
										
										
										
											2021-12-27 22:19:18 +00:00
										 |  |  | from utils import get_nickname_from_actor | 
					
						
							| 
									
										
										
										
											2021-12-27 19:05:25 +00:00
										 |  |  | from utils import get_domain_from_actor | 
					
						
							| 
									
										
										
										
											2021-12-26 20:36:08 +00:00
										 |  |  | from utils import locate_post | 
					
						
							| 
									
										
										
										
											2021-12-27 23:02:50 +00:00
										 |  |  | from utils import undo_reaction_collection_entry | 
					
						
							| 
									
										
										
										
											2021-12-26 10:19:59 +00:00
										 |  |  | from utils import local_actor_url | 
					
						
							| 
									
										
										
										
											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-27 11:05:24 +00:00
										 |  |  | from utils import remove_post_from_cache | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  | from utils import get_cached_post_filename | 
					
						
							| 
									
										
										
										
											2021-12-27 17:53:41 +00:00
										 |  |  | from utils import contains_invalid_chars | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | from posts import send_signed_json | 
					
						
							|  |  |  | from session import post_json | 
					
						
							|  |  |  | 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 posts import get_person_box | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 17:35:54 +00:00
										 |  |  | # the maximum number of reactions from individual actors which can be | 
					
						
							|  |  |  | # added to a post. Hence an adversary can't bombard you with sockpuppet | 
					
						
							|  |  |  | # generated reactions and make the post infeasibly large | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  | MAX_ACTOR_REACTIONS_PER_POST = 64 | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 17:35:54 +00:00
										 |  |  | # regex defining permissable emoji icon range | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  | EMOJI_REGEX = re.compile(r'[\u263a-\U0001f645]') | 
					
						
							| 
									
										
										
										
											2021-11-10 13:10:02 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  | def valid_emoji_content(emoji_content: str) -> bool: | 
					
						
							| 
									
										
										
										
											2021-11-10 13:10:02 +00:00
										 |  |  |     """Is the given emoji content valid?
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if not emoji_content: | 
					
						
							| 
									
										
										
										
											2021-11-10 13:10:02 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if len(emoji_content) > 2: | 
					
						
							| 
									
										
										
										
											2021-11-10 13:10:02 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if len(EMOJI_REGEX.findall(emoji_content)) == 0: | 
					
						
							| 
									
										
										
										
											2021-11-10 13:10:02 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if contains_invalid_chars(emoji_content): | 
					
						
							| 
									
										
										
										
											2021-11-11 10:35:05 +00:00
										 |  |  |         return False | 
					
						
							| 
									
										
										
										
											2021-11-10 13:10:02 +00:00
										 |  |  |     return True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def _reactionpost(recent_posts_cache: {}, | 
					
						
							|  |  |  |                   session, base_dir: str, federation_list: [], | 
					
						
							|  |  |  |                   nickname: str, domain: str, port: int, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                   cc_list: [], http_prefix: str, | 
					
						
							|  |  |  |                   object_url: str, emoji_content: str, | 
					
						
							|  |  |  |                   actor_reaction: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                   client_to_server: bool, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                   send_threads: [], post_log: [], | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                   person_cache: {}, cached_webfingers: {}, | 
					
						
							|  |  |  |                   debug: bool, project_version: str, | 
					
						
							| 
									
										
										
										
											2022-03-13 20:16:39 +00:00
										 |  |  |                   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: []) -> {}: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     """Creates an emoji reaction
 | 
					
						
							|  |  |  |     actor is the person doing the reacting | 
					
						
							|  |  |  |     'to' might be a specific person (actor) whose post was reaction | 
					
						
							|  |  |  |     object is typically the url of the message which was reaction | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if not url_permitted(object_url, federation_list): | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if not valid_emoji_content(emoji_content): | 
					
						
							|  |  |  |         print('_reaction: Invalid emoji reaction: "' + emoji_content + '"') | 
					
						
							| 
									
										
										
										
											2024-05-24 12:50:11 +00:00
										 |  |  |         return None | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     full_domain = get_full_domain(domain, port) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     new_reaction_json = { | 
					
						
							| 
									
										
										
										
											2024-09-14 16:40:11 +00:00
										 |  |  |         "@context": [ | 
					
						
							|  |  |  |             'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |             'https://w3id.org/security/v1' | 
					
						
							|  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         'type': 'EmojiReact', | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         'actor': local_actor_url(http_prefix, nickname, full_domain), | 
					
						
							|  |  |  |         'object': object_url, | 
					
						
							|  |  |  |         'content': emoji_content | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if cc_list: | 
					
						
							| 
									
										
										
										
											2025-04-12 20:14:32 +00:00
										 |  |  |         new_reaction_json['cc'] = cc_list | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # Extract the domain and nickname from a statuses link | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     reaction_post_nickname = None | 
					
						
							|  |  |  |     reaction_post_domain = None | 
					
						
							|  |  |  |     reaction_post_port = None | 
					
						
							| 
									
										
										
										
											2021-12-26 00:07:44 +00:00
										 |  |  |     group_account = False | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if actor_reaction: | 
					
						
							|  |  |  |         reaction_post_nickname = get_nickname_from_actor(actor_reaction) | 
					
						
							|  |  |  |         reaction_post_domain, reaction_post_port = \ | 
					
						
							|  |  |  |             get_domain_from_actor(actor_reaction) | 
					
						
							|  |  |  |         group_account = has_group_type(base_dir, actor_reaction, person_cache) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         if has_users_path(object_url): | 
					
						
							|  |  |  |             reaction_post_nickname = get_nickname_from_actor(object_url) | 
					
						
							|  |  |  |             reaction_post_domain, reaction_post_port = \ | 
					
						
							|  |  |  |                 get_domain_from_actor(object_url) | 
					
						
							| 
									
										
										
										
											2023-01-15 14:33:18 +00:00
										 |  |  |             if reaction_post_domain: | 
					
						
							|  |  |  |                 if '/' + str(reaction_post_nickname) + '/' in object_url: | 
					
						
							|  |  |  |                     actor_reaction = \ | 
					
						
							|  |  |  |                         object_url.split('/' + | 
					
						
							|  |  |  |                                          reaction_post_nickname + '/')[0] + \ | 
					
						
							|  |  |  |                         '/' + reaction_post_nickname | 
					
						
							|  |  |  |                     group_account = \ | 
					
						
							|  |  |  |                         has_group_type(base_dir, actor_reaction, person_cache) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if reaction_post_nickname: | 
					
						
							|  |  |  |         post_filename = locate_post(base_dir, nickname, domain, object_url) | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         if not post_filename: | 
					
						
							| 
									
										
										
										
											2021-12-25 16:17:53 +00:00
										 |  |  |             print('DEBUG: reaction base_dir: ' + base_dir) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |             print('DEBUG: reaction nickname: ' + nickname) | 
					
						
							|  |  |  |             print('DEBUG: reaction domain: ' + domain) | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             print('DEBUG: reaction object_url: ' + object_url) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |             return None | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |         actor_url = get_actor_from_post(new_reaction_json) | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         update_reaction_collection(recent_posts_cache, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                                    base_dir, post_filename, object_url, | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |                                    actor_url, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                                    nickname, domain, debug, None, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                                    emoji_content) | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-17 21:13:43 +00:00
										 |  |  |         extra_headers = {} | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         send_signed_json(new_reaction_json, session, base_dir, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                          nickname, domain, port, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                          reaction_post_nickname, | 
					
						
							|  |  |  |                          reaction_post_domain, reaction_post_port, | 
					
						
							| 
									
										
										
										
											2022-05-31 13:34:29 +00:00
										 |  |  |                          http_prefix, client_to_server, federation_list, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                          send_threads, post_log, cached_webfingers, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                          person_cache, | 
					
						
							|  |  |  |                          debug, project_version, None, group_account, | 
					
						
							| 
									
										
										
										
											2022-03-13 20:16:39 +00:00
										 |  |  |                          signing_priv_key_pem, 7165392, | 
					
						
							| 
									
										
										
										
											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) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     return new_reaction_json | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def reaction_post(recent_posts_cache: {}, | 
					
						
							|  |  |  |                   session, base_dir: str, federation_list: [], | 
					
						
							|  |  |  |                   nickname: str, domain: str, port: int, http_prefix: str, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                   reaction_nickname: str, reaction_domain: str, | 
					
						
							|  |  |  |                   reaction_port: int, cc_list: [], | 
					
						
							|  |  |  |                   reaction_status_number: int, emoji_content: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                   client_to_server: bool, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                   send_threads: [], post_log: [], | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                   person_cache: {}, cached_webfingers: {}, | 
					
						
							|  |  |  |                   debug: bool, project_version: str, | 
					
						
							| 
									
										
										
										
											2022-03-13 20:16:39 +00:00
										 |  |  |                   signing_priv_key_pem: str, | 
					
						
							| 
									
										
										
										
											2023-09-15 21:04:31 +00:00
										 |  |  |                   curr_domain: str, onion_domain: str, i2p_domain: str, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                   sites_unavailable: [], system_language: str, | 
					
						
							|  |  |  |                   mitm_servers: []) -> {}: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     """Adds a reaction to a given status post. This is only used by unit tests
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     reaction_domain = get_full_domain(reaction_domain, reaction_port) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     actor_reaction = \ | 
					
						
							|  |  |  |         local_actor_url(http_prefix, reaction_nickname, reaction_domain) | 
					
						
							|  |  |  |     object_url = actor_reaction + '/statuses/' + str(reaction_status_number) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |     return _reactionpost(recent_posts_cache, | 
					
						
							|  |  |  |                          session, base_dir, federation_list, | 
					
						
							|  |  |  |                          nickname, domain, port, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                          cc_list, http_prefix, object_url, emoji_content, | 
					
						
							|  |  |  |                          actor_reaction, client_to_server, | 
					
						
							|  |  |  |                          send_threads, post_log, person_cache, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                          cached_webfingers, | 
					
						
							| 
									
										
										
										
											2022-03-13 20:16:39 +00:00
										 |  |  |                          debug, project_version, signing_priv_key_pem, | 
					
						
							| 
									
										
										
										
											2023-09-15 21:04:31 +00:00
										 |  |  |                          curr_domain, onion_domain, i2p_domain, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                          sites_unavailable, system_language, | 
					
						
							|  |  |  |                          mitm_servers) | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def send_reaction_via_server(base_dir: str, session, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                              from_nickname: str, password: str, | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |                              from_domain: str, from_port: int, | 
					
						
							|  |  |  |                              http_prefix: str, reaction_url: str, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                              emoji_content: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                              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: []) -> {}: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     """Creates a reaction via c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('WARN: No session for send_reaction_via_server') | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return 6 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if not valid_emoji_content(emoji_content): | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('send_reaction_via_server: Invalid emoji reaction: "' + | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |               emoji_content + '"') | 
					
						
							| 
									
										
										
										
											2021-11-10 13:10:02 +00:00
										 |  |  |         return 7 | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |     from_domain_full = get_full_domain(from_domain, from_port) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     actor = local_actor_url(http_prefix, from_nickname, from_domain_full) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     new_reaction_json = { | 
					
						
							| 
									
										
										
										
											2024-09-14 16:40:11 +00:00
										 |  |  |         "@context": [ | 
					
						
							|  |  |  |             'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |             'https://w3id.org/security/v1' | 
					
						
							|  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         'type': 'EmojiReact', | 
					
						
							|  |  |  |         'actor': actor, | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |         'object': reaction_url, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         'content': emoji_content | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     handle = http_prefix + '://' + from_domain_full + '/@' + from_nickname | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # lookup the inbox for the To handle | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     wf_request = webfinger_handle(session, handle, http_prefix, | 
					
						
							|  |  |  |                                   cached_webfingers, | 
					
						
							|  |  |  |                                   from_domain, project_version, debug, False, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                                   signing_priv_key_pem, mitm_servers) | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if not wf_request: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: reaction webfinger failed for ' + handle) | 
					
						
							|  |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if not isinstance(wf_request, dict): | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         print('WARN: reaction webfinger for ' + handle + | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |               ' did not return a dict. ' + str(wf_request)) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     post_to_box = 'outbox' | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get the actor inbox for the To handle | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     origin_domain = from_domain | 
					
						
							|  |  |  |     (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, | 
					
						
							| 
									
										
										
										
											2023-10-25 19:55:40 +00:00
										 |  |  |                             post_to_box, 72873, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                             system_language, mitm_servers) | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not inbox_url: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             print('DEBUG: reaction no ' + post_to_box + | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |                   ' was found for ' + handle) | 
					
						
							|  |  |  |         return 3 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if not from_person_id: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: reaction no actor was found for ' + handle) | 
					
						
							|  |  |  |         return 4 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     auth_header = create_basic_auth_header(from_nickname, password) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     headers = { | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         'host': from_domain, | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         'Content-type': 'application/json', | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         'Authorization': auth_header | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     post_result = post_json(http_prefix, from_domain_full, | 
					
						
							|  |  |  |                             session, new_reaction_json, [], inbox_url, | 
					
						
							|  |  |  |                             headers, 3, True) | 
					
						
							|  |  |  |     if not post_result: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             print('WARN: POST reaction failed for c2s to ' + inbox_url) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return 5 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s POST reaction success') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     return new_reaction_json | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def send_undo_reaction_via_server(base_dir: str, session, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                                   from_nickname: str, password: str, | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |                                   from_domain: str, from_port: int, | 
					
						
							|  |  |  |                                   http_prefix: str, reaction_url: str, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                                   emoji_content: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                                   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: []) -> {}: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     """Undo a reaction via c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not session: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |         print('WARN: No session for send_undo_reaction_via_server') | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return 6 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |     from_domain_full = get_full_domain(from_domain, from_port) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     actor = local_actor_url(http_prefix, from_nickname, from_domain_full) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     new_undo_reaction_json = { | 
					
						
							| 
									
										
										
										
											2024-09-14 16:40:11 +00:00
										 |  |  |         "@context": [ | 
					
						
							|  |  |  |             'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |             'https://w3id.org/security/v1' | 
					
						
							|  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         'type': 'Undo', | 
					
						
							|  |  |  |         'actor': actor, | 
					
						
							|  |  |  |         'object': { | 
					
						
							|  |  |  |             'type': 'EmojiReact', | 
					
						
							|  |  |  |             'actor': actor, | 
					
						
							| 
									
										
										
										
											2022-05-30 21:41:18 +00:00
										 |  |  |             'object': reaction_url, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             'content': emoji_content | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     handle = http_prefix + '://' + from_domain_full + '/@' + from_nickname | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # lookup the inbox for the To handle | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     wf_request = webfinger_handle(session, handle, http_prefix, | 
					
						
							|  |  |  |                                   cached_webfingers, | 
					
						
							|  |  |  |                                   from_domain, project_version, debug, False, | 
					
						
							| 
									
										
										
										
											2024-12-17 13:50:48 +00:00
										 |  |  |                                   signing_priv_key_pem, mitm_servers) | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if not wf_request: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: unreaction webfinger failed for ' + handle) | 
					
						
							|  |  |  |         return 1 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if not isinstance(wf_request, dict): | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('WARN: unreaction webfinger for ' + handle + | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                   ' did not return a dict. ' + str(wf_request)) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return 1 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     post_to_box = 'outbox' | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # get the actor inbox for the To handle | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     origin_domain = from_domain | 
					
						
							|  |  |  |     (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
										 |  |  |                             72625, system_language, | 
					
						
							|  |  |  |                             mitm_servers) | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not inbox_url: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             print('DEBUG: unreaction no ' + post_to_box + | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |                   ' was found for ' + handle) | 
					
						
							|  |  |  |         return 3 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if not from_person_id: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: unreaction no actor was found for ' + handle) | 
					
						
							|  |  |  |         return 4 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     auth_header = create_basic_auth_header(from_nickname, password) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     headers = { | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         'host': from_domain, | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         'Content-type': 'application/json', | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         'Authorization': auth_header | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     post_result = post_json(http_prefix, from_domain_full, | 
					
						
							|  |  |  |                             session, new_undo_reaction_json, [], inbox_url, | 
					
						
							|  |  |  |                             headers, 3, True) | 
					
						
							|  |  |  |     if not post_result: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             print('WARN: POST unreaction failed for c2s to ' + inbox_url) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return 5 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s POST unreaction success') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     return new_undo_reaction_json | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def outbox_reaction(recent_posts_cache: {}, | 
					
						
							| 
									
										
										
										
											2022-06-12 21:31:53 +00:00
										 |  |  |                     base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                     message_json: {}, debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     """ When a reaction request is received by the outbox from c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json.get('type'): | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: reaction - no type') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['type'] == 'EmojiReact': | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: not a reaction') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 17:12:07 +00:00
										 |  |  |     if not has_object_string(message_json, debug): | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json.get('content'): | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not isinstance(message_json['content'], str): | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |     if not valid_emoji_content(message_json['content']): | 
					
						
							|  |  |  |         print('outbox_reaction: Invalid emoji reaction: "' + | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |               message_json['content'] + '"') | 
					
						
							| 
									
										
										
										
											2021-11-10 13:10:02 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s reaction request arrived in outbox') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     message_id = remove_id_ending(message_json['object']) | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     emoji_content = message_json['content'] | 
					
						
							|  |  |  |     post_filename = locate_post(base_dir, nickname, domain, message_id) | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     if not post_filename: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s reaction post not found in inbox or outbox') | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             print(message_id) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return True | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |     actor_url = get_actor_from_post(message_json) | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |     update_reaction_collection(recent_posts_cache, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                                base_dir, post_filename, message_id, | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |                                actor_url, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                                nickname, domain, debug, None, emoji_content) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         print('DEBUG: post reaction via c2s - ' + post_filename) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def outbox_undo_reaction(recent_posts_cache: {}, | 
					
						
							| 
									
										
										
										
											2022-06-12 21:31:53 +00:00
										 |  |  |                          base_dir: str, nickname: str, domain: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                          message_json: {}, debug: bool) -> None: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     """ When an undo reaction request is received by the outbox from c2s
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json.get('type'): | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['type'] == 'Undo': | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2022-04-09 15:11:22 +00:00
										 |  |  |     if not has_object_string_type(message_json, debug): | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['object']['type'] == 'EmojiReact': | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: not a undo reaction') | 
					
						
							|  |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not message_json['object'].get('content'): | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-25 23:51:19 +00:00
										 |  |  |     if not isinstance(message_json['object']['content'], str): | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return | 
					
						
							| 
									
										
										
										
											2021-12-26 15:54:46 +00:00
										 |  |  |     if not has_object_string_object(message_json, debug): | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return | 
					
						
							|  |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: c2s undo reaction request arrived in outbox') | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     message_id = remove_id_ending(message_json['object']['object']) | 
					
						
							|  |  |  |     emoji_content = message_json['object']['content'] | 
					
						
							| 
									
										
										
										
											2021-12-26 18:17:37 +00:00
										 |  |  |     domain = remove_domain_port(domain) | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     post_filename = locate_post(base_dir, nickname, domain, message_id) | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     if not post_filename: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         if debug: | 
					
						
							|  |  |  |             print('DEBUG: c2s undo reaction post not found in inbox or outbox') | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             print(message_id) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return True | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |     actor_url = get_actor_from_post(message_json) | 
					
						
							| 
									
										
										
										
											2021-12-27 23:02:50 +00:00
										 |  |  |     undo_reaction_collection_entry(recent_posts_cache, base_dir, post_filename, | 
					
						
							| 
									
										
										
										
											2024-02-15 12:41:09 +00:00
										 |  |  |                                    actor_url, domain, debug, None, | 
					
						
							|  |  |  |                                    emoji_content) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     if debug: | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         print('DEBUG: post undo reaction via c2s - ' + post_filename) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:49:53 +00:00
										 |  |  | def _update_common_reactions(base_dir: str, emoji_content: str) -> None: | 
					
						
							|  |  |  |     """Updates the list of commonly used reactions
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2024-05-12 12:35:26 +00:00
										 |  |  |     common_reactions_filename = data_dir(base_dir) + '/common_reactions.txt' | 
					
						
							| 
									
										
										
										
											2022-04-18 20:49:53 +00:00
										 |  |  |     common_reactions = None | 
					
						
							|  |  |  |     if os.path.isfile(common_reactions_filename): | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |             with open(common_reactions_filename, 'r', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_react: | 
					
						
							| 
									
										
										
										
											2022-04-18 20:49:53 +00:00
										 |  |  |                 common_reactions = fp_react.readlines() | 
					
						
							|  |  |  |         except OSError: | 
					
						
							| 
									
										
										
										
											2024-07-13 14:38:11 +00:00
										 |  |  |             print('EX: unable to load common reactions file' + | 
					
						
							|  |  |  |                   common_reactions_filename) | 
					
						
							| 
									
										
										
										
											2022-04-18 20:49:53 +00:00
										 |  |  |     if common_reactions: | 
					
						
							| 
									
										
										
										
											2024-12-23 17:45:20 +00:00
										 |  |  |         new_common_reactions: list[str] = [] | 
					
						
							| 
									
										
										
										
											2022-04-18 20:49:53 +00:00
										 |  |  |         reaction_found = False | 
					
						
							|  |  |  |         for line in common_reactions: | 
					
						
							|  |  |  |             if ' ' + emoji_content in line: | 
					
						
							|  |  |  |                 if not reaction_found: | 
					
						
							|  |  |  |                     reaction_found = True | 
					
						
							|  |  |  |                     counter = 1 | 
					
						
							|  |  |  |                     count_str = line.split(' ')[0] | 
					
						
							|  |  |  |                     if count_str.isdigit(): | 
					
						
							|  |  |  |                         counter = int(count_str) + 1 | 
					
						
							|  |  |  |                     count_str = str(counter).zfill(16) | 
					
						
							|  |  |  |                     line = count_str + ' ' + emoji_content | 
					
						
							|  |  |  |                     new_common_reactions.append(line) | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2022-06-21 11:58:50 +00:00
										 |  |  |                 line1 = remove_eol(line) | 
					
						
							|  |  |  |                 new_common_reactions.append(line1) | 
					
						
							| 
									
										
										
										
											2022-04-18 20:49:53 +00:00
										 |  |  |         if not reaction_found: | 
					
						
							|  |  |  |             new_common_reactions.append(str(1).zfill(16) + ' ' + emoji_content) | 
					
						
							|  |  |  |         new_common_reactions.sort(reverse=True) | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |             with open(common_reactions_filename, 'w+', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_react: | 
					
						
							| 
									
										
										
										
											2022-04-18 20:49:53 +00:00
										 |  |  |                 for line in new_common_reactions: | 
					
						
							|  |  |  |                     fp_react.write(line + '\n') | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: error writing common reactions 1') | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         line = str(1).zfill(16) + ' ' + emoji_content + '\n' | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2022-06-09 14:46:30 +00:00
										 |  |  |             with open(common_reactions_filename, 'w+', | 
					
						
							|  |  |  |                       encoding='utf-8') as fp_react: | 
					
						
							| 
									
										
										
										
											2022-04-18 20:49:53 +00:00
										 |  |  |                 fp_react.write(line) | 
					
						
							|  |  |  |         except OSError: | 
					
						
							|  |  |  |             print('EX: error writing common reactions 2') | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def update_reaction_collection(recent_posts_cache: {}, | 
					
						
							|  |  |  |                                base_dir: str, post_filename: str, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                                object_url: str, actor: str, | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                                nickname: str, domain: str, debug: bool, | 
					
						
							|  |  |  |                                post_json_object: {}, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                                emoji_content: str) -> None: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     """Updates the reactions collection within a post
 | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not post_json_object: | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         post_json_object = load_json(post_filename) | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not post_json_object: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # remove any cached version of this post so that the | 
					
						
							|  |  |  |     # reaction icon is changed | 
					
						
							| 
									
										
										
										
											2021-12-27 11:05:24 +00:00
										 |  |  |     remove_post_from_cache(post_json_object, recent_posts_cache) | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     cached_post_filename = \ | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |         get_cached_post_filename(base_dir, nickname, | 
					
						
							|  |  |  |                                  domain, post_json_object) | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     if cached_post_filename: | 
					
						
							|  |  |  |         if os.path.isfile(cached_post_filename): | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |             try: | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                 os.remove(cached_post_filename) | 
					
						
							| 
									
										
										
										
											2021-11-25 18:42:38 +00:00
										 |  |  |             except OSError: | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  |                 print('EX: update_reaction_collection unable to delete ' + | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                       cached_post_filename) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     obj = post_json_object | 
					
						
							| 
									
										
										
										
											2021-12-26 10:57:03 +00:00
										 |  |  |     if has_object_dict(post_json_object): | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |         obj = post_json_object['object'] | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-31 11:07:00 +00:00
										 |  |  |     reactions_ending = '/reactions' | 
					
						
							|  |  |  |     if not object_url.endswith(reactions_ending): | 
					
						
							|  |  |  |         collection_id = object_url + reactions_ending | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         collection_id = object_url | 
					
						
							|  |  |  |         reactions_ending_len = len(object_url) - len(reactions_ending) | 
					
						
							|  |  |  |         object_url = object_url[:reactions_ending_len] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     if not obj.get('reactions'): | 
					
						
							|  |  |  |         if debug: | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             print('DEBUG: Adding initial emoji reaction to ' + object_url) | 
					
						
							|  |  |  |         reactions_json = { | 
					
						
							| 
									
										
										
										
											2024-09-14 16:40:11 +00:00
										 |  |  |             "@context": [ | 
					
						
							|  |  |  |                 'https://www.w3.org/ns/activitystreams', | 
					
						
							|  |  |  |                 'https://w3id.org/security/v1' | 
					
						
							|  |  |  |             ], | 
					
						
							| 
									
										
										
										
											2025-03-31 11:07:00 +00:00
										 |  |  |             'id': collection_id, | 
					
						
							|  |  |  |             'reactionsOf': object_url, | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |             'type': 'Collection', | 
					
						
							|  |  |  |             "totalItems": 1, | 
					
						
							|  |  |  |             'items': [{ | 
					
						
							|  |  |  |                 'type': 'EmojiReact', | 
					
						
							|  |  |  |                 'actor': actor, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                 'content': emoji_content | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |             }] | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         obj['reactions'] = reactions_json | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     else: | 
					
						
							|  |  |  |         if not obj['reactions'].get('items'): | 
					
						
							| 
									
										
										
										
											2024-12-23 17:45:20 +00:00
										 |  |  |             obj['reactions']['items']: list[dict] = [] | 
					
						
							| 
									
										
										
										
											2021-11-10 17:35:54 +00:00
										 |  |  |         # upper limit for the number of reactions on a post | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         if len(obj['reactions']['items']) >= MAX_ACTOR_REACTIONS_PER_POST: | 
					
						
							| 
									
										
										
										
											2021-11-10 17:35:54 +00:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         for reaction_item in obj['reactions']['items']: | 
					
						
							|  |  |  |             if reaction_item.get('actor') and reaction_item.get('content'): | 
					
						
							|  |  |  |                 if reaction_item['actor'] == actor and \ | 
					
						
							|  |  |  |                    reaction_item['content'] == emoji_content: | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |                     # already reaction | 
					
						
							|  |  |  |                     return | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         new_reaction = { | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |             'type': 'EmojiReact', | 
					
						
							|  |  |  |             'actor': actor, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             'content': emoji_content | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         obj['reactions']['items'].append(new_reaction) | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |         itlen = len(obj['reactions']['items']) | 
					
						
							|  |  |  |         obj['reactions']['totalItems'] = itlen | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-18 20:49:53 +00:00
										 |  |  |     _update_common_reactions(base_dir, emoji_content) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 12:16:03 +00:00
										 |  |  |     if debug: | 
					
						
							|  |  |  |         print('DEBUG: saving post with emoji reaction added') | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |         pprint(post_json_object) | 
					
						
							| 
									
										
										
										
											2021-12-26 23:41:34 +00:00
										 |  |  |     save_json(post_json_object, post_filename) | 
					
						
							| 
									
										
										
										
											2021-11-10 17:14:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 21:55:09 +00:00
										 |  |  | def html_emoji_reactions(post_json_object: {}, interactive: bool, | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |                          actor: str, max_reaction_types: int, | 
					
						
							|  |  |  |                          box_name: str, page_number: int) -> str: | 
					
						
							| 
									
										
										
										
											2021-11-10 17:14:51 +00:00
										 |  |  |     """html containing row of emoji reactions
 | 
					
						
							| 
									
										
										
										
											2021-11-13 20:48:53 +00:00
										 |  |  |     displayed at the bottom of posts, above the icons | 
					
						
							| 
									
										
										
										
											2021-11-10 17:14:51 +00:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2021-12-26 10:57:03 +00:00
										 |  |  |     if not has_object_dict(post_json_object): | 
					
						
							| 
									
										
										
										
											2021-11-10 17:14:51 +00:00
										 |  |  |         return '' | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not post_json_object.get('actor'): | 
					
						
							| 
									
										
										
										
											2021-11-12 11:40:27 +00:00
										 |  |  |         return '' | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not post_json_object['object'].get('reactions'): | 
					
						
							| 
									
										
										
										
											2021-11-10 17:14:51 +00:00
										 |  |  |         return '' | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     if not post_json_object['object']['reactions'].get('items'): | 
					
						
							| 
									
										
										
										
											2021-11-10 17:14:51 +00:00
										 |  |  |         return '' | 
					
						
							|  |  |  |     reactions = {} | 
					
						
							| 
									
										
										
										
											2024-12-23 17:45:20 +00:00
										 |  |  |     reacted_to_by_this_actor: list[str] = [] | 
					
						
							| 
									
										
										
										
											2021-12-25 22:09:19 +00:00
										 |  |  |     for item in post_json_object['object']['reactions']['items']: | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         emoji_content = item['content'] | 
					
						
							|  |  |  |         emoji_actor = item['actor'] | 
					
						
							|  |  |  |         emoji_nickname = get_nickname_from_actor(emoji_actor) | 
					
						
							| 
									
										
										
										
											2022-03-23 23:59:29 +00:00
										 |  |  |         if not emoji_nickname: | 
					
						
							|  |  |  |             return '' | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         emoji_domain, _ = get_domain_from_actor(emoji_actor) | 
					
						
							| 
									
										
										
										
											2023-01-15 14:33:18 +00:00
										 |  |  |         if not emoji_domain: | 
					
						
							|  |  |  |             return '' | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         emoji_handle = emoji_nickname + '@' + emoji_domain | 
					
						
							|  |  |  |         if emoji_actor == actor: | 
					
						
							|  |  |  |             if emoji_content not in reacted_to_by_this_actor: | 
					
						
							|  |  |  |                 reacted_to_by_this_actor.append(emoji_content) | 
					
						
							|  |  |  |         if not reactions.get(emoji_content): | 
					
						
							|  |  |  |             if len(reactions.items()) < max_reaction_types: | 
					
						
							|  |  |  |                 reactions[emoji_content] = { | 
					
						
							|  |  |  |                     "handles": [emoji_handle], | 
					
						
							| 
									
										
										
										
											2021-11-13 20:48:53 +00:00
										 |  |  |                     "count": 1 | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-11-10 17:14:51 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             reactions[emoji_content]['count'] += 1 | 
					
						
							|  |  |  |             if len(reactions[emoji_content]['handles']) < 32: | 
					
						
							|  |  |  |                 reactions[emoji_content]['handles'].append(emoji_handle) | 
					
						
							| 
									
										
										
										
											2021-11-10 17:14:51 +00:00
										 |  |  |     if len(reactions.items()) == 0: | 
					
						
							|  |  |  |         return '' | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |     react_by = remove_id_ending(post_json_object['object']['id']) | 
					
						
							|  |  |  |     html_str = '<div class="emojiReactionBar">\n' | 
					
						
							|  |  |  |     for emoji_content, item in reactions.items(): | 
					
						
							| 
									
										
										
										
											2021-11-13 20:48:53 +00:00
										 |  |  |         count = item['count'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # get the handles of actors who reacted | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         handles_str = '' | 
					
						
							| 
									
										
										
										
											2021-11-13 20:48:53 +00:00
										 |  |  |         item['handles'].sort() | 
					
						
							|  |  |  |         for handle in item['handles']: | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             if handles_str: | 
					
						
							|  |  |  |                 handles_str += '
' | 
					
						
							|  |  |  |             handles_str += handle | 
					
						
							| 
									
										
										
										
											2021-11-13 20:48:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         if emoji_content not in reacted_to_by_this_actor: | 
					
						
							|  |  |  |             base_url = actor + '?react=' + react_by | 
					
						
							| 
									
										
										
										
											2021-11-10 21:55:56 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             base_url = actor + '?unreact=' + react_by | 
					
						
							| 
									
										
										
										
											2024-01-09 16:59:23 +00:00
										 |  |  |         actor_url = get_actor_from_post(post_json_object) | 
					
						
							|  |  |  |         base_url += '?actor=' + actor_url | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         base_url += '?tl=' + box_name | 
					
						
							|  |  |  |         base_url += '?page=' + str(page_number) | 
					
						
							|  |  |  |         base_url += '?emojreact=' | 
					
						
							| 
									
										
										
										
											2021-11-10 21:55:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |         html_str += '  <div class="emojiReactionButton">\n' | 
					
						
							| 
									
										
										
										
											2021-11-10 17:14:51 +00:00
										 |  |  |         if count < 100: | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             count_str = str(count) | 
					
						
							| 
									
										
										
										
											2021-11-10 17:14:51 +00:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             count_str = '99+' | 
					
						
							|  |  |  |         emoji_content_str = emoji_content + count_str | 
					
						
							| 
									
										
										
										
											2021-11-10 17:14:51 +00:00
										 |  |  |         if interactive: | 
					
						
							|  |  |  |             # urlencode the emoji | 
					
						
							| 
									
										
										
										
											2021-12-31 11:12:16 +00:00
										 |  |  |             emoji_content_encoded = urllib.parse.quote_plus(emoji_content) | 
					
						
							|  |  |  |             emoji_content_str = \ | 
					
						
							|  |  |  |                 '    <a href="' + base_url + emoji_content_encoded + \ | 
					
						
							|  |  |  |                 '" title="' + handles_str + '">' + \ | 
					
						
							|  |  |  |                 emoji_content_str + '</a>\n' | 
					
						
							|  |  |  |         html_str += emoji_content_str | 
					
						
							|  |  |  |         html_str += '  </div>\n' | 
					
						
							|  |  |  |     html_str += '</div>\n' | 
					
						
							|  |  |  |     return html_str |