Merge branch 'benbusby:develop' into develop

This commit is contained in:
Joao A. Candido Ramos 2021-05-10 09:41:25 +00:00
commit ad336a857b
19 changed files with 304 additions and 155 deletions

View File

@ -259,9 +259,11 @@ There are a few optional environment variables available for customizing a Whoog
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. 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 | | Variable | Description |
| ----------------------- | --------------------------------------------------------------- | | ------------------------------ | --------------------------------------------------------------- |
| WHOOGLE_CONFIG_COUNTRY | Filter results by hosting country | | WHOOGLE_CONFIG_COUNTRY | Filter results by hosting country |
| WHOOGLE_CONFIG_LANGUAGE | Set interface and search result language | | 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_DARK | Enable dark theme | | WHOOGLE_CONFIG_DARK | Enable dark theme |
| WHOOGLE_CONFIG_SAFE | Enable safe searches | | WHOOGLE_CONFIG_SAFE | Enable safe searches |
| WHOOGLE_CONFIG_ALTS | Use social media site alternatives (nitter, invidious, etc) | | WHOOGLE_CONFIG_ALTS | Use social media site alternatives (nitter, invidious, etc) |
@ -270,8 +272,7 @@ These environment variables allow setting default config values, but can be over
| WHOOGLE_CONFIG_VIEW_IMAGE | Enable View Image option | | WHOOGLE_CONFIG_VIEW_IMAGE | Enable View Image option |
| WHOOGLE_CONFIG_GET_ONLY | Search using GET requests only | | WHOOGLE_CONFIG_GET_ONLY | Search using GET requests only |
| WHOOGLE_CONFIG_URL | The root url of the instance (`https://<your url>/`) | | WHOOGLE_CONFIG_URL | The root url of the instance (`https://<your url>/`) |
| WHOOGLE_CONFIG_STYLE | The custom CSS to use for styling (must be single line) | | WHOOGLE_CONFIG_STYLE | The custom CSS to use for styling (should be single line) |
## Usage ## Usage
Same as most search engines, with the exception of filtering by time range. Same as most search engines, with the exception of filtering by time range.

View File

@ -71,7 +71,22 @@
"required": false "required": false
}, },
"WHOOGLE_CONFIG_LANGUAGE": { "WHOOGLE_CONFIG_LANGUAGE": {
"description": "[CONFIG] The language to use for search results and interface (use values from https://raw.githubusercontent.com/benbusby/whoogle-search/develop/app/static/settings/languages.json)", "description": "[CONFIG] The language to use for the interface (use values from https://raw.githubusercontent.com/benbusby/whoogle-search/develop/app/static/settings/languages.json)",
"value": "",
"required": false
},
"WHOOGLE_CONFIG_SEARCH_LANGUAGE": {
"description": "[CONFIG] The language to use for search results (use values from https://raw.githubusercontent.com/benbusby/whoogle-search/develop/app/static/settings/languages.json)",
"value": "",
"required": false
},
"WHOOGLE_CONFIG_DISABLE": {
"description": "[CONFIG] Disable ability for client to change config (set to 1 or leave blank)",
"value": "",
"required": false
},
"WHOOGLE_CONFIG_BLOCK": {
"description": "[CONFIG] Block websites from search results (comma-separated list)",
"value": "", "value": "",
"required": false "required": false
}, },

View File

@ -50,7 +50,7 @@ app.config['BANG_FILE'] = os.path.join(
'bangs.json') 'bangs.json')
app.config['CSP'] = 'default-src \'none\';' \ app.config['CSP'] = 'default-src \'none\';' \
'manifest-src \'self\';' \ 'manifest-src \'self\';' \
'img-src \'self\';' \ 'img-src \'self\' data:;' \
'style-src \'self\' \'unsafe-inline\';' \ 'style-src \'self\' \'unsafe-inline\';' \
'script-src \'self\';' \ 'script-src \'self\';' \
'media-src \'self\';' \ 'media-src \'self\';' \

View File

