diff --git a/daemon_get.py b/daemon_get.py index 96725ceb4..33715cd38 100644 --- a/daemon_get.py +++ b/daemon_get.py @@ -19,13 +19,6 @@ from city import get_spoofed_city from roles import get_actor_roles_list from languages import get_understood_languages from languages import get_reply_language -from bookmarks import undo_bookmark_post -from bookmarks import bookmark_post -from reaction import update_reaction_collection -from like import update_likes_collection -from manualapprove import manual_deny_follow_request_thread -from manualapprove import manual_approve_follow_request_thread -from announce import create_announce from webfinger import webfinger_lookup from webfinger import webfinger_node_info from webfinger import webfinger_meta @@ -49,11 +42,8 @@ from blog import html_blog_post from blog import path_contains_blog_link from blog import html_blog_view from speaker import get_ssml_box -from follow import follower_approval_active from follow import pending_followers_timeline_json from follow import get_following_feed -from blocking import unmute_post -from blocking import mute_post from blocking import broch_mode_is_active from blocking import remove_global_block from blocking import update_blocked_cache @@ -87,7 +77,6 @@ from webapp_manual import html_manual from webapp_specification import html_specification from webapp_about import html_about from webapp_tos import html_terms_of_service -from webapp_confirm import html_confirm_delete from webapp_confirm import html_confirm_remove_shared_item from webapp_welcome_profile import html_welcome_profile from webapp_welcome_final import html_welcome_final @@ -104,7 +93,6 @@ from webapp_login import html_login from webapp_post import html_individual_post from webapp_post import html_post_replies from webapp_post import html_emoji_reaction_picker -from webapp_post import individual_post_as_html from followerSync import update_followers_sync_cache from securemode import secure_mode from fitnessFunctions import sorted_watch_points @@ -113,7 +101,6 @@ from fitnessFunctions import html_watch_points_graph from session import establish_session from session import get_session_for_domains from crawlers import blocked_user_agent -from daemon_utils import post_to_outbox from daemon_utils import etag_exists from daemon_utils import has_accept from daemon_utils import show_person_options @@ -143,15 +130,8 @@ from utils import get_occupation_skills from utils import is_public_post_from_url from utils import can_reply_to from utils import get_new_post_endpoints -from utils import undo_reaction_collection_entry -from utils import undo_likes_collection_entry -from utils import get_full_domain -from utils import get_domain_from_actor from utils import save_json -from utils import delete_post from utils import locate_post -from utils import is_dm -from utils import get_cached_post_filename from utils import get_image_mime_type from utils import get_image_extensions from utils import is_account_dir @@ -191,8 +171,6 @@ from shares import shares_catalog_account_endpoint from shares import shares_catalog_csv_endpoint from posts import remove_post_interactions from posts import populate_replies_json -from posts import get_original_post_from_announce_url -from posts import save_post_to_box from posts import json_pin_post from posts import is_moderator from posts import get_pinned_post_as_json @@ -224,6 +202,19 @@ from daemon_get_feeds import show_following_feed from daemon_get_feeds import show_moved_feed from daemon_get_feeds import show_inactive_feed from daemon_get_feeds import show_followers_feed +from daemon_get_buttons import announce_button +from daemon_get_buttons import announce_button_undo +from daemon_get_buttons import follow_approve_button +from daemon_get_buttons import follow_deny_button +from daemon_get_buttons import like_button +from daemon_get_buttons import like_button_undo +from daemon_get_buttons import reaction_button +from daemon_get_buttons import reaction_button_undo +from daemon_get_buttons import bookmark_button +from daemon_get_buttons import bookmark_button_undo +from daemon_get_buttons import delete_button +from daemon_get_buttons import mute_button +from daemon_get_buttons import mute_button_undo # Blogs can be longer, so don't show many per page MAX_POSTS_IN_BLOGS_FEED = 4 @@ -3074,20 +3065,20 @@ def daemon_http_get(self) -> None: self.path = self.path.replace('?repeatprivate=', '?repeat=') # announce/repeat button was pressed if authorized and html_getreq and '?repeat=' in self.path: - _announce_button(self, calling_domain, self.path, - self.server.base_dir, - cookie, proxy_type, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.port, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - repeat_private, - self.server.debug, - curr_session, - self.server.sites_unavailable) + announce_button(self, calling_domain, self.path, + self.server.base_dir, + cookie, proxy_type, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.port, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + repeat_private, + self.server.debug, + curr_session, + self.server.sites_unavailable) self.server.getreq_busy = False return @@ -3100,18 +3091,18 @@ def daemon_http_get(self) -> None: # undo an announce/repeat from the web interface if authorized and html_getreq and '?unrepeat=' in self.path: - _announce_button_undo(self, calling_domain, self.path, - self.server.base_dir, - cookie, proxy_type, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - self.server.debug, - self.server.recent_posts_cache, - curr_session) + announce_button_undo(self, calling_domain, self.path, + self.server.base_dir, + cookie, proxy_type, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + self.server.debug, + self.server.recent_posts_cache, + curr_session) self.server.getreq_busy = False return @@ -3153,19 +3144,19 @@ def daemon_http_get(self) -> None: # send a follow request approval from the web interface if authorized and '/followapprove=' in self.path and \ self.path.startswith('/users/'): - _follow_approve_button(self, calling_domain, self.path, - cookie, - self.server.base_dir, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.port, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - proxy_type, - self.server.debug, - curr_session) + follow_approve_button(self, calling_domain, self.path, + cookie, + self.server.base_dir, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.port, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + proxy_type, + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -3176,17 +3167,17 @@ def daemon_http_get(self) -> None: # deny a follow request from the web interface if authorized and '/followdeny=' in self.path and \ self.path.startswith('/users/'): - _follow_deny_button(self, calling_domain, self.path, - cookie, - self.server.base_dir, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.port, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - self.server.debug) + follow_deny_button(self, calling_domain, self.path, + cookie, + self.server.base_dir, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.port, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + self.server.debug) self.server.getreq_busy = False return @@ -3196,18 +3187,18 @@ def daemon_http_get(self) -> None: # like from the web interface icon if authorized and html_getreq and '?like=' in self.path: - _like_button(self, calling_domain, self.path, - self.server.base_dir, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - proxy_type, - cookie, - self.server.debug, - curr_session) + like_button(self, calling_domain, self.path, + self.server.base_dir, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + proxy_type, + cookie, + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -3217,17 +3208,17 @@ def daemon_http_get(self) -> None: # undo a like from the web interface icon if authorized and html_getreq and '?unlike=' in self.path: - _undo_like_button(self, calling_domain, self.path, - self.server.base_dir, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - proxy_type, - cookie, self.server.debug, - curr_session) + like_button_undo(self, calling_domain, self.path, + self.server.base_dir, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + proxy_type, + cookie, self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -3239,18 +3230,18 @@ def daemon_http_get(self) -> None: if authorized and html_getreq and \ '?react=' in self.path and \ '?actor=' in self.path: - _reaction_button(self, calling_domain, self.path, - self.server.base_dir, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - proxy_type, - cookie, - self.server.debug, - curr_session) + reaction_button(self, calling_domain, self.path, + self.server.base_dir, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + proxy_type, + cookie, + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -3262,17 +3253,17 @@ def daemon_http_get(self) -> None: if authorized and html_getreq and \ '?unreact=' in self.path and \ '?actor=' in self.path: - _undo_reaction_button(self, calling_domain, self.path, - self.server.base_dir, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - proxy_type, - cookie, self.server.debug, - curr_session) + reaction_button_undo(self, calling_domain, self.path, + self.server.base_dir, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + proxy_type, + cookie, self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -3282,18 +3273,18 @@ def daemon_http_get(self) -> None: # bookmark from the web interface icon if authorized and html_getreq and '?bookmark=' in self.path: - _bookmark_button(self, calling_domain, self.path, - self.server.base_dir, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.port, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - proxy_type, - cookie, self.server.debug, - curr_session) + bookmark_button(self, calling_domain, self.path, + self.server.base_dir, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.port, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + proxy_type, + cookie, self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -3320,18 +3311,18 @@ def daemon_http_get(self) -> None: # undo a bookmark from the web interface icon if authorized and html_getreq and '?unbookmark=' in self.path: - _undo_bookmark_button(self, calling_domain, self.path, - self.server.base_dir, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.port, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - proxy_type, cookie, - self.server.debug, - curr_session) + bookmark_button_undo(self, calling_domain, self.path, + self.server.base_dir, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.port, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + proxy_type, cookie, + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -3341,16 +3332,16 @@ def daemon_http_get(self) -> None: # delete button is pressed on a post if authorized and html_getreq and '?delete=' in self.path: - _delete_button(self, calling_domain, self.path, - self.server.base_dir, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - proxy_type, cookie, - self.server.debug, - curr_session) + delete_button(self, calling_domain, self.path, + self.server.base_dir, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + proxy_type, cookie, + self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -3360,17 +3351,17 @@ def daemon_http_get(self) -> None: # The mute button is pressed if authorized and html_getreq and '?mute=' in self.path: - _mute_button2(self, calling_domain, self.path, - self.server.base_dir, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.port, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - cookie, self.server.debug, - curr_session) + mute_button(self, calling_domain, self.path, + self.server.base_dir, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.port, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + cookie, self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -3380,17 +3371,17 @@ def daemon_http_get(self) -> None: # unmute a post from the web interface icon if authorized and html_getreq and '?unmute=' in self.path: - _undo_mute_button(self, calling_domain, self.path, - self.server.base_dir, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.port, - self.server.onion_domain, - self.server.i2p_domain, - getreq_start_time, - cookie, self.server.debug, - curr_session) + mute_button_undo(self, calling_domain, self.path, + self.server.base_dir, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.port, + self.server.onion_domain, + self.server.i2p_domain, + getreq_start_time, + cookie, self.server.debug, + curr_session) self.server.getreq_busy = False return @@ -6104,361 +6095,6 @@ def _confirm_delete_event(self, calling_domain: str, path: str, return True -def _announce_button(self, calling_domain: str, path: str, - base_dir: str, - cookie: str, proxy_type: str, - http_prefix: str, - domain: str, domain_full: str, port: int, - onion_domain: str, i2p_domain: str, - getreq_start_time, - repeat_private: bool, - debug: bool, - curr_session, sites_unavailable: []) -> None: - """The announce/repeat button was pressed on a post - """ - page_number = 1 - repeat_url = path.split('?repeat=')[1] - if '?' in repeat_url: - repeat_url = repeat_url.split('?')[0] - first_post_id = '' - if '?firstpost=' in path: - first_post_id = path.split('?firstpost=')[1] - if '?' in first_post_id: - first_post_id = first_post_id.split('?')[0] - first_post_id = first_post_id.replace('/', '--') - first_post_id = ';firstpost=' + first_post_id.replace('#', '--') - timeline_bookmark = '' - if '?bm=' in path: - timeline_bookmark = path.split('?bm=')[1] - if '?' in timeline_bookmark: - timeline_bookmark = timeline_bookmark.split('?')[0] - timeline_bookmark = '#' + timeline_bookmark - if '?page=' in path: - page_number_str = path.split('?page=')[1] - if ';' in page_number_str: - page_number_str = page_number_str.split(';')[0] - if '?' in page_number_str: - page_number_str = page_number_str.split('?')[0] - if '#' in page_number_str: - page_number_str = page_number_str.split('#')[0] - if len(page_number_str) > 5: - page_number_str = "1" - if page_number_str.isdigit(): - page_number = int(page_number_str) - timeline_str = 'inbox' - if '?tl=' in path: - timeline_str = path.split('?tl=')[1] - if '?' in timeline_str: - timeline_str = timeline_str.split('?')[0] - actor = path.split('?repeat=')[0] - self.post_to_nickname = get_nickname_from_actor(actor) - if not self.post_to_nickname: - print('WARN: unable to find nickname in ' + actor) - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - actor - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) - redirect_headers(self, actor_path_str, cookie, - calling_domain) - return - - if onion_domain: - if '.onion/' in actor: - curr_session = self.server.session_onion - proxy_type = 'tor' - if i2p_domain: - if '.onion/' in actor: - curr_session = self.server.session_i2p - proxy_type = 'i2p' - - curr_session = \ - establish_session("announceButton", - curr_session, proxy_type, - self.server) - if not curr_session: - http_404(self, 47) - return - self.server.actorRepeat = path.split('?actor=')[1] - announce_to_str = \ - local_actor_url(http_prefix, self.post_to_nickname, - domain_full) + \ - '/followers' - if not repeat_private: - announce_to_str = 'https://www.w3.org/ns/activitystreams#Public' - announce_id = None - announce_json = \ - create_announce(curr_session, - base_dir, - self.server.federation_list, - self.post_to_nickname, - domain, port, - announce_to_str, - None, http_prefix, - repeat_url, False, False, - self.server.send_threads, - self.server.postLog, - self.server.person_cache, - self.server.cached_webfingers, - debug, - self.server.project_version, - self.server.signing_priv_key_pem, - self.server.domain, - onion_domain, - i2p_domain, sites_unavailable, - self.server.system_language) - announce_filename = None - if announce_json: - # save the announce straight to the outbox - # This is because the subsequent send is within a separate thread - # but the html still needs to be generated before this call ends - announce_id = remove_id_ending(announce_json['id']) - announce_filename = \ - save_post_to_box(base_dir, http_prefix, announce_id, - self.post_to_nickname, domain_full, - announce_json, 'outbox') - - # clear the icon from the cache so that it gets updated - if self.server.iconsCache.get('repeat.png'): - del self.server.iconsCache['repeat.png'] - - # send out the announce within a separate thread - post_to_outbox(self, announce_json, - self.server.project_version, - self.post_to_nickname, - curr_session, proxy_type) - - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_announce_button postToOutboxThread', - self.server.debug) - - # generate the html for the announce - if announce_json and announce_filename: - if debug: - print('Generating html post for announce') - cached_post_filename = \ - get_cached_post_filename(base_dir, self.post_to_nickname, - domain, announce_json) - if debug: - print('Announced post json: ' + str(announce_json)) - print('Announced post nickname: ' + - self.post_to_nickname + ' ' + domain) - print('Announced post cache: ' + str(cached_post_filename)) - show_individual_post_icons = True - manually_approve_followers = \ - follower_approval_active(base_dir, - self.post_to_nickname, domain) - show_repeats = not is_dm(announce_json) - timezone = None - if self.server.account_timezone.get(self.post_to_nickname): - timezone = \ - self.server.account_timezone.get(self.post_to_nickname) - mitm = False - if os.path.isfile(announce_filename.replace('.json', '') + - '.mitm'): - mitm = True - bold_reading = False - if self.server.bold_reading.get(self.post_to_nickname): - bold_reading = True - minimize_all_images = False - if self.post_to_nickname in self.server.min_images_for_accounts: - minimize_all_images = True - individual_post_as_html(self.server.signing_priv_key_pem, False, - self.server.recent_posts_cache, - self.server.max_recent_posts, - self.server.translate, - page_number, base_dir, - curr_session, - self.server.cached_webfingers, - self.server.person_cache, - self.post_to_nickname, domain, - self.server.port, announce_json, - None, True, - self.server.allow_deletion, - http_prefix, self.server.project_version, - timeline_str, - self.server.yt_replace_domain, - self.server.twitter_replacement_domain, - self.server.show_published_date_only, - self.server.peertube_instances, - self.server.allow_local_network_access, - self.server.theme_name, - self.server.system_language, - self.server.max_like_count, - show_repeats, - show_individual_post_icons, - manually_approve_followers, - False, True, False, - self.server.cw_lists, - self.server.lists_enabled, - timezone, mitm, bold_reading, - self.server.dogwhistles, - minimize_all_images, None, - self.server.buy_sites, - self.server.auto_cw_cache) - - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - '/users/' + self.post_to_nickname - - actor_path_str = \ - actor_absolute + '/' + timeline_str + '?page=' + \ - str(page_number) + first_post_id + timeline_bookmark - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_announce_button', - self.server.debug) - redirect_headers(self, actor_path_str, cookie, calling_domain) - - -def _announce_button_undo(self, calling_domain: str, path: str, - base_dir: str, cookie: str, proxy_type: str, - http_prefix: str, domain: str, domain_full: str, - onion_domain: str, i2p_domain: str, - getreq_start_time, debug: bool, - recent_posts_cache: {}, curr_session) -> None: - """Undo announce/repeat button was pressed - """ - page_number = 1 - - # the post which was referenced by the announce post - repeat_url = path.split('?unrepeat=')[1] - if '?' in repeat_url: - repeat_url = repeat_url.split('?')[0] - - first_post_id = '' - if '?firstpost=' in path: - first_post_id = path.split('?firstpost=')[1] - if '?' in first_post_id: - first_post_id = first_post_id.split('?')[0] - first_post_id = first_post_id.replace('/', '--') - first_post_id = ';firstpost=' + first_post_id.replace('#', '--') - - timeline_bookmark = '' - if '?bm=' in path: - timeline_bookmark = path.split('?bm=')[1] - if '?' in timeline_bookmark: - timeline_bookmark = timeline_bookmark.split('?')[0] - timeline_bookmark = '#' + timeline_bookmark - if '?page=' in path: - page_number_str = path.split('?page=')[1] - if ';' in page_number_str: - page_number_str = page_number_str.split(';')[0] - if '?' in page_number_str: - page_number_str = page_number_str.split('?')[0] - if '#' in page_number_str: - page_number_str = page_number_str.split('#')[0] - if len(page_number_str) > 5: - page_number_str = "1" - if page_number_str.isdigit(): - page_number = int(page_number_str) - timeline_str = 'inbox' - if '?tl=' in path: - timeline_str = path.split('?tl=')[1] - if '?' in timeline_str: - timeline_str = timeline_str.split('?')[0] - actor = path.split('?unrepeat=')[0] - self.post_to_nickname = get_nickname_from_actor(actor) - if not self.post_to_nickname: - print('WARN: unable to find nickname in ' + actor) - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - actor - actor_path_str = \ - actor_absolute + '/' + timeline_str + '?page=' + \ - str(page_number) - redirect_headers(self, actor_path_str, cookie, - calling_domain) - return - - if onion_domain: - if '.onion/' in actor: - curr_session = self.server.session_onion - proxy_type = 'tor' - if i2p_domain: - if '.onion/' in actor: - curr_session = self.server.session_i2p - proxy_type = 'i2p' - - curr_session = \ - establish_session("undoAnnounceButton", - curr_session, proxy_type, - self.server) - if not curr_session: - http_404(self, 48) - return - undo_announce_actor = \ - http_prefix + '://' + domain_full + \ - '/users/' + self.post_to_nickname - un_repeat_to_str = 'https://www.w3.org/ns/activitystreams#Public' - new_undo_announce = { - "@context": "https://www.w3.org/ns/activitystreams", - 'actor': undo_announce_actor, - 'type': 'Undo', - 'cc': [undo_announce_actor + '/followers'], - 'to': [un_repeat_to_str], - 'object': { - 'actor': undo_announce_actor, - 'cc': [undo_announce_actor + '/followers'], - 'object': repeat_url, - 'to': [un_repeat_to_str], - 'type': 'Announce' - } - } - # clear the icon from the cache so that it gets updated - if self.server.iconsCache.get('repeat_inactive.png'): - del self.server.iconsCache['repeat_inactive.png'] - - # delete the announce post - if '?unannounce=' in path: - announce_url = path.split('?unannounce=')[1] - if '?' in announce_url: - announce_url = announce_url.split('?')[0] - post_filename = None - nickname = get_nickname_from_actor(announce_url) - if nickname: - if domain_full + '/users/' + nickname + '/' in announce_url: - post_filename = \ - locate_post(base_dir, nickname, domain, announce_url) - if post_filename: - delete_post(base_dir, http_prefix, - nickname, domain, post_filename, - debug, recent_posts_cache, True) - - post_to_outbox(self, new_undo_announce, - self.server.project_version, - self.post_to_nickname, - curr_session, proxy_type) - - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - '/users/' + self.post_to_nickname - - actor_path_str = \ - actor_absolute + '/' + timeline_str + '?page=' + \ - str(page_number) + first_post_id + timeline_bookmark - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_undo_announce_button', - self.server.debug) - redirect_headers(self, actor_path_str, cookie, calling_domain) - - def _newswire_vote(self, calling_domain: str, path: str, cookie: str, base_dir: str, http_prefix: str, @@ -6569,1571 +6205,6 @@ def _newswire_unvote(self, calling_domain: str, path: str, '_GET', '_newswire_unvote', debug) -def _follow_approve_button(self, calling_domain: str, path: str, - cookie: str, - base_dir: str, http_prefix: str, - domain: str, domain_full: str, port: int, - onion_domain: str, i2p_domain: str, - getreq_start_time, - proxy_type: str, debug: bool, - curr_session) -> None: - """Follow approve button was pressed - """ - origin_path_str = path.split('/followapprove=')[0] - follower_nickname = origin_path_str.replace('/users/', '') - following_handle = path.split('/followapprove=')[1] - if '://' in following_handle: - handle_nickname = get_nickname_from_actor(following_handle) - handle_domain, handle_port = \ - get_domain_from_actor(following_handle) - if not handle_nickname or not handle_domain: - http_404(self, 49) - return - following_handle = \ - handle_nickname + '@' + \ - get_full_domain(handle_domain, handle_port) - if '@' in following_handle: - if self.server.onion_domain: - if following_handle.endswith('.onion'): - curr_session = self.server.session_onion - proxy_type = 'tor' - port = 80 - if self.server.i2p_domain: - if following_handle.endswith('.i2p'): - curr_session = self.server.session_i2p - proxy_type = 'i2p' - port = 80 - - curr_session = \ - establish_session("follow_approve_button", - curr_session, proxy_type, - self.server) - if not curr_session: - print('WARN: unable to establish session ' + - 'when approving follow request') - http_404(self, 50) - return - signing_priv_key_pem = \ - self.server.signing_priv_key_pem - followers_sync_cache = \ - self.server.followers_sync_cache - manual_approve_follow_request_thread(self.server.session, - self.server.session_onion, - self.server.session_i2p, - self.server.onion_domain, - self.server.i2p_domain, - base_dir, http_prefix, - follower_nickname, - domain, port, - following_handle, - self.server.federation_list, - self.server.send_threads, - self.server.postLog, - self.server.cached_webfingers, - self.server.person_cache, - debug, - self.server.project_version, - signing_priv_key_pem, - proxy_type, - followers_sync_cache, - self.server.sites_unavailable, - self.server.system_language) - origin_path_str_absolute = \ - http_prefix + '://' + domain_full + origin_path_str - if calling_domain.endswith('.onion') and onion_domain: - origin_path_str_absolute = \ - 'http://' + onion_domain + origin_path_str - elif (calling_domain.endswith('.i2p') and i2p_domain): - origin_path_str_absolute = \ - 'http://' + i2p_domain + origin_path_str - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_follow_approve_button', - self.server.debug) - redirect_headers(self, origin_path_str_absolute, - cookie, calling_domain) - - -def _follow_deny_button(self, calling_domain: str, path: str, - cookie: str, base_dir: str, http_prefix: str, - domain: str, domain_full: str, port: int, - onion_domain: str, i2p_domain: str, - getreq_start_time, debug: bool) -> None: - """Follow deny button was pressed - """ - origin_path_str = path.split('/followdeny=')[0] - follower_nickname = origin_path_str.replace('/users/', '') - following_handle = path.split('/followdeny=')[1] - if '://' in following_handle: - handle_nickname = get_nickname_from_actor(following_handle) - handle_domain, handle_port = \ - get_domain_from_actor(following_handle) - if not handle_nickname or not handle_domain: - http_404(self, 51) - return - following_handle = \ - handle_nickname + '@' + \ - get_full_domain(handle_domain, handle_port) - if '@' in following_handle: - manual_deny_follow_request_thread(self.server.session, - self.server.session_onion, - self.server.session_i2p, - onion_domain, - i2p_domain, - base_dir, http_prefix, - follower_nickname, - domain, port, - following_handle, - self.server.federation_list, - self.server.send_threads, - self.server.postLog, - self.server.cached_webfingers, - self.server.person_cache, - debug, - self.server.project_version, - self.server.signing_priv_key_pem, - self.server.followers_sync_cache, - self.server.sites_unavailable, - self.server.system_language) - origin_path_str_absolute = \ - http_prefix + '://' + domain_full + origin_path_str - if calling_domain.endswith('.onion') and onion_domain: - origin_path_str_absolute = \ - 'http://' + onion_domain + origin_path_str - elif calling_domain.endswith('.i2p') and i2p_domain: - origin_path_str_absolute = \ - 'http://' + i2p_domain + origin_path_str - redirect_headers(self, origin_path_str_absolute, - cookie, calling_domain) - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_follow_deny_button', - self.server.debug) - - -def _like_button(self, calling_domain: str, path: str, - base_dir: str, http_prefix: str, - domain: str, domain_full: str, - onion_domain: str, i2p_domain: str, - getreq_start_time, - proxy_type: str, cookie: str, - debug: str, - curr_session) -> None: - """Press the like button - """ - page_number = 1 - like_url = path.split('?like=')[1] - if '?' in like_url: - like_url = like_url.split('?')[0] - first_post_id = '' - if '?firstpost=' in path: - first_post_id = path.split('?firstpost=')[1] - if '?' in first_post_id: - first_post_id = first_post_id.split('?')[0] - first_post_id = first_post_id.replace('/', '--') - first_post_id = ';firstpost=' + first_post_id.replace('#', '--') - timeline_bookmark = '' - if '?bm=' in path: - timeline_bookmark = path.split('?bm=')[1] - if '?' in timeline_bookmark: - timeline_bookmark = timeline_bookmark.split('?')[0] - timeline_bookmark = '#' + timeline_bookmark - actor = path.split('?like=')[0] - if '?page=' in path: - page_number_str = path.split('?page=')[1] - if ';' in page_number_str: - page_number_str = page_number_str.split(';')[0] - if '?' in page_number_str: - page_number_str = page_number_str.split('?')[0] - if '#' in page_number_str: - page_number_str = page_number_str.split('#')[0] - if len(page_number_str) > 5: - page_number_str = "1" - if page_number_str.isdigit(): - page_number = int(page_number_str) - timeline_str = 'inbox' - if '?tl=' in path: - timeline_str = path.split('?tl=')[1] - if '?' in timeline_str: - timeline_str = timeline_str.split('?')[0] - - self.post_to_nickname = get_nickname_from_actor(actor) - if not self.post_to_nickname: - print('WARN: unable to find nickname in ' + actor) - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - actor - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) + timeline_bookmark - redirect_headers(self, actor_path_str, cookie, - calling_domain) - return - - if onion_domain: - if '.onion/' in actor: - curr_session = self.server.session_onion - proxy_type = 'tor' - if i2p_domain: - if '.onion/' in actor: - curr_session = self.server.session_i2p - proxy_type = 'i2p' - - curr_session = \ - establish_session("likeButton", - curr_session, proxy_type, - self.server) - if not curr_session: - http_404(self, 52) - return - like_actor = \ - local_actor_url(http_prefix, self.post_to_nickname, domain_full) - actor_liked = path.split('?actor=')[1] - if '?' in actor_liked: - actor_liked = actor_liked.split('?')[0] - - # if this is an announce then send the like to the original post - orig_actor, orig_post_url, orig_filename = \ - get_original_post_from_announce_url(like_url, base_dir, - self.post_to_nickname, domain) - like_url2 = like_url - liked_post_filename = orig_filename - if orig_actor and orig_post_url: - actor_liked = orig_actor - like_url2 = orig_post_url - liked_post_filename = None - - like_json = { - "@context": "https://www.w3.org/ns/activitystreams", - 'type': 'Like', - 'actor': like_actor, - 'to': [actor_liked], - 'object': like_url2 - } - - # send out the like to followers - post_to_outbox(self, like_json, self.server.project_version, None, - curr_session, proxy_type) - - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_like_button postToOutbox', - self.server.debug) - - print('Locating liked post ' + like_url) - # directly like the post file - if not liked_post_filename: - liked_post_filename = \ - locate_post(base_dir, self.post_to_nickname, domain, like_url) - if liked_post_filename: - recent_posts_cache = self.server.recent_posts_cache - liked_post_json = load_json(liked_post_filename, 0, 1) - if orig_filename and orig_post_url: - update_likes_collection(recent_posts_cache, - base_dir, liked_post_filename, - like_url, like_actor, - self.post_to_nickname, - domain, debug, liked_post_json) - like_url = orig_post_url - liked_post_filename = orig_filename - if debug: - print('Updating likes for ' + liked_post_filename) - update_likes_collection(recent_posts_cache, - base_dir, liked_post_filename, like_url, - like_actor, self.post_to_nickname, domain, - debug, None) - if debug: - print('Regenerating html post for changed likes collection') - # clear the icon from the cache so that it gets updated - if liked_post_json: - cached_post_filename = \ - get_cached_post_filename(base_dir, self.post_to_nickname, - domain, liked_post_json) - if debug: - print('Liked post json: ' + str(liked_post_json)) - print('Liked post nickname: ' + - self.post_to_nickname + ' ' + domain) - print('Liked post cache: ' + str(cached_post_filename)) - show_individual_post_icons = True - manually_approve_followers = \ - follower_approval_active(base_dir, - self.post_to_nickname, domain) - show_repeats = not is_dm(liked_post_json) - timezone = None - if self.server.account_timezone.get(self.post_to_nickname): - timezone = \ - self.server.account_timezone.get(self.post_to_nickname) - mitm = False - if os.path.isfile(liked_post_filename.replace('.json', '') + - '.mitm'): - mitm = True - bold_reading = False - if self.server.bold_reading.get(self.post_to_nickname): - bold_reading = True - minimize_all_images = False - if self.post_to_nickname in \ - self.server.min_images_for_accounts: - minimize_all_images = True - individual_post_as_html(self.server.signing_priv_key_pem, - False, - self.server.recent_posts_cache, - self.server.max_recent_posts, - self.server.translate, - page_number, base_dir, - curr_session, - self.server.cached_webfingers, - self.server.person_cache, - self.post_to_nickname, domain, - self.server.port, liked_post_json, - None, True, - self.server.allow_deletion, - http_prefix, - self.server.project_version, - timeline_str, - self.server.yt_replace_domain, - self.server.twitter_replacement_domain, - self.server.show_published_date_only, - self.server.peertube_instances, - self.server.allow_local_network_access, - self.server.theme_name, - self.server.system_language, - self.server.max_like_count, - show_repeats, - show_individual_post_icons, - manually_approve_followers, - False, True, False, - self.server.cw_lists, - self.server.lists_enabled, - timezone, mitm, bold_reading, - self.server.dogwhistles, - minimize_all_images, None, - self.server.buy_sites, - self.server.auto_cw_cache) - else: - print('WARN: Liked post not found: ' + liked_post_filename) - # clear the icon from the cache so that it gets updated - if self.server.iconsCache.get('like.png'): - del self.server.iconsCache['like.png'] - else: - print('WARN: unable to locate file for liked post ' + - like_url) - - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - '/users/' + self.post_to_nickname - - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) + first_post_id + \ - timeline_bookmark - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_like_button', - self.server.debug) - redirect_headers(self, actor_path_str, cookie, - calling_domain) - - -def _undo_like_button(self, calling_domain: str, path: str, - base_dir: str, http_prefix: str, - domain: str, domain_full: str, - onion_domain: str, i2p_domain: str, - getreq_start_time, - proxy_type: str, cookie: str, - debug: str, - curr_session) -> None: - """A button is pressed to undo - """ - page_number = 1 - like_url = path.split('?unlike=')[1] - if '?' in like_url: - like_url = like_url.split('?')[0] - first_post_id = '' - if '?firstpost=' in path: - first_post_id = path.split('?firstpost=')[1] - if '?' in first_post_id: - first_post_id = first_post_id.split('?')[0] - first_post_id = first_post_id.replace('/', '--') - first_post_id = ';firstpost=' + first_post_id.replace('#', '--') - timeline_bookmark = '' - if '?bm=' in path: - timeline_bookmark = path.split('?bm=')[1] - if '?' in timeline_bookmark: - timeline_bookmark = timeline_bookmark.split('?')[0] - timeline_bookmark = '#' + timeline_bookmark - if '?page=' in path: - page_number_str = path.split('?page=')[1] - if ';' in page_number_str: - page_number_str = page_number_str.split(';')[0] - if '?' in page_number_str: - page_number_str = page_number_str.split('?')[0] - if '#' in page_number_str: - page_number_str = page_number_str.split('#')[0] - if len(page_number_str) > 5: - page_number_str = "1" - if page_number_str.isdigit(): - page_number = int(page_number_str) - timeline_str = 'inbox' - if '?tl=' in path: - timeline_str = path.split('?tl=')[1] - if '?' in timeline_str: - timeline_str = timeline_str.split('?')[0] - actor = path.split('?unlike=')[0] - self.post_to_nickname = get_nickname_from_actor(actor) - if not self.post_to_nickname: - print('WARN: unable to find nickname in ' + actor) - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - actor - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) - redirect_headers(self, actor_path_str, cookie, - calling_domain) - return - - if onion_domain: - if '.onion/' in actor: - curr_session = self.server.session_onion - proxy_type = 'tor' - if i2p_domain: - if '.onion/' in actor: - curr_session = self.server.session_i2p - proxy_type = 'i2p' - - curr_session = \ - establish_session("undoLikeButton", - curr_session, proxy_type, - self.server) - if not curr_session: - http_404(self, 53) - return - undo_actor = \ - local_actor_url(http_prefix, self.post_to_nickname, domain_full) - actor_liked = path.split('?actor=')[1] - if '?' in actor_liked: - actor_liked = actor_liked.split('?')[0] - - # if this is an announce then send the like to the original post - orig_actor, orig_post_url, orig_filename = \ - get_original_post_from_announce_url(like_url, base_dir, - self.post_to_nickname, domain) - like_url2 = like_url - liked_post_filename = orig_filename - if orig_actor and orig_post_url: - actor_liked = orig_actor - like_url2 = orig_post_url - liked_post_filename = None - - undo_like_json = { - "@context": "https://www.w3.org/ns/activitystreams", - 'type': 'Undo', - 'actor': undo_actor, - 'to': [actor_liked], - 'object': { - 'type': 'Like', - 'actor': undo_actor, - 'to': [actor_liked], - 'object': like_url2 - } - } - - # send out the undo like to followers - post_to_outbox(self, undo_like_json, - self.server.project_version, None, - curr_session, proxy_type) - - # directly undo the like within the post file - if not liked_post_filename: - liked_post_filename = locate_post(base_dir, self.post_to_nickname, - domain, like_url) - if liked_post_filename: - recent_posts_cache = self.server.recent_posts_cache - liked_post_json = load_json(liked_post_filename, 0, 1) - if orig_filename and orig_post_url: - undo_likes_collection_entry(recent_posts_cache, - base_dir, liked_post_filename, - undo_actor, - domain, debug, - liked_post_json) - like_url = orig_post_url - liked_post_filename = orig_filename - if debug: - print('Removing likes for ' + liked_post_filename) - undo_likes_collection_entry(recent_posts_cache, - base_dir, - liked_post_filename, - undo_actor, domain, debug, None) - if debug: - print('Regenerating html post for changed likes collection') - if liked_post_json: - show_individual_post_icons = True - manually_approve_followers = \ - follower_approval_active(base_dir, - self.post_to_nickname, domain) - show_repeats = not is_dm(liked_post_json) - timezone = None - if self.server.account_timezone.get(self.post_to_nickname): - timezone = \ - self.server.account_timezone.get(self.post_to_nickname) - mitm = False - if os.path.isfile(liked_post_filename.replace('.json', '') + - '.mitm'): - mitm = True - bold_reading = False - if self.server.bold_reading.get(self.post_to_nickname): - bold_reading = True - minimize_all_images = False - if self.post_to_nickname in \ - self.server.min_images_for_accounts: - minimize_all_images = True - individual_post_as_html(self.server.signing_priv_key_pem, - False, - self.server.recent_posts_cache, - self.server.max_recent_posts, - self.server.translate, - page_number, base_dir, - curr_session, - self.server.cached_webfingers, - self.server.person_cache, - self.post_to_nickname, domain, - self.server.port, liked_post_json, - None, True, - self.server.allow_deletion, - http_prefix, - self.server.project_version, - timeline_str, - self.server.yt_replace_domain, - self.server.twitter_replacement_domain, - self.server.show_published_date_only, - self.server.peertube_instances, - self.server.allow_local_network_access, - self.server.theme_name, - self.server.system_language, - self.server.max_like_count, - show_repeats, - show_individual_post_icons, - manually_approve_followers, - False, True, False, - self.server.cw_lists, - self.server.lists_enabled, - timezone, mitm, bold_reading, - self.server.dogwhistles, - minimize_all_images, None, - self.server.buy_sites, - self.server.auto_cw_cache) - else: - print('WARN: Unliked post not found: ' + liked_post_filename) - # clear the icon from the cache so that it gets updated - if self.server.iconsCache.get('like_inactive.png'): - del self.server.iconsCache['like_inactive.png'] - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - '/users/' + self.post_to_nickname - - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) + first_post_id + \ - timeline_bookmark - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_undo_like_button', - self.server.debug) - redirect_headers(self, actor_path_str, cookie, - calling_domain) - - -def _reaction_button(self, calling_domain: str, path: str, - base_dir: str, http_prefix: str, - domain: str, domain_full: str, - onion_domain: str, i2p_domain: str, - getreq_start_time, - proxy_type: str, cookie: str, - debug: str, - curr_session) -> None: - """Press an emoji reaction button - Note that this is not the emoji reaction selection icon at the - bottom of the post - """ - page_number = 1 - reaction_url = path.split('?react=')[1] - if '?' in reaction_url: - reaction_url = reaction_url.split('?')[0] - first_post_id = '' - if '?firstpost=' in path: - first_post_id = path.split('?firstpost=')[1] - if '?' in first_post_id: - first_post_id = first_post_id.split('?')[0] - first_post_id = first_post_id.replace('/', '--') - first_post_id = ';firstpost=' + first_post_id.replace('#', '--') - timeline_bookmark = '' - if '?bm=' in path: - timeline_bookmark = path.split('?bm=')[1] - if '?' in timeline_bookmark: - timeline_bookmark = timeline_bookmark.split('?')[0] - timeline_bookmark = '#' + timeline_bookmark - actor = path.split('?react=')[0] - if '?page=' in path: - page_number_str = path.split('?page=')[1] - if ';' in page_number_str: - page_number_str = page_number_str.split(';')[0] - if '?' in page_number_str: - page_number_str = page_number_str.split('?')[0] - if '#' in page_number_str: - page_number_str = page_number_str.split('#')[0] - if len(page_number_str) > 5: - page_number_str = "1" - if page_number_str.isdigit(): - page_number = int(page_number_str) - timeline_str = 'inbox' - if '?tl=' in path: - timeline_str = path.split('?tl=')[1] - if '?' in timeline_str: - timeline_str = timeline_str.split('?')[0] - emoji_content_encoded = None - if '?emojreact=' in path: - emoji_content_encoded = path.split('?emojreact=')[1] - if '?' in emoji_content_encoded: - emoji_content_encoded = emoji_content_encoded.split('?')[0] - if not emoji_content_encoded: - print('WARN: no emoji reaction ' + actor) - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - actor - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) + timeline_bookmark - redirect_headers(self, actor_path_str, cookie, - calling_domain) - return - emoji_content = urllib.parse.unquote_plus(emoji_content_encoded) - self.post_to_nickname = get_nickname_from_actor(actor) - if not self.post_to_nickname: - print('WARN: unable to find nickname in ' + actor) - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - actor - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) + timeline_bookmark - redirect_headers(self, actor_path_str, cookie, - calling_domain) - return - - if onion_domain: - if '.onion/' in actor: - curr_session = self.server.session_onion - proxy_type = 'tor' - if i2p_domain: - if '.onion/' in actor: - curr_session = self.server.session_i2p - proxy_type = 'i2p' - - curr_session = \ - establish_session("reactionButton", - curr_session, proxy_type, - self.server) - if not curr_session: - http_404(self, 54) - return - reaction_actor = \ - local_actor_url(http_prefix, self.post_to_nickname, domain_full) - actor_reaction = path.split('?actor=')[1] - if '?' in actor_reaction: - actor_reaction = actor_reaction.split('?')[0] - - # if this is an announce then send the emoji reaction - # to the original post - orig_actor, orig_post_url, orig_filename = \ - get_original_post_from_announce_url(reaction_url, base_dir, - self.post_to_nickname, domain) - reaction_url2 = reaction_url - reaction_post_filename = orig_filename - if orig_actor and orig_post_url: - actor_reaction = orig_actor - reaction_url2 = orig_post_url - reaction_post_filename = None - - reaction_json = { - "@context": "https://www.w3.org/ns/activitystreams", - 'type': 'EmojiReact', - 'actor': reaction_actor, - 'to': [actor_reaction], - 'object': reaction_url2, - 'content': emoji_content - } - - # send out the emoji reaction to followers - post_to_outbox(self, reaction_json, self.server.project_version, None, - curr_session, proxy_type) - - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_reaction_button postToOutbox', - self.server.debug) - - print('Locating emoji reaction post ' + reaction_url) - # directly emoji reaction the post file - if not reaction_post_filename: - reaction_post_filename = \ - locate_post(base_dir, self.post_to_nickname, domain, - reaction_url) - if reaction_post_filename: - recent_posts_cache = self.server.recent_posts_cache - reaction_post_json = load_json(reaction_post_filename, 0, 1) - if orig_filename and orig_post_url: - update_reaction_collection(recent_posts_cache, - base_dir, reaction_post_filename, - reaction_url, - reaction_actor, - self.post_to_nickname, - domain, debug, reaction_post_json, - emoji_content) - reaction_url = orig_post_url - reaction_post_filename = orig_filename - if debug: - print('Updating emoji reaction for ' + reaction_post_filename) - update_reaction_collection(recent_posts_cache, - base_dir, reaction_post_filename, - reaction_url, - reaction_actor, - self.post_to_nickname, domain, - debug, None, emoji_content) - if debug: - print('Regenerating html post for changed ' + - 'emoji reaction collection') - # clear the icon from the cache so that it gets updated - if reaction_post_json: - cached_post_filename = \ - get_cached_post_filename(base_dir, self.post_to_nickname, - domain, reaction_post_json) - if debug: - print('Reaction post json: ' + str(reaction_post_json)) - print('Reaction post nickname: ' + - self.post_to_nickname + ' ' + domain) - print('Reaction post cache: ' + str(cached_post_filename)) - show_individual_post_icons = True - manually_approve_followers = \ - follower_approval_active(base_dir, - self.post_to_nickname, domain) - show_repeats = not is_dm(reaction_post_json) - timezone = None - if self.server.account_timezone.get(self.post_to_nickname): - timezone = \ - self.server.account_timezone.get(self.post_to_nickname) - mitm = False - if os.path.isfile(reaction_post_filename.replace('.json', '') + - '.mitm'): - mitm = True - bold_reading = False - if self.server.bold_reading.get(self.post_to_nickname): - bold_reading = True - minimize_all_images = False - if self.post_to_nickname in \ - self.server.min_images_for_accounts: - minimize_all_images = True - individual_post_as_html(self.server.signing_priv_key_pem, - False, - self.server.recent_posts_cache, - self.server.max_recent_posts, - self.server.translate, - page_number, base_dir, - curr_session, - self.server.cached_webfingers, - self.server.person_cache, - self.post_to_nickname, domain, - self.server.port, reaction_post_json, - None, True, - self.server.allow_deletion, - http_prefix, - self.server.project_version, - timeline_str, - self.server.yt_replace_domain, - self.server.twitter_replacement_domain, - self.server.show_published_date_only, - self.server.peertube_instances, - self.server.allow_local_network_access, - self.server.theme_name, - self.server.system_language, - self.server.max_like_count, - show_repeats, - show_individual_post_icons, - manually_approve_followers, - False, True, False, - self.server.cw_lists, - self.server.lists_enabled, - timezone, mitm, bold_reading, - self.server.dogwhistles, - minimize_all_images, None, - self.server.buy_sites, - self.server.auto_cw_cache) - else: - print('WARN: Emoji reaction post not found: ' + - reaction_post_filename) - else: - print('WARN: unable to locate file for emoji reaction post ' + - reaction_url) - - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - '/users/' + self.post_to_nickname - - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) + first_post_id + \ - timeline_bookmark - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_reaction_button', - self.server.debug) - redirect_headers(self, actor_path_str, cookie, - calling_domain) - - -def _undo_reaction_button(self, calling_domain: str, path: str, - base_dir: str, http_prefix: str, - domain: str, domain_full: str, - onion_domain: str, i2p_domain: str, - getreq_start_time, - proxy_type: str, cookie: str, - debug: str, - curr_session) -> None: - """A button is pressed to undo emoji reaction - """ - page_number = 1 - reaction_url = path.split('?unreact=')[1] - if '?' in reaction_url: - reaction_url = reaction_url.split('?')[0] - first_post_id = '' - if '?firstpost=' in path: - first_post_id = path.split('?firstpost=')[1] - if '?' in first_post_id: - first_post_id = first_post_id.split('?')[0] - first_post_id = first_post_id.replace('/', '--') - first_post_id = ';firstpost=' + first_post_id.replace('#', '--') - timeline_bookmark = '' - if '?bm=' in path: - timeline_bookmark = path.split('?bm=')[1] - if '?' in timeline_bookmark: - timeline_bookmark = timeline_bookmark.split('?')[0] - timeline_bookmark = '#' + timeline_bookmark - if '?page=' in path: - page_number_str = path.split('?page=')[1] - if ';' in page_number_str: - page_number_str = page_number_str.split(';')[0] - if '?' in page_number_str: - page_number_str = page_number_str.split('?')[0] - if '#' in page_number_str: - page_number_str = page_number_str.split('#')[0] - if len(page_number_str) > 5: - page_number_str = "1" - if page_number_str.isdigit(): - page_number = int(page_number_str) - timeline_str = 'inbox' - if '?tl=' in path: - timeline_str = path.split('?tl=')[1] - if '?' in timeline_str: - timeline_str = timeline_str.split('?')[0] - actor = path.split('?unreact=')[0] - self.post_to_nickname = get_nickname_from_actor(actor) - if not self.post_to_nickname: - print('WARN: unable to find nickname in ' + actor) - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - actor - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) - redirect_headers(self, actor_path_str, cookie, - calling_domain) - return - emoji_content_encoded = None - if '?emojreact=' in path: - emoji_content_encoded = path.split('?emojreact=')[1] - if '?' in emoji_content_encoded: - emoji_content_encoded = emoji_content_encoded.split('?')[0] - if not emoji_content_encoded: - print('WARN: no emoji reaction ' + actor) - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - actor - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) + timeline_bookmark - redirect_headers(self, actor_path_str, cookie, - calling_domain) - return - emoji_content = urllib.parse.unquote_plus(emoji_content_encoded) - - if onion_domain: - if '.onion/' in actor: - curr_session = self.server.session_onion - proxy_type = 'tor' - if i2p_domain: - if '.onion/' in actor: - curr_session = self.server.session_i2p - proxy_type = 'i2p' - - curr_session = \ - establish_session("undoReactionButton", - curr_session, proxy_type, - self.server) - if not curr_session: - http_404(self, 55) - return - undo_actor = \ - local_actor_url(http_prefix, self.post_to_nickname, domain_full) - actor_reaction = path.split('?actor=')[1] - if '?' in actor_reaction: - actor_reaction = actor_reaction.split('?')[0] - - # if this is an announce then send the emoji reaction - # to the original post - orig_actor, orig_post_url, orig_filename = \ - get_original_post_from_announce_url(reaction_url, base_dir, - self.post_to_nickname, domain) - reaction_url2 = reaction_url - reaction_post_filename = orig_filename - if orig_actor and orig_post_url: - actor_reaction = orig_actor - reaction_url2 = orig_post_url - reaction_post_filename = None - - undo_reaction_json = { - "@context": "https://www.w3.org/ns/activitystreams", - 'type': 'Undo', - 'actor': undo_actor, - 'to': [actor_reaction], - 'object': { - 'type': 'EmojiReact', - 'actor': undo_actor, - 'to': [actor_reaction], - 'object': reaction_url2 - } - } - - # send out the undo emoji reaction to followers - post_to_outbox(self, undo_reaction_json, - self.server.project_version, None, - curr_session, proxy_type) - - # directly undo the emoji reaction within the post file - if not reaction_post_filename: - reaction_post_filename = \ - locate_post(base_dir, self.post_to_nickname, domain, - reaction_url) - if reaction_post_filename: - recent_posts_cache = self.server.recent_posts_cache - reaction_post_json = load_json(reaction_post_filename, 0, 1) - if orig_filename and orig_post_url: - undo_reaction_collection_entry(recent_posts_cache, - base_dir, - reaction_post_filename, - undo_actor, domain, debug, - reaction_post_json, - emoji_content) - reaction_url = orig_post_url - reaction_post_filename = orig_filename - if debug: - print('Removing emoji reaction for ' + reaction_post_filename) - undo_reaction_collection_entry(recent_posts_cache, - base_dir, reaction_post_filename, - undo_actor, domain, debug, - reaction_post_json, emoji_content) - if debug: - print('Regenerating html post for changed ' + - 'emoji reaction collection') - if reaction_post_json: - show_individual_post_icons = True - manually_approve_followers = \ - follower_approval_active(base_dir, - self.post_to_nickname, domain) - show_repeats = not is_dm(reaction_post_json) - timezone = None - if self.server.account_timezone.get(self.post_to_nickname): - timezone = \ - self.server.account_timezone.get(self.post_to_nickname) - mitm = False - if os.path.isfile(reaction_post_filename.replace('.json', '') + - '.mitm'): - mitm = True - bold_reading = False - if self.server.bold_reading.get(self.post_to_nickname): - bold_reading = True - minimize_all_images = False - if self.post_to_nickname in \ - self.server.min_images_for_accounts: - minimize_all_images = True - individual_post_as_html(self.server.signing_priv_key_pem, - False, - self.server.recent_posts_cache, - self.server.max_recent_posts, - self.server.translate, - page_number, base_dir, - curr_session, - self.server.cached_webfingers, - self.server.person_cache, - self.post_to_nickname, domain, - self.server.port, reaction_post_json, - None, True, - self.server.allow_deletion, - http_prefix, - self.server.project_version, - timeline_str, - self.server.yt_replace_domain, - self.server.twitter_replacement_domain, - self.server.show_published_date_only, - self.server.peertube_instances, - self.server.allow_local_network_access, - self.server.theme_name, - self.server.system_language, - self.server.max_like_count, - show_repeats, - show_individual_post_icons, - manually_approve_followers, - False, True, False, - self.server.cw_lists, - self.server.lists_enabled, - timezone, mitm, bold_reading, - self.server.dogwhistles, - minimize_all_images, None, - self.server.buy_sites, - self.server.auto_cw_cache) - else: - print('WARN: Unreaction post not found: ' + - reaction_post_filename) - - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - '/users/' + self.post_to_nickname - - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) + first_post_id + \ - timeline_bookmark - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_undo_reaction_button', - self.server.debug) - redirect_headers(self, actor_path_str, cookie, calling_domain) - - -def _bookmark_button(self, calling_domain: str, path: str, - base_dir: str, http_prefix: str, - domain: str, domain_full: str, port: int, - onion_domain: str, i2p_domain: str, - getreq_start_time, - proxy_type: str, cookie: str, - debug: str, - curr_session) -> None: - """Bookmark button was pressed - """ - page_number = 1 - bookmark_url = path.split('?bookmark=')[1] - if '?' in bookmark_url: - bookmark_url = bookmark_url.split('?')[0] - first_post_id = '' - if '?firstpost=' in path: - first_post_id = path.split('?firstpost=')[1] - if '?' in first_post_id: - first_post_id = first_post_id.split('?')[0] - first_post_id = first_post_id.replace('/', '--') - first_post_id = ';firstpost=' + first_post_id.replace('#', '--') - timeline_bookmark = '' - if '?bm=' in path: - timeline_bookmark = path.split('?bm=')[1] - if '?' in timeline_bookmark: - timeline_bookmark = timeline_bookmark.split('?')[0] - timeline_bookmark = '#' + timeline_bookmark - actor = path.split('?bookmark=')[0] - if '?page=' in path: - page_number_str = path.split('?page=')[1] - if ';' in page_number_str: - page_number_str = page_number_str.split(';')[0] - if '?' in page_number_str: - page_number_str = page_number_str.split('?')[0] - if '#' in page_number_str: - page_number_str = page_number_str.split('#')[0] - if len(page_number_str) > 5: - page_number_str = "1" - if page_number_str.isdigit(): - page_number = int(page_number_str) - timeline_str = 'inbox' - if '?tl=' in path: - timeline_str = path.split('?tl=')[1] - if '?' in timeline_str: - timeline_str = timeline_str.split('?')[0] - - self.post_to_nickname = get_nickname_from_actor(actor) - if not self.post_to_nickname: - print('WARN: unable to find nickname in ' + actor) - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - actor - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) - redirect_headers(self, actor_path_str, cookie, - calling_domain) - return - - if onion_domain: - if '.onion/' in actor: - curr_session = self.server.session_onion - proxy_type = 'tor' - if i2p_domain: - if '.onion/' in actor: - curr_session = self.server.session_i2p - proxy_type = 'i2p' - - curr_session = \ - establish_session("bookmarkButton", - curr_session, proxy_type, - self.server) - if not curr_session: - http_404(self, 56) - return - bookmark_actor = \ - local_actor_url(http_prefix, self.post_to_nickname, domain_full) - cc_list = [] - bookmark_post(self.server.recent_posts_cache, - base_dir, self.server.federation_list, - self.post_to_nickname, domain, port, - cc_list, http_prefix, bookmark_url, bookmark_actor, - debug) - # clear the icon from the cache so that it gets updated - if self.server.iconsCache.get('bookmark.png'): - del self.server.iconsCache['bookmark.png'] - bookmark_filename = \ - locate_post(base_dir, self.post_to_nickname, domain, bookmark_url) - if bookmark_filename: - print('Regenerating html post for changed bookmark') - bookmark_post_json = load_json(bookmark_filename, 0, 1) - if bookmark_post_json: - cached_post_filename = \ - get_cached_post_filename(base_dir, self.post_to_nickname, - domain, bookmark_post_json) - print('Bookmarked post json: ' + str(bookmark_post_json)) - print('Bookmarked post nickname: ' + - self.post_to_nickname + ' ' + domain) - print('Bookmarked post cache: ' + str(cached_post_filename)) - show_individual_post_icons = True - manually_approve_followers = \ - follower_approval_active(base_dir, - self.post_to_nickname, domain) - show_repeats = not is_dm(bookmark_post_json) - timezone = None - if self.server.account_timezone.get(self.post_to_nickname): - timezone = \ - self.server.account_timezone.get(self.post_to_nickname) - mitm = False - if os.path.isfile(bookmark_filename.replace('.json', '') + - '.mitm'): - mitm = True - bold_reading = False - if self.server.bold_reading.get(self.post_to_nickname): - bold_reading = True - minimize_all_images = False - if self.post_to_nickname in \ - self.server.min_images_for_accounts: - minimize_all_images = True - individual_post_as_html(self.server.signing_priv_key_pem, - False, - self.server.recent_posts_cache, - self.server.max_recent_posts, - self.server.translate, - page_number, base_dir, - curr_session, - self.server.cached_webfingers, - self.server.person_cache, - self.post_to_nickname, domain, - self.server.port, bookmark_post_json, - None, True, - self.server.allow_deletion, - http_prefix, - self.server.project_version, - timeline_str, - self.server.yt_replace_domain, - self.server.twitter_replacement_domain, - self.server.show_published_date_only, - self.server.peertube_instances, - self.server.allow_local_network_access, - self.server.theme_name, - self.server.system_language, - self.server.max_like_count, - show_repeats, - show_individual_post_icons, - manually_approve_followers, - False, True, False, - self.server.cw_lists, - self.server.lists_enabled, - timezone, mitm, bold_reading, - self.server.dogwhistles, - minimize_all_images, None, - self.server.buy_sites, - self.server.auto_cw_cache) - else: - print('WARN: Bookmarked post not found: ' + bookmark_filename) - # _post_to_outbox(self, bookmark_json, - # self.server.project_version, None, - # curr_session, proxy_type) - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - '/users/' + self.post_to_nickname - - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) + first_post_id + \ - timeline_bookmark - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_bookmark_button', - debug) - redirect_headers(self, actor_path_str, cookie, - calling_domain) - - -def _undo_bookmark_button(self, calling_domain: str, path: str, - base_dir: str, http_prefix: str, - domain: str, domain_full: str, port: int, - onion_domain: str, i2p_domain: str, - getreq_start_time, - proxy_type: str, cookie: str, - debug: str, - curr_session) -> None: - """Button pressed to undo a bookmark - """ - page_number = 1 - bookmark_url = path.split('?unbookmark=')[1] - if '?' in bookmark_url: - bookmark_url = bookmark_url.split('?')[0] - first_post_id = '' - if '?firstpost=' in path: - first_post_id = path.split('?firstpost=')[1] - if '?' in first_post_id: - first_post_id = first_post_id.split('?')[0] - first_post_id = first_post_id.replace('/', '--') - first_post_id = ';firstpost=' + first_post_id.replace('#', '--') - timeline_bookmark = '' - if '?bm=' in path: - timeline_bookmark = path.split('?bm=')[1] - if '?' in timeline_bookmark: - timeline_bookmark = timeline_bookmark.split('?')[0] - timeline_bookmark = '#' + timeline_bookmark - if '?page=' in path: - page_number_str = path.split('?page=')[1] - if ';' in page_number_str: - page_number_str = page_number_str.split(';')[0] - if '?' in page_number_str: - page_number_str = page_number_str.split('?')[0] - if '#' in page_number_str: - page_number_str = page_number_str.split('#')[0] - if len(page_number_str) > 5: - page_number_str = "1" - if page_number_str.isdigit(): - page_number = int(page_number_str) - timeline_str = 'inbox' - if '?tl=' in path: - timeline_str = path.split('?tl=')[1] - if '?' in timeline_str: - timeline_str = timeline_str.split('?')[0] - actor = path.split('?unbookmark=')[0] - self.post_to_nickname = get_nickname_from_actor(actor) - if not self.post_to_nickname: - print('WARN: unable to find nickname in ' + actor) - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - actor - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) - redirect_headers(self, actor_path_str, cookie, - calling_domain) - return - - if onion_domain: - if '.onion/' in actor: - curr_session = self.server.session_onion - proxy_type = 'tor' - if i2p_domain: - if '.onion/' in actor: - curr_session = self.server.session_i2p - proxy_type = 'i2p' - - curr_session = \ - establish_session("undo_bookmarkButton", - curr_session, proxy_type, - self.server) - if not curr_session: - http_404(self, 57) - return - undo_actor = \ - local_actor_url(http_prefix, self.post_to_nickname, domain_full) - cc_list = [] - undo_bookmark_post(self.server.recent_posts_cache, - base_dir, self.server.federation_list, - self.post_to_nickname, - domain, port, cc_list, http_prefix, - bookmark_url, undo_actor, debug) - # clear the icon from the cache so that it gets updated - if self.server.iconsCache.get('bookmark_inactive.png'): - del self.server.iconsCache['bookmark_inactive.png'] - # post_to_outbox(self, undo_bookmark_json, - # self.server.project_version, None, - # curr_session, proxy_type) - bookmark_filename = \ - locate_post(base_dir, self.post_to_nickname, domain, bookmark_url) - if bookmark_filename: - print('Regenerating html post for changed unbookmark') - bookmark_post_json = load_json(bookmark_filename, 0, 1) - if bookmark_post_json: - cached_post_filename = \ - get_cached_post_filename(base_dir, self.post_to_nickname, - domain, bookmark_post_json) - print('Unbookmarked post json: ' + str(bookmark_post_json)) - print('Unbookmarked post nickname: ' + - self.post_to_nickname + ' ' + domain) - print('Unbookmarked post cache: ' + str(cached_post_filename)) - show_individual_post_icons = True - manually_approve_followers = \ - follower_approval_active(base_dir, - self.post_to_nickname, domain) - show_repeats = not is_dm(bookmark_post_json) - timezone = None - if self.server.account_timezone.get(self.post_to_nickname): - timezone = \ - self.server.account_timezone.get(self.post_to_nickname) - mitm = False - if os.path.isfile(bookmark_filename.replace('.json', '') + - '.mitm'): - mitm = True - bold_reading = False - if self.server.bold_reading.get(self.post_to_nickname): - bold_reading = True - minimize_all_images = False - if self.post_to_nickname in \ - self.server.min_images_for_accounts: - minimize_all_images = True - individual_post_as_html(self.server.signing_priv_key_pem, - False, - self.server.recent_posts_cache, - self.server.max_recent_posts, - self.server.translate, - page_number, base_dir, - curr_session, - self.server.cached_webfingers, - self.server.person_cache, - self.post_to_nickname, domain, - self.server.port, bookmark_post_json, - None, True, - self.server.allow_deletion, - http_prefix, - self.server.project_version, - timeline_str, - self.server.yt_replace_domain, - self.server.twitter_replacement_domain, - self.server.show_published_date_only, - self.server.peertube_instances, - self.server.allow_local_network_access, - self.server.theme_name, - self.server.system_language, - self.server.max_like_count, - show_repeats, - show_individual_post_icons, - manually_approve_followers, - False, True, False, - self.server.cw_lists, - self.server.lists_enabled, - timezone, mitm, bold_reading, - self.server.dogwhistles, - minimize_all_images, None, - self.server.buy_sites, - self.server.auto_cw_cache) - else: - print('WARN: Unbookmarked post not found: ' + - bookmark_filename) - actor_absolute = \ - get_instance_url(calling_domain, - self.server.http_prefix, - self.server.domain_full, - self.server.onion_domain, - self.server.i2p_domain) + \ - '/users/' + self.post_to_nickname - - actor_path_str = \ - actor_absolute + '/' + timeline_str + \ - '?page=' + str(page_number) + first_post_id + \ - timeline_bookmark - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_undo_bookmark_button', - self.server.debug) - redirect_headers(self, actor_path_str, cookie, - calling_domain) - - -def _delete_button(self, calling_domain: str, path: str, - base_dir: str, http_prefix: str, - domain_full: str, - onion_domain: str, i2p_domain: str, - getreq_start_time, - proxy_type: str, cookie: str, - debug: str, curr_session) -> None: - """Delete button is pressed on a post - """ - if not cookie: - print('ERROR: no cookie given when deleting ' + path) - http_400(self) - return - page_number = 1 - if '?page=' in path: - page_number_str = path.split('?page=')[1] - if '?' in page_number_str: - page_number_str = page_number_str.split('?')[0] - if '#' in page_number_str: - page_number_str = page_number_str.split('#')[0] - if len(page_number_str) > 5: - page_number_str = "1" - if page_number_str.isdigit(): - page_number = int(page_number_str) - delete_url = path.split('?delete=')[1] - if '?' in delete_url: - delete_url = delete_url.split('?')[0] - timeline_str = self.server.default_timeline - if '?tl=' in path: - timeline_str = path.split('?tl=')[1] - if '?' in timeline_str: - timeline_str = timeline_str.split('?')[0] - users_path = path.split('?delete=')[0] - actor = \ - http_prefix + '://' + domain_full + users_path - if self.server.allow_deletion or \ - delete_url.startswith(actor): - if self.server.debug: - print('DEBUG: delete_url=' + delete_url) - print('DEBUG: actor=' + actor) - if actor not in delete_url: - # You can only delete your own posts - if calling_domain.endswith('.onion') and onion_domain: - actor = 'http://' + onion_domain + users_path - elif calling_domain.endswith('.i2p') and i2p_domain: - actor = 'http://' + i2p_domain + users_path - redirect_headers(self, actor + '/' + timeline_str, - cookie, calling_domain) - return - self.post_to_nickname = get_nickname_from_actor(actor) - if not self.post_to_nickname: - print('WARN: unable to find nickname in ' + actor) - if calling_domain.endswith('.onion') and onion_domain: - actor = 'http://' + onion_domain + users_path - elif calling_domain.endswith('.i2p') and i2p_domain: - actor = 'http://' + i2p_domain + users_path - redirect_headers(self, actor + '/' + timeline_str, - cookie, calling_domain) - return - - if onion_domain: - if '.onion/' in actor: - curr_session = self.server.session_onion - proxy_type = 'tor' - if i2p_domain: - if '.onion/' in actor: - curr_session = self.server.session_i2p - proxy_type = 'i2p' - - curr_session = \ - establish_session("deleteButton", - curr_session, proxy_type, - self.server) - if not curr_session: - http_404(self, 58) - return - - delete_str = \ - html_confirm_delete(self.server, - self.server.recent_posts_cache, - self.server.max_recent_posts, - self.server.translate, page_number, - curr_session, base_dir, - delete_url, http_prefix, - self.server.project_version, - self.server.cached_webfingers, - self.server.person_cache, calling_domain, - self.server.yt_replace_domain, - self.server.twitter_replacement_domain, - self.server.show_published_date_only, - self.server.peertube_instances, - self.server.allow_local_network_access, - self.server.theme_name, - self.server.system_language, - self.server.max_like_count, - self.server.signing_priv_key_pem, - self.server.cw_lists, - self.server.lists_enabled, - self.server.dogwhistles, - self.server.min_images_for_accounts, - self.server.buy_sites, - self.server.auto_cw_cache) - if delete_str: - delete_str_len = len(delete_str) - set_headers(self, 'text/html', delete_str_len, - cookie, calling_domain, False) - write2(self, delete_str.encode('utf-8')) - self.server.getreq_busy = False - return - if calling_domain.endswith('.onion') and onion_domain: - actor = 'http://' + onion_domain + users_path - elif (calling_domain.endswith('.i2p') and i2p_domain): - actor = 'http://' + i2p_domain + users_path - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_delete_button', - debug) - redirect_headers(self, actor + '/' + timeline_str, - cookie, calling_domain) - - def _reaction_picker2(self, calling_domain: str, path: str, base_dir: str, http_prefix: str, domain: str, port: int, @@ -8253,297 +6324,6 @@ def _reaction_picker2(self, calling_domain: str, path: str, debug) -def _mute_button2(self, calling_domain: str, path: str, - base_dir: str, http_prefix: str, - domain: str, domain_full: str, port: int, - onion_domain: str, i2p_domain: str, - getreq_start_time, cookie: str, - debug: str, curr_session): - """Mute button is pressed - """ - mute_url = path.split('?mute=')[1] - if '?' in mute_url: - mute_url = mute_url.split('?')[0] - first_post_id = '' - if '?firstpost=' in path: - first_post_id = path.split('?firstpost=')[1] - if '?' in first_post_id: - first_post_id = first_post_id.split('?')[0] - first_post_id = first_post_id.replace('/', '--') - first_post_id = ';firstpost=' + first_post_id.replace('#', '--') - timeline_bookmark = '' - if '?bm=' in path: - timeline_bookmark = path.split('?bm=')[1] - if '?' in timeline_bookmark: - timeline_bookmark = timeline_bookmark.split('?')[0] - timeline_bookmark = '#' + timeline_bookmark - timeline_str = self.server.default_timeline - if '?tl=' in path: - timeline_str = path.split('?tl=')[1] - if '?' in timeline_str: - timeline_str = timeline_str.split('?')[0] - page_number = 1 - if '?page=' in path: - page_number_str = path.split('?page=')[1] - if ';' in page_number_str: - page_number_str = page_number_str.split(';')[0] - if '?' in page_number_str: - page_number_str = page_number_str.split('?')[0] - if '#' in page_number_str: - page_number_str = page_number_str.split('#')[0] - if len(page_number_str) > 5: - page_number_str = "1" - if page_number_str.isdigit(): - page_number = int(page_number_str) - actor = \ - http_prefix + '://' + domain_full + path.split('?mute=')[0] - nickname = get_nickname_from_actor(actor) - if not nickname: - http_404(self, 59) - return - mute_post(base_dir, nickname, domain, port, - http_prefix, mute_url, - self.server.recent_posts_cache, debug) - mute_filename = \ - locate_post(base_dir, nickname, domain, mute_url) - if mute_filename: - print('mute_post: Regenerating html post for changed mute status') - mute_post_json = load_json(mute_filename, 0, 1) - if mute_post_json: - cached_post_filename = \ - get_cached_post_filename(base_dir, nickname, - domain, mute_post_json) - print('mute_post: Muted post json: ' + str(mute_post_json)) - print('mute_post: Muted post nickname: ' + - nickname + ' ' + domain) - print('mute_post: Muted post cache: ' + - str(cached_post_filename)) - show_individual_post_icons = True - manually_approve_followers = \ - follower_approval_active(base_dir, - nickname, domain) - show_repeats = not is_dm(mute_post_json) - show_public_only = False - store_to_cache = True - use_cache_only = False - allow_downloads = False - show_avatar_options = True - avatar_url = None - timezone = None - if self.server.account_timezone.get(nickname): - timezone = \ - self.server.account_timezone.get(nickname) - mitm = False - if os.path.isfile(mute_filename.replace('.json', '') + - '.mitm'): - mitm = True - bold_reading = False - if self.server.bold_reading.get(nickname): - bold_reading = True - minimize_all_images = False - if nickname in self.server.min_images_for_accounts: - minimize_all_images = True - individual_post_as_html(self.server.signing_priv_key_pem, - allow_downloads, - self.server.recent_posts_cache, - self.server.max_recent_posts, - self.server.translate, - page_number, base_dir, - curr_session, - self.server.cached_webfingers, - self.server.person_cache, - nickname, domain, - self.server.port, mute_post_json, - avatar_url, show_avatar_options, - self.server.allow_deletion, - http_prefix, - self.server.project_version, - timeline_str, - self.server.yt_replace_domain, - self.server.twitter_replacement_domain, - self.server.show_published_date_only, - self.server.peertube_instances, - self.server.allow_local_network_access, - self.server.theme_name, - self.server.system_language, - self.server.max_like_count, - show_repeats, - show_individual_post_icons, - manually_approve_followers, - show_public_only, store_to_cache, - use_cache_only, - self.server.cw_lists, - self.server.lists_enabled, - timezone, mitm, bold_reading, - self.server.dogwhistles, - minimize_all_images, None, - self.server.buy_sites, - self.server.auto_cw_cache) - else: - print('WARN: Muted post not found: ' + mute_filename) - - if calling_domain.endswith('.onion') and onion_domain: - actor = \ - 'http://' + onion_domain + \ - path.split('?mute=')[0] - elif (calling_domain.endswith('.i2p') and i2p_domain): - actor = \ - 'http://' + i2p_domain + \ - path.split('?mute=')[0] - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_mute_button', self.server.debug) - - page_number_str = str(page_number) - redirect_str = \ - actor + '/' + timeline_str + '?page=' + page_number_str + \ - first_post_id + timeline_bookmark - redirect_headers(self, redirect_str, cookie, calling_domain) - - -def _undo_mute_button(self, calling_domain: str, path: str, - base_dir: str, http_prefix: str, - domain: str, domain_full: str, port: int, - onion_domain: str, i2p_domain: str, - getreq_start_time, cookie: str, - debug: str, curr_session): - """Undo mute button is pressed - """ - mute_url = path.split('?unmute=')[1] - if '?' in mute_url: - mute_url = mute_url.split('?')[0] - first_post_id = '' - if '?firstpost=' in path: - first_post_id = path.split('?firstpost=')[1] - if '?' in first_post_id: - first_post_id = first_post_id.split('?')[0] - first_post_id = first_post_id.replace('/', '--') - first_post_id = ';firstpost=' + first_post_id.replace('#', '--') - timeline_bookmark = '' - if '?bm=' in path: - timeline_bookmark = path.split('?bm=')[1] - if '?' in timeline_bookmark: - timeline_bookmark = timeline_bookmark.split('?')[0] - timeline_bookmark = '#' + timeline_bookmark - timeline_str = self.server.default_timeline - if '?tl=' in path: - timeline_str = path.split('?tl=')[1] - if '?' in timeline_str: - timeline_str = timeline_str.split('?')[0] - page_number = 1 - if '?page=' in path: - page_number_str = path.split('?page=')[1] - if ';' in page_number_str: - page_number_str = page_number_str.split(';')[0] - if '?' in page_number_str: - page_number_str = page_number_str.split('?')[0] - if '#' in page_number_str: - page_number_str = page_number_str.split('#')[0] - if len(page_number_str) > 5: - page_number_str = "1" - if page_number_str.isdigit(): - page_number = int(page_number_str) - actor = \ - http_prefix + '://' + domain_full + path.split('?unmute=')[0] - nickname = get_nickname_from_actor(actor) - if not nickname: - http_404(self, 60) - return - unmute_post(base_dir, nickname, domain, port, - http_prefix, mute_url, - self.server.recent_posts_cache, debug) - mute_filename = \ - locate_post(base_dir, nickname, domain, mute_url) - if mute_filename: - print('unmute_post: ' + - 'Regenerating html post for changed unmute status') - mute_post_json = load_json(mute_filename, 0, 1) - if mute_post_json: - cached_post_filename = \ - get_cached_post_filename(base_dir, nickname, - domain, mute_post_json) - print('unmute_post: Unmuted post json: ' + str(mute_post_json)) - print('unmute_post: Unmuted post nickname: ' + - nickname + ' ' + domain) - print('unmute_post: Unmuted post cache: ' + - str(cached_post_filename)) - show_individual_post_icons = True - manually_approve_followers = \ - follower_approval_active(base_dir, nickname, domain) - show_repeats = not is_dm(mute_post_json) - show_public_only = False - store_to_cache = True - use_cache_only = False - allow_downloads = False - show_avatar_options = True - avatar_url = None - timezone = None - if self.server.account_timezone.get(nickname): - timezone = \ - self.server.account_timezone.get(nickname) - mitm = False - if os.path.isfile(mute_filename.replace('.json', '') + - '.mitm'): - mitm = True - bold_reading = False - if self.server.bold_reading.get(nickname): - bold_reading = True - minimize_all_images = False - if nickname in self.server.min_images_for_accounts: - minimize_all_images = True - individual_post_as_html(self.server.signing_priv_key_pem, - allow_downloads, - self.server.recent_posts_cache, - self.server.max_recent_posts, - self.server.translate, - page_number, base_dir, - curr_session, - self.server.cached_webfingers, - self.server.person_cache, - nickname, domain, - self.server.port, mute_post_json, - avatar_url, show_avatar_options, - self.server.allow_deletion, - http_prefix, - self.server.project_version, - timeline_str, - self.server.yt_replace_domain, - self.server.twitter_replacement_domain, - self.server.show_published_date_only, - self.server.peertube_instances, - self.server.allow_local_network_access, - self.server.theme_name, - self.server.system_language, - self.server.max_like_count, - show_repeats, - show_individual_post_icons, - manually_approve_followers, - show_public_only, store_to_cache, - use_cache_only, - self.server.cw_lists, - self.server.lists_enabled, - timezone, mitm, bold_reading, - self.server.dogwhistles, - minimize_all_images, None, - self.server.buy_sites, - self.server.auto_cw_cache) - else: - print('WARN: Unmuted post not found: ' + mute_filename) - if calling_domain.endswith('.onion') and onion_domain: - actor = \ - 'http://' + onion_domain + path.split('?unmute=')[0] - elif calling_domain.endswith('.i2p') and i2p_domain: - actor = \ - 'http://' + i2p_domain + path.split('?unmute=')[0] - fitness_performance(getreq_start_time, self.server.fitness, - '_GET', '_undo_mute_button', self.server.debug) - - page_number_str = str(page_number) - redirect_str = \ - actor + '/' + timeline_str + '?page=' + page_number_str + \ - first_post_id + timeline_bookmark - redirect_headers(self, redirect_str, cookie, calling_domain) - - def _show_known_crawlers(self, calling_domain: str, path: str, base_dir: str, known_crawlers: {}) -> bool: """Show a list of known web crawlers diff --git a/daemon_get_buttons.py b/daemon_get_buttons.py new file mode 100644 index 000000000..c53c54423 --- /dev/null +++ b/daemon_get_buttons.py @@ -0,0 +1,2257 @@ +__filename__ = "daemon_get_buttons.py" +__author__ = "Bob Mottram" +__license__ = "AGPL3+" +__version__ = "1.5.0" +__maintainer__ = "Bob Mottram" +__email__ = "bob@libreserver.org" +__status__ = "Production" +__module_group__ = "Core" + +import os +import urllib.parse +from blocking import unmute_post +from blocking import mute_post +from bookmarks import bookmark_post +from bookmarks import undo_bookmark_post +from reaction import update_reaction_collection +from manualapprove import manual_deny_follow_request_thread +from manualapprove import manual_approve_follow_request_thread +from follow import follower_approval_active +from fitnessFunctions import fitness_performance +from daemon_utils import post_to_outbox +from posts import get_original_post_from_announce_url +from posts import save_post_to_box +from announce import create_announce +from session import establish_session +from httpheaders import set_headers +from httpheaders import redirect_headers +from httpcodes import write2 +from httpcodes import http_400 +from httpcodes import http_404 +from like import update_likes_collection +from utils import undo_reaction_collection_entry +from utils import undo_likes_collection_entry +from utils import load_json +from utils import get_full_domain +from utils import get_domain_from_actor +from utils import delete_post +from utils import locate_post +from utils import is_dm +from utils import get_cached_post_filename +from utils import remove_id_ending +from utils import local_actor_url +from utils import get_nickname_from_actor +from utils import get_instance_url +from webapp_post import individual_post_as_html +from webapp_confirm import html_confirm_delete + + +def announce_button(self, calling_domain: str, path: str, + base_dir: str, + cookie: str, proxy_type: str, + http_prefix: str, + domain: str, domain_full: str, port: int, + onion_domain: str, i2p_domain: str, + getreq_start_time, + repeat_private: bool, + debug: bool, + curr_session, sites_unavailable: []) -> None: + """The announce/repeat button was pressed on a post + """ + page_number = 1 + repeat_url = path.split('?repeat=')[1] + if '?' in repeat_url: + repeat_url = repeat_url.split('?')[0] + first_post_id = '' + if '?firstpost=' in path: + first_post_id = path.split('?firstpost=')[1] + if '?' in first_post_id: + first_post_id = first_post_id.split('?')[0] + first_post_id = first_post_id.replace('/', '--') + first_post_id = ';firstpost=' + first_post_id.replace('#', '--') + timeline_bookmark = '' + if '?bm=' in path: + timeline_bookmark = path.split('?bm=')[1] + if '?' in timeline_bookmark: + timeline_bookmark = timeline_bookmark.split('?')[0] + timeline_bookmark = '#' + timeline_bookmark + if '?page=' in path: + page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] + if '?' in page_number_str: + page_number_str = page_number_str.split('?')[0] + if '#' in page_number_str: + page_number_str = page_number_str.split('#')[0] + if len(page_number_str) > 5: + page_number_str = "1" + if page_number_str.isdigit(): + page_number = int(page_number_str) + timeline_str = 'inbox' + if '?tl=' in path: + timeline_str = path.split('?tl=')[1] + if '?' in timeline_str: + timeline_str = timeline_str.split('?')[0] + actor = path.split('?repeat=')[0] + self.post_to_nickname = get_nickname_from_actor(actor) + if not self.post_to_nickname: + print('WARN: unable to find nickname in ' + actor) + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + actor + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + redirect_headers(self, actor_path_str, cookie, + calling_domain) + return + + if onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + establish_session("announceButton", + curr_session, proxy_type, + self.server) + if not curr_session: + http_404(self, 47) + return + self.server.actorRepeat = path.split('?actor=')[1] + announce_to_str = \ + local_actor_url(http_prefix, self.post_to_nickname, + domain_full) + \ + '/followers' + if not repeat_private: + announce_to_str = 'https://www.w3.org/ns/activitystreams#Public' + announce_id = None + announce_json = \ + create_announce(curr_session, + base_dir, + self.server.federation_list, + self.post_to_nickname, + domain, port, + announce_to_str, + None, http_prefix, + repeat_url, False, False, + self.server.send_threads, + self.server.postLog, + self.server.person_cache, + self.server.cached_webfingers, + debug, + self.server.project_version, + self.server.signing_priv_key_pem, + self.server.domain, + onion_domain, + i2p_domain, sites_unavailable, + self.server.system_language) + announce_filename = None + if announce_json: + # save the announce straight to the outbox + # This is because the subsequent send is within a separate thread + # but the html still needs to be generated before this call ends + announce_id = remove_id_ending(announce_json['id']) + announce_filename = \ + save_post_to_box(base_dir, http_prefix, announce_id, + self.post_to_nickname, domain_full, + announce_json, 'outbox') + + # clear the icon from the cache so that it gets updated + if self.server.iconsCache.get('repeat.png'): + del self.server.iconsCache['repeat.png'] + + # send out the announce within a separate thread + post_to_outbox(self, announce_json, + self.server.project_version, + self.post_to_nickname, + curr_session, proxy_type) + + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_announce_button postToOutboxThread', + self.server.debug) + + # generate the html for the announce + if announce_json and announce_filename: + if debug: + print('Generating html post for announce') + cached_post_filename = \ + get_cached_post_filename(base_dir, self.post_to_nickname, + domain, announce_json) + if debug: + print('Announced post json: ' + str(announce_json)) + print('Announced post nickname: ' + + self.post_to_nickname + ' ' + domain) + print('Announced post cache: ' + str(cached_post_filename)) + show_individual_post_icons = True + manually_approve_followers = \ + follower_approval_active(base_dir, + self.post_to_nickname, domain) + show_repeats = not is_dm(announce_json) + timezone = None + if self.server.account_timezone.get(self.post_to_nickname): + timezone = \ + self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(announce_filename.replace('.json', '') + + '.mitm'): + mitm = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True + minimize_all_images = False + if self.post_to_nickname in self.server.min_images_for_accounts: + minimize_all_images = True + individual_post_as_html(self.server.signing_priv_key_pem, False, + self.server.recent_posts_cache, + self.server.max_recent_posts, + self.server.translate, + page_number, base_dir, + curr_session, + self.server.cached_webfingers, + self.server.person_cache, + self.post_to_nickname, domain, + self.server.port, announce_json, + None, True, + self.server.allow_deletion, + http_prefix, self.server.project_version, + timeline_str, + self.server.yt_replace_domain, + self.server.twitter_replacement_domain, + self.server.show_published_date_only, + self.server.peertube_instances, + self.server.allow_local_network_access, + self.server.theme_name, + self.server.system_language, + self.server.max_like_count, + show_repeats, + show_individual_post_icons, + manually_approve_followers, + False, True, False, + self.server.cw_lists, + self.server.lists_enabled, + timezone, mitm, bold_reading, + self.server.dogwhistles, + minimize_all_images, None, + self.server.buy_sites, + self.server.auto_cw_cache) + + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + '/users/' + self.post_to_nickname + + actor_path_str = \ + actor_absolute + '/' + timeline_str + '?page=' + \ + str(page_number) + first_post_id + timeline_bookmark + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_announce_button', + self.server.debug) + redirect_headers(self, actor_path_str, cookie, calling_domain) + + +def announce_button_undo(self, calling_domain: str, path: str, + base_dir: str, cookie: str, proxy_type: str, + http_prefix: str, domain: str, domain_full: str, + onion_domain: str, i2p_domain: str, + getreq_start_time, debug: bool, + recent_posts_cache: {}, curr_session) -> None: + """Undo announce/repeat button was pressed + """ + page_number = 1 + + # the post which was referenced by the announce post + repeat_url = path.split('?unrepeat=')[1] + if '?' in repeat_url: + repeat_url = repeat_url.split('?')[0] + + first_post_id = '' + if '?firstpost=' in path: + first_post_id = path.split('?firstpost=')[1] + if '?' in first_post_id: + first_post_id = first_post_id.split('?')[0] + first_post_id = first_post_id.replace('/', '--') + first_post_id = ';firstpost=' + first_post_id.replace('#', '--') + + timeline_bookmark = '' + if '?bm=' in path: + timeline_bookmark = path.split('?bm=')[1] + if '?' in timeline_bookmark: + timeline_bookmark = timeline_bookmark.split('?')[0] + timeline_bookmark = '#' + timeline_bookmark + if '?page=' in path: + page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] + if '?' in page_number_str: + page_number_str = page_number_str.split('?')[0] + if '#' in page_number_str: + page_number_str = page_number_str.split('#')[0] + if len(page_number_str) > 5: + page_number_str = "1" + if page_number_str.isdigit(): + page_number = int(page_number_str) + timeline_str = 'inbox' + if '?tl=' in path: + timeline_str = path.split('?tl=')[1] + if '?' in timeline_str: + timeline_str = timeline_str.split('?')[0] + actor = path.split('?unrepeat=')[0] + self.post_to_nickname = get_nickname_from_actor(actor) + if not self.post_to_nickname: + print('WARN: unable to find nickname in ' + actor) + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + actor + actor_path_str = \ + actor_absolute + '/' + timeline_str + '?page=' + \ + str(page_number) + redirect_headers(self, actor_path_str, cookie, + calling_domain) + return + + if onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + establish_session("undoAnnounceButton", + curr_session, proxy_type, + self.server) + if not curr_session: + http_404(self, 48) + return + undo_announce_actor = \ + http_prefix + '://' + domain_full + \ + '/users/' + self.post_to_nickname + un_repeat_to_str = 'https://www.w3.org/ns/activitystreams#Public' + new_undo_announce = { + "@context": "https://www.w3.org/ns/activitystreams", + 'actor': undo_announce_actor, + 'type': 'Undo', + 'cc': [undo_announce_actor + '/followers'], + 'to': [un_repeat_to_str], + 'object': { + 'actor': undo_announce_actor, + 'cc': [undo_announce_actor + '/followers'], + 'object': repeat_url, + 'to': [un_repeat_to_str], + 'type': 'Announce' + } + } + # clear the icon from the cache so that it gets updated + if self.server.iconsCache.get('repeat_inactive.png'): + del self.server.iconsCache['repeat_inactive.png'] + + # delete the announce post + if '?unannounce=' in path: + announce_url = path.split('?unannounce=')[1] + if '?' in announce_url: + announce_url = announce_url.split('?')[0] + post_filename = None + nickname = get_nickname_from_actor(announce_url) + if nickname: + if domain_full + '/users/' + nickname + '/' in announce_url: + post_filename = \ + locate_post(base_dir, nickname, domain, announce_url) + if post_filename: + delete_post(base_dir, http_prefix, + nickname, domain, post_filename, + debug, recent_posts_cache, True) + + post_to_outbox(self, new_undo_announce, + self.server.project_version, + self.post_to_nickname, + curr_session, proxy_type) + + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + '/users/' + self.post_to_nickname + + actor_path_str = \ + actor_absolute + '/' + timeline_str + '?page=' + \ + str(page_number) + first_post_id + timeline_bookmark + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_undo_announce_button', + self.server.debug) + redirect_headers(self, actor_path_str, cookie, calling_domain) + + +def follow_approve_button(self, calling_domain: str, path: str, + cookie: str, + base_dir: str, http_prefix: str, + domain: str, domain_full: str, port: int, + onion_domain: str, i2p_domain: str, + getreq_start_time, + proxy_type: str, debug: bool, + curr_session) -> None: + """Follow approve button was pressed + """ + origin_path_str = path.split('/followapprove=')[0] + follower_nickname = origin_path_str.replace('/users/', '') + following_handle = path.split('/followapprove=')[1] + if '://' in following_handle: + handle_nickname = get_nickname_from_actor(following_handle) + handle_domain, handle_port = \ + get_domain_from_actor(following_handle) + if not handle_nickname or not handle_domain: + http_404(self, 49) + return + following_handle = \ + handle_nickname + '@' + \ + get_full_domain(handle_domain, handle_port) + if '@' in following_handle: + if self.server.onion_domain: + if following_handle.endswith('.onion'): + curr_session = self.server.session_onion + proxy_type = 'tor' + port = 80 + if self.server.i2p_domain: + if following_handle.endswith('.i2p'): + curr_session = self.server.session_i2p + proxy_type = 'i2p' + port = 80 + + curr_session = \ + establish_session("follow_approve_button", + curr_session, proxy_type, + self.server) + if not curr_session: + print('WARN: unable to establish session ' + + 'when approving follow request') + http_404(self, 50) + return + signing_priv_key_pem = \ + self.server.signing_priv_key_pem + followers_sync_cache = \ + self.server.followers_sync_cache + manual_approve_follow_request_thread(self.server.session, + self.server.session_onion, + self.server.session_i2p, + self.server.onion_domain, + self.server.i2p_domain, + base_dir, http_prefix, + follower_nickname, + domain, port, + following_handle, + self.server.federation_list, + self.server.send_threads, + self.server.postLog, + self.server.cached_webfingers, + self.server.person_cache, + debug, + self.server.project_version, + signing_priv_key_pem, + proxy_type, + followers_sync_cache, + self.server.sites_unavailable, + self.server.system_language) + origin_path_str_absolute = \ + http_prefix + '://' + domain_full + origin_path_str + if calling_domain.endswith('.onion') and onion_domain: + origin_path_str_absolute = \ + 'http://' + onion_domain + origin_path_str + elif (calling_domain.endswith('.i2p') and i2p_domain): + origin_path_str_absolute = \ + 'http://' + i2p_domain + origin_path_str + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_follow_approve_button', + self.server.debug) + redirect_headers(self, origin_path_str_absolute, + cookie, calling_domain) + + +def follow_deny_button(self, calling_domain: str, path: str, + cookie: str, base_dir: str, http_prefix: str, + domain: str, domain_full: str, port: int, + onion_domain: str, i2p_domain: str, + getreq_start_time, debug: bool) -> None: + """Follow deny button was pressed + """ + origin_path_str = path.split('/followdeny=')[0] + follower_nickname = origin_path_str.replace('/users/', '') + following_handle = path.split('/followdeny=')[1] + if '://' in following_handle: + handle_nickname = get_nickname_from_actor(following_handle) + handle_domain, handle_port = \ + get_domain_from_actor(following_handle) + if not handle_nickname or not handle_domain: + http_404(self, 51) + return + following_handle = \ + handle_nickname + '@' + \ + get_full_domain(handle_domain, handle_port) + if '@' in following_handle: + manual_deny_follow_request_thread(self.server.session, + self.server.session_onion, + self.server.session_i2p, + onion_domain, + i2p_domain, + base_dir, http_prefix, + follower_nickname, + domain, port, + following_handle, + self.server.federation_list, + self.server.send_threads, + self.server.postLog, + self.server.cached_webfingers, + self.server.person_cache, + debug, + self.server.project_version, + self.server.signing_priv_key_pem, + self.server.followers_sync_cache, + self.server.sites_unavailable, + self.server.system_language) + origin_path_str_absolute = \ + http_prefix + '://' + domain_full + origin_path_str + if calling_domain.endswith('.onion') and onion_domain: + origin_path_str_absolute = \ + 'http://' + onion_domain + origin_path_str + elif calling_domain.endswith('.i2p') and i2p_domain: + origin_path_str_absolute = \ + 'http://' + i2p_domain + origin_path_str + redirect_headers(self, origin_path_str_absolute, + cookie, calling_domain) + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_follow_deny_button', + self.server.debug) + + +def like_button(self, calling_domain: str, path: str, + base_dir: str, http_prefix: str, + domain: str, domain_full: str, + onion_domain: str, i2p_domain: str, + getreq_start_time, + proxy_type: str, cookie: str, + debug: str, + curr_session) -> None: + """Press the like button + """ + page_number = 1 + like_url = path.split('?like=')[1] + if '?' in like_url: + like_url = like_url.split('?')[0] + first_post_id = '' + if '?firstpost=' in path: + first_post_id = path.split('?firstpost=')[1] + if '?' in first_post_id: + first_post_id = first_post_id.split('?')[0] + first_post_id = first_post_id.replace('/', '--') + first_post_id = ';firstpost=' + first_post_id.replace('#', '--') + timeline_bookmark = '' + if '?bm=' in path: + timeline_bookmark = path.split('?bm=')[1] + if '?' in timeline_bookmark: + timeline_bookmark = timeline_bookmark.split('?')[0] + timeline_bookmark = '#' + timeline_bookmark + actor = path.split('?like=')[0] + if '?page=' in path: + page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] + if '?' in page_number_str: + page_number_str = page_number_str.split('?')[0] + if '#' in page_number_str: + page_number_str = page_number_str.split('#')[0] + if len(page_number_str) > 5: + page_number_str = "1" + if page_number_str.isdigit(): + page_number = int(page_number_str) + timeline_str = 'inbox' + if '?tl=' in path: + timeline_str = path.split('?tl=')[1] + if '?' in timeline_str: + timeline_str = timeline_str.split('?')[0] + + self.post_to_nickname = get_nickname_from_actor(actor) + if not self.post_to_nickname: + print('WARN: unable to find nickname in ' + actor) + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + actor + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + timeline_bookmark + redirect_headers(self, actor_path_str, cookie, + calling_domain) + return + + if onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + establish_session("likeButton", + curr_session, proxy_type, + self.server) + if not curr_session: + http_404(self, 52) + return + like_actor = \ + local_actor_url(http_prefix, self.post_to_nickname, domain_full) + actor_liked = path.split('?actor=')[1] + if '?' in actor_liked: + actor_liked = actor_liked.split('?')[0] + + # if this is an announce then send the like to the original post + orig_actor, orig_post_url, orig_filename = \ + get_original_post_from_announce_url(like_url, base_dir, + self.post_to_nickname, domain) + like_url2 = like_url + liked_post_filename = orig_filename + if orig_actor and orig_post_url: + actor_liked = orig_actor + like_url2 = orig_post_url + liked_post_filename = None + + like_json = { + "@context": "https://www.w3.org/ns/activitystreams", + 'type': 'Like', + 'actor': like_actor, + 'to': [actor_liked], + 'object': like_url2 + } + + # send out the like to followers + post_to_outbox(self, like_json, self.server.project_version, None, + curr_session, proxy_type) + + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_like_button postToOutbox', + self.server.debug) + + print('Locating liked post ' + like_url) + # directly like the post file + if not liked_post_filename: + liked_post_filename = \ + locate_post(base_dir, self.post_to_nickname, domain, like_url) + if liked_post_filename: + recent_posts_cache = self.server.recent_posts_cache + liked_post_json = load_json(liked_post_filename, 0, 1) + if orig_filename and orig_post_url: + update_likes_collection(recent_posts_cache, + base_dir, liked_post_filename, + like_url, like_actor, + self.post_to_nickname, + domain, debug, liked_post_json) + like_url = orig_post_url + liked_post_filename = orig_filename + if debug: + print('Updating likes for ' + liked_post_filename) + update_likes_collection(recent_posts_cache, + base_dir, liked_post_filename, like_url, + like_actor, self.post_to_nickname, domain, + debug, None) + if debug: + print('Regenerating html post for changed likes collection') + # clear the icon from the cache so that it gets updated + if liked_post_json: + cached_post_filename = \ + get_cached_post_filename(base_dir, self.post_to_nickname, + domain, liked_post_json) + if debug: + print('Liked post json: ' + str(liked_post_json)) + print('Liked post nickname: ' + + self.post_to_nickname + ' ' + domain) + print('Liked post cache: ' + str(cached_post_filename)) + show_individual_post_icons = True + manually_approve_followers = \ + follower_approval_active(base_dir, + self.post_to_nickname, domain) + show_repeats = not is_dm(liked_post_json) + timezone = None + if self.server.account_timezone.get(self.post_to_nickname): + timezone = \ + self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(liked_post_filename.replace('.json', '') + + '.mitm'): + mitm = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True + minimize_all_images = False + if self.post_to_nickname in \ + self.server.min_images_for_accounts: + minimize_all_images = True + individual_post_as_html(self.server.signing_priv_key_pem, + False, + self.server.recent_posts_cache, + self.server.max_recent_posts, + self.server.translate, + page_number, base_dir, + curr_session, + self.server.cached_webfingers, + self.server.person_cache, + self.post_to_nickname, domain, + self.server.port, liked_post_json, + None, True, + self.server.allow_deletion, + http_prefix, + self.server.project_version, + timeline_str, + self.server.yt_replace_domain, + self.server.twitter_replacement_domain, + self.server.show_published_date_only, + self.server.peertube_instances, + self.server.allow_local_network_access, + self.server.theme_name, + self.server.system_language, + self.server.max_like_count, + show_repeats, + show_individual_post_icons, + manually_approve_followers, + False, True, False, + self.server.cw_lists, + self.server.lists_enabled, + timezone, mitm, bold_reading, + self.server.dogwhistles, + minimize_all_images, None, + self.server.buy_sites, + self.server.auto_cw_cache) + else: + print('WARN: Liked post not found: ' + liked_post_filename) + # clear the icon from the cache so that it gets updated + if self.server.iconsCache.get('like.png'): + del self.server.iconsCache['like.png'] + else: + print('WARN: unable to locate file for liked post ' + + like_url) + + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + '/users/' + self.post_to_nickname + + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + first_post_id + \ + timeline_bookmark + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_like_button', + self.server.debug) + redirect_headers(self, actor_path_str, cookie, + calling_domain) + + +def like_button_undo(self, calling_domain: str, path: str, + base_dir: str, http_prefix: str, + domain: str, domain_full: str, + onion_domain: str, i2p_domain: str, + getreq_start_time, + proxy_type: str, cookie: str, + debug: str, + curr_session) -> None: + """A button is pressed to undo + """ + page_number = 1 + like_url = path.split('?unlike=')[1] + if '?' in like_url: + like_url = like_url.split('?')[0] + first_post_id = '' + if '?firstpost=' in path: + first_post_id = path.split('?firstpost=')[1] + if '?' in first_post_id: + first_post_id = first_post_id.split('?')[0] + first_post_id = first_post_id.replace('/', '--') + first_post_id = ';firstpost=' + first_post_id.replace('#', '--') + timeline_bookmark = '' + if '?bm=' in path: + timeline_bookmark = path.split('?bm=')[1] + if '?' in timeline_bookmark: + timeline_bookmark = timeline_bookmark.split('?')[0] + timeline_bookmark = '#' + timeline_bookmark + if '?page=' in path: + page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] + if '?' in page_number_str: + page_number_str = page_number_str.split('?')[0] + if '#' in page_number_str: + page_number_str = page_number_str.split('#')[0] + if len(page_number_str) > 5: + page_number_str = "1" + if page_number_str.isdigit(): + page_number = int(page_number_str) + timeline_str = 'inbox' + if '?tl=' in path: + timeline_str = path.split('?tl=')[1] + if '?' in timeline_str: + timeline_str = timeline_str.split('?')[0] + actor = path.split('?unlike=')[0] + self.post_to_nickname = get_nickname_from_actor(actor) + if not self.post_to_nickname: + print('WARN: unable to find nickname in ' + actor) + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + actor + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + redirect_headers(self, actor_path_str, cookie, + calling_domain) + return + + if onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + establish_session("undoLikeButton", + curr_session, proxy_type, + self.server) + if not curr_session: + http_404(self, 53) + return + undo_actor = \ + local_actor_url(http_prefix, self.post_to_nickname, domain_full) + actor_liked = path.split('?actor=')[1] + if '?' in actor_liked: + actor_liked = actor_liked.split('?')[0] + + # if this is an announce then send the like to the original post + orig_actor, orig_post_url, orig_filename = \ + get_original_post_from_announce_url(like_url, base_dir, + self.post_to_nickname, domain) + like_url2 = like_url + liked_post_filename = orig_filename + if orig_actor and orig_post_url: + actor_liked = orig_actor + like_url2 = orig_post_url + liked_post_filename = None + + undo_like_json = { + "@context": "https://www.w3.org/ns/activitystreams", + 'type': 'Undo', + 'actor': undo_actor, + 'to': [actor_liked], + 'object': { + 'type': 'Like', + 'actor': undo_actor, + 'to': [actor_liked], + 'object': like_url2 + } + } + + # send out the undo like to followers + post_to_outbox(self, undo_like_json, + self.server.project_version, None, + curr_session, proxy_type) + + # directly undo the like within the post file + if not liked_post_filename: + liked_post_filename = locate_post(base_dir, self.post_to_nickname, + domain, like_url) + if liked_post_filename: + recent_posts_cache = self.server.recent_posts_cache + liked_post_json = load_json(liked_post_filename, 0, 1) + if orig_filename and orig_post_url: + undo_likes_collection_entry(recent_posts_cache, + base_dir, liked_post_filename, + undo_actor, + domain, debug, + liked_post_json) + like_url = orig_post_url + liked_post_filename = orig_filename + if debug: + print('Removing likes for ' + liked_post_filename) + undo_likes_collection_entry(recent_posts_cache, + base_dir, + liked_post_filename, + undo_actor, domain, debug, None) + if debug: + print('Regenerating html post for changed likes collection') + if liked_post_json: + show_individual_post_icons = True + manually_approve_followers = \ + follower_approval_active(base_dir, + self.post_to_nickname, domain) + show_repeats = not is_dm(liked_post_json) + timezone = None + if self.server.account_timezone.get(self.post_to_nickname): + timezone = \ + self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(liked_post_filename.replace('.json', '') + + '.mitm'): + mitm = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True + minimize_all_images = False + if self.post_to_nickname in \ + self.server.min_images_for_accounts: + minimize_all_images = True + individual_post_as_html(self.server.signing_priv_key_pem, + False, + self.server.recent_posts_cache, + self.server.max_recent_posts, + self.server.translate, + page_number, base_dir, + curr_session, + self.server.cached_webfingers, + self.server.person_cache, + self.post_to_nickname, domain, + self.server.port, liked_post_json, + None, True, + self.server.allow_deletion, + http_prefix, + self.server.project_version, + timeline_str, + self.server.yt_replace_domain, + self.server.twitter_replacement_domain, + self.server.show_published_date_only, + self.server.peertube_instances, + self.server.allow_local_network_access, + self.server.theme_name, + self.server.system_language, + self.server.max_like_count, + show_repeats, + show_individual_post_icons, + manually_approve_followers, + False, True, False, + self.server.cw_lists, + self.server.lists_enabled, + timezone, mitm, bold_reading, + self.server.dogwhistles, + minimize_all_images, None, + self.server.buy_sites, + self.server.auto_cw_cache) + else: + print('WARN: Unliked post not found: ' + liked_post_filename) + # clear the icon from the cache so that it gets updated + if self.server.iconsCache.get('like_inactive.png'): + del self.server.iconsCache['like_inactive.png'] + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + '/users/' + self.post_to_nickname + + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + first_post_id + \ + timeline_bookmark + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_undo_like_button', + self.server.debug) + redirect_headers(self, actor_path_str, cookie, + calling_domain) + + +def reaction_button(self, calling_domain: str, path: str, + base_dir: str, http_prefix: str, + domain: str, domain_full: str, + onion_domain: str, i2p_domain: str, + getreq_start_time, + proxy_type: str, cookie: str, + debug: str, + curr_session) -> None: + """Press an emoji reaction button + Note that this is not the emoji reaction selection icon at the + bottom of the post + """ + page_number = 1 + reaction_url = path.split('?react=')[1] + if '?' in reaction_url: + reaction_url = reaction_url.split('?')[0] + first_post_id = '' + if '?firstpost=' in path: + first_post_id = path.split('?firstpost=')[1] + if '?' in first_post_id: + first_post_id = first_post_id.split('?')[0] + first_post_id = first_post_id.replace('/', '--') + first_post_id = ';firstpost=' + first_post_id.replace('#', '--') + timeline_bookmark = '' + if '?bm=' in path: + timeline_bookmark = path.split('?bm=')[1] + if '?' in timeline_bookmark: + timeline_bookmark = timeline_bookmark.split('?')[0] + timeline_bookmark = '#' + timeline_bookmark + actor = path.split('?react=')[0] + if '?page=' in path: + page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] + if '?' in page_number_str: + page_number_str = page_number_str.split('?')[0] + if '#' in page_number_str: + page_number_str = page_number_str.split('#')[0] + if len(page_number_str) > 5: + page_number_str = "1" + if page_number_str.isdigit(): + page_number = int(page_number_str) + timeline_str = 'inbox' + if '?tl=' in path: + timeline_str = path.split('?tl=')[1] + if '?' in timeline_str: + timeline_str = timeline_str.split('?')[0] + emoji_content_encoded = None + if '?emojreact=' in path: + emoji_content_encoded = path.split('?emojreact=')[1] + if '?' in emoji_content_encoded: + emoji_content_encoded = emoji_content_encoded.split('?')[0] + if not emoji_content_encoded: + print('WARN: no emoji reaction ' + actor) + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + actor + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + timeline_bookmark + redirect_headers(self, actor_path_str, cookie, + calling_domain) + return + emoji_content = urllib.parse.unquote_plus(emoji_content_encoded) + self.post_to_nickname = get_nickname_from_actor(actor) + if not self.post_to_nickname: + print('WARN: unable to find nickname in ' + actor) + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + actor + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + timeline_bookmark + redirect_headers(self, actor_path_str, cookie, + calling_domain) + return + + if onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + establish_session("reactionButton", + curr_session, proxy_type, + self.server) + if not curr_session: + http_404(self, 54) + return + reaction_actor = \ + local_actor_url(http_prefix, self.post_to_nickname, domain_full) + actor_reaction = path.split('?actor=')[1] + if '?' in actor_reaction: + actor_reaction = actor_reaction.split('?')[0] + + # if this is an announce then send the emoji reaction + # to the original post + orig_actor, orig_post_url, orig_filename = \ + get_original_post_from_announce_url(reaction_url, base_dir, + self.post_to_nickname, domain) + reaction_url2 = reaction_url + reaction_post_filename = orig_filename + if orig_actor and orig_post_url: + actor_reaction = orig_actor + reaction_url2 = orig_post_url + reaction_post_filename = None + + reaction_json = { + "@context": "https://www.w3.org/ns/activitystreams", + 'type': 'EmojiReact', + 'actor': reaction_actor, + 'to': [actor_reaction], + 'object': reaction_url2, + 'content': emoji_content + } + + # send out the emoji reaction to followers + post_to_outbox(self, reaction_json, self.server.project_version, None, + curr_session, proxy_type) + + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_reaction_button postToOutbox', + self.server.debug) + + print('Locating emoji reaction post ' + reaction_url) + # directly emoji reaction the post file + if not reaction_post_filename: + reaction_post_filename = \ + locate_post(base_dir, self.post_to_nickname, domain, + reaction_url) + if reaction_post_filename: + recent_posts_cache = self.server.recent_posts_cache + reaction_post_json = load_json(reaction_post_filename, 0, 1) + if orig_filename and orig_post_url: + update_reaction_collection(recent_posts_cache, + base_dir, reaction_post_filename, + reaction_url, + reaction_actor, + self.post_to_nickname, + domain, debug, reaction_post_json, + emoji_content) + reaction_url = orig_post_url + reaction_post_filename = orig_filename + if debug: + print('Updating emoji reaction for ' + reaction_post_filename) + update_reaction_collection(recent_posts_cache, + base_dir, reaction_post_filename, + reaction_url, + reaction_actor, + self.post_to_nickname, domain, + debug, None, emoji_content) + if debug: + print('Regenerating html post for changed ' + + 'emoji reaction collection') + # clear the icon from the cache so that it gets updated + if reaction_post_json: + cached_post_filename = \ + get_cached_post_filename(base_dir, self.post_to_nickname, + domain, reaction_post_json) + if debug: + print('Reaction post json: ' + str(reaction_post_json)) + print('Reaction post nickname: ' + + self.post_to_nickname + ' ' + domain) + print('Reaction post cache: ' + str(cached_post_filename)) + show_individual_post_icons = True + manually_approve_followers = \ + follower_approval_active(base_dir, + self.post_to_nickname, domain) + show_repeats = not is_dm(reaction_post_json) + timezone = None + if self.server.account_timezone.get(self.post_to_nickname): + timezone = \ + self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(reaction_post_filename.replace('.json', '') + + '.mitm'): + mitm = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True + minimize_all_images = False + if self.post_to_nickname in \ + self.server.min_images_for_accounts: + minimize_all_images = True + individual_post_as_html(self.server.signing_priv_key_pem, + False, + self.server.recent_posts_cache, + self.server.max_recent_posts, + self.server.translate, + page_number, base_dir, + curr_session, + self.server.cached_webfingers, + self.server.person_cache, + self.post_to_nickname, domain, + self.server.port, reaction_post_json, + None, True, + self.server.allow_deletion, + http_prefix, + self.server.project_version, + timeline_str, + self.server.yt_replace_domain, + self.server.twitter_replacement_domain, + self.server.show_published_date_only, + self.server.peertube_instances, + self.server.allow_local_network_access, + self.server.theme_name, + self.server.system_language, + self.server.max_like_count, + show_repeats, + show_individual_post_icons, + manually_approve_followers, + False, True, False, + self.server.cw_lists, + self.server.lists_enabled, + timezone, mitm, bold_reading, + self.server.dogwhistles, + minimize_all_images, None, + self.server.buy_sites, + self.server.auto_cw_cache) + else: + print('WARN: Emoji reaction post not found: ' + + reaction_post_filename) + else: + print('WARN: unable to locate file for emoji reaction post ' + + reaction_url) + + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + '/users/' + self.post_to_nickname + + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + first_post_id + \ + timeline_bookmark + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_reaction_button', + self.server.debug) + redirect_headers(self, actor_path_str, cookie, + calling_domain) + + +def reaction_button_undo(self, calling_domain: str, path: str, + base_dir: str, http_prefix: str, + domain: str, domain_full: str, + onion_domain: str, i2p_domain: str, + getreq_start_time, + proxy_type: str, cookie: str, + debug: str, + curr_session) -> None: + """A button is pressed to undo emoji reaction + """ + page_number = 1 + reaction_url = path.split('?unreact=')[1] + if '?' in reaction_url: + reaction_url = reaction_url.split('?')[0] + first_post_id = '' + if '?firstpost=' in path: + first_post_id = path.split('?firstpost=')[1] + if '?' in first_post_id: + first_post_id = first_post_id.split('?')[0] + first_post_id = first_post_id.replace('/', '--') + first_post_id = ';firstpost=' + first_post_id.replace('#', '--') + timeline_bookmark = '' + if '?bm=' in path: + timeline_bookmark = path.split('?bm=')[1] + if '?' in timeline_bookmark: + timeline_bookmark = timeline_bookmark.split('?')[0] + timeline_bookmark = '#' + timeline_bookmark + if '?page=' in path: + page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] + if '?' in page_number_str: + page_number_str = page_number_str.split('?')[0] + if '#' in page_number_str: + page_number_str = page_number_str.split('#')[0] + if len(page_number_str) > 5: + page_number_str = "1" + if page_number_str.isdigit(): + page_number = int(page_number_str) + timeline_str = 'inbox' + if '?tl=' in path: + timeline_str = path.split('?tl=')[1] + if '?' in timeline_str: + timeline_str = timeline_str.split('?')[0] + actor = path.split('?unreact=')[0] + self.post_to_nickname = get_nickname_from_actor(actor) + if not self.post_to_nickname: + print('WARN: unable to find nickname in ' + actor) + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + actor + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + redirect_headers(self, actor_path_str, cookie, + calling_domain) + return + emoji_content_encoded = None + if '?emojreact=' in path: + emoji_content_encoded = path.split('?emojreact=')[1] + if '?' in emoji_content_encoded: + emoji_content_encoded = emoji_content_encoded.split('?')[0] + if not emoji_content_encoded: + print('WARN: no emoji reaction ' + actor) + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + actor + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + timeline_bookmark + redirect_headers(self, actor_path_str, cookie, + calling_domain) + return + emoji_content = urllib.parse.unquote_plus(emoji_content_encoded) + + if onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + establish_session("undoReactionButton", + curr_session, proxy_type, + self.server) + if not curr_session: + http_404(self, 55) + return + undo_actor = \ + local_actor_url(http_prefix, self.post_to_nickname, domain_full) + actor_reaction = path.split('?actor=')[1] + if '?' in actor_reaction: + actor_reaction = actor_reaction.split('?')[0] + + # if this is an announce then send the emoji reaction + # to the original post + orig_actor, orig_post_url, orig_filename = \ + get_original_post_from_announce_url(reaction_url, base_dir, + self.post_to_nickname, domain) + reaction_url2 = reaction_url + reaction_post_filename = orig_filename + if orig_actor and orig_post_url: + actor_reaction = orig_actor + reaction_url2 = orig_post_url + reaction_post_filename = None + + undo_reaction_json = { + "@context": "https://www.w3.org/ns/activitystreams", + 'type': 'Undo', + 'actor': undo_actor, + 'to': [actor_reaction], + 'object': { + 'type': 'EmojiReact', + 'actor': undo_actor, + 'to': [actor_reaction], + 'object': reaction_url2 + } + } + + # send out the undo emoji reaction to followers + post_to_outbox(self, undo_reaction_json, + self.server.project_version, None, + curr_session, proxy_type) + + # directly undo the emoji reaction within the post file + if not reaction_post_filename: + reaction_post_filename = \ + locate_post(base_dir, self.post_to_nickname, domain, + reaction_url) + if reaction_post_filename: + recent_posts_cache = self.server.recent_posts_cache + reaction_post_json = load_json(reaction_post_filename, 0, 1) + if orig_filename and orig_post_url: + undo_reaction_collection_entry(recent_posts_cache, + base_dir, + reaction_post_filename, + undo_actor, domain, debug, + reaction_post_json, + emoji_content) + reaction_url = orig_post_url + reaction_post_filename = orig_filename + if debug: + print('Removing emoji reaction for ' + reaction_post_filename) + undo_reaction_collection_entry(recent_posts_cache, + base_dir, reaction_post_filename, + undo_actor, domain, debug, + reaction_post_json, emoji_content) + if debug: + print('Regenerating html post for changed ' + + 'emoji reaction collection') + if reaction_post_json: + show_individual_post_icons = True + manually_approve_followers = \ + follower_approval_active(base_dir, + self.post_to_nickname, domain) + show_repeats = not is_dm(reaction_post_json) + timezone = None + if self.server.account_timezone.get(self.post_to_nickname): + timezone = \ + self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(reaction_post_filename.replace('.json', '') + + '.mitm'): + mitm = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True + minimize_all_images = False + if self.post_to_nickname in \ + self.server.min_images_for_accounts: + minimize_all_images = True + individual_post_as_html(self.server.signing_priv_key_pem, + False, + self.server.recent_posts_cache, + self.server.max_recent_posts, + self.server.translate, + page_number, base_dir, + curr_session, + self.server.cached_webfingers, + self.server.person_cache, + self.post_to_nickname, domain, + self.server.port, reaction_post_json, + None, True, + self.server.allow_deletion, + http_prefix, + self.server.project_version, + timeline_str, + self.server.yt_replace_domain, + self.server.twitter_replacement_domain, + self.server.show_published_date_only, + self.server.peertube_instances, + self.server.allow_local_network_access, + self.server.theme_name, + self.server.system_language, + self.server.max_like_count, + show_repeats, + show_individual_post_icons, + manually_approve_followers, + False, True, False, + self.server.cw_lists, + self.server.lists_enabled, + timezone, mitm, bold_reading, + self.server.dogwhistles, + minimize_all_images, None, + self.server.buy_sites, + self.server.auto_cw_cache) + else: + print('WARN: Unreaction post not found: ' + + reaction_post_filename) + + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + '/users/' + self.post_to_nickname + + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + first_post_id + \ + timeline_bookmark + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_undo_reaction_button', + self.server.debug) + redirect_headers(self, actor_path_str, cookie, calling_domain) + + +def bookmark_button(self, calling_domain: str, path: str, + base_dir: str, http_prefix: str, + domain: str, domain_full: str, port: int, + onion_domain: str, i2p_domain: str, + getreq_start_time, + proxy_type: str, cookie: str, + debug: str, + curr_session) -> None: + """Bookmark button was pressed + """ + page_number = 1 + bookmark_url = path.split('?bookmark=')[1] + if '?' in bookmark_url: + bookmark_url = bookmark_url.split('?')[0] + first_post_id = '' + if '?firstpost=' in path: + first_post_id = path.split('?firstpost=')[1] + if '?' in first_post_id: + first_post_id = first_post_id.split('?')[0] + first_post_id = first_post_id.replace('/', '--') + first_post_id = ';firstpost=' + first_post_id.replace('#', '--') + timeline_bookmark = '' + if '?bm=' in path: + timeline_bookmark = path.split('?bm=')[1] + if '?' in timeline_bookmark: + timeline_bookmark = timeline_bookmark.split('?')[0] + timeline_bookmark = '#' + timeline_bookmark + actor = path.split('?bookmark=')[0] + if '?page=' in path: + page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] + if '?' in page_number_str: + page_number_str = page_number_str.split('?')[0] + if '#' in page_number_str: + page_number_str = page_number_str.split('#')[0] + if len(page_number_str) > 5: + page_number_str = "1" + if page_number_str.isdigit(): + page_number = int(page_number_str) + timeline_str = 'inbox' + if '?tl=' in path: + timeline_str = path.split('?tl=')[1] + if '?' in timeline_str: + timeline_str = timeline_str.split('?')[0] + + self.post_to_nickname = get_nickname_from_actor(actor) + if not self.post_to_nickname: + print('WARN: unable to find nickname in ' + actor) + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + actor + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + redirect_headers(self, actor_path_str, cookie, + calling_domain) + return + + if onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + establish_session("bookmarkButton", + curr_session, proxy_type, + self.server) + if not curr_session: + http_404(self, 56) + return + bookmark_actor = \ + local_actor_url(http_prefix, self.post_to_nickname, domain_full) + cc_list = [] + bookmark_post(self.server.recent_posts_cache, + base_dir, self.server.federation_list, + self.post_to_nickname, domain, port, + cc_list, http_prefix, bookmark_url, bookmark_actor, + debug) + # clear the icon from the cache so that it gets updated + if self.server.iconsCache.get('bookmark.png'): + del self.server.iconsCache['bookmark.png'] + bookmark_filename = \ + locate_post(base_dir, self.post_to_nickname, domain, bookmark_url) + if bookmark_filename: + print('Regenerating html post for changed bookmark') + bookmark_post_json = load_json(bookmark_filename, 0, 1) + if bookmark_post_json: + cached_post_filename = \ + get_cached_post_filename(base_dir, self.post_to_nickname, + domain, bookmark_post_json) + print('Bookmarked post json: ' + str(bookmark_post_json)) + print('Bookmarked post nickname: ' + + self.post_to_nickname + ' ' + domain) + print('Bookmarked post cache: ' + str(cached_post_filename)) + show_individual_post_icons = True + manually_approve_followers = \ + follower_approval_active(base_dir, + self.post_to_nickname, domain) + show_repeats = not is_dm(bookmark_post_json) + timezone = None + if self.server.account_timezone.get(self.post_to_nickname): + timezone = \ + self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(bookmark_filename.replace('.json', '') + + '.mitm'): + mitm = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True + minimize_all_images = False + if self.post_to_nickname in \ + self.server.min_images_for_accounts: + minimize_all_images = True + individual_post_as_html(self.server.signing_priv_key_pem, + False, + self.server.recent_posts_cache, + self.server.max_recent_posts, + self.server.translate, + page_number, base_dir, + curr_session, + self.server.cached_webfingers, + self.server.person_cache, + self.post_to_nickname, domain, + self.server.port, bookmark_post_json, + None, True, + self.server.allow_deletion, + http_prefix, + self.server.project_version, + timeline_str, + self.server.yt_replace_domain, + self.server.twitter_replacement_domain, + self.server.show_published_date_only, + self.server.peertube_instances, + self.server.allow_local_network_access, + self.server.theme_name, + self.server.system_language, + self.server.max_like_count, + show_repeats, + show_individual_post_icons, + manually_approve_followers, + False, True, False, + self.server.cw_lists, + self.server.lists_enabled, + timezone, mitm, bold_reading, + self.server.dogwhistles, + minimize_all_images, None, + self.server.buy_sites, + self.server.auto_cw_cache) + else: + print('WARN: Bookmarked post not found: ' + bookmark_filename) + # _post_to_outbox(self, bookmark_json, + # self.server.project_version, None, + # curr_session, proxy_type) + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + '/users/' + self.post_to_nickname + + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + first_post_id + \ + timeline_bookmark + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_bookmark_button', + debug) + redirect_headers(self, actor_path_str, cookie, + calling_domain) + + +def bookmark_button_undo(self, calling_domain: str, path: str, + base_dir: str, http_prefix: str, + domain: str, domain_full: str, port: int, + onion_domain: str, i2p_domain: str, + getreq_start_time, + proxy_type: str, cookie: str, + debug: str, + curr_session) -> None: + """Button pressed to undo a bookmark + """ + page_number = 1 + bookmark_url = path.split('?unbookmark=')[1] + if '?' in bookmark_url: + bookmark_url = bookmark_url.split('?')[0] + first_post_id = '' + if '?firstpost=' in path: + first_post_id = path.split('?firstpost=')[1] + if '?' in first_post_id: + first_post_id = first_post_id.split('?')[0] + first_post_id = first_post_id.replace('/', '--') + first_post_id = ';firstpost=' + first_post_id.replace('#', '--') + timeline_bookmark = '' + if '?bm=' in path: + timeline_bookmark = path.split('?bm=')[1] + if '?' in timeline_bookmark: + timeline_bookmark = timeline_bookmark.split('?')[0] + timeline_bookmark = '#' + timeline_bookmark + if '?page=' in path: + page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] + if '?' in page_number_str: + page_number_str = page_number_str.split('?')[0] + if '#' in page_number_str: + page_number_str = page_number_str.split('#')[0] + if len(page_number_str) > 5: + page_number_str = "1" + if page_number_str.isdigit(): + page_number = int(page_number_str) + timeline_str = 'inbox' + if '?tl=' in path: + timeline_str = path.split('?tl=')[1] + if '?' in timeline_str: + timeline_str = timeline_str.split('?')[0] + actor = path.split('?unbookmark=')[0] + self.post_to_nickname = get_nickname_from_actor(actor) + if not self.post_to_nickname: + print('WARN: unable to find nickname in ' + actor) + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + actor + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + redirect_headers(self, actor_path_str, cookie, + calling_domain) + return + + if onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + establish_session("undo_bookmarkButton", + curr_session, proxy_type, + self.server) + if not curr_session: + http_404(self, 57) + return + undo_actor = \ + local_actor_url(http_prefix, self.post_to_nickname, domain_full) + cc_list = [] + undo_bookmark_post(self.server.recent_posts_cache, + base_dir, self.server.federation_list, + self.post_to_nickname, + domain, port, cc_list, http_prefix, + bookmark_url, undo_actor, debug) + # clear the icon from the cache so that it gets updated + if self.server.iconsCache.get('bookmark_inactive.png'): + del self.server.iconsCache['bookmark_inactive.png'] + # post_to_outbox(self, undo_bookmark_json, + # self.server.project_version, None, + # curr_session, proxy_type) + bookmark_filename = \ + locate_post(base_dir, self.post_to_nickname, domain, bookmark_url) + if bookmark_filename: + print('Regenerating html post for changed unbookmark') + bookmark_post_json = load_json(bookmark_filename, 0, 1) + if bookmark_post_json: + cached_post_filename = \ + get_cached_post_filename(base_dir, self.post_to_nickname, + domain, bookmark_post_json) + print('Unbookmarked post json: ' + str(bookmark_post_json)) + print('Unbookmarked post nickname: ' + + self.post_to_nickname + ' ' + domain) + print('Unbookmarked post cache: ' + str(cached_post_filename)) + show_individual_post_icons = True + manually_approve_followers = \ + follower_approval_active(base_dir, + self.post_to_nickname, domain) + show_repeats = not is_dm(bookmark_post_json) + timezone = None + if self.server.account_timezone.get(self.post_to_nickname): + timezone = \ + self.server.account_timezone.get(self.post_to_nickname) + mitm = False + if os.path.isfile(bookmark_filename.replace('.json', '') + + '.mitm'): + mitm = True + bold_reading = False + if self.server.bold_reading.get(self.post_to_nickname): + bold_reading = True + minimize_all_images = False + if self.post_to_nickname in \ + self.server.min_images_for_accounts: + minimize_all_images = True + individual_post_as_html(self.server.signing_priv_key_pem, + False, + self.server.recent_posts_cache, + self.server.max_recent_posts, + self.server.translate, + page_number, base_dir, + curr_session, + self.server.cached_webfingers, + self.server.person_cache, + self.post_to_nickname, domain, + self.server.port, bookmark_post_json, + None, True, + self.server.allow_deletion, + http_prefix, + self.server.project_version, + timeline_str, + self.server.yt_replace_domain, + self.server.twitter_replacement_domain, + self.server.show_published_date_only, + self.server.peertube_instances, + self.server.allow_local_network_access, + self.server.theme_name, + self.server.system_language, + self.server.max_like_count, + show_repeats, + show_individual_post_icons, + manually_approve_followers, + False, True, False, + self.server.cw_lists, + self.server.lists_enabled, + timezone, mitm, bold_reading, + self.server.dogwhistles, + minimize_all_images, None, + self.server.buy_sites, + self.server.auto_cw_cache) + else: + print('WARN: Unbookmarked post not found: ' + + bookmark_filename) + actor_absolute = \ + get_instance_url(calling_domain, + self.server.http_prefix, + self.server.domain_full, + self.server.onion_domain, + self.server.i2p_domain) + \ + '/users/' + self.post_to_nickname + + actor_path_str = \ + actor_absolute + '/' + timeline_str + \ + '?page=' + str(page_number) + first_post_id + \ + timeline_bookmark + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_undo_bookmark_button', + self.server.debug) + redirect_headers(self, actor_path_str, cookie, + calling_domain) + + +def delete_button(self, calling_domain: str, path: str, + base_dir: str, http_prefix: str, + domain_full: str, + onion_domain: str, i2p_domain: str, + getreq_start_time, + proxy_type: str, cookie: str, + debug: str, curr_session) -> None: + """Delete button is pressed on a post + """ + if not cookie: + print('ERROR: no cookie given when deleting ' + path) + http_400(self) + return + page_number = 1 + if '?page=' in path: + page_number_str = path.split('?page=')[1] + if '?' in page_number_str: + page_number_str = page_number_str.split('?')[0] + if '#' in page_number_str: + page_number_str = page_number_str.split('#')[0] + if len(page_number_str) > 5: + page_number_str = "1" + if page_number_str.isdigit(): + page_number = int(page_number_str) + delete_url = path.split('?delete=')[1] + if '?' in delete_url: + delete_url = delete_url.split('?')[0] + timeline_str = self.server.default_timeline + if '?tl=' in path: + timeline_str = path.split('?tl=')[1] + if '?' in timeline_str: + timeline_str = timeline_str.split('?')[0] + users_path = path.split('?delete=')[0] + actor = \ + http_prefix + '://' + domain_full + users_path + if self.server.allow_deletion or \ + delete_url.startswith(actor): + if self.server.debug: + print('DEBUG: delete_url=' + delete_url) + print('DEBUG: actor=' + actor) + if actor not in delete_url: + # You can only delete your own posts + if calling_domain.endswith('.onion') and onion_domain: + actor = 'http://' + onion_domain + users_path + elif calling_domain.endswith('.i2p') and i2p_domain: + actor = 'http://' + i2p_domain + users_path + redirect_headers(self, actor + '/' + timeline_str, + cookie, calling_domain) + return + self.post_to_nickname = get_nickname_from_actor(actor) + if not self.post_to_nickname: + print('WARN: unable to find nickname in ' + actor) + if calling_domain.endswith('.onion') and onion_domain: + actor = 'http://' + onion_domain + users_path + elif calling_domain.endswith('.i2p') and i2p_domain: + actor = 'http://' + i2p_domain + users_path + redirect_headers(self, actor + '/' + timeline_str, + cookie, calling_domain) + return + + if onion_domain: + if '.onion/' in actor: + curr_session = self.server.session_onion + proxy_type = 'tor' + if i2p_domain: + if '.onion/' in actor: + curr_session = self.server.session_i2p + proxy_type = 'i2p' + + curr_session = \ + establish_session("deleteButton", + curr_session, proxy_type, + self.server) + if not curr_session: + http_404(self, 58) + return + + delete_str = \ + html_confirm_delete(self.server, + self.server.recent_posts_cache, + self.server.max_recent_posts, + self.server.translate, page_number, + curr_session, base_dir, + delete_url, http_prefix, + self.server.project_version, + self.server.cached_webfingers, + self.server.person_cache, calling_domain, + self.server.yt_replace_domain, + self.server.twitter_replacement_domain, + self.server.show_published_date_only, + self.server.peertube_instances, + self.server.allow_local_network_access, + self.server.theme_name, + self.server.system_language, + self.server.max_like_count, + self.server.signing_priv_key_pem, + self.server.cw_lists, + self.server.lists_enabled, + self.server.dogwhistles, + self.server.min_images_for_accounts, + self.server.buy_sites, + self.server.auto_cw_cache) + if delete_str: + delete_str_len = len(delete_str) + set_headers(self, 'text/html', delete_str_len, + cookie, calling_domain, False) + write2(self, delete_str.encode('utf-8')) + self.server.getreq_busy = False + return + if calling_domain.endswith('.onion') and onion_domain: + actor = 'http://' + onion_domain + users_path + elif (calling_domain.endswith('.i2p') and i2p_domain): + actor = 'http://' + i2p_domain + users_path + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_delete_button', + debug) + redirect_headers(self, actor + '/' + timeline_str, + cookie, calling_domain) + + +def mute_button(self, calling_domain: str, path: str, + base_dir: str, http_prefix: str, + domain: str, domain_full: str, port: int, + onion_domain: str, i2p_domain: str, + getreq_start_time, cookie: str, + debug: str, curr_session): + """Mute button is pressed + """ + mute_url = path.split('?mute=')[1] + if '?' in mute_url: + mute_url = mute_url.split('?')[0] + first_post_id = '' + if '?firstpost=' in path: + first_post_id = path.split('?firstpost=')[1] + if '?' in first_post_id: + first_post_id = first_post_id.split('?')[0] + first_post_id = first_post_id.replace('/', '--') + first_post_id = ';firstpost=' + first_post_id.replace('#', '--') + timeline_bookmark = '' + if '?bm=' in path: + timeline_bookmark = path.split('?bm=')[1] + if '?' in timeline_bookmark: + timeline_bookmark = timeline_bookmark.split('?')[0] + timeline_bookmark = '#' + timeline_bookmark + timeline_str = self.server.default_timeline + if '?tl=' in path: + timeline_str = path.split('?tl=')[1] + if '?' in timeline_str: + timeline_str = timeline_str.split('?')[0] + page_number = 1 + if '?page=' in path: + page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] + if '?' in page_number_str: + page_number_str = page_number_str.split('?')[0] + if '#' in page_number_str: + page_number_str = page_number_str.split('#')[0] + if len(page_number_str) > 5: + page_number_str = "1" + if page_number_str.isdigit(): + page_number = int(page_number_str) + actor = \ + http_prefix + '://' + domain_full + path.split('?mute=')[0] + nickname = get_nickname_from_actor(actor) + if not nickname: + http_404(self, 59) + return + mute_post(base_dir, nickname, domain, port, + http_prefix, mute_url, + self.server.recent_posts_cache, debug) + mute_filename = \ + locate_post(base_dir, nickname, domain, mute_url) + if mute_filename: + print('mute_post: Regenerating html post for changed mute status') + mute_post_json = load_json(mute_filename, 0, 1) + if mute_post_json: + cached_post_filename = \ + get_cached_post_filename(base_dir, nickname, + domain, mute_post_json) + print('mute_post: Muted post json: ' + str(mute_post_json)) + print('mute_post: Muted post nickname: ' + + nickname + ' ' + domain) + print('mute_post: Muted post cache: ' + + str(cached_post_filename)) + show_individual_post_icons = True + manually_approve_followers = \ + follower_approval_active(base_dir, + nickname, domain) + show_repeats = not is_dm(mute_post_json) + show_public_only = False + store_to_cache = True + use_cache_only = False + allow_downloads = False + show_avatar_options = True + avatar_url = None + timezone = None + if self.server.account_timezone.get(nickname): + timezone = \ + self.server.account_timezone.get(nickname) + mitm = False + if os.path.isfile(mute_filename.replace('.json', '') + + '.mitm'): + mitm = True + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True + minimize_all_images = False + if nickname in self.server.min_images_for_accounts: + minimize_all_images = True + individual_post_as_html(self.server.signing_priv_key_pem, + allow_downloads, + self.server.recent_posts_cache, + self.server.max_recent_posts, + self.server.translate, + page_number, base_dir, + curr_session, + self.server.cached_webfingers, + self.server.person_cache, + nickname, domain, + self.server.port, mute_post_json, + avatar_url, show_avatar_options, + self.server.allow_deletion, + http_prefix, + self.server.project_version, + timeline_str, + self.server.yt_replace_domain, + self.server.twitter_replacement_domain, + self.server.show_published_date_only, + self.server.peertube_instances, + self.server.allow_local_network_access, + self.server.theme_name, + self.server.system_language, + self.server.max_like_count, + show_repeats, + show_individual_post_icons, + manually_approve_followers, + show_public_only, store_to_cache, + use_cache_only, + self.server.cw_lists, + self.server.lists_enabled, + timezone, mitm, bold_reading, + self.server.dogwhistles, + minimize_all_images, None, + self.server.buy_sites, + self.server.auto_cw_cache) + else: + print('WARN: Muted post not found: ' + mute_filename) + + if calling_domain.endswith('.onion') and onion_domain: + actor = \ + 'http://' + onion_domain + \ + path.split('?mute=')[0] + elif (calling_domain.endswith('.i2p') and i2p_domain): + actor = \ + 'http://' + i2p_domain + \ + path.split('?mute=')[0] + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_mute_button', self.server.debug) + + page_number_str = str(page_number) + redirect_str = \ + actor + '/' + timeline_str + '?page=' + page_number_str + \ + first_post_id + timeline_bookmark + redirect_headers(self, redirect_str, cookie, calling_domain) + + +def mute_button_undo(self, calling_domain: str, path: str, + base_dir: str, http_prefix: str, + domain: str, domain_full: str, port: int, + onion_domain: str, i2p_domain: str, + getreq_start_time, cookie: str, + debug: str, curr_session): + """Undo mute button is pressed + """ + mute_url = path.split('?unmute=')[1] + if '?' in mute_url: + mute_url = mute_url.split('?')[0] + first_post_id = '' + if '?firstpost=' in path: + first_post_id = path.split('?firstpost=')[1] + if '?' in first_post_id: + first_post_id = first_post_id.split('?')[0] + first_post_id = first_post_id.replace('/', '--') + first_post_id = ';firstpost=' + first_post_id.replace('#', '--') + timeline_bookmark = '' + if '?bm=' in path: + timeline_bookmark = path.split('?bm=')[1] + if '?' in timeline_bookmark: + timeline_bookmark = timeline_bookmark.split('?')[0] + timeline_bookmark = '#' + timeline_bookmark + timeline_str = self.server.default_timeline + if '?tl=' in path: + timeline_str = path.split('?tl=')[1] + if '?' in timeline_str: + timeline_str = timeline_str.split('?')[0] + page_number = 1 + if '?page=' in path: + page_number_str = path.split('?page=')[1] + if ';' in page_number_str: + page_number_str = page_number_str.split(';')[0] + if '?' in page_number_str: + page_number_str = page_number_str.split('?')[0] + if '#' in page_number_str: + page_number_str = page_number_str.split('#')[0] + if len(page_number_str) > 5: + page_number_str = "1" + if page_number_str.isdigit(): + page_number = int(page_number_str) + actor = \ + http_prefix + '://' + domain_full + path.split('?unmute=')[0] + nickname = get_nickname_from_actor(actor) + if not nickname: + http_404(self, 60) + return + unmute_post(base_dir, nickname, domain, port, + http_prefix, mute_url, + self.server.recent_posts_cache, debug) + mute_filename = \ + locate_post(base_dir, nickname, domain, mute_url) + if mute_filename: + print('unmute_post: ' + + 'Regenerating html post for changed unmute status') + mute_post_json = load_json(mute_filename, 0, 1) + if mute_post_json: + cached_post_filename = \ + get_cached_post_filename(base_dir, nickname, + domain, mute_post_json) + print('unmute_post: Unmuted post json: ' + str(mute_post_json)) + print('unmute_post: Unmuted post nickname: ' + + nickname + ' ' + domain) + print('unmute_post: Unmuted post cache: ' + + str(cached_post_filename)) + show_individual_post_icons = True + manually_approve_followers = \ + follower_approval_active(base_dir, nickname, domain) + show_repeats = not is_dm(mute_post_json) + show_public_only = False + store_to_cache = True + use_cache_only = False + allow_downloads = False + show_avatar_options = True + avatar_url = None + timezone = None + if self.server.account_timezone.get(nickname): + timezone = \ + self.server.account_timezone.get(nickname) + mitm = False + if os.path.isfile(mute_filename.replace('.json', '') + + '.mitm'): + mitm = True + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True + minimize_all_images = False + if nickname in self.server.min_images_for_accounts: + minimize_all_images = True + individual_post_as_html(self.server.signing_priv_key_pem, + allow_downloads, + self.server.recent_posts_cache, + self.server.max_recent_posts, + self.server.translate, + page_number, base_dir, + curr_session, + self.server.cached_webfingers, + self.server.person_cache, + nickname, domain, + self.server.port, mute_post_json, + avatar_url, show_avatar_options, + self.server.allow_deletion, + http_prefix, + self.server.project_version, + timeline_str, + self.server.yt_replace_domain, + self.server.twitter_replacement_domain, + self.server.show_published_date_only, + self.server.peertube_instances, + self.server.allow_local_network_access, + self.server.theme_name, + self.server.system_language, + self.server.max_like_count, + show_repeats, + show_individual_post_icons, + manually_approve_followers, + show_public_only, store_to_cache, + use_cache_only, + self.server.cw_lists, + self.server.lists_enabled, + timezone, mitm, bold_reading, + self.server.dogwhistles, + minimize_all_images, None, + self.server.buy_sites, + self.server.auto_cw_cache) + else: + print('WARN: Unmuted post not found: ' + mute_filename) + if calling_domain.endswith('.onion') and onion_domain: + actor = \ + 'http://' + onion_domain + path.split('?unmute=')[0] + elif calling_domain.endswith('.i2p') and i2p_domain: + actor = \ + 'http://' + i2p_domain + path.split('?unmute=')[0] + fitness_performance(getreq_start_time, self.server.fitness, + '_GET', '_undo_mute_button', self.server.debug) + + page_number_str = str(page_number) + redirect_str = \ + actor + '/' + timeline_str + '?page=' + page_number_str + \ + first_post_id + timeline_bookmark + redirect_headers(self, redirect_str, cookie, calling_domain)