diff --git a/app/routes.py b/app/routes.py index eb490e1..2c0aa1a 100644 --- a/app/routes.py +++ b/app/routes.py @@ -19,7 +19,8 @@ from app.utils.misc import get_proxy_host_url from app.filter import Filter from app.utils.misc import read_config_bool, get_client_ip, get_request_url, \ check_for_update -from app.utils.results import add_ip_card, bold_search_terms,\ +from app.utils.widgets import * +from app.utils.results import bold_search_terms,\ add_currency_card, check_currency, get_tabs_content from app.utils.search import Search, needs_https, has_captcha from app.utils.session import valid_user_session @@ -340,10 +341,15 @@ def search(): response = bold_search_terms(response, query) - # Feature to display IP address - if search_util.check_kw_ip(): + # check for widgets and add if requested + if search_util.widget != '': html_soup = bsoup(str(response), 'html.parser') - response = add_ip_card(html_soup, get_client_ip(request)) + match search_util.widget: + case 'ip': + response = add_ip_card(html_soup, get_client_ip(request)) + case 'calculator': + if not 'nojs' in request.args: + response = add_calculator_card(html_soup) # Update tabs content tabs = get_tabs_content(app.config['HEADER_TABS'], @@ -353,6 +359,8 @@ def search(): translation) # Feature to display currency_card + # Since this is determined by more than just the + # query is it not defined as a standard widget conversion = check_currency(str(response)) if conversion: html_soup = bsoup(str(response), 'html.parser') @@ -395,7 +403,7 @@ def search(): query=urlparse.unquote(query), search_type=search_util.search_type, mobile=g.user_request.mobile, - tabs=tabs)) + tabs=tabs)).replace(" ", "") @app.route(f'/{Endpoint.config}', methods=['GET', 'POST', 'PUT']) diff --git a/app/static/js/keyboard.js b/app/static/js/keyboard.js index 14df9d5..3ee90fe 100644 --- a/app/static/js/keyboard.js +++ b/app/static/js/keyboard.js @@ -52,6 +52,10 @@ } function focusSearch () { + if (window.usingCalculator) { + // if this function exists, it means the calculator widget has been displayed + if (usingCalculator()) return; + } activeIdx = -1; searchBar.focus(); } diff --git a/app/static/widgets/calculator.html b/app/static/widgets/calculator.html new file mode 100644 index 0000000..f0fbd36 --- /dev/null +++ b/app/static/widgets/calculator.html @@ -0,0 +1,260 @@ + + + +

+
+

