Add ability to set temp config in search query

Dark mode, country, interface language, and search language configs
can now be set in the search query by appending each option as a
url parameter.

Supported args are: 'dark', 'lang_search', 'lang_interface', and 'ctry'

Ex: /search?q=%s&dark=1&lang_search=lang_en...

These config settings persist across page navigation and switching
result type, but will be reset if the main search bar is used.

See #144
main
Ben Busby 2020-11-11 00:40:49 -05:00
parent a97e837b09
commit 72cbc342af
6 changed files with 57 additions and 3 deletions

View File

@ -53,7 +53,6 @@ class Filter:
self.fix_question_section() self.fix_question_section()
self.update_styling(soup) self.update_styling(soup)
for img in [_ for _ in soup.find_all('img') if 'src' in _.attrs]: for img in [_ for _ in soup.find_all('img') if 'src' in _.attrs]:
self.update_element_src(img, 'image/png') self.update_element_src(img, 'image/png')

View File

@ -325,3 +325,39 @@ class Config:
def __contains__(self, name): def __contains__(self, name):
return hasattr(self, name) return hasattr(self, name)
def is_safe_key(self, key) -> bool:
"""Establishes a group of config options that are safe to set
in the url.
Args:
key (str) -- the key to check against
Returns:
bool -- True/False depending on if the key is in the "safe"
array
"""
return key in [
'lang_search',
'lang_interface',
'ctry',
'dark'
]
def from_params(self, params) -> 'Config':
"""Modify user config with search parameters. This is primarily
used for specifying configuration on a search-by-search basis on
public instances.
Args:
params -- the url arguments (can be any deemed safe by is_safe())
Returns:
Config -- a modified config object
"""
for param_key in params.keys():
if not self.is_safe_key(param_key):
continue
self[param_key] = params.get(param_key)
return self

View File

@ -161,6 +161,9 @@ def search():
# Reset element counter # Reset element counter
app.user_elements[session['uuid']] = 0 app.user_elements[session['uuid']] = 0
# Update user config if specified in search args
g.user_config = g.user_config.from_params(g.request_params)
search_util = RoutingUtils(request, g.user_config, session, cookies_disabled=g.cookies_disabled) search_util = RoutingUtils(request, g.user_config, session, cookies_disabled=g.cookies_disabled)
query = search_util.new_search_query() query = search_util.new_search_query()

View File

@ -3,7 +3,7 @@
<div class="bz1lBb"> <div class="bz1lBb">
<form class="Pg70bf" id="search-form" method="POST"> <form class="Pg70bf" id="search-form" method="POST">
<a class="logo-link mobile-logo" <a class="logo-link mobile-logo"
href="" href="/"
style="display:flex; justify-content:center; align-items:center; color:#685e79; font-size:18px; "> style="display:flex; justify-content:center; align-items:center; color:#685e79; font-size:18px; ">
<span style="color: #685e79">Whoogle</span> <span style="color: #685e79">Whoogle</span>
</a> </a>
@ -24,7 +24,7 @@
{% else %} {% else %}
<header> <header>
<div class="logo-div"> <div class="logo-div">
<a class="logo-link" href=""> <a class="logo-link" href="/">
<span style="color: #685e79">Whoogle</span> <span style="color: #685e79">Whoogle</span>
</a> </a>
</div> </div>

View File

@ -81,4 +81,14 @@ class RoutingUtils:
return get_first_link(html_soup), 1 return get_first_link(html_soup), 1
else: else:
formatted_results = content_filter.clean(html_soup) formatted_results = content_filter.clean(html_soup)
# Append user config to all search links, if available
param_str = ''.join('&{}={}'.format(k, v)
for k, v in self.request_params.to_dict(flat=True).items()
if self.config.is_safe_key(k))
for link in formatted_results.find_all('a', href=True):
if 'search?' not in link['href'] or link['href'].index('search?') > 1:
continue
link['href'] += param_str
return formatted_results, content_filter.elements return formatted_results, content_filter.elements

View File

@ -48,6 +48,12 @@ def test_config(client):
for key in demo_config.keys(): for key in demo_config.keys():
assert config[key] == demo_config[key] assert config[key] == demo_config[key]
# Test setting config via search
custom_config = '&dark=1&lang_interface=lang_en'
rv = client.get('/search?q=test' + custom_config)
assert rv._status_code == 200
assert custom_config.replace('&', '&amp;') in str(rv.data)
def test_opensearch(client): def test_opensearch(client):
rv = client.get('/opensearch.xml') rv = client.get('/opensearch.xml')