From 219fc58401393744bdc3dbbffdc960625137fee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o?= Date: Fri, 30 Sep 2022 22:39:13 +0200 Subject: [PATCH] Fix handling of bangs (#851) Changed the implementation to work if the bang is at anyplace in the query. Added a check to not spend time looking for an operator if a "!" is not present in the query. No longer allowed to have the bang at the "!" char at the end, since this may cause some conflicts like the issue cited before, where the ! is after a word in the query, which is natural in most languages. --- app/utils/bangs.py | 54 ++++++++++++++++++++++++++++----------------- test/test_routes.py | 5 ----- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/app/utils/bangs.py b/app/utils/bangs.py index e0bfe24..603e54b 100644 --- a/app/utils/bangs.py +++ b/app/utils/bangs.py @@ -53,24 +53,38 @@ def resolve_bang(query: str, bangs_dict: dict) -> str: wasn't a match or didn't contain a bang operator """ - # Ensure bang search is case insensitive - query = query.lower() - split_query = query.split(' ') - for operator in bangs_dict.keys(): - if operator not in split_query \ - and operator[1:] + operator[0] not in split_query: - continue - - bang_query = query.replace( - operator if operator in split_query else operator[1:] + - operator[0], '' - ).strip() - - bang_url = bangs_dict[operator]['url'] - - if bang_query: - return bang_url.replace('{}', bang_query, 1) - else: - parsed_url = urlparse.urlparse(bang_url) - return f'{parsed_url.scheme}://{parsed_url.netloc}' + + #if ! not in query simply return (speed up processing) + if '!' not in query: + return '' + + split_query = query.strip().split(' ') + + # look for operator in query if one is found, list operator should be of + # length 1, operator should not be case-sensitive here to remove it later + operator = [ + word + for word in split_query + if word.lower() in bangs_dict + ] + if len(operator) == 1: + # get operator + operator = operator[0] + + # removes operator from query + split_query.remove(operator) + + # rebuild the query string + bang_query = ' '.join(split_query).strip() + + # Check if operator is a key in bangs and get bang if exists + bang = bangs_dict.get(operator.lower(), None) + if bang: + bang_url = bang['url'] + + if bang_query: + return bang_url.replace('{}', bang_query, 1) + else: + parsed_url = urlparse.urlparse(bang_url) + return f'{parsed_url.scheme}://{parsed_url.netloc}' return '' diff --git a/test/test_routes.py b/test/test_routes.py index 94fcfef..8cb79fa 100644 --- a/test/test_routes.py +++ b/test/test_routes.py @@ -37,11 +37,6 @@ def test_ddg_bang(client): assert rv._status_code == 302 assert rv.headers.get('Location').startswith('https://www.reddit.com') - # Move '!' to end of the bang - rv = client.get(f'/{Endpoint.search}?q=gitlab%20w!') - assert rv._status_code == 302 - assert rv.headers.get('Location').startswith('https://en.wikipedia.org') - # Ensure bang is case insensitive rv = client.get(f'/{Endpoint.search}?q=!GH%20whoogle') assert rv._status_code == 302