@ -12,12 +12,13 @@ class Config:
app_config = current_app.config app_config = current_app.config
self.url = os.getenv('WHOOGLE_CONFIG_URL', '') self.url = os.getenv('WHOOGLE_CONFIG_URL', '')
self.lang_search = os.getenv('WHOOGLE_CONFIG_LANGUAGE', '') self.lang_search = os.getenv('WHOOGLE_CONFIG_SEARCH_LANGUAGE', '')
self.lang_interface = os.getenv('WHOOGLE_CONFIG_LANGUAGE', '') self.lang_interface = os.getenv('WHOOGLE_CONFIG_LANGUAGE', '')
self.style = os.getenv( self.style = os.getenv(
'WHOOGLE_CONFIG_STYLE', 'WHOOGLE_CONFIG_STYLE',
open(os.path.join(app_config['STATIC_FOLDER'], open(os.path.join(app_config['STATIC_FOLDER'],
'css/variables.css')).read()) 'css/variables.css')).read())
self.block = os.getenv('WHOOGLE_CONFIG_BLOCK', '')
self.ctry = os.getenv('WHOOGLE_CONFIG_COUNTRY', '') self.ctry = os.getenv('WHOOGLE_CONFIG_COUNTRY', '')
self.safe = read_config_bool('WHOOGLE_CONFIG_SAFE') self.safe = read_config_bool('WHOOGLE_CONFIG_SAFE')
self.dark = read_config_bool('WHOOGLE_CONFIG_DARK') self.dark = read_config_bool('WHOOGLE_CONFIG_DARK')
@ -38,11 +39,12 @@ class Config:
# Skip setting custom config if there isn't one # Skip setting custom config if there isn't one
if kwargs: if kwargs:
for attr in self.get_mutable_attrs(): mutable_attrs = self.get_mutable_attrs()
if attr not in kwargs.keys(): for attr in mutable_attrs:
setattr(self, attr, '') if attr in kwargs.keys():
else:
setattr(self, attr, kwargs[attr]) setattr(self, attr, kwargs[attr])
elif attr not in kwargs.keys() and mutable_attrs[attr] == bool:
setattr(self, attr, False)
def __getitem__(self, name): def __getitem__(self, name):
return getattr(self, name) return getattr(self, name)
@ -57,7 +59,7 @@ class Config:
return hasattr(self, name) return hasattr(self, name)
def get_mutable_attrs(self): def get_mutable_attrs(self):
return {name: attr for name, attr in self.__dict__.items() return {name: type(attr) for name, attr in self.__dict__.items()
if not name.startswith("__") if not name.startswith("__")
and (type(attr) is bool or type(attr) is str)} and (type(attr) is bool or type(attr) is str)}

View File

@ -120,6 +120,10 @@ def gen_query(query, args, config, near_city=None) -> str:
) if config.lang_interface else '' ) if config.lang_interface else ''
param_dict['safe'] = '&safe=' + ('active' if config.safe else 'off') param_dict['safe'] = '&safe=' + ('active' if config.safe else 'off')
# Block all sites specified in the user config
for blocked in config.block.split(','):
query += (' -site:' + blocked) if blocked else ''
for val in param_dict.values(): for val in param_dict.values():
if not val: if not val:
continue continue

View File

@ -2,7 +2,6 @@ import argparse
import base64 import base64
import io import io
import json import json
import os
import pickle import pickle
import urllib.parse as urlparse import urllib.parse as urlparse
import uuid import uuid
@ -17,7 +16,7 @@ from app import app
from app.models.config import Config from app.models.config import Config
from app.request import Request, TorError from app.request import Request, TorError
from app.utils.bangs import resolve_bang from app.utils.bangs import resolve_bang
from app.utils.session import valid_user_session from app.utils.session import generate_user_key, valid_user_session
from app.utils.search import * from app.utils.search import *
# Load DDG bang json files only on init # Load DDG bang json files only on init

View File

@ -66,7 +66,7 @@ select {
} }
#search-bar { #search-bar {
border: 2px solid var(--whoogle-dark-element-bg) !important; border-color: var(--whoogle-dark-element-bg) !important;
color: var(--whoogle-dark-text) !important; color: var(--whoogle-dark-text) !important;
} }

View File

