Repository: benbusby/whoogle-search
File: app/utils/results.py (Python)

Code before:

        # 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 and currency_link.text.lower() == 'disclaimer':
        for i in range(4):
            currency_link = currency_link.parent
        currency1 = currency_link
        for i in range(5):
            currency1 = currency1.parent
        for i in range(2):
            currency1 = currency1.previous_sibling
        currency1 = currency1.string
        currency2 = currency_link.previous_sibling.string
        currency1 = currency1.text.rstrip('=').split(' ', 1)
        currency2 = currency2.text.split(' ', 1)
        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
    """

Review comment (suggestion):
I think looking for a specific class name would actually be a better approach -- if we switch to traversing up N number of parents, and the layout for the conversion card returned by Google gets changed at some point, it'll be more effort to determine how deep the child element is nested. As long as we keep it to one class name, it should be easy enough to maintain in the future. 

Something like (pseudocode, not tested):

```py
while currency_link.parent and 'ZINbbc' not in currency_link.attrs['class']:
    currency_link = currency_link.parent
```

Code after:

        # 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