0

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ diff --git a/app/utils/results.py b/app/utils/results.py index 4ae8c9f..1453859 100644 --- a/app/utils/results.py +++ b/app/utils/results.py @@ -281,44 +281,6 @@ def append_anon_view(result: BeautifulSoup, config: Config) -> None: av_link['class'] = 'anon-view' result.append(av_link) - -def add_ip_card(html_soup: BeautifulSoup, ip: str) -> BeautifulSoup: - """Adds the client's IP address to the search results - if query contains keywords - - Args: - html_soup: The parsed search result containing the keywords - ip: ip address of the client - - Returns: - BeautifulSoup - - """ - main_div = html_soup.select_one('#main') - if main_div: - # HTML IP card tag - ip_tag = html_soup.new_tag('div') - ip_tag['class'] = 'ZINbbc xpd O9g5cc uUPGi' - - # For IP Address html tag - ip_address = html_soup.new_tag('div') - ip_address['class'] = 'kCrYT ip-address-div' - ip_address.string = ip - - # Text below the IP address - ip_text = html_soup.new_tag('div') - ip_text.string = 'Your public IP address' - ip_text['class'] = 'kCrYT ip-text-div' - - # Adding all the above html tags to the IP card - ip_tag.append(ip_address) - ip_tag.append(ip_text) - - # Insert the element at the top of the result list - main_div.insert_before(ip_tag) - return html_soup - - def check_currency(response: str) -> dict: """Check whether the results have currency conversion diff --git a/app/utils/search.py b/app/utils/search.py index ecdadba..8de53f8 100644 --- a/app/utils/search.py +++ b/app/utils/search.py @@ -64,6 +64,7 @@ class Search: self.config = config self.session_key = session_key self.query = '' + self.widget = '' self.cookies_disabled = cookies_disabled self.search_type = self.request_params.get( 'tbm') if 'tbm' in self.request_params else '' @@ -104,6 +105,11 @@ class Search: # Strip leading '! ' for "feeling lucky" queries self.feeling_lucky = q.startswith('! ') self.query = q[2:] if self.feeling_lucky else q + # Check for possible widgets + self.widget = "ip" if re.search("([^a-z0-9]|^)my *[^a-z0-9] *(ip|internet protocol)" + + "($|( *[^a-z0-9] *(((addres|address|adres|" + + "adress)|a)? *$)))", self.query.lower()) else self.widget + self.widget = 'calculator' if re.search("calculator|calc|calclator|math", self.query.lower()) else self.widget return self.query def generate_response(self) -> str: @@ -171,13 +177,3 @@ class Search: return str(formatted_results) - def check_kw_ip(self) -> re.Match: - """Checks for keywords related to 'my ip' in the query - - Returns: - bool - - """ - return re.search("([^a-z0-9]|^)my *[^a-z0-9] *(ip|internet protocol)" + - "($|( *[^a-z0-9] *(((addres|address|adres|" + - "adress)|a)? *$)))", self.query.lower()) diff --git a/app/utils/widgets.py b/app/utils/widgets.py new file mode 100644 index 0000000..eef06fc --- /dev/null +++ b/app/utils/widgets.py @@ -0,0 +1,65 @@ +from bs4 import BeautifulSoup + +def add_ip_card(html_soup: BeautifulSoup, ip: str) -> BeautifulSoup: + """Adds the client's IP address to the search results + if query contains keywords + + Args: + html_soup: The parsed search result containing the keywords + ip: ip address of the client + + Returns: + BeautifulSoup + + """ + main_div = html_soup.select_one('#main') + if main_div: + # HTML IP card tag + ip_tag = html_soup.new_tag('div') + ip_tag['class'] = 'ZINbbc xpd O9g5cc uUPGi' + + # For IP Address html tag + ip_address = html_soup.new_tag('div') + ip_address['class'] = 'kCrYT ip-address-div' + ip_address.string = ip + + # Text below the IP address + ip_text = html_soup.new_tag('div') + ip_text.string = 'Your public IP address' + ip_text['class'] = 'kCrYT ip-text-div' + + # Adding all the above html tags to the IP card + ip_tag.append(ip_address) + ip_tag.append(ip_text) + + # Insert the element at the top of the result list + main_div.insert_before(ip_tag) + return html_soup + +def add_calculator_card(html_soup: BeautifulSoup) -> BeautifulSoup: + """Adds the a calculator widget to the search results + if query contains keywords + + Args: + html_soup: The parsed search result containing the keywords + + Returns: + BeautifulSoup + """ + main_div = html_soup.select_one('#main') + if main_div: + widget_file = open('app/static/widgets/calculator.html') + widget_tag = html_soup.new_tag('div') + widget_tag['class'] = 'ZINbbc xpd O9g5cc uUPGi' + widget_tag['id'] = 'calculator-wrapper' + calculator_text = html_soup.new_tag('div') + calculator_text['class'] = 'kCrYT ip-address-div' + calculator_text.string = 'Calculator' + calculator_widget = html_soup.new_tag('div') + calculator_widget.append(BeautifulSoup(widget_file, 'html.parser')); + calculator_widget['class'] = 'kCrYT ip-text-div' + widget_tag.append(calculator_text) + widget_tag.append(calculator_widget) + main_div.insert_before(widget_tag) + widget_file.close() + return html_soup