@ -27,6 +27,11 @@ header {
font-smoothing: antialiased; font-smoothing: antialiased;
} }
.search-bar-desktop {
border-radius: 8px 8px 0 0;
height: 40px !important;
}
.search-div { .search-div {
border-radius: 8px 8px 0 0; border-radius: 8px 8px 0 0;
box-shadow: 0 1px 6px rgba(32, 33, 36, 0.18); box-shadow: 0 1px 6px rgba(32, 33, 36, 0.18);
@ -37,6 +42,7 @@ header {
height: 39px; height: 39px;
display: flex; display: flex;
width: 100%; width: 100%;
margin: 0px;
} }
.search-input { .search-input {
@ -61,7 +67,6 @@ header {
display: block; display: block;
} }
#main>div:focus-within { #main>div:focus-within {
border-radius: 8px; border-radius: 8px;
box-shadow: 0 0 6px 1px #2375e8; box-shadow: 0 0 6px 1px #2375e8;

14
app/static/css/input.css Normal file
View File

@ -0,0 +1,14 @@
#search-bar {
background: transparent !important;
padding-right: 50px;
}
#search-reset {
all: unset;
margin-left: -50px;
text-align: center;
background-color: transparent !important;
cursor: pointer;
height: 40px;
width: 50px;
}

View File

@ -122,6 +122,7 @@ input {
.autocomplete-items div:hover { .autocomplete-items div:hover {
background-color: var(--whoogle-element-bg); background-color: var(--whoogle-element-bg);
color: var(--whoogle-contrast-text) !important;
} }
.autocomplete-active { .autocomplete-active {

View File

@ -57,4 +57,13 @@ const checkForTracking = () => {
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
checkForTracking(); checkForTracking();
// Clear input if reset button tapped
const search = document.getElementById("search-bar");
const resetBtn = document.getElementById("search-reset");
resetBtn.addEventListener("click", event => {
event.preventDefault();
search.value = "";
search.focus();
});
}); });

View File

@ -5,6 +5,7 @@
<link rel="search" href="opensearch.xml" type="application/opensearchdescription+xml" title="Whoogle Search"> <link rel="search" href="opensearch.xml" type="application/opensearchdescription+xml" title="Whoogle Search">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="referrer" content="no-referrer"> <meta name="referrer" content="no-referrer">
<link rel="stylesheet" href="static/css/input.css">
<link rel="stylesheet" href="static/css/search.css"> <link rel="stylesheet" href="static/css/search.css">
<link rel="stylesheet" href="static/css/variables.css"> <link rel="stylesheet" href="static/css/variables.css">
<link rel="stylesheet" href="static/css/header.css"> <link rel="stylesheet" href="static/css/header.css">

View File

