mirror of
https://github.com/searxng/searxng
synced 2024-01-01 19:24:07 +01:00
Merge branch 'master' into fix-engine-spotify
This commit is contained in:
commit
36e72a4619
244 changed files with 10745 additions and 11499 deletions
|
|
@ -1,14 +1,15 @@
|
|||
{
|
||||
"ua": "Mozilla/5.0 ({os}; rv:{version}) Gecko/20100101 Firefox/{version}",
|
||||
"versions": [
|
||||
"61.0.1",
|
||||
"61.0",
|
||||
"60.0.2",
|
||||
"60.0.1",
|
||||
"60.0"
|
||||
"70.0.1",
|
||||
"70.0",
|
||||
"69.0.3",
|
||||
"69.0.2",
|
||||
"69.0.1",
|
||||
"69.0"
|
||||
],
|
||||
"os": [
|
||||
"Windows NT 10; WOW64",
|
||||
"X11; Linux x86_64"
|
||||
]
|
||||
],
|
||||
"ua": "Mozilla/5.0 ({os}; rv:{version}) Gecko/20100101 Firefox/{version}"
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ from json import loads
|
|||
from requests import get
|
||||
from searx import settings
|
||||
from searx import logger
|
||||
from searx.utils import load_module, match_language
|
||||
from searx.utils import load_module, match_language, get_engine_from_settings
|
||||
|
||||
|
||||
logger = logger.getChild('engines')
|
||||
|
|
@ -53,7 +53,8 @@ engine_default_args = {'paging': False,
|
|||
'disabled': False,
|
||||
'suspend_end_time': 0,
|
||||
'continuous_errors': 0,
|
||||
'time_range_support': False}
|
||||
'time_range_support': False,
|
||||
'offline': False}
|
||||
|
||||
|
||||
def load_engine(engine_data):
|
||||
|
|
@ -128,14 +129,16 @@ def load_engine(engine_data):
|
|||
engine.stats = {
|
||||
'result_count': 0,
|
||||
'search_count': 0,
|
||||
'page_load_time': 0,
|
||||
'page_load_count': 0,
|
||||
'engine_time': 0,
|
||||
'engine_time_count': 0,
|
||||
'score_count': 0,
|
||||
'errors': 0
|
||||
}
|
||||
|
||||
if not engine.offline:
|
||||
engine.stats['page_load_time'] = 0
|
||||
engine.stats['page_load_count'] = 0
|
||||
|
||||
for category_name in engine.categories:
|
||||
categories.setdefault(category_name, []).append(engine)
|
||||
|
||||
|
|
@ -173,11 +176,6 @@ def get_engines_stats():
|
|||
results_num = \
|
||||
engine.stats['result_count'] / float(engine.stats['search_count'])
|
||||
|
||||
if engine.stats['page_load_count'] != 0:
|
||||
load_times = engine.stats['page_load_time'] / float(engine.stats['page_load_count']) # noqa
|
||||
else:
|
||||
load_times = 0
|
||||
|
||||
if engine.stats['engine_time_count'] != 0:
|
||||
this_engine_time = engine.stats['engine_time'] / float(engine.stats['engine_time_count']) # noqa
|
||||
else:
|
||||
|
|
@ -189,14 +187,19 @@ def get_engines_stats():
|
|||
else:
|
||||
score = score_per_result = 0.0
|
||||
|
||||
max_pageload = max(load_times, max_pageload)
|
||||
if not engine.offline:
|
||||
load_times = 0
|
||||
if engine.stats['page_load_count'] != 0:
|
||||
load_times = engine.stats['page_load_time'] / float(engine.stats['page_load_count']) # noqa
|
||||
max_pageload = max(load_times, max_pageload)
|
||||
pageloads.append({'avg': load_times, 'name': engine.name})
|
||||
|
||||
max_engine_times = max(this_engine_time, max_engine_times)
|
||||
max_results = max(results_num, max_results)
|
||||
max_score = max(score, max_score)
|
||||
max_score_per_result = max(score_per_result, max_score_per_result)
|
||||
max_errors = max(max_errors, engine.stats['errors'])
|
||||
|
||||
pageloads.append({'avg': load_times, 'name': engine.name})
|
||||
engine_times.append({'avg': this_engine_time, 'name': engine.name})
|
||||
results.append({'avg': results_num, 'name': engine.name})
|
||||
scores.append({'avg': score, 'name': engine.name})
|
||||
|
|
@ -255,7 +258,7 @@ def initialize_engines(engine_list):
|
|||
load_engines(engine_list)
|
||||
|
||||
def engine_init(engine_name, init_fn):
|
||||
init_fn()
|
||||
init_fn(get_engine_from_settings(engine_name))
|
||||
logger.debug('%s engine: Initialized', engine_name)
|
||||
|
||||
for engine_name, engine in engines.items():
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ from searx.url_utils import urlencode
|
|||
|
||||
|
||||
categories = ['science']
|
||||
paging = True
|
||||
|
||||
base_url = 'http://export.arxiv.org/api/query?search_query=all:'\
|
||||
+ '{query}&start={offset}&max_results={number_of_results}'
|
||||
|
|
@ -29,7 +30,7 @@ def request(query, params):
|
|||
# basic search
|
||||
offset = (params['pageno'] - 1) * number_of_results
|
||||
|
||||
string_args = dict(query=query,
|
||||
string_args = dict(query=query.decode('utf-8'),
|
||||
offset=offset,
|
||||
number_of_results=number_of_results)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,10 +13,14 @@
|
|||
@todo publishedDate
|
||||
"""
|
||||
|
||||
import re
|
||||
from lxml import html
|
||||
from searx import logger, utils
|
||||
from searx.engines.xpath import extract_text
|
||||
from searx.url_utils import urlencode
|
||||
from searx.utils import match_language, gen_useragent
|
||||
from searx.utils import match_language, gen_useragent, eval_xpath
|
||||
|
||||
logger = logger.getChild('bing engine')
|
||||
|
||||
# engine dependent config
|
||||
categories = ['general']
|
||||
|
|
@ -30,9 +34,13 @@ base_url = 'https://www.bing.com/'
|
|||
search_string = 'search?{query}&first={offset}'
|
||||
|
||||
|
||||
def _get_offset_from_pageno(pageno):
|
||||
return (pageno - 1) * 10 + 1
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
offset = (params['pageno'] - 1) * 10 + 1
|
||||
offset = _get_offset_from_pageno(params.get('pageno', 0))
|
||||
|
||||
if params['language'] == 'all':
|
||||
lang = 'EN'
|
||||
|
|
@ -47,29 +55,21 @@ def request(query, params):
|
|||
|
||||
params['url'] = base_url + search_path
|
||||
|
||||
params['headers']['User-Agent'] = gen_useragent('Windows NT 6.3; WOW64')
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
result_len = 0
|
||||
|
||||
dom = html.fromstring(resp.text)
|
||||
|
||||
try:
|
||||
results.append({'number_of_results': int(dom.xpath('//span[@class="sb_count"]/text()')[0]
|
||||
.split()[0].replace(',', ''))})
|
||||
except:
|
||||
pass
|
||||
|
||||
# parse results
|
||||
for result in dom.xpath('//div[@class="sa_cc"]'):
|
||||
link = result.xpath('.//h3/a')[0]
|
||||
for result in eval_xpath(dom, '//div[@class="sa_cc"]'):
|
||||
link = eval_xpath(result, './/h3/a')[0]
|
||||
url = link.attrib.get('href')
|
||||
title = extract_text(link)
|
||||
content = extract_text(result.xpath('.//p'))
|
||||
content = extract_text(eval_xpath(result, './/p'))
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
|
|
@ -77,18 +77,35 @@ def response(resp):
|
|||
'content': content})
|
||||
|
||||
# parse results again if nothing is found yet
|
||||
for result in dom.xpath('//li[@class="b_algo"]'):
|
||||
link = result.xpath('.//h2/a')[0]
|
||||
for result in eval_xpath(dom, '//li[@class="b_algo"]'):
|
||||
link = eval_xpath(result, './/h2/a')[0]
|
||||
url = link.attrib.get('href')
|
||||
title = extract_text(link)
|
||||
content = extract_text(result.xpath('.//p'))
|
||||
content = extract_text(eval_xpath(result, './/p'))
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
'content': content})
|
||||
|
||||
# return results
|
||||
try:
|
||||
result_len_container = "".join(eval_xpath(dom, '//span[@class="sb_count"]/text()'))
|
||||
result_len_container = utils.to_string(result_len_container)
|
||||
if "-" in result_len_container:
|
||||
# Remove the part "from-to" for paginated request ...
|
||||
result_len_container = result_len_container[result_len_container.find("-") * 2 + 2:]
|
||||
|
||||
result_len_container = re.sub('[^0-9]', '', result_len_container)
|
||||
if len(result_len_container) > 0:
|
||||
result_len = int(result_len_container)
|
||||
except Exception as e:
|
||||
logger.debug('result error :\n%s', e)
|
||||
pass
|
||||
|
||||
if _get_offset_from_pageno(resp.search_params.get("pageno", 0)) > result_len:
|
||||
return []
|
||||
|
||||
results.append({'number_of_results': result_len})
|
||||
return results
|
||||
|
||||
|
||||
|
|
@ -96,9 +113,9 @@ def response(resp):
|
|||
def _fetch_supported_languages(resp):
|
||||
supported_languages = []
|
||||
dom = html.fromstring(resp.text)
|
||||
options = dom.xpath('//div[@id="limit-languages"]//input')
|
||||
options = eval_xpath(dom, '//div[@id="limit-languages"]//input')
|
||||
for option in options:
|
||||
code = option.xpath('./@id')[0].replace('_', '-')
|
||||
code = eval_xpath(option, './@id')[0].replace('_', '-')
|
||||
if code == 'nb':
|
||||
code = 'no'
|
||||
supported_languages.append(code)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
from json import loads
|
||||
from datetime import datetime
|
||||
from searx.url_utils import urlencode
|
||||
from searx.utils import match_language
|
||||
from searx.utils import match_language, html_to_text
|
||||
|
||||
# engine dependent config
|
||||
categories = ['videos']
|
||||
|
|
@ -59,7 +59,7 @@ def response(resp):
|
|||
for res in search_res['list']:
|
||||
title = res['title']
|
||||
url = res['url']
|
||||
content = res['description']
|
||||
content = html_to_text(res['description'])
|
||||
thumbnail = res['thumbnail_360_url']
|
||||
publishedDate = datetime.fromtimestamp(res['created_time'], None)
|
||||
embedded = embedded_url.format(videoid=res['id'])
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ time_range_support = True
|
|||
|
||||
# search-url
|
||||
base_url = 'https://www.deviantart.com/'
|
||||
search_url = base_url + 'browse/all/?offset={offset}&{query}'
|
||||
search_url = base_url + 'search?page={page}&{query}'
|
||||
time_range_url = '&order={range}'
|
||||
|
||||
time_range_dict = {'day': 11,
|
||||
|
|
@ -37,9 +37,7 @@ def request(query, params):
|
|||
if params['time_range'] and params['time_range'] not in time_range_dict:
|
||||
return params
|
||||
|
||||
offset = (params['pageno'] - 1) * 24
|
||||
|
||||
params['url'] = search_url.format(offset=offset,
|
||||
params['url'] = search_url.format(page=params['pageno'],
|
||||
query=urlencode({'q': query}))
|
||||
if params['time_range'] in time_range_dict:
|
||||
params['url'] += time_range_url.format(range=time_range_dict[params['time_range']])
|
||||
|
|
@ -57,28 +55,27 @@ def response(resp):
|
|||
|
||||
dom = html.fromstring(resp.text)
|
||||
|
||||
regex = re.compile(r'\/200H\/')
|
||||
|
||||
# parse results
|
||||
for result in dom.xpath('.//span[@class="thumb wide"]'):
|
||||
link = result.xpath('.//a[@class="torpedo-thumb-link"]')[0]
|
||||
url = link.attrib.get('href')
|
||||
title = extract_text(result.xpath('.//span[@class="title"]'))
|
||||
thumbnail_src = link.xpath('.//img')[0].attrib.get('src')
|
||||
img_src = regex.sub('/', thumbnail_src)
|
||||
for row in dom.xpath('//div[contains(@data-hook, "content_row")]'):
|
||||
for result in row.xpath('./div'):
|
||||
link = result.xpath('.//a[@data-hook="deviation_link"]')[0]
|
||||
url = link.attrib.get('href')
|
||||
title = link.attrib.get('title')
|
||||
thumbnail_src = result.xpath('.//img')[0].attrib.get('src')
|
||||
img_src = thumbnail_src
|
||||
|
||||
# http to https, remove domain sharding
|
||||
thumbnail_src = re.sub(r"https?://(th|fc)\d+.", "https://th01.", thumbnail_src)
|
||||
thumbnail_src = re.sub(r"http://", "https://", thumbnail_src)
|
||||
# http to https, remove domain sharding
|
||||
thumbnail_src = re.sub(r"https?://(th|fc)\d+.", "https://th01.", thumbnail_src)
|
||||
thumbnail_src = re.sub(r"http://", "https://", thumbnail_src)
|
||||
|
||||
url = re.sub(r"http://(.*)\.deviantart\.com/", "https://\\1.deviantart.com/", url)
|
||||
url = re.sub(r"http://(.*)\.deviantart\.com/", "https://\\1.deviantart.com/", url)
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
'img_src': img_src,
|
||||
'thumbnail_src': thumbnail_src,
|
||||
'template': 'images.html'})
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
'img_src': img_src,
|
||||
'thumbnail_src': thumbnail_src,
|
||||
'template': 'images.html'})
|
||||
|
||||
# return results
|
||||
return results
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@
|
|||
|
||||
import re
|
||||
from lxml import html
|
||||
from searx.utils import is_valid_lang
|
||||
from searx.utils import is_valid_lang, eval_xpath
|
||||
from searx.url_utils import urljoin
|
||||
|
||||
categories = ['general']
|
||||
url = u'http://dictzone.com/{from_lang}-{to_lang}-dictionary/{query}'
|
||||
url = u'https://dictzone.com/{from_lang}-{to_lang}-dictionary/{query}'
|
||||
weight = 100
|
||||
|
||||
parser_re = re.compile(b'.*?([a-z]+)-([a-z]+) ([^ ]+)$', re.I)
|
||||
|
|
@ -47,14 +47,14 @@ def response(resp):
|
|||
|
||||
dom = html.fromstring(resp.text)
|
||||
|
||||
for k, result in enumerate(dom.xpath(results_xpath)[1:]):
|
||||
for k, result in enumerate(eval_xpath(dom, results_xpath)[1:]):
|
||||
try:
|
||||
from_result, to_results_raw = result.xpath('./td')
|
||||
from_result, to_results_raw = eval_xpath(result, './td')
|
||||
except:
|
||||
continue
|
||||
|
||||
to_results = []
|
||||
for to_result in to_results_raw.xpath('./p/a'):
|
||||
for to_result in eval_xpath(to_results_raw, './p/a'):
|
||||
t = to_result.text_content()
|
||||
if t.strip():
|
||||
to_results.append(to_result.text_content())
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ import string
|
|||
from dateutil import parser
|
||||
from json import loads
|
||||
from lxml import html
|
||||
from searx.url_utils import quote_plus
|
||||
from searx.url_utils import urlencode
|
||||
from datetime import datetime
|
||||
|
||||
# engine dependent config
|
||||
categories = ['news', 'social media']
|
||||
|
|
@ -23,7 +24,7 @@ paging = True
|
|||
|
||||
# search-url
|
||||
base_url = 'https://digg.com/'
|
||||
search_url = base_url + 'api/search/{query}.json?position={position}&format=html'
|
||||
search_url = base_url + 'api/search/?{query}&from={position}&size=20&format=html'
|
||||
|
||||
# specific xpath variables
|
||||
results_xpath = '//article'
|
||||
|
|
@ -38,9 +39,9 @@ digg_cookie_chars = string.ascii_uppercase + string.ascii_lowercase +\
|
|||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
offset = (params['pageno'] - 1) * 10
|
||||
offset = (params['pageno'] - 1) * 20
|
||||
params['url'] = search_url.format(position=offset,
|
||||
query=quote_plus(query))
|
||||
query=urlencode({'q': query}))
|
||||
params['cookies']['frontend.auid'] = ''.join(random.choice(
|
||||
digg_cookie_chars) for _ in range(22))
|
||||
return params
|
||||
|
|
@ -52,30 +53,17 @@ def response(resp):
|
|||
|
||||
search_result = loads(resp.text)
|
||||
|
||||
if 'html' not in search_result or search_result['html'] == '':
|
||||
return results
|
||||
|
||||
dom = html.fromstring(search_result['html'])
|
||||
|
||||
# parse results
|
||||
for result in dom.xpath(results_xpath):
|
||||
url = result.attrib.get('data-contenturl')
|
||||
thumbnail = result.xpath('.//img')[0].attrib.get('src')
|
||||
title = ''.join(result.xpath(title_xpath))
|
||||
content = ''.join(result.xpath(content_xpath))
|
||||
pubdate = result.xpath(pubdate_xpath)[0].attrib.get('datetime')
|
||||
publishedDate = parser.parse(pubdate)
|
||||
|
||||
# http to https
|
||||
thumbnail = thumbnail.replace("http://static.digg.com", "https://static.digg.com")
|
||||
for result in search_result['mapped']:
|
||||
|
||||
published = datetime.strptime(result['created']['ISO'], "%Y-%m-%d %H:%M:%S")
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
'content': content,
|
||||
results.append({'url': result['url'],
|
||||
'title': result['title'],
|
||||
'content': result['excerpt'],
|
||||
'template': 'videos.html',
|
||||
'publishedDate': publishedDate,
|
||||
'thumbnail': thumbnail})
|
||||
'publishedDate': published,
|
||||
'thumbnail': result['images']['thumbImage']})
|
||||
|
||||
# return results
|
||||
return results
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
from lxml.html import fromstring
|
||||
from searx.engines.xpath import extract_text
|
||||
from searx.utils import eval_xpath
|
||||
from searx.url_utils import urlencode
|
||||
|
||||
# engine dependent config
|
||||
|
|
@ -45,16 +46,16 @@ def response(resp):
|
|||
|
||||
# parse results
|
||||
# Quickhits
|
||||
for r in doc.xpath('//div[@class="search_quickresult"]/ul/li'):
|
||||
for r in eval_xpath(doc, '//div[@class="search_quickresult"]/ul/li'):
|
||||
try:
|
||||
res_url = r.xpath('.//a[@class="wikilink1"]/@href')[-1]
|
||||
res_url = eval_xpath(r, './/a[@class="wikilink1"]/@href')[-1]
|
||||
except:
|
||||
continue
|
||||
|
||||
if not res_url:
|
||||
continue
|
||||
|
||||
title = extract_text(r.xpath('.//a[@class="wikilink1"]/@title'))
|
||||
title = extract_text(eval_xpath(r, './/a[@class="wikilink1"]/@title'))
|
||||
|
||||
# append result
|
||||
results.append({'title': title,
|
||||
|
|
@ -62,13 +63,13 @@ def response(resp):
|
|||
'url': base_url + res_url})
|
||||
|
||||
# Search results
|
||||
for r in doc.xpath('//dl[@class="search_results"]/*'):
|
||||
for r in eval_xpath(doc, '//dl[@class="search_results"]/*'):
|
||||
try:
|
||||
if r.tag == "dt":
|
||||
res_url = r.xpath('.//a[@class="wikilink1"]/@href')[-1]
|
||||
title = extract_text(r.xpath('.//a[@class="wikilink1"]/@title'))
|
||||
res_url = eval_xpath(r, './/a[@class="wikilink1"]/@href')[-1]
|
||||
title = extract_text(eval_xpath(r, './/a[@class="wikilink1"]/@title'))
|
||||
elif r.tag == "dd":
|
||||
content = extract_text(r.xpath('.'))
|
||||
content = extract_text(eval_xpath(r, '.'))
|
||||
|
||||
# append result
|
||||
results.append({'title': title,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ from json import loads
|
|||
from searx.engines.xpath import extract_text
|
||||
from searx.poolrequests import get
|
||||
from searx.url_utils import urlencode
|
||||
from searx.utils import match_language
|
||||
from searx.utils import match_language, eval_xpath
|
||||
|
||||
# engine dependent config
|
||||
categories = ['general']
|
||||
|
|
@ -65,21 +65,36 @@ def get_region_code(lang, lang_list=[]):
|
|||
|
||||
|
||||
def request(query, params):
|
||||
if params['time_range'] and params['time_range'] not in time_range_dict:
|
||||
if params['time_range'] not in (None, 'None', '') and params['time_range'] not in time_range_dict:
|
||||
return params
|
||||
|
||||
offset = (params['pageno'] - 1) * 30
|
||||
|
||||
region_code = get_region_code(params['language'], supported_languages)
|
||||
if region_code:
|
||||
params['url'] = url.format(
|
||||
query=urlencode({'q': query, 'kl': region_code}), offset=offset, dc_param=offset)
|
||||
params['url'] = 'https://duckduckgo.com/html/'
|
||||
if params['pageno'] > 1:
|
||||
params['method'] = 'POST'
|
||||
params['data']['q'] = query
|
||||
params['data']['s'] = offset
|
||||
params['data']['dc'] = 30
|
||||
params['data']['nextParams'] = ''
|
||||
params['data']['v'] = 'l'
|
||||
params['data']['o'] = 'json'
|
||||
params['data']['api'] = '/d.js'
|
||||
if params['time_range'] in time_range_dict:
|
||||
params['data']['df'] = time_range_dict[params['time_range']]
|
||||
if region_code:
|
||||
params['data']['kl'] = region_code
|
||||
else:
|
||||
params['url'] = url.format(
|
||||
query=urlencode({'q': query}), offset=offset, dc_param=offset)
|
||||
if region_code:
|
||||
params['url'] = url.format(
|
||||
query=urlencode({'q': query, 'kl': region_code}), offset=offset, dc_param=offset)
|
||||
else:
|
||||
params['url'] = url.format(
|
||||
query=urlencode({'q': query}), offset=offset, dc_param=offset)
|
||||
|
||||
if params['time_range'] in time_range_dict:
|
||||
params['url'] += time_range_url.format(range=time_range_dict[params['time_range']])
|
||||
if params['time_range'] in time_range_dict:
|
||||
params['url'] += time_range_url.format(range=time_range_dict[params['time_range']])
|
||||
|
||||
return params
|
||||
|
||||
|
|
@ -91,17 +106,19 @@ def response(resp):
|
|||
doc = fromstring(resp.text)
|
||||
|
||||
# parse results
|
||||
for r in doc.xpath(result_xpath):
|
||||
for i, r in enumerate(eval_xpath(doc, result_xpath)):
|
||||
if i >= 30:
|
||||
break
|
||||
try:
|
||||
res_url = r.xpath(url_xpath)[-1]
|
||||
res_url = eval_xpath(r, url_xpath)[-1]
|
||||
except:
|
||||
continue
|
||||
|
||||
if not res_url:
|
||||
continue
|
||||
|
||||
title = extract_text(r.xpath(title_xpath))
|
||||
content = extract_text(r.xpath(content_xpath))
|
||||
title = extract_text(eval_xpath(r, title_xpath))
|
||||
content = extract_text(eval_xpath(r, content_xpath))
|
||||
|
||||
# append result
|
||||
results.append({'title': title,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,14 @@
|
|||
"""
|
||||
DuckDuckGo (definitions)
|
||||
|
||||
- `Instant Answer API`_
|
||||
- `DuckDuckGo query`_
|
||||
|
||||
.. _Instant Answer API: https://duckduckgo.com/api
|
||||
.. _DuckDuckGo query: https://api.duckduckgo.com/?q=DuckDuckGo&format=json&pretty=1
|
||||
|
||||
"""
|
||||
|
||||
import json
|
||||
from lxml import html
|
||||
from re import compile
|
||||
|
|
@ -25,7 +36,8 @@ def result_to_text(url, text, htmlResult):
|
|||
def request(query, params):
|
||||
params['url'] = url.format(query=urlencode({'q': query}))
|
||||
language = match_language(params['language'], supported_languages, language_aliases)
|
||||
params['headers']['Accept-Language'] = language.split('-')[0]
|
||||
language = language.split('-')[0]
|
||||
params['headers']['Accept-Language'] = language
|
||||
return params
|
||||
|
||||
|
||||
|
|
@ -43,8 +55,9 @@ def response(resp):
|
|||
|
||||
# add answer if there is one
|
||||
answer = search_res.get('Answer', '')
|
||||
if answer != '':
|
||||
results.append({'answer': html_to_text(answer)})
|
||||
if answer:
|
||||
if search_res.get('AnswerType', '') not in ['calc']:
|
||||
results.append({'answer': html_to_text(answer)})
|
||||
|
||||
# add infobox
|
||||
if 'Definition' in search_res:
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
from lxml import html, etree
|
||||
import re
|
||||
from searx.engines.xpath import extract_text
|
||||
from searx.utils import eval_xpath
|
||||
from searx.url_utils import quote, urljoin
|
||||
from searx import logger
|
||||
|
||||
|
|
@ -52,9 +53,9 @@ def response(resp):
|
|||
dom = html.fromstring(resp.text)
|
||||
|
||||
try:
|
||||
number_of_results_string = re.sub('[^0-9]', '', dom.xpath(
|
||||
'//a[@class="active" and contains(@href,"/suchen/dudenonline")]/span/text()')[0]
|
||||
)
|
||||
number_of_results_string =\
|
||||
re.sub('[^0-9]', '',
|
||||
eval_xpath(dom, '//a[@class="active" and contains(@href,"/suchen/dudenonline")]/span/text()')[0])
|
||||
|
||||
results.append({'number_of_results': int(number_of_results_string)})
|
||||
|
||||
|
|
@ -62,12 +63,12 @@ def response(resp):
|
|||
logger.debug("Couldn't read number of results.")
|
||||
pass
|
||||
|
||||
for result in dom.xpath('//section[not(contains(@class, "essay"))]'):
|
||||
for result in eval_xpath(dom, '//section[not(contains(@class, "essay"))]'):
|
||||
try:
|
||||
url = result.xpath('.//h2/a')[0].get('href')
|
||||
url = eval_xpath(result, './/h2/a')[0].get('href')
|
||||
url = urljoin(base_url, url)
|
||||
title = result.xpath('string(.//h2/a)').strip()
|
||||
content = extract_text(result.xpath('.//p'))
|
||||
title = eval_xpath(result, 'string(.//h2/a)').strip()
|
||||
content = extract_text(eval_xpath(result, './/p'))
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@ categories = ['files']
|
|||
paging = True
|
||||
|
||||
# search-url
|
||||
base_url = 'https://f-droid.org/'
|
||||
search_url = base_url + 'repository/browse/?{query}'
|
||||
base_url = 'https://search.f-droid.org/'
|
||||
search_url = base_url + '?{query}'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
query = urlencode({'fdfilter': query, 'fdpage': params['pageno']})
|
||||
query = urlencode({'q': query, 'page': params['pageno'], 'lang': ''})
|
||||
params['url'] = search_url.format(query=query)
|
||||
return params
|
||||
|
||||
|
|
@ -35,17 +35,16 @@ def response(resp):
|
|||
|
||||
dom = html.fromstring(resp.text)
|
||||
|
||||
for app in dom.xpath('//div[@id="appheader"]'):
|
||||
url = app.xpath('./ancestor::a/@href')[0]
|
||||
title = app.xpath('./p/span/text()')[0]
|
||||
img_src = app.xpath('.//img/@src')[0]
|
||||
for app in dom.xpath('//a[@class="package-header"]'):
|
||||
app_url = app.xpath('./@href')[0]
|
||||
app_title = extract_text(app.xpath('./div/h4[@class="package-name"]/text()'))
|
||||
app_content = extract_text(app.xpath('./div/div/span[@class="package-summary"]')).strip() \
|
||||
+ ' - ' + extract_text(app.xpath('./div/div/span[@class="package-license"]')).strip()
|
||||
app_img_src = app.xpath('./img[@class="package-icon"]/@src')[0]
|
||||
|
||||
content = extract_text(app.xpath('./p')[0])
|
||||
content = content.replace(title, '', 1).strip()
|
||||
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
'content': content,
|
||||
'img_src': img_src})
|
||||
results.append({'url': app_url,
|
||||
'title': app_title,
|
||||
'content': app_content,
|
||||
'img_src': app_img_src})
|
||||
|
||||
return results
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ from json import loads
|
|||
from time import time
|
||||
import re
|
||||
from searx.engines import logger
|
||||
from searx.url_utils import urlencode, unquote
|
||||
from searx.url_utils import urlencode
|
||||
from searx.utils import ecma_unescape, html_to_text
|
||||
|
||||
logger = logger.getChild('flickr-noapi')
|
||||
|
||||
|
|
@ -75,11 +76,10 @@ def response(resp):
|
|||
|
||||
for index in legend:
|
||||
photo = model_export['main'][index[0]][int(index[1])][index[2]][index[3]][int(index[4])]
|
||||
author = unquote(photo.get('realname', ''))
|
||||
source = unquote(photo.get('username', '')) + ' @ Flickr'
|
||||
title = unquote(photo.get('title', ''))
|
||||
content = unquote(photo.get('description', ''))
|
||||
|
||||
author = ecma_unescape(photo.get('realname', ''))
|
||||
source = ecma_unescape(photo.get('username', '')) + ' @ Flickr'
|
||||
title = ecma_unescape(photo.get('title', ''))
|
||||
content = html_to_text(ecma_unescape(photo.get('description', '')))
|
||||
img_src = None
|
||||
# From the biggest to the lowest format
|
||||
for image_size in image_sizes:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@
|
|||
@parse url, title, content, thumbnail, img_src
|
||||
"""
|
||||
|
||||
from cgi import escape
|
||||
try:
|
||||
from cgi import escape
|
||||
except:
|
||||
from html import escape
|
||||
from lxml import html
|
||||
from searx.engines.xpath import extract_text
|
||||
from searx.url_utils import urljoin, urlencode
|
||||
|
|
|
|||
|
|
@ -14,7 +14,9 @@ import random
|
|||
from json import loads
|
||||
from time import time
|
||||
from lxml.html import fromstring
|
||||
from searx.poolrequests import get
|
||||
from searx.url_utils import urlencode
|
||||
from searx.utils import eval_xpath
|
||||
|
||||
# engine dependent config
|
||||
categories = ['general']
|
||||
|
|
@ -30,13 +32,9 @@ search_string = 'search?{query}'\
|
|||
'&c=main'\
|
||||
'&s={offset}'\
|
||||
'&format=json'\
|
||||
'&qh=0'\
|
||||
'&qlang={lang}'\
|
||||
'&langcountry={lang}'\
|
||||
'&ff={safesearch}'\
|
||||
'&rxiec={rxieu}'\
|
||||
'&ulse={ulse}'\
|
||||
'&rand={rxikd}' # current unix timestamp
|
||||
|
||||
'&rand={rxikd}'
|
||||
# specific xpath variables
|
||||
results_xpath = '//response//result'
|
||||
url_xpath = './/url'
|
||||
|
|
@ -45,9 +43,26 @@ content_xpath = './/sum'
|
|||
|
||||
supported_languages_url = 'https://gigablast.com/search?&rxikd=1'
|
||||
|
||||
extra_param = '' # gigablast requires a random extra parameter
|
||||
# which can be extracted from the source code of the search page
|
||||
|
||||
|
||||
def parse_extra_param(text):
|
||||
global extra_param
|
||||
param_lines = [x for x in text.splitlines() if x.startswith('var url=') or x.startswith('url=url+')]
|
||||
extra_param = ''
|
||||
for l in param_lines:
|
||||
extra_param += l.split("'")[1]
|
||||
extra_param = extra_param.split('&')[-1]
|
||||
|
||||
|
||||
def init(engine_settings=None):
|
||||
parse_extra_param(get('http://gigablast.com/search?c=main&qlangcountry=en-us&q=south&s=10').text)
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
print("EXTRAPARAM:", extra_param)
|
||||
offset = (params['pageno'] - 1) * number_of_results
|
||||
|
||||
if params['language'] == 'all':
|
||||
|
|
@ -66,13 +81,11 @@ def request(query, params):
|
|||
search_path = search_string.format(query=urlencode({'q': query}),
|
||||
offset=offset,
|
||||
number_of_results=number_of_results,
|
||||
rxikd=int(time() * 1000),
|
||||
rxieu=random.randint(1000000000, 9999999999),
|
||||
ulse=random.randint(100000000, 999999999),
|
||||
lang=language,
|
||||
rxikd=int(time() * 1000),
|
||||
safesearch=safesearch)
|
||||
|
||||
params['url'] = base_url + search_path
|
||||
params['url'] = base_url + search_path + '&' + extra_param
|
||||
|
||||
return params
|
||||
|
||||
|
|
@ -82,7 +95,11 @@ def response(resp):
|
|||
results = []
|
||||
|
||||
# parse results
|
||||
response_json = loads(resp.text)
|
||||
try:
|
||||
response_json = loads(resp.text)
|
||||
except:
|
||||
parse_extra_param(resp.text)
|
||||
raise Exception('extra param expired, please reload')
|
||||
|
||||
for result in response_json['results']:
|
||||
# append result
|
||||
|
|
@ -98,9 +115,9 @@ def response(resp):
|
|||
def _fetch_supported_languages(resp):
|
||||
supported_languages = []
|
||||
dom = fromstring(resp.text)
|
||||
links = dom.xpath('//span[@id="menu2"]/a')
|
||||
links = eval_xpath(dom, '//span[@id="menu2"]/a')
|
||||
for link in links:
|
||||
href = link.xpath('./@href')[0].split('lang%3A')
|
||||
href = eval_xpath(link, './@href')[0].split('lang%3A')
|
||||
if len(href) == 2:
|
||||
code = href[1].split('_')
|
||||
if len(code) == 2:
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ from lxml import html, etree
|
|||
from searx.engines.xpath import extract_text, extract_url
|
||||
from searx import logger
|
||||
from searx.url_utils import urlencode, urlparse, parse_qsl
|
||||
from searx.utils import match_language
|
||||
from searx.utils import match_language, eval_xpath
|
||||
|
||||
logger = logger.getChild('google engine')
|
||||
|
||||
|
|
@ -107,13 +107,12 @@ images_path = '/images'
|
|||
supported_languages_url = 'https://www.google.com/preferences?#languages'
|
||||
|
||||
# specific xpath variables
|
||||
results_xpath = '//div[@class="g"]'
|
||||
url_xpath = './/h3/a/@href'
|
||||
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"]'
|
||||
results_xpath = '//div[contains(@class, "ZINbbc")]'
|
||||
url_xpath = './/div[@class="kCrYT"][1]/a/@href'
|
||||
title_xpath = './/div[@class="kCrYT"][1]/a/div[1]'
|
||||
content_xpath = './/div[@class="kCrYT"][2]//div[contains(@class, "BNeawe")]//div[contains(@class, "BNeawe")]'
|
||||
suggestion_xpath = '//div[contains(@class, "ZINbbc")][last()]//div[@class="rVLSBd"]/a//div[contains(@class, "BNeawe")]'
|
||||
spelling_suggestion_xpath = '//div[@id="scc"]//a'
|
||||
|
||||
# map : detail location
|
||||
map_address_xpath = './/div[@class="s"]//table//td[2]/span/text()'
|
||||
|
|
@ -156,7 +155,7 @@ def parse_url(url_string, google_hostname):
|
|||
|
||||
# returns extract_text on the first result selected by the xpath or None
|
||||
def extract_text_from_dom(result, xpath):
|
||||
r = result.xpath(xpath)
|
||||
r = eval_xpath(result, xpath)
|
||||
if len(r) > 0:
|
||||
return extract_text(r[0])
|
||||
return None
|
||||
|
|
@ -199,9 +198,6 @@ def request(query, params):
|
|||
params['headers']['Accept-Language'] = language + ',' + language + '-' + country
|
||||
params['headers']['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
|
||||
|
||||
# Force Internet Explorer 12 user agent to avoid loading the new UI that Searx can't parse
|
||||
params['headers']['User-Agent'] = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"
|
||||
|
||||
params['google_hostname'] = google_hostname
|
||||
|
||||
return params
|
||||
|
|
@ -226,21 +222,21 @@ def response(resp):
|
|||
# convert the text to dom
|
||||
dom = html.fromstring(resp.text)
|
||||
|
||||
instant_answer = dom.xpath('//div[@id="_vBb"]//text()')
|
||||
instant_answer = eval_xpath(dom, '//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]
|
||||
results_num = int(eval_xpath(dom, '//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):
|
||||
for result in eval_xpath(dom, results_xpath):
|
||||
try:
|
||||
title = extract_text(result.xpath(title_xpath)[0])
|
||||
url = parse_url(extract_url(result.xpath(url_xpath), google_url), google_hostname)
|
||||
title = extract_text(eval_xpath(result, title_xpath)[0])
|
||||
url = parse_url(extract_url(eval_xpath(result, url_xpath), google_url), google_hostname)
|
||||
parsed_url = urlparse(url, google_hostname)
|
||||
|
||||
# map result
|
||||
|
|
@ -249,7 +245,7 @@ def response(resp):
|
|||
continue
|
||||
# if parsed_url.path.startswith(maps_path) or parsed_url.netloc.startswith(map_hostname_start):
|
||||
# print "yooooo"*30
|
||||
# x = result.xpath(map_near)
|
||||
# x = eval_xpath(result, map_near)
|
||||
# if len(x) > 0:
|
||||
# # map : near the location
|
||||
# results = results + parse_map_near(parsed_url, x, google_hostname)
|
||||
|
|
@ -273,9 +269,7 @@ def response(resp):
|
|||
content = extract_text_from_dom(result, content_xpath)
|
||||
if content is None:
|
||||
continue
|
||||
content_misc = extract_text_from_dom(result, content_misc_xpath)
|
||||
if content_misc is not None:
|
||||
content = content_misc + "<br />" + content
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
|
|
@ -286,11 +280,11 @@ def response(resp):
|
|||
continue
|
||||
|
||||
# parse suggestion
|
||||
for suggestion in dom.xpath(suggestion_xpath):
|
||||
for suggestion in eval_xpath(dom, suggestion_xpath):
|
||||
# append suggestion
|
||||
results.append({'suggestion': extract_text(suggestion)})
|
||||
|
||||
for correction in dom.xpath(spelling_suggestion_xpath):
|
||||
for correction in eval_xpath(dom, spelling_suggestion_xpath):
|
||||
results.append({'correction': extract_text(correction)})
|
||||
|
||||
# return results
|
||||
|
|
@ -299,9 +293,9 @@ def response(resp):
|
|||
|
||||
def parse_images(result, google_hostname):
|
||||
results = []
|
||||
for image in result.xpath(images_xpath):
|
||||
url = parse_url(extract_text(image.xpath(image_url_xpath)[0]), google_hostname)
|
||||
img_src = extract_text(image.xpath(image_img_src_xpath)[0])
|
||||
for image in eval_xpath(result, images_xpath):
|
||||
url = parse_url(extract_text(eval_xpath(image, image_url_xpath)[0]), google_hostname)
|
||||
img_src = extract_text(eval_xpath(image, image_img_src_xpath)[0])
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
|
|
@ -388,10 +382,10 @@ def attributes_to_html(attributes):
|
|||
def _fetch_supported_languages(resp):
|
||||
supported_languages = {}
|
||||
dom = html.fromstring(resp.text)
|
||||
options = dom.xpath('//*[@id="langSec"]//input[@name="lr"]')
|
||||
options = eval_xpath(dom, '//*[@id="langSec"]//input[@name="lr"]')
|
||||
for option in options:
|
||||
code = option.xpath('./@value')[0].split('_')[-1]
|
||||
name = option.xpath('./@data-name')[0].title()
|
||||
code = eval_xpath(option, './@value')[0].split('_')[-1]
|
||||
name = eval_xpath(option, './@data-name')[0].title()
|
||||
supported_languages[code] = {"name": name}
|
||||
|
||||
return supported_languages
|
||||
|
|
|
|||
|
|
@ -70,11 +70,21 @@ def response(resp):
|
|||
|
||||
try:
|
||||
metadata = loads(result)
|
||||
img_format = "{0} {1}x{2}".format(metadata['ity'], str(metadata['ow']), str(metadata['oh']))
|
||||
source = "{0} ({1})".format(metadata['st'], metadata['isu'])
|
||||
|
||||
img_format = metadata.get('ity', '')
|
||||
img_width = metadata.get('ow', '')
|
||||
img_height = metadata.get('oh', '')
|
||||
if img_width and img_height:
|
||||
img_format += " {0}x{1}".format(img_width, img_height)
|
||||
|
||||
source = metadata.get('st', '')
|
||||
source_url = metadata.get('isu', '')
|
||||
if source_url:
|
||||
source += " ({0})".format(source_url)
|
||||
|
||||
results.append({'url': metadata['ru'],
|
||||
'title': metadata['pt'],
|
||||
'content': metadata['s'],
|
||||
'content': metadata.get('s', ''),
|
||||
'source': source,
|
||||
'img_format': img_format,
|
||||
'thumbnail_src': metadata['tu'],
|
||||
|
|
|
|||
|
|
@ -75,15 +75,17 @@ def response(resp):
|
|||
|
||||
# get thumbnails
|
||||
script = str(dom.xpath('//script[contains(., "_setImagesSrc")]')[0].text)
|
||||
id = result.xpath('.//div[@class="s"]//img/@id')[0]
|
||||
thumbnails_data = re.findall('s=\'(.*?)(?:\\\\[a-z,1-9,\\\\]+\'|\')\;var ii=\[(?:|[\'vidthumb\d+\',]+)\'' + id,
|
||||
script)
|
||||
tmp = []
|
||||
if len(thumbnails_data) != 0:
|
||||
tmp = re.findall('(data:image/jpeg;base64,[a-z,A-Z,0-9,/,\+]+)', thumbnails_data[0])
|
||||
thumbnail = ''
|
||||
if len(tmp) != 0:
|
||||
thumbnail = tmp[-1]
|
||||
ids = result.xpath('.//div[@class="s"]//img/@id')
|
||||
if len(ids) > 0:
|
||||
thumbnails_data = \
|
||||
re.findall('s=\'(.*?)(?:\\\\[a-z,1-9,\\\\]+\'|\')\;var ii=\[(?:|[\'vidthumb\d+\',]+)\'' + ids[0],
|
||||
script)
|
||||
tmp = []
|
||||
if len(thumbnails_data) != 0:
|
||||
tmp = re.findall('(data:image/jpeg;base64,[a-z,A-Z,0-9,/,\+]+)', thumbnails_data[0])
|
||||
thumbnail = ''
|
||||
if len(tmp) != 0:
|
||||
thumbnail = tmp[-1]
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
|
|
|
|||
100
searx/engines/invidious.py
Normal file
100
searx/engines/invidious.py
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
# Invidious (Videos)
|
||||
#
|
||||
# @website https://invidio.us/
|
||||
# @provide-api yes (https://github.com/omarroth/invidious/wiki/API)
|
||||
#
|
||||
# @using-api yes
|
||||
# @results JSON
|
||||
# @stable yes
|
||||
# @parse url, title, content, publishedDate, thumbnail, embedded
|
||||
|
||||
from searx.url_utils import quote_plus
|
||||
from dateutil import parser
|
||||
import time
|
||||
|
||||
# engine dependent config
|
||||
categories = ["videos", "music"]
|
||||
paging = True
|
||||
language_support = True
|
||||
time_range_support = True
|
||||
|
||||
# search-url
|
||||
base_url = "https://invidio.us/"
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
time_range_dict = {
|
||||
"day": "today",
|
||||
"week": "week",
|
||||
"month": "month",
|
||||
"year": "year",
|
||||
}
|
||||
search_url = base_url + "api/v1/search?q={query}"
|
||||
params["url"] = search_url.format(
|
||||
query=quote_plus(query)
|
||||
) + "&page={pageno}".format(pageno=params["pageno"])
|
||||
|
||||
if params["time_range"] in time_range_dict:
|
||||
params["url"] += "&date={timerange}".format(
|
||||
timerange=time_range_dict[params["time_range"]]
|
||||
)
|
||||
|
||||
if params["language"] != "all":
|
||||
lang = params["language"].split("-")
|
||||
if len(lang) == 2:
|
||||
params["url"] += "&range={lrange}".format(lrange=lang[1])
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
search_results = resp.json()
|
||||
embedded_url = (
|
||||
'<iframe width="540" height="304" '
|
||||
+ 'data-src="'
|
||||
+ base_url
|
||||
+ 'embed/{videoid}" '
|
||||
+ 'frameborder="0" allowfullscreen></iframe>'
|
||||
)
|
||||
|
||||
base_invidious_url = base_url + "watch?v="
|
||||
|
||||
for result in search_results:
|
||||
rtype = result.get("type", None)
|
||||
if rtype == "video":
|
||||
videoid = result.get("videoId", None)
|
||||
if not videoid:
|
||||
continue
|
||||
|
||||
url = base_invidious_url + videoid
|
||||
embedded = embedded_url.format(videoid=videoid)
|
||||
thumbs = result.get("videoThumbnails", [])
|
||||
thumb = next(
|
||||
(th for th in thumbs if th["quality"] == "sddefault"), None
|
||||
)
|
||||
if thumb:
|
||||
thumbnail = thumb.get("url", "")
|
||||
else:
|
||||
thumbnail = ""
|
||||
|
||||
publishedDate = parser.parse(
|
||||
time.ctime(result.get("published", 0))
|
||||
)
|
||||
|
||||
results.append(
|
||||
{
|
||||
"url": url,
|
||||
"title": result.get("title", ""),
|
||||
"content": result.get("description", ""),
|
||||
"template": "videos.html",
|
||||
"publishedDate": publishedDate,
|
||||
"embedded": embedded,
|
||||
"thumbnail": thumbnail,
|
||||
}
|
||||
)
|
||||
|
||||
return results
|
||||
|
|
@ -24,7 +24,7 @@ result_base_url = 'https://openstreetmap.org/{osm_type}/{osm_id}'
|
|||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
params['url'] = base_url + search_string.format(query=query)
|
||||
params['url'] = base_url + search_string.format(query=query.decode('utf-8'))
|
||||
|
||||
return params
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ def request(query, params):
|
|||
language = match_language(params['language'], supported_languages, language_aliases)
|
||||
params['url'] += '&locale=' + language.replace('-', '_').lower()
|
||||
|
||||
params['headers']['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0'
|
||||
return params
|
||||
|
||||
|
||||
|
|
|
|||
78
searx/engines/seedpeer.py
Normal file
78
searx/engines/seedpeer.py
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
# Seedpeer (Videos, Music, Files)
|
||||
#
|
||||
# @website https://seedpeer.me
|
||||
# @provide-api no (nothing found)
|
||||
#
|
||||
# @using-api no
|
||||
# @results HTML (using search portal)
|
||||
# @stable yes (HTML can change)
|
||||
# @parse url, title, content, seed, leech, magnetlink
|
||||
|
||||
from lxml import html
|
||||
from json import loads
|
||||
from operator import itemgetter
|
||||
from searx.url_utils import quote, urljoin
|
||||
from searx.engines.xpath import extract_text
|
||||
|
||||
|
||||
url = 'https://seedpeer.me/'
|
||||
search_url = url + 'search/{search_term}?page={page_no}'
|
||||
torrent_file_url = url + 'torrent/{torrent_hash}'
|
||||
|
||||
# specific xpath variables
|
||||
script_xpath = '//script[@type="text/javascript"][not(@src)]'
|
||||
torrent_xpath = '(//table)[2]/tbody/tr'
|
||||
link_xpath = '(./td)[1]/a/@href'
|
||||
age_xpath = '(./td)[2]'
|
||||
size_xpath = '(./td)[3]'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
params['url'] = search_url.format(search_term=quote(query),
|
||||
page_no=params['pageno'])
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
dom = html.fromstring(resp.text)
|
||||
result_rows = dom.xpath(torrent_xpath)
|
||||
|
||||
try:
|
||||
script_element = dom.xpath(script_xpath)[0]
|
||||
json_string = script_element.text[script_element.text.find('{'):]
|
||||
torrents_json = loads(json_string)
|
||||
except:
|
||||
return []
|
||||
|
||||
# parse results
|
||||
for torrent_row, torrent_json in zip(result_rows, torrents_json['data']['list']):
|
||||
title = torrent_json['name']
|
||||
seed = int(torrent_json['seeds'])
|
||||
leech = int(torrent_json['peers'])
|
||||
size = int(torrent_json['size'])
|
||||
torrent_hash = torrent_json['hash']
|
||||
|
||||
torrentfile = torrent_file_url.format(torrent_hash=torrent_hash)
|
||||
magnetlink = 'magnet:?xt=urn:btih:{}'.format(torrent_hash)
|
||||
|
||||
age = extract_text(torrent_row.xpath(age_xpath))
|
||||
link = torrent_row.xpath(link_xpath)[0]
|
||||
|
||||
href = urljoin(url, link)
|
||||
|
||||
# append result
|
||||
results.append({'url': href,
|
||||
'title': title,
|
||||
'content': age,
|
||||
'seed': seed,
|
||||
'leech': leech,
|
||||
'filesize': size,
|
||||
'torrentfile': torrentfile,
|
||||
'magnetlink': magnetlink,
|
||||
'template': 'torrent.html'})
|
||||
|
||||
# return results sorted by seeder
|
||||
return sorted(results, key=itemgetter('seed'), reverse=True)
|
||||
|
|
@ -51,7 +51,9 @@ def get_client_id():
|
|||
|
||||
if response.ok:
|
||||
tree = html.fromstring(response.content)
|
||||
script_tags = tree.xpath("//script[contains(@src, '/assets/app')]")
|
||||
# script_tags has been moved from /assets/app/ to /assets/ path. I
|
||||
# found client_id in https://a-v2.sndcdn.com/assets/49-a0c01933-3.js
|
||||
script_tags = tree.xpath("//script[contains(@src, '/assets/')]")
|
||||
app_js_urls = [script_tag.get('src') for script_tag in script_tags if script_tag is not None]
|
||||
|
||||
# extracts valid app_js urls from soundcloud.com content
|
||||
|
|
@ -66,7 +68,7 @@ def get_client_id():
|
|||
return ""
|
||||
|
||||
|
||||
def init():
|
||||
def init(engine_settings=None):
|
||||
global guest_client_id
|
||||
# api-key
|
||||
guest_client_id = get_client_id()
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ from dateutil import parser
|
|||
from datetime import datetime, timedelta
|
||||
import re
|
||||
from searx.engines.xpath import extract_text
|
||||
from searx.languages import language_codes
|
||||
from searx.utils import eval_xpath
|
||||
|
||||
# engine dependent config
|
||||
categories = ['general']
|
||||
|
|
@ -22,7 +24,7 @@ categories = ['general']
|
|||
# (probably the parameter qid), require
|
||||
# storing of qid's between mulitble search-calls
|
||||
|
||||
# paging = False
|
||||
paging = True
|
||||
language_support = True
|
||||
|
||||
# search-url
|
||||
|
|
@ -32,23 +34,32 @@ search_url = base_url + 'do/search'
|
|||
# specific xpath variables
|
||||
# ads xpath //div[@id="results"]/div[@id="sponsored"]//div[@class="result"]
|
||||
# not ads: div[@class="result"] are the direct childs of div[@id="results"]
|
||||
results_xpath = '//li[contains(@class, "search-result") and contains(@class, "search-item")]'
|
||||
link_xpath = './/h3/a'
|
||||
content_xpath = './p[@class="search-item__body"]'
|
||||
results_xpath = '//div[@class="w-gl__result"]'
|
||||
link_xpath = './/a[@class="w-gl__result-title"]'
|
||||
content_xpath = './/p[@class="w-gl__description"]'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
offset = (params['pageno'] - 1) * 10
|
||||
|
||||
params['url'] = search_url
|
||||
params['method'] = 'POST'
|
||||
params['data'] = {'query': query,
|
||||
'startat': offset}
|
||||
params['data'] = {
|
||||
'query': query,
|
||||
'page': params['pageno'],
|
||||
'cat': 'web',
|
||||
'cmd': 'process_search',
|
||||
'engine0': 'v1all',
|
||||
}
|
||||
|
||||
# set language if specified
|
||||
if params['language'] != 'all':
|
||||
params['data']['with_language'] = ('lang_' + params['language'].split('-')[0])
|
||||
language = 'english'
|
||||
for lc, _, _, lang in language_codes:
|
||||
if lc == params['language']:
|
||||
language = lang
|
||||
params['data']['language'] = language
|
||||
params['data']['lui'] = language
|
||||
|
||||
return params
|
||||
|
||||
|
|
@ -60,8 +71,8 @@ def response(resp):
|
|||
dom = html.fromstring(resp.text)
|
||||
|
||||
# parse results
|
||||
for result in dom.xpath(results_xpath):
|
||||
links = result.xpath(link_xpath)
|
||||
for result in eval_xpath(dom, results_xpath):
|
||||
links = eval_xpath(result, link_xpath)
|
||||
if not links:
|
||||
continue
|
||||
link = links[0]
|
||||
|
|
@ -77,8 +88,8 @@ def response(resp):
|
|||
|
||||
title = extract_text(link)
|
||||
|
||||
if result.xpath(content_xpath):
|
||||
content = extract_text(result.xpath(content_xpath))
|
||||
if eval_xpath(result, content_xpath):
|
||||
content = extract_text(eval_xpath(result, content_xpath))
|
||||
else:
|
||||
content = ''
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from searx.poolrequests import get
|
|||
from searx.engines.xpath import extract_text
|
||||
from searx.engines.wikipedia import _fetch_supported_languages, supported_languages_url
|
||||
from searx.url_utils import urlencode
|
||||
from searx.utils import match_language
|
||||
from searx.utils import match_language, eval_xpath
|
||||
|
||||
from json import loads
|
||||
from lxml.html import fromstring
|
||||
|
|
@ -57,22 +57,6 @@ language_fallback_xpath = '//sup[contains(@class,"wb-language-fallback-indicator
|
|||
calendar_name_xpath = './/sup[contains(@class,"wb-calendar-name")]'
|
||||
media_xpath = value_xpath + '//div[contains(@class,"commons-media-caption")]//a'
|
||||
|
||||
# xpath_cache
|
||||
xpath_cache = {}
|
||||
|
||||
|
||||
def get_xpath(xpath_str):
|
||||
result = xpath_cache.get(xpath_str, None)
|
||||
if not result:
|
||||
result = etree.XPath(xpath_str)
|
||||
xpath_cache[xpath_str] = result
|
||||
return result
|
||||
|
||||
|
||||
def eval_xpath(element, xpath_str):
|
||||
xpath = get_xpath(xpath_str)
|
||||
return xpath(element)
|
||||
|
||||
|
||||
def get_id_cache(result):
|
||||
id_cache = {}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ search_url = base_url + u'w/api.php?'\
|
|||
'action=query'\
|
||||
'&format=json'\
|
||||
'&{query}'\
|
||||
'&prop=extracts|pageimages'\
|
||||
'&prop=extracts|pageimages|pageprops'\
|
||||
'&ppprop=disambiguation'\
|
||||
'&exintro'\
|
||||
'&explaintext'\
|
||||
'&pithumbsize=300'\
|
||||
|
|
@ -79,12 +80,15 @@ def response(resp):
|
|||
|
||||
# wikipedia article's unique id
|
||||
# first valid id is assumed to be the requested article
|
||||
if 'pages' not in search_result['query']:
|
||||
return results
|
||||
|
||||
for article_id in search_result['query']['pages']:
|
||||
page = search_result['query']['pages'][article_id]
|
||||
if int(article_id) > 0:
|
||||
break
|
||||
|
||||
if int(article_id) < 0:
|
||||
if int(article_id) < 0 or 'disambiguation' in page.get('pageprops', {}):
|
||||
return []
|
||||
|
||||
title = page.get('title')
|
||||
|
|
@ -96,6 +100,7 @@ def response(resp):
|
|||
extract = page.get('extract')
|
||||
|
||||
summary = extract_first_paragraph(extract, title, image)
|
||||
summary = summary.replace('() ', '')
|
||||
|
||||
# link to wikipedia article
|
||||
wikipedia_link = base_url.format(language=url_lang(resp.search_params['language'])) \
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ def obtain_token():
|
|||
return token
|
||||
|
||||
|
||||
def init():
|
||||
def init(engine_settings=None):
|
||||
obtain_token()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
"""
|
||||
|
||||
from lxml import html
|
||||
import re
|
||||
from searx.url_utils import urlencode, urljoin
|
||||
from searx.engines.xpath import extract_text
|
||||
|
||||
# engine dependent config
|
||||
categories = ['images']
|
||||
|
|
@ -34,41 +34,18 @@ def request(query, params):
|
|||
def response(resp):
|
||||
results = []
|
||||
|
||||
# get links from result-text
|
||||
regex = re.compile('(</a>|<a)')
|
||||
results_parts = re.split(regex, resp.text)
|
||||
|
||||
cur_element = ''
|
||||
|
||||
# iterate over link parts
|
||||
for result_part in results_parts:
|
||||
dom = html.fromstring(resp.text)
|
||||
for res in dom.xpath('//div[@class="List-item MainListing"]'):
|
||||
# processed start and end of link
|
||||
if result_part == '<a':
|
||||
cur_element = result_part
|
||||
continue
|
||||
elif result_part != '</a>':
|
||||
cur_element += result_part
|
||||
continue
|
||||
|
||||
cur_element += result_part
|
||||
|
||||
# fix xml-error
|
||||
cur_element = cur_element.replace('"></a>', '"/></a>')
|
||||
|
||||
dom = html.fromstring(cur_element)
|
||||
link = dom.xpath('//a')[0]
|
||||
link = res.xpath('//a')[0]
|
||||
|
||||
url = urljoin(base_url, link.attrib.get('href'))
|
||||
title = link.attrib.get('title', '')
|
||||
title = extract_text(link)
|
||||
|
||||
thumbnail_src = urljoin(base_url, link.xpath('.//img')[0].attrib['src'])
|
||||
thumbnail_src = urljoin(base_url, res.xpath('.//img')[0].attrib['src'])
|
||||
# TODO: get image with higher resolution
|
||||
img_src = thumbnail_src
|
||||
|
||||
# check if url is showing to a photo
|
||||
if '/photo/' not in url:
|
||||
continue
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from lxml import html
|
||||
from lxml.etree import _ElementStringResult, _ElementUnicodeResult
|
||||
from searx.utils import html_to_text
|
||||
from searx.utils import html_to_text, eval_xpath
|
||||
from searx.url_utils import unquote, urlencode, urljoin, urlparse
|
||||
|
||||
search_url = None
|
||||
|
|
@ -104,15 +104,15 @@ def response(resp):
|
|||
results = []
|
||||
dom = html.fromstring(resp.text)
|
||||
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))
|
||||
content = extract_text(result.xpath(content_xpath))
|
||||
for result in eval_xpath(dom, results_xpath):
|
||||
url = extract_url(eval_xpath(result, url_xpath), search_url)
|
||||
title = extract_text(eval_xpath(result, title_xpath))
|
||||
content = extract_text(eval_xpath(result, content_xpath))
|
||||
tmp_result = {'url': url, 'title': title, 'content': content}
|
||||
|
||||
# add thumbnail if available
|
||||
if thumbnail_xpath:
|
||||
thumbnail_xpath_result = result.xpath(thumbnail_xpath)
|
||||
thumbnail_xpath_result = eval_xpath(result, thumbnail_xpath)
|
||||
if len(thumbnail_xpath_result) > 0:
|
||||
tmp_result['img_src'] = extract_url(thumbnail_xpath_result, search_url)
|
||||
|
||||
|
|
@ -120,14 +120,14 @@ def response(resp):
|
|||
else:
|
||||
for url, title, content in zip(
|
||||
(extract_url(x, search_url) for
|
||||
x in dom.xpath(url_xpath)),
|
||||
map(extract_text, dom.xpath(title_xpath)),
|
||||
map(extract_text, dom.xpath(content_xpath))
|
||||
x in eval_xpath(dom, url_xpath)),
|
||||
map(extract_text, eval_xpath(dom, title_xpath)),
|
||||
map(extract_text, eval_xpath(dom, content_xpath))
|
||||
):
|
||||
results.append({'url': url, 'title': title, 'content': content})
|
||||
|
||||
if not suggestion_xpath:
|
||||
return results
|
||||
for suggestion in dom.xpath(suggestion_xpath):
|
||||
for suggestion in eval_xpath(dom, suggestion_xpath):
|
||||
results.append({'suggestion': extract_text(suggestion)})
|
||||
return results
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
from lxml import html
|
||||
from searx.engines.xpath import extract_text, extract_url
|
||||
from searx.url_utils import unquote, urlencode
|
||||
from searx.utils import match_language
|
||||
from searx.utils import match_language, eval_xpath
|
||||
|
||||
# engine dependent config
|
||||
categories = ['general']
|
||||
|
|
@ -109,21 +109,21 @@ def response(resp):
|
|||
dom = html.fromstring(resp.text)
|
||||
|
||||
try:
|
||||
results_num = int(dom.xpath('//div[@class="compPagination"]/span[last()]/text()')[0]
|
||||
results_num = int(eval_xpath(dom, '//div[@class="compPagination"]/span[last()]/text()')[0]
|
||||
.split()[0].replace(',', ''))
|
||||
results.append({'number_of_results': results_num})
|
||||
except:
|
||||
pass
|
||||
|
||||
# parse results
|
||||
for result in dom.xpath(results_xpath):
|
||||
for result in eval_xpath(dom, results_xpath):
|
||||
try:
|
||||
url = parse_url(extract_url(result.xpath(url_xpath), search_url))
|
||||
title = extract_text(result.xpath(title_xpath)[0])
|
||||
url = parse_url(extract_url(eval_xpath(result, url_xpath), search_url))
|
||||
title = extract_text(eval_xpath(result, title_xpath)[0])
|
||||
except:
|
||||
continue
|
||||
|
||||
content = extract_text(result.xpath(content_xpath)[0])
|
||||
content = extract_text(eval_xpath(result, content_xpath)[0])
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
|
|
@ -131,7 +131,7 @@ def response(resp):
|
|||
'content': content})
|
||||
|
||||
# if no suggestion found, return results
|
||||
suggestions = dom.xpath(suggestion_xpath)
|
||||
suggestions = eval_xpath(dom, suggestion_xpath)
|
||||
if not suggestions:
|
||||
return results
|
||||
|
||||
|
|
@ -148,9 +148,9 @@ def response(resp):
|
|||
def _fetch_supported_languages(resp):
|
||||
supported_languages = []
|
||||
dom = html.fromstring(resp.text)
|
||||
options = dom.xpath('//div[@id="yschlang"]/span/label/input')
|
||||
options = eval_xpath(dom, '//div[@id="yschlang"]/span/label/input')
|
||||
for option in options:
|
||||
code_parts = option.xpath('./@value')[0][5:].split('_')
|
||||
code_parts = eval_xpath(option, './@value')[0][5:].split('_')
|
||||
if len(code_parts) == 2:
|
||||
code = code_parts[0] + '-' + code_parts[1].upper()
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -67,12 +67,8 @@ def response(resp):
|
|||
if videoid is not None:
|
||||
url = base_youtube_url + videoid
|
||||
thumbnail = 'https://i.ytimg.com/vi/' + videoid + '/hqdefault.jpg'
|
||||
title = video.get('title', {}).get('simpleText', videoid)
|
||||
description_snippet = video.get('descriptionSnippet', {})
|
||||
if 'runs' in description_snippet:
|
||||
content = reduce(lambda a, b: a + b.get('text', ''), description_snippet.get('runs'), '')
|
||||
else:
|
||||
content = description_snippet.get('simpleText', '')
|
||||
title = get_text_from_json(video.get('title', {}))
|
||||
content = get_text_from_json(video.get('descriptionSnippet', {}))
|
||||
embedded = embedded_url.format(videoid=videoid)
|
||||
|
||||
# append result
|
||||
|
|
@ -85,3 +81,10 @@ def response(resp):
|
|||
|
||||
# return results
|
||||
return results
|
||||
|
||||
|
||||
def get_text_from_json(element):
|
||||
if 'runs' in element:
|
||||
return reduce(lambda a, b: a + b.get('text', ''), element.get('runs'), '')
|
||||
else:
|
||||
return element.get('simpleText', '')
|
||||
|
|
|
|||
|
|
@ -28,5 +28,6 @@ class SearxParameterException(SearxException):
|
|||
else:
|
||||
message = 'Invalid value "' + value + '" for parameter ' + name
|
||||
super(SearxParameterException, self).__init__(message)
|
||||
self.message = message
|
||||
self.parameter_name = name
|
||||
self.parameter_value = value
|
||||
|
|
|
|||
|
|
@ -225,6 +225,9 @@ def https_url_rewrite(result):
|
|||
|
||||
|
||||
def on_result(request, search, result):
|
||||
if 'parsed_url' not in result:
|
||||
return True
|
||||
|
||||
if result['parsed_url'].scheme == 'http':
|
||||
https_url_rewrite(result)
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ def get_doi_resolver(args, preference_doi_resolver):
|
|||
|
||||
|
||||
def on_result(request, search, result):
|
||||
if 'parsed_url' not in result:
|
||||
return True
|
||||
|
||||
doi = extract_doi(result['parsed_url'])
|
||||
if doi and len(doi) < 50:
|
||||
for suffix in ('/', '.pdf', '/full', '/meta', '/abstract'):
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
|
|||
|
||||
from flask_babel import gettext
|
||||
import re
|
||||
from searx.url_utils import urlunparse
|
||||
from searx.url_utils import urlunparse, parse_qsl, urlencode
|
||||
|
||||
regexes = {re.compile(r'utm_[^&]+&?'),
|
||||
re.compile(r'(wkey|wemail)[^&]+&?'),
|
||||
regexes = {re.compile(r'utm_[^&]+'),
|
||||
re.compile(r'(wkey|wemail)[^&]*'),
|
||||
re.compile(r'&$')}
|
||||
|
||||
name = gettext('Tracker URL remover')
|
||||
|
|
@ -30,16 +30,23 @@ preference_section = 'privacy'
|
|||
|
||||
|
||||
def on_result(request, search, result):
|
||||
if 'parsed_url' not in result:
|
||||
return True
|
||||
|
||||
query = result['parsed_url'].query
|
||||
|
||||
if query == "":
|
||||
return True
|
||||
parsed_query = parse_qsl(query)
|
||||
|
||||
for reg in regexes:
|
||||
query = reg.sub('', query)
|
||||
|
||||
if query != result['parsed_url'].query:
|
||||
result['parsed_url'] = result['parsed_url']._replace(query=query)
|
||||
result['url'] = urlunparse(result['parsed_url'])
|
||||
changes = 0
|
||||
for i, (param_name, _) in enumerate(list(parsed_query)):
|
||||
for reg in regexes:
|
||||
if reg.match(param_name):
|
||||
parsed_query.pop(i - changes)
|
||||
changes += 1
|
||||
result['parsed_url'] = result['parsed_url']._replace(query=urlencode(parsed_query))
|
||||
result['url'] = urlunparse(result['parsed_url'])
|
||||
break
|
||||
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ class RawTextQuery(object):
|
|||
self.query_parts = []
|
||||
self.engines = []
|
||||
self.languages = []
|
||||
self.timeout_limit = None
|
||||
self.specific = False
|
||||
|
||||
# parse query, if tags are set, which
|
||||
|
|
@ -69,6 +70,21 @@ class RawTextQuery(object):
|
|||
self.query_parts.append(query_part)
|
||||
continue
|
||||
|
||||
# this force the timeout
|
||||
if query_part[0] == '<':
|
||||
try:
|
||||
raw_timeout_limit = int(query_part[1:])
|
||||
if raw_timeout_limit < 100:
|
||||
# below 100, the unit is the second ( <3 = 3 seconds timeout )
|
||||
self.timeout_limit = float(raw_timeout_limit)
|
||||
else:
|
||||
# 100 or above, the unit is the millisecond ( <850 = 850 milliseconds timeout )
|
||||
self.timeout_limit = raw_timeout_limit / 1000.0
|
||||
parse_next = True
|
||||
except ValueError:
|
||||
# error not reported to the user
|
||||
pass
|
||||
|
||||
# this force a language
|
||||
if query_part[0] == ':':
|
||||
lang = query_part[1:].lower().replace('_', '-')
|
||||
|
|
@ -161,14 +177,15 @@ class RawTextQuery(object):
|
|||
class SearchQuery(object):
|
||||
"""container for all the search parameters (query, language, etc...)"""
|
||||
|
||||
def __init__(self, query, engines, categories, lang, safesearch, pageno, time_range):
|
||||
def __init__(self, query, engines, categories, lang, safesearch, pageno, time_range, timeout_limit=None):
|
||||
self.query = query.encode('utf-8')
|
||||
self.engines = engines
|
||||
self.categories = categories
|
||||
self.lang = lang
|
||||
self.safesearch = safesearch
|
||||
self.pageno = pageno
|
||||
self.time_range = time_range
|
||||
self.time_range = None if time_range in ('', 'None', None) else time_range
|
||||
self.timeout_limit = timeout_limit
|
||||
|
||||
def __str__(self):
|
||||
return str(self.query) + ";" + str(self.engines)
|
||||
|
|
|
|||
|
|
@ -67,8 +67,9 @@ def merge_two_infoboxes(infobox1, infobox2):
|
|||
|
||||
for url2 in infobox2.get('urls', []):
|
||||
unique_url = True
|
||||
for url1 in infobox1.get('urls', []):
|
||||
if compare_urls(urlparse(url1.get('url', '')), urlparse(url2.get('url', ''))):
|
||||
parsed_url2 = urlparse(url2.get('url', ''))
|
||||
for url1 in urls1:
|
||||
if compare_urls(urlparse(url1.get('url', '')), parsed_url2):
|
||||
unique_url = False
|
||||
break
|
||||
if unique_url:
|
||||
|
|
@ -188,8 +189,9 @@ class ResultContainer(object):
|
|||
add_infobox = True
|
||||
infobox_id = infobox.get('id', None)
|
||||
if infobox_id is not None:
|
||||
parsed_url_infobox_id = urlparse(infobox_id)
|
||||
for existingIndex in self.infoboxes:
|
||||
if compare_urls(urlparse(existingIndex.get('id', '')), urlparse(infobox_id)):
|
||||
if compare_urls(urlparse(existingIndex.get('id', '')), parsed_url_infobox_id):
|
||||
merge_two_infoboxes(existingIndex, infobox)
|
||||
add_infobox = False
|
||||
|
||||
|
|
@ -197,6 +199,13 @@ class ResultContainer(object):
|
|||
self.infoboxes.append(infobox)
|
||||
|
||||
def _merge_result(self, result, position):
|
||||
if 'url' in result:
|
||||
self.__merge_url_result(result, position)
|
||||
return
|
||||
|
||||
self.__merge_result_no_url(result, position)
|
||||
|
||||
def __merge_url_result(self, result, position):
|
||||
result['parsed_url'] = urlparse(result['url'])
|
||||
|
||||
# if the result has no scheme, use http as default
|
||||
|
|
@ -210,51 +219,60 @@ class ResultContainer(object):
|
|||
if result.get('content'):
|
||||
result['content'] = WHITESPACE_REGEX.sub(' ', result['content'])
|
||||
|
||||
# check for duplicates
|
||||
duplicated = False
|
||||
duplicated = self.__find_duplicated_http_result(result)
|
||||
if duplicated:
|
||||
self.__merge_duplicated_http_result(duplicated, result, position)
|
||||
return
|
||||
|
||||
# if there is no duplicate found, append result
|
||||
result['positions'] = [position]
|
||||
with RLock():
|
||||
self._merged_results.append(result)
|
||||
|
||||
def __find_duplicated_http_result(self, result):
|
||||
result_template = result.get('template')
|
||||
for merged_result in self._merged_results:
|
||||
if 'parsed_url' not in merged_result:
|
||||
continue
|
||||
if compare_urls(result['parsed_url'], merged_result['parsed_url'])\
|
||||
and result_template == merged_result.get('template'):
|
||||
if result_template != 'images.html':
|
||||
# not an image, same template, same url : it's a duplicate
|
||||
duplicated = merged_result
|
||||
break
|
||||
return merged_result
|
||||
else:
|
||||
# it's an image
|
||||
# it's a duplicate if the parsed_url, template and img_src are differents
|
||||
if result.get('img_src', '') == merged_result.get('img_src', ''):
|
||||
duplicated = merged_result
|
||||
break
|
||||
return merged_result
|
||||
return None
|
||||
|
||||
# merge duplicates together
|
||||
if duplicated:
|
||||
# using content with more text
|
||||
if result_content_len(result.get('content', '')) >\
|
||||
result_content_len(duplicated.get('content', '')):
|
||||
duplicated['content'] = result['content']
|
||||
def __merge_duplicated_http_result(self, duplicated, result, position):
|
||||
# using content with more text
|
||||
if result_content_len(result.get('content', '')) >\
|
||||
result_content_len(duplicated.get('content', '')):
|
||||
duplicated['content'] = result['content']
|
||||
|
||||
# merge all result's parameters not found in duplicate
|
||||
for key in result.keys():
|
||||
if not duplicated.get(key):
|
||||
duplicated[key] = result.get(key)
|
||||
# merge all result's parameters not found in duplicate
|
||||
for key in result.keys():
|
||||
if not duplicated.get(key):
|
||||
duplicated[key] = result.get(key)
|
||||
|
||||
# add the new position
|
||||
duplicated['positions'].append(position)
|
||||
# add the new position
|
||||
duplicated['positions'].append(position)
|
||||
|
||||
# add engine to list of result-engines
|
||||
duplicated['engines'].add(result['engine'])
|
||||
# add engine to list of result-engines
|
||||
duplicated['engines'].add(result['engine'])
|
||||
|
||||
# using https if possible
|
||||
if duplicated['parsed_url'].scheme != 'https' and result['parsed_url'].scheme == 'https':
|
||||
duplicated['url'] = result['parsed_url'].geturl()
|
||||
duplicated['parsed_url'] = result['parsed_url']
|
||||
# using https if possible
|
||||
if duplicated['parsed_url'].scheme != 'https' and result['parsed_url'].scheme == 'https':
|
||||
duplicated['url'] = result['parsed_url'].geturl()
|
||||
duplicated['parsed_url'] = result['parsed_url']
|
||||
|
||||
# if there is no duplicate found, append result
|
||||
else:
|
||||
result['positions'] = [position]
|
||||
with RLock():
|
||||
self._merged_results.append(result)
|
||||
def __merge_result_no_url(self, result, position):
|
||||
result['engines'] = set([result['engine']])
|
||||
result['positions'] = [position]
|
||||
with RLock():
|
||||
self._merged_results.append(result)
|
||||
|
||||
def order_results(self):
|
||||
for result in self._merged_results:
|
||||
|
|
|
|||
130
searx/search.py
130
searx/search.py
|
|
@ -45,6 +45,16 @@ if sys.version_info[0] == 3:
|
|||
logger = logger.getChild('search')
|
||||
|
||||
number_of_searches = 0
|
||||
max_request_timeout = settings.get('outgoing', {}).get('max_request_timeout' or None)
|
||||
if max_request_timeout is None:
|
||||
logger.info('max_request_timeout={0}'.format(max_request_timeout))
|
||||
else:
|
||||
if isinstance(max_request_timeout, float):
|
||||
logger.info('max_request_timeout={0} second(s)'.format(max_request_timeout))
|
||||
else:
|
||||
logger.critical('outgoing.max_request_timeout if defined has to be float')
|
||||
from sys import exit
|
||||
exit(1)
|
||||
|
||||
|
||||
def send_http_request(engine, request_params):
|
||||
|
|
@ -67,7 +77,7 @@ def send_http_request(engine, request_params):
|
|||
return req(request_params['url'], **request_args)
|
||||
|
||||
|
||||
def search_one_request(engine, query, request_params):
|
||||
def search_one_http_request(engine, query, request_params):
|
||||
# update request parameters dependent on
|
||||
# search-engine (contained in engines folder)
|
||||
engine.request(query, request_params)
|
||||
|
|
@ -87,7 +97,53 @@ def search_one_request(engine, query, request_params):
|
|||
return engine.response(response)
|
||||
|
||||
|
||||
def search_one_offline_request(engine, query, request_params):
|
||||
return engine.search(query, request_params)
|
||||
|
||||
|
||||
def search_one_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit):
|
||||
if engines[engine_name].offline:
|
||||
return search_one_offline_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit) # noqa
|
||||
return search_one_http_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit)
|
||||
|
||||
|
||||
def search_one_offline_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit):
|
||||
engine = engines[engine_name]
|
||||
|
||||
try:
|
||||
search_results = search_one_offline_request(engine, query, request_params)
|
||||
|
||||
if search_results:
|
||||
result_container.extend(engine_name, search_results)
|
||||
|
||||
engine_time = time() - start_time
|
||||
result_container.add_timing(engine_name, engine_time, engine_time)
|
||||
with threading.RLock():
|
||||
engine.stats['engine_time'] += engine_time
|
||||
engine.stats['engine_time_count'] += 1
|
||||
|
||||
except ValueError as e:
|
||||
record_offline_engine_stats_on_error(engine, result_container, start_time)
|
||||
logger.exception('engine {0} : invalid input : {1}'.format(engine_name, e))
|
||||
except Exception as e:
|
||||
record_offline_engine_stats_on_error(engine, result_container, start_time)
|
||||
|
||||
result_container.add_unresponsive_engine((
|
||||
engine_name,
|
||||
u'{0}: {1}'.format(gettext('unexpected crash'), e),
|
||||
))
|
||||
logger.exception('engine {0} : exception : {1}'.format(engine_name, e))
|
||||
|
||||
|
||||
def record_offline_engine_stats_on_error(engine, result_container, start_time):
|
||||
engine_time = time() - start_time
|
||||
result_container.add_timing(engine.name, engine_time, engine_time)
|
||||
|
||||
with threading.RLock():
|
||||
engine.stats['errors'] += 1
|
||||
|
||||
|
||||
def search_one_http_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit):
|
||||
# set timeout for all HTTP requests
|
||||
requests_lib.set_timeout_for_thread(timeout_limit, start_time=start_time)
|
||||
# reset the HTTP total time
|
||||
|
|
@ -101,7 +157,7 @@ def search_one_request_safe(engine_name, query, request_params, result_container
|
|||
|
||||
try:
|
||||
# send requests and parse the results
|
||||
search_results = search_one_request(engine, query, request_params)
|
||||
search_results = search_one_http_request(engine, query, request_params)
|
||||
|
||||
# check if the engine accepted the request
|
||||
if search_results is not None:
|
||||
|
|
@ -265,6 +321,18 @@ def get_search_query_from_webapp(preferences, form):
|
|||
# query_engines
|
||||
query_engines = raw_text_query.engines
|
||||
|
||||
# timeout_limit
|
||||
query_timeout = raw_text_query.timeout_limit
|
||||
if query_timeout is None and 'timeout_limit' in form:
|
||||
raw_time_limit = form.get('timeout_limit')
|
||||
if raw_time_limit in ['None', '']:
|
||||
raw_time_limit = None
|
||||
else:
|
||||
try:
|
||||
query_timeout = float(raw_time_limit)
|
||||
except ValueError:
|
||||
raise SearxParameterException('timeout_limit', raw_time_limit)
|
||||
|
||||
# query_categories
|
||||
query_categories = []
|
||||
|
||||
|
|
@ -338,7 +406,8 @@ def get_search_query_from_webapp(preferences, form):
|
|||
query_engines = deduplicate_query_engines(query_engines)
|
||||
|
||||
return (SearchQuery(query, query_engines, query_categories,
|
||||
query_lang, query_safesearch, query_pageno, query_time_range),
|
||||
query_lang, query_safesearch, query_pageno,
|
||||
query_time_range, query_timeout),
|
||||
raw_text_query)
|
||||
|
||||
|
||||
|
|
@ -351,6 +420,7 @@ class Search(object):
|
|||
super(Search, self).__init__()
|
||||
self.search_query = search_query
|
||||
self.result_container = ResultContainer()
|
||||
self.actual_timeout = None
|
||||
|
||||
# do search-request
|
||||
def search(self):
|
||||
|
|
@ -380,7 +450,7 @@ class Search(object):
|
|||
search_query = self.search_query
|
||||
|
||||
# max of all selected engine timeout
|
||||
timeout_limit = 0
|
||||
default_timeout = 0
|
||||
|
||||
# start search-reqest for all selected engines
|
||||
for selected_engine in search_query.engines:
|
||||
|
|
@ -403,29 +473,51 @@ class Search(object):
|
|||
continue
|
||||
|
||||
# set default request parameters
|
||||
request_params = default_request_params()
|
||||
request_params['headers']['User-Agent'] = user_agent
|
||||
request_params = {}
|
||||
if not engine.offline:
|
||||
request_params = default_request_params()
|
||||
request_params['headers']['User-Agent'] = user_agent
|
||||
|
||||
if hasattr(engine, 'language') and engine.language:
|
||||
request_params['language'] = engine.language
|
||||
else:
|
||||
request_params['language'] = search_query.lang
|
||||
|
||||
request_params['safesearch'] = search_query.safesearch
|
||||
request_params['time_range'] = search_query.time_range
|
||||
|
||||
request_params['category'] = selected_engine['category']
|
||||
request_params['pageno'] = search_query.pageno
|
||||
|
||||
if hasattr(engine, 'language') and engine.language:
|
||||
request_params['language'] = engine.language
|
||||
else:
|
||||
request_params['language'] = search_query.lang
|
||||
|
||||
# 0 = None, 1 = Moderate, 2 = Strict
|
||||
request_params['safesearch'] = search_query.safesearch
|
||||
request_params['time_range'] = search_query.time_range
|
||||
|
||||
# append request to list
|
||||
requests.append((selected_engine['name'], search_query.query, request_params))
|
||||
|
||||
# update timeout_limit
|
||||
timeout_limit = max(timeout_limit, engine.timeout)
|
||||
# update default_timeout
|
||||
default_timeout = max(default_timeout, engine.timeout)
|
||||
|
||||
# adjust timeout
|
||||
self.actual_timeout = default_timeout
|
||||
query_timeout = self.search_query.timeout_limit
|
||||
|
||||
if max_request_timeout is None and query_timeout is None:
|
||||
# No max, no user query: default_timeout
|
||||
pass
|
||||
elif max_request_timeout is None and query_timeout is not None:
|
||||
# No max, but user query: From user query except if above default
|
||||
self.actual_timeout = min(default_timeout, query_timeout)
|
||||
elif max_request_timeout is not None and query_timeout is None:
|
||||
# Max, no user query: Default except if above max
|
||||
self.actual_timeout = min(default_timeout, max_request_timeout)
|
||||
elif max_request_timeout is not None and query_timeout is not None:
|
||||
# Max & user query: From user query except if above max
|
||||
self.actual_timeout = min(query_timeout, max_request_timeout)
|
||||
|
||||
logger.debug("actual_timeout={0} (default_timeout={1}, ?timeout_limit={2}, max_request_timeout={3})"
|
||||
.format(self.actual_timeout, default_timeout, query_timeout, max_request_timeout))
|
||||
|
||||
# send all search-request
|
||||
if requests:
|
||||
# send all search-request
|
||||
search_multiple_requests(requests, self.result_container, start_time, timeout_limit)
|
||||
search_multiple_requests(requests, self.result_container, start_time, self.actual_timeout)
|
||||
start_new_thread(gc.collect, tuple())
|
||||
|
||||
# return results, suggestions, answers and infoboxes
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ ui:
|
|||
# key : !!binary "your_morty_proxy_key"
|
||||
|
||||
outgoing: # communication with search engines
|
||||
request_timeout : 2.0 # seconds
|
||||
request_timeout : 2.0 # default timeout in seconds, can be override by engine
|
||||
# max_request_timeout: 10.0 # the maximum timeout in seconds
|
||||
useragent_suffix : "" # suffix of searx_useragent, could contain informations like an email address to the administrator
|
||||
pool_connections : 100 # Number of different hosts
|
||||
pool_maxsize : 10 # Number of simultaneous requests by host
|
||||
|
|
@ -160,11 +161,12 @@ engines:
|
|||
weight : 2
|
||||
disabled : True
|
||||
|
||||
- name : digbt
|
||||
engine : digbt
|
||||
shortcut : dbt
|
||||
timeout : 6.0
|
||||
disabled : True
|
||||
# cloudflare protected
|
||||
# - name : digbt
|
||||
# engine : digbt
|
||||
# shortcut : dbt
|
||||
# timeout : 6.0
|
||||
# disabled : True
|
||||
|
||||
- name : digg
|
||||
engine : digg
|
||||
|
|
@ -203,11 +205,11 @@ engines:
|
|||
- name : etymonline
|
||||
engine : xpath
|
||||
paging : True
|
||||
search_url : http://etymonline.com/?search={query}&p={pageno}
|
||||
url_xpath : //a[contains(@class, "word--")]/@href
|
||||
title_xpath : //p[contains(@class, "word__name--")]/text()
|
||||
content_xpath : //section[contains(@class, "word__defination")]/object
|
||||
first_page_num : 0
|
||||
search_url : https://etymonline.com/search?page={pageno}&q={query}
|
||||
url_xpath : //a[contains(@class, "word__name--")]/@href
|
||||
title_xpath : //a[contains(@class, "word__name--")]
|
||||
content_xpath : //section[contains(@class, "word__defination")]
|
||||
first_page_num : 1
|
||||
shortcut : et
|
||||
disabled : True
|
||||
|
||||
|
|
@ -392,6 +394,12 @@ engines:
|
|||
timeout : 6.0
|
||||
disabled : True
|
||||
|
||||
- name : invidious
|
||||
engine : invidious
|
||||
base_url : 'https://invidio.us/'
|
||||
shortcut: iv
|
||||
timeout : 5.0
|
||||
|
||||
- name: kickass
|
||||
engine : kickass
|
||||
shortcut : kc
|
||||
|
|
@ -400,7 +408,7 @@ engines:
|
|||
|
||||
- name : library genesis
|
||||
engine : xpath
|
||||
search_url : http://libgen.io/search.php?req={query}
|
||||
search_url : https://libgen.is/search.php?req={query}
|
||||
url_xpath : //a[contains(@href,"bookfi.net")]/@href
|
||||
title_xpath : //a[contains(@href,"book/")]/text()[1]
|
||||
content_xpath : //td/a[1][contains(@href,"=author")]/text()
|
||||
|
|
@ -456,7 +464,7 @@ engines:
|
|||
- name : openairedatasets
|
||||
engine : json_engine
|
||||
paging : True
|
||||
search_url : http://api.openaire.eu/search/datasets?format=json&page={pageno}&size=10&title={query}
|
||||
search_url : https://api.openaire.eu/search/datasets?format=json&page={pageno}&size=10&title={query}
|
||||
results_query : response/results/result
|
||||
url_query : metadata/oaf:entity/oaf:result/children/instance/webresource/url/$
|
||||
title_query : metadata/oaf:entity/oaf:result/title/$
|
||||
|
|
@ -468,7 +476,7 @@ engines:
|
|||
- name : openairepublications
|
||||
engine : json_engine
|
||||
paging : True
|
||||
search_url : http://api.openaire.eu/search/publications?format=json&page={pageno}&size=10&title={query}
|
||||
search_url : https://api.openaire.eu/search/publications?format=json&page={pageno}&size=10&title={query}
|
||||
results_query : response/results/result
|
||||
url_query : metadata/oaf:entity/oaf:result/children/instance/webresource/url/$
|
||||
title_query : metadata/oaf:entity/oaf:result/title/$
|
||||
|
|
@ -699,9 +707,9 @@ engines:
|
|||
shortcut: vo
|
||||
categories: social media
|
||||
search_url : https://searchvoat.co/?t={query}
|
||||
url_xpath : //div[@class="entry"]/p/a[@class="title"]/@href
|
||||
title_xpath : //div[@class="entry"]/p/a[@class="title"]
|
||||
content_xpath : //div[@class="entry"]/p/span[@class="domain"]
|
||||
url_xpath : //div[@class="entry"]//p[@class="title"]/a/@href
|
||||
title_xpath : //div[@class="entry"]//p[@class="title"]/a/text()
|
||||
content_xpath : //div[@class="entry"]//span[@class="domain"]/a/text()
|
||||
timeout : 10.0
|
||||
disabled : True
|
||||
|
||||
|
|
@ -739,10 +747,15 @@ engines:
|
|||
title_xpath : ./h2
|
||||
content_xpath : ./p[@class="s"]
|
||||
suggestion_xpath : /html/body//div[@class="top-info"]/p[@class="top-info spell"]/a
|
||||
first_page_num : 1
|
||||
first_page_num : 0
|
||||
page_size : 10
|
||||
disabled : True
|
||||
|
||||
- name : seedpeer
|
||||
shortcut : speu
|
||||
engine : seedpeer
|
||||
categories: files, music, videos
|
||||
|
||||
# - name : yacy
|
||||
# engine : yacy
|
||||
# shortcut : ya
|
||||
|
|
@ -802,7 +815,7 @@ locales:
|
|||
doi_resolvers :
|
||||
oadoi.org : 'https://oadoi.org/'
|
||||
doi.org : 'https://doi.org/'
|
||||
doai.io : 'http://doai.io/'
|
||||
sci-hub.tw : 'http://sci-hub.tw/'
|
||||
doai.io : 'https://doai.io/'
|
||||
sci-hub.tw : 'https://sci-hub.tw/'
|
||||
|
||||
default_doi_resolver : 'oadoi.org'
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ locales:
|
|||
doi_resolvers :
|
||||
oadoi.org : 'https://oadoi.org/'
|
||||
doi.org : 'https://doi.org/'
|
||||
doai.io : 'http://doai.io/'
|
||||
sci-hub.tw : 'http://sci-hub.tw/'
|
||||
doai.io : 'https://doai.io/'
|
||||
sci-hub.tw : 'https://sci-hub.tw/'
|
||||
|
||||
default_doi_resolver : 'oadoi.org'
|
||||
|
|
|
|||
2
searx/static/css/bootstrap.min.css
vendored
2
searx/static/css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
|
|
@ -125,6 +125,14 @@ $(document).ready(function() {
|
|||
}
|
||||
});
|
||||
|
||||
function nextResult(current, direction) {
|
||||
var next = current[direction]();
|
||||
while (!next.is('.result') && next.length !== 0) {
|
||||
next = next[direction]();
|
||||
}
|
||||
return next
|
||||
}
|
||||
|
||||
function highlightResult(which) {
|
||||
return function() {
|
||||
var current = $('.result[data-vim-selected]');
|
||||
|
|
@ -157,13 +165,13 @@ $(document).ready(function() {
|
|||
}
|
||||
break;
|
||||
case 'down':
|
||||
next = current.next('.result');
|
||||
next = nextResult(current, 'next');
|
||||
if (next.length === 0) {
|
||||
next = $('.result:first');
|
||||
}
|
||||
break;
|
||||
case 'up':
|
||||
next = current.prev('.result');
|
||||
next = nextResult(current, 'prev');
|
||||
if (next.length === 0) {
|
||||
next = $('.result:last');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
.q{padding:.5em 1em .5em 3em}#search_submit{left:0;right:auto}.result .favicon{float:right;margin-left:.5em;margin-right:0}#sidebar{right:auto;left:0}#results{padding:0 32px 0 272px}.search.center{padding-right:0;padding-left:17em}.right{right:auto;left:0}#pagination form+form{float:left;margin-top:-2em}.engine-table{text-align:right}
|
||||
#search_submit,#sidebar,.right{right:auto;left:0}.q{padding:.5em 1em .5em 3em}.result .favicon{float:right;margin-left:.5em;margin-right:0}#results{padding:0 32px 0 272px}.search.center{padding-right:0;padding-left:17em}#pagination form+form{float:left;margin-top:-2em}.engine-table{text-align:right}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -325,6 +325,10 @@ a {
|
|||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.result .engines {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.result .content {
|
||||
margin: 0;
|
||||
color: #666;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,61 +1,61 @@
|
|||
/*
|
||||
* searx, A privacy-respecting, hackable metasearch engine
|
||||
*/
|
||||
|
||||
ul {
|
||||
&.autocompleter-choices {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
border: 1px solid @color-autocompleter-choices-border;
|
||||
border-left-color: @color-autocompleter-choices-border-left-right;
|
||||
border-right-color: @color-autocompleter-choices-border-left-right;
|
||||
border-bottom-color: @color-autocompleter-choices-border-bottom;
|
||||
text-align: left;
|
||||
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
||||
z-index: 50;
|
||||
background-color: @color-autocompleter-choices-background;
|
||||
color: @color-autocompleter-choices-font;
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
margin: -2px 0 0 0;
|
||||
padding: 0.2em 1.5em 0.2em 1em;
|
||||
display: block;
|
||||
float: none !important;
|
||||
cursor: pointer;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
font-size: 1em;
|
||||
line-height: 1.5em;
|
||||
|
||||
&.autocompleter-selected {
|
||||
background-color: @color-autocompleter-selected-background;
|
||||
color: @color-autocompleter-selected-font;
|
||||
|
||||
span.autocompleter-queried {
|
||||
color: @color-autocompleter-selected-queried-font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
span.autocompleter-queried {
|
||||
display: inline;
|
||||
float: none;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*.autocompleter-loading {
|
||||
//background-image: url(images/spinner.gif);
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 50%;
|
||||
}*/
|
||||
|
||||
/*textarea.autocompleter-loading {
|
||||
background-position: right bottom;
|
||||
}*/
|
||||
/*
|
||||
* searx, A privacy-respecting, hackable metasearch engine
|
||||
*/
|
||||
|
||||
ul {
|
||||
&.autocompleter-choices {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
border: 1px solid @color-autocompleter-choices-border;
|
||||
border-left-color: @color-autocompleter-choices-border-left-right;
|
||||
border-right-color: @color-autocompleter-choices-border-left-right;
|
||||
border-bottom-color: @color-autocompleter-choices-border-bottom;
|
||||
text-align: left;
|
||||
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
||||
z-index: 50;
|
||||
background-color: @color-autocompleter-choices-background;
|
||||
color: @color-autocompleter-choices-font;
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
margin: -2px 0 0 0;
|
||||
padding: 0.2em 1.5em 0.2em 1em;
|
||||
display: block;
|
||||
float: none !important;
|
||||
cursor: pointer;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
font-size: 1em;
|
||||
line-height: 1.5em;
|
||||
|
||||
&.autocompleter-selected {
|
||||
background-color: @color-autocompleter-selected-background;
|
||||
color: @color-autocompleter-selected-font;
|
||||
|
||||
span.autocompleter-queried {
|
||||
color: @color-autocompleter-selected-queried-font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
span.autocompleter-queried {
|
||||
display: inline;
|
||||
float: none;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*.autocompleter-loading {
|
||||
//background-image: url(images/spinner.gif);
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 50%;
|
||||
}*/
|
||||
|
||||
/*textarea.autocompleter-loading {
|
||||
background-position: right bottom;
|
||||
}*/
|
||||
|
|
|
|||
|
|
@ -376,6 +376,10 @@ table {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.result-table {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
|
|
|||
732
searx/static/themes/oscar/css/logicodev-dark.css
Normal file
732
searx/static/themes/oscar/css/logicodev-dark.css
Normal file
|
|
@ -0,0 +1,732 @@
|
|||
.searx-navbar {
|
||||
background: #29314d;
|
||||
height: 2.3rem;
|
||||
font-size: 1.3rem;
|
||||
line-height: 1.3rem;
|
||||
padding: 0.5rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.8rem;
|
||||
}
|
||||
.searx-navbar a,
|
||||
.searx-navbar a:hover {
|
||||
margin-right: 2.0rem;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
.searx-navbar .instance a {
|
||||
color: #01d7d4;
|
||||
margin-left: 2.0rem;
|
||||
}
|
||||
#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 {
|
||||
/* Margin bottom by footer height */
|
||||
font-family: 'Roboto', Helvetica, Arial, sans-serif;
|
||||
margin-bottom: 80px;
|
||||
background-color: white;
|
||||
}
|
||||
body a {
|
||||
color: #0088cc;
|
||||
}
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
/* Set the fixed height of the footer here */
|
||||
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 #FFFFFF !important;
|
||||
border-radius: 50px !important;
|
||||
}
|
||||
.onoffswitch-inner {
|
||||
display: block;
|
||||
transition: margin 0.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: #EEEEEE;
|
||||
}
|
||||
.onoffswitch-switch {
|
||||
display: block;
|
||||
width: 37px;
|
||||
background-color: #01d7d4;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0px;
|
||||
border: 2px solid #FFFFFF !important;
|
||||
border-radius: 50px !important;
|
||||
transition: all 0.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: 0px;
|
||||
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: #0088cc;
|
||||
}
|
||||
.result_header a:visited {
|
||||
color: #684898;
|
||||
}
|
||||
.result_header a .highlight {
|
||||
background-color: #f6f9fa;
|
||||
}
|
||||
.result-content,
|
||||
.result-format,
|
||||
.result-source {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 0;
|
||||
word-wrap: break-word;
|
||||
color: #666666;
|
||||
font-size: 13px;
|
||||
}
|
||||
.result-content .highlight,
|
||||
.result-format .highlight,
|
||||
.result-source .highlight {
|
||||
font-weight: bold;
|
||||
}
|
||||
.result-source {
|
||||
font-size: 10px;
|
||||
float: left;
|
||||
}
|
||||
.result-format {
|
||||
font-size: 10px;
|
||||
float: right;
|
||||
}
|
||||
.external-link {
|
||||
color: #069025;
|
||||
font-size: 12px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.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: #666666;
|
||||
}
|
||||
.suggestion_item {
|
||||
margin: 2px 5px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.suggestion_item .btn {
|
||||
max-width: 100%;
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
text-align: left;
|
||||
}
|
||||
.result_download {
|
||||
margin-right: 5px;
|
||||
}
|
||||
#pagination {
|
||||
margin-top: 30px;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
.label-default {
|
||||
color: #a4a4a4;
|
||||
background: transparent;
|
||||
}
|
||||
.result .text-muted small {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.modal-wrapper {
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.modal-wrapper {
|
||||
background-clip: padding-box;
|
||||
background-color: #fff;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 3px 9px rgba(0, 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: white;
|
||||
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: 0.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: normal;
|
||||
background-color: white;
|
||||
border: #dddddd 1px solid;
|
||||
border-right: none;
|
||||
color: #666666;
|
||||
padding-bottom: 0.4rem;
|
||||
padding-top: 0.4rem;
|
||||
text-align: center;
|
||||
min-width: 50px;
|
||||
}
|
||||
.search_categories label:last-child,
|
||||
#categories label:last-child,
|
||||
.search_categories .input-group-addon:last-child,
|
||||
#categories .input-group-addon:last-child {
|
||||
border-right: #dddddd 1px solid;
|
||||
}
|
||||
.search_categories input[type="checkbox"]:checked + label,
|
||||
#categories input[type="checkbox"]:checked + label {
|
||||
color: #29314d;
|
||||
font-weight: bold;
|
||||
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: white;
|
||||
}
|
||||
.custom-select {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
font-size: 1.2rem;
|
||||
font-weight: normal;
|
||||
background-color: white;
|
||||
border: #dddddd 1px solid;
|
||||
color: #666666;
|
||||
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;
|
||||
}
|
||||
#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: normal;
|
||||
background-color: white;
|
||||
border: #dddddd 1px solid;
|
||||
border-right: none;
|
||||
color: #666666;
|
||||
padding-bottom: 0.4rem;
|
||||
padding-right: 0.7rem;
|
||||
padding-left: 0.7rem;
|
||||
}
|
||||
#advanced-search-container label:last-child,
|
||||
#advanced-search-container .input-group-addon:last-child {
|
||||
border-right: #dddddd 1px solid;
|
||||
}
|
||||
#advanced-search-container input[type="radio"] {
|
||||
display: none;
|
||||
}
|
||||
#advanced-search-container input[type="radio"]:checked + label {
|
||||
color: #29314d;
|
||||
font-weight: bold;
|
||||
border-bottom: #01d7d4 5px solid;
|
||||
}
|
||||
#check-advanced {
|
||||
display: none;
|
||||
}
|
||||
#check-advanced:checked ~ #advanced-search-container {
|
||||
display: block;
|
||||
}
|
||||
.advanced {
|
||||
padding: 0;
|
||||
margin-top: 0.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: #ffffcc;
|
||||
}
|
||||
.highlight {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
.highlight .c {
|
||||
color: #556366;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Comment */
|
||||
.highlight .err {
|
||||
border: 1px solid #ffa92f;
|
||||
}
|
||||
/* Error */
|
||||
.highlight .k {
|
||||
color: #BE74D5;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword */
|
||||
.highlight .o {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Operator */
|
||||
.highlight .cm {
|
||||
color: #556366;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Comment.Multiline */
|
||||
.highlight .cp {
|
||||
color: #bc7a00;
|
||||
}
|
||||
/* Comment.Preproc */
|
||||
.highlight .c1 {
|
||||
color: #556366;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Comment.Single */
|
||||
.highlight .cs {
|
||||
color: #556366;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Comment.Special */
|
||||
.highlight .gd {
|
||||
color: #a00000;
|
||||
}
|
||||
/* Generic.Deleted */
|
||||
.highlight .ge {
|
||||
font-style: italic;
|
||||
}
|
||||
/* Generic.Emph */
|
||||
.highlight .gr {
|
||||
color: #ff0000;
|
||||
}
|
||||
/* Generic.Error */
|
||||
.highlight .gh {
|
||||
color: #000080;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Generic.Heading */
|
||||
.highlight .gi {
|
||||
color: #00a000;
|
||||
}
|
||||
/* Generic.Inserted */
|
||||
.highlight .go {
|
||||
color: #888888;
|
||||
}
|
||||
/* Generic.Output */
|
||||
.highlight .gp {
|
||||
color: #000080;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Generic.Prompt */
|
||||
.highlight .gs {
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Generic.Strong */
|
||||
.highlight .gu {
|
||||
color: #800080;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Generic.Subheading */
|
||||
.highlight .gt {
|
||||
color: #0044dd;
|
||||
}
|
||||
/* Generic.Traceback */
|
||||
.highlight .kc {
|
||||
color: #BE74D5;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword.Constant */
|
||||
.highlight .kd {
|
||||
color: #BE74D5;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword.Declaration */
|
||||
.highlight .kn {
|
||||
color: #BE74D5;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword.Namespace */
|
||||
.highlight .kp {
|
||||
color: #be74d5;
|
||||
}
|
||||
/* Keyword.Pseudo */
|
||||
.highlight .kr {
|
||||
color: #BE74D5;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword.Reserved */
|
||||
.highlight .kt {
|
||||
color: #d46c72;
|
||||
}
|
||||
/* Keyword.Type */
|
||||
.highlight .m {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Literal.Number */
|
||||
.highlight .s {
|
||||
color: #86c372;
|
||||
}
|
||||
/* Literal.String */
|
||||
.highlight .na {
|
||||
color: #7d9029;
|
||||
}
|
||||
/* Name.Attribute */
|
||||
.highlight .nb {
|
||||
color: #be74d5;
|
||||
}
|
||||
/* Name.Builtin */
|
||||
.highlight .nc {
|
||||
color: #61AFEF;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Class */
|
||||
.highlight .no {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Name.Constant */
|
||||
.highlight .nd {
|
||||
color: #aa22ff;
|
||||
}
|
||||
/* Name.Decorator */
|
||||
.highlight .ni {
|
||||
color: #999999;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Entity */
|
||||
.highlight .ne {
|
||||
color: #D2413A;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Exception */
|
||||
.highlight .nf {
|
||||
color: #61afef;
|
||||
}
|
||||
/* Name.Function */
|
||||
.highlight .nl {
|
||||
color: #a0a000;
|
||||
}
|
||||
/* Name.Label */
|
||||
.highlight .nn {
|
||||
color: #61AFEF;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Namespace */
|
||||
.highlight .nt {
|
||||
color: #BE74D5;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Tag */
|
||||
.highlight .nv {
|
||||
color: #dfc06f;
|
||||
}
|
||||
/* Name.Variable */
|
||||
.highlight .ow {
|
||||
color: #AA22FF;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Operator.Word */
|
||||
.highlight .w {
|
||||
color: #d7dae0;
|
||||
}
|
||||
/* Text.Whitespace */
|
||||
.highlight .mf {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Literal.Number.Float */
|
||||
.highlight .mh {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Literal.Number.Hex */
|
||||
.highlight .mi {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Literal.Number.Integer */
|
||||
.highlight .mo {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Literal.Number.Oct */
|
||||
.highlight .sb {
|
||||
color: #86c372;
|
||||
}
|
||||
/* Literal.String.Backtick */
|
||||
.highlight .sc {
|
||||
color: #86c372;
|
||||
}
|
||||
/* Literal.String.Char */
|
||||
.highlight .sd {
|
||||
color: #86C372;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Literal.String.Doc */
|
||||
.highlight .s2 {
|
||||
color: #86c372;
|
||||
}
|
||||
/* Literal.String.Double */
|
||||
.highlight .se {
|
||||
color: #BB6622;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Literal.String.Escape */
|
||||
.highlight .sh {
|
||||
color: #86c372;
|
||||
}
|
||||
/* Literal.String.Heredoc */
|
||||
.highlight .si {
|
||||
color: #BB6688;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Literal.String.Interpol */
|
||||
.highlight .sx {
|
||||
color: #be74d5;
|
||||
}
|
||||
/* Literal.String.Other */
|
||||
.highlight .sr {
|
||||
color: #bb6688;
|
||||
}
|
||||
/* Literal.String.Regex */
|
||||
.highlight .s1 {
|
||||
color: #86c372;
|
||||
}
|
||||
/* Literal.String.Single */
|
||||
.highlight .ss {
|
||||
color: #dfc06f;
|
||||
}
|
||||
/* Literal.String.Symbol */
|
||||
.highlight .bp {
|
||||
color: #be74d5;
|
||||
}
|
||||
/* Name.Builtin.Pseudo */
|
||||
.highlight .vc {
|
||||
color: #dfc06f;
|
||||
}
|
||||
/* Name.Variable.Class */
|
||||
.highlight .vg {
|
||||
color: #dfc06f;
|
||||
}
|
||||
/* Name.Variable.Global */
|
||||
.highlight .vi {
|
||||
color: #dfc06f;
|
||||
}
|
||||
/* Name.Variable.Instance */
|
||||
.highlight .il {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Literal.Number.Integer.Long */
|
||||
.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: transparent;
|
||||
/* WebKit/Blink Browsers */
|
||||
}
|
||||
.highlight .lineno::-moz-selection {
|
||||
background: transparent;
|
||||
/* Gecko Browsers */
|
||||
}
|
||||
.highlight pre {
|
||||
background-color: #282C34;
|
||||
color: #D7DAE0;
|
||||
border: none;
|
||||
margin-bottom: 25px;
|
||||
font-size: 15px;
|
||||
padding: 20px 10px;
|
||||
}
|
||||
.highlight {
|
||||
font-weight: 700;
|
||||
}
|
||||
.table > tbody > tr > td,
|
||||
.table > tbody > tr > th {
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
931
searx/static/themes/oscar/css/logicodev.css
Normal file
931
searx/static/themes/oscar/css/logicodev.css
Normal file
|
|
@ -0,0 +1,931 @@
|
|||
* {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
color: #29314d;
|
||||
}
|
||||
body {
|
||||
/* Margin bottom by footer height */
|
||||
font-family: 'Roboto', Helvetica, Arial, sans-serif;
|
||||
margin-bottom: 80px;
|
||||
background-color: white;
|
||||
}
|
||||
body a {
|
||||
color: #0088cc;
|
||||
}
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
/* Set the fixed height of the footer here */
|
||||
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 #FFFFFF !important;
|
||||
border-radius: 50px !important;
|
||||
}
|
||||
.onoffswitch-inner {
|
||||
display: block;
|
||||
transition: margin 0.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: #EEEEEE;
|
||||
}
|
||||
.onoffswitch-switch {
|
||||
display: block;
|
||||
width: 37px;
|
||||
background-color: #01d7d4;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0px;
|
||||
border: 2px solid #FFFFFF !important;
|
||||
border-radius: 50px !important;
|
||||
transition: all 0.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: 0px;
|
||||
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: #0088cc;
|
||||
}
|
||||
.result_header a:visited {
|
||||
color: #684898;
|
||||
}
|
||||
.result_header a .highlight {
|
||||
background-color: #f6f9fa;
|
||||
}
|
||||
.result-content,
|
||||
.result-format,
|
||||
.result-source {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 0;
|
||||
word-wrap: break-word;
|
||||
color: #666666;
|
||||
font-size: 13px;
|
||||
}
|
||||
.result-content .highlight,
|
||||
.result-format .highlight,
|
||||
.result-source .highlight {
|
||||
font-weight: bold;
|
||||
}
|
||||
.result-source {
|
||||
font-size: 10px;
|
||||
float: left;
|
||||
}
|
||||
.result-format {
|
||||
font-size: 10px;
|
||||
float: right;
|
||||
}
|
||||
.external-link {
|
||||
color: #069025;
|
||||
font-size: 12px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.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: #666666;
|
||||
}
|
||||
.suggestion_item {
|
||||
margin: 2px 5px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.suggestion_item .btn {
|
||||
max-width: 100%;
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
text-align: left;
|
||||
}
|
||||
.result_download {
|
||||
margin-right: 5px;
|
||||
}
|
||||
#pagination {
|
||||
margin-top: 30px;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
.label-default {
|
||||
color: #a4a4a4;
|
||||
background: transparent;
|
||||
}
|
||||
.result .text-muted small {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.modal-wrapper {
|
||||
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.modal-wrapper {
|
||||
background-clip: padding-box;
|
||||
background-color: #fff;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 3px 9px rgba(0, 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: white;
|
||||
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: 0.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: normal;
|
||||
background-color: white;
|
||||
border: #dddddd 1px solid;
|
||||
border-right: none;
|
||||
color: #666666;
|
||||
padding-bottom: 0.4rem;
|
||||
padding-top: 0.4rem;
|
||||
text-align: center;
|
||||
min-width: 50px;
|
||||
}
|
||||
.search_categories label:last-child,
|
||||
#categories label:last-child,
|
||||
.search_categories .input-group-addon:last-child,
|
||||
#categories .input-group-addon:last-child {
|
||||
border-right: #dddddd 1px solid;
|
||||
}
|
||||
.search_categories input[type="checkbox"]:checked + label,
|
||||
#categories input[type="checkbox"]:checked + label {
|
||||
color: #29314d;
|
||||
font-weight: bold;
|
||||
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: white;
|
||||
}
|
||||
.custom-select {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
font-size: 1.2rem;
|
||||
font-weight: normal;
|
||||
background-color: white;
|
||||
border: #dddddd 1px solid;
|
||||
color: #666666;
|
||||
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;
|
||||
}
|
||||
#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: normal;
|
||||
background-color: white;
|
||||
border: #dddddd 1px solid;
|
||||
border-right: none;
|
||||
color: #666666;
|
||||
padding-bottom: 0.4rem;
|
||||
padding-right: 0.7rem;
|
||||
padding-left: 0.7rem;
|
||||
}
|
||||
#advanced-search-container label:last-child,
|
||||
#advanced-search-container .input-group-addon:last-child {
|
||||
border-right: #dddddd 1px solid;
|
||||
}
|
||||
#advanced-search-container input[type="radio"] {
|
||||
display: none;
|
||||
}
|
||||
#advanced-search-container input[type="radio"]:checked + label {
|
||||
color: #29314d;
|
||||
font-weight: bold;
|
||||
border-bottom: #01d7d4 5px solid;
|
||||
}
|
||||
#check-advanced {
|
||||
display: none;
|
||||
}
|
||||
#check-advanced:checked ~ #advanced-search-container {
|
||||
display: block;
|
||||
}
|
||||
.advanced {
|
||||
padding: 0;
|
||||
margin-top: 0.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: #ffffcc;
|
||||
}
|
||||
.highlight {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
.highlight .c {
|
||||
color: #556366;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Comment */
|
||||
.highlight .err {
|
||||
border: 1px solid #ffa92f;
|
||||
}
|
||||
/* Error */
|
||||
.highlight .k {
|
||||
color: #BE74D5;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword */
|
||||
.highlight .o {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Operator */
|
||||
.highlight .cm {
|
||||
color: #556366;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Comment.Multiline */
|
||||
.highlight .cp {
|
||||
color: #bc7a00;
|
||||
}
|
||||
/* Comment.Preproc */
|
||||
.highlight .c1 {
|
||||
color: #556366;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Comment.Single */
|
||||
.highlight .cs {
|
||||
color: #556366;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Comment.Special */
|
||||
.highlight .gd {
|
||||
color: #a00000;
|
||||
}
|
||||
/* Generic.Deleted */
|
||||
.highlight .ge {
|
||||
font-style: italic;
|
||||
}
|
||||
/* Generic.Emph */
|
||||
.highlight .gr {
|
||||
color: #ff0000;
|
||||
}
|
||||
/* Generic.Error */
|
||||
.highlight .gh {
|
||||
color: #000080;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Generic.Heading */
|
||||
.highlight .gi {
|
||||
color: #00a000;
|
||||
}
|
||||
/* Generic.Inserted */
|
||||
.highlight .go {
|
||||
color: #888888;
|
||||
}
|
||||
/* Generic.Output */
|
||||
.highlight .gp {
|
||||
color: #000080;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Generic.Prompt */
|
||||
.highlight .gs {
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Generic.Strong */
|
||||
.highlight .gu {
|
||||
color: #800080;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Generic.Subheading */
|
||||
.highlight .gt {
|
||||
color: #0044dd;
|
||||
}
|
||||
/* Generic.Traceback */
|
||||
.highlight .kc {
|
||||
color: #BE74D5;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword.Constant */
|
||||
.highlight .kd {
|
||||
color: #BE74D5;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword.Declaration */
|
||||
.highlight .kn {
|
||||
color: #BE74D5;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword.Namespace */
|
||||
.highlight .kp {
|
||||
color: #be74d5;
|
||||
}
|
||||
/* Keyword.Pseudo */
|
||||
.highlight .kr {
|
||||
color: #BE74D5;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword.Reserved */
|
||||
.highlight .kt {
|
||||
color: #d46c72;
|
||||
}
|
||||
/* Keyword.Type */
|
||||
.highlight .m {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Literal.Number */
|
||||
.highlight .s {
|
||||
color: #86c372;
|
||||
}
|
||||
/* Literal.String */
|
||||
.highlight .na {
|
||||
color: #7d9029;
|
||||
}
|
||||
/* Name.Attribute */
|
||||
.highlight .nb {
|
||||
color: #be74d5;
|
||||
}
|
||||
/* Name.Builtin */
|
||||
.highlight .nc {
|
||||
color: #61AFEF;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Class */
|
||||
.highlight .no {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Name.Constant */
|
||||
.highlight .nd {
|
||||
color: #aa22ff;
|
||||
}
|
||||
/* Name.Decorator */
|
||||
.highlight .ni {
|
||||
color: #999999;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Entity */
|
||||
.highlight .ne {
|
||||
color: #D2413A;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Exception */
|
||||
.highlight .nf {
|
||||
color: #61afef;
|
||||
}
|
||||
/* Name.Function */
|
||||
.highlight .nl {
|
||||
color: #a0a000;
|
||||
}
|
||||
/* Name.Label */
|
||||
.highlight .nn {
|
||||
color: #61AFEF;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Namespace */
|
||||
.highlight .nt {
|
||||
color: #BE74D5;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Tag */
|
||||
.highlight .nv {
|
||||
color: #dfc06f;
|
||||
}
|
||||
/* Name.Variable */
|
||||
.highlight .ow {
|
||||
color: #AA22FF;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Operator.Word */
|
||||
.highlight .w {
|
||||
color: #d7dae0;
|
||||
}
|
||||
/* Text.Whitespace */
|
||||
.highlight .mf {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Literal.Number.Float */
|
||||
.highlight .mh {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Literal.Number.Hex */
|
||||
.highlight .mi {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Literal.Number.Integer */
|
||||
.highlight .mo {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Literal.Number.Oct */
|
||||
.highlight .sb {
|
||||
color: #86c372;
|
||||
}
|
||||
/* Literal.String.Backtick */
|
||||
.highlight .sc {
|
||||
color: #86c372;
|
||||
}
|
||||
/* Literal.String.Char */
|
||||
.highlight .sd {
|
||||
color: #86C372;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Literal.String.Doc */
|
||||
.highlight .s2 {
|
||||
color: #86c372;
|
||||
}
|
||||
/* Literal.String.Double */
|
||||
.highlight .se {
|
||||
color: #BB6622;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Literal.String.Escape */
|
||||
.highlight .sh {
|
||||
color: #86c372;
|
||||
}
|
||||
/* Literal.String.Heredoc */
|
||||
.highlight .si {
|
||||
color: #BB6688;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Literal.String.Interpol */
|
||||
.highlight .sx {
|
||||
color: #be74d5;
|
||||
}
|
||||
/* Literal.String.Other */
|
||||
.highlight .sr {
|
||||
color: #bb6688;
|
||||
}
|
||||
/* Literal.String.Regex */
|
||||
.highlight .s1 {
|
||||
color: #86c372;
|
||||
}
|
||||
/* Literal.String.Single */
|
||||
.highlight .ss {
|
||||
color: #dfc06f;
|
||||
}
|
||||
/* Literal.String.Symbol */
|
||||
.highlight .bp {
|
||||
color: #be74d5;
|
||||
}
|
||||
/* Name.Builtin.Pseudo */
|
||||
.highlight .vc {
|
||||
color: #dfc06f;
|
||||
}
|
||||
/* Name.Variable.Class */
|
||||
.highlight .vg {
|
||||
color: #dfc06f;
|
||||
}
|
||||
/* Name.Variable.Global */
|
||||
.highlight .vi {
|
||||
color: #dfc06f;
|
||||
}
|
||||
/* Name.Variable.Instance */
|
||||
.highlight .il {
|
||||
color: #d19a66;
|
||||
}
|
||||
/* Literal.Number.Integer.Long */
|
||||
.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: transparent;
|
||||
/* WebKit/Blink Browsers */
|
||||
}
|
||||
.highlight .lineno::-moz-selection {
|
||||
background: transparent;
|
||||
/* Gecko Browsers */
|
||||
}
|
||||
.highlight pre {
|
||||
background-color: #282C34;
|
||||
color: #D7DAE0;
|
||||
border: none;
|
||||
margin-bottom: 25px;
|
||||
font-size: 15px;
|
||||
padding: 20px 10px;
|
||||
}
|
||||
.highlight {
|
||||
font-weight: 700;
|
||||
}
|
||||
.table > tbody > tr > td,
|
||||
.table > tbody > tr > th {
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
/*Global*/
|
||||
body {
|
||||
background: #1d1f21 none !important;
|
||||
color: #D5D8D7 !important;
|
||||
}
|
||||
a {
|
||||
color: #41a2ce !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
a:hover {
|
||||
color: #5F89AC !important;
|
||||
}
|
||||
input,
|
||||
button,
|
||||
textarea,
|
||||
select {
|
||||
border: 1px solid #282a2e !important;
|
||||
background-color: #444 !important;
|
||||
color: #BBB !important;
|
||||
}
|
||||
input:focus,
|
||||
button:focus,
|
||||
textarea:focus,
|
||||
select:focus {
|
||||
border: 1px solid #C5C8C6 !important;
|
||||
box-shadow: initial !important;
|
||||
}
|
||||
div#advanced-search-container div#categories label {
|
||||
background: none;
|
||||
border: 1px solid #282a2e;
|
||||
}
|
||||
ul.nav li a {
|
||||
border: 0 !important;
|
||||
border-bottom: 1px solid #4d3f43 !important;
|
||||
}
|
||||
#categories *,
|
||||
.modal-wrapper * {
|
||||
background: #1d1f21 none !important;
|
||||
color: #D5D8D7 !important;
|
||||
}
|
||||
#categories * {
|
||||
border: 1px solid #3d3f43 !important;
|
||||
}
|
||||
#categories *:checked + label {
|
||||
border-bottom: 4px solid #3d9f94 !important;
|
||||
}
|
||||
.result-content,
|
||||
.result-source,
|
||||
.result-format {
|
||||
color: #B5B8B7 !important;
|
||||
}
|
||||
.external-link {
|
||||
color: #35B887 !important;
|
||||
}
|
||||
.table-striped tr td,
|
||||
.table-striped tr th {
|
||||
border-color: #4d3f43 !important;
|
||||
}
|
||||
.highlight {
|
||||
background: #333333 !important;
|
||||
}
|
||||
/*nav*/
|
||||
.navbar {
|
||||
background: #1d1f21 none;
|
||||
border: none;
|
||||
}
|
||||
.navbar .active,
|
||||
.menu {
|
||||
background: none !important;
|
||||
}
|
||||
.label-default {
|
||||
background: none;
|
||||
color: #BBB;
|
||||
}
|
||||
.navbar-default .navbar-nav > .active > a,
|
||||
.navbar-default .navbar-nav > .active > a:hover,
|
||||
.navbar-default .navbar-nav > .active > a:focus,
|
||||
.nav-tabs.nav-justified > .active > a {
|
||||
background-color: #282a2e !important;
|
||||
}
|
||||
/*Search Page*/
|
||||
.result-default:hover,
|
||||
.result-code:hover,
|
||||
.result-torrent:hover,
|
||||
.result-videos:hover,
|
||||
.result-map:hover {
|
||||
background-color: #222426;
|
||||
}
|
||||
/*buttons*/
|
||||
.btn {
|
||||
color: #BBB;
|
||||
background-color: #444 ;
|
||||
border: 1px solid #282a2e;
|
||||
}
|
||||
.btn:hover {
|
||||
color: #444 !important;
|
||||
background-color: #BBB !important;
|
||||
}
|
||||
.btn-primary.active {
|
||||
color: #C5C8C6;
|
||||
background-color: #5F89AC;
|
||||
border-color: #5F89AC;
|
||||
}
|
||||
/*Right Pannels*/
|
||||
.panel {
|
||||
border: 1px solid #111;
|
||||
background: none;
|
||||
}
|
||||
.panel-heading {
|
||||
color: #C5C8C6 !important;
|
||||
background: #282a2e !important;
|
||||
border-bottom: none;
|
||||
}
|
||||
.panel-body {
|
||||
color: #C5C8C6 !important;
|
||||
background: #1d1f21 !important;
|
||||
border-color: #111 !important;
|
||||
}
|
||||
p.btn.btn-default {
|
||||
background: none;
|
||||
}
|
||||
.table-striped > tbody > tr:nth-child(odd) > td,
|
||||
.table-striped > tbody > tr:nth-child(odd) > th,
|
||||
.table-striped > thead > tr:nth-child(odd) > th {
|
||||
background: #2d2f32 none !important;
|
||||
color: #D5D8D7 !important;
|
||||
}
|
||||
.label-success {
|
||||
background: #1d6f42 none !important;
|
||||
}
|
||||
.label-danger {
|
||||
background: #ad1f12 none !important;
|
||||
}
|
||||
.searx-navbar {
|
||||
background: #333334;
|
||||
height: 2.3rem;
|
||||
font-size: 1.3rem;
|
||||
line-height: 1.3rem;
|
||||
padding: 0.5rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.8rem;
|
||||
}
|
||||
.searx-navbar a,
|
||||
.searx-navbar a:hover {
|
||||
margin-right: 2.0rem;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
.searx-navbar .instance a {
|
||||
color: #01d7d4;
|
||||
margin-left: 2.0rem;
|
||||
}
|
||||
#main-logo {
|
||||
margin-top: 20vh;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
#main-logo > img {
|
||||
max-width: 350px;
|
||||
width: 80%;
|
||||
}
|
||||
.onoffswitch-inner:before,
|
||||
.onoffswitch-inner:after {
|
||||
background: #1d1f21 none !important;
|
||||
}
|
||||
.onoffswitch-switch,
|
||||
.onoffswitch-label {
|
||||
border: 2px solid #3d3f43 !important;
|
||||
}
|
||||
.nav > li > a:hover,
|
||||
.nav > li > a:focus {
|
||||
background-color: #3d3f43 !important;
|
||||
}
|
||||
/*Images search*/
|
||||
.img-thumbnail,
|
||||
.thumbnail {
|
||||
padding: 0px;
|
||||
line-height: 1.42857143;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
.modal-content {
|
||||
background: #1d1f21 none !important;
|
||||
}
|
||||
/*Preferences*/
|
||||
.table > thead > tr > td.danger,
|
||||
.table > tbody > tr > td.danger,
|
||||
.table > tfoot > tr > td.danger,
|
||||
.table > thead > tr > th.danger,
|
||||
.table > tbody > tr > th.danger,
|
||||
.table > tfoot > tr > th.danger,
|
||||
.table > thead > tr.danger > td,
|
||||
.table > tbody > tr.danger > td,
|
||||
.table > tfoot > tr.danger > td,
|
||||
.table > thead > tr.danger > th,
|
||||
.table > tbody > tr.danger > th,
|
||||
.table > tfoot > tr.danger > th {
|
||||
background: rgba(240, 0, 0, 0.56) !important;
|
||||
color: #C5C8C6 !important;
|
||||
}
|
||||
.table-hover > tbody > tr > td.danger:hover,
|
||||
.table-hover > tbody > tr > th.danger:hover,
|
||||
.table-hover > tbody > tr.danger:hover > td,
|
||||
.table-hover > tbody > tr:hover > .danger,
|
||||
.table-hover > tbody > tr.danger:hover > th {
|
||||
background: rgba(237, 59, 59, 0.61) !important;
|
||||
color: #C5C8C6 !important;
|
||||
}
|
||||
.table-hover > tbody > tr:hover > td,
|
||||
.table-hover > tbody > tr:hover > th {
|
||||
background: #66696e !important;
|
||||
}
|
||||
.btn-success {
|
||||
color: #C5C8C6;
|
||||
background: #449d44;
|
||||
}
|
||||
.btn-danger {
|
||||
color: #C5C8C6;
|
||||
background: #d9534f;
|
||||
}
|
||||
.well {
|
||||
background: #444;
|
||||
border-color: #282a2e;
|
||||
}
|
||||
.highlight {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
562
searx/static/themes/oscar/css/pointhi.css
Normal file
562
searx/static/themes/oscar/css/pointhi.css
Normal file
|
|
@ -0,0 +1,562 @@
|
|||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
}
|
||||
body {
|
||||
/* Margin bottom by footer height */
|
||||
margin-bottom: 80px;
|
||||
}
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
/* Set the fixed height of the footer here */
|
||||
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 #FFFFFF !important;
|
||||
border-radius: 50px !important;
|
||||
}
|
||||
.onoffswitch-inner {
|
||||
display: block;
|
||||
transition: margin 0.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: #EEEEEE;
|
||||
}
|
||||
.onoffswitch-switch {
|
||||
display: block;
|
||||
width: 37px;
|
||||
background-color: #00CC00;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0px;
|
||||
border: 2px solid #FFFFFF !important;
|
||||
border-radius: 50px !important;
|
||||
transition: all 0.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: bold;
|
||||
}
|
||||
.result-content {
|
||||
margin-top: 5px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.result-content .highlight {
|
||||
font-weight: bold;
|
||||
}
|
||||
.result-default {
|
||||
clear: both;
|
||||
}
|
||||
.result-images {
|
||||
float: left !important;
|
||||
height: 138px;
|
||||
}
|
||||
.img-thumbnail {
|
||||
margin: 5px;
|
||||
max-height: 128px;
|
||||
}
|
||||
.result-videos {
|
||||
clear: both;
|
||||
}
|
||||
.result-torrents {
|
||||
clear: both;
|
||||
}
|
||||
.result-map {
|
||||
clear: both;
|
||||
}
|
||||
.result-code {
|
||||
clear: both;
|
||||
}
|
||||
.suggestion_item {
|
||||
margin: 2px 5px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.suggestion_item .btn {
|
||||
max-width: 100%;
|
||||
white-space: normal;
|
||||
word-wrap: break-word;
|
||||
text-align: left;
|
||||
}
|
||||
.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, 0.5);
|
||||
}
|
||||
.modal-wrapper {
|
||||
background-clip: padding-box;
|
||||
background-color: #fff;
|
||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 3px 9px rgba(0, 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: normal;
|
||||
background-color: white;
|
||||
border: #DDD 1px solid;
|
||||
border-right: none;
|
||||
color: #333;
|
||||
padding-bottom: 0.8rem;
|
||||
padding-top: 0.8rem;
|
||||
text-align: center;
|
||||
min-width: 50px;
|
||||
}
|
||||
.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: black;
|
||||
font-weight: bold;
|
||||
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: normal;
|
||||
background-color: white;
|
||||
border: #DDD 1px solid;
|
||||
border-right: none;
|
||||
color: #333;
|
||||
padding-bottom: 0.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: black;
|
||||
font-weight: bold;
|
||||
background-color: #EEE;
|
||||
}
|
||||
#check-advanced {
|
||||
display: none;
|
||||
}
|
||||
#check-advanced:checked ~ #advanced-search-container {
|
||||
display: block;
|
||||
}
|
||||
.advanced {
|
||||
padding: 0;
|
||||
margin-top: 0.3rem;
|
||||
text-align: right;
|
||||
}
|
||||
.advanced label,
|
||||
.advanced select {
|
||||
cursor: pointer;
|
||||
}
|
||||
.cursor-text {
|
||||
cursor: text !important;
|
||||
}
|
||||
.cursor-pointer {
|
||||
cursor: pointer !important;
|
||||
}
|
||||
.highlight .hll {
|
||||
background-color: #ffffcc;
|
||||
}
|
||||
.highlight {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
.highlight .c {
|
||||
color: #408080;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Comment */
|
||||
.highlight .err {
|
||||
border: 1px solid #ff0000;
|
||||
}
|
||||
/* Error */
|
||||
.highlight .k {
|
||||
color: #008000;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword */
|
||||
.highlight .o {
|
||||
color: #666666;
|
||||
}
|
||||
/* Operator */
|
||||
.highlight .cm {
|
||||
color: #408080;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Comment.Multiline */
|
||||
.highlight .cp {
|
||||
color: #bc7a00;
|
||||
}
|
||||
/* Comment.Preproc */
|
||||
.highlight .c1 {
|
||||
color: #408080;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Comment.Single */
|
||||
.highlight .cs {
|
||||
color: #408080;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Comment.Special */
|
||||
.highlight .gd {
|
||||
color: #a00000;
|
||||
}
|
||||
/* Generic.Deleted */
|
||||
.highlight .ge {
|
||||
font-style: italic;
|
||||
}
|
||||
/* Generic.Emph */
|
||||
.highlight .gr {
|
||||
color: #ff0000;
|
||||
}
|
||||
/* Generic.Error */
|
||||
.highlight .gh {
|
||||
color: #000080;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Generic.Heading */
|
||||
.highlight .gi {
|
||||
color: #00a000;
|
||||
}
|
||||
/* Generic.Inserted */
|
||||
.highlight .go {
|
||||
color: #888888;
|
||||
}
|
||||
/* Generic.Output */
|
||||
.highlight .gp {
|
||||
color: #000080;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Generic.Prompt */
|
||||
.highlight .gs {
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Generic.Strong */
|
||||
.highlight .gu {
|
||||
color: #800080;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Generic.Subheading */
|
||||
.highlight .gt {
|
||||
color: #0044dd;
|
||||
}
|
||||
/* Generic.Traceback */
|
||||
.highlight .kc {
|
||||
color: #008000;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword.Constant */
|
||||
.highlight .kd {
|
||||
color: #008000;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword.Declaration */
|
||||
.highlight .kn {
|
||||
color: #008000;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword.Namespace */
|
||||
.highlight .kp {
|
||||
color: #008000;
|
||||
}
|
||||
/* Keyword.Pseudo */
|
||||
.highlight .kr {
|
||||
color: #008000;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Keyword.Reserved */
|
||||
.highlight .kt {
|
||||
color: #b00040;
|
||||
}
|
||||
/* Keyword.Type */
|
||||
.highlight .m {
|
||||
color: #666666;
|
||||
}
|
||||
/* Literal.Number */
|
||||
.highlight .s {
|
||||
color: #ba2121;
|
||||
}
|
||||
/* Literal.String */
|
||||
.highlight .na {
|
||||
color: #7d9029;
|
||||
}
|
||||
/* Name.Attribute */
|
||||
.highlight .nb {
|
||||
color: #008000;
|
||||
}
|
||||
/* Name.Builtin */
|
||||
.highlight .nc {
|
||||
color: #0000FF;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Class */
|
||||
.highlight .no {
|
||||
color: #880000;
|
||||
}
|
||||
/* Name.Constant */
|
||||
.highlight .nd {
|
||||
color: #aa22ff;
|
||||
}
|
||||
/* Name.Decorator */
|
||||
.highlight .ni {
|
||||
color: #999999;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Entity */
|
||||
.highlight .ne {
|
||||
color: #D2413A;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Exception */
|
||||
.highlight .nf {
|
||||
color: #0000ff;
|
||||
}
|
||||
/* Name.Function */
|
||||
.highlight .nl {
|
||||
color: #a0a000;
|
||||
}
|
||||
/* Name.Label */
|
||||
.highlight .nn {
|
||||
color: #0000FF;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Namespace */
|
||||
.highlight .nt {
|
||||
color: #008000;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Name.Tag */
|
||||
.highlight .nv {
|
||||
color: #19177c;
|
||||
}
|
||||
/* Name.Variable */
|
||||
.highlight .ow {
|
||||
color: #AA22FF;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Operator.Word */
|
||||
.highlight .w {
|
||||
color: #bbbbbb;
|
||||
}
|
||||
/* Text.Whitespace */
|
||||
.highlight .mf {
|
||||
color: #666666;
|
||||
}
|
||||
/* Literal.Number.Float */
|
||||
.highlight .mh {
|
||||
color: #666666;
|
||||
}
|
||||
/* Literal.Number.Hex */
|
||||
.highlight .mi {
|
||||
color: #666666;
|
||||
}
|
||||
/* Literal.Number.Integer */
|
||||
.highlight .mo {
|
||||
color: #666666;
|
||||
}
|
||||
/* Literal.Number.Oct */
|
||||
.highlight .sb {
|
||||
color: #ba2121;
|
||||
}
|
||||
/* Literal.String.Backtick */
|
||||
.highlight .sc {
|
||||
color: #ba2121;
|
||||
}
|
||||
/* Literal.String.Char */
|
||||
.highlight .sd {
|
||||
color: #BA2121;
|
||||
font-style: italic;
|
||||
}
|
||||
/* Literal.String.Doc */
|
||||
.highlight .s2 {
|
||||
color: #ba2121;
|
||||
}
|
||||
/* Literal.String.Double */
|
||||
.highlight .se {
|
||||
color: #BB6622;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Literal.String.Escape */
|
||||
.highlight .sh {
|
||||
color: #ba2121;
|
||||
}
|
||||
/* Literal.String.Heredoc */
|
||||
.highlight .si {
|
||||
color: #BB6688;
|
||||
font-weight: bold;
|
||||
}
|
||||
/* Literal.String.Interpol */
|
||||
.highlight .sx {
|
||||
color: #008000;
|
||||
}
|
||||
/* Literal.String.Other */
|
||||
.highlight .sr {
|
||||
color: #bb6688;
|
||||
}
|
||||
/* Literal.String.Regex */
|
||||
.highlight .s1 {
|
||||
color: #ba2121;
|
||||
}
|
||||
/* Literal.String.Single */
|
||||
.highlight .ss {
|
||||
color: #19177c;
|
||||
}
|
||||
/* Literal.String.Symbol */
|
||||
.highlight .bp {
|
||||
color: #008000;
|
||||
}
|
||||
/* Name.Builtin.Pseudo */
|
||||
.highlight .vc {
|
||||
color: #19177c;
|
||||
}
|
||||
/* Name.Variable.Class */
|
||||
.highlight .vg {
|
||||
color: #19177c;
|
||||
}
|
||||
/* Name.Variable.Global */
|
||||
.highlight .vi {
|
||||
color: #19177c;
|
||||
}
|
||||
/* Name.Variable.Instance */
|
||||
.highlight .il {
|
||||
color: #666666;
|
||||
}
|
||||
/* Literal.Number.Integer.Long */
|
||||
.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: transparent;
|
||||
/* WebKit/Blink Browsers */
|
||||
}
|
||||
.highlight .lineno::-moz-selection {
|
||||
background: transparent;
|
||||
/* Gecko Browsers */
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.searx-navbar a,
|
||||
.searx-navbar a:hover {
|
||||
margin-right: 2.0rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
.searx-navbar .instance a {
|
||||
color: #444;
|
||||
margin-left: 2.0rem;
|
||||
}
|
||||
.table > tbody > tr > td,
|
||||
.table > tbody > tr > th {
|
||||
vertical-align: middle !important;
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ module.exports = function(grunt) {
|
|||
jshint: {
|
||||
files: ['gruntfile.js', 'js/searx_src/*.js'],
|
||||
options: {
|
||||
reporterOutput: "",
|
||||
reporterOutput: "",
|
||||
// options here to override JSHint defaults
|
||||
globals: {
|
||||
jQuery: true,
|
||||
|
|
@ -55,7 +55,7 @@ module.exports = function(grunt) {
|
|||
"css/logicodev-dark.min.css": "less/logicodev-dark/oscar.less"}
|
||||
},
|
||||
/*
|
||||
// built with ./manage.sh styles
|
||||
// built with ./manage.sh styles
|
||||
bootstrap: {
|
||||
options: {
|
||||
paths: ["less/bootstrap"],
|
||||
|
|
@ -90,7 +90,7 @@ module.exports = function(grunt) {
|
|||
grunt.registerTask('test', ['jshint']);
|
||||
|
||||
grunt.registerTask('default', ['jshint', 'concat', 'uglify', 'less']);
|
||||
|
||||
|
||||
grunt.registerTask('styles', ['less']);
|
||||
|
||||
};
|
||||
|
|
|
|||
BIN
searx/static/themes/oscar/img/icons/invidious.png
Normal file
BIN
searx/static/themes/oscar/img/icons/invidious.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
356
searx/static/themes/oscar/js/searx.js
Normal file
356
searx/static/themes/oscar/js/searx.js
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
/**
|
||||
* 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) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||
*/
|
||||
|
||||
requirejs.config({
|
||||
baseUrl: './static/themes/oscar/js',
|
||||
paths: {
|
||||
app: '../app'
|
||||
}
|
||||
});
|
||||
;/**
|
||||
* 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) 2019 by Alexandre Flament
|
||||
*/
|
||||
window.searx = (function(d) {
|
||||
'use strict';
|
||||
|
||||
// add data- properties
|
||||
var script = d.currentScript || (function() {
|
||||
var scripts = d.getElementsByTagName('script');
|
||||
return scripts[scripts.length - 1];
|
||||
})();
|
||||
|
||||
return {
|
||||
autocompleter: script.getAttribute('data-autocompleter') === 'true',
|
||||
method: script.getAttribute('data-method')
|
||||
};
|
||||
})(document);
|
||||
;/**
|
||||
* 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) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||
*/
|
||||
|
||||
if(searx.autocompleter) {
|
||||
searx.searchResults = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
remote: './autocompleter?q=%QUERY'
|
||||
});
|
||||
searx.searchResults.initialize();
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
if(searx.autocompleter) {
|
||||
$('#q').typeahead(null, {
|
||||
name: 'search-results',
|
||||
displayKey: function(result) {
|
||||
return result;
|
||||
},
|
||||
source: searx.searchResults.ttAdapter()
|
||||
});
|
||||
}
|
||||
});
|
||||
;/**
|
||||
* 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) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||
*/
|
||||
|
||||
$(document).ready(function(){
|
||||
/**
|
||||
* focus element if class="autofocus" and id="q"
|
||||
*/
|
||||
$('#q.autofocus').focus();
|
||||
|
||||
/**
|
||||
* select full content on click if class="select-all-on-click"
|
||||
*/
|
||||
$(".select-all-on-click").click(function () {
|
||||
$(this).select();
|
||||
});
|
||||
|
||||
/**
|
||||
* change text during btn-collapse click if possible
|
||||
*/
|
||||
$('.btn-collapse').click(function() {
|
||||
var btnTextCollapsed = $(this).data('btn-text-collapsed');
|
||||
var btnTextNotCollapsed = $(this).data('btn-text-not-collapsed');
|
||||
|
||||
if(btnTextCollapsed !== '' && btnTextNotCollapsed !== '') {
|
||||
if($(this).hasClass('collapsed')) {
|
||||
new_html = $(this).html().replace(btnTextCollapsed, btnTextNotCollapsed);
|
||||
} else {
|
||||
new_html = $(this).html().replace(btnTextNotCollapsed, btnTextCollapsed);
|
||||
}
|
||||
$(this).html(new_html);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* change text during btn-toggle click if possible
|
||||
*/
|
||||
$('.btn-toggle .btn').click(function() {
|
||||
var btnClass = 'btn-' + $(this).data('btn-class');
|
||||
var btnLabelDefault = $(this).data('btn-label-default');
|
||||
var btnLabelToggled = $(this).data('btn-label-toggled');
|
||||
if(btnLabelToggled !== '') {
|
||||
if($(this).hasClass('btn-default')) {
|
||||
new_html = $(this).html().replace(btnLabelDefault, btnLabelToggled);
|
||||
} else {
|
||||
new_html = $(this).html().replace(btnLabelToggled, btnLabelDefault);
|
||||
}
|
||||
$(this).html(new_html);
|
||||
}
|
||||
$(this).toggleClass(btnClass);
|
||||
$(this).toggleClass('btn-default');
|
||||
});
|
||||
|
||||
/**
|
||||
* change text during btn-toggle click if possible
|
||||
*/
|
||||
$('.media-loader').click(function() {
|
||||
var target = $(this).data('target');
|
||||
var iframe_load = $(target + ' > iframe');
|
||||
var srctest = iframe_load.attr('src');
|
||||
if(srctest === undefined || srctest === false){
|
||||
iframe_load.attr('src', iframe_load.data('src'));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Select or deselect every categories on double clic
|
||||
*/
|
||||
$(".btn-sm").dblclick(function() {
|
||||
var btnClass = 'btn-' + $(this).data('btn-class'); // primary
|
||||
if($(this).hasClass('btn-default')) {
|
||||
$(".btn-sm > input").attr('checked', 'checked');
|
||||
$(".btn-sm > input").prop("checked", true);
|
||||
$(".btn-sm").addClass(btnClass);
|
||||
$(".btn-sm").addClass('active');
|
||||
$(".btn-sm").removeClass('btn-default');
|
||||
} else {
|
||||
$(".btn-sm > input").attr('checked', '');
|
||||
$(".btn-sm > input").removeAttr('checked');
|
||||
$(".btn-sm > input").checked = false;
|
||||
$(".btn-sm").removeClass(btnClass);
|
||||
$(".btn-sm").removeClass('active');
|
||||
$(".btn-sm").addClass('btn-default');
|
||||
}
|
||||
});
|
||||
});
|
||||
;/**
|
||||
* 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) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||
*/
|
||||
|
||||
$(document).ready(function(){
|
||||
$(".searx_overpass_request").on( "click", function( event ) {
|
||||
var overpass_url = "https://overpass-api.de/api/interpreter?data=";
|
||||
var query_start = overpass_url + "[out:json][timeout:25];(";
|
||||
var query_end = ");out meta;";
|
||||
|
||||
var osm_id = $(this).data('osm-id');
|
||||
var osm_type = $(this).data('osm-type');
|
||||
var result_table = $(this).data('result-table');
|
||||
var result_table_loadicon = "#" + $(this).data('result-table-loadicon');
|
||||
|
||||
// tags which can be ignored
|
||||
var osm_ignore_tags = [ "addr:city", "addr:country", "addr:housenumber", "addr:postcode", "addr:street" ];
|
||||
|
||||
if(osm_id && osm_type && result_table) {
|
||||
result_table = "#" + result_table;
|
||||
var query = null;
|
||||
switch(osm_type) {
|
||||
case 'node':
|
||||
query = query_start + "node(" + osm_id + ");" + query_end;
|
||||
break;
|
||||
case 'way':
|
||||
query = query_start + "way(" + osm_id + ");" + query_end;
|
||||
break;
|
||||
case 'relation':
|
||||
query = query_start + "relation(" + osm_id + ");" + query_end;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(query) {
|
||||
//alert(query);
|
||||
var ajaxRequest = $.ajax( query )
|
||||
.done(function( html) {
|
||||
if(html && html.elements && html.elements[0]) {
|
||||
var element = html.elements[0];
|
||||
var newHtml = $(result_table).html();
|
||||
for (var row in element.tags) {
|
||||
if(element.tags.name === null || osm_ignore_tags.indexOf(row) == -1) {
|
||||
newHtml += "<tr><td>" + row + "</td><td>";
|
||||
switch(row) {
|
||||
case "phone":
|
||||
case "fax":
|
||||
newHtml += "<a href=\"tel:" + element.tags[row].replace(/ /g,'') + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
case "email":
|
||||
newHtml += "<a href=\"mailto:" + element.tags[row] + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
case "website":
|
||||
case "url":
|
||||
newHtml += "<a href=\"" + element.tags[row] + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
case "wikidata":
|
||||
newHtml += "<a href=\"https://www.wikidata.org/wiki/" + element.tags[row] + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
case "wikipedia":
|
||||
if(element.tags[row].indexOf(":") != -1) {
|
||||
newHtml += "<a href=\"https://" + element.tags[row].substring(0,element.tags[row].indexOf(":")) + ".wikipedia.org/wiki/" + element.tags[row].substring(element.tags[row].indexOf(":")+1) + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
}
|
||||
/* jshint ignore:start */
|
||||
default:
|
||||
/* jshint ignore:end */
|
||||
newHtml += element.tags[row];
|
||||
break;
|
||||
}
|
||||
newHtml += "</td></tr>";
|
||||
}
|
||||
}
|
||||
$(result_table).html(newHtml);
|
||||
$(result_table).removeClass('hidden');
|
||||
$(result_table_loadicon).addClass('hidden');
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
$(result_table_loadicon).html($(result_table_loadicon).html() + "<p class=\"text-muted\">could not load data!</p>");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// this event occour only once per element
|
||||
$( this ).off( event );
|
||||
});
|
||||
|
||||
$(".searx_init_map").on( "click", function( event ) {
|
||||
var leaflet_target = $(this).data('leaflet-target');
|
||||
var map_lon = $(this).data('map-lon');
|
||||
var map_lat = $(this).data('map-lat');
|
||||
var map_zoom = $(this).data('map-zoom');
|
||||
var map_boundingbox = $(this).data('map-boundingbox');
|
||||
var map_geojson = $(this).data('map-geojson');
|
||||
|
||||
require(['leaflet-0.7.3.min'], function(leaflet) {
|
||||
if(map_boundingbox) {
|
||||
southWest = L.latLng(map_boundingbox[0], map_boundingbox[2]);
|
||||
northEast = L.latLng(map_boundingbox[1], map_boundingbox[3]);
|
||||
map_bounds = L.latLngBounds(southWest, northEast);
|
||||
}
|
||||
|
||||
// TODO hack
|
||||
// change default imagePath
|
||||
L.Icon.Default.imagePath = "./static/themes/oscar/img/map";
|
||||
|
||||
// init map
|
||||
var map = L.map(leaflet_target);
|
||||
|
||||
// create the tile layer with correct attribution
|
||||
var osmMapnikUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
var osmMapnikAttrib='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
|
||||
var osmMapnik = new L.TileLayer(osmMapnikUrl, {minZoom: 1, maxZoom: 19, attribution: osmMapnikAttrib});
|
||||
|
||||
var osmWikimediaUrl='https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png';
|
||||
var osmWikimediaAttrib = 'Wikimedia maps beta | Maps data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
|
||||
var osmWikimedia = new L.TileLayer(osmWikimediaUrl, {minZoom: 1, maxZoom: 19, attribution: osmWikimediaAttrib});
|
||||
|
||||
// init map view
|
||||
if(map_bounds) {
|
||||
// TODO hack: https://github.com/Leaflet/Leaflet/issues/2021
|
||||
setTimeout(function () {
|
||||
map.fitBounds(map_bounds, {
|
||||
maxZoom:17
|
||||
});
|
||||
}, 0);
|
||||
} else if (map_lon && map_lat) {
|
||||
if(map_zoom)
|
||||
map.setView(new L.LatLng(map_lat, map_lon),map_zoom);
|
||||
else
|
||||
map.setView(new L.LatLng(map_lat, map_lon),8);
|
||||
}
|
||||
|
||||
map.addLayer(osmMapnik);
|
||||
|
||||
var baseLayers = {
|
||||
"OSM Mapnik": osmMapnik/*,
|
||||
"OSM Wikimedia": osmWikimedia*/
|
||||
};
|
||||
|
||||
L.control.layers(baseLayers).addTo(map);
|
||||
|
||||
|
||||
if(map_geojson)
|
||||
L.geoJson(map_geojson).addTo(map);
|
||||
/*else if(map_bounds)
|
||||
L.rectangle(map_bounds, {color: "#ff7800", weight: 3, fill:false}).addTo(map);*/
|
||||
});
|
||||
|
||||
// this event occour only once per element
|
||||
$( this ).off( event );
|
||||
});
|
||||
});
|
||||
4
searx/static/themes/oscar/js/searx.min.js
vendored
4
searx/static/themes/oscar/js/searx.min.js
vendored
|
|
@ -1,2 +1,2 @@
|
|||
/*! oscar/searx.min.js | 06-10-2017 | https://github.com/asciimoo/searx */
|
||||
requirejs.config({baseUrl:"./static/themes/oscar/js",paths:{app:"../app"}}),searx.autocompleter&&(searx.searchResults=new Bloodhound({datumTokenizer:Bloodhound.tokenizers.obj.whitespace("value"),queryTokenizer:Bloodhound.tokenizers.whitespace,remote:"./autocompleter?q=%QUERY"}),searx.searchResults.initialize()),$(document).ready(function(){searx.autocompleter&&$("#q").typeahead(null,{name:"search-results",displayKey:function(a){return a},source:searx.searchResults.ttAdapter()})}),$(document).ready(function(){$("#q.autofocus").focus(),$(".select-all-on-click").click(function(){$(this).select()}),$(".btn-collapse").click(function(){var a=$(this).data("btn-text-collapsed"),b=$(this).data("btn-text-not-collapsed");""!==a&&""!==b&&($(this).hasClass("collapsed")?new_html=$(this).html().replace(a,b):new_html=$(this).html().replace(b,a),$(this).html(new_html))}),$(".btn-toggle .btn").click(function(){var a="btn-"+$(this).data("btn-class"),b=$(this).data("btn-label-default"),c=$(this).data("btn-label-toggled");""!==c&&($(this).hasClass("btn-default")?new_html=$(this).html().replace(b,c):new_html=$(this).html().replace(c,b),$(this).html(new_html)),$(this).toggleClass(a),$(this).toggleClass("btn-default")}),$(".media-loader").click(function(){var a=$(this).data("target"),b=$(a+" > iframe"),c=b.attr("src");void 0!==c&&c!==!1||b.attr("src",b.data("src"))}),$(".btn-sm").dblclick(function(){var a="btn-"+$(this).data("btn-class");$(this).hasClass("btn-default")?($(".btn-sm > input").attr("checked","checked"),$(".btn-sm > input").prop("checked",!0),$(".btn-sm").addClass(a),$(".btn-sm").addClass("active"),$(".btn-sm").removeClass("btn-default")):($(".btn-sm > input").attr("checked",""),$(".btn-sm > input").removeAttr("checked"),$(".btn-sm > input").checked=!1,$(".btn-sm").removeClass(a),$(".btn-sm").removeClass("active"),$(".btn-sm").addClass("btn-default"))})}),$(document).ready(function(){$(".searx_overpass_request").on("click",function(a){var b="https://overpass-api.de/api/interpreter?data=",c=b+"[out:json][timeout:25];(",d=");out meta;",e=$(this).data("osm-id"),f=$(this).data("osm-type"),g=$(this).data("result-table"),h="#"+$(this).data("result-table-loadicon"),i=["addr:city","addr:country","addr:housenumber","addr:postcode","addr:street"];if(e&&f&&g){g="#"+g;var j=null;switch(f){case"node":j=c+"node("+e+");"+d;break;case"way":j=c+"way("+e+");"+d;break;case"relation":j=c+"relation("+e+");"+d}if(j){$.ajax(j).done(function(a){if(a&&a.elements&&a.elements[0]){var b=a.elements[0],c=$(g).html();for(var d in b.tags)if(null===b.tags.name||i.indexOf(d)==-1){switch(c+="<tr><td>"+d+"</td><td>",d){case"phone":case"fax":c+='<a href="tel:'+b.tags[d].replace(/ /g,"")+'">'+b.tags[d]+"</a>";break;case"email":c+='<a href="mailto:'+b.tags[d]+'">'+b.tags[d]+"</a>";break;case"website":case"url":c+='<a href="'+b.tags[d]+'">'+b.tags[d]+"</a>";break;case"wikidata":c+='<a href="https://www.wikidata.org/wiki/'+b.tags[d]+'">'+b.tags[d]+"</a>";break;case"wikipedia":if(b.tags[d].indexOf(":")!=-1){c+='<a href="https://'+b.tags[d].substring(0,b.tags[d].indexOf(":"))+".wikipedia.org/wiki/"+b.tags[d].substring(b.tags[d].indexOf(":")+1)+'">'+b.tags[d]+"</a>";break}default:c+=b.tags[d]}c+="</td></tr>"}$(g).html(c),$(g).removeClass("hidden"),$(h).addClass("hidden")}}).fail(function(){$(h).html($(h).html()+'<p class="text-muted">could not load data!</p>')})}}$(this).off(a)}),$(".searx_init_map").on("click",function(a){var b=$(this).data("leaflet-target"),c=$(this).data("map-lon"),d=$(this).data("map-lat"),e=$(this).data("map-zoom"),f=$(this).data("map-boundingbox"),g=$(this).data("map-geojson");require(["leaflet-0.7.3.min"],function(a){f&&(southWest=L.latLng(f[0],f[2]),northEast=L.latLng(f[1],f[3]),map_bounds=L.latLngBounds(southWest,northEast)),L.Icon.Default.imagePath="./static/themes/oscar/img/map";var h=L.map(b),i="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",j='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors',k=new L.TileLayer(i,{minZoom:1,maxZoom:19,attribution:j}),l="https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png",m='Wikimedia maps beta | Maps data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';new L.TileLayer(l,{minZoom:1,maxZoom:19,attribution:m});map_bounds?setTimeout(function(){h.fitBounds(map_bounds,{maxZoom:17})},0):c&&d&&(e?h.setView(new L.LatLng(d,c),e):h.setView(new L.LatLng(d,c),8)),h.addLayer(k);var n={"OSM Mapnik":k};L.control.layers(n).addTo(h),g&&L.geoJson(g).addTo(h)}),$(this).off(a)})});
|
||||
/*! oscar/searx.min.js | 06-08-2019 | https://github.com/asciimoo/searx */
|
||||
requirejs.config({baseUrl:"./static/themes/oscar/js",paths:{app:"../app"}}),window.searx=function(a){"use strict";var b=a.currentScript||function(){var b=a.getElementsByTagName("script");return b[b.length-1]}();return{autocompleter:"true"===b.getAttribute("data-autocompleter"),method:b.getAttribute("data-method")}}(document),searx.autocompleter&&(searx.searchResults=new Bloodhound({datumTokenizer:Bloodhound.tokenizers.obj.whitespace("value"),queryTokenizer:Bloodhound.tokenizers.whitespace,remote:"./autocompleter?q=%QUERY"}),searx.searchResults.initialize()),$(document).ready(function(){searx.autocompleter&&$("#q").typeahead(null,{name:"search-results",displayKey:function(a){return a},source:searx.searchResults.ttAdapter()})}),$(document).ready(function(){$("#q.autofocus").focus(),$(".select-all-on-click").click(function(){$(this).select()}),$(".btn-collapse").click(function(){var a=$(this).data("btn-text-collapsed"),b=$(this).data("btn-text-not-collapsed");""!==a&&""!==b&&($(this).hasClass("collapsed")?new_html=$(this).html().replace(a,b):new_html=$(this).html().replace(b,a),$(this).html(new_html))}),$(".btn-toggle .btn").click(function(){var a="btn-"+$(this).data("btn-class"),b=$(this).data("btn-label-default"),c=$(this).data("btn-label-toggled");""!==c&&($(this).hasClass("btn-default")?new_html=$(this).html().replace(b,c):new_html=$(this).html().replace(c,b),$(this).html(new_html)),$(this).toggleClass(a),$(this).toggleClass("btn-default")}),$(".media-loader").click(function(){var a=$(this).data("target"),b=$(a+" > iframe"),c=b.attr("src");void 0!==c&&!1!==c||b.attr("src",b.data("src"))}),$(".btn-sm").dblclick(function(){var a="btn-"+$(this).data("btn-class");$(this).hasClass("btn-default")?($(".btn-sm > input").attr("checked","checked"),$(".btn-sm > input").prop("checked",!0),$(".btn-sm").addClass(a),$(".btn-sm").addClass("active"),$(".btn-sm").removeClass("btn-default")):($(".btn-sm > input").attr("checked",""),$(".btn-sm > input").removeAttr("checked"),$(".btn-sm > input").checked=!1,$(".btn-sm").removeClass(a),$(".btn-sm").removeClass("active"),$(".btn-sm").addClass("btn-default"))})}),$(document).ready(function(){$(".searx_overpass_request").on("click",function(a){var b="https://overpass-api.de/api/interpreter?data=",c=b+"[out:json][timeout:25];(",d=");out meta;",e=$(this).data("osm-id"),f=$(this).data("osm-type"),g=$(this).data("result-table"),h="#"+$(this).data("result-table-loadicon"),i=["addr:city","addr:country","addr:housenumber","addr:postcode","addr:street"];if(e&&f&&g){g="#"+g;var j=null;switch(f){case"node":j=c+"node("+e+");"+d;break;case"way":j=c+"way("+e+");"+d;break;case"relation":j=c+"relation("+e+");"+d}if(j){$.ajax(j).done(function(a){if(a&&a.elements&&a.elements[0]){var b=a.elements[0],c=$(g).html();for(var d in b.tags)if(null===b.tags.name||-1==i.indexOf(d)){switch(c+="<tr><td>"+d+"</td><td>",d){case"phone":case"fax":c+='<a href="tel:'+b.tags[d].replace(/ /g,"")+'">'+b.tags[d]+"</a>";break;case"email":c+='<a href="mailto:'+b.tags[d]+'">'+b.tags[d]+"</a>";break;case"website":case"url":c+='<a href="'+b.tags[d]+'">'+b.tags[d]+"</a>";break;case"wikidata":c+='<a href="https://www.wikidata.org/wiki/'+b.tags[d]+'">'+b.tags[d]+"</a>";break;case"wikipedia":if(-1!=b.tags[d].indexOf(":")){c+='<a href="https://'+b.tags[d].substring(0,b.tags[d].indexOf(":"))+".wikipedia.org/wiki/"+b.tags[d].substring(b.tags[d].indexOf(":")+1)+'">'+b.tags[d]+"</a>";break}default:c+=b.tags[d]}c+="</td></tr>"}$(g).html(c),$(g).removeClass("hidden"),$(h).addClass("hidden")}}).fail(function(){$(h).html($(h).html()+'<p class="text-muted">could not load data!</p>')})}}$(this).off(a)}),$(".searx_init_map").on("click",function(a){var b=$(this).data("leaflet-target"),c=$(this).data("map-lon"),d=$(this).data("map-lat"),e=$(this).data("map-zoom"),f=$(this).data("map-boundingbox"),g=$(this).data("map-geojson");require(["leaflet-0.7.3.min"],function(a){f&&(southWest=L.latLng(f[0],f[2]),northEast=L.latLng(f[1],f[3]),map_bounds=L.latLngBounds(southWest,northEast)),L.Icon.Default.imagePath="./static/themes/oscar/img/map";var h=L.map(b),i="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",j='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors',k=new L.TileLayer(i,{minZoom:1,maxZoom:19,attribution:j}),l="https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png",m='Wikimedia maps beta | Maps data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';new L.TileLayer(l,{minZoom:1,maxZoom:19,attribution:m});map_bounds?setTimeout(function(){h.fitBounds(map_bounds,{maxZoom:17})},0):c&&d&&(e?h.setView(new L.LatLng(d,c),e):h.setView(new L.LatLng(d,c),8)),h.addLayer(k);var n={"OSM Mapnik":k};L.control.layers(n).addTo(h),g&&L.geoJson(g).addTo(h)}),$(this).off(a)})});
|
||||
|
|
@ -1,23 +1,23 @@
|
|||
/**
|
||||
* 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) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||
*/
|
||||
|
||||
requirejs.config({
|
||||
baseUrl: './static/themes/oscar/js',
|
||||
paths: {
|
||||
app: '../app'
|
||||
}
|
||||
});
|
||||
/**
|
||||
* 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) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||
*/
|
||||
|
||||
requirejs.config({
|
||||
baseUrl: './static/themes/oscar/js',
|
||||
paths: {
|
||||
app: '../app'
|
||||
}
|
||||
});
|
||||
|
|
|
|||
30
searx/static/themes/oscar/js/searx_src/01_init.js
Normal file
30
searx/static/themes/oscar/js/searx_src/01_init.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* 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) 2019 by Alexandre Flament
|
||||
*/
|
||||
window.searx = (function(d) {
|
||||
'use strict';
|
||||
|
||||
// add data- properties
|
||||
var script = d.currentScript || (function() {
|
||||
var scripts = d.getElementsByTagName('script');
|
||||
return scripts[scripts.length - 1];
|
||||
})();
|
||||
|
||||
return {
|
||||
autocompleter: script.getAttribute('data-autocompleter') === 'true',
|
||||
method: script.getAttribute('data-method')
|
||||
};
|
||||
})(document);
|
||||
|
|
@ -1,37 +1,37 @@
|
|||
/**
|
||||
* 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) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||
*/
|
||||
|
||||
if(searx.autocompleter) {
|
||||
searx.searchResults = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
remote: './autocompleter?q=%QUERY'
|
||||
});
|
||||
searx.searchResults.initialize();
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
if(searx.autocompleter) {
|
||||
$('#q').typeahead(null, {
|
||||
name: 'search-results',
|
||||
displayKey: function(result) {
|
||||
return result;
|
||||
},
|
||||
source: searx.searchResults.ttAdapter()
|
||||
});
|
||||
}
|
||||
});
|
||||
/**
|
||||
* 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) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||
*/
|
||||
|
||||
if(searx.autocompleter) {
|
||||
searx.searchResults = new Bloodhound({
|
||||
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
|
||||
queryTokenizer: Bloodhound.tokenizers.whitespace,
|
||||
remote: './autocompleter?q=%QUERY'
|
||||
});
|
||||
searx.searchResults.initialize();
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
if(searx.autocompleter) {
|
||||
$('#q').typeahead(null, {
|
||||
name: 'search-results',
|
||||
displayKey: function(result) {
|
||||
return result;
|
||||
},
|
||||
source: searx.searchResults.ttAdapter()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,99 +1,99 @@
|
|||
/**
|
||||
* 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) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||
*/
|
||||
|
||||
$(document).ready(function(){
|
||||
/**
|
||||
* focus element if class="autofocus" and id="q"
|
||||
*/
|
||||
$('#q.autofocus').focus();
|
||||
|
||||
/**
|
||||
* select full content on click if class="select-all-on-click"
|
||||
*/
|
||||
$(".select-all-on-click").click(function () {
|
||||
$(this).select();
|
||||
});
|
||||
|
||||
/**
|
||||
* change text during btn-collapse click if possible
|
||||
*/
|
||||
$('.btn-collapse').click(function() {
|
||||
var btnTextCollapsed = $(this).data('btn-text-collapsed');
|
||||
var btnTextNotCollapsed = $(this).data('btn-text-not-collapsed');
|
||||
|
||||
if(btnTextCollapsed !== '' && btnTextNotCollapsed !== '') {
|
||||
if($(this).hasClass('collapsed')) {
|
||||
new_html = $(this).html().replace(btnTextCollapsed, btnTextNotCollapsed);
|
||||
} else {
|
||||
new_html = $(this).html().replace(btnTextNotCollapsed, btnTextCollapsed);
|
||||
}
|
||||
$(this).html(new_html);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* change text during btn-toggle click if possible
|
||||
*/
|
||||
$('.btn-toggle .btn').click(function() {
|
||||
var btnClass = 'btn-' + $(this).data('btn-class');
|
||||
var btnLabelDefault = $(this).data('btn-label-default');
|
||||
var btnLabelToggled = $(this).data('btn-label-toggled');
|
||||
if(btnLabelToggled !== '') {
|
||||
if($(this).hasClass('btn-default')) {
|
||||
new_html = $(this).html().replace(btnLabelDefault, btnLabelToggled);
|
||||
} else {
|
||||
new_html = $(this).html().replace(btnLabelToggled, btnLabelDefault);
|
||||
}
|
||||
$(this).html(new_html);
|
||||
}
|
||||
$(this).toggleClass(btnClass);
|
||||
$(this).toggleClass('btn-default');
|
||||
});
|
||||
|
||||
/**
|
||||
* change text during btn-toggle click if possible
|
||||
*/
|
||||
$('.media-loader').click(function() {
|
||||
var target = $(this).data('target');
|
||||
var iframe_load = $(target + ' > iframe');
|
||||
var srctest = iframe_load.attr('src');
|
||||
if(srctest === undefined || srctest === false){
|
||||
iframe_load.attr('src', iframe_load.data('src'));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Select or deselect every categories on double clic
|
||||
*/
|
||||
$(".btn-sm").dblclick(function() {
|
||||
var btnClass = 'btn-' + $(this).data('btn-class'); // primary
|
||||
if($(this).hasClass('btn-default')) {
|
||||
$(".btn-sm > input").attr('checked', 'checked');
|
||||
$(".btn-sm > input").prop("checked", true);
|
||||
$(".btn-sm").addClass(btnClass);
|
||||
$(".btn-sm").addClass('active');
|
||||
$(".btn-sm").removeClass('btn-default');
|
||||
} else {
|
||||
$(".btn-sm > input").attr('checked', '');
|
||||
$(".btn-sm > input").removeAttr('checked');
|
||||
$(".btn-sm > input").checked = false;
|
||||
$(".btn-sm").removeClass(btnClass);
|
||||
$(".btn-sm").removeClass('active');
|
||||
$(".btn-sm").addClass('btn-default');
|
||||
}
|
||||
});
|
||||
});
|
||||
/**
|
||||
* 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) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||
*/
|
||||
|
||||
$(document).ready(function(){
|
||||
/**
|
||||
* focus element if class="autofocus" and id="q"
|
||||
*/
|
||||
$('#q.autofocus').focus();
|
||||
|
||||
/**
|
||||
* select full content on click if class="select-all-on-click"
|
||||
*/
|
||||
$(".select-all-on-click").click(function () {
|
||||
$(this).select();
|
||||
});
|
||||
|
||||
/**
|
||||
* change text during btn-collapse click if possible
|
||||
*/
|
||||
$('.btn-collapse').click(function() {
|
||||
var btnTextCollapsed = $(this).data('btn-text-collapsed');
|
||||
var btnTextNotCollapsed = $(this).data('btn-text-not-collapsed');
|
||||
|
||||
if(btnTextCollapsed !== '' && btnTextNotCollapsed !== '') {
|
||||
if($(this).hasClass('collapsed')) {
|
||||
new_html = $(this).html().replace(btnTextCollapsed, btnTextNotCollapsed);
|
||||
} else {
|
||||
new_html = $(this).html().replace(btnTextNotCollapsed, btnTextCollapsed);
|
||||
}
|
||||
$(this).html(new_html);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* change text during btn-toggle click if possible
|
||||
*/
|
||||
$('.btn-toggle .btn').click(function() {
|
||||
var btnClass = 'btn-' + $(this).data('btn-class');
|
||||
var btnLabelDefault = $(this).data('btn-label-default');
|
||||
var btnLabelToggled = $(this).data('btn-label-toggled');
|
||||
if(btnLabelToggled !== '') {
|
||||
if($(this).hasClass('btn-default')) {
|
||||
new_html = $(this).html().replace(btnLabelDefault, btnLabelToggled);
|
||||
} else {
|
||||
new_html = $(this).html().replace(btnLabelToggled, btnLabelDefault);
|
||||
}
|
||||
$(this).html(new_html);
|
||||
}
|
||||
$(this).toggleClass(btnClass);
|
||||
$(this).toggleClass('btn-default');
|
||||
});
|
||||
|
||||
/**
|
||||
* change text during btn-toggle click if possible
|
||||
*/
|
||||
$('.media-loader').click(function() {
|
||||
var target = $(this).data('target');
|
||||
var iframe_load = $(target + ' > iframe');
|
||||
var srctest = iframe_load.attr('src');
|
||||
if(srctest === undefined || srctest === false){
|
||||
iframe_load.attr('src', iframe_load.data('src'));
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Select or deselect every categories on double clic
|
||||
*/
|
||||
$(".btn-sm").dblclick(function() {
|
||||
var btnClass = 'btn-' + $(this).data('btn-class'); // primary
|
||||
if($(this).hasClass('btn-default')) {
|
||||
$(".btn-sm > input").attr('checked', 'checked');
|
||||
$(".btn-sm > input").prop("checked", true);
|
||||
$(".btn-sm").addClass(btnClass);
|
||||
$(".btn-sm").addClass('active');
|
||||
$(".btn-sm").removeClass('btn-default');
|
||||
} else {
|
||||
$(".btn-sm > input").attr('checked', '');
|
||||
$(".btn-sm > input").removeAttr('checked');
|
||||
$(".btn-sm > input").checked = false;
|
||||
$(".btn-sm").removeClass(btnClass);
|
||||
$(".btn-sm").removeClass('active');
|
||||
$(".btn-sm").addClass('btn-default');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,167 +1,167 @@
|
|||
/**
|
||||
* 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) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||
*/
|
||||
|
||||
$(document).ready(function(){
|
||||
$(".searx_overpass_request").on( "click", function( event ) {
|
||||
var overpass_url = "https://overpass-api.de/api/interpreter?data=";
|
||||
var query_start = overpass_url + "[out:json][timeout:25];(";
|
||||
var query_end = ");out meta;";
|
||||
|
||||
var osm_id = $(this).data('osm-id');
|
||||
var osm_type = $(this).data('osm-type');
|
||||
var result_table = $(this).data('result-table');
|
||||
var result_table_loadicon = "#" + $(this).data('result-table-loadicon');
|
||||
|
||||
// tags which can be ignored
|
||||
var osm_ignore_tags = [ "addr:city", "addr:country", "addr:housenumber", "addr:postcode", "addr:street" ];
|
||||
|
||||
if(osm_id && osm_type && result_table) {
|
||||
result_table = "#" + result_table;
|
||||
var query = null;
|
||||
switch(osm_type) {
|
||||
case 'node':
|
||||
query = query_start + "node(" + osm_id + ");" + query_end;
|
||||
break;
|
||||
case 'way':
|
||||
query = query_start + "way(" + osm_id + ");" + query_end;
|
||||
break;
|
||||
case 'relation':
|
||||
query = query_start + "relation(" + osm_id + ");" + query_end;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(query) {
|
||||
//alert(query);
|
||||
var ajaxRequest = $.ajax( query )
|
||||
.done(function( html) {
|
||||
if(html && html.elements && html.elements[0]) {
|
||||
var element = html.elements[0];
|
||||
var newHtml = $(result_table).html();
|
||||
for (var row in element.tags) {
|
||||
if(element.tags.name === null || osm_ignore_tags.indexOf(row) == -1) {
|
||||
newHtml += "<tr><td>" + row + "</td><td>";
|
||||
switch(row) {
|
||||
case "phone":
|
||||
case "fax":
|
||||
newHtml += "<a href=\"tel:" + element.tags[row].replace(/ /g,'') + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
case "email":
|
||||
newHtml += "<a href=\"mailto:" + element.tags[row] + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
case "website":
|
||||
case "url":
|
||||
newHtml += "<a href=\"" + element.tags[row] + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
case "wikidata":
|
||||
newHtml += "<a href=\"https://www.wikidata.org/wiki/" + element.tags[row] + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
case "wikipedia":
|
||||
if(element.tags[row].indexOf(":") != -1) {
|
||||
newHtml += "<a href=\"https://" + element.tags[row].substring(0,element.tags[row].indexOf(":")) + ".wikipedia.org/wiki/" + element.tags[row].substring(element.tags[row].indexOf(":")+1) + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
}
|
||||
/* jshint ignore:start */
|
||||
default:
|
||||
/* jshint ignore:end */
|
||||
newHtml += element.tags[row];
|
||||
break;
|
||||
}
|
||||
newHtml += "</td></tr>";
|
||||
}
|
||||
}
|
||||
$(result_table).html(newHtml);
|
||||
$(result_table).removeClass('hidden');
|
||||
$(result_table_loadicon).addClass('hidden');
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
$(result_table_loadicon).html($(result_table_loadicon).html() + "<p class=\"text-muted\">could not load data!</p>");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// this event occour only once per element
|
||||
$( this ).off( event );
|
||||
});
|
||||
|
||||
$(".searx_init_map").on( "click", function( event ) {
|
||||
var leaflet_target = $(this).data('leaflet-target');
|
||||
var map_lon = $(this).data('map-lon');
|
||||
var map_lat = $(this).data('map-lat');
|
||||
var map_zoom = $(this).data('map-zoom');
|
||||
var map_boundingbox = $(this).data('map-boundingbox');
|
||||
var map_geojson = $(this).data('map-geojson');
|
||||
|
||||
require(['leaflet-0.7.3.min'], function(leaflet) {
|
||||
if(map_boundingbox) {
|
||||
southWest = L.latLng(map_boundingbox[0], map_boundingbox[2]);
|
||||
northEast = L.latLng(map_boundingbox[1], map_boundingbox[3]);
|
||||
map_bounds = L.latLngBounds(southWest, northEast);
|
||||
}
|
||||
|
||||
// TODO hack
|
||||
// change default imagePath
|
||||
L.Icon.Default.imagePath = "./static/themes/oscar/img/map";
|
||||
|
||||
// init map
|
||||
var map = L.map(leaflet_target);
|
||||
|
||||
// create the tile layer with correct attribution
|
||||
var osmMapnikUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
var osmMapnikAttrib='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
|
||||
var osmMapnik = new L.TileLayer(osmMapnikUrl, {minZoom: 1, maxZoom: 19, attribution: osmMapnikAttrib});
|
||||
|
||||
var osmWikimediaUrl='https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png';
|
||||
var osmWikimediaAttrib = 'Wikimedia maps beta | Maps data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
|
||||
var osmWikimedia = new L.TileLayer(osmWikimediaUrl, {minZoom: 1, maxZoom: 19, attribution: osmWikimediaAttrib});
|
||||
|
||||
// init map view
|
||||
if(map_bounds) {
|
||||
// TODO hack: https://github.com/Leaflet/Leaflet/issues/2021
|
||||
setTimeout(function () {
|
||||
map.fitBounds(map_bounds, {
|
||||
maxZoom:17
|
||||
});
|
||||
}, 0);
|
||||
} else if (map_lon && map_lat) {
|
||||
if(map_zoom)
|
||||
map.setView(new L.LatLng(map_lat, map_lon),map_zoom);
|
||||
else
|
||||
map.setView(new L.LatLng(map_lat, map_lon),8);
|
||||
}
|
||||
|
||||
map.addLayer(osmMapnik);
|
||||
|
||||
var baseLayers = {
|
||||
"OSM Mapnik": osmMapnik/*,
|
||||
"OSM Wikimedia": osmWikimedia*/
|
||||
};
|
||||
|
||||
L.control.layers(baseLayers).addTo(map);
|
||||
|
||||
|
||||
if(map_geojson)
|
||||
L.geoJson(map_geojson).addTo(map);
|
||||
/*else if(map_bounds)
|
||||
L.rectangle(map_bounds, {color: "#ff7800", weight: 3, fill:false}).addTo(map);*/
|
||||
});
|
||||
|
||||
// this event occour only once per element
|
||||
$( this ).off( event );
|
||||
});
|
||||
});
|
||||
/**
|
||||
* 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) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
|
||||
*/
|
||||
|
||||
$(document).ready(function(){
|
||||
$(".searx_overpass_request").on( "click", function( event ) {
|
||||
var overpass_url = "https://overpass-api.de/api/interpreter?data=";
|
||||
var query_start = overpass_url + "[out:json][timeout:25];(";
|
||||
var query_end = ");out meta;";
|
||||
|
||||
var osm_id = $(this).data('osm-id');
|
||||
var osm_type = $(this).data('osm-type');
|
||||
var result_table = $(this).data('result-table');
|
||||
var result_table_loadicon = "#" + $(this).data('result-table-loadicon');
|
||||
|
||||
// tags which can be ignored
|
||||
var osm_ignore_tags = [ "addr:city", "addr:country", "addr:housenumber", "addr:postcode", "addr:street" ];
|
||||
|
||||
if(osm_id && osm_type && result_table) {
|
||||
result_table = "#" + result_table;
|
||||
var query = null;
|
||||
switch(osm_type) {
|
||||
case 'node':
|
||||
query = query_start + "node(" + osm_id + ");" + query_end;
|
||||
break;
|
||||
case 'way':
|
||||
query = query_start + "way(" + osm_id + ");" + query_end;
|
||||
break;
|
||||
case 'relation':
|
||||
query = query_start + "relation(" + osm_id + ");" + query_end;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(query) {
|
||||
//alert(query);
|
||||
var ajaxRequest = $.ajax( query )
|
||||
.done(function( html) {
|
||||
if(html && html.elements && html.elements[0]) {
|
||||
var element = html.elements[0];
|
||||
var newHtml = $(result_table).html();
|
||||
for (var row in element.tags) {
|
||||
if(element.tags.name === null || osm_ignore_tags.indexOf(row) == -1) {
|
||||
newHtml += "<tr><td>" + row + "</td><td>";
|
||||
switch(row) {
|
||||
case "phone":
|
||||
case "fax":
|
||||
newHtml += "<a href=\"tel:" + element.tags[row].replace(/ /g,'') + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
case "email":
|
||||
newHtml += "<a href=\"mailto:" + element.tags[row] + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
case "website":
|
||||
case "url":
|
||||
newHtml += "<a href=\"" + element.tags[row] + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
case "wikidata":
|
||||
newHtml += "<a href=\"https://www.wikidata.org/wiki/" + element.tags[row] + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
case "wikipedia":
|
||||
if(element.tags[row].indexOf(":") != -1) {
|
||||
newHtml += "<a href=\"https://" + element.tags[row].substring(0,element.tags[row].indexOf(":")) + ".wikipedia.org/wiki/" + element.tags[row].substring(element.tags[row].indexOf(":")+1) + "\">" + element.tags[row] + "</a>";
|
||||
break;
|
||||
}
|
||||
/* jshint ignore:start */
|
||||
default:
|
||||
/* jshint ignore:end */
|
||||
newHtml += element.tags[row];
|
||||
break;
|
||||
}
|
||||
newHtml += "</td></tr>";
|
||||
}
|
||||
}
|
||||
$(result_table).html(newHtml);
|
||||
$(result_table).removeClass('hidden');
|
||||
$(result_table_loadicon).addClass('hidden');
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
$(result_table_loadicon).html($(result_table_loadicon).html() + "<p class=\"text-muted\">could not load data!</p>");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// this event occour only once per element
|
||||
$( this ).off( event );
|
||||
});
|
||||
|
||||
$(".searx_init_map").on( "click", function( event ) {
|
||||
var leaflet_target = $(this).data('leaflet-target');
|
||||
var map_lon = $(this).data('map-lon');
|
||||
var map_lat = $(this).data('map-lat');
|
||||
var map_zoom = $(this).data('map-zoom');
|
||||
var map_boundingbox = $(this).data('map-boundingbox');
|
||||
var map_geojson = $(this).data('map-geojson');
|
||||
|
||||
require(['leaflet-0.7.3.min'], function(leaflet) {
|
||||
if(map_boundingbox) {
|
||||
southWest = L.latLng(map_boundingbox[0], map_boundingbox[2]);
|
||||
northEast = L.latLng(map_boundingbox[1], map_boundingbox[3]);
|
||||
map_bounds = L.latLngBounds(southWest, northEast);
|
||||
}
|
||||
|
||||
// TODO hack
|
||||
// change default imagePath
|
||||
L.Icon.Default.imagePath = "./static/themes/oscar/img/map";
|
||||
|
||||
// init map
|
||||
var map = L.map(leaflet_target);
|
||||
|
||||
// create the tile layer with correct attribution
|
||||
var osmMapnikUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
var osmMapnikAttrib='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
|
||||
var osmMapnik = new L.TileLayer(osmMapnikUrl, {minZoom: 1, maxZoom: 19, attribution: osmMapnikAttrib});
|
||||
|
||||
var osmWikimediaUrl='https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png';
|
||||
var osmWikimediaAttrib = 'Wikimedia maps beta | Maps data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';
|
||||
var osmWikimedia = new L.TileLayer(osmWikimediaUrl, {minZoom: 1, maxZoom: 19, attribution: osmWikimediaAttrib});
|
||||
|
||||
// init map view
|
||||
if(map_bounds) {
|
||||
// TODO hack: https://github.com/Leaflet/Leaflet/issues/2021
|
||||
setTimeout(function () {
|
||||
map.fitBounds(map_bounds, {
|
||||
maxZoom:17
|
||||
});
|
||||
}, 0);
|
||||
} else if (map_lon && map_lat) {
|
||||
if(map_zoom)
|
||||
map.setView(new L.LatLng(map_lat, map_lon),map_zoom);
|
||||
else
|
||||
map.setView(new L.LatLng(map_lat, map_lon),8);
|
||||
}
|
||||
|
||||
map.addLayer(osmMapnik);
|
||||
|
||||
var baseLayers = {
|
||||
"OSM Mapnik": osmMapnik/*,
|
||||
"OSM Wikimedia": osmWikimedia*/
|
||||
};
|
||||
|
||||
L.control.layers(baseLayers).addTo(map);
|
||||
|
||||
|
||||
if(map_geojson)
|
||||
L.geoJson(map_geojson).addTo(map);
|
||||
/*else if(map_bounds)
|
||||
L.rectangle(map_bounds, {color: "#ff7800", weight: 3, fill:false}).addTo(map);*/
|
||||
});
|
||||
|
||||
// this event occour only once per element
|
||||
$( this ).off( event );
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ ul.nav li a {
|
|||
border-bottom: 4px solid #3d9f94 !important;
|
||||
}
|
||||
|
||||
.result-content {
|
||||
.result-content, .result-source, .result-format {
|
||||
color:#B5B8B7 !important;
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ ul.nav li a {
|
|||
|
||||
.btn:hover {
|
||||
color:#444 !important;
|
||||
background-color: #BBB !important;
|
||||
background-color: #BBB !important;
|
||||
}
|
||||
|
||||
.btn-primary.active {
|
||||
|
|
@ -221,7 +221,7 @@ p.btn.btn-default{
|
|||
}
|
||||
|
||||
.table-hover > tbody > tr:hover > td, .table-hover > tbody > tr:hover > th {
|
||||
background: rgb(102, 105, 110) !important;
|
||||
background: rgb(102, 105, 110) !important;
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ pre, code{
|
|||
user-select: none;
|
||||
cursor: default;
|
||||
color: #556366;
|
||||
|
||||
|
||||
&::selection {
|
||||
background: transparent; /* WebKit/Blink Browsers */
|
||||
}
|
||||
|
|
@ -99,5 +99,3 @@ pre, code{
|
|||
.highlight {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
table-layout: fixed;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.infobox_part:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,4 +28,3 @@
|
|||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.result-content {
|
||||
.result-content, .result-format, .result-source {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 0;
|
||||
word-wrap: break-word;
|
||||
|
|
@ -41,6 +41,16 @@
|
|||
|
||||
}
|
||||
|
||||
.result-source {
|
||||
font-size: 10px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.result-format {
|
||||
font-size: 10px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.external-link {
|
||||
color: @dark-green;
|
||||
font-size: 12px;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@
|
|||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
|
||||
|
||||
&::selection {
|
||||
background: transparent; /* WebKit/Blink Browsers */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
word-wrap: break-word;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
|
||||
.infobox_part:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@
|
|||
"devDependencies": {
|
||||
"grunt": "~0.4.5",
|
||||
"grunt-contrib-uglify": "~0.6.0",
|
||||
"grunt-contrib-watch" : "~0.6.1",
|
||||
"grunt-contrib-concat" : "~0.5.0",
|
||||
"grunt-contrib-jshint" : "~0.10.0",
|
||||
"grunt-contrib-less" : "~0.11.0"
|
||||
"grunt-contrib-watch": "~0.6.1",
|
||||
"grunt-contrib-concat": "~0.5.0",
|
||||
"grunt-contrib-jshint": "~0.10.0",
|
||||
"grunt-contrib-less": "~0.11.0"
|
||||
},
|
||||
|
||||
"scripts": {
|
||||
"build": "npm install && grunt",
|
||||
"start": "grunt watch",
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
/*! searx | 14-08-2018 | https://github.com/asciimoo/searx */
|
||||
/*! searx | 06-08-2019 | https://github.com/asciimoo/searx */
|
||||
/*
|
||||
* searx, A privacy-respecting, hackable metasearch engine
|
||||
*
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
/*! searx | 14-08-2018 | https://github.com/asciimoo/searx */
|
||||
/*! searx | 06-08-2019 | https://github.com/asciimoo/searx */
|
||||
/*
|
||||
* searx, A privacy-respecting, hackable metasearch engine
|
||||
*
|
||||
|
|
|
|||
2
searx/static/themes/simple/css/searx.min.css
vendored
2
searx/static/themes/simple/css/searx.min.css
vendored
File diff suppressed because one or more lines are too long
|
|
@ -10,35 +10,8 @@ module.exports = function(grunt) {
|
|||
tasks: ['jshint', 'concat', 'uglify', 'webfont', 'less:development', 'less:production']
|
||||
}
|
||||
},
|
||||
concat: {
|
||||
options: {
|
||||
separator: ';'
|
||||
},
|
||||
dist: {
|
||||
src: ['js/searx_src/*.js'],
|
||||
dest: 'js/searx.js'
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
options: {
|
||||
banner: '/*! simple/searx.min.js | <%= grunt.template.today("dd-mm-yyyy") %> | https://github.com/asciimoo/searx */\n',
|
||||
output: {
|
||||
comments: 'some'
|
||||
},
|
||||
ie8: false,
|
||||
warnings: true,
|
||||
compress: false,
|
||||
mangle: true,
|
||||
sourceMap: true
|
||||
},
|
||||
dist: {
|
||||
files: {
|
||||
'js/searx.min.js': ['<%= concat.dist.dest %>']
|
||||
}
|
||||
}
|
||||
},
|
||||
jshint: {
|
||||
files: ['js/searx_src/*.js'],
|
||||
files: ['js/searx_src/*.js', 'js/searx_header/*.js'],
|
||||
options: {
|
||||
reporterOutput: "",
|
||||
proto: true,
|
||||
|
|
@ -50,6 +23,36 @@ module.exports = function(grunt) {
|
|||
}
|
||||
}
|
||||
},
|
||||
concat: {
|
||||
head_and_body: {
|
||||
options: {
|
||||
separator: ';'
|
||||
},
|
||||
files: {
|
||||
'js/searx.head.js': ['js/searx_head/*.js'],
|
||||
'js/searx.js': ['js/searx_src/*.js']
|
||||
}
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
options: {
|
||||
banner: '/*! simple/searx.min.js | <%= grunt.template.today("dd-mm-yyyy") %> | https://github.com/asciimoo/searx */\n',
|
||||
output: {
|
||||
comments: 'some'
|
||||
},
|
||||
ie8: false,
|
||||
warnings: true,
|
||||
compress: false,
|
||||
mangle: true,
|
||||
sourceMap: true
|
||||
},
|
||||
dist: {
|
||||
files: {
|
||||
'js/searx.head.min.js': ['js/searx.head.js'],
|
||||
'js/searx.min.js': ['js/searx.js']
|
||||
}
|
||||
}
|
||||
},
|
||||
less: {
|
||||
development: {
|
||||
options: {
|
||||
|
|
|
|||
40
searx/static/themes/simple/js/searx.head.js
Normal file
40
searx/static/themes/simple/js/searx.head.js
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* 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) 2019 by Alexandre Flament
|
||||
*
|
||||
*/
|
||||
(function(w, d) {
|
||||
'use strict';
|
||||
|
||||
// add data- properties
|
||||
var script = d.currentScript || (function() {
|
||||
var scripts = d.getElementsByTagName('script');
|
||||
return scripts[scripts.length - 1];
|
||||
})();
|
||||
|
||||
// try to detect touch screen
|
||||
w.searx = {
|
||||
touch: (("ontouchstart" in w) || w.DocumentTouch && document instanceof DocumentTouch) || false,
|
||||
method: script.getAttribute('data-method'),
|
||||
autocompleter: script.getAttribute('data-autocompleter') === 'true',
|
||||
search_on_category_select: script.getAttribute('data-search-on-category-select') === 'true',
|
||||
infinite_scroll: script.getAttribute('data-infinite-scroll') === 'true',
|
||||
static_path: script.getAttribute('data-static-path'),
|
||||
no_item_found: script.getAttribute('data-no-item-found')
|
||||
}
|
||||
|
||||
// update the css
|
||||
d.getElementsByTagName("html")[0].className = (w.searx.touch)?"js touch":"js";
|
||||
})(window, document);
|
||||
4
searx/static/themes/simple/js/searx.head.min.js
vendored
Normal file
4
searx/static/themes/simple/js/searx.head.min.js
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
/*! simple/searx.min.js | 06-08-2019 | https://github.com/asciimoo/searx */
|
||||
|
||||
(function(t,e){"use strict";var a=e.currentScript||function(){var t=e.getElementsByTagName("script");return t[t.length-1]}();t.searx={touch:"ontouchstart"in t||t.DocumentTouch&&document instanceof DocumentTouch||false,method:a.getAttribute("data-method"),autocompleter:a.getAttribute("data-autocompleter")==="true",search_on_category_select:a.getAttribute("data-search-on-category-select")==="true",infinite_scroll:a.getAttribute("data-infinite-scroll")==="true",static_path:a.getAttribute("data-static-path"),no_item_found:a.getAttribute("data-no-item-found")};e.getElementsByTagName("html")[0].className=t.searx.touch?"js touch":"js"})(window,document);
|
||||
//# sourceMappingURL=searx.head.min.js.map
|
||||
1
searx/static/themes/simple/js/searx.head.min.js.map
Normal file
1
searx/static/themes/simple/js/searx.head.min.js.map
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"sources":["searx.head.js"],"names":["w","d","script","currentScript","scripts","getElementsByTagName","length","searx","touch","DocumentTouch","document","method","getAttribute","autocompleter","search_on_category_select","infinite_scroll","static_path","no_item_found","className","window"],"mappings":";;CAiBA,SAAUA,EAAGC,GACT,aAGA,IAAIC,EAASD,EAAEE,eAAkB,WAC7B,IAAIC,EAAUH,EAAEI,qBAAqB,UACrC,OAAOD,EAAQA,EAAQE,OAAS,GAFH,GAMjCN,EAAEO,MAAQ,CACNC,MAAS,iBAAkBR,GAAMA,EAAES,eAAiBC,oBAAoBD,eAAkB,MAC1FE,OAAQT,EAAOU,aAAa,eAC5BC,cAAeX,EAAOU,aAAa,wBAA0B,OAC7DE,0BAA2BZ,EAAOU,aAAa,oCAAsC,OACrFG,gBAAiBb,EAAOU,aAAa,0BAA4B,OACjEI,YAAad,EAAOU,aAAa,oBACjCK,cAAef,EAAOU,aAAa,uBAIvCX,EAAEI,qBAAqB,QAAQ,GAAGa,UAAalB,EAAEO,MAAW,MAAE,WAAW,MArB7E,CAsBGY,OAAQT","file":"searx.head.min.js"}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* (C) 2017 by Alexandre Flament, <alex@al-f.net>
|
||||
*
|
||||
*/
|
||||
(function(w, d, searx) {
|
||||
window.searx = (function(w, d) {
|
||||
|
||||
'use strict';
|
||||
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
searx = searx || {};
|
||||
var searx = window.searx || {};
|
||||
|
||||
searx.on = function(obj, eventType, callback, useCapture) {
|
||||
useCapture = useCapture || false;
|
||||
|
|
@ -110,7 +110,7 @@
|
|||
};
|
||||
|
||||
searx.loadStyle = function(src) {
|
||||
var path = searx.staticPath + src,
|
||||
var path = searx.static_path + src,
|
||||
id = "style_" + src.replace('.', '_'),
|
||||
s = d.getElementById(id);
|
||||
if (s === null) {
|
||||
|
|
@ -124,7 +124,7 @@
|
|||
};
|
||||
|
||||
searx.loadScript = function(src, callback) {
|
||||
var path = searx.staticPath + src,
|
||||
var path = searx.static_path + src,
|
||||
id = "script_" + src.replace('.', '_'),
|
||||
s = d.getElementById(id);
|
||||
if (s === null) {
|
||||
|
|
@ -161,7 +161,7 @@
|
|||
});
|
||||
|
||||
return searx;
|
||||
})(window, document, window.searx);
|
||||
})(window, document);
|
||||
;(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.AutoComplete = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
/*
|
||||
* @license MIT
|
||||
|
|
@ -1529,7 +1529,7 @@ module.exports = AutoComplete;
|
|||
if (searx.autocompleter) {
|
||||
searx.autocomplete = AutoComplete.call(w, {
|
||||
Url: "./autocompleter",
|
||||
EmptyMessage: searx.noItemFound,
|
||||
EmptyMessage: searx.no_item_found,
|
||||
HttpMethod: searx.method,
|
||||
MinChars: 4,
|
||||
Delay: 300,
|
||||
|
|
|
|||
10
searx/static/themes/simple/js/searx.min.js
vendored
10
searx/static/themes/simple/js/searx.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
40
searx/static/themes/simple/js/searx_head/00_init.js
Normal file
40
searx/static/themes/simple/js/searx_head/00_init.js
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* 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) 2019 by Alexandre Flament
|
||||
*
|
||||
*/
|
||||
(function(w, d) {
|
||||
'use strict';
|
||||
|
||||
// add data- properties
|
||||
var script = d.currentScript || (function() {
|
||||
var scripts = d.getElementsByTagName('script');
|
||||
return scripts[scripts.length - 1];
|
||||
})();
|
||||
|
||||
// try to detect touch screen
|
||||
w.searx = {
|
||||
touch: (("ontouchstart" in w) || w.DocumentTouch && document instanceof DocumentTouch) || false,
|
||||
method: script.getAttribute('data-method'),
|
||||
autocompleter: script.getAttribute('data-autocompleter') === 'true',
|
||||
search_on_category_select: script.getAttribute('data-search-on-category-select') === 'true',
|
||||
infinite_scroll: script.getAttribute('data-infinite-scroll') === 'true',
|
||||
static_path: script.getAttribute('data-static-path'),
|
||||
no_item_found: script.getAttribute('data-no-item-found')
|
||||
}
|
||||
|
||||
// update the css
|
||||
d.getElementsByTagName("html")[0].className = (w.searx.touch)?"js touch":"js";
|
||||
})(window, document);
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* (C) 2017 by Alexandre Flament, <alex@al-f.net>
|
||||
*
|
||||
*/
|
||||
(function(w, d, searx) {
|
||||
window.searx = (function(w, d) {
|
||||
|
||||
'use strict';
|
||||
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
searx = searx || {};
|
||||
var searx = window.searx || {};
|
||||
|
||||
searx.on = function(obj, eventType, callback, useCapture) {
|
||||
useCapture = useCapture || false;
|
||||
|
|
@ -110,7 +110,7 @@
|
|||
};
|
||||
|
||||
searx.loadStyle = function(src) {
|
||||
var path = searx.staticPath + src,
|
||||
var path = searx.static_path + src,
|
||||
id = "style_" + src.replace('.', '_'),
|
||||
s = d.getElementById(id);
|
||||
if (s === null) {
|
||||
|
|
@ -124,7 +124,7 @@
|
|||
};
|
||||
|
||||
searx.loadScript = function(src, callback) {
|
||||
var path = searx.staticPath + src,
|
||||
var path = searx.static_path + src,
|
||||
id = "script_" + src.replace('.', '_'),
|
||||
s = d.getElementById(id);
|
||||
if (s === null) {
|
||||
|
|
@ -161,4 +161,4 @@
|
|||
});
|
||||
|
||||
return searx;
|
||||
})(window, document, window.searx);
|
||||
})(window, document);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@
|
|||
if (searx.autocompleter) {
|
||||
searx.autocomplete = AutoComplete.call(w, {
|
||||
Url: "./autocompleter",
|
||||
EmptyMessage: searx.noItemFound,
|
||||
EmptyMessage: searx.no_item_found,
|
||||
HttpMethod: searx.method,
|
||||
MinChars: 4,
|
||||
Delay: 300,
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
13
searx/templates/courgette/result_templates/key-value.html
Normal file
13
searx/templates/courgette/result_templates/key-value.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<div class="result">
|
||||
<table>
|
||||
{% for key, value in result.items() %}
|
||||
{% if key in ['engine', 'engines', 'template', 'score', 'category', 'positions'] %}
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td><b>{{ key|upper }}</b>: {{ value|safe }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<p class="engines">{{ result.engines|join(', ') }}</p>
|
||||
</div>
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
{% endif %}
|
||||
<h3 class="result_title"><a href="{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.title|safe }}</a></h3>
|
||||
{% if result.content %}<span class="content">{{ result.content|safe }}</span><br />{% endif %}
|
||||
{% if result.seed %}<span class="stats">{{ _('Seeder') }} : {{ result.seed }}, {{ _('Leecher') }} : {{ result.leech }}</span><br />{% endif %}
|
||||
{% if result.seed is defined %}<span class="stats">{{ _('Seeder') }} : {{ result.seed }}, {{ _('Leecher') }} : {{ result.leech }}</span><br />{% endif %}
|
||||
<span>
|
||||
{% if result.magnetlink %}<a href="{{ result.magnetlink }}" class="magnetlink">{{ _('magnet link') }}</a>{% endif %}
|
||||
{% if result.torrentfile %}<a href="{{ result.torrentfile }}" class="torrentfile" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ _('torrent file') }}</a>{% endif %}
|
||||
|
|
|
|||
13
searx/templates/legacy/result_templates/key-value.html
Normal file
13
searx/templates/legacy/result_templates/key-value.html
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<table class="result-table">
|
||||
{% for key, value in result.items() %}
|
||||
{% if key in ['engine', 'engines', 'template', 'score', 'category', 'positions'] %}
|
||||
{% continue %}
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td><b>{{ key|upper }}</b>: {{ value|safe }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
<tr>
|
||||
<td><b>ENGINES</b>: {{ result.engines|join(', ') }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
@ -8,6 +8,6 @@
|
|||
<p>
|
||||
{% if result.magnetlink %}<a href="{{ result.magnetlink }}" class="magnetlink">{{ _('magnet link') }}</a>{% endif %}
|
||||
{% if result.torrentfile %}<a href="{{ result.torrentfile }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %} class="torrentfile">{{ _('torrent file') }}</a>{% endif %} -
|
||||
{% if result.seed %}<span class="stats">{{ _('Seeder') }} : {{ result.seed }}, {{ _('Leecher') }} : {{ result.leech }}</span>{% endif %}
|
||||
{% if result.seed is defined %}<span class="stats">{{ _('Seeder') }} : {{ result.seed }}, {{ _('Leecher') }} : {{ result.leech }}</span>{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
<input type="checkbox" name="advanced_search" id="check-advanced" {% if advanced_search %} checked="checked"{% endif %}>
|
||||
<label for="check-advanced">
|
||||
<label for="check-advanced">{{- "" -}}
|
||||
<span class="glyphicon glyphicon-cog"></span>
|
||||
{{ _('Advanced settings') }}
|
||||
{{- _('Advanced settings') -}}
|
||||
</label>
|
||||
<div id="advanced-search-container">
|
||||
{% include 'oscar/categories.html' %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
{% include 'oscar/time-range.html' %}
|
||||
{%- include 'oscar/time-range.html' -%}
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
{% include 'oscar/languages.html' %}
|
||||
{%- include 'oscar/languages.html' -%}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -10,16 +10,17 @@
|
|||
<meta name="referrer" content="no-referrer">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1 , maximum-scale=1.0, user-scalable=1" />
|
||||
{% block meta %}{% endblock %}
|
||||
<title>{% block title %}{% endblock %}{{ instance_name }}</title>
|
||||
|
||||
<title>{% block title %}{% endblock %}{{ instance_name }}</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}" type="text/css" />
|
||||
{% if preferences.get_value('oscar-style') %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/'+preferences.get_value('oscar-style')+'.min.css') }}" type="text/css" />
|
||||
{% else %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/logicodev.min.css') }}" type="text/css" />
|
||||
{% endif %}
|
||||
{% if preferences.get_value('oscar-style') -%}
|
||||
{{' '}}<link rel="stylesheet" href="{{ url_for('static', filename='css/'+preferences.get_value('oscar-style')+'.min.css') }}" type="text/css" />
|
||||
{%- else -%}
|
||||
{{' '}}<link rel="stylesheet" href="{{ url_for('static', filename='css/logicodev.min.css') }}" type="text/css" />
|
||||
{%- endif %}
|
||||
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/leaflet.min.css') }}" type="text/css" />
|
||||
{% for css in styles %}
|
||||
{%- for css in styles %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename=css) }}" type="text/css" />
|
||||
{% endfor %}
|
||||
|
||||
|
|
@ -37,12 +38,6 @@
|
|||
{% endblock %}
|
||||
|
||||
<link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
|
||||
|
||||
<script type="text/javascript">
|
||||
searx = {};
|
||||
searx.method = "{{ method or 'POST' }}";
|
||||
searx.autocompleter = {% if autocomplete %}true{% else %}false{% endif %};
|
||||
</script>
|
||||
<noscript>
|
||||
<style type="text/css">
|
||||
.tab-content > .active_if_nojs, .active_if_nojs {display: block !important; visibility: visible !important;}
|
||||
|
|
@ -54,6 +49,7 @@
|
|||
</head>
|
||||
<body>
|
||||
{% include 'oscar/navbar.html' %}
|
||||
|
||||
<div class="container">
|
||||
{% if errors %}
|
||||
<div class="alert alert-danger fade in" role="alert">
|
||||
|
|
@ -99,11 +95,14 @@
|
|||
</div>
|
||||
<script src="{{ url_for('static', filename='js/jquery-1.11.1.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/bootstrap.min.js') }}"></script>
|
||||
{% if autocomplete %}<script src="{{ url_for('static', filename='js/typeahead.bundle.min.js') }}"></script>{% endif %}
|
||||
{% if autocomplete %} <script src="{{ url_for('static', filename='js/typeahead.bundle.min.js') }}"></script>{% endif %}
|
||||
|
||||
<script src="{{ url_for('static', filename='js/require-2.1.15.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/searx.min.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/searx.min.js') }}"
|
||||
data-method="{{ method or 'POST' }}"
|
||||
data-autocompleter="{% if autocomplete %}true{% else %}false{% endif %}"></script>
|
||||
{% for script in scripts %}
|
||||
<script src="{{ url_for('static', filename=script) }}"></script>
|
||||
{{""}}<script src="{{ url_for('static', filename=script) }}"></script>
|
||||
{% endfor %}
|
||||
<noscript>
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
<div id="categories">
|
||||
{% if rtl %}
|
||||
{% for category in categories | reverse %}
|
||||
<input class="hidden" type="checkbox" id="checkbox_{{ category|replace(' ', '_') }}" name="category_{{ category }}" {% if category in selected_categories %}checked="checked"{% endif %} />
|
||||
{%- if rtl -%}
|
||||
{% for category in categories | reverse -%}
|
||||
<input class="hidden" type="checkbox" id="checkbox_{{ category|replace(' ', '_') }}" name="category_{{ category }}" {% if category in selected_categories %}checked="checked"{% endif %} />{{- '' -}}
|
||||
<label for="checkbox_{{ category|replace(' ', '_') }}">{{ _(category) }}</label>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for category in categories %}
|
||||
<input class="hidden" type="checkbox" id="checkbox_{{ category|replace(' ', '_') }}" name="category_{{ category }}" {% if category in selected_categories %}checked="checked"{% endif %} />
|
||||
{%- endfor %}
|
||||
{%- else -%}
|
||||
{% for category in categories -%}
|
||||
<input class="hidden" type="checkbox" id="checkbox_{{ category|replace(' ', '_') }}" name="category_{{ category }}" {% if category in selected_categories %}checked="checked"{% endif %} />{{- '' -}}
|
||||
<label for="checkbox_{{ category|replace(' ', '_') }}">{{ _(category) }}</label>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{%- endfor %}
|
||||
{%- endif -%}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,34 +1,35 @@
|
|||
{% from 'oscar/macros.html' import result_link with context %}
|
||||
<div class="panel panel-default infobox">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title infobox_part"><bdi>{{ infobox.infobox }}</bdi></h4>
|
||||
<div class="panel-heading">{{- "" -}}
|
||||
<h4 class="panel-title infobox_part"><bdi>{{ infobox.infobox }}</bdi></h4>{{- "" -}}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{% if infobox.img_src %}<img class="img-responsive center-block infobox_part" src="{{ image_proxify(infobox.img_src) }}" alt="{{ infobox.infobox }}" />{% endif %}
|
||||
{% if infobox.content %}<bdi><p class="infobox_part">{{ infobox.content }}</bdi></p>{% endif %}
|
||||
|
||||
{% if infobox.attributes %}
|
||||
{% if infobox.content %}<bdi><p class="infobox_part">{{ infobox.content | safe }}</p></bdi>{% endif %}
|
||||
|
||||
{% if infobox.attributes -%}
|
||||
<table class="table table-striped infobox_part">
|
||||
{% for attribute in infobox.attributes %}
|
||||
<tr>
|
||||
{% for attribute in infobox.attributes -%}
|
||||
<tr>{{- "" -}}
|
||||
<td><bdi>{{ attribute.label }}</bdi></td>
|
||||
{% if attribute.image %}
|
||||
{%- if attribute.image -%}
|
||||
<td><img class="img-responsive" src="{{ image_proxify(attribute.image.src) }}" alt="{{ attribute.image.alt }}" /></td>
|
||||
{% else %}
|
||||
{%- else -%}
|
||||
<td><bdi>{{ attribute.value }}</bdi></td>
|
||||
{% endif %}
|
||||
{%- endif -%}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endfor -%}
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
{% if infobox.urls %}
|
||||
<div class="infobox_part">
|
||||
{% if infobox.urls -%}
|
||||
<div class="infobox_part">{{- "\n" -}}
|
||||
<bdi>
|
||||
{% for url in infobox.urls %}
|
||||
<p class="btn btn-default btn-xs">{{ result_link(url.url, url.title) }}</a></p>
|
||||
{% endfor %}
|
||||
</bdi>
|
||||
{%- for url in infobox.urls -%}
|
||||
<p class="btn btn-default btn-xs">{{ result_link(url.url, url.title) }}</p>
|
||||
{% endfor -%}
|
||||
</bdi>{{- "" -}}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
{% if preferences %}
|
||||
<select class="custom-select form-control" name='language'>
|
||||
{% else %}
|
||||
<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) %}
|
||||
<option value="{{ lang_id }}" {% if lang_id == current_language %}selected="selected"{% endif %}>
|
||||
{{ lang_name }} {% if country_name %}({{ country_name }}) {% endif %}- {{ lang_id }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
<select class="language custom-select form-control" id="language" name="language" accesskey="l">
|
||||
<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) -%}
|
||||
<option value="{{ lang_id }}" {% if lang_id == current_language %}selected="selected"{% endif %}>
|
||||
{{- lang_name }} {% if country_name %}({{ country_name }}) {% endif %}- {{ lang_id -}}
|
||||
</option>
|
||||
{%- endfor -%}
|
||||
</select>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
<!-- Draw result header -->
|
||||
{% macro result_header(result, favicons) -%}
|
||||
<h4 class="result_header">{% if result.engine~".png" in favicons %}{{ draw_favicon(result.engine) }} {% endif %}{{ result_link(result.url, result.title|safe) }}</h4>
|
||||
<h4 class="result_header">{% if result.engine~".png" in favicons %}{{ draw_favicon(result.engine) }} {% endif %}{% if result.url %}{{ result_link(result.url, result.title|safe) }}{% else %}{{ result.title|safe}}{% endif %}</h4>
|
||||
{%- endmacro %}
|
||||
|
||||
<!-- Draw result sub header -->
|
||||
|
|
@ -26,30 +26,38 @@
|
|||
|
||||
<!-- Draw result footer -->
|
||||
{% macro result_footer(result) -%}
|
||||
<div class="clearfix"></div>
|
||||
<div class="clearfix"></div>{{- "" -}}
|
||||
<div class="pull-right">
|
||||
{% for engine in result.engines %}
|
||||
<span class="label label-default">{{ engine }}</span>
|
||||
{% endfor %}
|
||||
<small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info") }}</small>
|
||||
{% if proxify %}
|
||||
<small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="external-link">{{ result.pretty_url }}</div>
|
||||
{%- for engine in result.engines -%}
|
||||
<span class="label label-default">{{ engine }}</span>
|
||||
{%- endfor -%}
|
||||
{%- if result.url -%}
|
||||
<small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info") }}</small>
|
||||
{%- endif -%}
|
||||
{%- if proxify -%}
|
||||
<small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small>
|
||||
{%- endif -%}
|
||||
</div>
|
||||
{%- if result.pretty_url -%}
|
||||
<div class="external-link">{{ result.pretty_url }}</div>
|
||||
{%- endif -%}
|
||||
{%- endmacro %}
|
||||
|
||||
<!-- Draw result footer -->
|
||||
{% macro result_footer_rtl(result) -%}
|
||||
<div class="clearfix"></div>
|
||||
{% for engine in result.engines %}
|
||||
<div class="clearfix"></div>{{- "" -}}
|
||||
{% for engine in result.engines -%}
|
||||
<span class="label label-default">{{ engine }}</span>
|
||||
{% endfor %}
|
||||
{%- endfor %}
|
||||
{%- if result.url -%}
|
||||
<small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info") }}</small>
|
||||
{% if proxify %}
|
||||
{%- endif -%}
|
||||
{% if proxify -%}
|
||||
<small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small>
|
||||
{% endif %}
|
||||
{%- endif %}
|
||||
{%- if result.pretty_url -%}
|
||||
<div class="external-link">{{ result.pretty_url }}</div>
|
||||
{%- endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro preferences_item_header(info, label, rtl) -%}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
<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 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>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
{% set language_label = _('Search language') %}
|
||||
{% set language_info = _('What language do you prefer for search?') %}
|
||||
{{ preferences_item_header(language_info, language_label, rtl) }}
|
||||
{% include 'oscar/languages.html' %}
|
||||
{% include 'oscar/languages.html' %}
|
||||
{{ preferences_item_footer(language_info, language_label, rtl) }}
|
||||
|
||||
{% set locale_label = _('Interface language') %}
|
||||
|
|
@ -156,26 +156,26 @@
|
|||
<div class="container-fluid">
|
||||
<fieldset>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-condensed table-striped">
|
||||
<tr>
|
||||
<table class="table table-hover table-condensed table-striped">
|
||||
<tr>
|
||||
{% if not rtl %}
|
||||
<th>{{ _("Allow") }}</th>
|
||||
<th>{{ _("Engine name") }}</th>
|
||||
<th>{{ _("Shortcut") }}</th>
|
||||
<th>{{ _("Selected language") }}</th>
|
||||
<th>{{ _("SafeSearch") }}</th>
|
||||
<th>{{ _("Time range") }}</th>
|
||||
<th>{{ _("Avg. time") }}</th>
|
||||
<th>{{ _("Max time") }}</th>
|
||||
<th>{{ _("Allow") }}</th>
|
||||
<th>{{ _("Engine name") }}</th>
|
||||
<th>{{ _("Shortcut") }}</th>
|
||||
<th>{{ _("Selected language") }}</th>
|
||||
<th>{{ _("SafeSearch") }}</th>
|
||||
<th>{{ _("Time range") }}</th>
|
||||
<th>{{ _("Avg. time") }}</th>
|
||||
<th>{{ _("Max time") }}</th>
|
||||
{% else %}
|
||||
<th>{{ _("Max time") }}</th>
|
||||
<th>{{ _("Avg. time") }}</th>
|
||||
<th>{{ _("Time range") }}</th>
|
||||
<th>{{ _("SafeSearch") }}</th>
|
||||
<th>{{ _("Selected language") }}</th>
|
||||
<th>{{ _("Shortcut") }}</th>
|
||||
<th>{{ _("Engine name") }}</th>
|
||||
<th>{{ _("Allow") }}</th>
|
||||
<th>{{ _("Max time") }}</th>
|
||||
<th>{{ _("Avg. time") }}</th>
|
||||
<th>{{ _("Time range") }}</th>
|
||||
<th>{{ _("SafeSearch") }}</th>
|
||||
<th>{{ _("Selected language") }}</th>
|
||||
<th>{{ _("Shortcut") }}</th>
|
||||
<th>{{ _("Engine name") }}</th>
|
||||
<th>{{ _("Allow") }}</th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% for search_engine in engines_by_category[categ] %}
|
||||
|
|
@ -186,19 +186,19 @@
|
|||
{{ checkbox_toggle('engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_'), (search_engine.name, categ) in disabled_engines) }}
|
||||
</td>
|
||||
<th>{{ search_engine.name }}</th>
|
||||
<td class="name">{{ shortcuts[search_engine.name] }}</td>
|
||||
<td>{{ support_toggle(stats[search_engine.name].supports_selected_language) }}</td>
|
||||
<td>{{ support_toggle(search_engine.safesearch==True) }}</td>
|
||||
<td>{{ support_toggle(search_engine.time_range_support==True) }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_time'] else '' }}">{{ 'N/A' if stats[search_engine.name].time==None else stats[search_engine.name].time }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td>
|
||||
{% else %}
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_time'] else '' }}">{{ 'N/A' if stats[search_engine.name].time==None else stats[search_engine.name].time }}</td>
|
||||
<td>{{ support_toggle(search_engine.time_range_support==True) }}</td>
|
||||
<td>{{ support_toggle(search_engine.safesearch==True) }}</td>
|
||||
<td>{{ support_toggle(stats[search_engine.name].supports_selected_language) }}</td>
|
||||
<td>{{ shortcuts[search_engine.name] }}</td>
|
||||
<td class="name">{{ shortcuts[search_engine.name] }}</td>
|
||||
<td>{{ support_toggle(stats[search_engine.name].supports_selected_language) }}</td>
|
||||
<td>{{ support_toggle(search_engine.safesearch==True) }}</td>
|
||||
<td>{{ support_toggle(search_engine.time_range_support==True) }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_time'] else '' }}">{{ 'N/A' if stats[search_engine.name].time==None else stats[search_engine.name].time }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td>
|
||||
{% else %}
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_time'] else '' }}">{{ 'N/A' if stats[search_engine.name].time==None else stats[search_engine.name].time }}</td>
|
||||
<td>{{ support_toggle(search_engine.time_range_support==True) }}</td>
|
||||
<td>{{ support_toggle(search_engine.safesearch==True) }}</td>
|
||||
<td>{{ support_toggle(stats[search_engine.name].supports_selected_language) }}</td>
|
||||
<td>{{ shortcuts[search_engine.name] }}</td>
|
||||
<th>{{ search_engine.name }}</th>
|
||||
<td class="onoff-checkbox">
|
||||
{{ checkbox_toggle('engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_'), (search_engine.name, categ) in disabled_engines) }}
|
||||
|
|
@ -207,7 +207,7 @@
|
|||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
</table>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
{% from 'oscar/macros.html' import result_header, result_sub_header, result_footer, result_footer_rtl, icon %}
|
||||
|
||||
{{ result_header(result, favicons) }}
|
||||
{{ result_sub_header(result) }}
|
||||
|
||||
{% if result.content %}<p class="result-content">{{ result.content|safe }}</p>{% endif %}
|
||||
|
||||
{% if result.repository %}<p class="result-content">{{ icon('file') }} <a href="{{ result.repository }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.repository }}</a></p>{% endif %}
|
||||
|
||||
<div dir="ltr">
|
||||
{{ result.codelines|code_highlighter(result.code_language)|safe }}
|
||||
</div>
|
||||
|
||||
{% if rtl %}
|
||||
{{ result_footer_rtl(result) }}
|
||||
{% else %}
|
||||
{{ result_footer(result) }}
|
||||
{% endif %}
|
||||
{% from 'oscar/macros.html' import result_header, result_sub_header, result_footer, result_footer_rtl, icon %}
|
||||
|
||||
{{ result_header(result, favicons) }}
|
||||
{{ result_sub_header(result) }}
|
||||
|
||||
{% if result.content %}<p class="result-content">{{ result.content|safe }}</p>{% endif %}
|
||||
|
||||
{% if result.repository %}<p class="result-content">{{ icon('file') }} <a href="{{ result.repository }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.repository }}</a></p>{% endif %}
|
||||
|
||||
<div dir="ltr">
|
||||
{{ result.codelines|code_highlighter(result.code_language)|safe }}
|
||||
</div>
|
||||
|
||||
{% if rtl %}
|
||||
{{ result_footer_rtl(result) }}
|
||||
{% else %}
|
||||
{{ result_footer(result) }}
|
||||
{% endif %}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue