diff --git a/app/routes.py b/app/routes.py index b949f651ba..bb15295989 100644 --- a/app/routes.py +++ b/app/routes.py @@ -15,8 +15,8 @@ from app.request import Request, TorError from app.utils.bangs import resolve_bang from app.utils.misc import read_config_bool, get_client_ip, get_request_url -from app.utils.results import add_ip_card -from app.utils.results import bold_search_terms +from app.utils.results import add_ip_card, bold_search_terms,\ + add_currency_card, check_currency from app.utils.search import * from app.utils.session import generate_user_key, valid_user_session from bs4 import BeautifulSoup as bsoup @@ -318,6 +318,12 @@ def search(): html_soup = bsoup(str(response), 'html.parser') response = add_ip_card(html_soup, get_client_ip(request)) + # Feature to display currency_card + conversion = check_currency(str(response)) + if conversion: + html_soup = bsoup(str(response), 'html.parser') + response = add_currency_card(html_soup, conversion) + return render_template( 'display.html', newest_version=newest_version, diff --git a/app/static/css/dark-theme.css b/app/static/css/dark-theme.css index 68b7cad10b..c30b1515b4 100644 --- a/app/static/css/dark-theme.css +++ b/app/static/css/dark-theme.css @@ -187,6 +187,10 @@ path { color: var(--whoogle-dark-text) !important; } -.ip-text-div, .update_available { +.ip-text-div, .update_available, .cb_label, .cb { color: var(--whoogle-dark-secondary-text) !important; } + +.cb:focus { + color: var(--whoogle-dark-contrast-text) !important; +} diff --git a/app/static/css/input.css b/app/static/css/input.css index 96cc10861f..2da2aa38d2 100644 --- a/app/static/css/input.css +++ b/app/static/css/input.css @@ -12,3 +12,30 @@ height: 40px; width: 50px; } +.ZINbbc.xpd.O9g5cc.uUPGi input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} + +.cb { + width: 40%; + overflow: hidden; + text-align: left; + line-height: 28px; + background: transparent; + border-radius: 6px; + border: 1px solid #5f6368; + font-size: 14px !important; + height: 36px; + padding: 0 0 0 12px; + margin: 10px 10px 10px 0; +} + +.conversion_box { + margin-top: 15px; +} + +.ZINbbc.xpd.O9g5cc.uUPGi input:focus-visible { + outline: 0; +} diff --git a/app/static/css/light-theme.css b/app/static/css/light-theme.css index de371574b4..bc179527ea 100644 --- a/app/static/css/light-theme.css +++ b/app/static/css/light-theme.css @@ -175,6 +175,10 @@ path { border-bottom: 0px; } -.ip-text-div, .update_available { +.ip-text-div, .update_available, .cb_label, .cb { color: var(--whoogle-secondary-text) !important; } + +.cb:focus { + color: var(--whoogle-text) !important; +} diff --git a/app/static/js/currency.js b/app/static/js/currency.js new file mode 100644 index 0000000000..b6695964ba --- /dev/null +++ b/app/static/js/currency.js @@ -0,0 +1,9 @@ +const convert = (n1, n2, conversionFactor) => { + // id's for currency input boxes + let id1 = "cb" + n1; + let id2 = "cb" + n2; + // getting the value of the input box that just got filled + let inputBox = document.getElementById(id1).value; + // updating the other input box after conversion + document.getElementById(id2).value = ((inputBox * conversionFactor).toFixed(2)); +} diff --git a/app/templates/display.html b/app/templates/display.html index 3cd76b6595..fe39df7802 100644 --- a/app/templates/display.html +++ b/app/templates/display.html @@ -38,4 +38,5 @@ + diff --git a/app/utils/results.py b/app/utils/results.py index 0b445afb44..02757d777c 100644 --- a/app/utils/results.py +++ b/app/utils/results.py @@ -223,3 +223,107 @@ def add_ip_card(html_soup: BeautifulSoup, ip: str) -> BeautifulSoup: # Inserting the element ref_element.insert_before(ip_tag) return html_soup + + +def check_currency(response: str) -> dict: + """Check whether the results have currency conversion + + Args: + response: Search query Result + + Returns: + dict: Consists of currency names and values + + """ + soup = BeautifulSoup(response, 'html.parser') + currency_link = soup.find('a', {'href': 'https://g.co/gfd'}) + if currency_link: + while 'class' not in currency_link.attrs or \ + 'ZINbbc' not in currency_link.attrs['class']: + currency_link = currency_link.parent + currency_link = currency_link.find_all(class_='BNeawe') + currency1 = currency_link[0].text + currency2 = currency_link[1].text + currency1 = currency1.rstrip('=').split(' ', 1) + currency2 = currency2.split(' ', 1) + if currency2[0][-3] == ',': + currency1[0] = currency1[0].replace('.', '') + currency1[0] = currency1[0].replace(',', '.') + currency2[0] = currency2[0].replace('.', '') + currency2[0] = currency2[0].replace(',', '.') + else: + currency1[0] = currency1[0].replace(',', '') + currency2[0] = currency2[0].replace(',', '') + return {'currencyValue1': float(currency1[0]), + 'currencyLabel1': currency1[1], + 'currencyValue2': float(currency2[0]), + 'currencyLabel2': currency2[1] + } + return {} + + +def add_currency_card(soup: BeautifulSoup, + conversion_details: dict) -> BeautifulSoup: + """Adds the currency conversion boxes + to response of the search query + + Args: + soup: Parsed search result + conversion_details: Dictionary of currency + related information + + Returns: + BeautifulSoup + """ + # Element before which the code will be changed + # (This is the 'disclaimer' link) + element1 = soup.find('a', {'href': 'https://g.co/gfd'}) + + while 'class' not in element1.attrs or \ + 'nXE3Ob' not in element1.attrs['class']: + element1 = element1.parent + + # Creating the conversion factor + conversion_factor = (conversion_details['currencyValue1'] / + conversion_details['currencyValue2']) + + # Creating a new div for the input boxes + conversion_box = soup.new_tag('div') + conversion_box['class'] = 'conversion_box' + + # Currency to be converted from + input_box1 = soup.new_tag('input') + input_box1['id'] = 'cb1' + input_box1['type'] = 'number' + input_box1['class'] = 'cb' + input_box1['value'] = conversion_details['currencyValue1'] + input_box1['oninput'] = f'convert(1, 2, {1 / conversion_factor})' + + label_box1 = soup.new_tag('label') + label_box1['for'] = 'cb1' + label_box1['class'] = 'cb_label' + label_box1.append(conversion_details['currencyLabel1']) + + br = soup.new_tag('br') + + # Currency to be converted to + input_box2 = soup.new_tag('input') + input_box2['id'] = 'cb2' + input_box2['type'] = 'number' + input_box2['class'] = 'cb' + input_box2['value'] = conversion_details['currencyValue2'] + input_box2['oninput'] = f'convert(2, 1, {conversion_factor})' + + label_box2 = soup.new_tag('label') + label_box2['for'] = 'cb2' + label_box2['class'] = 'cb_label' + label_box2.append(conversion_details['currencyLabel2']) + + conversion_box.append(input_box1) + conversion_box.append(label_box1) + conversion_box.append(br) + conversion_box.append(input_box2) + conversion_box.append(label_box2) + + element1.insert_before(conversion_box) + return soup