@ -1,7 +1,7 @@
{% if mobile %} {% if mobile %}
<header> <header>
<div class="bz1lBb"> <div style="background-color: {{ 'var(--whoogle-dark-result-bg)' if config.dark else 'var(--whoogle-result-bg)' }} !important;" class="bz1lBb">
<form class="Pg70bf" id="search-form" method="POST"> <form class="search-form 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;"> style="display:flex; justify-content:center; align-items:center;">
@ -11,11 +11,19 @@
</a> </a>
<div class="H0PQec" style="width: 100%;"> <div class="H0PQec" style="width: 100%;">
<div class="sbc esbc autocomplete"> <div class="sbc esbc autocomplete">
<input id="search-bar" autocapitalize="none" autocomplete="off" class="noHIxc" name="q" <input
id="search-bar"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
spellcheck="false"
class="noHIxc"
name="q"
style="background-color: {{ 'var(--whoogle-dark-result-bg)' if config.dark else 'var(--whoogle-result-bg)' }} !important; style="background-color: {{ 'var(--whoogle-dark-result-bg)' if config.dark else 'var(--whoogle-result-bg)' }} !important;
color: {{ 'var(--whoogle-dark-text)' if config.dark else 'var(--whoogle-text)' }}; color: {{ 'var(--whoogle-dark-text)' if config.dark else 'var(--whoogle-text)' }};
border: {{ '2px solid var(--whoogle-dark-element-bg)' if config.dark else '' }}; border-radius: 8px;" type="text"
spellcheck="false" type="text" value="{{ query }}"> value="{{ query[:query.find('-site:')] }}">
<input style="color: {{ 'var(--whoogle-dark-text)' if config.dark else 'var(--whoogle-text)' }}" id="search-reset" type="reset" value="x">
<input name="tbm" value="{{ search_type }}" style="display: none"> <input name="tbm" value="{{ search_type }}" style="display: none">
<input type="submit" style="display: none;"> <input type="submit" style="display: none;">
<div class="sc"></div> <div class="sc"></div>
@ -37,11 +45,19 @@
<form id="search-form" class="search-form" id="sf" method="POST"> <form id="search-form" class="search-form" id="sf" method="POST">
<div class="autocomplete" style="width: 100%; flex: 1"> <div class="autocomplete" style="width: 100%; flex: 1">
<div style="width: 100%; display: flex"> <div style="width: 100%; display: flex">
<input id="search-bar" autocapitalize="none" autocomplete="off" class="noHIxc" name="q" <input
spellcheck="false" type="text" value="{{ query }}" id="search-bar"
autocapitalize="none"
autocomplete="off"
autocorrect="off"
class="search-bar-desktop noHIxc"
name="q"
spellcheck="false"
type="text"
value="{{ query[:query.find('-site:')] }}"
style="background-color: {{ 'var(--whoogle-dark-result-bg)' if config.dark else 'var(--whoogle-result-bg)' }} !important; style="background-color: {{ 'var(--whoogle-dark-result-bg)' if config.dark else 'var(--whoogle-result-bg)' }} !important;
color: {{ 'var(--whoogle-dark-text)' if config.dark else 'var(--whoogle-text)' }}; color: {{ 'var(--whoogle-dark-text)' if config.dark else 'var(--whoogle-text)' }};
border: {{ '2px solid var(--whoogle-dark-element-bg)' if config.dark else '' }}; border-radius: 8px;"> border-bottom: {{ '2px solid var(--whoogle-dark-element-bg)' if config.dark else '0px' }};">
<input name="tbm" value="{{ search_type }}" style="display: none"> <input name="tbm" value="{{ search_type }}" style="display: none">
<input type="submit" style="display: none;"> <input type="submit" style="display: none;">
<div class="sc"></div> <div class="sc"></div>

View File

