From 2921101654dc1659d79928bde49da207cc4730b6 Mon Sep 17 00:00:00 2001 From: Bob Mottram <bob@libreserver.org> Date: Sun, 3 Mar 2024 20:03:11 +0000 Subject: [PATCH] Move daemon search function to its own module --- daemon_post.py | 649 ++---------------------------------------- daemon_post_search.py | 640 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 657 insertions(+), 632 deletions(-) create mode 100644 daemon_post_search.py diff --git a/daemon_post.py b/daemon_post.py index 4ebf35f1f..bff07dcd9 100644 --- a/daemon_post.py +++ b/daemon_post.py @@ -22,10 +22,8 @@ from utils import get_image_extension_from_mime_type from utils import remove_post_from_cache from utils import get_cached_post_filename from utils import text_in_file -from utils import has_users_path from utils import has_group_type from utils import get_status_number -from utils import remove_eol from utils import load_json from utils import save_json from utils import delete_post @@ -76,7 +74,6 @@ from httpcodes import http_503 from httpheaders import login_headers from httpheaders import redirect_headers from daemon_utils import get_user_agent -from daemon_utils import show_person_options from daemon_utils import post_to_outbox from daemon_utils import update_inbox_queue from daemon_utils import is_authorized @@ -94,21 +91,12 @@ from cache import clear_actor_cache from theme import reset_theme_designer_settings from theme import set_theme from theme import set_theme_from_designer -from webapp_profile import html_profile_after_search -from webapp_search import html_hashtag_search from languages import get_understood_languages from follow import send_follow_request from follow import unfollow_account from follow import remove_follower -from follow import is_follower_of_person -from follow import is_following_actor from daemon_utils import post_to_outbox_thread from reading import remove_reading_event -from webapp_search import html_skills_search -from webapp_search import html_history_search -from webapp_search import html_search_emoji -from webapp_search import html_search_shared_items -from webapp_utils import get_avatar_image_url from city import get_spoofed_city from posts import create_direct_message_post from happening import remove_calendar_event @@ -116,6 +104,7 @@ from daemon_post_login import post_login_screen from daemon_post_receive import receive_new_post from daemon_post_profile import profile_edit from daemon_post_person_options import person_options2 +from daemon_post_search import receive_search_query # maximum number of posts in a hashtag feed MAX_POSTS_IN_HASHTAG_FEED = 6 @@ -369,25 +358,26 @@ def daemon_http_post(self) -> None: if ((authorized or search_for_emoji) and (self.path.endswith('/searchhandle') or '/searchhandle?page=' in self.path)): - _receive_search_query(self, calling_domain, cookie, - authorized, self.path, - self.server.base_dir, - self.server.http_prefix, - self.server.domain, - self.server.domain_full, - self.server.port, - search_for_emoji, - self.server.onion_domain, - self.server.i2p_domain, - postreq_start_time, - self.server.debug, - curr_session, - proxy_type) + receive_search_query(self, calling_domain, cookie, + authorized, self.path, + self.server.base_dir, + self.server.http_prefix, + self.server.domain, + self.server.domain_full, + self.server.port, + search_for_emoji, + self.server.onion_domain, + self.server.i2p_domain, + postreq_start_time, + self.server.debug, + curr_session, + proxy_type, MAX_POSTS_IN_HASHTAG_FEED, + MAX_POSTS_IN_FEED) self.server.postreq_busy = False return fitness_performance(postreq_start_time, self.server.fitness, - '_POST', '_receive_search_query', + '_POST', 'receive_search_query', self.server.debug) if not authorized: @@ -2180,611 +2170,6 @@ def _unblock_confirm(self, calling_domain: str, cookie: str, self.server.postreq_busy = False -def _receive_search_query(self, calling_domain: str, cookie: str, - authorized: bool, path: str, - base_dir: str, http_prefix: str, - domain: str, domain_full: str, - port: int, search_for_emoji: bool, - onion_domain: str, i2p_domain: str, - getreq_start_time, debug: bool, - curr_session, proxy_type: str) -> None: - """Receive a search query - """ - # get the page number - page_number = 1 - if '/searchhandle?page=' in path: - page_number_str = path.split('/searchhandle?page=')[1] - 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) - path = path.split('?page=')[0] - - users_path = path.replace('/searchhandle', '') - actor_str = \ - get_instance_url(calling_domain, - http_prefix, - domain_full, - onion_domain, - i2p_domain) + \ - users_path - length = int(self.headers['Content-length']) - try: - search_params = self.rfile.read(length).decode('utf-8') - except SocketError as ex: - if ex.errno == errno.ECONNRESET: - print('EX: POST search_params connection was reset') - else: - print('EX: POST search_params socket error') - self.send_response(400) - self.end_headers() - self.server.postreq_busy = False - return - except ValueError as ex: - print('EX: POST search_params rfile.read failed, ' + str(ex)) - self.send_response(400) - self.end_headers() - self.server.postreq_busy = False - return - if 'submitBack=' in search_params: - # go back on search screen - redirect_headers(self, actor_str + '/' + - self.server.default_timeline, - cookie, calling_domain) - self.server.postreq_busy = False - return - if 'searchtext=' in search_params: - search_str = search_params.split('searchtext=')[1] - if '&' in search_str: - search_str = search_str.split('&')[0] - search_str = \ - urllib.parse.unquote_plus(search_str.strip()) - search_str = search_str.strip() - print('search_str: ' + search_str) - if search_for_emoji: - search_str = ':' + search_str + ':' - if search_str.startswith('#'): - nickname = get_nickname_from_actor(actor_str) - if not nickname: - self.send_response(400) - self.end_headers() - self.server.postreq_busy = False - return - - # hashtag search - timezone = None - if self.server.account_timezone.get(nickname): - timezone = \ - self.server.account_timezone.get(nickname) - bold_reading = False - if self.server.bold_reading.get(nickname): - bold_reading = True - hashtag_str = \ - html_hashtag_search(nickname, domain, port, - self.server.recent_posts_cache, - self.server.max_recent_posts, - self.server.translate, - base_dir, - search_str[1:], 1, - MAX_POSTS_IN_HASHTAG_FEED, - curr_session, - self.server.cached_webfingers, - self.server.person_cache, - http_prefix, - self.server.project_version, - 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, - timezone, bold_reading, - self.server.dogwhistles, - self.server.map_format, - self.server.access_keys, - 'search', - self.server.min_images_for_accounts, - self.server.buy_sites, - self.server.auto_cw_cache) - if hashtag_str: - msg = hashtag_str.encode('utf-8') - msglen = len(msg) - login_headers(self, 'text/html', - msglen, calling_domain) - write2(self, msg) - self.server.postreq_busy = False - return - elif (search_str.startswith('*') or - search_str.endswith(' skill')): - possible_endings = ( - ' skill' - ) - for poss_ending in possible_endings: - if search_str.endswith(poss_ending): - search_str = search_str.replace(poss_ending, '') - break - # skill search - search_str = search_str.replace('*', '').strip() - nickname = get_nickname_from_actor(actor_str) - skill_str = \ - html_skills_search(actor_str, - self.server.translate, - base_dir, - search_str, - self.server.instance_only_skills_search, - 64, nickname, domain, - self.server.theme_name, - self.server.access_keys) - if skill_str: - msg = skill_str.encode('utf-8') - msglen = len(msg) - login_headers(self, 'text/html', - msglen, calling_domain) - write2(self, msg) - self.server.postreq_busy = False - return - elif (search_str.startswith("'") or - search_str.endswith(' history') or - search_str.endswith(' in sent') or - search_str.endswith(' in outbox') or - search_str.endswith(' in outgoing') or - search_str.endswith(' in sent items') or - search_str.endswith(' in sent posts') or - search_str.endswith(' in outgoing posts') or - search_str.endswith(' in my history') or - search_str.endswith(' in my outbox') or - search_str.endswith(' in my posts')): - possible_endings = ( - ' in my posts', - ' in my history', - ' in my outbox', - ' in sent posts', - ' in outgoing posts', - ' in sent items', - ' in history', - ' in outbox', - ' in outgoing', - ' in sent', - ' history' - ) - for poss_ending in possible_endings: - if search_str.endswith(poss_ending): - search_str = search_str.replace(poss_ending, '') - break - # your post history search - nickname = get_nickname_from_actor(actor_str) - if not nickname: - self.send_response(400) - self.end_headers() - self.server.postreq_busy = False - return - search_str = search_str.replace("'", '', 1).strip() - timezone = None - if self.server.account_timezone.get(nickname): - timezone = \ - self.server.account_timezone.get(nickname) - bold_reading = False - if self.server.bold_reading.get(nickname): - bold_reading = True - history_str = \ - html_history_search(self.server.translate, - base_dir, - http_prefix, - nickname, - domain, - search_str, - MAX_POSTS_IN_FEED, - page_number, - self.server.project_version, - self.server.recent_posts_cache, - self.server.max_recent_posts, - curr_session, - self.server.cached_webfingers, - self.server.person_cache, - port, - 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, 'outbox', - self.server.system_language, - self.server.max_like_count, - self.server.signing_priv_key_pem, - self.server.cw_lists, - self.server.lists_enabled, - timezone, bold_reading, - self.server.dogwhistles, - self.server.access_keys, - self.server.min_images_for_accounts, - self.server.buy_sites, - self.server.auto_cw_cache) - if history_str: - msg = history_str.encode('utf-8') - msglen = len(msg) - login_headers(self, 'text/html', - msglen, calling_domain) - write2(self, msg) - self.server.postreq_busy = False - return - elif (search_str.startswith('-') or - search_str.endswith(' in my saved items') or - search_str.endswith(' in my saved posts') or - search_str.endswith(' in my bookmarks') or - search_str.endswith(' in my saved') or - search_str.endswith(' in my saves') or - search_str.endswith(' in saved posts') or - search_str.endswith(' in saved items') or - search_str.endswith(' in bookmarks') or - search_str.endswith(' in saved') or - search_str.endswith(' in saves') or - search_str.endswith(' bookmark')): - possible_endings = ( - ' in my bookmarks' - ' in my saved posts' - ' in my saved items' - ' in my saved' - ' in my saves' - ' in saved posts' - ' in saved items' - ' in saved' - ' in saves' - ' in bookmarks' - ' bookmark' - ) - for poss_ending in possible_endings: - if search_str.endswith(poss_ending): - search_str = search_str.replace(poss_ending, '') - break - # bookmark search - nickname = get_nickname_from_actor(actor_str) - if not nickname: - self.send_response(400) - self.end_headers() - self.server.postreq_busy = False - return - search_str = search_str.replace('-', '', 1).strip() - timezone = None - if self.server.account_timezone.get(nickname): - timezone = \ - self.server.account_timezone.get(nickname) - bold_reading = False - if self.server.bold_reading.get(nickname): - bold_reading = True - bookmarks_str = \ - html_history_search(self.server.translate, - base_dir, - http_prefix, - nickname, - domain, - search_str, - MAX_POSTS_IN_FEED, - page_number, - self.server.project_version, - self.server.recent_posts_cache, - self.server.max_recent_posts, - curr_session, - self.server.cached_webfingers, - self.server.person_cache, - port, - 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, 'bookmarks', - self.server.system_language, - self.server.max_like_count, - self.server.signing_priv_key_pem, - self.server.cw_lists, - self.server.lists_enabled, - timezone, bold_reading, - self.server.dogwhistles, - self.server.access_keys, - self.server.min_images_for_accounts, - self.server.buy_sites, - self.server.auto_cw_cache) - if bookmarks_str: - msg = bookmarks_str.encode('utf-8') - msglen = len(msg) - login_headers(self, 'text/html', - msglen, calling_domain) - write2(self, msg) - self.server.postreq_busy = False - return - elif ('@' in search_str or - ('://' in search_str and - has_users_path(search_str))): - remote_only = False - if search_str.endswith(';remote'): - search_str = search_str.replace(';remote', '') - remote_only = True - if search_str.endswith(':') or \ - search_str.endswith(';') or \ - search_str.endswith('.'): - actor_str = \ - get_instance_url(calling_domain, http_prefix, - domain_full, onion_domain, - i2p_domain) + \ - users_path - redirect_headers(self, actor_str + '/search', - cookie, calling_domain) - self.server.postreq_busy = False - return - # profile search - nickname = get_nickname_from_actor(actor_str) - if not nickname: - self.send_response(400) - self.end_headers() - self.server.postreq_busy = False - return - profile_path_str = path.replace('/searchhandle', '') - - # are we already following or followed by the searched - # for handle? - search_nickname = get_nickname_from_actor(search_str) - search_domain, search_port = \ - get_domain_from_actor(search_str) - search_follower = \ - is_follower_of_person(base_dir, nickname, domain, - search_nickname, search_domain) - search_following = \ - is_following_actor(base_dir, nickname, domain, search_str) - if not remote_only and (search_follower or search_following): - # get the actor - if not has_users_path(search_str): - if not search_nickname or not search_domain: - self.send_response(400) - self.end_headers() - self.server.postreq_busy = False - return - search_domain_full = \ - get_full_domain(search_domain, search_port) - actor = \ - local_actor_url(http_prefix, search_nickname, - search_domain_full) - else: - actor = search_str - - # establish the session - curr_proxy_type = proxy_type - if '.onion/' in actor: - curr_proxy_type = 'tor' - curr_session = self.server.session_onion - elif '.i2p/' in actor: - curr_proxy_type = 'i2p' - curr_session = self.server.session_i2p - - curr_session = \ - establish_session("handle search", - curr_session, - curr_proxy_type, - self.server) - if not curr_session: - self.server.postreq_busy = False - return - - # get the avatar url for the actor - avatar_url = \ - get_avatar_image_url(curr_session, - base_dir, http_prefix, - actor, - self.server.person_cache, - None, True, - self.server.signing_priv_key_pem) - profile_path_str += \ - '?options=' + actor + ';1;' + avatar_url - - show_person_options(self, calling_domain, profile_path_str, - base_dir, - domain, domain_full, - getreq_start_time, - cookie, debug, authorized, - curr_session) - return - else: - show_published_date_only = \ - self.server.show_published_date_only - allow_local_network_access = \ - self.server.allow_local_network_access - - access_keys = self.server.access_keys - if self.server.key_shortcuts.get(nickname): - access_keys = self.server.key_shortcuts[nickname] - - signing_priv_key_pem = \ - self.server.signing_priv_key_pem - twitter_replacement_domain = \ - self.server.twitter_replacement_domain - peertube_instances = \ - self.server.peertube_instances - yt_replace_domain = \ - self.server.yt_replace_domain - cached_webfingers = \ - self.server.cached_webfingers - recent_posts_cache = \ - self.server.recent_posts_cache - timezone = None - if self.server.account_timezone.get(nickname): - timezone = \ - self.server.account_timezone.get(nickname) - - profile_handle = remove_eol(search_str).strip() - - # establish the session - curr_proxy_type = proxy_type - if '.onion/' in profile_handle or \ - profile_handle.endswith('.onion'): - curr_proxy_type = 'tor' - curr_session = self.server.session_onion - elif ('.i2p/' in profile_handle or - profile_handle.endswith('.i2p')): - curr_proxy_type = 'i2p' - curr_session = self.server.session_i2p - - curr_session = \ - establish_session("handle search", - curr_session, - curr_proxy_type, - self.server) - if not curr_session: - self.server.postreq_busy = False - return - - bold_reading = False - if self.server.bold_reading.get(nickname): - bold_reading = True - - min_images_for_accounts = \ - self.server.min_images_for_accounts - max_shares_on_profile = \ - self.server.max_shares_on_profile - profile_str = \ - html_profile_after_search(authorized, - recent_posts_cache, - self.server.max_recent_posts, - self.server.translate, - base_dir, - profile_path_str, - http_prefix, - nickname, - domain, - port, - profile_handle, - curr_session, - cached_webfingers, - self.server.person_cache, - self.server.debug, - self.server.project_version, - yt_replace_domain, - twitter_replacement_domain, - show_published_date_only, - self.server.default_timeline, - peertube_instances, - allow_local_network_access, - self.server.theme_name, - access_keys, - self.server.system_language, - self.server.max_like_count, - signing_priv_key_pem, - self.server.cw_lists, - self.server.lists_enabled, - timezone, - self.server.onion_domain, - self.server.i2p_domain, - bold_reading, - self.server.dogwhistles, - min_images_for_accounts, - self.server.buy_sites, - max_shares_on_profile, - self.server.no_of_books, - self.server.auto_cw_cache) - if profile_str: - msg = profile_str.encode('utf-8') - msglen = len(msg) - login_headers(self, 'text/html', - msglen, calling_domain) - write2(self, msg) - self.server.postreq_busy = False - return - actor_str = \ - get_instance_url(calling_domain, - http_prefix, domain_full, - onion_domain, i2p_domain) + \ - users_path - redirect_headers(self, actor_str + '/search', - cookie, calling_domain) - self.server.postreq_busy = False - return - elif (search_str.startswith(':') or - search_str.endswith(' emoji')): - # eg. "cat emoji" - if search_str.endswith(' emoji'): - search_str = \ - search_str.replace(' emoji', '') - # emoji search - nickname = get_nickname_from_actor(actor_str) - emoji_str = \ - html_search_emoji(self.server.translate, - base_dir, search_str, - nickname, domain, - self.server.theme_name, - self.server.access_keys) - if emoji_str: - msg = emoji_str.encode('utf-8') - msglen = len(msg) - login_headers(self, 'text/html', - msglen, calling_domain) - write2(self, msg) - self.server.postreq_busy = False - return - elif search_str.startswith('.'): - # wanted items search - shared_items_federated_domains = \ - self.server.shared_items_federated_domains - nickname = get_nickname_from_actor(actor_str) - wanted_items_str = \ - html_search_shared_items(self.server.translate, - base_dir, - search_str[1:], page_number, - MAX_POSTS_IN_FEED, - http_prefix, - domain_full, - actor_str, calling_domain, - shared_items_federated_domains, - 'wanted', nickname, domain, - self.server.theme_name, - self.server.access_keys) - if wanted_items_str: - msg = wanted_items_str.encode('utf-8') - msglen = len(msg) - login_headers(self, 'text/html', - msglen, calling_domain) - write2(self, msg) - self.server.postreq_busy = False - return - else: - # shared items search - shared_items_federated_domains = \ - self.server.shared_items_federated_domains - nickname = get_nickname_from_actor(actor_str) - shared_items_str = \ - html_search_shared_items(self.server.translate, - base_dir, - search_str, page_number, - MAX_POSTS_IN_FEED, - http_prefix, - domain_full, - actor_str, calling_domain, - shared_items_federated_domains, - 'shares', nickname, domain, - self.server.theme_name, - self.server.access_keys) - if shared_items_str: - msg = shared_items_str.encode('utf-8') - msglen = len(msg) - login_headers(self, 'text/html', - msglen, calling_domain) - write2(self, msg) - self.server.postreq_busy = False - return - actor_str = \ - get_instance_url(calling_domain, http_prefix, - domain_full, onion_domain, i2p_domain) + \ - users_path - redirect_headers(self, actor_str + '/' + - self.server.default_timeline, - cookie, calling_domain) - self.server.postreq_busy = False - - def _receive_vote(self, calling_domain: str, cookie: str, path: str, http_prefix: str, domain: str, domain_full: str, port: int, diff --git a/daemon_post_search.py b/daemon_post_search.py new file mode 100644 index 000000000..b139cfde7 --- /dev/null +++ b/daemon_post_search.py @@ -0,0 +1,640 @@ +__filename__ = "daemon_post_search.py" +__author__ = "Bob Mottram" +__license__ = "AGPL3+" +__version__ = "1.5.0" +__maintainer__ = "Bob Mottram" +__email__ = "bob@libreserver.org" +__status__ = "Production" +__module_group__ = "Core" + +import errno +import urllib.parse +from socket import error as SocketError +from utils import get_instance_url +from httpcodes import write2 +from httpheaders import login_headers +from httpheaders import redirect_headers +from utils import has_users_path +from utils import get_nickname_from_actor +from utils import get_domain_from_actor +from utils import get_full_domain +from utils import local_actor_url +from utils import remove_eol +from webapp_utils import get_avatar_image_url +from webapp_search import html_hashtag_search +from webapp_search import html_skills_search +from webapp_search import html_history_search +from webapp_search import html_search_emoji +from webapp_search import html_search_shared_items +from webapp_profile import html_profile_after_search +from follow import is_follower_of_person +from follow import is_following_actor +from session import establish_session +from daemon_utils import show_person_options + + +def receive_search_query(self, calling_domain: str, cookie: str, + authorized: bool, path: str, + base_dir: str, http_prefix: str, + domain: str, domain_full: str, + port: int, search_for_emoji: bool, + onion_domain: str, i2p_domain: str, + getreq_start_time, debug: bool, + curr_session, proxy_type: str, + max_posts_in_hashtag_feed: int, + max_posts_in_feed: int) -> None: + """Receive a search query + """ + # get the page number + page_number = 1 + if '/searchhandle?page=' in path: + page_number_str = path.split('/searchhandle?page=')[1] + 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) + path = path.split('?page=')[0] + + users_path = path.replace('/searchhandle', '') + actor_str = \ + get_instance_url(calling_domain, + http_prefix, + domain_full, + onion_domain, + i2p_domain) + \ + users_path + length = int(self.headers['Content-length']) + try: + search_params = self.rfile.read(length).decode('utf-8') + except SocketError as ex: + if ex.errno == errno.ECONNRESET: + print('EX: POST search_params connection was reset') + else: + print('EX: POST search_params socket error') + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return + except ValueError as ex: + print('EX: POST search_params rfile.read failed, ' + str(ex)) + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return + if 'submitBack=' in search_params: + # go back on search screen + redirect_headers(self, actor_str + '/' + + self.server.default_timeline, + cookie, calling_domain) + self.server.postreq_busy = False + return + if 'searchtext=' in search_params: + search_str = search_params.split('searchtext=')[1] + if '&' in search_str: + search_str = search_str.split('&')[0] + search_str = \ + urllib.parse.unquote_plus(search_str.strip()) + search_str = search_str.strip() + print('search_str: ' + search_str) + if search_for_emoji: + search_str = ':' + search_str + ':' + if search_str.startswith('#'): + nickname = get_nickname_from_actor(actor_str) + if not nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return + + # hashtag search + timezone = None + if self.server.account_timezone.get(nickname): + timezone = \ + self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True + hashtag_str = \ + html_hashtag_search(nickname, domain, port, + self.server.recent_posts_cache, + self.server.max_recent_posts, + self.server.translate, + base_dir, + search_str[1:], 1, + max_posts_in_hashtag_feed, + curr_session, + self.server.cached_webfingers, + self.server.person_cache, + http_prefix, + self.server.project_version, + 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, + timezone, bold_reading, + self.server.dogwhistles, + self.server.map_format, + self.server.access_keys, + 'search', + self.server.min_images_for_accounts, + self.server.buy_sites, + self.server.auto_cw_cache) + if hashtag_str: + msg = hashtag_str.encode('utf-8') + msglen = len(msg) + login_headers(self, 'text/html', + msglen, calling_domain) + write2(self, msg) + self.server.postreq_busy = False + return + elif (search_str.startswith('*') or + search_str.endswith(' skill')): + possible_endings = ( + ' skill' + ) + for poss_ending in possible_endings: + if search_str.endswith(poss_ending): + search_str = search_str.replace(poss_ending, '') + break + # skill search + search_str = search_str.replace('*', '').strip() + nickname = get_nickname_from_actor(actor_str) + skill_str = \ + html_skills_search(actor_str, + self.server.translate, + base_dir, + search_str, + self.server.instance_only_skills_search, + 64, nickname, domain, + self.server.theme_name, + self.server.access_keys) + if skill_str: + msg = skill_str.encode('utf-8') + msglen = len(msg) + login_headers(self, 'text/html', + msglen, calling_domain) + write2(self, msg) + self.server.postreq_busy = False + return + elif (search_str.startswith("'") or + search_str.endswith(' history') or + search_str.endswith(' in sent') or + search_str.endswith(' in outbox') or + search_str.endswith(' in outgoing') or + search_str.endswith(' in sent items') or + search_str.endswith(' in sent posts') or + search_str.endswith(' in outgoing posts') or + search_str.endswith(' in my history') or + search_str.endswith(' in my outbox') or + search_str.endswith(' in my posts')): + possible_endings = ( + ' in my posts', + ' in my history', + ' in my outbox', + ' in sent posts', + ' in outgoing posts', + ' in sent items', + ' in history', + ' in outbox', + ' in outgoing', + ' in sent', + ' history' + ) + for poss_ending in possible_endings: + if search_str.endswith(poss_ending): + search_str = search_str.replace(poss_ending, '') + break + # your post history search + nickname = get_nickname_from_actor(actor_str) + if not nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return + search_str = search_str.replace("'", '', 1).strip() + timezone = None + if self.server.account_timezone.get(nickname): + timezone = \ + self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True + history_str = \ + html_history_search(self.server.translate, + base_dir, + http_prefix, + nickname, + domain, + search_str, + max_posts_in_feed, + page_number, + self.server.project_version, + self.server.recent_posts_cache, + self.server.max_recent_posts, + curr_session, + self.server.cached_webfingers, + self.server.person_cache, + port, + 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, 'outbox', + self.server.system_language, + self.server.max_like_count, + self.server.signing_priv_key_pem, + self.server.cw_lists, + self.server.lists_enabled, + timezone, bold_reading, + self.server.dogwhistles, + self.server.access_keys, + self.server.min_images_for_accounts, + self.server.buy_sites, + self.server.auto_cw_cache) + if history_str: + msg = history_str.encode('utf-8') + msglen = len(msg) + login_headers(self, 'text/html', + msglen, calling_domain) + write2(self, msg) + self.server.postreq_busy = False + return + elif (search_str.startswith('-') or + search_str.endswith(' in my saved items') or + search_str.endswith(' in my saved posts') or + search_str.endswith(' in my bookmarks') or + search_str.endswith(' in my saved') or + search_str.endswith(' in my saves') or + search_str.endswith(' in saved posts') or + search_str.endswith(' in saved items') or + search_str.endswith(' in bookmarks') or + search_str.endswith(' in saved') or + search_str.endswith(' in saves') or + search_str.endswith(' bookmark')): + possible_endings = ( + ' in my bookmarks' + ' in my saved posts' + ' in my saved items' + ' in my saved' + ' in my saves' + ' in saved posts' + ' in saved items' + ' in saved' + ' in saves' + ' in bookmarks' + ' bookmark' + ) + for poss_ending in possible_endings: + if search_str.endswith(poss_ending): + search_str = search_str.replace(poss_ending, '') + break + # bookmark search + nickname = get_nickname_from_actor(actor_str) + if not nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return + search_str = search_str.replace('-', '', 1).strip() + timezone = None + if self.server.account_timezone.get(nickname): + timezone = \ + self.server.account_timezone.get(nickname) + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True + bookmarks_str = \ + html_history_search(self.server.translate, + base_dir, + http_prefix, + nickname, + domain, + search_str, + max_posts_in_feed, + page_number, + self.server.project_version, + self.server.recent_posts_cache, + self.server.max_recent_posts, + curr_session, + self.server.cached_webfingers, + self.server.person_cache, + port, + 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, 'bookmarks', + self.server.system_language, + self.server.max_like_count, + self.server.signing_priv_key_pem, + self.server.cw_lists, + self.server.lists_enabled, + timezone, bold_reading, + self.server.dogwhistles, + self.server.access_keys, + self.server.min_images_for_accounts, + self.server.buy_sites, + self.server.auto_cw_cache) + if bookmarks_str: + msg = bookmarks_str.encode('utf-8') + msglen = len(msg) + login_headers(self, 'text/html', + msglen, calling_domain) + write2(self, msg) + self.server.postreq_busy = False + return + elif ('@' in search_str or + ('://' in search_str and + has_users_path(search_str))): + remote_only = False + if search_str.endswith(';remote'): + search_str = search_str.replace(';remote', '') + remote_only = True + if search_str.endswith(':') or \ + search_str.endswith(';') or \ + search_str.endswith('.'): + actor_str = \ + get_instance_url(calling_domain, http_prefix, + domain_full, onion_domain, + i2p_domain) + \ + users_path + redirect_headers(self, actor_str + '/search', + cookie, calling_domain) + self.server.postreq_busy = False + return + # profile search + nickname = get_nickname_from_actor(actor_str) + if not nickname: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return + profile_path_str = path.replace('/searchhandle', '') + + # are we already following or followed by the searched + # for handle? + search_nickname = get_nickname_from_actor(search_str) + search_domain, search_port = \ + get_domain_from_actor(search_str) + search_follower = \ + is_follower_of_person(base_dir, nickname, domain, + search_nickname, search_domain) + search_following = \ + is_following_actor(base_dir, nickname, domain, search_str) + if not remote_only and (search_follower or search_following): + # get the actor + if not has_users_path(search_str): + if not search_nickname or not search_domain: + self.send_response(400) + self.end_headers() + self.server.postreq_busy = False + return + search_domain_full = \ + get_full_domain(search_domain, search_port) + actor = \ + local_actor_url(http_prefix, search_nickname, + search_domain_full) + else: + actor = search_str + + # establish the session + curr_proxy_type = proxy_type + if '.onion/' in actor: + curr_proxy_type = 'tor' + curr_session = self.server.session_onion + elif '.i2p/' in actor: + curr_proxy_type = 'i2p' + curr_session = self.server.session_i2p + + curr_session = \ + establish_session("handle search", + curr_session, + curr_proxy_type, + self.server) + if not curr_session: + self.server.postreq_busy = False + return + + # get the avatar url for the actor + avatar_url = \ + get_avatar_image_url(curr_session, + base_dir, http_prefix, + actor, + self.server.person_cache, + None, True, + self.server.signing_priv_key_pem) + profile_path_str += \ + '?options=' + actor + ';1;' + avatar_url + + show_person_options(self, calling_domain, profile_path_str, + base_dir, + domain, domain_full, + getreq_start_time, + cookie, debug, authorized, + curr_session) + return + else: + show_published_date_only = \ + self.server.show_published_date_only + allow_local_network_access = \ + self.server.allow_local_network_access + + access_keys = self.server.access_keys + if self.server.key_shortcuts.get(nickname): + access_keys = self.server.key_shortcuts[nickname] + + signing_priv_key_pem = \ + self.server.signing_priv_key_pem + twitter_replacement_domain = \ + self.server.twitter_replacement_domain + peertube_instances = \ + self.server.peertube_instances + yt_replace_domain = \ + self.server.yt_replace_domain + cached_webfingers = \ + self.server.cached_webfingers + recent_posts_cache = \ + self.server.recent_posts_cache + timezone = None + if self.server.account_timezone.get(nickname): + timezone = \ + self.server.account_timezone.get(nickname) + + profile_handle = remove_eol(search_str).strip() + + # establish the session + curr_proxy_type = proxy_type + if '.onion/' in profile_handle or \ + profile_handle.endswith('.onion'): + curr_proxy_type = 'tor' + curr_session = self.server.session_onion + elif ('.i2p/' in profile_handle or + profile_handle.endswith('.i2p')): + curr_proxy_type = 'i2p' + curr_session = self.server.session_i2p + + curr_session = \ + establish_session("handle search", + curr_session, + curr_proxy_type, + self.server) + if not curr_session: + self.server.postreq_busy = False + return + + bold_reading = False + if self.server.bold_reading.get(nickname): + bold_reading = True + + min_images_for_accounts = \ + self.server.min_images_for_accounts + max_shares_on_profile = \ + self.server.max_shares_on_profile + profile_str = \ + html_profile_after_search(authorized, + recent_posts_cache, + self.server.max_recent_posts, + self.server.translate, + base_dir, + profile_path_str, + http_prefix, + nickname, + domain, + port, + profile_handle, + curr_session, + cached_webfingers, + self.server.person_cache, + self.server.debug, + self.server.project_version, + yt_replace_domain, + twitter_replacement_domain, + show_published_date_only, + self.server.default_timeline, + peertube_instances, + allow_local_network_access, + self.server.theme_name, + access_keys, + self.server.system_language, + self.server.max_like_count, + signing_priv_key_pem, + self.server.cw_lists, + self.server.lists_enabled, + timezone, + self.server.onion_domain, + self.server.i2p_domain, + bold_reading, + self.server.dogwhistles, + min_images_for_accounts, + self.server.buy_sites, + max_shares_on_profile, + self.server.no_of_books, + self.server.auto_cw_cache) + if profile_str: + msg = profile_str.encode('utf-8') + msglen = len(msg) + login_headers(self, 'text/html', + msglen, calling_domain) + write2(self, msg) + self.server.postreq_busy = False + return + actor_str = \ + get_instance_url(calling_domain, + http_prefix, domain_full, + onion_domain, i2p_domain) + \ + users_path + redirect_headers(self, actor_str + '/search', + cookie, calling_domain) + self.server.postreq_busy = False + return + elif (search_str.startswith(':') or + search_str.endswith(' emoji')): + # eg. "cat emoji" + if search_str.endswith(' emoji'): + search_str = \ + search_str.replace(' emoji', '') + # emoji search + nickname = get_nickname_from_actor(actor_str) + emoji_str = \ + html_search_emoji(self.server.translate, + base_dir, search_str, + nickname, domain, + self.server.theme_name, + self.server.access_keys) + if emoji_str: + msg = emoji_str.encode('utf-8') + msglen = len(msg) + login_headers(self, 'text/html', + msglen, calling_domain) + write2(self, msg) + self.server.postreq_busy = False + return + elif search_str.startswith('.'): + # wanted items search + shared_items_federated_domains = \ + self.server.shared_items_federated_domains + nickname = get_nickname_from_actor(actor_str) + wanted_items_str = \ + html_search_shared_items(self.server.translate, + base_dir, + search_str[1:], page_number, + max_posts_in_feed, + http_prefix, + domain_full, + actor_str, calling_domain, + shared_items_federated_domains, + 'wanted', nickname, domain, + self.server.theme_name, + self.server.access_keys) + if wanted_items_str: + msg = wanted_items_str.encode('utf-8') + msglen = len(msg) + login_headers(self, 'text/html', + msglen, calling_domain) + write2(self, msg) + self.server.postreq_busy = False + return + else: + # shared items search + shared_items_federated_domains = \ + self.server.shared_items_federated_domains + nickname = get_nickname_from_actor(actor_str) + shared_items_str = \ + html_search_shared_items(self.server.translate, + base_dir, + search_str, page_number, + max_posts_in_feed, + http_prefix, + domain_full, + actor_str, calling_domain, + shared_items_federated_domains, + 'shares', nickname, domain, + self.server.theme_name, + self.server.access_keys) + if shared_items_str: + msg = shared_items_str.encode('utf-8') + msglen = len(msg) + login_headers(self, 'text/html', + msglen, calling_domain) + write2(self, msg) + self.server.postreq_busy = False + return + actor_str = \ + get_instance_url(calling_domain, http_prefix, + domain_full, onion_domain, i2p_domain) + \ + users_path + redirect_headers(self, actor_str + '/' + + self.server.default_timeline, + cookie, calling_domain) + self.server.postreq_busy = False