diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | searx/settings.yml | 2 | ||||
-rw-r--r-- | searx/static/default/css/style.css (renamed from searx/static/css/style.css) | 0 | ||||
-rw-r--r-- | searx/static/default/img/favicon.png (renamed from searx/static/img/favicon.png) | bin | 3208 -> 3208 bytes | |||
-rw-r--r-- | searx/static/default/img/github_ribbon.png (renamed from searx/static/img/github_ribbon.png) | bin | 7791 -> 7791 bytes | |||
-rw-r--r-- | searx/static/default/img/icon_github.ico (renamed from searx/static/img/icon_github.ico) | bin | 6518 -> 6518 bytes | |||
-rw-r--r-- | searx/static/default/img/icon_soundcloud.ico (renamed from searx/static/img/icon_soundcloud.ico) | bin | 1150 -> 1150 bytes | |||
-rw-r--r-- | searx/static/default/img/icon_stackoverflow.ico (renamed from searx/static/img/icon_stackoverflow.ico) | bin | 1150 -> 1150 bytes | |||
-rw-r--r-- | searx/static/default/img/icon_twitter.ico (renamed from searx/static/img/icon_twitter.ico) | bin | 1150 -> 1150 bytes | |||
-rw-r--r-- | searx/static/default/img/icon_vimeo.ico (renamed from searx/static/img/icon_vimeo.ico) | bin | 6518 -> 6518 bytes | |||
-rw-r--r-- | searx/static/default/img/icon_wikipedia.ico (renamed from searx/static/img/icon_wikipedia.ico) | bin | 14858 -> 14858 bytes | |||
-rw-r--r-- | searx/static/default/img/icon_youtube.ico (renamed from searx/static/img/icon_youtube.ico) | bin | 1150 -> 1150 bytes | |||
-rw-r--r-- | searx/static/default/img/preference-icon.png (renamed from searx/static/img/preference-icon.png) | bin | 837 -> 837 bytes | |||
-rw-r--r-- | searx/static/default/img/search-icon.png (renamed from searx/static/img/search-icon.png) | bin | 3287 -> 3287 bytes | |||
-rw-r--r-- | searx/static/default/img/searx.png (renamed from searx/static/img/searx.png) | bin | 7647 -> 7647 bytes | |||
-rw-r--r-- | searx/static/default/img/searx_logo.svg (renamed from searx/static/img/searx_logo.svg) | 0 | ||||
-rw-r--r-- | searx/static/default/js/mootools-autocompleter-1.1.2-min.js (renamed from searx/static/js/mootools-autocompleter-1.1.2-min.js) | 0 | ||||
-rw-r--r-- | searx/static/default/js/mootools-core-1.4.5-min.js (renamed from searx/static/js/mootools-core-1.4.5-min.js) | 0 | ||||
-rw-r--r-- | searx/static/default/js/searx.js (renamed from searx/static/js/searx.js) | 0 | ||||
-rw-r--r-- | searx/static/default/less/autocompleter.less (renamed from searx/static/less/autocompleter.less) | 0 | ||||
-rw-r--r-- | searx/static/default/less/definitions.less (renamed from searx/static/less/definitions.less) | 0 | ||||
-rw-r--r-- | searx/static/default/less/mixins.less (renamed from searx/static/less/mixins.less) | 0 | ||||
-rw-r--r-- | searx/static/default/less/search.less (renamed from searx/static/less/search.less) | 0 | ||||
-rw-r--r-- | searx/static/default/less/style.less (renamed from searx/static/less/style.less) | 0 | ||||
-rw-r--r-- | searx/templates/default/about.html (renamed from searx/templates/about.html) | 4 | ||||
-rw-r--r-- | searx/templates/default/base.html (renamed from searx/templates/base.html) | 0 | ||||
-rw-r--r-- | searx/templates/default/categories.html (renamed from searx/templates/categories.html) | 0 | ||||
-rw-r--r-- | searx/templates/default/github_ribbon.html (renamed from searx/templates/github_ribbon.html) | 0 | ||||
-rw-r--r-- | searx/templates/default/index.html (renamed from searx/templates/index.html) | 4 | ||||
-rw-r--r-- | searx/templates/default/opensearch.xml (renamed from searx/templates/opensearch.xml) | 0 | ||||
-rw-r--r-- | searx/templates/default/opensearch_response_rss.xml (renamed from searx/templates/opensearch_response_rss.xml) | 0 | ||||
-rw-r--r-- | searx/templates/default/preferences.html (renamed from searx/templates/preferences.html) | 14 | ||||
-rw-r--r-- | searx/templates/default/result_templates/default.html (renamed from searx/templates/result_templates/default.html) | 2 | ||||
-rw-r--r-- | searx/templates/default/result_templates/images.html (renamed from searx/templates/result_templates/images.html) | 0 | ||||
-rw-r--r-- | searx/templates/default/result_templates/torrent.html (renamed from searx/templates/result_templates/torrent.html) | 0 | ||||
-rw-r--r-- | searx/templates/default/result_templates/videos.html (renamed from searx/templates/result_templates/videos.html) | 2 | ||||
-rw-r--r-- | searx/templates/default/results.html (renamed from searx/templates/results.html) | 8 | ||||
-rw-r--r-- | searx/templates/default/search.html (renamed from searx/templates/search.html) | 2 | ||||
-rw-r--r-- | searx/templates/default/stats.html (renamed from searx/templates/stats.html) | 2 | ||||
-rw-r--r-- | searx/utils.py | 22 | ||||
-rw-r--r-- | searx/webapp.py | 65 |
41 files changed, 103 insertions, 28 deletions
@@ -44,13 +44,13 @@ minimal: bin/buildout minimal.cfg setup.py bin/buildout -c minimal.cfg $(options) styles: - @lessc -x searx/static/less/style.less > searx/static/css/style.css + @lessc -x searx/static/default/less/style.less > searx/static/default/css/style.css locales: @pybabel compile -d searx/translations clean: @rm -rf .installed.cfg .mr.developer.cfg bin parts develop-eggs \ - searx.egg-info lib include .coverage coverage searx/static/css/*.css + searx.egg-info lib include .coverage coverage searx/static/default/css/*.css .PHONY: all tests robot flake8 coverage production minimal styles locales clean diff --git a/searx/settings.yml b/searx/settings.yml index eac7593c6..69f22f5d4 100644 --- a/searx/settings.yml +++ b/searx/settings.yml @@ -4,6 +4,8 @@ server: debug : True request_timeout : 2.0 # seconds base_url : False + themes_path : "" + default_theme : default engines: - name : wikipedia diff --git a/searx/static/css/style.css b/searx/static/default/css/style.css index 69190b21d..69190b21d 100644 --- a/searx/static/css/style.css +++ b/searx/static/default/css/style.css diff --git a/searx/static/img/favicon.png b/searx/static/default/img/favicon.png Binary files differindex cefbac496..cefbac496 100644 --- a/searx/static/img/favicon.png +++ b/searx/static/default/img/favicon.png diff --git a/searx/static/img/github_ribbon.png b/searx/static/default/img/github_ribbon.png Binary files differindex 146ef8a80..146ef8a80 100644 --- a/searx/static/img/github_ribbon.png +++ b/searx/static/default/img/github_ribbon.png diff --git a/searx/static/img/icon_github.ico b/searx/static/default/img/icon_github.ico Binary files differindex 133f0ca35..133f0ca35 100644 --- a/searx/static/img/icon_github.ico +++ b/searx/static/default/img/icon_github.ico diff --git a/searx/static/img/icon_soundcloud.ico b/searx/static/default/img/icon_soundcloud.ico Binary files differindex 4130bea1b..4130bea1b 100644 --- a/searx/static/img/icon_soundcloud.ico +++ b/searx/static/default/img/icon_soundcloud.ico diff --git a/searx/static/img/icon_stackoverflow.ico b/searx/static/default/img/icon_stackoverflow.ico Binary files differindex b2242bc6c..b2242bc6c 100644 --- a/searx/static/img/icon_stackoverflow.ico +++ b/searx/static/default/img/icon_stackoverflow.ico diff --git a/searx/static/img/icon_twitter.ico b/searx/static/default/img/icon_twitter.ico Binary files differindex b4a71699a..b4a71699a 100644 --- a/searx/static/img/icon_twitter.ico +++ b/searx/static/default/img/icon_twitter.ico diff --git a/searx/static/img/icon_vimeo.ico b/searx/static/default/img/icon_vimeo.ico Binary files differindex 4fe4336da..4fe4336da 100644 --- a/searx/static/img/icon_vimeo.ico +++ b/searx/static/default/img/icon_vimeo.ico diff --git a/searx/static/img/icon_wikipedia.ico b/searx/static/default/img/icon_wikipedia.ico Binary files differindex 911fa76f6..911fa76f6 100644 --- a/searx/static/img/icon_wikipedia.ico +++ b/searx/static/default/img/icon_wikipedia.ico diff --git a/searx/static/img/icon_youtube.ico b/searx/static/default/img/icon_youtube.ico Binary files differindex 977887dbb..977887dbb 100644 --- a/searx/static/img/icon_youtube.ico +++ b/searx/static/default/img/icon_youtube.ico diff --git a/searx/static/img/preference-icon.png b/searx/static/default/img/preference-icon.png Binary files differindex f74635788..f74635788 100644 --- a/searx/static/img/preference-icon.png +++ b/searx/static/default/img/preference-icon.png diff --git a/searx/static/img/search-icon.png b/searx/static/default/img/search-icon.png Binary files differindex 1222421b2..1222421b2 100644 --- a/searx/static/img/search-icon.png +++ b/searx/static/default/img/search-icon.png diff --git a/searx/static/img/searx.png b/searx/static/default/img/searx.png Binary files differindex e162da502..e162da502 100644 --- a/searx/static/img/searx.png +++ b/searx/static/default/img/searx.png diff --git a/searx/static/img/searx_logo.svg b/searx/static/default/img/searx_logo.svg index 67a2d4588..67a2d4588 100644 --- a/searx/static/img/searx_logo.svg +++ b/searx/static/default/img/searx_logo.svg diff --git a/searx/static/js/mootools-autocompleter-1.1.2-min.js b/searx/static/default/js/mootools-autocompleter-1.1.2-min.js index 364e611cc..364e611cc 100644 --- a/searx/static/js/mootools-autocompleter-1.1.2-min.js +++ b/searx/static/default/js/mootools-autocompleter-1.1.2-min.js diff --git a/searx/static/js/mootools-core-1.4.5-min.js b/searx/static/default/js/mootools-core-1.4.5-min.js index 569473d1c..569473d1c 100644 --- a/searx/static/js/mootools-core-1.4.5-min.js +++ b/searx/static/default/js/mootools-core-1.4.5-min.js diff --git a/searx/static/js/searx.js b/searx/static/default/js/searx.js index 47dc722da..47dc722da 100644 --- a/searx/static/js/searx.js +++ b/searx/static/default/js/searx.js diff --git a/searx/static/less/autocompleter.less b/searx/static/default/less/autocompleter.less index db9601aeb..db9601aeb 100644 --- a/searx/static/less/autocompleter.less +++ b/searx/static/default/less/autocompleter.less diff --git a/searx/static/less/definitions.less b/searx/static/default/less/definitions.less index 3e0b6579d..3e0b6579d 100644 --- a/searx/static/less/definitions.less +++ b/searx/static/default/less/definitions.less diff --git a/searx/static/less/mixins.less b/searx/static/default/less/mixins.less index dbccce6e3..dbccce6e3 100644 --- a/searx/static/less/mixins.less +++ b/searx/static/default/less/mixins.less diff --git a/searx/static/less/search.less b/searx/static/default/less/search.less index d285ca734..d285ca734 100644 --- a/searx/static/less/search.less +++ b/searx/static/default/less/search.less diff --git a/searx/static/less/style.less b/searx/static/default/less/style.less index f1f729b8d..f1f729b8d 100644 --- a/searx/static/less/style.less +++ b/searx/static/default/less/style.less diff --git a/searx/templates/about.html b/searx/templates/default/about.html index 0ddf12254..19aba1905 100644 --- a/searx/templates/about.html +++ b/searx/templates/default/about.html @@ -1,6 +1,6 @@ -{% extends 'base.html' %} +{% extends 'default/base.html' %} {% block content %} -{% include 'github_ribbon.html' %} +{% include 'default/github_ribbon.html' %} <div class="row"> <h1>About <a href="{{ url_for('index') }}">searx</a></h1> diff --git a/searx/templates/base.html b/searx/templates/default/base.html index da5ae905f..da5ae905f 100644 --- a/searx/templates/base.html +++ b/searx/templates/default/base.html diff --git a/searx/templates/categories.html b/searx/templates/default/categories.html index 57e63c85d..57e63c85d 100644 --- a/searx/templates/categories.html +++ b/searx/templates/default/categories.html diff --git a/searx/templates/github_ribbon.html b/searx/templates/default/github_ribbon.html index bdd9cf180..bdd9cf180 100644 --- a/searx/templates/github_ribbon.html +++ b/searx/templates/default/github_ribbon.html diff --git a/searx/templates/index.html b/searx/templates/default/index.html index 57b67ef09..43ba88370 100644 --- a/searx/templates/index.html +++ b/searx/templates/default/index.html @@ -1,8 +1,8 @@ -{% extends "base.html" %} +{% extends "default/base.html" %} {% block content %} <div class="center"> <div class="title"><h1>searx</h1></div> - {% include 'search.html' %} + {% include 'default/search.html' %} <p class="top_margin"> <a href="{{ url_for('about') }}" class="hmarg">{{ _('about') }}</a> <a href="{{ url_for('preferences') }}" class="hmarg">{{ _('preferences') }}</a> diff --git a/searx/templates/opensearch.xml b/searx/templates/default/opensearch.xml index f39283f99..f39283f99 100644 --- a/searx/templates/opensearch.xml +++ b/searx/templates/default/opensearch.xml diff --git a/searx/templates/opensearch_response_rss.xml b/searx/templates/default/opensearch_response_rss.xml index 5673eb2e1..5673eb2e1 100644 --- a/searx/templates/opensearch_response_rss.xml +++ b/searx/templates/default/opensearch_response_rss.xml diff --git a/searx/templates/preferences.html b/searx/templates/default/preferences.html index eeb86577f..7d35de7c3 100644 --- a/searx/templates/preferences.html +++ b/searx/templates/default/preferences.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends "default/base.html" %} {% block head %} {% endblock %} {% block content %} <div class="row"> @@ -8,7 +8,7 @@ <fieldset> <legend>{{ _('Default categories') }}</legend> <p> - {% include 'categories.html' %} + {% include 'default/categories.html' %} </p> </fieldset> <fieldset> @@ -53,6 +53,16 @@ </p> </fieldset> <fieldset> + <legend>{{ _('Themes') }}</legend> + <p> + <select name="theme"> + {% for name in themes %} + <option value="{{ name }}" {% if name == theme %}selected="selected"{% endif %}>{{ name }}</option> + {% endfor %} + </select> + </p> + </fieldset> + <fieldset> <legend>{{ _('Currently used search engines') }}</legend> <table> diff --git a/searx/templates/result_templates/default.html b/searx/templates/default/result_templates/default.html index e0711b761..734f9066c 100644 --- a/searx/templates/result_templates/default.html +++ b/searx/templates/default/result_templates/default.html @@ -1,7 +1,7 @@ <div class="result {{ result.class }}"> {% if result['favicon'] %} - <img width="14" height="14" class="favicon" src="static/img/icon_{{result['favicon']}}.ico" /> + <img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result['favicon']}}.ico" /> {% endif %} <div> diff --git a/searx/templates/result_templates/images.html b/searx/templates/default/result_templates/images.html index 1f15ff2bb..1f15ff2bb 100644 --- a/searx/templates/result_templates/images.html +++ b/searx/templates/default/result_templates/images.html diff --git a/searx/templates/result_templates/torrent.html b/searx/templates/default/result_templates/torrent.html index 6c62793a5..6c62793a5 100644 --- a/searx/templates/result_templates/torrent.html +++ b/searx/templates/default/result_templates/torrent.html diff --git a/searx/templates/result_templates/videos.html b/searx/templates/default/result_templates/videos.html index ab869a6eb..8ceb0b180 100644 --- a/searx/templates/result_templates/videos.html +++ b/searx/templates/default/result_templates/videos.html @@ -1,6 +1,6 @@ <div class="result"> {% if result['favicon'] %} - <img width="14" height="14" class="favicon" src="static/img/icon_{{result['favicon']}}.ico" /> + <img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result['favicon']}}.ico" /> {% endif %} <p> diff --git a/searx/templates/results.html b/searx/templates/default/results.html index 608cfb20a..d0b53b48a 100644 --- a/searx/templates/results.html +++ b/searx/templates/default/results.html @@ -1,9 +1,9 @@ -{% extends "base.html" %} +{% extends "default/base.html" %} {% block title %}{{ q }} - {% endblock %} {% block content %} <div class="right"><a href="{{ url_for('preferences') }}" id="preferences"><span>preferences</span></a></div> <div class="small search center"> - {% include 'search.html' %} + {% include 'default/search.html' %} </div> <div id="results"> <div id="sidebar"> @@ -43,9 +43,9 @@ {% for result in results %} {% if result['template'] %} - {% include 'result_templates/'+result['template'] %} + {% include 'default/result_templates/'+result['template'] %} {% else %} - {% include 'result_templates/default.html' %} + {% include 'default/result_templates/default.html' %} {% endif %} {% endfor %} diff --git a/searx/templates/search.html b/searx/templates/default/search.html index 30d1568cf..8a9965582 100644 --- a/searx/templates/search.html +++ b/searx/templates/default/search.html @@ -3,5 +3,5 @@ <input type="text" placeholder="{{ _('Search for...') }}" id="q" class="q" name="q" tabindex="1" autocomplete="off" {% if q %}value="{{ q }}"{% endif %}/> <input type="submit" value="search" id="search_submit" /> </div> - {% include 'categories.html' %} + {% include 'default/categories.html' %} </form> diff --git a/searx/templates/stats.html b/searx/templates/default/stats.html index cb5757b31..70fe98ac7 100644 --- a/searx/templates/stats.html +++ b/searx/templates/default/stats.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends "default/base.html" %} {% block head %} {% endblock %} {% block content %} <h2>{{ _('Engine stats') }}</h2> diff --git a/searx/utils.py b/searx/utils.py index b8c7a8c6b..a9ece355a 100644 --- a/searx/utils.py +++ b/searx/utils.py @@ -1,10 +1,12 @@ -from HTMLParser import HTMLParser #import htmlentitydefs -import csv from codecs import getincrementalencoder +from HTMLParser import HTMLParser +from random import choice + import cStringIO +import csv +import os import re -from random import choice ua_versions = ('26.0', '27.0', '28.0') ua_os = ('Windows NT 6.3; WOW64', @@ -110,3 +112,17 @@ class UnicodeWriter: def writerows(self, rows): for row in rows: self.writerow(row) + + +def get_themes(root): + """Returns available themes list.""" + + static_path = os.path.join(root, 'static') + static_names = set(os.listdir(static_path)) + templates_path = os.path.join(root, 'templates') + templates_names = set(os.listdir(templates_path)) + + themes = [] + for name in static_names.intersection(templates_names): + themes += [name] + return static_path, templates_path, themes diff --git a/searx/webapp.py b/searx/webapp.py index 89d288e73..158dc35a7 100644 --- a/searx/webapp.py +++ b/searx/webapp.py @@ -38,16 +38,23 @@ from searx.engines import ( search as do_search, categories, engines, get_engines_stats, engine_shortcuts ) -from searx.utils import UnicodeWriter, highlight_content, html_to_text +from searx.utils import ( + UnicodeWriter, highlight_content, html_to_text, get_themes +) from searx.languages import language_codes from searx.search import Search from searx.autocomplete import backends as autocomplete_backends +static_path, templates_path, themes = get_themes(settings['themes_path'] if \ + settings.get('themes_path', None) else searx_dir) +default_theme = settings['default_theme'] if \ + settings.get('default_theme', None) else 'default' + app = Flask( __name__, - static_folder=os.path.join(searx_dir, 'static'), - template_folder=os.path.join(searx_dir, 'templates') + static_folder=static_path, + template_folder=templates_path ) app.secret_key = settings['server']['secret_key'] @@ -90,7 +97,30 @@ def get_base_url(): return hostname -def render(template_name, **kwargs): +def get_current_theme_name(override=None): + """Returns theme name. + + Checks in this order: + 1. override + 2. cookies + 3. settings""" + + if override and override in themes: + return override + theme_name = request.cookies.get('theme', default_theme) + if theme_name not in themes: + theme_name = default_theme + return theme_name + + +def url_for_theme(endpoint, override_theme=None, **values): + if endpoint == 'static' and values.get('filename', None): + theme_name = get_current_theme_name(override=override_theme) + values['filename'] = "{}/{}".format(theme_name, values['filename']) + return url_for(endpoint, **values) + + +def render(template_name, override_theme=None, **kwargs): blocked_engines = request.cookies.get('blocked_engines', '').split(',') autocomplete = request.cookies.get('autocomplete') @@ -125,7 +155,13 @@ def render(template_name, **kwargs): kwargs['method'] = request.cookies.get('method', 'POST') - return render_template(template_name, **kwargs) + # override url_for function in templates + kwargs['url_for'] = url_for_theme + + kwargs['theme'] = get_current_theme_name(override=override_theme) + + return render_template( + '{}/{}'.format(kwargs['theme'], template_name), **kwargs) @app.route('/search', methods=['GET', 'POST']) @@ -232,7 +268,8 @@ def index(): paging=search.paging, pageno=search.pageno, base_url=get_base_url(), - suggestions=search.suggestions + suggestions=search.suggestions, + theme=get_current_theme_name() ) @@ -290,7 +327,7 @@ def preferences(): if request.method == 'GET': blocked_engines = request.cookies.get('blocked_engines', '').split(',') - else: + else: # on save selected_categories = [] locale = None autocomplete = '' @@ -315,6 +352,8 @@ def preferences(): engine_name = pd_name.replace('engine_', '', 1) if engine_name in engines: blocked_engines.append(engine_name) + elif pd_name == 'theme': + theme = pd if pd in themes else default_theme resp = make_response(redirect(url_for('index'))) @@ -352,6 +391,9 @@ def preferences(): resp.set_cookie('method', method, max_age=cookie_max_age) + resp.set_cookie( + 'theme', theme, max_age=cookie_max_age) + return resp return render('preferences.html', locales=settings['locales'], @@ -361,7 +403,9 @@ def preferences(): categs=categories.items(), blocked_engines=blocked_engines, autocomplete_backends=autocomplete_backends, - shortcuts={y: x for x, y in engine_shortcuts.items()}) + shortcuts={y: x for x, y in engine_shortcuts.items()}, + themes=themes, + theme=get_current_theme_name()) @app.route('/stats', methods=['GET']) @@ -404,7 +448,10 @@ def opensearch(): @app.route('/favicon.ico') def favicon(): - return send_from_directory(os.path.join(app.root_path, 'static/img'), + return send_from_directory(os.path.join(app.root_path, + 'static', + get_current_theme_name(), + 'img'), 'favicon.png', mimetype='image/vnd.microsoft.icon') |