@ -42,11 +42,21 @@
<form id="search-form" action="search" method="{{ 'get' if config.get_only else 'post' }}"> <form id="search-form" action="search" method="{{ 'get' if config.get_only else 'post' }}">
<div class="search-fields"> <div class="search-fields">
<div class="autocomplete"> <div class="autocomplete">
<input type="text" name="q" id="search-bar" class="home-search" autofocus="autofocus" autocapitalize="none" autocomplete="off"> <input
type="text"
name="q"
id="search-bar"
class="home-search"
autofocus="autofocus"
autocapitalize="none"
spellcheck="false"
autocorrect="off"
autocomplete="off">
</div> </div>
<input type="submit" id="search-submit" value="Search"> <input type="submit" id="search-submit" value="Search">
</div> </div>
</form> </form>
{% if not config_disabled %}
<br/> <br/>
<button id="config-collapsible" class="collapsible">Configuration</button> <button id="config-collapsible" class="collapsible">Configuration</button>
<div class="content"> <div class="content">
@ -96,6 +106,10 @@
<label for="config-near">Near: </label> <label for="config-near">Near: </label>
<input type="text" name="near" id="config-near" placeholder="City Name" value="{{ config.near }}"> <input type="text" name="near" id="config-near" placeholder="City Name" value="{{ config.near }}">
</div> </div>
<div class="config-div config-div-block">
<label for="config-block">Block: </label>
<input type="text" name="block" id="config-block" placeholder="Comma-separated site list" value="{{ config.block }}">
</div>
<div class="config-div config-div-nojs"> <div class="config-div config-div-nojs">
<label for="config-nojs">Show NoJS Links: </label> <label for="config-nojs">Show NoJS Links: </label>
<input type="checkbox" name="nojs" id="config-nojs" {{ 'checked' if config.nojs else '' }}> <input type="checkbox" name="nojs" id="config-nojs" {{ 'checked' if config.nojs else '' }}>
@ -119,7 +133,7 @@
<input type="checkbox" name="new_tab" id="config-new-tab" {{ 'checked' if config.new_tab else '' }}> <input type="checkbox" name="new_tab" id="config-new-tab" {{ 'checked' if config.new_tab else '' }}>
</div> </div>
<div class="config-div config-div-view-image"> <div class="config-div config-div-view-image">
<label for="config-view-image">View image: </label> <label for="config-view-image">View Image: </label>
<input type="checkbox" name="view_image" id="config-view-image" {{ 'checked' if config.view_image else '' }}> <input type="checkbox" name="view_image" id="config-view-image" {{ 'checked' if config.view_image else '' }}>
<div><span class="info-text"> — Adds the "View Image" option to image search results. <div><span class="info-text"> — Adds the "View Image" option to image search results.
Note: This will cause image result thumbnails to be lower resolution.</span></div> Note: This will cause image result thumbnails to be lower resolution.</span></div>
@ -138,7 +152,16 @@
</div> </div>
<div class="config-div config-div-custom-css"> <div class="config-div config-div-custom-css">
<label for="config-style">Custom CSS:</label> <label for="config-style">Custom CSS:</label>
<textarea name="style" id="config-style" value="">{{ config.style }}</textarea> <textarea
name="style"
id="config-style"
autocapitalize="off"
autocomplete="off"
spellcheck="false"
autocorrect="off"
value="">
{{ config.style }}
</textarea>
</div> </div>
<div class="config-div"> <div class="config-div">
<input type="submit" id="config-load" value="Load">&nbsp; <input type="submit" id="config-load" value="Load">&nbsp;
@ -148,6 +171,7 @@
</form> </form>
</div> </div>
</div> </div>
{% endif %}
</div> </div>
<footer> <footer>
<p style="color: {{ 'var(--whoogle-dark-text)' if config.dark else 'var(--whoogle-text)' }};"> <p style="color: {{ 'var(--whoogle-dark-text)' if config.dark else 'var(--whoogle-text)' }};">

View File

@ -1,5 +1,4 @@
from app.filter import Filter, get_first_link from app.filter import Filter, get_first_link
from app.utils.session import generate_user_key
from app.request import gen_query from app.request import gen_query
from bs4 import BeautifulSoup as bsoup from bs4 import BeautifulSoup as bsoup
from cryptography.fernet import Fernet, InvalidToken from cryptography.fernet import Fernet, InvalidToken

View File

@ -37,8 +37,8 @@ services:
#- WHOOGLE_ALT_YT=invidious.snopyta.org #- WHOOGLE_ALT_YT=invidious.snopyta.org
#- WHOOGLE_ALT_IG=bibliogram.art/u #- WHOOGLE_ALT_IG=bibliogram.art/u
#- WHOOGLE_ALT_RD=libredd.it #- WHOOGLE_ALT_RD=libredd.it
# Load environment variables from whoogle.env #env_file: # Alternatively, load variables from whoogle.env
#- WHOOGLE_DOTENV=1 #- whoogle.env
ports: ports:
- 5000:5000 - 5000:5000
restart: unless-stopped restart: unless-stopped

View File

@ -16,7 +16,7 @@ MarkupSafe==1.1.1
more-itertools==8.3.0 more-itertools==8.3.0
packaging==20.4 packaging==20.4
pluggy==0.13.1 pluggy==0.13.1
py==1.8.1 py==1.10.0
pycodestyle==2.6.0 pycodestyle==2.6.0
pycparser==2.19 pycparser==2.19
pyOpenSSL==19.1.0 pyOpenSSL==19.1.0

View File

@ -3,6 +3,9 @@ from app.filter import Filter
from app.utils.session import generate_user_key from app.utils.session import generate_user_key
from datetime import datetime from datetime import datetime
from dateutil.parser import * from dateutil.parser import *
from urllib.parse import urlparse
from test.conftest import demo_config
def get_search_results(data): def get_search_results(data):
@ -46,6 +49,29 @@ def test_post_results(client):
assert len(get_search_results(rv.data)) <= 15 assert len(get_search_results(rv.data)) <= 15
def test_block_results(client):
rv = client.post('/search', data=dict(q='pinterest'))
assert rv._status_code == 200
has_pinterest = False
for link in BeautifulSoup(rv.data, 'html.parser').find_all('a', href=True):
if 'pinterest.com' in urlparse(link['href']).netloc:
has_pinterest = True
break
assert has_pinterest
demo_config['block'] = 'pinterest.com'
rv = client.post('/config', data=demo_config)
assert rv._status_code == 302
rv = client.post('/search', data=dict(q='pinterest'))
assert rv._status_code == 200
for link in BeautifulSoup(rv.data, 'html.parser').find_all('a', href=True):
assert 'pinterest.com' not in urlparse(link['href']).netloc
# TODO: Unit test the site alt method instead -- the results returned # TODO: Unit test the site alt method instead -- the results returned
# are too unreliable for this test in particular. # are too unreliable for this test in particular.
# def test_site_alts(client): # def test_site_alts(client):

View File

@ -1,5 +1,8 @@
# You can set Whoogle environment variables here, but must set # You can set Whoogle environment variables here, but must
# WHOOGLE_DOTENV=1 in your deployment to enable these values # modify your deployment to enable these values:
# - Local: Set WHOOGLE_DOTENV=1
# - docker-compose: Uncomment the env_file option
# - docker: Add "--env-file ./whoogle.env" to your build command
#WHOOGLE_ALT_TW=nitter.net #WHOOGLE_ALT_TW=nitter.net
#WHOOGLE_ALT_YT=invidious.snopyta.org #WHOOGLE_ALT_YT=invidious.snopyta.org
@ -13,14 +16,44 @@
#WHOOGLE_PROXY_LOC="" #WHOOGLE_PROXY_LOC=""
#HTTPS_ONLY=1 #HTTPS_ONLY=1
#WHOOGLE_CONFIG_COUNTRY=countryUK # See app/static/settings/countries.json for values # See app/static/settings/countries.json for values
#WHOOGLE_CONFIG_LANGUAGE=lang_en # See app/static/settings/languages.json for values #WHOOGLE_CONFIG_COUNTRY=countryUK
#WHOOGLE_CONFIG_DARK=1 # Dark mode
#WHOOGLE_CONFIG_SAFE=1 # Safe searches # See app/static/settings/languages.json for values
#WHOOGLE_CONFIG_ALTS=1 # Use social media site alternatives #WHOOGLE_CONFIG_LANGUAGE=lang_en
#WHOOGLE_CONFIG_TOR=1 # Use Tor if available
#WHOOGLE_CONFIG_NEW_TAB=1 # Open results in new tab # See app/static/settings/languages.json for values
#WHOOGLE_CONFIG_VIEW_IMAGE=1 # Enable View Image option #WHOOGLE_CONFIG_SEARCH_LANGUAGE=lang_en
#WHOOGLE_CONFIG_GET_ONLY=1 # Search using GET requests only
# Disable changing of config from client
#WHOOGLE_CONFIG_DISABLE=1
# Block websites from search results (comma-separated list)
#WHOOGLE_CONFIG_BLOCK=pinterest.com,whitehouse.gov
# Dark mode
#WHOOGLE_CONFIG_DARK=1
# Safe search mode
#WHOOGLE_CONFIG_SAFE=1
# Use social media site alternatives (nitter, bibliogram, etc)
#WHOOGLE_CONFIG_ALTS=1
# Enable "View Image" option
#WHOOGLE_CONFIG_VIEW_IMAGE=1
# Use Tor if available
#WHOOGLE_CONFIG_TOR=1
# Open results in new tab
#WHOOGLE_CONFIG_NEW_TAB=1
# Search using GET requests only (exposes query in logs)
#WHOOGLE_CONFIG_GET_ONLY=1
# Set instance URL
#WHOOGLE_CONFIG_URL=https://<whoogle url>/ #WHOOGLE_CONFIG_URL=https://<whoogle url>/
# 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; }" #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; }"