logo

searx

My custom branche(s) on searx, a meta-search engine git clone https://hacktivis.me/git/searx.git
commit: e67dfaaac7991b299dd9c33ae69e7028cd8f6589
parent 7a16aca346c14994f304a6961c55b63ab260265a
Author: Alexandre Flament <alex@al-f.net>
Date:   Fri, 27 Jan 2017 13:47:59 +0000

Merge branch 'master' into flask_perimeter

Diffstat:

Mmanage.sh4++--
Msearx/engines/google.py10++++++++++
Msearx/engines/xpath.py8++++----
Asearx/exceptions.py32++++++++++++++++++++++++++++++++
Msearx/preferences.py3++-
Msearx/results.py4++++
Msearx/search.py65++++++++++++++++++++++++++++++++++++++++++-----------------------
Msearx/settings.yml11+++++++++++
Msearx/static/themes/oscar/css/logicodev.min.css4++--
Msearx/static/themes/oscar/css/pointhi.min.css4++--
Msearx/static/themes/oscar/less/logicodev/advanced.less23-----------------------
Msearx/static/themes/oscar/less/logicodev/navbar.less98++++++++++++++++---------------------------------------------------------------
Msearx/static/themes/oscar/less/logicodev/results.less11++++++-----
Msearx/static/themes/oscar/less/logicodev/search.less24++++++++++++++++++++++++
Msearx/static/themes/oscar/less/logicodev/variables.less1+
Msearx/static/themes/oscar/less/pointhi/navbar.less42+++++++++++++++++-------------------------
Asearx/templates/__common__/about.html62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rsearx/templates/courgette/opensearch.xml -> searx/templates/__common__/opensearch.xml0
Asearx/templates/__common__/opensearch_response_rss.xml29+++++++++++++++++++++++++++++
Msearx/templates/courgette/about.html63+--------------------------------------------------------------
Dsearx/templates/courgette/opensearch_response_rss.xml23-----------------------
Msearx/templates/legacy/about.html63+--------------------------------------------------------------
Dsearx/templates/legacy/opensearch.xml28----------------------------
Dsearx/templates/legacy/opensearch_response_rss.xml23-----------------------
Msearx/templates/oscar/about.html63+--------------------------------------------------------------
Msearx/templates/oscar/advanced.html12+++++++++---
Msearx/templates/oscar/base.html5+++++
Msearx/templates/oscar/languages.html2+-
Msearx/templates/oscar/macros.html6+++---
Msearx/templates/oscar/navbar.html21++++++++-------------
Dsearx/templates/oscar/opensearch.xml28----------------------------
Dsearx/templates/oscar/opensearch_response_rss.xml23-----------------------
Msearx/templates/oscar/results.html23++++++++++++++---------
Msearx/templates/oscar/search.html18+++++++++++++++---
Msearx/templates/oscar/time-range.html2+-
Msearx/templates/pix-art/about.html63+--------------------------------------------------------------
Msearx/utils.py2++
Msearx/webapp.py77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
Mtests/unit/test_webapp.py3+++
39 files changed, 394 insertions(+), 589 deletions(-)

diff --git a/manage.sh b/manage.sh @@ -6,12 +6,12 @@ SEARX_DIR="$BASE_DIR/searx" ACTION=$1 update_packages() { - pip install --upgrade -r "$BASE_DIR/requirements.txt" + pip install -r "$BASE_DIR/requirements.txt" } update_dev_packages() { update_packages - pip install --upgrade -r "$BASE_DIR/requirements-dev.txt" + pip install -r "$BASE_DIR/requirements-dev.txt" } check_geckodriver() { diff --git a/searx/engines/google.py b/searx/engines/google.py @@ -112,6 +112,7 @@ title_xpath = './/h3' content_xpath = './/span[@class="st"]' content_misc_xpath = './/div[@class="f slp"]' suggestion_xpath = '//p[@class="_Bmc"]' +spelling_suggestion_xpath = '//a[@class="spell"]' # map : detail location map_address_xpath = './/div[@class="s"]//table//td[2]/span/text()' @@ -220,6 +221,12 @@ def response(resp): instant_answer = dom.xpath('//div[@id="_vBb"]//text()') if instant_answer: results.append({'answer': u' '.join(instant_answer)}) + try: + results_num = int(dom.xpath('//div[@id="resultStats"]//text()')[0] + .split()[1].replace(',', '')) + results.append({'number_of_results': results_num}) + except: + pass # parse results for result in dom.xpath(results_xpath): @@ -275,6 +282,9 @@ def response(resp): # append suggestion results.append({'suggestion': extract_text(suggestion)}) + for correction in dom.xpath(spelling_suggestion_xpath): + results.append({'correction': extract_text(correction)}) + # return results return results diff --git a/searx/engines/xpath.py b/searx/engines/xpath.py @@ -31,8 +31,6 @@ if xpath_results is a string element, then it's already done def extract_text(xpath_results): if type(xpath_results) == list: # it's list of result : concat everything using recursive call - if not xpath_results: - raise Exception('Empty url resultset') result = '' for e in xpath_results: result = result + extract_text(e) @@ -48,6 +46,8 @@ def extract_text(xpath_results): def extract_url(xpath_results, search_url): + if xpath_results == []: + raise Exception('Empty url resultset') url = extract_text(xpath_results) if url.startswith('//'): @@ -103,8 +103,8 @@ def response(resp): if results_xpath: for result in dom.xpath(results_xpath): url = extract_url(result.xpath(url_xpath), search_url) - title = extract_text(result.xpath(title_xpath)[0]) - content = extract_text(result.xpath(content_xpath)[0]) + title = extract_text(result.xpath(title_xpath)) + content = extract_text(result.xpath(content_xpath)) results.append({'url': url, 'title': title, 'content': content}) else: for url, title, content in zip( diff --git a/searx/exceptions.py b/searx/exceptions.py @@ -0,0 +1,32 @@ +''' +searx is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +searx is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with searx. If not, see < http://www.gnu.org/licenses/ >. + +(C) 2017- by Alexandre Flament, <alex@al-f.net> +''' + + +class SearxException(Exception): + pass + + +class SearxParameterException(SearxException): + + def __init__(self, name, value): + if value == '' or value is None: + message = 'Empty ' + name + ' parameter' + else: + message = 'Invalid value "' + value + '" for parameter ' + name + super(SearxParameterException, self).__init__(message) + self.parameter_name = name + self.parameter_value = value diff --git a/searx/preferences.py b/searx/preferences.py @@ -130,7 +130,8 @@ class MapSetting(Setting): self.key = data def save(self, name, resp): - resp.set_cookie(name, bytes(self.key), max_age=COOKIE_MAX_AGE) + if hasattr(self, 'key'): + resp.set_cookie(name, bytes(self.key), max_age=COOKIE_MAX_AGE) class SwitchableSetting(Setting): diff --git a/searx/results.py b/searx/results.py @@ -127,6 +127,7 @@ class ResultContainer(object): self.infoboxes = [] self.suggestions = set() self.answers = set() + self.corrections = set() self._number_of_results = [] self._ordered = False self.paging = False @@ -140,6 +141,9 @@ class ResultContainer(object): elif 'answer' in result: self.answers.add(result['answer']) results.remove(result) + elif 'correction' in result: + self.corrections.add(result['correction']) + results.remove(result) elif 'infobox' in result: self._merge_infobox(result) results.remove(result) diff --git a/searx/search.py b/searx/search.py @@ -31,11 +31,16 @@ from searx.query import RawTextQuery, SearchQuery from searx.results import ResultContainer from searx import logger from searx.plugins import plugins +from searx.languages import language_codes +from searx.exceptions import SearxParameterException logger = logger.getChild('search') number_of_searches = 0 +language_code_set = set(l[0].lower() for l in language_codes) +language_code_set.add('all') + def send_http_request(engine, request_params, start_time, timeout_limit): # for page_load_time stats @@ -182,33 +187,13 @@ def default_request_params(): def get_search_query_from_webapp(preferences, form): - query = None - query_engines = [] - query_categories = [] - query_pageno = 1 - query_lang = 'all' - query_time_range = None + # no text for the query ? + if not form.get('q'): + raise SearxParameterException('q', '') # set blocked engines disabled_engines = preferences.engines.get_disabled() - # set specific language if set - query_lang = preferences.get_value('language') - - # safesearch - query_safesearch = preferences.get_value('safesearch') - - # TODO better exceptions - if not form.get('q'): - raise Exception('noquery') - - # set pagenumber - pageno_param = form.get('pageno', '1') - if not pageno_param.isdigit() or int(pageno_param) < 1: - pageno_param = 1 - - query_pageno = int(pageno_param) - # parse query, if tags are set, which change # the serch engine or search-language raw_text_query = RawTextQuery(form['q'], disabled_engines) @@ -217,6 +202,13 @@ def get_search_query_from_webapp(preferences, form): # set query query = raw_text_query.getSearchQuery() + # get and check page number + pageno_param = form.get('pageno', '1') + if not pageno_param.isdigit() or int(pageno_param) < 1: + raise SearxParameterException('pageno', pageno_param) + query_pageno = int(pageno_param) + + # get language # set specific language if set on request, query or preferences # TODO support search with multible languages if len(raw_text_query.languages): @@ -226,10 +218,37 @@ def get_search_query_from_webapp(preferences, form): else: query_lang = preferences.get_value('language') + # check language + if query_lang.lower() not in language_code_set: + raise SearxParameterException('language', query_lang) + + # get safesearch + if 'safesearch' in form: + query_safesearch = form.get('safesearch') + # first check safesearch + if not query_safesearch.isdigit(): + raise SearxParameterException('safesearch', query_safesearch) + query_safesearch = int(query_safesearch) + else: + query_safesearch = preferences.get_value('safesearch') + + # safesearch : second check + if query_safesearch < 0 or query_safesearch > 2: + raise SearxParameterException('safesearch', query_safesearch) + + # get time_range query_time_range = form.get('time_range') + # check time_range + if query_time_range not in ('None', None, '', 'day', 'week', 'month', 'year'): + raise SearxParameterException('time_range', query_time_range) + + # query_engines query_engines = raw_text_query.engines + # query_categories + query_categories = [] + # if engines are calculated from query, # set categories by using that informations if query_engines and raw_text_query.specific: diff --git a/searx/settings.yml b/searx/settings.yml @@ -462,6 +462,17 @@ engines: # - ... # disabled : True + - name : semantic scholar + engine : xpath + paging : True + search_url : https://www.semanticscholar.org/search?q={query}&sort=relevance&page={pageno}&ae=false + results_xpath : //article + url_xpath : .//div[@class="search-result-title"]/a/@href + title_xpath : .//div[@class="search-result-title"]/a + content_xpath : .//div[@class="search-result-abstract"] + shortcut : se + categories : science + - name : spotify engine : spotify shortcut : stf diff --git a/searx/static/themes/oscar/css/logicodev.min.css b/searx/static/themes/oscar/css/logicodev.min.css @@ -1 +1 @@ -.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{background:#29314d;color:#01d7d4}.navbar>li>a{padding:0;margin:0}.navbar-nav>li>a{background:#29314d;padding:0 8px;margin:0;line-height:30px}.navbar,.navbar-default,.menu{background-color:#29314d;border:none;border-top:4px solid #01d7d4;padding-top:5px;color:#f6f9fa!important;font-weight:700;font-size:1.1em;text-transform:lowercase;margin-bottom:24px;height:30px;line-height:30px;z-index:10}.navbar .navbar-nav>li>a,.navbar-default .navbar-nav>li>a,.menu .navbar-nav>li>a{color:#f6f9fa}.navbar .navbar-brand,.navbar-default .navbar-brand,.menu .navbar-brand{font-weight:700;color:#01d7d4;line-height:30px;padding:0 30px;margin:0}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#01d7d4;background:#29314d}.navbar-toggle{margin-top:0}.menu{margin:0;padding:0;position:absolute;top:4px;border:0;z-index:1000000000;height:40px;line-height:40px}.menu ul{padding:0;margin:0}.menu ul li{padding:0 .6em;margin:0;float:left;list-style:none}.menu ul li a{color:#f6f9fa}.menu ul li.active a{color:#01d7d4}.menu-right{right:2em}.menu-left{left:2em}*{border-radius:0!important}html{position:relative;min-height:100%;color:#29314d}body{font-family:Roboto,Helvetica,Arial,sans-serif;margin-bottom:80px;background-color:#fff}body a{color:#08c}.footer{position:absolute;bottom:0;width:100%;height:60px;text-align:center;color:#999}input[type=checkbox]:checked+.label_hide_if_checked,input[type=checkbox]:checked+.label_hide_if_not_checked+.label_hide_if_checked{display:none}input[type=checkbox]:not(:checked)+.label_hide_if_not_checked,input[type=checkbox]:not(:checked)+.label_hide_if_checked+.label_hide_if_not_checked{display:none}.onoff-checkbox{width:15%}.onoffswitch{position:relative;width:110px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.onoffswitch-checkbox{display:none}.onoffswitch-label{display:block;overflow:hidden;cursor:pointer;border:2px solid #FFF!important;border-radius:50px!important}.onoffswitch-inner{display:block;transition:margin .3s ease-in 0s}.onoffswitch-inner:before,.onoffswitch-inner:after{display:block;float:left;width:50%;height:30px;padding:0;line-height:40px;font-size:20px;box-sizing:border-box;content:"";background-color:#EEE}.onoffswitch-switch{display:block;width:37px;background-color:#01d7d4;position:absolute;top:0;bottom:0;right:0;border:2px solid #FFF!important;border-radius:50px!important;transition:all .3s ease-in 0s}.onoffswitch-checkbox:checked+.onoffswitch-label .onoffswitch-inner{margin-right:0}.onoffswitch-checkbox:checked+.onoffswitch-label .onoffswitch-switch{right:71px;background-color:#A1A1A1}.result_header{margin-top:6px;margin-bottom:4px;font-size:16px}.result_header .favicon{margin-bottom:-3px}.result_header a{color:#29314d;text-decoration:none}.result_header a:hover{color:#08c}.result_header a:visited{color:#684898}.result_header a .highlight{background-color:#f6f9fa}.result-content{margin-top:2px;margin-bottom:0;word-wrap:break-word;color:#666;font-size:13px}.result-content .highlight{font-weight:700}.external-link,.external-link a{color:#2ecc71}.external-link a,.external-link a a{margin-right:3px}.result-default,.result-code,.result-torrent,.result-videos,.result-map{clear:both;padding:2px 4px}.result-default:hover,.result-code:hover,.result-torrent:hover,.result-videos:hover,.result-map:hover{background-color:#f6f9fa}.result-images{float:left!important;width:24%;margin:.5%}.result-images a{display:block;width:100%;background-size:cover}.img-thumbnail{margin:5px;max-height:128px;min-height:128px}.result-videos{clear:both}.result-videos hr{margin:5px 0 15px 0}.result-videos .collapse{width:100%}.result-videos .in{margin-bottom:8px}.result-torrent{clear:both}.result-torrent b{margin-right:5px;margin-left:5px}.result-torrent .seeders{color:#2ecc71}.result-torrent .leechers{color:#f35e77}.result-map{clear:both}.result-code{clear:both}.result-code .code-fork,.result-code .code-fork a{color:#666}.suggestion_item{margin:2px 5px}.result_download{margin-right:5px}#pagination{margin-top:30px;padding-bottom:60px}.label-default{color:#a4a4a4;background:0 0}.result .text-muted small{word-wrap:break-word}.modal-wrapper{box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-wrapper{background-clip:padding-box;background-color:#fff;border:1px solid rgba(0,0,0,.2);border-radius:6px;box-shadow:0 3px 9px rgba(0,0,0,.5);outline:0 none;position:relative}.infobox .panel-heading{background-color:#f6f9fa}.infobox .panel-heading .panel-title{font-weight:700}.infobox p{font-family:"DejaVu Serif",Georgia,Cambria,"Times New Roman",Times,serif!important;font-style:italic}.infobox .btn{background-color:#2ecc71;border:none}.infobox .btn a{color:#fff;margin:5px}.infobox .infobox_part{margin-bottom:20px;word-wrap:break-word;table-layout:fixed}.infobox .infobox_part:last-child{margin-bottom:0}.search_categories,#categories{text-transform:capitalize;margin-bottom:.5rem;display:flex;flex-wrap:wrap;flex-flow:row wrap;align-content:stretch}.search_categories label,#categories label,.search_categories .input-group-addon,#categories .input-group-addon{flex-grow:1;flex-basis:auto;font-size:1.2rem;font-weight:400;background-color:#fff;border:#ddd 1px solid;border-right:none;color:#666;padding-bottom:.4rem;padding-top:.4rem;text-align:center}.search_categories label:last-child,#categories label:last-child,.search_categories .input-group-addon:last-child,#categories .input-group-addon:last-child{border-right:#ddd 1px solid}.search_categories input[type=checkbox]:checked+label,#categories input[type=checkbox]:checked+label{color:#29314d;font-weight:700;border-bottom:#01d7d4 5px solid}#main-logo{margin-top:10vh;margin-bottom:25px}#main-logo>img{max-width:350px;width:80%}#q{box-shadow:none;border-right:none;border-color:#a4a4a4}#search_form .input-group-btn .btn{border-color:#a4a4a4}#search_form .input-group-btn .btn:hover{background-color:#2ecc71;color:#fff}#advanced-search-container{display:none;text-align:left;margin-bottom:1rem;clear:both}#advanced-search-container label,#advanced-search-container .input-group-addon{font-size:1.2rem;font-weight:400;background-color:#fff;border:#ddd 1px solid;border-right:none;color:#666;padding-bottom:.4rem;padding-right:.7rem;padding-left:.7rem}#advanced-search-container label:last-child,#advanced-search-container .input-group-addon:last-child{border-right:#ddd 1px solid}#advanced-search-container input[type=radio]{display:none}#advanced-search-container input[type=radio]:checked+label{color:#29314d;font-weight:700;border-bottom:#01d7d4 5px solid}#advanced-search-container select{appearance:none;-webkit-appearance:none;-moz-appearance:none;font-size:1.2rem;font-weight:400;background-color:#fff;border:#ddd 1px solid;color:#666;padding-bottom:.4rem;padding-top:.4rem;padding-left:1rem;padding-right:5rem;margin-right:.5rem;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAQAAACR313BAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAABFkAAARZAVnbJUkAAAAHdElNRQfgBxgLDwB20OFsAAAAbElEQVQY073OsQ3CMAAEwJMYwJGnsAehpoXJItltBkmcdZBYgIIiQoLglnz3ui+eP+bk5uneteTMZJa6OJuIqvYzSJoqwqBq8gdmTTW86/dghxAUq4xsVYT9laBYXCw93Aajh7GPEF23t4fkBYevGFTANkPRAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTA3LTI0VDExOjU1OjU4KzAyOjAwRFqFOQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wNy0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC) 96% no-repeat}#check-advanced{display:none}#check-advanced:checked~#advanced-search-container{display:block}.advanced{padding:0;margin-top:.3rem;text-align:right}.advanced label,.advanced select{cursor:pointer}.cursor-text{cursor:text!important}.cursor-pointer{cursor:pointer!important}pre,code{font-family:'Ubuntu Mono','Courier New','Lucida Console',monospace!important}.lineno{margin-right:5px}.highlight .hll{background-color:#ffc}.highlight{background:#f8f8f8}.highlight .c{color:#556366;font-style:italic}.highlight .err{border:1px solid #ffa92f}.highlight .k{color:#BE74D5;font-weight:700}.highlight .o{color:#d19a66}.highlight .cm{color:#556366;font-style:italic}.highlight .cp{color:#bc7a00}.highlight .c1{color:#556366;font-style:italic}.highlight .cs{color:#556366;font-style:italic}.highlight .gd{color:#a00000}.highlight .ge{font-style:italic}.highlight .gr{color:red}.highlight .gh{color:navy;font-weight:700}.highlight .gi{color:#00a000}.highlight .go{color:#888}.highlight .gp{color:navy;font-weight:700}.highlight .gs{font-weight:700}.highlight .gu{color:purple;font-weight:700}.highlight .gt{color:#04d}.highlight .kc{color:#BE74D5;font-weight:700}.highlight .kd{color:#BE74D5;font-weight:700}.highlight .kn{color:#BE74D5;font-weight:700}.highlight .kp{color:#be74d5}.highlight .kr{color:#BE74D5;font-weight:700}.highlight .kt{color:#d46c72}.highlight .m{color:#d19a66}.highlight .s{color:#86c372}.highlight .na{color:#7d9029}.highlight .nb{color:#be74d5}.highlight .nc{color:#61AFEF;font-weight:700}.highlight .no{color:#d19a66}.highlight .nd{color:#a2f}.highlight .ni{color:#999;font-weight:700}.highlight .ne{color:#D2413A;font-weight:700}.highlight .nf{color:#61afef}.highlight .nl{color:#a0a000}.highlight .nn{color:#61AFEF;font-weight:700}.highlight .nt{color:#BE74D5;font-weight:700}.highlight .nv{color:#dfc06f}.highlight .ow{color:#A2F;font-weight:700}.highlight .w{color:#d7dae0}.highlight .mf{color:#d19a66}.highlight .mh{color:#d19a66}.highlight .mi{color:#d19a66}.highlight .mo{color:#d19a66}.highlight .sb{color:#86c372}.highlight .sc{color:#86c372}.highlight .sd{color:#86C372;font-style:italic}.highlight .s2{color:#86c372}.highlight .se{color:#B62;font-weight:700}.highlight .sh{color:#86c372}.highlight .si{color:#B68;font-weight:700}.highlight .sx{color:#be74d5}.highlight .sr{color:#b68}.highlight .s1{color:#86c372}.highlight .ss{color:#dfc06f}.highlight .bp{color:#be74d5}.highlight .vc{color:#dfc06f}.highlight .vg{color:#dfc06f}.highlight .vi{color:#dfc06f}.highlight .il{color:#d19a66}.highlight .lineno{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default;color:#556366}.highlight .lineno::selection{background:0 0}.highlight .lineno::-moz-selection{background:0 0}.highlight pre{background-color:#282C34;color:#D7DAE0;border:none;margin-bottom:25px;font-size:15px;padding:20px 10px}.highlight{font-weight:700} -\ No newline at end of file +.searx-navbar{background:#29314d;height:2.3rem;font-size:1.3rem;line-height:1.3rem;padding:.5rem;font-weight:700;margin-bottom:.8rem}.searx-navbar a,.searx-navbar a:hover{margin-right:2rem;color:#fff;text-decoration:none}.searx-navbar .instance a{color:#01d7d4;margin-left:2rem}#main-logo{margin-top:20vh;margin-bottom:25px}#main-logo>img{max-width:350px;width:80%}*{border-radius:0!important}html{position:relative;min-height:100%;color:#29314d}body{font-family:Roboto,Helvetica,Arial,sans-serif;margin-bottom:80px;background-color:#fff}body a{color:#08c}.footer{position:absolute;bottom:0;width:100%;height:60px;text-align:center;color:#999}input[type=checkbox]:checked+.label_hide_if_checked,input[type=checkbox]:checked+.label_hide_if_not_checked+.label_hide_if_checked{display:none}input[type=checkbox]:not(:checked)+.label_hide_if_not_checked,input[type=checkbox]:not(:checked)+.label_hide_if_checked+.label_hide_if_not_checked{display:none}.onoff-checkbox{width:15%}.onoffswitch{position:relative;width:110px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.onoffswitch-checkbox{display:none}.onoffswitch-label{display:block;overflow:hidden;cursor:pointer;border:2px solid #FFF!important;border-radius:50px!important}.onoffswitch-inner{display:block;transition:margin .3s ease-in 0s}.onoffswitch-inner:before,.onoffswitch-inner:after{display:block;float:left;width:50%;height:30px;padding:0;line-height:40px;font-size:20px;box-sizing:border-box;content:"";background-color:#EEE}.onoffswitch-switch{display:block;width:37px;background-color:#01d7d4;position:absolute;top:0;bottom:0;right:0;border:2px solid #FFF!important;border-radius:50px!important;transition:all .3s ease-in 0s}.onoffswitch-checkbox:checked+.onoffswitch-label .onoffswitch-inner{margin-right:0}.onoffswitch-checkbox:checked+.onoffswitch-label .onoffswitch-switch{right:71px;background-color:#A1A1A1}.result_header{margin-top:0;margin-bottom:2px;font-size:16px}.result_header .favicon{margin-bottom:-3px}.result_header a{color:#29314d;text-decoration:none}.result_header a:hover{color:#08c}.result_header a:visited{color:#684898}.result_header a .highlight{background-color:#f6f9fa}.result-content{margin-top:2px;margin-bottom:0;word-wrap:break-word;color:#666;font-size:13px}.result-content .highlight{font-weight:700}.external-link{color:#069025;font-size:12px}.external-link a{margin-right:3px}.result-default,.result-code,.result-torrent,.result-videos,.result-map{clear:both;padding:2px 4px}.result-default:hover,.result-code:hover,.result-torrent:hover,.result-videos:hover,.result-map:hover{background-color:#f6f9fa}.result-images{float:left!important;width:24%;margin:.5%}.result-images a{display:block;width:100%;background-size:cover}.img-thumbnail{margin:5px;max-height:128px;min-height:128px}.result-videos{clear:both}.result-videos hr{margin:5px 0 15px 0}.result-videos .collapse{width:100%}.result-videos .in{margin-bottom:8px}.result-torrent{clear:both}.result-torrent b{margin-right:5px;margin-left:5px}.result-torrent .seeders{color:#2ecc71}.result-torrent .leechers{color:#f35e77}.result-map{clear:both}.result-code{clear:both}.result-code .code-fork,.result-code .code-fork a{color:#666}.suggestion_item{margin:2px 5px}.result_download{margin-right:5px}#pagination{margin-top:30px;padding-bottom:60px}.label-default{color:#a4a4a4;background:0 0}.result .text-muted small{word-wrap:break-word}.modal-wrapper{box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-wrapper{background-clip:padding-box;background-color:#fff;border:1px solid rgba(0,0,0,.2);border-radius:6px;box-shadow:0 3px 9px rgba(0,0,0,.5);outline:0 none;position:relative}.infobox .panel-heading{background-color:#f6f9fa}.infobox .panel-heading .panel-title{font-weight:700}.infobox p{font-family:"DejaVu Serif",Georgia,Cambria,"Times New Roman",Times,serif!important;font-style:italic}.infobox .btn{background-color:#2ecc71;border:none}.infobox .btn a{color:#fff;margin:5px}.infobox .infobox_part{margin-bottom:20px;word-wrap:break-word;table-layout:fixed}.infobox .infobox_part:last-child{margin-bottom:0}.search_categories,#categories{text-transform:capitalize;margin-bottom:.5rem;display:flex;flex-wrap:wrap;flex-flow:row wrap;align-content:stretch}.search_categories label,#categories label,.search_categories .input-group-addon,#categories .input-group-addon{flex-grow:1;flex-basis:auto;font-size:1.2rem;font-weight:400;background-color:#fff;border:#ddd 1px solid;border-right:none;color:#666;padding-bottom:.4rem;padding-top:.4rem;text-align:center}.search_categories label:last-child,#categories label:last-child,.search_categories .input-group-addon:last-child,#categories .input-group-addon:last-child{border-right:#ddd 1px solid}.search_categories input[type=checkbox]:checked+label,#categories input[type=checkbox]:checked+label{color:#29314d;font-weight:700;border-bottom:#01d7d4 5px solid}#main-logo{margin-top:10vh;margin-bottom:25px}#main-logo>img{max-width:350px;width:80%}#q{box-shadow:none;border-right:none;border-color:#a4a4a4}#search_form .input-group-btn .btn{border-color:#a4a4a4}#search_form .input-group-btn .btn:hover{background-color:#2ecc71;color:#fff}.custom-select{appearance:none;-webkit-appearance:none;-moz-appearance:none;font-size:1.2rem;font-weight:400;background-color:#fff;border:#ddd 1px solid;color:#666;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAQAAACR313BAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAABFkAAARZAVnbJUkAAAAHdElNRQfgBxgLDwB20OFsAAAAbElEQVQY073OsQ3CMAAEwJMYwJGnsAehpoXJItltBkmcdZBYgIIiQoLglnz3ui+eP+bk5uneteTMZJa6OJuIqvYzSJoqwqBq8gdmTTW86/dghxAUq4xsVYT9laBYXCw93Aajh7GPEF23t4fkBYevGFTANkPRAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTA3LTI0VDExOjU1OjU4KzAyOjAwRFqFOQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wNy0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC) 96% no-repeat}.search-margin{margin-bottom:.6em}#advanced-search-container{display:none;text-align:left;margin-bottom:1rem;clear:both}#advanced-search-container label,#advanced-search-container .input-group-addon{font-size:1.2rem;font-weight:400;background-color:#fff;border:#ddd 1px solid;border-right:none;color:#666;padding-bottom:.4rem;padding-right:.7rem;padding-left:.7rem}#advanced-search-container label:last-child,#advanced-search-container .input-group-addon:last-child{border-right:#ddd 1px solid}#advanced-search-container input[type=radio]{display:none}#advanced-search-container input[type=radio]:checked+label{color:#29314d;font-weight:700;border-bottom:#01d7d4 5px solid}#check-advanced{display:none}#check-advanced:checked~#advanced-search-container{display:block}.advanced{padding:0;margin-top:.3rem;text-align:right}.advanced label,.advanced select{cursor:pointer}.cursor-text{cursor:text!important}.cursor-pointer{cursor:pointer!important}pre,code{font-family:'Ubuntu Mono','Courier New','Lucida Console',monospace!important}.lineno{margin-right:5px}.highlight .hll{background-color:#ffc}.highlight{background:#f8f8f8}.highlight .c{color:#556366;font-style:italic}.highlight .err{border:1px solid #ffa92f}.highlight .k{color:#BE74D5;font-weight:700}.highlight .o{color:#d19a66}.highlight .cm{color:#556366;font-style:italic}.highlight .cp{color:#bc7a00}.highlight .c1{color:#556366;font-style:italic}.highlight .cs{color:#556366;font-style:italic}.highlight .gd{color:#a00000}.highlight .ge{font-style:italic}.highlight .gr{color:red}.highlight .gh{color:navy;font-weight:700}.highlight .gi{color:#00a000}.highlight .go{color:#888}.highlight .gp{color:navy;font-weight:700}.highlight .gs{font-weight:700}.highlight .gu{color:purple;font-weight:700}.highlight .gt{color:#04d}.highlight .kc{color:#BE74D5;font-weight:700}.highlight .kd{color:#BE74D5;font-weight:700}.highlight .kn{color:#BE74D5;font-weight:700}.highlight .kp{color:#be74d5}.highlight .kr{color:#BE74D5;font-weight:700}.highlight .kt{color:#d46c72}.highlight .m{color:#d19a66}.highlight .s{color:#86c372}.highlight .na{color:#7d9029}.highlight .nb{color:#be74d5}.highlight .nc{color:#61AFEF;font-weight:700}.highlight .no{color:#d19a66}.highlight .nd{color:#a2f}.highlight .ni{color:#999;font-weight:700}.highlight .ne{color:#D2413A;font-weight:700}.highlight .nf{color:#61afef}.highlight .nl{color:#a0a000}.highlight .nn{color:#61AFEF;font-weight:700}.highlight .nt{color:#BE74D5;font-weight:700}.highlight .nv{color:#dfc06f}.highlight .ow{color:#A2F;font-weight:700}.highlight .w{color:#d7dae0}.highlight .mf{color:#d19a66}.highlight .mh{color:#d19a66}.highlight .mi{color:#d19a66}.highlight .mo{color:#d19a66}.highlight .sb{color:#86c372}.highlight .sc{color:#86c372}.highlight .sd{color:#86C372;font-style:italic}.highlight .s2{color:#86c372}.highlight .se{color:#B62;font-weight:700}.highlight .sh{color:#86c372}.highlight .si{color:#B68;font-weight:700}.highlight .sx{color:#be74d5}.highlight .sr{color:#b68}.highlight .s1{color:#86c372}.highlight .ss{color:#dfc06f}.highlight .bp{color:#be74d5}.highlight .vc{color:#dfc06f}.highlight .vg{color:#dfc06f}.highlight .vi{color:#dfc06f}.highlight .il{color:#d19a66}.highlight .lineno{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default;color:#556366}.highlight .lineno::selection{background:0 0}.highlight .lineno::-moz-selection{background:0 0}.highlight pre{background-color:#282C34;color:#D7DAE0;border:none;margin-bottom:25px;font-size:15px;padding:20px 10px}.highlight{font-weight:700} +\ No newline at end of file diff --git a/searx/static/themes/oscar/css/pointhi.min.css b/searx/static/themes/oscar/css/pointhi.min.css @@ -1 +1 @@ -html{position:relative;min-height:100%}body{margin-bottom:80px}.footer{position:absolute;bottom:0;width:100%;height:60px}input[type=checkbox]:checked+.label_hide_if_checked,input[type=checkbox]:checked+.label_hide_if_not_checked+.label_hide_if_checked{display:none}input[type=checkbox]:not(:checked)+.label_hide_if_not_checked,input[type=checkbox]:not(:checked)+.label_hide_if_checked+.label_hide_if_not_checked{display:none}.onoff-checkbox{width:15%}.onoffswitch{position:relative;width:110px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.onoffswitch-checkbox{display:none}.onoffswitch-label{display:block;overflow:hidden;cursor:pointer;border:2px solid #FFF!important;border-radius:50px!important}.onoffswitch-inner{display:block;transition:margin .3s ease-in 0s}.onoffswitch-inner:before,.onoffswitch-inner:after{display:block;float:left;width:50%;height:30px;padding:0;line-height:40px;font-size:20px;box-sizing:border-box;content:"";background-color:#EEE}.onoffswitch-switch{display:block;width:37px;background-color:#0C0;position:absolute;top:0;bottom:0;right:0;border:2px solid #FFF!important;border-radius:50px!important;transition:all .3s ease-in 0s}.onoffswitch-checkbox:checked+.onoffswitch-label .onoffswitch-inner{margin-right:0}.onoffswitch-checkbox:checked+.onoffswitch-label .onoffswitch-switch{right:71px;background-color:#A1A1A1}.result_header{margin-bottom:5px;margin-top:20px}.result_header .favicon{margin-bottom:-3px}.result_header a{vertical-align:bottom}.result_header a .highlight{font-weight:700}.result-content{margin-top:5px;word-wrap:break-word}.result-content .highlight{font-weight:700}.result-default{clear:both}.result-images{float:left!important}.img-thumbnail{margin:5px;max-height:128px;min-height:128px}.result-videos{clear:both}.result-torrents{clear:both}.result-map{clear:both}.result-code{clear:both}.suggestion_item{margin:2px 5px}.result_download{margin-right:5px}#pagination{margin-top:30px;padding-bottom:50px}.label-default{color:#AAA;background:#FFF}.result .text-muted small{word-wrap:break-word}.modal-wrapper{box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-wrapper{background-clip:padding-box;background-color:#fff;border:1px solid rgba(0,0,0,.2);border-radius:6px;box-shadow:0 3px 9px rgba(0,0,0,.5);outline:0 none;position:relative}.infobox .infobox_part{margin-bottom:20px;word-wrap:break-word;table-layout:fixed}.infobox .infobox_part:last-child{margin-bottom:0}.search_categories,#categories{text-transform:capitalize;margin-bottom:1.5rem;margin-top:1.5rem;display:flex;flex-wrap:wrap;align-content:stretch}.search_categories label,#categories label,.search_categories .input-group-addon,#categories .input-group-addon{flex-grow:1;flex-basis:auto;font-size:1.3rem;font-weight:400;background-color:#fff;border:#DDD 1px solid;border-right:none;color:#333;padding-bottom:.8rem;padding-top:.8rem;text-align:center}.search_categories label:last-child,#categories label:last-child,.search_categories .input-group-addon:last-child,#categories .input-group-addon:last-child{border-right:#DDD 1px solid}.search_categories input[type=checkbox]:checked+label,#categories input[type=checkbox]:checked+label{color:#000;font-weight:700;background-color:#EEE}#advanced-search-container{display:none;text-align:center;margin-bottom:1rem;clear:both}#advanced-search-container label,#advanced-search-container .input-group-addon{font-size:1.3rem;font-weight:400;background-color:#fff;border:#DDD 1px solid;border-right:none;color:#333;padding-bottom:.8rem;padding-left:1.2rem;padding-right:1.2rem}#advanced-search-container label:last-child,#advanced-search-container .input-group-addon:last-child{border-right:#DDD 1px solid}#advanced-search-container input[type=radio]{display:none}#advanced-search-container input[type=radio]:checked+label{color:#000;font-weight:700;background-color:#EEE}#check-advanced{display:none}#check-advanced:checked~#advanced-search-container{display:block}.advanced{padding:0;margin-top:.3rem;text-align:right}.advanced label,.advanced select{cursor:pointer}.cursor-text{cursor:text!important}.cursor-pointer{cursor:pointer!important}.highlight .hll{background-color:#ffc}.highlight{background:#f8f8f8}.highlight .c{color:#408080;font-style:italic}.highlight .err{border:1px solid red}.highlight .k{color:green;font-weight:700}.highlight .o{color:#666}.highlight .cm{color:#408080;font-style:italic}.highlight .cp{color:#bc7a00}.highlight .c1{color:#408080;font-style:italic}.highlight .cs{color:#408080;font-style:italic}.highlight .gd{color:#a00000}.highlight .ge{font-style:italic}.highlight .gr{color:red}.highlight .gh{color:navy;font-weight:700}.highlight .gi{color:#00a000}.highlight .go{color:#888}.highlight .gp{color:navy;font-weight:700}.highlight .gs{font-weight:700}.highlight .gu{color:purple;font-weight:700}.highlight .gt{color:#04d}.highlight .kc{color:green;font-weight:700}.highlight .kd{color:green;font-weight:700}.highlight .kn{color:green;font-weight:700}.highlight .kp{color:green}.highlight .kr{color:green;font-weight:700}.highlight .kt{color:#b00040}.highlight .m{color:#666}.highlight .s{color:#ba2121}.highlight .na{color:#7d9029}.highlight .nb{color:green}.highlight .nc{color:#00F;font-weight:700}.highlight .no{color:#800}.highlight .nd{color:#a2f}.highlight .ni{color:#999;font-weight:700}.highlight .ne{color:#D2413A;font-weight:700}.highlight .nf{color:#00f}.highlight .nl{color:#a0a000}.highlight .nn{color:#00F;font-weight:700}.highlight .nt{color:green;font-weight:700}.highlight .nv{color:#19177c}.highlight .ow{color:#A2F;font-weight:700}.highlight .w{color:#bbb}.highlight .mf{color:#666}.highlight .mh{color:#666}.highlight .mi{color:#666}.highlight .mo{color:#666}.highlight .sb{color:#ba2121}.highlight .sc{color:#ba2121}.highlight .sd{color:#BA2121;font-style:italic}.highlight .s2{color:#ba2121}.highlight .se{color:#B62;font-weight:700}.highlight .sh{color:#ba2121}.highlight .si{color:#B68;font-weight:700}.highlight .sx{color:green}.highlight .sr{color:#b68}.highlight .s1{color:#ba2121}.highlight .ss{color:#19177c}.highlight .bp{color:green}.highlight .vc{color:#19177c}.highlight .vg{color:#19177c}.highlight .vi{color:#19177c}.highlight .il{color:#666}.highlight .lineno{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.highlight .lineno::selection{background:0 0}.highlight .lineno::-moz-selection{background:0 0}.menu{margin:0;padding:0;position:absolute;top:4px;border:0;z-index:1000000000;height:40px;line-height:40px}.menu ul{padding:0;margin:0}.menu ul li{padding:0 .6em;margin:0;float:left;list-style:none}.menu-right{right:2em}.menu-left{left:2em} -\ No newline at end of file +html{position:relative;min-height:100%}body{margin-bottom:80px}.footer{position:absolute;bottom:0;width:100%;height:60px}input[type=checkbox]:checked+.label_hide_if_checked,input[type=checkbox]:checked+.label_hide_if_not_checked+.label_hide_if_checked{display:none}input[type=checkbox]:not(:checked)+.label_hide_if_not_checked,input[type=checkbox]:not(:checked)+.label_hide_if_checked+.label_hide_if_not_checked{display:none}.onoff-checkbox{width:15%}.onoffswitch{position:relative;width:110px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.onoffswitch-checkbox{display:none}.onoffswitch-label{display:block;overflow:hidden;cursor:pointer;border:2px solid #FFF!important;border-radius:50px!important}.onoffswitch-inner{display:block;transition:margin .3s ease-in 0s}.onoffswitch-inner:before,.onoffswitch-inner:after{display:block;float:left;width:50%;height:30px;padding:0;line-height:40px;font-size:20px;box-sizing:border-box;content:"";background-color:#EEE}.onoffswitch-switch{display:block;width:37px;background-color:#0C0;position:absolute;top:0;bottom:0;right:0;border:2px solid #FFF!important;border-radius:50px!important;transition:all .3s ease-in 0s}.onoffswitch-checkbox:checked+.onoffswitch-label .onoffswitch-inner{margin-right:0}.onoffswitch-checkbox:checked+.onoffswitch-label .onoffswitch-switch{right:71px;background-color:#A1A1A1}.result_header{margin-bottom:5px;margin-top:20px}.result_header .favicon{margin-bottom:-3px}.result_header a{vertical-align:bottom}.result_header a .highlight{font-weight:700}.result-content{margin-top:5px;word-wrap:break-word}.result-content .highlight{font-weight:700}.result-default{clear:both}.result-images{float:left!important}.img-thumbnail{margin:5px;max-height:128px;min-height:128px}.result-videos{clear:both}.result-torrents{clear:both}.result-map{clear:both}.result-code{clear:both}.suggestion_item{margin:2px 5px}.result_download{margin-right:5px}#pagination{margin-top:30px;padding-bottom:50px}.label-default{color:#AAA;background:#FFF}.result .text-muted small{word-wrap:break-word}.modal-wrapper{box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-wrapper{background-clip:padding-box;background-color:#fff;border:1px solid rgba(0,0,0,.2);border-radius:6px;box-shadow:0 3px 9px rgba(0,0,0,.5);outline:0 none;position:relative}.infobox .infobox_part{margin-bottom:20px;word-wrap:break-word;table-layout:fixed}.infobox .infobox_part:last-child{margin-bottom:0}.search_categories,#categories{text-transform:capitalize;margin-bottom:1.5rem;margin-top:1.5rem;display:flex;flex-wrap:wrap;align-content:stretch}.search_categories label,#categories label,.search_categories .input-group-addon,#categories .input-group-addon{flex-grow:1;flex-basis:auto;font-size:1.3rem;font-weight:400;background-color:#fff;border:#DDD 1px solid;border-right:none;color:#333;padding-bottom:.8rem;padding-top:.8rem;text-align:center}.search_categories label:last-child,#categories label:last-child,.search_categories .input-group-addon:last-child,#categories .input-group-addon:last-child{border-right:#DDD 1px solid}.search_categories input[type=checkbox]:checked+label,#categories input[type=checkbox]:checked+label{color:#000;font-weight:700;background-color:#EEE}#advanced-search-container{display:none;text-align:center;margin-bottom:1rem;clear:both}#advanced-search-container label,#advanced-search-container .input-group-addon{font-size:1.3rem;font-weight:400;background-color:#fff;border:#DDD 1px solid;border-right:none;color:#333;padding-bottom:.8rem;padding-left:1.2rem;padding-right:1.2rem}#advanced-search-container label:last-child,#advanced-search-container .input-group-addon:last-child{border-right:#DDD 1px solid}#advanced-search-container input[type=radio]{display:none}#advanced-search-container input[type=radio]:checked+label{color:#000;font-weight:700;background-color:#EEE}#check-advanced{display:none}#check-advanced:checked~#advanced-search-container{display:block}.advanced{padding:0;margin-top:.3rem;text-align:right}.advanced label,.advanced select{cursor:pointer}.cursor-text{cursor:text!important}.cursor-pointer{cursor:pointer!important}.highlight .hll{background-color:#ffc}.highlight{background:#f8f8f8}.highlight .c{color:#408080;font-style:italic}.highlight .err{border:1px solid red}.highlight .k{color:green;font-weight:700}.highlight .o{color:#666}.highlight .cm{color:#408080;font-style:italic}.highlight .cp{color:#bc7a00}.highlight .c1{color:#408080;font-style:italic}.highlight .cs{color:#408080;font-style:italic}.highlight .gd{color:#a00000}.highlight .ge{font-style:italic}.highlight .gr{color:red}.highlight .gh{color:navy;font-weight:700}.highlight .gi{color:#00a000}.highlight .go{color:#888}.highlight .gp{color:navy;font-weight:700}.highlight .gs{font-weight:700}.highlight .gu{color:purple;font-weight:700}.highlight .gt{color:#04d}.highlight .kc{color:green;font-weight:700}.highlight .kd{color:green;font-weight:700}.highlight .kn{color:green;font-weight:700}.highlight .kp{color:green}.highlight .kr{color:green;font-weight:700}.highlight .kt{color:#b00040}.highlight .m{color:#666}.highlight .s{color:#ba2121}.highlight .na{color:#7d9029}.highlight .nb{color:green}.highlight .nc{color:#00F;font-weight:700}.highlight .no{color:#800}.highlight .nd{color:#a2f}.highlight .ni{color:#999;font-weight:700}.highlight .ne{color:#D2413A;font-weight:700}.highlight .nf{color:#00f}.highlight .nl{color:#a0a000}.highlight .nn{color:#00F;font-weight:700}.highlight .nt{color:green;font-weight:700}.highlight .nv{color:#19177c}.highlight .ow{color:#A2F;font-weight:700}.highlight .w{color:#bbb}.highlight .mf{color:#666}.highlight .mh{color:#666}.highlight .mi{color:#666}.highlight .mo{color:#666}.highlight .sb{color:#ba2121}.highlight .sc{color:#ba2121}.highlight .sd{color:#BA2121;font-style:italic}.highlight .s2{color:#ba2121}.highlight .se{color:#B62;font-weight:700}.highlight .sh{color:#ba2121}.highlight .si{color:#B68;font-weight:700}.highlight .sx{color:green}.highlight .sr{color:#b68}.highlight .s1{color:#ba2121}.highlight .ss{color:#19177c}.highlight .bp{color:green}.highlight .vc{color:#19177c}.highlight .vg{color:#19177c}.highlight .vi{color:#19177c}.highlight .il{color:#666}.highlight .lineno{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.highlight .lineno::selection{background:0 0}.highlight .lineno::-moz-selection{background:0 0}.searx-navbar{background:#eee;color:#aaa;height:2.3rem;font-size:1.3rem;line-height:1.3rem;padding:.5rem;font-weight:700;margin-bottom:1.3rem}.searx-navbar a,.searx-navbar a:hover{margin-right:2rem;text-decoration:none}.searx-navbar .instance a{color:#444;margin-left:2rem} +\ No newline at end of file diff --git a/searx/static/themes/oscar/less/logicodev/advanced.less b/searx/static/themes/oscar/less/logicodev/advanced.less @@ -29,29 +29,6 @@ font-weight: bold; border-bottom: @light-green 5px solid; } - select { - appearance: none; - -webkit-appearance: none; - -moz-appearance: none; - font-size: 1.2rem; - font-weight:normal; - background-color: white; - border: @mild-gray 1px solid; - color: @dark-gray; - padding-bottom: 0.4rem; - padding-top: 0.4rem; - padding-left: 1rem; - padding-right: 5rem; - margin-right: 0.5rem; - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAQAAACR313BAAAABGdBTUEAALGPC/xhBQAAACBjSFJN -AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZ -cwAABFkAAARZAVnbJUkAAAAHdElNRQfgBxgLDwB20OFsAAAAbElEQVQY073OsQ3CMAAEwJMYwJGn -sAehpoXJItltBkmcdZBYgIIiQoLglnz3ui+eP+bk5uneteTMZJa6OJuIqvYzSJoqwqBq8gdmTTW8 -6/dghxAUq4xsVYT9laBYXCw93Aajh7GPEF23t4fkBYevGFTANkPRAAAAJXRFWHRkYXRlOmNyZWF0 -ZQAyMDE2LTA3LTI0VDExOjU1OjU4KzAyOjAwRFqFOQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0w -Ny0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb -7jwaAAAAAElFTkSuQmCC) 96% no-repeat; - } } #check-advanced { diff --git a/searx/static/themes/oscar/less/logicodev/navbar.less b/searx/static/themes/oscar/less/logicodev/navbar.less @@ -1,89 +1,31 @@ -.navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus{ +.searx-navbar { background: @black; - color: @light-green; -} - -.navbar > li > a { - padding: 0; - margin: 0; -} - -.navbar-nav > li > a { - background: @black; - padding: 0 8px; - margin: 0; - line-height: 30px; -} - -.navbar, .navbar-default, .menu { - background-color: @black; - border: none; - border-top: 4px solid @light-green; - padding-top: 5px; - color: @dim-gray !important; - font-weight: 700; - font-size: 1.1em; - text-transform: lowercase; - margin-bottom: 24px; - height: 30px; - line-height: 30px; - - .navbar-nav > li > a{ - color: @dim-gray; + height: 2.3rem; + font-size: 1.3rem; + line-height: 1.3rem; + padding: 0.5rem; + font-weight: bold; + margin-bottom: 0.8rem; + + a, a:hover { + margin-right: 2.0rem; + color: white; + text-decoration: none; } - .navbar-brand{ - font-weight: 700; + .instance a { color: @light-green; - line-height: 30px; - padding: 0 30px; - margin: 0; + margin-left: 2.0rem; } - z-index: 10; } -// Hover color -// http://stackoverflow.com/users/114029/leniel-macaferi -.navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { - color: @light-green; - background: @black; -} - -.navbar-toggle { - margin-top: 0; -} +#main-logo { + margin-top: 20vh; + margin-bottom: 25px; -.menu { - margin: 0; - padding: 0; - position: absolute; - top: 4px; - border: 0; - z-index: 1000000000; - height: 40px; - line-height: 40px; - ul { - padding: 0; - margin: 0; - li { - padding: 0 0.6em; - margin: 0; - float: left; - list-style: none; - a { - color: @dim-gray; - } - } - li.active a { - color: @light-green; - } + & > img { + max-width: 350px; + width: 80%; } } -.menu-right { - right: 2em; -} - -.menu-left { - left: 2em; -} diff --git a/searx/static/themes/oscar/less/logicodev/results.less b/searx/static/themes/oscar/less/logicodev/results.less @@ -1,6 +1,6 @@ .result_header { - margin-top: 6px; - margin-bottom: 4px; + margin-top: 0px; + margin-bottom: 2px; font-size: 16px; .favicon { @@ -41,10 +41,11 @@ } -.external-link, .external-link a{ - color: @green; +.external-link { + color: @dark-green; + font-size: 12px; - a{ + a { margin-right: 3px; } } diff --git a/searx/static/themes/oscar/less/logicodev/search.less b/searx/static/themes/oscar/less/logicodev/search.less @@ -54,3 +54,26 @@ background-color: @green; color: white; } + +.custom-select { + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + font-size: 1.2rem; + font-weight:normal; + background-color: white; + border: @mild-gray 1px solid; + color: @dark-gray; + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAQAAACR313BAAAABGdBTUEAALGPC/xhBQAAACBjSFJN +AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZ +cwAABFkAAARZAVnbJUkAAAAHdElNRQfgBxgLDwB20OFsAAAAbElEQVQY073OsQ3CMAAEwJMYwJGn +sAehpoXJItltBkmcdZBYgIIiQoLglnz3ui+eP+bk5uneteTMZJa6OJuIqvYzSJoqwqBq8gdmTTW8 +6/dghxAUq4xsVYT9laBYXCw93Aajh7GPEF23t4fkBYevGFTANkPRAAAAJXRFWHRkYXRlOmNyZWF0 +ZQAyMDE2LTA3LTI0VDExOjU1OjU4KzAyOjAwRFqFOQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0w +Ny0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb +7jwaAAAAAElFTkSuQmCC) 96% no-repeat; +} + +.search-margin { + margin-bottom: 0.6em; +} +\ No newline at end of file diff --git a/searx/static/themes/oscar/less/logicodev/variables.less b/searx/static/themes/oscar/less/logicodev/variables.less @@ -7,6 +7,7 @@ @blue: #0088CC; @red: #F35E77; @violet: #684898; +@dark-green: #069025; @green: #2ecc71; @light-green: #01D7D4; @orange: #FFA92F; diff --git a/searx/static/themes/oscar/less/pointhi/navbar.less b/searx/static/themes/oscar/less/pointhi/navbar.less @@ -1,28 +1,20 @@ -.menu { - margin: 0; - padding: 0; - position: absolute; - top: 4px; - border: 0; - z-index: 1000000000; - height: 40px; - line-height: 40px; - ul { - padding: 0; - margin: 0; - li { - padding: 0 0.6em; - margin: 0; - float: left; - list-style: none; - } - } -} +.searx-navbar { + background: #eee; + color: #aaa; + height: 2.3rem; + font-size: 1.3rem; + line-height: 1.3rem; + padding: 0.5rem; + font-weight: bold; + margin-bottom: 1.3rem; -.menu-right { - right: 2em; -} + a, a:hover { + margin-right: 2.0rem; + text-decoration: none; + } -.menu-left { - left: 2em; + .instance a { + color: #444; + margin-left: 2.0rem; + } } diff --git a/searx/templates/__common__/about.html b/searx/templates/__common__/about.html @@ -0,0 +1,62 @@ +<div{% if rtl %} dir="ltr"{% endif %}> + <h1>About <a href="{{ url_for('index') }}">searx</a></h1> + + <p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, aggregating the results of other <a href="{{ url_for('preferences') }}">search engines</a> while not storing information about its users. + </p> + <h2>Why use searx?</h2> + <ul> + <li>searx may not offer you as personalised results as Google, but it doesn't generate a profile about you</li> + <li>searx doesn't care about what you search for, never shares anything with a third party, and it can't be used to compromise you</li> + <li>searx is free software, the code is 100% open and you can help to make it better. See more on <a href="https://github.com/asciimoo/searx">github</a></li> + </ul> + <p>If you do care about privacy, want to be a conscious user, or otherwise believe + in digital freedom, make searx your default search engine or run it on your own server</p> + +<h2>Technical details - How does it work?</h2> + +<p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, +inspired by the <a href="https://beniz.github.io/seeks/">seeks project</a>.<br /> +It provides basic privacy by mixing your queries with searches on other platforms without storing search data. Queries are made using a POST request on every browser (except chrome*). Therefore they show up in neither our logs, nor your url history. In case of Chrome* users there is an exception, searx uses the search bar to perform GET requests.<br /> +Searx can be added to your browser's search bar; moreover, it can be set as the default search engine. +</p> + +<h2>How can I make it my own?</h2> + +<p>Searx appreciates your concern regarding logs, so take the <a href="https://github.com/asciimoo/searx">code</a> and run it yourself! <br />Add your Searx to this <a href="https://github.com/asciimoo/searx/wiki/Searx-instances">list</a> to help other people reclaim their privacy and make the Internet freer! +<br />The more decentralized the Internet is, the more freedom we have!</p> + + +<h2>More about searx</h2> + +<ul> + <li><a href="https://github.com/asciimoo/searx">github</a></li> + <li><a href="https://www.ohloh.net/p/searx/">ohloh</a></li> + <li><a href="https://twitter.com/Searx_engine">twitter</a></li> + <li>IRC: #searx @ freenode (<a href="https://kiwiirc.com/client/irc.freenode.com/searx">webclient</a>)</li> + <li><a href="https://www.transifex.com/projects/p/searx/">transifex</a></li> +</ul> + + +<hr /> + +<h2 id="faq">FAQ</h2> + +<h3>How to add to firefox?</h3> +<p><a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a> searx as a search engine on any version of Firefox! (javascript required)</p> + +<h2 id="dev_faq">Developer FAQ</h2> + +<h3>New engines?</h3> +<ul> + <li>Edit your <a href="https://raw.github.com/asciimoo/searx/master/searx/settings.yml">settings.yml</a></li> + <li>Create your custom engine module, check the <a href="https://github.com/asciimoo/searx/blob/master/examples/basic_engine.py">example engine</a></li> +</ul> +<p>Don't forget to restart searx after config edit!</p> + +<h3>Installation/WSGI support?</h3> +<p>See the <a href="https://github.com/asciimoo/searx/wiki/Installation">installation and setup</a> wiki page</p> + +<h3>How to debug engines?</h3> +<p><a href="{{ url_for('stats') }}">Stats page</a> contains some useful data about the engines used.</p> + +</div> diff --git a/searx/templates/courgette/opensearch.xml b/searx/templates/__common__/opensearch.xml diff --git a/searx/templates/__common__/opensearch_response_rss.xml b/searx/templates/__common__/opensearch_response_rss.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<rss version="2.0" + xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" + xmlns:atom="http://www.w3.org/2005/Atom"> + <channel> + <title>Searx search: {{ q|e }}</title> + <link>{{ base_url }}?q={{ q|e }}</link> + <description>Search results for "{{ q|e }}" - searx</description> + <opensearch:totalResults>{{ number_of_results }}</opensearch:totalResults> + <opensearch:startIndex>1</opensearch:startIndex> + <opensearch:itemsPerPage>{{ number_of_results }}</opensearch:itemsPerPage> + <atom:link rel="search" type="application/opensearchdescription+xml" href="{{ base_url }}opensearch.xml"/> + <opensearch:Query role="request" searchTerms="{{ q|e }}" startPage="1" /> + {% if error_message %} + <item> + <title>Error</title> + <description>{{ error_message|e }}</description> + </item> + {% endif %} + {% for r in results %} + <item> + <title>{{ r.title }}</title> + <link>{{ r.url }}</link> + <description>{{ r.content }}</description> + {% if r.pubdate %}<pubDate>{{ r.pubdate }}</pubDate>{% endif %} + </item> + {% endfor %} + </channel> +</rss> diff --git a/searx/templates/courgette/about.html b/searx/templates/courgette/about.html @@ -1,66 +1,5 @@ {% extends 'courgette/base.html' %} {% block content %} {% include 'courgette/github_ribbon.html' %} -<div class="row"{% if rtl %} dir="ltr"{% endif %}> - <h1>About <a href="{{ url_for('index') }}">searx</a></h1> - - <p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, aggregating the results of other <a href="{{ url_for('preferences') }}">search engines</a> while not storing information about its users. - </p> - <h2>Why use searx?</h2> - <ul> - <li>searx may not offer you as personalised results as Google, but it doesn't generate a profile about you</li> - <li>searx doesn't care about what you search for, never shares anything with a third party, and it can't be used to compromise you</li> - <li>searx is free software, the code is 100% open and you can help to make it better. See more on <a href="https://github.com/asciimoo/searx">github</a></li> - </ul> - <p>If you do care about privacy, want to be a conscious user, or otherwise believe - in digital freedom, make searx your default search engine or run it on your own server</p> - -<h2>Technical details - How does it work?</h2> - -<p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, -inspired by the <a href="https://beniz.github.io/seeks/">seeks project</a>.<br /> -It provides basic privacy by mixing your queries with searches on other platforms without storing search data. Queries are made using a POST request on every browser (except chrome*). Therefore they show up in neither our logs, nor your url history. In case of Chrome* users there is an exception, searx uses the search bar to perform GET requests.<br /> -Searx can be added to your browser's search bar; moreover, it can be set as the default search engine. -</p> - -<h2>How can I make it my own?</h2> - -<p>Searx appreciates your concern regarding logs, so take the <a href="https://github.com/asciimoo/searx">code</a> and run it yourself! <br />Add your Searx to this <a href="https://github.com/asciimoo/searx/wiki/Searx-instances">list</a> to help other people reclaim their privacy and make the Internet freer! -<br />The more decentralized the Internet, is the more freedom we have!</p> - - -<h2>More about searx</h2> - -<ul> - <li><a href="https://github.com/asciimoo/searx">github</a></li> - <li><a href="https://www.ohloh.net/p/searx/">ohloh</a></li> - <li><a href="https://twitter.com/Searx_engine">twitter</a></li> - <li>IRC: #searx @ freenode (<a href="https://kiwiirc.com/client/irc.freenode.com/searx">webclient</a>)</li> - <li><a href="https://www.transifex.com/projects/p/searx/">transifex</a></li> -</ul> - - -<hr /> - -<h2 id="faq">FAQ</h2> - -<h3>How to add to firefox?</h3> -<p><a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a> searx as a search engine on any version of Firefox! (javascript required)</p> - -<h2 id="dev_faq">Developer FAQ</h2> - -<h3>New engines?</h3> -<ul> - <li>Edit your <a href="https://raw.github.com/asciimoo/searx/master/searx/settings.yml">settings.yml</a></li> - <li>Create your custom engine module, check the <a href="https://github.com/asciimoo/searx/blob/master/examples/basic_engine.py">example engine</a></li> -</ul> -<p>Don't forget to restart searx after config edit!</p> - -<h3>Installation/WSGI support?</h3> -<p>See the <a href="https://github.com/asciimoo/searx/wiki/Installation">installation and setup</a> wiki page</p> - -<h3>How to debug engines?</h3> -<p><a href="{{ url_for('stats') }}">Stats page</a> contains some useful data about the engines used.</p> - -</div> +{% include '__common__/about.html' %} {% endblock %} diff --git a/searx/templates/courgette/opensearch_response_rss.xml b/searx/templates/courgette/opensearch_response_rss.xml @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<rss version="2.0" - xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" - xmlns:atom="http://www.w3.org/2005/Atom"> - <channel> - <title>Searx search: {{ q|e }}</title> - <link>{{ base_url }}?q={{ q|e }}</link> - <description>Search results for "{{ q|e }}" - searx</description> - <opensearch:totalResults>{{ number_of_results }}</opensearch:totalResults> - <opensearch:startIndex>1</opensearch:startIndex> - <opensearch:itemsPerPage>{{ number_of_results }}</opensearch:itemsPerPage> - <atom:link rel="search" type="application/opensearchdescription+xml" href="{{ base_url }}opensearch.xml"/> - <opensearch:Query role="request" searchTerms="{{ q|e }}" startPage="1" /> - {% for r in results %} - <item> - <title>{{ r.title }}</title> - <link>{{ r.url }}</link> - <description>{{ r.content }}</description> - {% if r.pubdate %}<pubDate>{{ r.pubdate }}</pubDate>{% endif %} - </item> - {% endfor %} - </channel> -</rss> diff --git a/searx/templates/legacy/about.html b/searx/templates/legacy/about.html @@ -1,66 +1,5 @@ {% extends 'legacy/base.html' %} {% block content %} {% include 'legacy/github_ribbon.html' %} -<div class="row"{% if rtl %} dir="ltr"{% endif %}> - <h1>About <a href="{{ url_for('index') }}">searx</a></h1> - - <p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, aggregating the results of other <a href="{{ url_for('preferences') }}">search engines</a> while not storing information about its users. - </p> - <h2>Why use searx?</h2> - <ul> - <li>searx may not offer you as personalised results as Google, but it doesn't generate a profile about you</li> - <li>searx doesn't care about what you search for, never shares anything with a third party, and it can't be used to compromise you</li> - <li>searx is free software, the code is 100% open and you can help to make it better. See more on <a href="https://github.com/asciimoo/searx">github</a></li> - </ul> - <p>If you do care about privacy, want to be a conscious user, or otherwise believe - in digital freedom, make searx your default search engine or run it on your own server</p> - -<h2>Technical details - How does it work?</h2> - -<p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, -inspired by the <a href="https://beniz.github.io/seeks/">seeks project</a>.<br /> -It provides basic privacy by mixing your queries with searches on other platforms without storing search data. Queries are made using a POST request on every browser (except chrome*). Therefore they show up in neither our logs, nor your url history. In case of Chrome* users there is an exception, if searx used from the search bar it performs GET requests.<br /> -Searx can be added to your browser's search bar; moreover, it can be set as the default search engine. -</p> - -<h2>How can I make it my own?</h2> - -<p>Searx appreciates your concern regarding logs, so take the <a href="https://github.com/asciimoo/searx">code</a> and run it yourself! <br />Add your Searx to this <a href="https://github.com/asciimoo/searx/wiki/Searx-instances">list</a> to help other people reclaim their privacy and make the Internet freer! -<br />The more decentralized Internet is the more freedom we have!</p> - - -<h2>More about searx</h2> - -<ul> - <li><a href="https://github.com/asciimoo/searx">github</a></li> - <li><a href="https://www.ohloh.net/p/searx/">ohloh</a></li> - <li><a href="https://twitter.com/Searx_engine">twitter</a></li> - <li>IRC: #searx @ freenode (<a href="https://kiwiirc.com/client/irc.freenode.com/searx">webclient</a>)</li> - <li><a href="https://www.transifex.com/projects/p/searx/">transifex</a></li> -</ul> - - -<hr /> - -<h2 id="faq">FAQ</h2> - -<h3>How to add to firefox?</h3> -<p><a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a> searx as a search engine on any version of Firefox! (javascript required)</p> - -<h2 id="dev_faq">Developer FAQ</h2> - -<h3>New engines?</h3> -<ul> - <li>Edit your <a href="https://raw.github.com/asciimoo/searx/master/searx/settings.yml">settings.yml</a></li> - <li>Create your custom engine module, check the <a href="https://github.com/asciimoo/searx/blob/master/examples/basic_engine.py">example engine</a></li> -</ul> -<p>Don't forget to restart searx after config edit!</p> - -<h3>Installation/WSGI support?</h3> -<p>See the <a href="https://github.com/asciimoo/searx/wiki/Installation">installation and setup</a> wiki page</p> - -<h3>How to debug engines?</h3> -<p><a href="{{ url_for('stats') }}">Stats page</a> contains some useful data about the engines used.</p> - -</div> +{% include '__common__/about.html' %} {% endblock %} diff --git a/searx/templates/legacy/opensearch.xml b/searx/templates/legacy/opensearch.xml @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"> - <ShortName>{{ instance_name }}</ShortName> - <Description>a privacy-respecting, hackable metasearch engine</Description> - <InputEncoding>UTF-8</InputEncoding> - <Image>{{ urljoin(host, url_for('static', filename='img/favicon.png')) }}</Image> - <LongName>searx metasearch</LongName> - {% if opensearch_method == 'get' %} - <Url type="text/html" method="get" template="{{ host }}search?q={searchTerms}"/> - {% if autocomplete %} - <Url type="application/x-suggestions+json" method="get" template="{{ host }}autocompleter"> - <Param name="format" value="x-suggestions" /> - <Param name="q" value="{searchTerms}" /> - </Url> - {% endif %} - {% else %} - <Url type="text/html" method="post" template="{{ host }}"> - <Param name="q" value="{searchTerms}" /> - </Url> - {% if autocomplete %} - <!-- TODO, POST REQUEST doesn't work --> - <Url type="application/x-suggestions+json" method="get" template="{{ host }}autocompleter"> - <Param name="format" value="x-suggestions" /> - <Param name="q" value="{searchTerms}" /> - </Url> - {% endif %} - {% endif %} -</OpenSearchDescription> diff --git a/searx/templates/legacy/opensearch_response_rss.xml b/searx/templates/legacy/opensearch_response_rss.xml @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<rss version="2.0" - xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" - xmlns:atom="http://www.w3.org/2005/Atom"> - <channel> - <title>Searx search: {{ q|e }}</title> - <link>{{ base_url }}?q={{ q|e }}</link> - <description>Search results for "{{ q|e }}" - searx</description> - <opensearch:totalResults>{{ number_of_results }}</opensearch:totalResults> - <opensearch:startIndex>1</opensearch:startIndex> - <opensearch:itemsPerPage>{{ number_of_results }}</opensearch:itemsPerPage> - <atom:link rel="search" type="application/opensearchdescription+xml" href="{{ base_url }}opensearch.xml"/> - <opensearch:Query role="request" searchTerms="{{ q|e }}" startPage="1" /> - {% for r in results %} - <item> - <title>{{ r.title }}</title> - <link>{{ r.url }}</link> - <description>{{ r.content }}</description> - {% if r.pubdate %}<pubDate>{{ r.pubdate }}</pubDate>{% endif %} - </item> - {% endfor %} - </channel> -</rss> diff --git a/searx/templates/oscar/about.html b/searx/templates/oscar/about.html @@ -1,66 +1,5 @@ {% extends "oscar/base.html" %} {% block title %}{{ _('about') }} - {% endblock %} {% block content %} -<div{% if rtl %} dir="ltr"{% endif %}> - <h1>About <a href="{{ url_for('index') }}">searx</a></h1> - - <p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, aggregating the results of other <a href="{{ url_for('preferences') }}">search engines</a> while not storing information about its users. - </p> - <h2>Why use searx?</h2> - <ul> - <li>searx may not offer you as personalised results as Google, but it doesn't generate a profile about you</li> - <li>searx doesn't care about what you search for, never shares anything with a third party, and it can't be used to compromise you</li> - <li>searx is free software, the code is 100% open and you can help to make it better. See more on <a href="https://github.com/asciimoo/searx">github</a></li> - </ul> - <p>If you do care about privacy, want to be a conscious user, or otherwise believe - in digital freedom, make searx your default search engine or run it on your own server</p> - -<h2>Technical details - How does it work?</h2> - -<p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, -inspired by the <a href="https://beniz.github.io/seeks/">seeks project</a>.<br /> -It provides basic privacy by mixing your queries with searches on other platforms without storing search data. Queries are made using a POST request on every browser (except chrome*). Therefore they show up in neither our logs, nor your url history. In case of Chrome* users there is an exception, searx uses the search bar to perform GET requests.<br /> -Searx can be added to your browser's search bar; moreover, it can be set as the default search engine. -</p> - -<h2>How can I make it my own?</h2> - -<p>Searx appreciates your concern regarding logs, so take the <a href="https://github.com/asciimoo/searx">code</a> and run it yourself! <br />Add your Searx to this <a href="https://github.com/asciimoo/searx/wiki/Searx-instances">list</a> to help other people reclaim their privacy and make the Internet freer! -<br />The more decentralized the Internet is, the more freedom we have!</p> - - -<h2>More about searx</h2> - -<ul> - <li><a href="https://github.com/asciimoo/searx">github</a></li> - <li><a href="https://www.ohloh.net/p/searx/">ohloh</a></li> - <li><a href="https://twitter.com/Searx_engine">twitter</a></li> - <li>IRC: #searx @ freenode (<a href="https://kiwiirc.com/client/irc.freenode.com/searx">webclient</a>)</li> - <li><a href="https://www.transifex.com/projects/p/searx/">transifex</a></li> -</ul> - - -<hr /> - -<h2 id="faq">FAQ</h2> - -<h3>How to add to firefox?</h3> -<p><a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a> searx as a search engine on any version of Firefox! (javascript required)</p> - -<h2 id="dev_faq">Developer FAQ</h2> - -<h3>New engines?</h3> -<ul> - <li>Edit your <a href="https://raw.github.com/asciimoo/searx/master/searx/settings.yml">settings.yml</a></li> - <li>Create your custom engine module, check the <a href="https://github.com/asciimoo/searx/blob/master/examples/basic_engine.py">example engine</a></li> -</ul> -<p>Don't forget to restart searx after config edit!</p> - -<h3>Installation/WSGI support?</h3> -<p>See the <a href="https://github.com/asciimoo/searx/wiki/Installation">installation and setup</a> wiki page</p> - -<h3>How to debug engines?</h3> -<p><a href="{{ url_for('stats') }}">Stats page</a> contains some useful data about the engines used.</p> - -</div> +{% include '__common__/about.html' %} {% endblock %} diff --git a/searx/templates/oscar/advanced.html b/searx/templates/oscar/advanced.html @@ -4,7 +4,13 @@ {{ _('Advanced settings') }} </label> <div id="advanced-search-container"> - {% include 'oscar/categories.html' %} - {% include 'oscar/time-range.html' %} - {% include 'oscar/languages.html' %} + {% include 'oscar/categories.html' %} + <div class="row"> + <div class="col-xs-6"> + {% include 'oscar/time-range.html' %} + </div> + <div class="col-xs-6"> + {% include 'oscar/languages.html' %} + </div> + </div> </div> diff --git a/searx/templates/oscar/base.html b/searx/templates/oscar/base.html @@ -98,5 +98,10 @@ {% for script in scripts %} <script src="{{ url_for('static', filename=script) }}"></script> {% endfor %} + <noscript> + <style> + .glyphicon { display: none; } + </style> + </noscript> </body> </html> diff --git a/searx/templates/oscar/languages.html b/searx/templates/oscar/languages.html @@ -1,7 +1,7 @@ {% if preferences %} <select class="form-control" name='language'> {% else %} -<select class="time_range" id='language' name='language'> +<select class="time_range custom-select form-control" id='language' name='language'> {% endif %} <option value="all" {% if current_language == 'all' %}selected="selected"{% endif %}>{{ _('Default language') }}</option> {% for lang_id,lang_name,country_name,english_name in language_codes | sort(attribute=1) %} diff --git a/searx/templates/oscar/macros.html b/searx/templates/oscar/macros.html @@ -10,7 +10,7 @@ {%- endmacro %} {%- macro result_link(url, title, classes='') -%} -<a href="{{ url }}" {% if classes %}class="{{ classes }} "{% endif %}{% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ title }}</a> +<a href="{{ url }}" {% if classes %}class="{{ classes }}" {% endif %}{% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ title }}</a> {%- endmacro -%} <!-- Draw result header --> @@ -37,7 +37,7 @@ <small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small> {% endif %} </div> - <div class="text-muted"><small>{{ result.pretty_url }}</small></div> +<div class="external-link">{{ result.pretty_url }}</div> {%- endmacro %} <!-- Draw result footer --> @@ -50,7 +50,7 @@ {% if proxify %} <small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small> {% endif %} - <div class="text-muted"><small>{{ result.pretty_url }}</small></div> + <div class="external-link">{{ result.pretty_url }}</div> {%- endmacro %} {% macro preferences_item_header(info, label, rtl) -%} diff --git a/searx/templates/oscar/navbar.html b/searx/templates/oscar/navbar.html @@ -1,14 +1,9 @@ -<!-- Static navbar --> -<div class="navbar navbar-default" role="navigation"> - <div class="container-fluid"> - <div class="navbar-header{% if rtl %} navbar-right{% endif %}"> - <a class="navbar-brand" href="{{ url_for('index') }}">{{ instance_name }}</a> - </div> - </div><!--/.container-fluid --> +<div class="searx-navbar"> + <span class="instance {% if rtl %}pull-right{% else %}pull-left{% endif%}"> + <a href="{{ url_for('index') }}">{{ instance_name }}</a> + </span> + <span class="{% if rtl %}pull-left{% else %}pull-right{% endif %}"> + <a href="{{ url_for('about') }}">{{ _('about') }}</a> + <a href="{{ url_for('preferences') }}">{{ _('preferences') }}</a> + </span> </div> -<div class="menu menu-{% if rtl %}left{% else %}right{% endif %}"> - <ul> <!-- results.html --> - <li{% if template_name == 'about.html' %} class="active"{% endif %}><a href="{{ url_for('about') }}" class="hmarg">{{ _('about') }}</a></li> - <li{% if template_name == 'preferences.html' %} class="active"{% endif %}><a href="{{ url_for('preferences') }}" class="hmarg">{{ _('preferences') }}</a></li> - </ul> -</div><!--/.nav-collapse --> diff --git a/searx/templates/oscar/opensearch.xml b/searx/templates/oscar/opensearch.xml @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"> - <ShortName>{{ instance_name }}</ShortName> - <Description>a privacy-respecting, hackable metasearch engine</Description> - <InputEncoding>UTF-8</InputEncoding> - <Image>{{ urljoin(host, url_for('static', filename='img/favicon.png')) }}</Image> - <LongName>searx metasearch</LongName> - {% if opensearch_method == 'get' %} - <Url type="text/html" method="get" template="{{ host }}search?q={searchTerms}"/> - {% if autocomplete %} - <Url type="application/x-suggestions+json" method="get" template="{{ host }}autocompleter"> - <Param name="format" value="x-suggestions" /> - <Param name="q" value="{searchTerms}" /> - </Url> - {% endif %} - {% else %} - <Url type="text/html" method="post" template="{{ host }}"> - <Param name="q" value="{searchTerms}" /> - </Url> - {% if autocomplete %} - <!-- TODO, POST REQUEST doesn't work --> - <Url type="application/x-suggestions+json" method="get" template="{{ host }}autocompleter"> - <Param name="format" value="x-suggestions" /> - <Param name="q" value="{searchTerms}" /> - </Url> - {% endif %} - {% endif %} -</OpenSearchDescription> diff --git a/searx/templates/oscar/opensearch_response_rss.xml b/searx/templates/oscar/opensearch_response_rss.xml @@ -1,23 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<rss version="2.0" - xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" - xmlns:atom="http://www.w3.org/2005/Atom"> - <channel> - <title>Searx search: {{ q|e }}</title> - <link>{{ base_url }}?q={{ q|e }}</link> - <description>Search results for "{{ q|e }}" - searx</description> - <opensearch:totalResults>{{ number_of_results }}</opensearch:totalResults> - <opensearch:startIndex>1</opensearch:startIndex> - <opensearch:itemsPerPage>{{ number_of_results }}</opensearch:itemsPerPage> - <atom:link rel="search" type="application/opensearchdescription+xml" href="{{ base_url }}opensearch.xml"/> - <opensearch:Query role="request" searchTerms="{{ q|e }}" startPage="1" /> - {% for r in results %} - <item> - <title>{{ r.title }}</title> - <link>{{ r.url }}</link> - <description>{{ r.content }}</description> - {% if r.pubdate %}<pubDate>{{ r.pubdate }}</pubDate>{% endif %} - </item> - {% endfor %} - </channel> -</rss> diff --git a/searx/templates/oscar/results.html b/searx/templates/oscar/results.html @@ -11,10 +11,22 @@ {% block title %}{{ q|e }} - {% endblock %} {% block meta %}<link rel="alternate" type="application/rss+xml" title="Searx search: {{ q|e }}" href="{{ search_url() }}&amp;format=rss">{% endblock %} {% block content %} + {% include 'oscar/search.html' %} <div class="row"> <div class="col-sm-8" id="main_results"> <h1 class="sr-only">{{ _('Search results') }}</h1> - {% include 'oscar/search.html' %} + + {% if corrections %} + <div class="result"> + <span class="result_header text-muted form-inline pull-left suggestion_item">{{ _('Try searching for:') }}</span> + {% for correction in corrections %} + <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" role="navigation" class="form-inline pull-left suggestion_item"> + <input type="hidden" name="q" value="{{ correction }}"> + <button type="submit" class="btn btn-default btn-xs">{{ correction }}</button> + </form> + {% endfor %} + </div> + {% endif %} {% if answers %} {% for answer in answers %} @@ -80,14 +92,7 @@ <div class="col-sm-4" id="sidebar_results"> {% if number_of_results != '0' %} - <div class="panel panel-default"> - <div class="panel-heading"> - <h4 class="panel-title">{{ _('Number of results') }}</h4> - </div> - <div class="panel-body"> - {{ number_of_results }} - </div> - </div> + <p><small>{{ _('Number of results') }}: {{ number_of_results }}</small></p> {% endif %} {% if infoboxes %} {% for infobox in infoboxes %} diff --git a/searx/templates/oscar/search.html b/searx/templates/oscar/search.html @@ -1,12 +1,24 @@ {% from 'oscar/macros.html' import icon %} <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" id="search_form" role="search"> - <div class="input-group col-sm-12"> + <div class="row"> + <div class="col-xs-12 col-md-8"> + <div class="input-group search-margin"> <input type="search" name="q" class="form-control" id="q" placeholder="{{ _('Search for...') }}" autocomplete="off" value="{{ q }}"> <span class="input-group-btn"> <button type="submit" class="btn btn-default"><span class="hide_if_nojs">{{ icon('search') }}</span><span class="hidden active_if_nojs">{{ _('Start search') }}</span></button> </span> + </div> </div> - <div class="input-group col-sm-12 advanced"> - {% include 'oscar/advanced.html' %} + <div class="col-xs-6 col-md-2 search-margin"> + {% include 'oscar/time-range.html' %} </div> + <div class="col-xs-6 col-md-2 search-margin"> + {% include 'oscar/languages.html' %} + </div> + </div> + <div class="row"> + <div class="col-sm-12"> + {% include 'oscar/categories.html' %} + </div> + </div> </form><!-- / #search_form_full --> diff --git a/searx/templates/oscar/time-range.html b/searx/templates/oscar/time-range.html @@ -1,4 +1,4 @@ -<select name="time_range" id="time-range"> +<select name="time_range" id="time-range" class="custom-select form-control"> <option id="time-range-anytime" value="" {{ "selected" if time_range=="" or not time_range else ""}}> {{ _('Anytime') }} </option> diff --git a/searx/templates/pix-art/about.html b/searx/templates/pix-art/about.html @@ -1,65 +1,4 @@ {% extends 'pix-art/base.html' %} {% block content %} -<div class="row"{% if rtl %} dir="ltr"{% endif %}> - <h1>About <a href="{{ url_for('index') }}">searx</a></h1> - - <p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, aggregating the results of other <a href="{{ url_for('preferences') }}">search engines</a> while not storing information about its users. - </p> - <h2>Why use searx?</h2> - <ul> - <li>searx may not offer you as personalised results as Google, but it doesn't generate a profile about you</li> - <li>searx doesn't care about what you search for, never shares anything with a third party, and it can't be used to compromise you</li> - <li>searx is free software, the code is 100% open and you can help to make it better. See more on <a href="https://github.com/asciimoo/searx">github</a></li> - </ul> - <p>If you do care about privacy, want to be a conscious user, or otherwise believe - in digital freedom, make searx your default search engine or run it on your own server</p> - -<h2>Technical details - How does it work?</h2> - -<p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, -inspired by the <a href="https://beniz.github.io/seeks/">seeks project</a>.<br /> -It provides basic privacy by mixing your queries with searches on other platforms without storing search data. Queries are made using a POST request on every browser (except chrome*). Therefore they show up in neither our logs, nor your url history. In case of Chrome* users there is an exception, if searx used from the search bar it performs GET requests.<br /> -Searx can be added to your browser's search bar; moreover, it can be set as the default search engine. -</p> - -<h2>How can I make it my own?</h2> - -<p>Searx appreciates your concern regarding logs, so take the <a href="https://github.com/asciimoo/searx">code</a> and run it yourself! <br />Add your Searx to this <a href="https://github.com/asciimoo/searx/wiki/Searx-instances">list</a> to help other people reclaim their privacy and make the Internet freer! -<br />The more decentralized Internet is the more freedom we have!</p> - - -<h2>More about searx</h2> - -<ul> - <li><a href="https://github.com/asciimoo/searx">github</a></li> - <li><a href="https://www.ohloh.net/p/searx/">ohloh</a></li> - <li><a href="https://twitter.com/Searx_engine">twitter</a></li> - <li>IRC: #searx @ freenode (<a href="https://kiwiirc.com/client/irc.freenode.com/searx">webclient</a>)</li> - <li><a href="https://www.transifex.com/projects/p/searx/">transifex</a></li> -</ul> - - -<hr /> - -<h2 id="faq">FAQ</h2> - -<h3>How to add to firefox?</h3> -<p><a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a> searx as a search engine on any version of Firefox! (javascript required)</p> - -<h2 id="dev_faq">Developer FAQ</h2> - -<h3>New engines?</h3> -<ul> - <li>Edit your <a href="https://raw.github.com/asciimoo/searx/master/searx/settings.yml">settings.yml</a></li> - <li>Create your custom engine module, check the <a href="https://github.com/asciimoo/searx/blob/master/examples/basic_engine.py">example engine</a></li> -</ul> -<p>Don't forget to restart searx after config edit!</p> - -<h3>Installation/WSGI support?</h3> -<p>See the <a href="https://github.com/asciimoo/searx/wiki/Installation">installation and setup</a> wiki page</p> - -<h3>How to debug engines?</h3> -<p><a href="{{ url_for('stats') }}">Stats page</a> contains some useful data about the engines used.</p> - -</div> +{% include '__common__/about.html' %} {% endblock %} diff --git a/searx/utils.py b/searx/utils.py @@ -175,6 +175,8 @@ def get_themes(root): templates_path = os.path.join(root, 'templates') themes = os.listdir(os.path.join(static_path, 'themes')) + if '__common__' in themes: + themes.remove('__common__') return static_path, templates_path, themes diff --git a/searx/webapp.py b/searx/webapp.py @@ -52,6 +52,7 @@ from flask import ( from flask_babel import Babel, gettext, format_date, format_decimal from flask.json import jsonify from searx import settings, searx_dir, searx_debug +from searx.exceptions import SearxException, SearxParameterException from searx.engines import ( categories, engines, engine_shortcuts, get_engines_stats, initialize_engines ) @@ -226,7 +227,7 @@ def get_current_theme_name(override=None): 2. cookies 3. settings""" - if override and override in themes: + if override and (override in themes or override == '__common__'): return override theme_name = request.args.get('theme', request.preferences.get_value('theme')) if theme_name not in themes: @@ -400,6 +401,33 @@ def pre_request(): request.user_plugins.append(plugin) +def index_error(output_format, error_message): + if output_format == 'json': + return Response(json.dumps({'error': error_message}), + mimetype='application/json') + elif output_format == 'csv': + response = Response('', mimetype='application/csv') + cont_disp = 'attachment;Filename=searx.csv' + response.headers.add('Content-Disposition', cont_disp) + return response + elif output_format == 'rss': + response_rss = render( + 'opensearch_response_rss.xml', + results=[], + q=request.form['q'] if 'q' in request.form else '', + number_of_results=0, + base_url=get_base_url(), + error_message=error_message + ) + return Response(response_rss, mimetype='text/xml') + else: + # html + request.errors.append(gettext('search error')) + return render( + 'index.html', + ) + + @app.route('/search', methods=['GET', 'POST']) @app.route('/', methods=['GET', 'POST']) def index(): @@ -408,10 +436,19 @@ def index(): Supported outputs: html, json, csv, rss. """ + # output_format + output_format = request.form.get('format', 'html') + if output_format not in ['html', 'csv', 'json', 'rss']: + output_format = 'html' + + # check if there is query if request.form.get('q') is None: - return render( - 'index.html', - ) + if output_format == 'html': + return render( + 'index.html', + ) + else: + return index_error(output_format, 'No query'), 400 # search search_query = None @@ -421,20 +458,24 @@ def index(): # search = Search(search_query) # without plugins search = SearchWithPlugins(search_query, request.user_plugins, request) result_container = search.search() - except: - request.errors.append(gettext('search error')) + except Exception as e: + # log exception logger.exception('search error') - return render( - 'index.html', - ) + # is it an invalid input parameter or something else ? + if (issubclass(e.__class__, SearxParameterException)): + return index_error(output_format, e.message), 400 + else: + return index_error(output_format, gettext('search error')), 500 + + # results results = result_container.get_ordered_results() + number_of_results = result_container.results_number() + if number_of_results < result_container.results_length(): + number_of_results = 0 # UI advanced_search = request.form.get('advanced_search', None) - output_format = request.form.get('format', 'html') - if output_format not in ['html', 'csv', 'json', 'rss']: - output_format = 'html' # output for result in results: @@ -470,15 +511,12 @@ def index(): else: result['publishedDate'] = format_date(result['publishedDate']) - number_of_results = result_container.results_number() - if number_of_results < result_container.results_length(): - number_of_results = 0 - if output_format == 'json': return Response(json.dumps({'query': search_query.query, 'number_of_results': number_of_results, 'results': results, 'answers': list(result_container.answers), + 'corrections': list(result_container.corrections), 'infoboxes': result_container.infoboxes, 'suggestions': list(result_container.suggestions)}), mimetype='application/json') @@ -500,7 +538,8 @@ def index(): results=results, q=request.form['q'], number_of_results=number_of_results, - base_url=get_base_url() + base_url=get_base_url(), + override_theme='__common__', ) return Response(response_rss, mimetype='text/xml') @@ -515,6 +554,7 @@ def index(): advanced_search=advanced_search, suggestions=result_container.suggestions, answers=result_container.answers, + corrections=result_container.corrections, infoboxes=result_container.infoboxes, paging=result_container.paging, current_language=search_query.lang, @@ -720,7 +760,8 @@ def opensearch(): ret = render('opensearch.xml', opensearch_method=method, host=get_base_url(), - urljoin=urljoin) + urljoin=urljoin, + override_theme='__common__') resp = Response(response=ret, status=200, diff --git a/tests/unit/test_webapp.py b/tests/unit/test_webapp.py @@ -36,6 +36,7 @@ class ViewsTestCase(SearxTestCase): def search_mock(search_self, *args): search_self.result_container = Mock(get_ordered_results=lambda: self.test_results, answers=set(), + corrections=set(), suggestions=set(), infoboxes=[], results=self.test_results, @@ -45,6 +46,8 @@ class ViewsTestCase(SearxTestCase): Search.search = search_mock def get_current_theme_name_mock(override=None): + if override: + return override return 'legacy' webapp.get_current_theme_name = get_current_theme_name_mock