Encode config params in URL (#842)
Adds support for encoding (and optionally encrypting) user config values as a single string that can be passed to any endpoint with the "preferences" url param. Co-authored-by: Ben Busby <contact@benbusby.com>main
parent
11275a7796
commit
74503d542e
|
@ -14,7 +14,7 @@ RUN pip install --prefix /install --no-warn-script-location --no-cache-dir -r re
|
|||
|
||||
FROM python:3.11.0a5-alpine
|
||||
|
||||
RUN apk add --update --no-cache tor curl openrc
|
||||
RUN apk add --update --no-cache tor curl openrc libstdc++
|
||||
# libcurl4-openssl-dev
|
||||
|
||||
RUN apk -U upgrade
|
||||
|
|
36
README.md
36
README.md
|
@ -389,23 +389,25 @@ There are a few optional environment variables available for customizing a Whoog
|
|||
### Config Environment Variables
|
||||
These environment variables allow setting default config values, but can be overwritten manually by using the home page config menu. These allow a shortcut for destroying/rebuilding an instance to the same config state every time.
|
||||
|
||||
| Variable | Description |
|
||||
| ------------------------------ | --------------------------------------------------------------- |
|
||||
| WHOOGLE_CONFIG_DISABLE | Hide config from UI and disallow changes to config by client |
|
||||
| WHOOGLE_CONFIG_COUNTRY | Filter results by hosting country |
|
||||
| WHOOGLE_CONFIG_LANGUAGE | Set interface language |
|
||||
| WHOOGLE_CONFIG_SEARCH_LANGUAGE | Set search result language |
|
||||
| WHOOGLE_CONFIG_BLOCK | Block websites from search results (use comma-separated list) |
|
||||
| WHOOGLE_CONFIG_THEME | Set theme mode (light, dark, or system) |
|
||||
| WHOOGLE_CONFIG_SAFE | Enable safe searches |
|
||||
| WHOOGLE_CONFIG_ALTS | Use social media site alternatives (nitter, invidious, etc) |
|
||||
| WHOOGLE_CONFIG_NEAR | Restrict results to only those near a particular city |
|
||||
| WHOOGLE_CONFIG_TOR | Use Tor routing (if available) |
|
||||
| WHOOGLE_CONFIG_NEW_TAB | Always open results in new tab |
|
||||
| WHOOGLE_CONFIG_VIEW_IMAGE | Enable View Image option |
|
||||
| WHOOGLE_CONFIG_GET_ONLY | Search using GET requests only |
|
||||
| WHOOGLE_CONFIG_URL | The root url of the instance (`https://<your url>/`) |
|
||||
| WHOOGLE_CONFIG_STYLE | The custom CSS to use for styling (should be single line) |
|
||||
| Variable | Description |
|
||||
| ------------------------------------ | --------------------------------------------------------------- |
|
||||
| WHOOGLE_CONFIG_DISABLE | Hide config from UI and disallow changes to config by client |
|
||||
| WHOOGLE_CONFIG_COUNTRY | Filter results by hosting country |
|
||||
| WHOOGLE_CONFIG_LANGUAGE | Set interface language |
|
||||
| WHOOGLE_CONFIG_SEARCH_LANGUAGE | Set search result language |
|
||||
| WHOOGLE_CONFIG_BLOCK | Block websites from search results (use comma-separated list) |
|
||||
| WHOOGLE_CONFIG_THEME | Set theme mode (light, dark, or system) |
|
||||
| WHOOGLE_CONFIG_SAFE | Enable safe searches |
|
||||
| WHOOGLE_CONFIG_ALTS | Use social media site alternatives (nitter, invidious, etc) |
|
||||
| WHOOGLE_CONFIG_NEAR | Restrict results to only those near a particular city |
|
||||
| WHOOGLE_CONFIG_TOR | Use Tor routing (if available) |
|
||||
| WHOOGLE_CONFIG_NEW_TAB | Always open results in new tab |
|
||||
| WHOOGLE_CONFIG_VIEW_IMAGE | Enable View Image option |
|
||||
| WHOOGLE_CONFIG_GET_ONLY | Search using GET requests only |
|
||||
| WHOOGLE_CONFIG_URL | The root url of the instance (`https://<your url>/`) |
|
||||
| WHOOGLE_CONFIG_STYLE | The custom CSS to use for styling (should be single line) |
|
||||
| WHOOGLE_CONFIG_PREFERENCES_ENCRYPTED | Encrypt preferences token, requires preferences key |
|
||||
| WHOOGLE_CONFIG_PREFERENCES_KEY | Key to encrypt preferences in URL (REQUIRED to show url) |
|
||||
|
||||
## Usage
|
||||
Same as most search engines, with the exception of filtering by time range.
|
||||
|
|
10
app.json
10
app.json
|
@ -174,6 +174,16 @@
|
|||
"description": "[CONFIG] Custom CSS styling (paste in CSS or leave blank)",
|
||||
"value": ":root { /* LIGHT THEME COLORS */ --whoogle-background: #d8dee9; --whoogle-accent: #2e3440; --whoogle-text: #3B4252; --whoogle-contrast-text: #eceff4; --whoogle-secondary-text: #70757a; --whoogle-result-bg: #fff; --whoogle-result-title: #4c566a; --whoogle-result-url: #81a1c1; --whoogle-result-visited: #a3be8c; /* DARK THEME COLORS */ --whoogle-dark-background: #222; --whoogle-dark-accent: #685e79; --whoogle-dark-text: #fff; --whoogle-dark-contrast-text: #000; --whoogle-dark-secondary-text: #bbb; --whoogle-dark-result-bg: #000; --whoogle-dark-result-title: #1967d2; --whoogle-dark-result-url: #4b11a8; --whoogle-dark-result-visited: #bbbbff; }",
|
||||
"required": false
|
||||
},
|
||||
"WHOOGLE_CONFIG_PREFERENCES_ENCRYPTED": {
|
||||
"description": "[CONFIG] Encrypt preferences token, requires WHOOGLE_CONFIG_PREFERENCES_KEY to be set",
|
||||
"value": "",
|
||||
"required": false
|
||||
},
|
||||
"WHOOGLE_CONFIG_PREFERENCES_KEY": {
|
||||
"description": "[CONFIG] Key to encrypt preferences",
|
||||
"value": "NEEDS_TO_BE_MODIFIED",
|
||||
"required": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
from inspect import Attribute
|
||||
from app.utils.misc import read_config_bool
|
||||
from flask import current_app
|
||||
import os
|
||||
import re
|
||||
from base64 import urlsafe_b64encode, urlsafe_b64decode
|
||||
import pickle
|
||||
from cryptography.fernet import Fernet
|
||||
import hashlib
|
||||
import brotli
|
||||
|
||||
|
||||
class Config:
|
||||
|
@ -29,6 +35,9 @@ class Config:
|
|||
self.view_image = read_config_bool('WHOOGLE_CONFIG_VIEW_IMAGE')
|
||||
self.get_only = read_config_bool('WHOOGLE_CONFIG_GET_ONLY')
|
||||
self.anon_view = read_config_bool('WHOOGLE_CONFIG_ANON_VIEW')
|
||||
self.preferences_encrypted = read_config_bool('WHOOGLE_CONFIG_PREFERENCES_ENCRYPTED')
|
||||
self.preferences_key = os.getenv('WHOOGLE_CONFIG_PREFERENCES_KEY', '')
|
||||
|
||||
self.accept_language = False
|
||||
|
||||
self.safe_keys = [
|
||||
|
@ -42,7 +51,8 @@ class Config:
|
|||
'block',
|
||||
'safe',
|
||||
'nojs',
|
||||
'anon_view'
|
||||
'anon_view',
|
||||
'preferences_encrypted'
|
||||
]
|
||||
|
||||
# Skip setting custom config if there isn't one
|
||||
|
@ -71,6 +81,24 @@ class Config:
|
|||
if not name.startswith("__")
|
||||
and (type(attr) is bool or type(attr) is str)}
|
||||
|
||||
def get_attrs(self):
|
||||
return {name: attr for name, attr in self.__dict__.items()
|
||||
if not name.startswith("__")
|
||||
and (type(attr) is bool or type(attr) is str)}
|
||||
|
||||
@property
|
||||
def preferences(self) -> str:
|
||||
# if encryption key is not set will uncheck preferences encryption
|
||||
if self.preferences_encrypted:
|
||||
self.preferences_encrypted = bool(self.preferences_key)
|
||||
|
||||
# add a tag for visibility if preferences token startswith 'e' it means
|
||||
# the token is encrypted, 'u' means the token is unencrypted and can be
|
||||
# used by other whoogle instances
|
||||
encrypted_flag = "e" if self.preferences_encrypted else 'u'
|
||||
preferences_digest = self._encode_preferences()
|
||||
return f"{encrypted_flag}{preferences_digest}"
|
||||
|
||||
def is_safe_key(self, key) -> bool:
|
||||
"""Establishes a group of config options that are safe to set
|
||||
in the url.
|
||||
|
@ -109,6 +137,13 @@ class Config:
|
|||
Returns:
|
||||
Config -- a modified config object
|
||||
"""
|
||||
if 'preferences' in params:
|
||||
params_new = self._decode_preferences(params['preferences'])
|
||||
# if preferences leads to an empty dictionary it means preferences
|
||||
# parameter was not decrypted successfully
|
||||
if len(params_new):
|
||||
params = params_new
|
||||
|
||||
for param_key in params.keys():
|
||||
if not self.is_safe_key(param_key):
|
||||
continue
|
||||
|
@ -116,8 +151,9 @@ class Config:
|
|||
|
||||
if param_val == 'off':
|
||||
param_val = False
|
||||
elif param_val.isdigit():
|
||||
param_val = int(param_val)
|
||||
elif isinstance(param_val, str):
|
||||
if param_val.isdigit():
|
||||
param_val = int(param_val)
|
||||
|
||||
self[param_key] = param_val
|
||||
return self
|
||||
|
@ -135,3 +171,40 @@ class Config:
|
|||
param_str = param_str + f'&{safe_key}={self[safe_key]}'
|
||||
|
||||
return param_str
|
||||
|
||||
def _get_fernet_key(self, password: str) -> bytes:
|
||||
hash_object = hashlib.md5(password.encode())
|
||||
key = urlsafe_b64encode(hash_object.hexdigest().encode())
|
||||
return key
|
||||
|
||||
def _encode_preferences(self) -> str:
|
||||
encoded_preferences = brotli.compress(pickle.dumps(self.get_attrs()))
|
||||
if self.preferences_encrypted:
|
||||
if self.preferences_key != '':
|
||||
key = self._get_fernet_key(self.preferences_key)
|
||||
encoded_preferences = Fernet(key).encrypt(encoded_preferences)
|
||||
encoded_preferences = brotli.compress(encoded_preferences)
|
||||
|
||||
return urlsafe_b64encode(encoded_preferences).decode()
|
||||
|
||||
def _decode_preferences(self, preferences: str) -> dict:
|
||||
mode = preferences[0]
|
||||
preferences = preferences[1:]
|
||||
if mode == 'e': # preferences are encrypted
|
||||
try:
|
||||
key = self._get_fernet_key(self.preferences_key)
|
||||
|
||||
config = Fernet(key).decrypt(
|
||||
brotli.decompress(urlsafe_b64decode(preferences.encode()))
|
||||
)
|
||||
|
||||
config = pickle.loads(brotli.decompress(config))
|
||||
except Exception:
|
||||
config = {}
|
||||
elif mode == 'u': # preferences are not encrypted
|
||||
config = pickle.loads(
|
||||
brotli.decompress(urlsafe_b64decode(preferences.encode()))
|
||||
)
|
||||
else: # preferences are incorrectly formatted
|
||||
config = {}
|
||||
return config
|
||||
|
|
|
@ -193,6 +193,9 @@ def index():
|
|||
session['error_message'] = ''
|
||||
return render_template('error.html', error_message=error_message)
|
||||
|
||||
# Update user config if specified in search args
|
||||
g.user_config = g.user_config.from_params(g.request_params)
|
||||
|
||||
return render_template('index.html',
|
||||
has_update=app.config['HAS_UPDATE'],
|
||||
languages=app.config['LANGUAGES'],
|
||||
|
@ -231,7 +234,8 @@ def opensearch():
|
|||
main_url=opensearch_url,
|
||||
request_type='' if get_only else 'method="post"',
|
||||
search_type=request.args.get('tbm'),
|
||||
search_name=get_search_name(request.args.get('tbm'))
|
||||
search_name=get_search_name(request.args.get('tbm')),
|
||||
preferences=g.user_config.preferences
|
||||
), 200, {'Content-Type': 'application/xml'}
|
||||
|
||||
|
||||
|
@ -334,6 +338,7 @@ def search():
|
|||
tabs = get_tabs_content(app.config['HEADER_TABS'],
|
||||
search_util.full_query,
|
||||
search_util.search_type,
|
||||
g.user_config.preferences,
|
||||
translation)
|
||||
|
||||
# Feature to display currency_card
|
||||
|
@ -342,6 +347,9 @@ def search():
|
|||
html_soup = bsoup(str(response), 'html.parser')
|
||||
response = add_currency_card(html_soup, conversion)
|
||||
|
||||
preferences = g.user_config.preferences
|
||||
home_url = f"home?preferences={preferences}" if preferences else "home"
|
||||
|
||||
return render_template(
|
||||
'display.html',
|
||||
has_update=app.config['HAS_UPDATE'],
|
||||
|
@ -365,6 +373,7 @@ def search():
|
|||
version_number=app.config['VERSION_NUMBER'],
|
||||
search_header=render_template(
|
||||
'header.html',
|
||||
home_url=home_url,
|
||||
config=g.user_config,
|
||||
translation=translation,
|
||||
languages=app.config['LANGUAGES'],
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
"config-tor": "Use Tor",
|
||||
"config-get-only": "GET Requests Only",
|
||||
"config-url": "Root URL",
|
||||
"config-pref-url": "Preferences URL",
|
||||
"config-pref-encryption": "Encrypt Preferences",
|
||||
"config-pref-help": "Requires WHOOGLE_CONFIG_PREFERENCES_KEY, otherwise this will be ignored.",
|
||||
"config-css": "Custom CSS",
|
||||
"load": "Load",
|
||||
"apply": "Apply",
|
||||
|
@ -72,6 +75,9 @@
|
|||
"config-tor": "Gebruik Tor",
|
||||
"config-get-only": "Alleen GET Requests",
|
||||
"config-url": "Root URL",
|
||||
"config-pref-url": "Voorkeurs URL",
|
||||
"config-pref-encryption": "Versleutel voorkeuren",
|
||||
"config-pref-help": "Vereist WHOOGLE_CONFIG_PREFERENCES_KEY, anders wordt dit genegeerd.",
|
||||
"config-css": "Eigen CSS",
|
||||
"load": "Laden",
|
||||
"apply": "Opslaan",
|
||||
|
@ -118,6 +124,9 @@
|
|||
"config-tor": "Tor benutzen",
|
||||
"config-get-only": "Auschließlich GET-Anfragen",
|
||||
"config-url": "Root URL",
|
||||
"config-pref-url": "Einstellungs URL",
|
||||
"config-pref-encryption": "Einstellungen verschlüsseln",
|
||||
"config-pref-help": "Erfordert WHOOGLE_CONFIG_PREFERENCES_KEY, sonst wird dies ignoriert.",
|
||||
"config-css": "Custom CSS",
|
||||
"load": "Laden",
|
||||
"apply": "Übernehmen",
|
||||
|
@ -164,6 +173,9 @@
|
|||
"config-tor": "Usa Tor",
|
||||
"config-get-only": "GET solo solicitudes",
|
||||
"config-url": "URL raíz",
|
||||
"config-pref-url": "URL de preferencias",
|
||||
"config-pref-encryption": "Cifrar preferencias",
|
||||
"config-pref-help": "Requiere WHOOGLE_CONFIG_PREFERENCES_KEY; de lo contrario, se ignorará.",
|
||||
"config-css": "CSS personalizado",
|
||||
"load": "Cargar",
|
||||
"apply": "Aplicar",
|
||||
|
@ -210,6 +222,9 @@
|
|||
"config-tor": "Usa Tor",
|
||||
"config-get-only": "Utilizza solo richieste GET",
|
||||
"config-url": "Root URL",
|
||||
"config-pref-url": "URL delle preferenze",
|
||||
"config-pref-encryption": "Crittografa le preferenze",
|
||||
"config-pref-help": "Richiede WHOOGLE_CONFIG_PREFERENCES_KEY, altrimenti verrà ignorato.",
|
||||
"config-css": "CSS Personalizzato",
|
||||
"load": "Carica",
|
||||
"apply": "Applica",
|
||||
|
@ -256,6 +271,9 @@
|
|||
"config-tor": "Usar Tor",
|
||||
"config-get-only": "Apenas Pedidos GET",
|
||||
"config-url": "URL Fonte",
|
||||
"config-pref-url": "URL de preferências",
|
||||
"config-pref-encryption": "Criptografar preferências",
|
||||
"config-pref-help": "Requer WHOOGLE_CONFIG_PREFERENCES_KEY, caso contrário, será ignorado.",
|
||||
"config-css": "CSS Personalizado",
|
||||
"load": "Carregar",
|
||||
"apply": "Aplicar",
|
||||
|
@ -302,6 +320,9 @@
|
|||
"config-tor": "Использовать Tor",
|
||||
"config-get-only": "Только GET-запросы",
|
||||
"config-url": "Корневой URL-адрес",
|
||||
"config-pref-url": "URL-адрес настроек",
|
||||
"config-pref-encryption": "Зашифровать настройки",
|
||||
"config-pref-help": "Требуется WHOOGLE_CONFIG_PREFERENCES_KEY, иначе это будет проигнорировано.",
|
||||
"config-css": "Пользовательский CSS",
|
||||
"load": "Загрузить",
|
||||
"apply": "Применить",
|
||||
|
@ -348,6 +369,9 @@
|
|||
"config-tor": "使用 Tor",
|
||||
"config-get-only": "仅限 GET 请求",
|
||||
"config-url": "站点根 URL",
|
||||
"config-pref-url": "首选项网址",
|
||||
"config-pref-encryption": "加密首选项",
|
||||
"config-pref-help": "需要 WHOOGLE_CONFIG_PREFERENCES_KEY,否则将被忽略。",
|
||||
"config-css": "自定义 CSS",
|
||||
"load": "载入",
|
||||
"apply": "应用",
|
||||
|
@ -394,6 +418,9 @@
|
|||
"config-tor": "ටෝර් භාවිතා කරන්න",
|
||||
"config-get-only": "ඉල්ලීම් පමණක් ලබා ගන්න",
|
||||
"config-url": "ඒ.ස.නි.(URL) මූලය",
|
||||
"config-pref-url": "මනාප URL",
|
||||
"config-pref-encryption": "මනාප සංකේතනය කරන්න",
|
||||
"config-pref-help": "WHOOGLE_CONFIG_PREFERENCES_KEY අවශ්ය වේ, එසේ නොමැතිනම් මෙය නොසලකා හරිනු ඇත.",
|
||||
"config-css": "අභිරුචි සීඑස්එස්",
|
||||
"load": "පූරනය කරන්න",
|
||||
"apply": "යොදන්න",
|
||||
|
@ -440,6 +467,9 @@
|
|||
"config-tor": "Utiliser Tor",
|
||||
"config-get-only": "Requêtes GET seulement",
|
||||
"config-url": "URL de la racine",
|
||||
"config-pref-url": "URL des préférences",
|
||||
"config-pref-encryption": "Chiffrer les préférences",
|
||||
"config-pref-help": "Nécessite WHOOGLE_CONFIG_PREFERENCES_KEY, sinon cela sera ignoré.",
|
||||
"config-css": "CSS Personalisé",
|
||||
"load": "Charger",
|
||||
"apply": "Appliquer",
|
||||
|
@ -486,6 +516,9 @@
|
|||
"config-tor": "استفاده از تور",
|
||||
"config-get-only": "فقط درخواستهای GET",
|
||||
"config-url": "آدرس ریشهی سایت",
|
||||
"config-pref-url": "URL تنظیمات برگزیده",
|
||||
"config-pref-encryption": "رمزگذاری تنظیمات برگزیده",
|
||||
"config-pref-help": "به WHOOGLE_CONFIG_PREFERENCES_KEY نیاز دارد، در غیر این صورت نادیده گرفته خواهد شد.",
|
||||
"config-css": "CSS دلخواه",
|
||||
"load": "بارگذاری",
|
||||
"apply": "تایید",
|
||||
|
@ -532,6 +565,9 @@
|
|||
"config-tor": "Používat Tor",
|
||||
"config-get-only": "Pouze požadavky GET",
|
||||
"config-url": "Kořenová adresa URL",
|
||||
"config-pref-url": "Adresa URL předvoleb",
|
||||
"config-pref-encryption": "Předvolby šifrování",
|
||||
"config-pref-help": "Vyžaduje WHOOGLE_CONFIG_PREFERENCES_KEY, jinak bude ignorována.",
|
||||
"config-css": "Vlastní CSS",
|
||||
"load": "Načíst",
|
||||
"apply": "Použít",
|
||||
|
@ -578,6 +614,9 @@
|
|||
"config-tor": "使用 Tor",
|
||||
"config-get-only": "僅限於 GET 要求",
|
||||
"config-url": "首頁網址",
|
||||
"config-pref-url": "首選項網址",
|
||||
"config-pref-encryption": "加密首選項",
|
||||
"config-pref-help": "需要 WHOOGLE_CONFIG_PREFERENCES_KEY,否則將被忽略。",
|
||||
"config-css": "自定 CSS",
|
||||
"load": "載入",
|
||||
"apply": "套用",
|
||||
|
@ -624,6 +663,9 @@
|
|||
"config-tor": "Използвайте Tor",
|
||||
"config-get-only": "Само GET заявки",
|
||||
"config-url": "Основен URL адрес",
|
||||
"config-pref-url": "URL адрес на предпочитанията",
|
||||
"config-pref-encryption": "Шифроване на предпочитанията",
|
||||
"config-pref-help": "Изисква WHOOGLE_CONFIG_PREFERENCES_KEY, в противен случай това ще бъде игнорирано.",
|
||||
"config-css": "Персонализиран CSS",
|
||||
"load": "Зареди",
|
||||
"apply": "Приложи",
|
||||
|
@ -670,6 +712,9 @@
|
|||
"config-tor": "TOR का प्रयोग करें",
|
||||
"config-get-only": "केवल GET अनुरोध",
|
||||
"config-url": "रूट यूआरएल",
|
||||
"config-pref-url": "वरीयताएँ URL",
|
||||
"config-pref-encryption": "एन्क्रिप्ट प्राथमिकताएं",
|
||||
"config-pref-help": "WHOOGLE_CONFIG_PREFERENCES_KEY की आवश्यकता है, अन्यथा इसे अनदेखा कर दिया जाएगा।",
|
||||
"config-css": "कस्टम सीएसएस",
|
||||
"load": "भार",
|
||||
"apply": "लागू करना",
|
||||
|
@ -716,6 +761,9 @@
|
|||
"config-tor": "Torを使用",
|
||||
"config-get-only": "GETリクエストのみ",
|
||||
"config-url": "ルートURL",
|
||||
"config-pref-url": "設定 URL",
|
||||
"config-pref-encryption": "設定を暗号化する",
|
||||
"config-pref-help": "WHOOGLE_CONFIG_PREFERENCES_KEY が必要です。それ以外の場合、これは無視されます。",
|
||||
"config-css": "カスタムCSS",
|
||||
"load": "読み込み",
|
||||
"apply": "反映",
|
||||
|
@ -762,6 +810,9 @@
|
|||
"config-tor": "Tor 사용",
|
||||
"config-get-only": "GET 요청만",
|
||||
"config-url": "루트 URL",
|
||||
"config-pref-url": "환경설정 URL",
|
||||
"config-pref-encryption": "암호화 환경 설정",
|
||||
"config-pref-help": "WHOOGLE_CONFIG_PREFERENCES_KEY이 필요합니다. 그렇지 않으면 무시됩니다.",
|
||||
"config-css": "커스텀 CSS",
|
||||
"load": "불러오기",
|
||||
"apply": "적용",
|
||||
|
@ -808,6 +859,9 @@
|
|||
"config-tor": "Tor bi kar bîne",
|
||||
"config-get-only": "Daxwazan bi Dest Bixe",
|
||||
"config-url": "Reha URL",
|
||||
"config-pref-url": "Preferences URL",
|
||||
"config-pref-encryption": "Vebijêrkên şîfre bikin",
|
||||
"config-pref-help": "WHOOGLE_CONFIG_PREFERENCES_KEY hewce dike, wekî din ev ê were paşguh kirin.",
|
||||
"config-css": "CSS kesane bike",
|
||||
"load": "Bar bike",
|
||||
"apply": "Bisepîne",
|
||||
|
|
|
@ -4,13 +4,16 @@
|
|||
<form class="search-form header"
|
||||
id="search-form"
|
||||
method="{{ 'GET' if config.get_only else 'POST' }}">
|
||||
<a class="logo-link mobile-logo" href="home">
|
||||
<a class="logo-link mobile-logo" href="{{ home_url }}">
|
||||
<div id="mobile-header-logo">
|
||||
{{ logo|safe }}
|
||||
</div>
|
||||
</a>
|
||||
<div class="H0PQec mobile-input-div">
|
||||
<div class="autocomplete-mobile esbc autocomplete">
|
||||
{% if config.preferences %}
|
||||
<input type="hidden" name="preferences" value="{{ config.preferences }}" />
|
||||
{% endif %}
|
||||
<input
|
||||
id="search-bar"
|
||||
class="mobile-search-bar"
|
||||
|
@ -57,7 +60,7 @@
|
|||
{% else %}
|
||||
<header>
|
||||
<div class="logo-div">
|
||||
<a class="logo-link" href="home">
|
||||
<a class="logo-link" href="{{ home_url }}">
|
||||
<div class="desktop-header-logo">
|
||||
{{ logo|safe }}
|
||||
</div>
|
||||
|
@ -70,6 +73,9 @@
|
|||
method="{{ 'GET' if config.get_only else 'POST' }}">
|
||||
<div class="autocomplete header-autocomplete">
|
||||
<div style="width: 100%; display: flex">
|
||||
{% if config.preferences %}
|
||||
<input type="hidden" name="preferences" value="{{ config.preferences }}" />
|
||||
{% endif %}
|
||||
<input
|
||||
id="search-bar"
|
||||
autocapitalize="none"
|
||||
|
|
|
@ -66,6 +66,9 @@
|
|||
<form id="search-form" action="search" method="{{ 'get' if config.get_only else 'post' }}">
|
||||
<div class="search-fields">
|
||||
<div class="autocomplete">
|
||||
{% if config.preferences %}
|
||||
<input type="hidden" name="preferences" value="{{ config.preferences }}" />
|
||||
{% endif %}
|
||||
<input
|
||||
type="text"
|
||||
name="q"
|
||||
|
@ -233,6 +236,14 @@
|
|||
{{ config.style.replace('\t', '') }}
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="config-div config-div-pref-url">
|
||||
<label for="config-pref-encryption">{{ translation['config-pref-encryption'] }}: </label>
|
||||
<input type="checkbox" name="preferences_encrypted"
|
||||
id="config-pref-encryption" {{ 'checked' if config.preferences_encrypted and config.preferences_key else '' }}>
|
||||
<div><span class="info-text"> — {{ translation['config-pref-help'] }}</span></div>
|
||||
<label for="config-pref-url">{{ translation['config-pref-url'] }}: </label>
|
||||
<input type="text" name="pref-url" id="config-pref-url" value="{{ config.url }}?preferences={{ config.preferences }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="config-div config-buttons">
|
||||
<input type="submit" id="config-load" value="{{ translation['load'] }}">
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
{% if search_type %}
|
||||
<Param name="tbm" value="{{ search_type }}"/>
|
||||
{% endif %}
|
||||
{% if preferences %}
|
||||
<Param name="preferences" value="{{ preferences }}"/>
|
||||
{% endif %}
|
||||
</Url>
|
||||
<Url type="application/x-suggestions+json" {{ request_type|safe }} template="{{ main_url }}/autocomplete">
|
||||
<Param name="q" value="{searchTerms}"/>
|
||||
|
|
|
@ -393,6 +393,7 @@ def add_currency_card(soup: BeautifulSoup,
|
|||
def get_tabs_content(tabs: dict,
|
||||
full_query: str,
|
||||
search_type: str,
|
||||
preferences: str,
|
||||
translation: dict) -> dict:
|
||||
"""Takes the default tabs content and updates it according to the query.
|
||||
|
||||
|
@ -417,6 +418,9 @@ def get_tabs_content(tabs: dict,
|
|||
if tab_content['tbm'] is not None:
|
||||
query = f"{query}&tbm={tab_content['tbm']}"
|
||||
|
||||
if preferences:
|
||||
query = f"{query}&preferences={preferences}"
|
||||
|
||||
tab_content['href'] = tab_content['href'].format(query=query)
|
||||
|
||||
# update if selected tab (default all tab is selected)
|
||||
|
|
|
@ -47,21 +47,23 @@ conf: {}
|
|||
# WHOOGLE_AUTOCOMPLETE: "" # Controls visibility of autocomplete/search suggestions. Default on -- use '0' to disable
|
||||
# WHOOGLE_MINIMAL: "" # Remove everything except basic result cards from all search queries.
|
||||
|
||||
# WHOOGLE_CONFIG_DISABLE: "" # Hide config from UI and disallow changes to config by client
|
||||
# WHOOGLE_CONFIG_COUNTRY: "" # Filter results by hosting country
|
||||
# WHOOGLE_CONFIG_LANGUAGE: "" # Set interface language
|
||||
# WHOOGLE_CONFIG_SEARCH_LANGUAGE: "" # Set search result language
|
||||
# WHOOGLE_CONFIG_BLOCK: "" # Block websites from search results (use comma-separated list)
|
||||
# WHOOGLE_CONFIG_THEME: "" # Set theme mode (light, dark, or system)
|
||||
# WHOOGLE_CONFIG_SAFE: "" # Enable safe searches
|
||||
# WHOOGLE_CONFIG_ALTS: "" # Use social media site alternatives (nitter, invidious, etc)
|
||||
# WHOOGLE_CONFIG_NEAR: "" # Restrict results to only those near a particular city
|
||||
# WHOOGLE_CONFIG_TOR: "" # Use Tor routing (if available)
|
||||
# WHOOGLE_CONFIG_NEW_TAB: "" # Always open results in new tab
|
||||
# WHOOGLE_CONFIG_VIEW_IMAGE: "" # Enable View Image option
|
||||
# WHOOGLE_CONFIG_GET_ONLY: "" # Search using GET requests only
|
||||
# WHOOGLE_CONFIG_URL: "" # The root url of the instance (https://<your url>/)
|
||||
# WHOOGLE_CONFIG_STYLE: "" # The custom CSS to use for styling (should be single line)
|
||||
# WHOOGLE_CONFIG_DISABLE: "" # Hide config from UI and disallow changes to config by client
|
||||
# WHOOGLE_CONFIG_COUNTRY: "" # Filter results by hosting country
|
||||
# WHOOGLE_CONFIG_LANGUAGE: "" # Set interface language
|
||||
# WHOOGLE_CONFIG_SEARCH_LANGUAGE: "" # Set search result language
|
||||
# WHOOGLE_CONFIG_BLOCK: "" # Block websites from search results (use comma-separated list)
|
||||
# WHOOGLE_CONFIG_THEME: "" # Set theme mode (light, dark, or system)
|
||||
# WHOOGLE_CONFIG_SAFE: "" # Enable safe searches
|
||||
# WHOOGLE_CONFIG_ALTS: "" # Use social media site alternatives (nitter, invidious, etc)
|
||||
# WHOOGLE_CONFIG_NEAR: "" # Restrict results to only those near a particular city
|
||||
# WHOOGLE_CONFIG_TOR: "" # Use Tor routing (if available)
|
||||
# WHOOGLE_CONFIG_NEW_TAB: "" # Always open results in new tab
|
||||
# WHOOGLE_CONFIG_VIEW_IMAGE: "" # Enable View Image option
|
||||
# WHOOGLE_CONFIG_GET_ONLY: "" # Search using GET requests only
|
||||
# WHOOGLE_CONFIG_URL: "" # The root url of the instance (https://<your url>/)
|
||||
# WHOOGLE_CONFIG_STYLE: "" # The custom CSS to use for styling (should be single line)
|
||||
# WHOOGLE_CONFIG_PREFERENCES_ENCRYPTED: "" # Encrypt preferences token, requires key
|
||||
# WHOOGLE_CONFIG_PREFERENCES_KEY: "" # Key to encrypt preferences in URL (REQUIRED to show url)
|
||||
|
||||
podAnnotations: {}
|
||||
podSecurityContext: {}
|
||||
|
|
|
@ -72,6 +72,8 @@ services:
|
|||
# - WHOOGLE_CONFIG_SEARCH_LANGUAGE=lang_en
|
||||
# - WHOOGLE_CONFIG_GET_ONLY=1
|
||||
# - WHOOGLE_CONFIG_COUNTRY=FR
|
||||
# - WHOOGLE_CONFIG_PREFERENCES_ENCRYPTED=1
|
||||
# - WHOOGLE_CONFIG_PREFERENCES_KEY="NEEDS_TO_BE_MODIFIED"
|
||||
#env_file: # Alternatively, load variables from whoogle.env
|
||||
#- whoogle.env
|
||||
ports:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
attrs==19.3.0
|
||||
beautifulsoup4==4.10.0
|
||||
brotli==1.0.9
|
||||
cachelib==0.4.1
|
||||
certifi==2020.4.5.1
|
||||
cffi==1.15.0
|
||||
|
|
|
@ -5,6 +5,20 @@ from app.models.endpoint import Endpoint
|
|||
from app.utils.session import generate_user_key, valid_user_session
|
||||
|
||||
|
||||
JAPAN_PREFS = 'uG-gGIJwHdqxl6DrS3mnu_511HlQcRpxYlG03Xs-' \
|
||||
+ '_znXNiJWI9nLOkRLkiiFwIpeUYMTGfUF5-t9fP5DGmzDLEt04DCx703j3nPf' \
|
||||
+ '29v_RWkU7gXw_44m2oAFIaKGmYlu4Z0bKyu9k5WXfL9Dy6YKKnpcR5CiaFsG' \
|
||||
+ 'rccNRkAPYm-eYGAFUV8M59f8StsGd_M-gHKGS9fLok7EhwBWjHxBJ2Kv8hsT' \
|
||||
+ '87zftP2gMJOevTdNnezw2Y5WOx-ZotgeheCW1BYCFcRqatlov21PHp22NGVG' \
|
||||
+ '8ZuBNAFW0bE99WSdyT7dUIvzeWCLJpbdSsq-3FUUZkxbRdFYlGd8vY1UgVAp' \
|
||||
+ 'OSie2uAmpgLFXygO-VfNBBZ68Q7gAap2QtzHCiKD5cFYwH3LPgVJ-DoZvJ6k' \
|
||||
+ 'alt34TaYiJphgiqFKV4SCeVmLWTkr0SF3xakSR78yYJU_d41D2ng-TojA9XZ' \
|
||||
+ 'uR2ZqjSvPKOWvjimu89YhFOgJxG1Po8Henj5h9OL9VXXvdvlJwBSAKw1E3FV' \
|
||||
+ '7UHWiglMxPblfxqou1cYckMYkFeIMCD2SBtju68mBiQh2k328XRPTsQ_ocby' \
|
||||
+ 'cgVKnleGperqbD6crRk3Z9xE5sVCjujn9JNVI-7mqOITMZ0kntq9uJ3R5n25' \
|
||||
+ 'Vec0TJ0P19nEtvjY0nJIrIjtnBg=='
|
||||
|
||||
|
||||
def test_generate_user_keys():
|
||||
key = generate_user_key()
|
||||
assert Fernet(key)
|
||||
|
@ -49,3 +63,16 @@ def test_query_decryption(client):
|
|||
|
||||
with client.session_transaction() as session:
|
||||
assert valid_user_session(session)
|
||||
|
||||
|
||||
def test_prefs_url(client):
|
||||
base_url = f'/{Endpoint.search}?q=wikipedia'
|
||||
rv = client.get(base_url)
|
||||
assert rv._status_code == 200
|
||||
assert b'wikipedia.org' in rv.data
|
||||
assert b'ja.wikipedia.org' not in rv.data
|
||||
|
||||
rv = client.get(f'{base_url}&preferences={JAPAN_PREFS}')
|
||||
assert rv._status_code == 200
|
||||
assert b'ja.wikipedia.org' in rv.data
|
||||
|
||||
|
|
|
@ -85,3 +85,9 @@
|
|||
|
||||
# Set custom CSS styling/theming
|
||||
#WHOOGLE_CONFIG_STYLE=":root { /* LIGHT THEME COLORS */ --whoogle-background: #d8dee9; --whoogle-accent: #2e3440; --whoogle-text: #3B4252; --whoogle-contrast-text: #eceff4; --whoogle-secondary-text: #70757a; --whoogle-result-bg: #fff; --whoogle-result-title: #4c566a; --whoogle-result-url: #81a1c1; --whoogle-result-visited: #a3be8c; /* DARK THEME COLORS */ --whoogle-dark-background: #222; --whoogle-dark-accent: #685e79; --whoogle-dark-text: #fff; --whoogle-dark-contrast-text: #000; --whoogle-dark-secondary-text: #bbb; --whoogle-dark-result-bg: #000; --whoogle-dark-result-title: #1967d2; --whoogle-dark-result-url: #4b11a8; --whoogle-dark-result-visited: #bbbbff; }"
|
||||
|
||||
# Enable preferences encryption (requires key)
|
||||
#WHOOGLE_CONFIG_PREFERENCES_ENCRYPTED=1
|
||||
|
||||
# Set Key to encode config in url
|
||||
#WHOOGLE_CONFIG_PREFERENCES_KEY="NEEDS_TO_BE_MODIFIED"
|
Loading…
Reference in New Issue