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.
This commit is contained in:
João 2022-09-30 22:39:13 +02:00 committed by GitHub
parent 74503d542e
commit 219fc58401
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 22 deletions

View File

@ -53,24 +53,38 @@ def resolve_bang(query: str, bangs_dict: dict) -> str:
wasn't a match or didn't contain a bang operator 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( #if ! not in query simply return (speed up processing)
operator if operator in split_query else operator[1:] + if '!' not in query:
operator[0], '' return ''
).strip()
bang_url = bangs_dict[operator]['url'] split_query = query.strip().split(' ')
if bang_query: # look for operator in query if one is found, list operator should be of
return bang_url.replace('{}', bang_query, 1) # length 1, operator should not be case-sensitive here to remove it later
else: operator = [
parsed_url = urlparse.urlparse(bang_url) word
return f'{parsed_url.scheme}://{parsed_url.netloc}' 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 '' return ''

View File

@ -37,11 +37,6 @@ def test_ddg_bang(client):
assert rv._status_code == 302 assert rv._status_code == 302
assert rv.headers.get('Location').startswith('https://www.reddit.com') 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 # Ensure bang is case insensitive
rv = client.get(f'/{Endpoint.search}?q=!GH%20whoogle') rv = client.get(f'/{Endpoint.search}?q=!GH%20whoogle')
assert rv._status_code == 302 assert rv._status_code == 302