__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 POST"

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 string_ends_with
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_redirect(self, calling_domain: str,
                             http_prefix: str,
                             domain_full: str,
                             onion_domain: str,
                             i2p_domain: str,
                             users_path: str,
                             default_timeline: str,
                             cookie: str) -> None:
    """Redirect to a different screen after search
    """
    actor_str = \
        get_instance_url(calling_domain, http_prefix,
                         domain_full, onion_domain, i2p_domain) + users_path
    redirect_headers(self, actor_str + '/' + default_timeline,
                     cookie, calling_domain, 303)
    self.server.postreq_busy = False


def _receive_search_hashtag(self, actor_str: str,
                            account_timezone: {},
                            bold_reading_nicknames: {},
                            domain: str, port: int,
                            recent_posts_cache: {},
                            max_recent_posts: int,
                            translate: {},
                            base_dir: str,
                            search_str: str,
                            max_posts_in_hashtag_feed: int,
                            curr_session,
                            cached_webfingers: {},
                            person_cache: {},
                            http_prefix: str,
                            project_version: str,
                            yt_replace_domain: str,
                            twitter_replacement_domain: str,
                            show_published_date_only: bool,
                            peertube_instances: [],
                            allow_local_network_access: bool,
                            theme_name: str,
                            system_language: str,
                            max_like_count: int,
                            signing_priv_key_pem: str,
                            cw_lists: {},
                            lists_enabled: {},
                            dogwhistles: {},
                            map_format: str,
                            access_keys: {},
                            min_images_for_accounts: {},
                            buy_sites: [],
                            auto_cw_cache: {},
                            calling_domain: str) -> bool:
    """Receive a search for a hashtag from the search screen
    """
    nickname = get_nickname_from_actor(actor_str)
    if not nickname:
        self.send_response(400)
        self.end_headers()
        self.server.postreq_busy = False
        return True

    # hashtag search
    timezone = None
    if account_timezone.get(nickname):
        timezone = account_timezone.get(nickname)
    bold_reading = False
    if bold_reading_nicknames.get(nickname):
        bold_reading = True
    hashtag_str = \
        html_hashtag_search(nickname, domain, port,
                            recent_posts_cache,
                            max_recent_posts,
                            translate,
                            base_dir,
                            search_str[1:], 1,
                            max_posts_in_hashtag_feed,
                            curr_session,
                            cached_webfingers,
                            person_cache,
                            http_prefix,
                            project_version,
                            yt_replace_domain,
                            twitter_replacement_domain,
                            show_published_date_only,
                            peertube_instances,
                            allow_local_network_access,
                            theme_name,
                            system_language,
                            max_like_count,
                            signing_priv_key_pem,
                            cw_lists,
                            lists_enabled,
                            timezone, bold_reading,
                            dogwhistles,
                            map_format,
                            access_keys,
                            'search',
                            min_images_for_accounts,
                            buy_sites,
                            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 True
    return False


def _receive_search_skills(self, search_str: str,
                           actor_str: str,
                           translate: {},
                           base_dir: str,
                           instance_only_skills_search: bool,
                           domain: str,
                           theme_name: str, access_keys: {},
                           calling_domain: str) -> bool:
    """Receive a search for a skill from the search screen
    """
    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, translate,
                           base_dir, search_str,
                           instance_only_skills_search,
                           64, nickname, domain,
                           theme_name, 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 True
    return False


def _receive_search_my_posts(self, search_str: str,
                             actor_str: str,
                             account_timezone: {},
                             bold_reading_nicknames: {},
                             translate: {},
                             base_dir: str,
                             http_prefix: str,
                             domain: str,
                             max_posts_in_feed: int,
                             page_number: int,
                             project_version: str,
                             recent_posts_cache: {},
                             max_recent_posts: int,
                             curr_session,
                             cached_webfingers: {},
                             person_cache: {},
                             port: int,
                             yt_replace_domain: str,
                             twitter_replacement_domain: str,
                             show_published_date_only: bool,
                             peertube_instances: [],
                             allow_local_network_access: bool,
                             theme_name: str,
                             system_language: str,
                             max_like_count: int,
                             signing_priv_key_pem: str,
                             cw_lists: {},
                             lists_enabled: {},
                             dogwhistles: {},
                             access_keys: {},
                             min_images_for_accounts: {},
                             buy_sites: [],
                             auto_cw_cache: {},
                             calling_domain: str) -> bool:
    """Receive a search for your own posts from the search screen
    """
    # your post history search
    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
    nickname = get_nickname_from_actor(actor_str)
    if not nickname:
        self.send_response(400)
        self.end_headers()
        self.server.postreq_busy = False
        return True
    search_str = search_str.replace("'", '', 1).strip()
    timezone = None
    if account_timezone.get(nickname):
        timezone = account_timezone.get(nickname)
    bold_reading = False
    if bold_reading_nicknames.get(nickname):
        bold_reading = True
    history_str = \
        html_history_search(translate,
                            base_dir,
                            http_prefix,
                            nickname,
                            domain,
                            search_str,
                            max_posts_in_feed,
                            page_number,
                            project_version,
                            recent_posts_cache,
                            max_recent_posts,
                            curr_session,
                            cached_webfingers,
                            person_cache,
                            port,
                            yt_replace_domain,
                            twitter_replacement_domain,
                            show_published_date_only,
                            peertube_instances,
                            allow_local_network_access,
                            theme_name, 'outbox',
                            system_language,
                            max_like_count,
                            signing_priv_key_pem,
                            cw_lists,
                            lists_enabled,
                            timezone, bold_reading,
                            dogwhistles,
                            access_keys,
                            min_images_for_accounts,
                            buy_sites,
                            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 True
    return False


def _receive_search_bookmarks(self, search_str: str,
                              actor_str: str,
                              account_timezone: {},
                              bold_reading_nicknames: {},
                              translate: {},
                              base_dir: str,
                              http_prefix: str,
                              domain: str,
                              max_posts_in_feed: int,
                              page_number: int,
                              project_version: str,
                              recent_posts_cache: {},
                              max_recent_posts: int,
                              curr_session,
                              cached_webfingers: {},
                              person_cache: {},
                              port: int,
                              yt_replace_domain: str,
                              twitter_replacement_domain: str,
                              show_published_date_only: bool,
                              peertube_instances: [],
                              allow_local_network_access: bool,
                              theme_name: str,
                              system_language: str,
                              max_like_count: int,
                              signing_priv_key_pem: str,
                              cw_lists: {},
                              lists_enabled: {},
                              dogwhistles: {},
                              access_keys: {},
                              min_images_for_accounts: {},
                              buy_sites: [],
                              auto_cw_cache: {},
                              calling_domain: str) -> bool:
    """Receive a search for bookmarked posts from the search screen
    """
    # bookmark search
    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
    nickname = get_nickname_from_actor(actor_str)
    if not nickname:
        self.send_response(400)
        self.end_headers()
        self.server.postreq_busy = False
        return True
    search_str = search_str.replace('-', '', 1).strip()
    timezone = None
    if account_timezone.get(nickname):
        timezone = account_timezone.get(nickname)
    bold_reading = False
    if bold_reading_nicknames.get(nickname):
        bold_reading = True
    bookmarks_str = \
        html_history_search(translate,
                            base_dir,
                            http_prefix,
                            nickname,
                            domain,
                            search_str,
                            max_posts_in_feed,
                            page_number,
                            project_version,
                            recent_posts_cache,
                            max_recent_posts,
                            curr_session,
                            cached_webfingers,
                            person_cache,
                            port,
                            yt_replace_domain,
                            twitter_replacement_domain,
                            show_published_date_only,
                            peertube_instances,
                            allow_local_network_access,
                            theme_name, 'bookmarks',
                            system_language,
                            max_like_count,
                            signing_priv_key_pem,
                            cw_lists,
                            lists_enabled,
                            timezone, bold_reading,
                            dogwhistles,
                            access_keys,
                            min_images_for_accounts,
                            buy_sites,
                            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 True
    return False


def _receive_search_handle(self, search_str: str,
                           calling_domain: str, http_prefix: str,
                           domain_full: str, onion_domain: str,
                           i2p_domain: str, users_path: str,
                           cookie: str, path: str, base_dir: str,
                           domain: str, proxy_type: str,
                           person_cache: {}, signing_priv_key_pem: str,
                           getreq_start_time, debug: bool,
                           authorized: bool, key_shortcuts: {},
                           account_timezone: {},
                           bold_reading_nicknames: {},
                           recent_posts_cache: {},
                           max_recent_posts: int,
                           translate: {}, port: int,
                           cached_webfingers: {},
                           project_version: str,
                           yt_replace_domain: str,
                           twitter_replacement_domain: str,
                           show_published_date_only: bool,
                           default_timeline: str,
                           peertube_instances: [],
                           allow_local_network_access: bool,
                           theme_name: str,
                           system_language: str,
                           max_like_count: int,
                           cw_lists: {},
                           lists_enabled: {},
                           dogwhistles: {},
                           min_images_for_accounts: {},
                           buy_sites: [],
                           max_shares_on_profile: int,
                           no_of_books: int,
                           auto_cw_cache: {},
                           actor_str: str,
                           curr_session) -> bool:
    """Receive a search for a fediverse handle or url from the search screen
    """
    remote_only = False
    if search_str.endswith(';remote'):
        search_str = search_str.replace(';remote', '')
        remote_only = True
    if string_ends_with(search_str, (':', ';', '.')):
        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, 303)
        self.server.postreq_busy = False
        return True
    # 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 True
    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 True
            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 True

        # get the avatar url for the actor
        avatar_url = \
            get_avatar_image_url(curr_session,
                                 base_dir, http_prefix,
                                 actor, person_cache,
                                 None, True,
                                 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 True
    else:
        if key_shortcuts.get(nickname):
            access_keys = key_shortcuts[nickname]

        timezone = None
        if account_timezone.get(nickname):
            timezone = 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 True

        bold_reading = False
        if bold_reading_nicknames.get(nickname):
            bold_reading = True

        profile_str = \
            html_profile_after_search(authorized,
                                      recent_posts_cache,
                                      max_recent_posts,
                                      translate,
                                      base_dir,
                                      profile_path_str,
                                      http_prefix,
                                      nickname,
                                      domain,
                                      port,
                                      profile_handle,
                                      curr_session,
                                      cached_webfingers,
                                      person_cache,
                                      debug,
                                      project_version,
                                      yt_replace_domain,
                                      twitter_replacement_domain,
                                      show_published_date_only,
                                      default_timeline,
                                      peertube_instances,
                                      allow_local_network_access,
                                      theme_name,
                                      access_keys,
                                      system_language,
                                      max_like_count,
                                      signing_priv_key_pem,
                                      cw_lists,
                                      lists_enabled,
                                      timezone,
                                      onion_domain,
                                      i2p_domain,
                                      bold_reading,
                                      dogwhistles,
                                      min_images_for_accounts,
                                      buy_sites,
                                      max_shares_on_profile,
                                      no_of_books,
                                      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 True
    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, 303)
    self.server.postreq_busy = False
    return True


def _receive_search_emoji(self, search_str: str,
                          actor_str: str, translate: {},
                          base_dir: str, domain: str,
                          theme_name: str, access_keys: {},
                          calling_domain: str) -> bool:
    """Receive a search for an emoji from the search screen
    """
    # 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(translate,
                          base_dir, search_str,
                          nickname, domain,
                          theme_name, 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 True
    return False


def _receive_search_wanted(self, search_str: str,
                           actor_str: str,
                           translate: {},
                           base_dir: str,
                           page_number: int,
                           max_posts_in_feed: int,
                           http_prefix: str,
                           domain_full: str,
                           calling_domain: str,
                           shared_items_federated_domains: [],
                           domain: str,
                           theme_name: str,
                           access_keys: {}) -> bool:
    """Receive a search for wanted items from the search screen
    """
    # wanted items search
    nickname = get_nickname_from_actor(actor_str)
    wanted_items_str = \
        html_search_shared_items(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,
                                 theme_name,
                                 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 True
    return False


def _receive_search_shared(self, search_str: str,
                           actor_str: str,
                           translate: {}, base_dir: str,
                           page_number: int,
                           max_posts_in_feed: int,
                           http_prefix: str, domain_full: str,
                           calling_domain: str,
                           shared_items_federated_domains: [],
                           domain: str,
                           theme_name: str, access_keys: {}) -> bool:
    """Receive a search for shared items from the search screen
    """
    # shared items search
    nickname = get_nickname_from_actor(actor_str)
    shared_items_str = \
        html_search_shared_items(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,
                                 theme_name, 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 True
    return 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,
                         max_posts_in_hashtag_feed: int,
                         max_posts_in_feed: int,
                         default_timeline: str,
                         account_timezone: {},
                         bold_reading_nicknames: {},
                         recent_posts_cache: {},
                         max_recent_posts: int,
                         translate: {},
                         cached_webfingers: {},
                         person_cache: {},
                         project_version: str,
                         yt_replace_domain: str,
                         twitter_replacement_domain: str,
                         show_published_date_only: bool,
                         peertube_instances: [],
                         allow_local_network_access: bool,
                         theme_name: str,
                         system_language: str,
                         max_like_count: int,
                         signing_priv_key_pem: str,
                         cw_lists: {},
                         lists_enabled: {},
                         dogwhistles: {},
                         map_format: str,
                         access_keys: {},
                         min_images_for_accounts: [],
                         buy_sites: [],
                         auto_cw_cache: {},
                         instance_only_skills_search: bool,
                         key_shortcuts: {},
                         max_shares_on_profile: int,
                         no_of_books: int,
                         shared_items_federated_domains: []) -> 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 + '/' +
                         default_timeline, cookie, calling_domain, 303)
        self.server.postreq_busy = False
        return
    if 'searchtext=' not in search_params:
        _receive_search_redirect(self, calling_domain,
                                 http_prefix, domain_full,
                                 onion_domain, i2p_domain,
                                 users_path, default_timeline,
                                 cookie)
        return

    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 + ':'

    my_posts_endings = (
        ' history', ' in sent', ' in outbox', ' in outgoing',
        ' in sent items', ' in sent posts', ' in outgoing posts',
        ' in my history', ' in my outbox', ' in my posts')
    bookmark_endings = (
        ' in my saved items', ' in my saved posts',
        ' in my bookmarks', ' in my saved', ' in my saves',
        ' in saved posts', ' in saved items', ' in bookmarks',
        ' in saved', ' in saves', ' bookmark')

    if search_str.startswith('#'):
        if _receive_search_hashtag(self, actor_str,
                                   account_timezone,
                                   bold_reading_nicknames,
                                   domain, port,
                                   recent_posts_cache,
                                   max_recent_posts,
                                   translate,
                                   base_dir,
                                   search_str,
                                   max_posts_in_hashtag_feed,
                                   curr_session,
                                   cached_webfingers,
                                   person_cache,
                                   http_prefix,
                                   project_version,
                                   yt_replace_domain,
                                   twitter_replacement_domain,
                                   show_published_date_only,
                                   peertube_instances,
                                   allow_local_network_access,
                                   theme_name,
                                   system_language,
                                   max_like_count,
                                   signing_priv_key_pem,
                                   cw_lists,
                                   lists_enabled,
                                   dogwhistles,
                                   map_format,
                                   access_keys,
                                   min_images_for_accounts,
                                   buy_sites,
                                   auto_cw_cache,
                                   calling_domain):
            return
    elif (search_str.startswith('*') or
          search_str.endswith(' skill')):
        if _receive_search_skills(self, search_str,
                                  actor_str,
                                  translate,
                                  base_dir,
                                  instance_only_skills_search,
                                  domain,
                                  theme_name, access_keys,
                                  calling_domain):
            return
    elif (search_str.startswith("'") or
          string_ends_with(search_str, my_posts_endings)):
        if _receive_search_my_posts(self, search_str,
                                    actor_str,
                                    account_timezone,
                                    bold_reading_nicknames,
                                    translate,
                                    base_dir,
                                    http_prefix,
                                    domain,
                                    max_posts_in_feed,
                                    page_number,
                                    project_version,
                                    recent_posts_cache,
                                    max_recent_posts,
                                    curr_session,
                                    cached_webfingers,
                                    person_cache,
                                    port,
                                    yt_replace_domain,
                                    twitter_replacement_domain,
                                    show_published_date_only,
                                    peertube_instances,
                                    allow_local_network_access,
                                    theme_name,
                                    system_language,
                                    max_like_count,
                                    signing_priv_key_pem,
                                    cw_lists,
                                    lists_enabled,
                                    dogwhistles,
                                    access_keys,
                                    min_images_for_accounts,
                                    buy_sites,
                                    auto_cw_cache,
                                    calling_domain):
            return
    elif (search_str.startswith('-') or
          string_ends_with(search_str, bookmark_endings)):
        if _receive_search_bookmarks(self, search_str,
                                     actor_str,
                                     account_timezone,
                                     bold_reading_nicknames,
                                     translate,
                                     base_dir,
                                     http_prefix,
                                     domain,
                                     max_posts_in_feed,
                                     page_number,
                                     project_version,
                                     recent_posts_cache,
                                     max_recent_posts,
                                     curr_session,
                                     cached_webfingers,
                                     person_cache,
                                     port,
                                     yt_replace_domain,
                                     twitter_replacement_domain,
                                     show_published_date_only,
                                     peertube_instances,
                                     allow_local_network_access,
                                     theme_name,
                                     system_language,
                                     max_like_count,
                                     signing_priv_key_pem,
                                     cw_lists,
                                     lists_enabled,
                                     dogwhistles,
                                     access_keys,
                                     min_images_for_accounts,
                                     buy_sites,
                                     auto_cw_cache,
                                     calling_domain):
            return
    elif ('@' in search_str or
          ('://' in search_str and
           has_users_path(search_str))):
        if _receive_search_handle(self, search_str,
                                  calling_domain, http_prefix,
                                  domain_full, onion_domain,
                                  i2p_domain, users_path,
                                  cookie, path, base_dir,
                                  domain, proxy_type,
                                  person_cache, signing_priv_key_pem,
                                  getreq_start_time, debug,
                                  authorized, key_shortcuts,
                                  account_timezone,
                                  bold_reading_nicknames,
                                  recent_posts_cache,
                                  max_recent_posts,
                                  translate, port,
                                  cached_webfingers,
                                  project_version,
                                  yt_replace_domain,
                                  twitter_replacement_domain,
                                  show_published_date_only,
                                  default_timeline,
                                  peertube_instances,
                                  allow_local_network_access,
                                  theme_name,
                                  system_language,
                                  max_like_count,
                                  cw_lists,
                                  lists_enabled,
                                  dogwhistles,
                                  min_images_for_accounts,
                                  buy_sites,
                                  max_shares_on_profile,
                                  no_of_books,
                                  auto_cw_cache, actor_str,
                                  curr_session):
            return
    elif (search_str.startswith(':') or
          search_str.endswith(' emoji')):
        if _receive_search_emoji(self, search_str,
                                 actor_str, translate,
                                 base_dir, domain,
                                 theme_name, access_keys,
                                 calling_domain):
            return
    elif search_str.startswith('.'):
        if _receive_search_wanted(self, search_str,
                                  actor_str, translate,
                                  base_dir, page_number,
                                  max_posts_in_feed,
                                  http_prefix, domain_full,
                                  calling_domain,
                                  shared_items_federated_domains,
                                  domain, theme_name,
                                  access_keys):
            return
    else:
        if _receive_search_shared(self, search_str,
                                  actor_str,
                                  translate, base_dir,
                                  page_number,
                                  max_posts_in_feed,
                                  http_prefix, domain_full,
                                  calling_domain,
                                  shared_items_federated_domains,
                                  domain,
                                  theme_name, access_keys):
            return

    _receive_search_redirect(self, calling_domain,
                             http_prefix, domain_full,
                             onion_domain, i2p_domain,
                             users_path, default_timeline,
                             cookie)