mirror of
https://github.com/YunoHost-Apps/searx_ynh.git
synced 2024-09-03 20:16:30 +02:00
update version 0.6
This commit is contained in:
parent
684b966c57
commit
c2d95ecba4
61 changed files with 1141 additions and 448 deletions
26
sources/CHANGELOG.rst
Normal file
26
sources/CHANGELOG.rst
Normal file
|
@ -0,0 +1,26 @@
|
|||
0.6.0
|
||||
=====
|
||||
|
||||
- Changelog added
|
||||
- New engines
|
||||
- Flickr (api)
|
||||
- Subtitleseeker
|
||||
- photon
|
||||
- 500px
|
||||
- Searchcode
|
||||
- Searchcode doc
|
||||
- Kickass torrent
|
||||
- Precise search request timeout handling
|
||||
- Better favicon support
|
||||
- Stricter config parsing
|
||||
- Translation updates
|
||||
- Multiple ui fixes
|
||||
- Flickr (noapi) engine fix
|
||||
- Pep8 fixes
|
||||
|
||||
|
||||
News
|
||||
~~~~
|
||||
|
||||
Health status of searx instances and engines: http://stats.searx.oe5tpo.com
|
||||
(source: https://github.com/pointhi/searx_stats)
|
57
sources/searx/engines/500px.py
Normal file
57
sources/searx/engines/500px.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
## 500px (Images)
|
||||
#
|
||||
# @website https://500px.com
|
||||
# @provide-api yes (https://developers.500px.com/)
|
||||
#
|
||||
# @using-api no
|
||||
# @results HTML
|
||||
# @stable no (HTML can change)
|
||||
# @parse url, title, thumbnail, img_src, content
|
||||
#
|
||||
# @todo rewrite to api
|
||||
|
||||
|
||||
from urllib import urlencode
|
||||
from urlparse import urljoin
|
||||
from lxml import html
|
||||
|
||||
# engine dependent config
|
||||
categories = ['images']
|
||||
paging = True
|
||||
|
||||
# search-url
|
||||
base_url = 'https://500px.com'
|
||||
search_url = base_url+'/search?search?page={pageno}&type=photos&{query}'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
params['url'] = search_url.format(pageno=params['pageno'],
|
||||
query=urlencode({'q': query}))
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
dom = html.fromstring(resp.text)
|
||||
|
||||
# parse results
|
||||
for result in dom.xpath('//div[@class="photo"]'):
|
||||
link = result.xpath('.//a')[0]
|
||||
url = urljoin(base_url, link.attrib.get('href'))
|
||||
title = result.xpath('.//div[@class="title"]//text()')[0]
|
||||
img_src = link.xpath('.//img')[0].attrib['src']
|
||||
content = result.xpath('.//div[@class="info"]//text()')[0]
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
'img_src': img_src,
|
||||
'content': content,
|
||||
'template': 'images.html'})
|
||||
|
||||
# return results
|
||||
return results
|
|
@ -41,11 +41,8 @@ def load_module(filename):
|
|||
module.name = modname
|
||||
return module
|
||||
|
||||
if 'engines' not in settings or not settings['engines']:
|
||||
print '[E] Error no engines found. Edit your settings.yml'
|
||||
exit(2)
|
||||
|
||||
for engine_data in settings['engines']:
|
||||
def load_engine(engine_data):
|
||||
engine_name = engine_data['engine']
|
||||
engine = load_module(engine_name + '.py')
|
||||
|
||||
|
@ -84,10 +81,10 @@ for engine_data in settings['engines']:
|
|||
if engine_attr.startswith('_'):
|
||||
continue
|
||||
if getattr(engine, engine_attr) is None:
|
||||
print '[E] Engine config error: Missing attribute "{0}.{1}"'.format(engine.name, engine_attr) # noqa
|
||||
print('[E] Engine config error: Missing attribute "{0}.{1}"'\
|
||||
.format(engine.name, engine_attr))
|
||||
sys.exit(1)
|
||||
|
||||
engines[engine.name] = engine
|
||||
engine.stats = {
|
||||
'result_count': 0,
|
||||
'search_count': 0,
|
||||
|
@ -104,7 +101,12 @@ for engine_data in settings['engines']:
|
|||
|
||||
if engine.shortcut:
|
||||
# TODO check duplications
|
||||
if engine.shortcut in engine_shortcuts:
|
||||
print('[E] Engine config error: ambigious shortcut: {0}'\
|
||||
.format(engine.shortcut))
|
||||
sys.exit(1)
|
||||
engine_shortcuts[engine.shortcut] = engine.name
|
||||
return engine
|
||||
|
||||
|
||||
def get_engines_stats():
|
||||
|
@ -194,3 +196,12 @@ def get_engines_stats():
|
|||
sorted(errors, key=itemgetter('avg'), reverse=True)
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
if 'engines' not in settings or not settings['engines']:
|
||||
print '[E] Error no engines found. Edit your settings.yml'
|
||||
exit(2)
|
||||
|
||||
for engine_data in settings['engines']:
|
||||
engine = load_engine(engine_data)
|
||||
engines[engine.name] = engine
|
||||
|
|
|
@ -57,12 +57,16 @@ def response(resp):
|
|||
link = result.xpath('.//div[@class="newstitle"]/a')[0]
|
||||
url = link.attrib.get('href')
|
||||
title = ' '.join(link.xpath('.//text()'))
|
||||
contentXPath = result.xpath('.//div[@class="sn_txt"]/div//span[@class="sn_snip"]//text()')
|
||||
contentXPath = result.xpath('.//div[@class="sn_txt"]/div'
|
||||
'//span[@class="sn_snip"]//text()')
|
||||
if contentXPath is not None:
|
||||
content = escape(' '.join(contentXPath))
|
||||
|
||||
# parse publishedDate
|
||||
publishedDateXPath = result.xpath('.//div[@class="sn_txt"]/div//span[contains(@class,"sn_ST")]//span[contains(@class,"sn_tm")]//text()')
|
||||
publishedDateXPath = result.xpath('.//div[@class="sn_txt"]/div'
|
||||
'//span[contains(@class,"sn_ST")]'
|
||||
'//span[contains(@class,"sn_tm")]'
|
||||
'//text()')
|
||||
if publishedDateXPath is not None:
|
||||
publishedDate = escape(' '.join(publishedDateXPath))
|
||||
|
||||
|
@ -74,7 +78,8 @@ def response(resp):
|
|||
timeNumbers = re.findall(r'\d+', publishedDate)
|
||||
publishedDate = datetime.now()\
|
||||
- timedelta(hours=int(timeNumbers[0]))
|
||||
elif re.match("^[0-9]+ hour(s|), [0-9]+ minute(s|) ago$", publishedDate):
|
||||
elif re.match("^[0-9]+ hour(s|),"
|
||||
" [0-9]+ minute(s|) ago$", publishedDate):
|
||||
timeNumbers = re.findall(r'\d+', publishedDate)
|
||||
publishedDate = datetime.now()\
|
||||
- timedelta(hours=int(timeNumbers[0]))\
|
||||
|
|
|
@ -22,10 +22,17 @@ api_key = None
|
|||
|
||||
# search-url
|
||||
url = 'http://www.faroo.com/'
|
||||
search_url = url + 'api?{query}&start={offset}&length={number_of_results}&l={language}&src={categorie}&i=false&f=json&key={api_key}'
|
||||
search_url = url + 'api?{query}'\
|
||||
'&start={offset}'\
|
||||
'&length={number_of_results}'\
|
||||
'&l={language}'\
|
||||
'&src={categorie}'\
|
||||
'&i=false'\
|
||||
'&f=json'\
|
||||
'&key={api_key}' # noqa
|
||||
|
||||
search_category = {'general': 'web',
|
||||
'news': 'news'}
|
||||
'news': 'news'}
|
||||
|
||||
|
||||
# do search-request
|
||||
|
@ -80,8 +87,8 @@ def response(resp):
|
|||
# parse results
|
||||
for result in search_res['results']:
|
||||
if result['news']:
|
||||
# timestamp (how many milliseconds have passed between now and the beginning of 1970)
|
||||
publishedDate = datetime.datetime.fromtimestamp(result['date']/1000.0)
|
||||
# timestamp (milliseconds since 1970)
|
||||
publishedDate = datetime.datetime.fromtimestamp(result['date']/1000.0) # noqa
|
||||
|
||||
# append news result
|
||||
results.append({'url': result['url'],
|
||||
|
|
89
sources/searx/engines/flickr-noapi.py
Normal file
89
sources/searx/engines/flickr-noapi.py
Normal file
|
@ -0,0 +1,89 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Flickr (Images)
|
||||
#
|
||||
# @website https://www.flickr.com
|
||||
# @provide-api yes (https://secure.flickr.com/services/api/flickr.photos.search.html)
|
||||
#
|
||||
# @using-api no
|
||||
# @results HTML
|
||||
# @stable no
|
||||
# @parse url, title, thumbnail, img_src
|
||||
|
||||
from urllib import urlencode
|
||||
from json import loads
|
||||
import re
|
||||
|
||||
categories = ['images']
|
||||
|
||||
url = 'https://secure.flickr.com/'
|
||||
search_url = url+'search/?{query}&page={page}'
|
||||
photo_url = 'https://www.flickr.com/photos/{userid}/{photoid}'
|
||||
regex = re.compile(r"\"search-photos-models\",\"photos\":(.*}),\"totalItems\":", re.DOTALL)
|
||||
image_sizes = ('o', 'k', 'h', 'b', 'c', 'z', 'n', 'm', 't', 'q', 's')
|
||||
|
||||
paging = True
|
||||
|
||||
|
||||
def build_flickr_url(user_id, photo_id):
|
||||
return photo_url.format(userid=user_id, photoid=photo_id)
|
||||
|
||||
|
||||
def request(query, params):
|
||||
params['url'] = search_url.format(query=urlencode({'text': query}),
|
||||
page=params['pageno'])
|
||||
return params
|
||||
|
||||
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
matches = regex.search(resp.text)
|
||||
|
||||
if matches is None:
|
||||
return results
|
||||
|
||||
match = matches.group(1)
|
||||
search_results = loads(match)
|
||||
|
||||
if '_data' not in search_results:
|
||||
return []
|
||||
|
||||
photos = search_results['_data']
|
||||
|
||||
for photo in photos:
|
||||
|
||||
# In paged configuration, the first pages' photos are represented by a None object
|
||||
if photo is None:
|
||||
continue
|
||||
|
||||
img_src = None
|
||||
# From the biggest to the lowest format
|
||||
for image_size in image_sizes:
|
||||
if image_size in photo['sizes']:
|
||||
img_src = photo['sizes'][image_size]['displayUrl']
|
||||
break
|
||||
|
||||
if not img_src:
|
||||
continue
|
||||
|
||||
if 'id' not in photo['owner']:
|
||||
continue
|
||||
|
||||
url = build_flickr_url(photo['owner']['id'], photo['id'])
|
||||
|
||||
title = photo['title']
|
||||
|
||||
content = '<span class="photo-author">' + photo['owner']['username'] + '</span><br />'
|
||||
|
||||
if 'description' in photo:
|
||||
content = content + '<span class="description">' + photo['description'] + '</span>'
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
'img_src': img_src,
|
||||
'content': content,
|
||||
'template': 'images.html'})
|
||||
|
||||
return results
|
|
@ -1,54 +1,80 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
## Flickr (Images)
|
||||
#
|
||||
# @website https://www.flickr.com
|
||||
# @provide-api yes (https://secure.flickr.com/services/api/flickr.photos.search.html)
|
||||
#
|
||||
# @using-api yes
|
||||
# @results JSON
|
||||
# @stable yes
|
||||
# @parse url, title, thumbnail, img_src
|
||||
#More info on api-key : https://www.flickr.com/services/apps/create/
|
||||
|
||||
from urllib import urlencode
|
||||
#from json import loads
|
||||
from urlparse import urljoin
|
||||
from lxml import html
|
||||
from time import time
|
||||
from json import loads
|
||||
|
||||
categories = ['images']
|
||||
|
||||
url = 'https://secure.flickr.com/'
|
||||
search_url = url+'search/?{query}&page={page}'
|
||||
results_xpath = '//div[@class="view display-item-tile"]/figure/div'
|
||||
nb_per_page = 15
|
||||
paging = True
|
||||
api_key= None
|
||||
|
||||
|
||||
url = 'https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key={api_key}&{text}&sort=relevance&extras=description%2C+owner_name%2C+url_o%2C+url_z&per_page={nb_per_page}&format=json&nojsoncallback=1&page={page}'
|
||||
photo_url = 'https://www.flickr.com/photos/{userid}/{photoid}'
|
||||
|
||||
paging = True
|
||||
|
||||
def build_flickr_url(user_id, photo_id):
|
||||
return photo_url.format(userid=user_id,photoid=photo_id)
|
||||
|
||||
|
||||
def request(query, params):
|
||||
params['url'] = search_url.format(query=urlencode({'text': query}),
|
||||
page=params['pageno'])
|
||||
time_string = str(int(time())-3)
|
||||
params['cookies']['BX'] = '3oqjr6d9nmpgl&b=3&s=dh'
|
||||
params['cookies']['xb'] = '421409'
|
||||
params['cookies']['localization'] = 'en-us'
|
||||
params['cookies']['flrbp'] = time_string +\
|
||||
'-3a8cdb85a427a33efda421fbda347b2eaf765a54'
|
||||
params['cookies']['flrbs'] = time_string +\
|
||||
'-ed142ae8765ee62c9ec92a9513665e0ee1ba6776'
|
||||
params['cookies']['flrb'] = '9'
|
||||
params['url'] = url.format(text=urlencode({'text': query}),
|
||||
api_key=api_key,
|
||||
nb_per_page=nb_per_page,
|
||||
page=params['pageno'])
|
||||
return params
|
||||
|
||||
|
||||
def response(resp):
|
||||
results = []
|
||||
dom = html.fromstring(resp.text)
|
||||
for result in dom.xpath(results_xpath):
|
||||
img = result.xpath('.//img')
|
||||
|
||||
search_results = loads(resp.text)
|
||||
|
||||
if not img:
|
||||
# return empty array if there are no results
|
||||
if not 'photos' in search_results:
|
||||
return []
|
||||
|
||||
if not 'photo' in search_results['photos']:
|
||||
return []
|
||||
|
||||
photos = search_results['photos']['photo']
|
||||
|
||||
# parse results
|
||||
for photo in photos:
|
||||
if 'url_o' in photo:
|
||||
img_src = photo['url_o']
|
||||
elif 'url_z' in photo:
|
||||
img_src = photo['url_z']
|
||||
else:
|
||||
continue
|
||||
|
||||
img = img[0]
|
||||
img_src = 'https:'+img.attrib.get('src')
|
||||
url = build_flickr_url(photo['owner'], photo['id'])
|
||||
|
||||
if not img_src:
|
||||
continue
|
||||
|
||||
href = urljoin(url, result.xpath('.//a')[0].attrib.get('href'))
|
||||
title = img.attrib.get('alt', '')
|
||||
results.append({'url': href,
|
||||
title = photo['title']
|
||||
|
||||
content = '<span class="photo-author">'+ photo['ownername'] +'</span><br />'
|
||||
|
||||
content = content + '<span class="description">' + photo['description']['_content'] + '</span>'
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
'img_src': img_src,
|
||||
'content': content,
|
||||
'template': 'images.html'})
|
||||
|
||||
# return results
|
||||
return results
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
# @stable yes (but deprecated)
|
||||
# @parse url, title, img_src
|
||||
|
||||
from urllib import urlencode,unquote
|
||||
from urllib import urlencode, unquote
|
||||
from json import loads
|
||||
|
||||
# engine dependent config
|
||||
|
|
87
sources/searx/engines/kickass.py
Normal file
87
sources/searx/engines/kickass.py
Normal file
|
@ -0,0 +1,87 @@
|
|||
## Kickass Torrent (Videos, Music, Files)
|
||||
#
|
||||
# @website https://kickass.so
|
||||
# @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 urlparse import urljoin
|
||||
from cgi import escape
|
||||
from urllib import quote
|
||||
from lxml import html
|
||||
from operator import itemgetter
|
||||
|
||||
# engine dependent config
|
||||
categories = ['videos', 'music', 'files']
|
||||
paging = True
|
||||
|
||||
# search-url
|
||||
url = 'https://kickass.so/'
|
||||
search_url = url + 'search/{search_term}/{pageno}/'
|
||||
|
||||
# specific xpath variables
|
||||
magnet_xpath = './/a[@title="Torrent magnet link"]'
|
||||
#content_xpath = './/font[@class="detDesc"]//text()'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
params['url'] = search_url.format(search_term=quote(query),
|
||||
pageno=params['pageno'])
|
||||
|
||||
# FIX: SSLError: hostname 'kickass.so'
|
||||
# doesn't match either of '*.kickass.to', 'kickass.to'
|
||||
params['verify'] = False
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
dom = html.fromstring(resp.text)
|
||||
|
||||
search_res = dom.xpath('//table[@class="data"]//tr')
|
||||
|
||||
# return empty array if nothing is found
|
||||
if not search_res:
|
||||
return []
|
||||
|
||||
# parse results
|
||||
for result in search_res[1:]:
|
||||
link = result.xpath('.//a[@class="cellMainLink"]')[0]
|
||||
href = urljoin(url, link.attrib['href'])
|
||||
title = ' '.join(link.xpath('.//text()'))
|
||||
content = escape(html.tostring(result.xpath('.//span[@class="font11px lightgrey block"]')[0], method="text"))
|
||||
seed = result.xpath('.//td[contains(@class, "green")]/text()')[0]
|
||||
leech = result.xpath('.//td[contains(@class, "red")]/text()')[0]
|
||||
|
||||
# convert seed to int if possible
|
||||
if seed.isdigit():
|
||||
seed = int(seed)
|
||||
else:
|
||||
seed = 0
|
||||
|
||||
# convert leech to int if possible
|
||||
if leech.isdigit():
|
||||
leech = int(leech)
|
||||
else:
|
||||
leech = 0
|
||||
|
||||
magnetlink = result.xpath(magnet_xpath)[0].attrib['href']
|
||||
|
||||
# append result
|
||||
results.append({'url': href,
|
||||
'title': title,
|
||||
'content': content,
|
||||
'seed': seed,
|
||||
'leech': leech,
|
||||
'magnetlink': magnetlink,
|
||||
'template': 'torrent.html'})
|
||||
|
||||
# return results sorted by seeder
|
||||
return sorted(results, key=itemgetter('seed'), reverse=True)
|
|
@ -28,15 +28,17 @@ search_url = base_url + 'w/api.php?action=query'\
|
|||
'&srprop=timestamp'\
|
||||
'&format=json'\
|
||||
'&sroffset={offset}'\
|
||||
'&srlimit={limit}'
|
||||
'&srlimit={limit}' # noqa
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
offset = (params['pageno'] - 1) * number_of_results
|
||||
|
||||
string_args = dict(query=urlencode({'srsearch': query}),
|
||||
offset=offset,
|
||||
limit=number_of_results)
|
||||
offset=offset,
|
||||
limit=number_of_results)
|
||||
|
||||
format_strings = list(Formatter().parse(base_url))
|
||||
|
||||
if params['language'] == 'all':
|
||||
|
@ -67,7 +69,8 @@ def response(resp):
|
|||
|
||||
# parse results
|
||||
for result in search_results['query']['search']:
|
||||
url = base_url.format(language=resp.search_params['language']) + 'wiki/' + quote(result['title'].replace(' ', '_').encode('utf-8'))
|
||||
url = base_url.format(language=resp.search_params['language']) +\
|
||||
'wiki/' + quote(result['title'].replace(' ', '_').encode('utf-8'))
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
|
|
|
@ -9,20 +9,24 @@
|
|||
# @parse url, title
|
||||
|
||||
from json import loads
|
||||
from searx.utils import searx_useragent
|
||||
|
||||
# engine dependent config
|
||||
categories = ['map']
|
||||
paging = False
|
||||
|
||||
# search-url
|
||||
url = 'https://nominatim.openstreetmap.org/search/{query}?format=json&polygon_geojson=1&addressdetails=1'
|
||||
|
||||
base_url = 'https://nominatim.openstreetmap.org/'
|
||||
search_string = 'search/{query}?format=json&polygon_geojson=1&addressdetails=1'
|
||||
result_base_url = 'https://openstreetmap.org/{osm_type}/{osm_id}'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
params['url'] = url.format(query=query)
|
||||
params['url'] = base_url + search_string.format(query=query)
|
||||
|
||||
# using searx User-Agent
|
||||
params['headers']['User-Agent'] = searx_useragent()
|
||||
|
||||
return params
|
||||
|
||||
|
@ -68,8 +72,8 @@ def response(resp):
|
|||
address.update({'house_number': address_raw.get('house_number'),
|
||||
'road': address_raw.get('road'),
|
||||
'locality': address_raw.get('city',
|
||||
address_raw.get('town',
|
||||
address_raw.get('village'))),
|
||||
address_raw.get('town', # noqa
|
||||
address_raw.get('village'))), # noqa
|
||||
'postcode': address_raw.get('postcode'),
|
||||
'country': address_raw.get('country'),
|
||||
'country_code': address_raw.get('country_code')})
|
||||
|
|
132
sources/searx/engines/photon.py
Normal file
132
sources/searx/engines/photon.py
Normal file
|
@ -0,0 +1,132 @@
|
|||
## Photon (Map)
|
||||
#
|
||||
# @website https://photon.komoot.de
|
||||
# @provide-api yes (https://photon.komoot.de/)
|
||||
#
|
||||
# @using-api yes
|
||||
# @results JSON
|
||||
# @stable yes
|
||||
# @parse url, title
|
||||
|
||||
from urllib import urlencode
|
||||
from json import loads
|
||||
from searx.utils import searx_useragent
|
||||
|
||||
# engine dependent config
|
||||
categories = ['map']
|
||||
paging = False
|
||||
language_support = True
|
||||
number_of_results = 10
|
||||
|
||||
# search-url
|
||||
base_url = 'https://photon.komoot.de/'
|
||||
search_string = 'api/?{query}&limit={limit}'
|
||||
result_base_url = 'https://openstreetmap.org/{osm_type}/{osm_id}'
|
||||
|
||||
# list of supported languages
|
||||
allowed_languages = ['de', 'en', 'fr', 'it']
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
params['url'] = base_url +\
|
||||
search_string.format(query=urlencode({'q': query}),
|
||||
limit=number_of_results)
|
||||
|
||||
if params['language'] != 'all':
|
||||
language = params['language'].split('_')[0]
|
||||
if language in allowed_languages:
|
||||
params['url'] = params['url'] + "&lang=" + language
|
||||
|
||||
# using searx User-Agent
|
||||
params['headers']['User-Agent'] = searx_useragent()
|
||||
|
||||
# FIX: SSLError: SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
|
||||
params['verify'] = False
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
json = loads(resp.text)
|
||||
|
||||
# parse results
|
||||
for r in json.get('features', {}):
|
||||
|
||||
properties = r.get('properties')
|
||||
|
||||
if not properties:
|
||||
continue
|
||||
|
||||
# get title
|
||||
title = properties['name']
|
||||
|
||||
# get osm-type
|
||||
if properties.get('osm_type') == 'N':
|
||||
osm_type = 'node'
|
||||
elif properties.get('osm_type') == 'W':
|
||||
osm_type = 'way'
|
||||
elif properties.get('osm_type') == 'R':
|
||||
osm_type = 'relation'
|
||||
else:
|
||||
# continue if invalide osm-type
|
||||
continue
|
||||
|
||||
url = result_base_url.format(osm_type=osm_type,
|
||||
osm_id=properties.get('osm_id'))
|
||||
|
||||
osm = {'type': osm_type,
|
||||
'id': properties.get('osm_id')}
|
||||
|
||||
geojson = r.get('geometry')
|
||||
|
||||
if properties.get('extent'):
|
||||
boundingbox = [properties.get('extent')[3],
|
||||
properties.get('extent')[1],
|
||||
properties.get('extent')[0],
|
||||
properties.get('extent')[2]]
|
||||
else:
|
||||
# TODO: better boundingbox calculation
|
||||
boundingbox = [geojson['coordinates'][1],
|
||||
geojson['coordinates'][1],
|
||||
geojson['coordinates'][0],
|
||||
geojson['coordinates'][0]]
|
||||
|
||||
# address calculation
|
||||
address = {}
|
||||
|
||||
# get name
|
||||
if properties.get('osm_key') == 'amenity' or\
|
||||
properties.get('osm_key') == 'shop' or\
|
||||
properties.get('osm_key') == 'tourism' or\
|
||||
properties.get('osm_key') == 'leisure':
|
||||
address = {'name': properties.get('name')}
|
||||
|
||||
# add rest of adressdata, if something is already found
|
||||
if address.get('name'):
|
||||
address.update({'house_number': properties.get('housenumber'),
|
||||
'road': properties.get('street'),
|
||||
'locality': properties.get('city',
|
||||
properties.get('town', # noqa
|
||||
properties.get('village'))), # noqa
|
||||
'postcode': properties.get('postcode'),
|
||||
'country': properties.get('country')})
|
||||
else:
|
||||
address = None
|
||||
|
||||
# append result
|
||||
results.append({'template': 'map.html',
|
||||
'title': title,
|
||||
'content': '',
|
||||
'longitude': geojson['coordinates'][0],
|
||||
'latitude': geojson['coordinates'][1],
|
||||
'boundingbox': boundingbox,
|
||||
'geojson': geojson,
|
||||
'address': address,
|
||||
'osm': osm,
|
||||
'url': url})
|
||||
|
||||
# return results
|
||||
return results
|
65
sources/searx/engines/searchcode_code.py
Normal file
65
sources/searx/engines/searchcode_code.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
## Searchcode (It)
|
||||
#
|
||||
# @website https://searchcode.com/
|
||||
# @provide-api yes (https://searchcode.com/api/)
|
||||
#
|
||||
# @using-api yes
|
||||
# @results JSON
|
||||
# @stable yes
|
||||
# @parse url, title, content
|
||||
|
||||
from urllib import urlencode
|
||||
from json import loads
|
||||
import cgi
|
||||
import re
|
||||
|
||||
# engine dependent config
|
||||
categories = ['it']
|
||||
paging = True
|
||||
|
||||
# search-url
|
||||
url = 'https://searchcode.com/'
|
||||
search_url = url+'api/codesearch_I/?{query}&p={pageno}'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
params['url'] = search_url.format(query=urlencode({'q': query}),
|
||||
pageno=params['pageno']-1)
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
search_results = loads(resp.text)
|
||||
|
||||
# parse results
|
||||
for result in search_results['results']:
|
||||
href = result['url']
|
||||
title = "" + result['name'] + " - " + result['filename']
|
||||
content = result['repo'] + "<br />"
|
||||
|
||||
lines = dict()
|
||||
for line, code in result['lines'].items():
|
||||
lines[int(line)] = code
|
||||
|
||||
content = content + '<pre class="code-formatter"><table class="code">'
|
||||
for line, code in sorted(lines.items()):
|
||||
content = content + '<tr><td class="line-number" style="padding-right:5px;">'
|
||||
content = content + str(line) + '</td><td class="code-snippet">'
|
||||
# Replace every two spaces with ' &nbps;' to keep formatting while allowing the browser to break the line if necessary
|
||||
content = content + cgi.escape(code).replace('\t', ' ').replace(' ', ' ').replace(' ', ' ')
|
||||
content = content + "</td></tr>"
|
||||
|
||||
content = content + "</table></pre>"
|
||||
|
||||
# append result
|
||||
results.append({'url': href,
|
||||
'title': title,
|
||||
'content': content})
|
||||
|
||||
# return results
|
||||
return results
|
49
sources/searx/engines/searchcode_doc.py
Normal file
49
sources/searx/engines/searchcode_doc.py
Normal file
|
@ -0,0 +1,49 @@
|
|||
## Searchcode (It)
|
||||
#
|
||||
# @website https://searchcode.com/
|
||||
# @provide-api yes (https://searchcode.com/api/)
|
||||
#
|
||||
# @using-api yes
|
||||
# @results JSON
|
||||
# @stable yes
|
||||
# @parse url, title, content
|
||||
|
||||
from urllib import urlencode
|
||||
from json import loads
|
||||
|
||||
# engine dependent config
|
||||
categories = ['it']
|
||||
paging = True
|
||||
|
||||
# search-url
|
||||
url = 'https://searchcode.com/'
|
||||
search_url = url+'api/search_IV/?{query}&p={pageno}'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
params['url'] = search_url.format(query=urlencode({'q': query}),
|
||||
pageno=params['pageno']-1)
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
search_results = loads(resp.text)
|
||||
|
||||
# parse results
|
||||
for result in search_results['results']:
|
||||
href = result['url']
|
||||
title = "[" + result['type'] + "] " + result['namespace'] + " " + result['name']
|
||||
content = '<span class="highlight">[' + result['type'] + "] " + result['name'] + " " + result['synopsis'] + "</span><br />" + result['description']
|
||||
|
||||
# append result
|
||||
results.append({'url': href,
|
||||
'title': title,
|
||||
'content': content})
|
||||
|
||||
# return results
|
||||
return results
|
|
@ -20,7 +20,12 @@ guest_client_id = 'b45b1aa10f1ac2941910a7f0d10f8e28'
|
|||
|
||||
# search-url
|
||||
url = 'https://api.soundcloud.com/'
|
||||
search_url = url + 'search?{query}&facet=model&limit=20&offset={offset}&linked_partitioning=1&client_id={client_id}'
|
||||
search_url = url + 'search?{query}'\
|
||||
'&facet=model'\
|
||||
'&limit=20'\
|
||||
'&offset={offset}'\
|
||||
'&linked_partitioning=1'\
|
||||
'&client_id={client_id}' # noqa
|
||||
|
||||
|
||||
# do search-request
|
||||
|
|
74
sources/searx/engines/subtitleseeker.py
Normal file
74
sources/searx/engines/subtitleseeker.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
## Subtitleseeker (Video)
|
||||
#
|
||||
# @website http://www.subtitleseeker.com
|
||||
# @provide-api no
|
||||
#
|
||||
# @using-api no
|
||||
# @results HTML
|
||||
# @stable no (HTML can change)
|
||||
# @parse url, title, content
|
||||
|
||||
from cgi import escape
|
||||
from urllib import quote_plus
|
||||
from lxml import html
|
||||
from searx.languages import language_codes
|
||||
|
||||
# engine dependent config
|
||||
categories = ['videos']
|
||||
paging = True
|
||||
language = ""
|
||||
|
||||
# search-url
|
||||
url = 'http://www.subtitleseeker.com/'
|
||||
search_url = url+'search/TITLES/{query}&p={pageno}'
|
||||
|
||||
# specific xpath variables
|
||||
results_xpath = '//div[@class="boxRows"]'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
params['url'] = search_url.format(query=quote_plus(query),
|
||||
pageno=params['pageno'])
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
dom = html.fromstring(resp.text)
|
||||
|
||||
search_lang = ""
|
||||
|
||||
if resp.search_params['language'] != 'all':
|
||||
search_lang = [lc[1]
|
||||
for lc in language_codes
|
||||
if lc[0][:2] == resp.search_params['language']][0]
|
||||
|
||||
# parse results
|
||||
for result in dom.xpath(results_xpath):
|
||||
link = result.xpath(".//a")[0]
|
||||
href = link.attrib.get('href')
|
||||
|
||||
if language is not "":
|
||||
href = href + language + '/'
|
||||
elif search_lang:
|
||||
href = href + search_lang + '/'
|
||||
|
||||
title = escape(link.xpath(".//text()")[0])
|
||||
|
||||
content = result.xpath('.//div[contains(@class,"red")]//text()')[0]
|
||||
content = content + " - "
|
||||
content = content + html.tostring(result.xpath('.//div[contains(@class,"grey-web")]')[0], method='text')
|
||||
|
||||
if result.xpath(".//span") != []:
|
||||
content = content + " - (" + result.xpath(".//span//text()")[0].strip() + ")"
|
||||
|
||||
# append result
|
||||
results.append({'url': href,
|
||||
'title': title,
|
||||
'content': escape(content)})
|
||||
|
||||
# return results
|
||||
return results
|
|
@ -24,7 +24,11 @@ number_of_results = 5
|
|||
|
||||
# search-url
|
||||
base_url = 'http://localhost:8090'
|
||||
search_url = '/yacysearch.json?{query}&startRecord={offset}&maximumRecords={limit}&contentdom={search_type}&resource=global'
|
||||
search_url = '/yacysearch.json?{query}'\
|
||||
'&startRecord={offset}'\
|
||||
'&maximumRecords={limit}'\
|
||||
'&contentdom={search_type}'\
|
||||
'&resource=global' # noqa
|
||||
|
||||
# yacy specific type-definitions
|
||||
search_types = {'general': 'text',
|
||||
|
@ -39,10 +43,11 @@ def request(query, params):
|
|||
offset = (params['pageno'] - 1) * number_of_results
|
||||
search_type = search_types.get(params['category'], '0')
|
||||
|
||||
params['url'] = base_url + search_url.format(query=urlencode({'query': query}),
|
||||
offset=offset,
|
||||
limit=number_of_results,
|
||||
search_type=search_type)
|
||||
params['url'] = base_url +\
|
||||
search_url.format(query=urlencode({'query': query}),
|
||||
offset=offset,
|
||||
limit=number_of_results,
|
||||
search_type=search_type)
|
||||
|
||||
# add language tag if specified
|
||||
if params['language'] != 'all':
|
||||
|
@ -70,19 +75,19 @@ def response(resp):
|
|||
|
||||
# append result
|
||||
results.append({'url': result['link'],
|
||||
'title': result['title'],
|
||||
'content': result['description'],
|
||||
'publishedDate': publishedDate})
|
||||
'title': result['title'],
|
||||
'content': result['description'],
|
||||
'publishedDate': publishedDate})
|
||||
|
||||
elif resp.search_params['category'] == 'images':
|
||||
# parse image results
|
||||
for result in search_results:
|
||||
# append result
|
||||
results.append({'url': result['url'],
|
||||
'title': result['title'],
|
||||
'content': '',
|
||||
'img_src': result['image'],
|
||||
'template': 'images.html'})
|
||||
'title': result['title'],
|
||||
'content': '',
|
||||
'img_src': result['image'],
|
||||
'template': 'images.html'})
|
||||
|
||||
#TODO parse video, audio and file results
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ paging = True
|
|||
language_support = True
|
||||
|
||||
# search-url
|
||||
search_url = 'https://search.yahoo.com/search?{query}&b={offset}&fl=1&vl=lang_{lang}'
|
||||
base_url = 'https://search.yahoo.com/'
|
||||
search_url = 'search?{query}&b={offset}&fl=1&vl=lang_{lang}'
|
||||
|
||||
# specific xpath variables
|
||||
results_xpath = '//div[@class="res"]'
|
||||
|
@ -57,9 +58,9 @@ def request(query, params):
|
|||
else:
|
||||
language = params['language'].split('_')[0]
|
||||
|
||||
params['url'] = search_url.format(offset=offset,
|
||||
query=urlencode({'p': query}),
|
||||
lang=language)
|
||||
params['url'] = base_url + search_url.format(offset=offset,
|
||||
query=urlencode({'p': query}),
|
||||
lang=language)
|
||||
|
||||
# TODO required?
|
||||
params['cookies']['sB'] = 'fl=1&vl=lang_{lang}&sh=1&rw=new&v=1'\
|
||||
|
|
|
@ -16,6 +16,7 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
|
|||
'''
|
||||
|
||||
import re
|
||||
from urlparse import urlparse
|
||||
from lxml import etree
|
||||
from os import listdir
|
||||
from os.path import isfile, isdir, join
|
||||
|
@ -86,15 +87,23 @@ def load_single_https_ruleset(filepath):
|
|||
|
||||
# TODO hack, which convert a javascript regex group
|
||||
# into a valid python regex group
|
||||
rule_from = ruleset.attrib.get('from').replace('$', '\\')
|
||||
rule_to = ruleset.attrib.get('to').replace('$', '\\')
|
||||
rule_from = ruleset.attrib['from'].replace('$', '\\')
|
||||
if rule_from.endswith('\\'):
|
||||
rule_from = rule_from[:-1]+'$'
|
||||
rule_to = ruleset.attrib['to'].replace('$', '\\')
|
||||
if rule_to.endswith('\\'):
|
||||
rule_to = rule_to[:-1]+'$'
|
||||
|
||||
# TODO, not working yet because of the hack above,
|
||||
# currently doing that in webapp.py
|
||||
# rule_from_rgx = re.compile(rule_from, re.I)
|
||||
|
||||
# append rule
|
||||
rules.append((rule_from, rule_to))
|
||||
try:
|
||||
rules.append((re.compile(rule_from, re.I | re.U), rule_to))
|
||||
except:
|
||||
# TODO log regex error
|
||||
continue
|
||||
|
||||
# this child define an exclusion
|
||||
elif ruleset.tag == 'exclusion':
|
||||
|
@ -143,3 +152,56 @@ def load_https_rules(rules_path):
|
|||
https_rules.append(ruleset)
|
||||
|
||||
print(' * {n} https-rules loaded'.format(n=len(https_rules)))
|
||||
|
||||
|
||||
|
||||
def https_url_rewrite(result):
|
||||
skip_https_rewrite = False
|
||||
# check if HTTPS rewrite is possible
|
||||
for target, rules, exclusions in https_rules:
|
||||
|
||||
# check if target regex match with url
|
||||
if target.match(result['parsed_url'].netloc):
|
||||
# process exclusions
|
||||
for exclusion in exclusions:
|
||||
# check if exclusion match with url
|
||||
if exclusion.match(result['url']):
|
||||
skip_https_rewrite = True
|
||||
break
|
||||
|
||||
# skip https rewrite if required
|
||||
if skip_https_rewrite:
|
||||
break
|
||||
|
||||
# process rules
|
||||
for rule in rules:
|
||||
try:
|
||||
new_result_url = rule[0].sub(rule[1], result['url'])
|
||||
except:
|
||||
break
|
||||
|
||||
# parse new url
|
||||
new_parsed_url = urlparse(new_result_url)
|
||||
|
||||
# continiue if nothing was rewritten
|
||||
if result['url'] == new_result_url:
|
||||
continue
|
||||
|
||||
# get domainname from result
|
||||
# TODO, does only work correct with TLD's like
|
||||
# asdf.com, not for asdf.com.de
|
||||
# TODO, using publicsuffix instead of this rewrite rule
|
||||
old_result_domainname = '.'.join(
|
||||
result['parsed_url'].hostname.split('.')[-2:])
|
||||
new_result_domainname = '.'.join(
|
||||
new_parsed_url.hostname.split('.')[-2:])
|
||||
|
||||
# check if rewritten hostname is the same,
|
||||
# to protect against wrong or malicious rewrite rules
|
||||
if old_result_domainname == new_result_domainname:
|
||||
# set new url
|
||||
result['url'] = new_result_url
|
||||
|
||||
# target has matched, do not search over the other rules
|
||||
break
|
||||
return result
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
<rule from="^http://([aiw]\d|api|wis)\.sndcdn\.com/"
|
||||
to="https://$1.sndcdn.com/" />
|
||||
|
||||
<rule from="^http://((?:api|backstage|blog|connect|developers|ec-media|eventlogger|help-assets|media|visuals|w|www)\.)?soundcloud\.com/"
|
||||
<rule from="^http://((?:api|backstage|blog|connect|developers|ec-media|eventlogger|help-assets|media|visuals|w|www)\.|)soundcloud\.com/"
|
||||
to="https://$1soundcloud.com/" />
|
||||
|
||||
<rule from="^https?://scbackstage\.wpengine\.netdna-cdn\.com/"
|
||||
|
|
|
@ -19,8 +19,9 @@ import requests as requests_lib
|
|||
import threading
|
||||
import re
|
||||
from itertools import izip_longest, chain
|
||||
from datetime import datetime
|
||||
from operator import itemgetter
|
||||
from Queue import Queue
|
||||
from time import time
|
||||
from urlparse import urlparse, unquote
|
||||
from searx.engines import (
|
||||
categories, engines
|
||||
|
@ -33,82 +34,74 @@ from searx.query import Query
|
|||
number_of_searches = 0
|
||||
|
||||
|
||||
def search_request_wrapper(fn, url, engine_name, **kwargs):
|
||||
try:
|
||||
return fn(url, **kwargs)
|
||||
except Exception, e:
|
||||
# increase errors stats
|
||||
engines[engine_name].stats['errors'] += 1
|
||||
|
||||
# print engine name and specific error message
|
||||
print('[E] Error with engine "{0}":\n\t{1}'.format(
|
||||
engine_name, str(e)))
|
||||
return
|
||||
|
||||
|
||||
def threaded_requests(requests):
|
||||
for fn, url, request_args in requests:
|
||||
timeout_limit = max(r[2]['timeout'] for r in requests)
|
||||
search_start = time()
|
||||
for fn, url, request_args, engine_name in requests:
|
||||
request_args['timeout'] = timeout_limit
|
||||
th = threading.Thread(
|
||||
target=fn,
|
||||
args=(url,),
|
||||
target=search_request_wrapper,
|
||||
args=(fn, url, engine_name),
|
||||
kwargs=request_args,
|
||||
name='search_request',
|
||||
)
|
||||
th._engine_name = engine_name
|
||||
th.start()
|
||||
|
||||
for th in threading.enumerate():
|
||||
if th.name == 'search_request':
|
||||
th.join()
|
||||
remaining_time = max(0.0, timeout_limit - (time() - search_start))
|
||||
th.join(remaining_time)
|
||||
if th.isAlive():
|
||||
print('engine timeout: {0}'.format(th._engine_name))
|
||||
|
||||
|
||||
|
||||
# get default reqest parameter
|
||||
def default_request_params():
|
||||
return {
|
||||
'method': 'GET', 'headers': {}, 'data': {}, 'url': '', 'cookies': {}}
|
||||
'method': 'GET', 'headers': {}, 'data': {}, 'url': '', 'cookies': {}, 'verify': True}
|
||||
|
||||
|
||||
# create a callback wrapper for the search engine results
|
||||
def make_callback(engine_name,
|
||||
results,
|
||||
suggestions,
|
||||
answers,
|
||||
infoboxes,
|
||||
callback,
|
||||
params):
|
||||
def make_callback(engine_name, results_queue, callback, params):
|
||||
|
||||
# creating a callback wrapper for the search engine results
|
||||
def process_callback(response, **kwargs):
|
||||
cb_res = []
|
||||
response.search_params = params
|
||||
|
||||
# callback
|
||||
try:
|
||||
search_results = callback(response)
|
||||
except Exception, e:
|
||||
# increase errors stats
|
||||
timeout_overhead = 0.2 # seconds
|
||||
search_duration = time() - params['started']
|
||||
timeout_limit = engines[engine_name].timeout + timeout_overhead
|
||||
if search_duration > timeout_limit:
|
||||
engines[engine_name].stats['page_load_time'] += timeout_limit
|
||||
engines[engine_name].stats['errors'] += 1
|
||||
results[engine_name] = cb_res
|
||||
|
||||
# print engine name and specific error message
|
||||
print '[E] Error with engine "{0}":\n\t{1}'.format(
|
||||
engine_name, str(e))
|
||||
return
|
||||
|
||||
# callback
|
||||
search_results = callback(response)
|
||||
|
||||
# add results
|
||||
for result in search_results:
|
||||
result['engine'] = engine_name
|
||||
|
||||
# if it is a suggestion, add it to list of suggestions
|
||||
if 'suggestion' in result:
|
||||
# TODO type checks
|
||||
suggestions.add(result['suggestion'])
|
||||
continue
|
||||
|
||||
# if it is an answer, add it to list of answers
|
||||
if 'answer' in result:
|
||||
answers.add(result['answer'])
|
||||
continue
|
||||
|
||||
# if it is an infobox, add it to list of infoboxes
|
||||
if 'infobox' in result:
|
||||
infoboxes.append(result)
|
||||
continue
|
||||
|
||||
# append result
|
||||
cb_res.append(result)
|
||||
|
||||
results[engine_name] = cb_res
|
||||
results_queue.put_nowait((engine_name, search_results))
|
||||
|
||||
# update stats with current page-load-time
|
||||
engines[engine_name].stats['page_load_time'] += \
|
||||
(datetime.now() - params['started']).total_seconds()
|
||||
engines[engine_name].stats['page_load_time'] += search_duration
|
||||
|
||||
return process_callback
|
||||
|
||||
|
@ -420,6 +413,7 @@ class Search(object):
|
|||
|
||||
# init vars
|
||||
requests = []
|
||||
results_queue = Queue()
|
||||
results = {}
|
||||
suggestions = set()
|
||||
answers = set()
|
||||
|
@ -452,14 +446,13 @@ class Search(object):
|
|||
request_params = default_request_params()
|
||||
request_params['headers']['User-Agent'] = user_agent
|
||||
request_params['category'] = selected_engine['category']
|
||||
request_params['started'] = datetime.now()
|
||||
request_params['started'] = time()
|
||||
request_params['pageno'] = self.pageno
|
||||
request_params['language'] = self.lang
|
||||
|
||||
# update request parameters dependent on
|
||||
# search-engine (contained in engines folder)
|
||||
request_params = engine.request(self.query.encode('utf-8'),
|
||||
request_params)
|
||||
engine.request(self.query.encode('utf-8'), request_params)
|
||||
|
||||
if request_params['url'] is None:
|
||||
# TODO add support of offline engines
|
||||
|
@ -468,13 +461,9 @@ class Search(object):
|
|||
# create a callback wrapper for the search engine results
|
||||
callback = make_callback(
|
||||
selected_engine['name'],
|
||||
results,
|
||||
suggestions,
|
||||
answers,
|
||||
infoboxes,
|
||||
results_queue,
|
||||
engine.response,
|
||||
request_params
|
||||
)
|
||||
request_params)
|
||||
|
||||
# create dictionary which contain all
|
||||
# informations about the request
|
||||
|
@ -482,7 +471,8 @@ class Search(object):
|
|||
headers=request_params['headers'],
|
||||
hooks=dict(response=callback),
|
||||
cookies=request_params['cookies'],
|
||||
timeout=engine.timeout
|
||||
timeout=engine.timeout,
|
||||
verify=request_params['verify']
|
||||
)
|
||||
|
||||
# specific type of request (GET or POST)
|
||||
|
@ -497,11 +487,34 @@ class Search(object):
|
|||
continue
|
||||
|
||||
# append request to list
|
||||
requests.append((req, request_params['url'], request_args))
|
||||
requests.append((req, request_params['url'], request_args, selected_engine['name']))
|
||||
|
||||
if not requests:
|
||||
return results, suggestions, answers, infoboxes
|
||||
# send all search-request
|
||||
threaded_requests(requests)
|
||||
|
||||
|
||||
while not results_queue.empty():
|
||||
engine_name, engine_results = results_queue.get_nowait()
|
||||
|
||||
# TODO type checks
|
||||
[suggestions.add(x['suggestion'])
|
||||
for x in list(engine_results)
|
||||
if 'suggestion' in x
|
||||
and engine_results.remove(x) is None]
|
||||
|
||||
[answers.add(x['answer'])
|
||||
for x in list(engine_results)
|
||||
if 'answer' in x
|
||||
and engine_results.remove(x) is None]
|
||||
|
||||
infoboxes.extend(x for x in list(engine_results)
|
||||
if 'infobox' in x
|
||||
and engine_results.remove(x) is None)
|
||||
|
||||
results[engine_name] = engine_results
|
||||
|
||||
# update engine-specific stats
|
||||
for engine_name, engine_results in results.items():
|
||||
engines[engine_name].stats['search_count'] += 1
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
server:
|
||||
port : 8888
|
||||
secret_key : "ultrasecretkey" # change this!
|
||||
debug : True # Debug mode, only for development
|
||||
debug : False # Debug mode, only for development
|
||||
request_timeout : 2.0 # seconds
|
||||
base_url : False # Set custom base_url. Possible values: False or "https://your.custom.host/location/"
|
||||
themes_path : "" # Custom ui themes path
|
||||
|
@ -64,12 +64,20 @@ engines:
|
|||
# engine : filecrop
|
||||
# categories : files
|
||||
# shortcut : fc
|
||||
|
||||
- name : 500px
|
||||
engine : 500px
|
||||
shortcut : px
|
||||
|
||||
- name : flickr
|
||||
engine : flickr
|
||||
categories : images
|
||||
shortcut : fl
|
||||
timeout: 3.0
|
||||
# You can use the engine using the official stable API, but you need an API key
|
||||
# See : https://www.flickr.com/services/apps/create/
|
||||
# engine : flickr
|
||||
# api_key: 'apikey' # required!
|
||||
# Or you can use the html non-stable engine, activated by default
|
||||
engine : flickr-noapi
|
||||
|
||||
- name : general-file
|
||||
engine : generalfile
|
||||
|
@ -95,10 +103,18 @@ engines:
|
|||
engine : openstreetmap
|
||||
shortcut : osm
|
||||
|
||||
- name : photon
|
||||
engine : photon
|
||||
shortcut : ph
|
||||
|
||||
# - name : piratebay
|
||||
# engine : piratebay
|
||||
# shortcut : tpb
|
||||
|
||||
- name : kickass
|
||||
engine : kickass
|
||||
shortcut : ka
|
||||
|
||||
- name : soundcloud
|
||||
engine : soundcloud
|
||||
shortcut : sc
|
||||
|
@ -106,6 +122,21 @@ engines:
|
|||
- name : stackoverflow
|
||||
engine : stackoverflow
|
||||
shortcut : st
|
||||
|
||||
- name : searchcode doc
|
||||
engine : searchcode_doc
|
||||
shortcut : scd
|
||||
|
||||
- name : searchcode code
|
||||
engine : searchcode_code
|
||||
shortcut : scc
|
||||
|
||||
- name : subtitleseeker
|
||||
engine : subtitleseeker
|
||||
shortcut : ss
|
||||
# The language is an option. You can put any language written in english
|
||||
# Examples : English, French, German, Hungarian, Chinese...
|
||||
# language : English
|
||||
|
||||
- name : startpage
|
||||
engine : startpage
|
||||
|
|
BIN
sources/searx/static/courgette/img/icon_kickass.ico
Normal file
BIN
sources/searx/static/courgette/img/icon_kickass.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
sources/searx/static/default/img/icon_kickass.ico
Normal file
BIN
sources/searx/static/default/img/icon_kickass.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
sources/searx/static/oscar/img/icons/kickass.png
Normal file
BIN
sources/searx/static/oscar/img/icons/kickass.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
4
sources/searx/static/oscar/js/searx.min.js
vendored
4
sources/searx/static/oscar/js/searx.min.js
vendored
|
@ -1,2 +1,2 @@
|
|||
/*! oscar/searx.min.js | 30-11-2014 | https://github.com/asciimoo/searx */
|
||||
requirejs.config({baseUrl:"/static/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&&(new_html=$(this).hasClass("collapsed")?$(this).html().replace(a,b):$(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&&(new_html=$(this).hasClass("btn-default")?$(this).html().replace(b,c):$(this).html().replace(c,b),$(this).html(new_html)),$(this).toggleClass(a),$(this).toggleClass("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(){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/oscar/img/map";{var a=L.map(b),h="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",i='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors',j=new L.TileLayer(h,{minZoom:1,maxZoom:19,attribution:i}),k="http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpg",l='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors | Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png">',m=new L.TileLayer(k,{minZoom:1,maxZoom:18,subdomains:"1234",attribution:l}),n="http://otile{s}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg",o='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors | Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="https://developer.mapquest.com/content/osm/mq_logo.png"> | Portions Courtesy NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency';new L.TileLayer(n,{minZoom:1,maxZoom:11,subdomains:"1234",attribution:o})}map_bounds?setTimeout(function(){a.fitBounds(map_bounds,{maxZoom:17})},0):c&&d&&(e?a.setView(new L.LatLng(d,c),e):a.setView(new L.LatLng(d,c),8)),a.addLayer(m);var p={"OSM Mapnik":j,MapQuest:m};L.control.layers(p).addTo(a),g&&L.geoJson(g).addTo(a)}),$(this).off(a)})});
|
||||
/*! oscar/searx.min.js | 19-12-2014 | https://github.com/asciimoo/searx */
|
||||
requirejs.config({baseUrl:"./static/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&&(new_html=$(this).hasClass("collapsed")?$(this).html().replace(a,b):$(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&&(new_html=$(this).hasClass("btn-default")?$(this).html().replace(b,c):$(this).html().replace(c,b),$(this).html(new_html)),$(this).toggleClass(a),$(this).toggleClass("btn-default")}),$(".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(){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/oscar/img/map";{var a=L.map(b),h="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",i='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors',j=new L.TileLayer(h,{minZoom:1,maxZoom:19,attribution:i}),k="http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpg",l='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors | Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png">',m=new L.TileLayer(k,{minZoom:1,maxZoom:18,subdomains:"1234",attribution:l}),n="http://otile{s}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg",o='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors | Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="https://developer.mapquest.com/content/osm/mq_logo.png"> | Portions Courtesy NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency';new L.TileLayer(n,{minZoom:1,maxZoom:11,subdomains:"1234",attribution:o})}map_bounds?setTimeout(function(){a.fitBounds(map_bounds,{maxZoom:17})},0):c&&d&&(e?a.setView(new L.LatLng(d,c),e):a.setView(new L.LatLng(d,c),8)),a.addLayer(m);var p={"OSM Mapnik":j,MapQuest:m};L.control.layers(p).addTo(a),g&&L.geoJson(g).addTo(a)}),$(this).off(a)})});
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
|
||||
requirejs.config({
|
||||
baseUrl: '/static/oscar/js',
|
||||
baseUrl: './static/oscar/js',
|
||||
paths: {
|
||||
app: '../app'
|
||||
}
|
||||
|
|
|
@ -63,4 +63,25 @@ $(document).ready(function(){
|
|||
$(this).toggleClass(btnClass);
|
||||
$(this).toggleClass('btn-default');
|
||||
});
|
||||
|
||||
/**
|
||||
* 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');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -116,7 +116,7 @@ $(document).ready(function(){
|
|||
|
||||
// TODO hack
|
||||
// change default imagePath
|
||||
L.Icon.Default.imagePath = "/static/oscar/img/map";
|
||||
L.Icon.Default.imagePath = "./static/oscar/img/map";
|
||||
|
||||
// init map
|
||||
var map = L.map(leaflet_target);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="result {{ result.class }}">
|
||||
|
||||
{% if result['favicon'] %}
|
||||
<img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result['favicon']}}.ico" />
|
||||
{% if "icon_"~result.engine~".ico" in favicons %}
|
||||
<img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result.engine}}.ico" alt="{{result.engine}}" />
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="image_result">
|
||||
<p>
|
||||
<a href="{{ result.img_src }}"><img src="{{ result.img_src }}" title={{ result.title }}/></a>
|
||||
<a href="{{ result.img_src }}"><img src="{{ result.img_src }}" title="{{ result.title|striptags }}" alt="{{ result.title|striptags }}"/></a>
|
||||
<span class="url"><a href="{{ result.url }}" class="small_font">original context</a></span>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="result {{ result.class }}">
|
||||
|
||||
{% if result['favicon'] %}
|
||||
<img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result['favicon']}}.ico" />
|
||||
{% if "icon_"~result.engine~".ico" in favicons %}
|
||||
<img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result.engine}}.ico" alt="{{result.engine}}" />
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
<div class="result">
|
||||
{% if result['favicon'] %}
|
||||
<img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result['favicon']}}.ico" />
|
||||
{% if "icon_"~result.engine~".ico" in favicons %}
|
||||
<img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result.engine}}.ico" alt="{{result.engine}}" />
|
||||
{% endif %}
|
||||
|
||||
<p>
|
||||
<h3 class="result_title"><a href="{{ result.url }}">{{ result.title|safe }}</a></h3>
|
||||
{% if result.publishedDate %}<p class="published_date">{{ result.publishedDate }}</p>{% endif %}
|
||||
<a href="{{ result.url }}"><img width="400px" src="{{ result.thumbnail }}" title={{ result.title }} alt=" {{ result.title }}"/></a>
|
||||
<a href="{{ result.url }}"><img width="400" src="{{ result.thumbnail }}" title="{{ result.title|striptags }}" alt="{{ result.title|striptags }}"/></a>
|
||||
<p class="url">{{ result.url }}</p>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<div id="search_url">
|
||||
{{ _('Search URL') }}:
|
||||
<input type="text" value="{{ base_url }}?q={{ q|urlencode }}&pageno={{ pageno }}{% if selected_categories %}&category_{{ selected_categories|join("&category_") }}{% endif %}" readonly="" />
|
||||
<input type="text" value="{{ base_url }}?q={{ q|urlencode }}&pageno={{ pageno }}{% if selected_categories %}&category_{{ selected_categories|join("&category_")|replace(' ','+') }}{% endif %}" readonly />
|
||||
</div>
|
||||
<div id="apis">
|
||||
{{ _('Download results') }}
|
||||
|
@ -43,9 +43,9 @@
|
|||
|
||||
{% for result in results %}
|
||||
{% if result['template'] %}
|
||||
{% include 'default/result_templates/'+result['template'] %}
|
||||
{% include 'courgette/result_templates/'+result['template'] %}
|
||||
{% else %}
|
||||
{% include 'default/result_templates/default.html' %}
|
||||
{% include 'courgette/result_templates/default.html' %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="infobox">
|
||||
<h2>{{ infobox.infobox }}</h2>
|
||||
{% if infobox.img_src %}<img src="{{ infobox.img_src }}" />{% endif %}
|
||||
{% if infobox.img_src %}<img src="{{ infobox.img_src }}" title="{{ infobox.infobox|striptags }}" alt="{{ infobox.infobox|striptags }}" />{% endif %}
|
||||
<p>{{ infobox.entity }}</p>
|
||||
<p>{{ infobox.content | safe }}</p>
|
||||
{% if infobox.attributes %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="result {{ result.class }}">
|
||||
<h3 class="result_title"> {% if result['favicon'] %}<img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result['favicon']}}.ico" />{% endif %}<a href="{{ result.url }}">{{ result.title|safe }}</a></h3>
|
||||
<h3 class="result_title">{% if "icon_"~result.engine~".ico" in favicons %}<img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result.engine}}.ico" alt="{{result.engine}}" />{% endif %}<a href="{{ result.url }}">{{ result.title|safe }}</a></h3>
|
||||
<p class="url">{{ result.pretty_url }} <a class="cache_link" href="https://web.archive.org/web/{{ result.url }}">cached</a></p>
|
||||
{% if result.publishedDate %}<p class="published_date">{{ result.publishedDate }}</p>{% endif %}
|
||||
<p class="content">{% if result.img_src %}<img src="{{ result.img_src }}" class="image" />{% endif %}{% if result.content %}{{ result.content|safe }}<br class="last"/>{% endif %}</p>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="image_result">
|
||||
<p>
|
||||
<a href="{{ result.img_src }}"><img src="{{ result.img_src }}" title="{{ result.title }}"/></a>
|
||||
<a href="{{ result.img_src }}"><img src="{{ result.img_src }}" title="{{ result.title|striptags }}" alt="{{ result.title|striptags }}" /></a>
|
||||
<span class="url"><a href="{{ result.url }}" class="small_font">original context</a></span>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="result {{ result.class }}">
|
||||
|
||||
{% if result['favicon'] %}
|
||||
<img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result['favicon']}}.ico" />
|
||||
{% if "icon_"~result.engine~".ico" in favicons %}
|
||||
<img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result.engine}}.ico" alt="{{result.engine}}" />
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<div class="result torrent_result">
|
||||
<h3 class="result_title"><a href="{{ result.url }}">{{ result.title|safe }}</a></h3>
|
||||
{% if result.content %}<p class="content">{{ result.content|safe }}</p>{% endif %}
|
||||
<p class="stats">Seed: {{ result.seed }}, Leech: {{ result.leech }}</p>
|
||||
<p><a href="{{ result.magnetlink }}" class="magnetlink">magnet link</a></p>
|
||||
<p class="url">{{ result.pretty_url }}</p>
|
||||
{% if result.content %}<p class="content">{{ result.content|safe }}</p>{% endif %}
|
||||
<p><a href="{{ result.magnetlink }}" class="magnetlink">magnet link</a> - <span class="stats">Seed: {{ result.seed }}, Leech: {{ result.leech }}</span></p>
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
<div class="result">
|
||||
<p>
|
||||
<h3 class="result_title"> {% if result['favicon'] %}<img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result['favicon']}}.ico" />{% endif %}<a href="{{ result.url }}">{{ result.title|safe }}</a></h3>
|
||||
<h3 class="result_title">{% if "icon_"~result.engine~".ico" in favicons %}<img width="14" height="14" class="favicon" src="static/{{theme}}/img/icon_{{result.engine}}.ico" alt="{{result.engine}}" />{% endif %}<a href="{{ result.url }}">{{ result.title|safe }}</a></h3>
|
||||
{% if result.publishedDate %}<p class="published_date">{{ result.publishedDate }}</p>{% endif %}
|
||||
<a href="{{ result.url }}"><img class="thumbnail" src="{{ result.thumbnail }}" title={{ result.title }} alt=" {{ result.title }}"/></a>
|
||||
<a href="{{ result.url }}"><img class="thumbnail" src="{{ result.thumbnail }}" title="{{ result.title|striptags }}" alt="{{ result.title|striptags }}"/></a>
|
||||
<p class="url">{{ result.url }}</p>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
<div id="search_url">
|
||||
{{ _('Search URL') }}:
|
||||
<input type="text" value="{{ base_url }}?q={{ q|urlencode }}&pageno={{ pageno }}{% if selected_categories %}&category_{{ selected_categories|join("&category_") }}{% endif %}" readonly="" />
|
||||
<input type="text" value="{{ base_url }}?q={{ q|urlencode }}&pageno={{ pageno }}{% if selected_categories %}&category_{{ selected_categories|join("&category_")|replace(' ','+') }}{% endif %}" readonly />
|
||||
</div>
|
||||
<div id="apis">
|
||||
{{ _('Download results') }}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% from 'oscar/macros.html' import icon %}
|
||||
|
||||
<h4 class="result_header">{% if result['favicon'] %}<img width="32" height="32" class="favicon" src="static/{{ theme }}/img/icons/{{ result['favicon'] }}.png" alt="{{ result['favicon'] }}" /> {% endif %}<a href="{{ result.url }}">{{ result.title|safe }}</a></h4>
|
||||
<h4 class="result_header">{% if result.engine~".png" in favicons %}<img width="32" height="32" class="favicon" src="static/{{ theme }}/img/icons/{{ result.engine }}.png" alt="{{ result.engine }}" /> {% endif %}<a href="{{ result.url }}">{{ result.title|safe }}</a></h4>
|
||||
|
||||
{% if result.publishedDate %}<time class="text-muted" datetime="{{ result.pubdate }}" >{{ result.publishedDate }}</time>{% endif %}
|
||||
<small><a class="text-info" href="https://web.archive.org/web/{{ result.url }}">{{ icon('link') }} {{ _('cached') }}</a></small>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
||||
<h4 class="modal-title">{% if result['favicon'] %}<img width="32" height="32" class="favicon" src="static/{{ theme }}/img/icons/{{ result['favicon'] }}.png" alt="{{ result['favicon'] }}" /> {% endif %}{{ result.title|striptags }}</h4>
|
||||
<h4 class="modal-title">{% if result.engine~".png" in favicons %}<img width="32" height="32" class="favicon" src="static/{{ theme }}/img/icons/{{ result.engine }}.png" alt="{{ result.engine }}" /> {% endif %}{{ result.title|striptags }}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<img class="img-responsive center-block" src="{{ result.img_src }}" alt="{{ result.title }}">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% from 'oscar/macros.html' import icon %}
|
||||
|
||||
<h4 class="result_header">{% if result['favicon'] %}<img width="32" height="32" class="favicon" src="static/{{ theme }}/img/icons/{{ result['favicon'] }}.png" alt="{{ result['favicon'] }}" /> {% endif %}<a href="{{ result.url }}">{{ result.title|safe }}</a></h4>
|
||||
<h4 class="result_header">{% if result.engine~".png" in favicons %}<img width="32" height="32" class="favicon" src="static/{{ theme }}/img/icons/{{ result.engine }}.png" alt="{{ result.engine }}" /> {% endif %}<a href="{{ result.url }}">{{ result.title|safe }}</a></h4>
|
||||
|
||||
{% if result.publishedDate %}<time class="text-muted" datetime="{{ result.pubdate }}" >{{ result.publishedDate }}</time>{% endif %}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% from 'oscar/macros.html' import icon %}
|
||||
|
||||
<h4 class="result_header">{% if result['favicon'] %}<img width="32" height="32" class="favicon" src="static/{{ theme }}/img/icons/{{ result['favicon'] }}.png" alt="{{ result['favicon'] }}" /> {% endif %}<a href="{{ result.url }}">{{ result.title|safe }}</a></h4>
|
||||
<h4 class="result_header">{% if result.engine~".png" in favicons %}<img width="32" height="32" class="favicon" src="static/{{ theme }}/img/icons/{{ result.engine }}.png" alt="{{ result.engine }}" /> {% endif %}<a href="{{ result.url }}">{{ result.title|safe }}</a></h4>
|
||||
|
||||
{% if result.publishedDate %}<time class="text-muted" datetime="{{ result.pubdate }}" >{{ result.publishedDate }}</time>{% endif %}
|
||||
<small><a class="text-info" href="https://web.archive.org/web/{{ result.url }}">{{ icon('link') }} {{ _('cached') }}</a></small>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
{% from 'oscar/macros.html' import icon %}
|
||||
|
||||
<h4 class="result_header">{% if result['favicon'] %}<img width="32" height="32" class="favicon" src="static/{{ theme }}/img/icons/{{ result['favicon'] }}.png" alt="{{ result['favicon'] }}" /> {% endif %}<a href="{{ result.url }}">{{ result.title|safe }}</a></h4>
|
||||
<h4 class="result_header">{% if result.engine~".png" in favicons %}<img width="32" height="32" class="favicon" src="static/{{ theme }}/img/icons/{{ result.engine }}.png" alt="{{ result.engine }}" /> {% endif %}<a href="{{ result.url }}">{{ result.title|safe }}</a></h4>
|
||||
|
||||
{% if result.publishedDate %}<time class="text-muted" datetime="{{ result.pubdate }}" >{{ result.publishedDate }}</time>{% endif %}
|
||||
<small><a class="text-info" href="https://web.archive.org/web/{{ result.url }}">{{ icon('link') }} {{ _('cached') }}</a></small>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<img class="thumbnail col-xs-6 col-sm-4 col-md-4 result-content" src="{{ result.thumbnail|safe }}" alt="{{ result.title|urlencode }} {{ result['favicon'] }}" />
|
||||
<a href="{{ result.url }}"><img class="thumbnail col-xs-6 col-sm-4 col-md-4 result-content" src="{{ result.thumbnail|safe }}" alt="{{ result.title|striptags }} {{ result.engine }}" /></a>
|
||||
{% if result.content %}<p class="col-xs-12 col-sm-8 col-md-8 result-content">{{ result.content|safe }}</p>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -49,7 +49,7 @@ class ViewsTestCase(SearxTestCase):
|
|||
)
|
||||
result = self.app.post('/', data={'q': 'test'})
|
||||
self.assertIn(
|
||||
'<h3 class="result_title"> <img width="14" height="14" class="favicon" src="static/default/img/icon_youtube.ico" /><a href="http://first.test.xyz">First <span class="highlight">Test</span></a></h3>', # noqa
|
||||
'<h3 class="result_title"><img width="14" height="14" class="favicon" src="static/default/img/icon_youtube.ico" alt="youtube" /><a href="http://second.test.xyz">Second <span class="highlight">Test</span></a></h3>', # noqa
|
||||
result.data
|
||||
)
|
||||
self.assertIn(
|
||||
|
|
Binary file not shown.
|
@ -1,25 +1,28 @@
|
|||
# English translations for .
|
||||
# English translations for PROJECT.
|
||||
# Copyright (C) 2014 ORGANIZATION
|
||||
# This file is distributed under the same license as the project.
|
||||
#
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
#
|
||||
# Translators:
|
||||
# pointhi, 2014
|
||||
# pointhi, 2014
|
||||
# rike, 2014
|
||||
# stf <stefan.marsiske@gmail.com>, 2014
|
||||
# stf <stefan.marsiske@gmail.com>, 2014
|
||||
# rike, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: searx\n"
|
||||
"Project-Id-Version: searx\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2014-11-26 20:41+0100\n"
|
||||
"PO-Revision-Date: 2014-03-15 18:40+0000\n"
|
||||
"Last-Translator: pointhi\n"
|
||||
"Language-Team: German "
|
||||
"(http://www.transifex.com/projects/p/searx/language/de/)\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"PO-Revision-Date: 2014-12-25 10:01+0000\n"
|
||||
"Last-Translator: Adam Tauber <asciimoo@gmail.com>\n"
|
||||
"Language-Team: German (http://www.transifex.com/projects/p/searx/language/de/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 1.3\n"
|
||||
"Language: de\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: searx/webapp.py:308
|
||||
msgid "{minutes} minute(s) ago"
|
||||
|
@ -143,11 +146,9 @@ msgstr "Blockieren"
|
|||
#: searx/templates/default/preferences.html:94
|
||||
#: searx/templates/oscar/preferences.html:132
|
||||
msgid ""
|
||||
"These settings are stored in your cookies, this allows us not to store "
|
||||
"this data about you."
|
||||
msgstr ""
|
||||
"Diese Informationen werden in Cookies auf Ihrem Rechner gespeichert, "
|
||||
"damit wir keine Ihrer persönlichen Daten speichern müssen."
|
||||
"These settings are stored in your cookies, this allows us not to store this "
|
||||
"data about you."
|
||||
msgstr "Diese Informationen werden in Cookies auf Ihrem Rechner gespeichert, damit wir keine Ihrer persönlichen Daten speichern müssen."
|
||||
|
||||
#: searx/templates/courgette/preferences.html:94
|
||||
#: searx/templates/default/preferences.html:96
|
||||
|
@ -155,9 +156,7 @@ msgstr ""
|
|||
msgid ""
|
||||
"These cookies serve your sole convenience, we don't use these cookies to "
|
||||
"track you."
|
||||
msgstr ""
|
||||
"Diese Cookies dienen einzig Ihrem Komfort, wir verwenden sie nicht, um "
|
||||
"Sie zu überwachen."
|
||||
msgstr "Diese Cookies dienen einzig Ihrem Komfort, wir verwenden sie nicht, um Sie zu überwachen."
|
||||
|
||||
#: searx/templates/courgette/preferences.html:97
|
||||
#: searx/templates/default/preferences.html:99
|
||||
|
@ -214,35 +213,35 @@ msgstr "Suchmaschinenstatistik"
|
|||
|
||||
#: searx/templates/default/categories.html:8
|
||||
msgid "Click on the magnifier to perform search"
|
||||
msgstr ""
|
||||
msgstr "klicke auf die Lupe, um die Suche zu starten"
|
||||
|
||||
#: searx/templates/default/preferences.html:72
|
||||
msgid "Localization"
|
||||
msgstr ""
|
||||
msgstr "Übersetzung"
|
||||
|
||||
#: searx/templates/default/preferences.html:82
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
msgstr "Ja"
|
||||
|
||||
#: searx/templates/default/preferences.html:82
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
msgstr "Nein"
|
||||
|
||||
#: searx/templates/default/results.html:34
|
||||
msgid "Answers"
|
||||
msgstr ""
|
||||
msgstr "Antworten"
|
||||
|
||||
#: searx/templates/oscar/base.html:69
|
||||
msgid "Powered by"
|
||||
msgstr ""
|
||||
msgstr "Powered by"
|
||||
|
||||
#: searx/templates/oscar/base.html:69
|
||||
msgid "a privacy-respecting, hackable metasearch engine"
|
||||
msgstr "eine privatsphären respektierende, hackbare Metasuchmaschine"
|
||||
msgstr "eine privatsphären-respektierende, hackbare Metasuchmaschine"
|
||||
|
||||
#: searx/templates/oscar/navbar.html:6
|
||||
msgid "Toggle navigation"
|
||||
msgstr ""
|
||||
msgstr "Navigation umschalten"
|
||||
|
||||
#: searx/templates/oscar/navbar.html:15
|
||||
msgid "home"
|
||||
|
@ -260,25 +259,22 @@ msgstr "Suchmaschinen"
|
|||
|
||||
#: searx/templates/oscar/preferences.html:39
|
||||
msgid "What language do you prefer for search?"
|
||||
msgstr "Welche Sprache bevorzugst du für die Suche?"
|
||||
msgstr "welche Sprache bevorzugst du für die Suche?"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:50
|
||||
msgid "Change the language of the layout"
|
||||
msgstr "Ändere die Sprache des Layouts"
|
||||
msgstr "ändere die Sprache des Layouts"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:63
|
||||
msgid "Find stuff as you type"
|
||||
msgstr "finde Sachen während der Eingabe"
|
||||
msgstr "zeige Vorschläge während der Eingabe an"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:73
|
||||
msgid ""
|
||||
"Change how forms are submited, <a "
|
||||
"href=\"http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods\""
|
||||
" rel=\"external\">learn more about request methods</a>"
|
||||
msgstr ""
|
||||
"ändere wie Formulare übertragen werden, <a "
|
||||
"href=\"https://de.wikipedia.org/wiki/Hypertext_Transfer_Protocol#HTTP-"
|
||||
"Anfragemethoden\" rel=\"external\">lerne mehr über Anfragemethoden</a>"
|
||||
msgstr "ändere wie Formulare übertragen werden, <a href=\"https://de.wikipedia.org/wiki/Hypertext_Transfer_Protocol#HTTP-Anfragemethoden\" rel=\"external\">lerne mehr über Anfragemethoden</a>"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:84
|
||||
msgid "Change searx layout"
|
||||
|
@ -290,9 +286,10 @@ msgstr "Suchergebnisse"
|
|||
|
||||
#: searx/templates/oscar/results.html:73
|
||||
msgid "Links"
|
||||
msgstr ""
|
||||
msgstr "Links"
|
||||
|
||||
#: searx/templates/oscar/search.html:6 searx/templates/oscar/search_full.html:7
|
||||
#: searx/templates/oscar/search.html:6
|
||||
#: searx/templates/oscar/search_full.html:7
|
||||
msgid "Start search"
|
||||
msgstr "Suche starten"
|
||||
|
||||
|
@ -302,7 +299,7 @@ msgstr "Suchfilter anzeigen"
|
|||
|
||||
#: searx/templates/oscar/search_full.html:11
|
||||
msgid "Hide search filters"
|
||||
msgstr "Suchfilter verstecke"
|
||||
msgstr "Suchfilter verstecken"
|
||||
|
||||
#: searx/templates/oscar/stats.html:2
|
||||
msgid "stats"
|
||||
|
@ -318,11 +315,11 @@ msgstr "Schließen"
|
|||
#: searx/templates/oscar/messages/first_time.html:6
|
||||
#: searx/templates/oscar/messages/no_data_available.html:3
|
||||
msgid "Heads up!"
|
||||
msgstr "Information!"
|
||||
msgstr "Achtung"
|
||||
|
||||
#: searx/templates/oscar/messages/first_time.html:7
|
||||
msgid "It look like you are using searx first time."
|
||||
msgstr ""
|
||||
msgstr "Es sieht so aus als ob das dein erstes mal mit searx ist."
|
||||
|
||||
#: searx/templates/oscar/messages/js_disabled.html:2
|
||||
msgid "Warning!"
|
||||
|
@ -330,7 +327,7 @@ msgstr "Warnung!"
|
|||
|
||||
#: searx/templates/oscar/messages/js_disabled.html:3
|
||||
msgid "Please enable JavaScript to use full functionality of this site."
|
||||
msgstr "Bitte aktiviere JavaScript um alle möglichkeiten dieser Seite zu nutzen."
|
||||
msgstr "Bitte aktiviere JavaScript, um alle funktionen dieser Seite zu nutzen. "
|
||||
|
||||
#: searx/templates/oscar/messages/no_data_available.html:4
|
||||
msgid "There is currently no data available. "
|
||||
|
@ -344,13 +341,11 @@ msgstr "Entschuldigung!"
|
|||
msgid ""
|
||||
"we didn't find any results. Please use another query or search in more "
|
||||
"categories."
|
||||
msgstr ""
|
||||
"Es konnten keine Suchergebnisse gefunden werden. Bitte nutze einen "
|
||||
"anderen Suchbegriff oder Suche das gewünschte in einer anderen Kategorie."
|
||||
msgstr "Es konnten keine Suchergebnisse gefunden werden. Bitte nutze einen anderen Suchbegriff, oder Suche das gewünschte in einer anderen Kategorie. "
|
||||
|
||||
#: searx/templates/oscar/messages/save_settings_successfull.html:7
|
||||
msgid "Well done!"
|
||||
msgstr "Gut gemacht!"
|
||||
msgstr "Gut gemacht"
|
||||
|
||||
#: searx/templates/oscar/messages/save_settings_successfull.html:8
|
||||
msgid "Settings saved successfully."
|
||||
|
@ -358,7 +353,7 @@ msgstr "Einstellungen wurden erfolgreich gespeichert."
|
|||
|
||||
#: searx/templates/oscar/messages/unknow_error.html:7
|
||||
msgid "Oh snap!"
|
||||
msgstr "Verdammt!"
|
||||
msgstr "Oh nein'"
|
||||
|
||||
#: searx/templates/oscar/messages/unknow_error.html:8
|
||||
msgid "Something went wrong."
|
||||
|
@ -369,7 +364,7 @@ msgstr "Irgendetwas ist falsch gelaufen."
|
|||
#: searx/templates/oscar/result_templates/torrent.html:6
|
||||
#: searx/templates/oscar/result_templates/videos.html:6
|
||||
msgid "cached"
|
||||
msgstr "cached"
|
||||
msgstr "zwischengelagert"
|
||||
|
||||
#: searx/templates/oscar/result_templates/images.html:21
|
||||
msgid "Get image"
|
||||
|
@ -393,15 +388,15 @@ msgstr "Details anzeigen"
|
|||
|
||||
#: searx/templates/oscar/result_templates/map.html:14
|
||||
msgid "hide details"
|
||||
msgstr "Details verstecke"
|
||||
msgstr "Details verstecken"
|
||||
|
||||
#: searx/templates/oscar/result_templates/torrent.html:8
|
||||
msgid "Seeder"
|
||||
msgstr ""
|
||||
msgstr "Samenverstreuer"
|
||||
|
||||
#: searx/templates/oscar/result_templates/torrent.html:8
|
||||
msgid "Leecher"
|
||||
msgstr ""
|
||||
msgstr "Zecke"
|
||||
|
||||
# categories - manually added
|
||||
# TODO - automatically add
|
||||
|
@ -431,4 +426,3 @@ msgstr "Neuigkeiten"
|
|||
|
||||
msgid "map"
|
||||
msgstr "Karte"
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,24 +1,27 @@
|
|||
# French translations for SEARX
|
||||
# Copyright (C) 2014 Benjamin Sonntag, rike, Adam Tauber
|
||||
# This file is distributed under CC0 License
|
||||
#
|
||||
# English translations for PROJECT.
|
||||
# Copyright (C) 2014 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
#
|
||||
# Translators:
|
||||
# Benjamin Sonntag <benjamin@sonntag.fr>, 2014
|
||||
# Cqoicebordel <david.barouh@wanadoo.fr>, 2014
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014
|
||||
# rike, 2014
|
||||
# rike, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: searx\n"
|
||||
"Project-Id-Version: searx\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2014-11-26 20:41+0100\n"
|
||||
"PO-Revision-Date: 2014-09-07 21:24+0000\n"
|
||||
"Last-Translator: Adam Tauber <asciimoo@gmail.com>\n"
|
||||
"Language-Team: French "
|
||||
"(http://www.transifex.com/projects/p/searx/language/fr/)\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
|
||||
"PO-Revision-Date: 2014-12-14 21:00+0000\n"
|
||||
"Last-Translator: Cqoicebordel <david.barouh@wanadoo.fr>\n"
|
||||
"Language-Team: French (http://www.transifex.com/projects/p/searx/language/fr/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 1.3\n"
|
||||
"Language: fr\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: searx/webapp.py:308
|
||||
msgid "{minutes} minute(s) ago"
|
||||
|
@ -142,11 +145,9 @@ msgstr "Bloquer"
|
|||
#: searx/templates/default/preferences.html:94
|
||||
#: searx/templates/oscar/preferences.html:132
|
||||
msgid ""
|
||||
"These settings are stored in your cookies, this allows us not to store "
|
||||
"this data about you."
|
||||
msgstr ""
|
||||
"Ces paramètres sont stockés dans vos cookies ; ceci nous permet de ne pas"
|
||||
" collecter vos données."
|
||||
"These settings are stored in your cookies, this allows us not to store this "
|
||||
"data about you."
|
||||
msgstr "Ces paramètres sont stockés dans vos cookies ; ceci nous permet de ne pas collecter vos données."
|
||||
|
||||
#: searx/templates/courgette/preferences.html:94
|
||||
#: searx/templates/default/preferences.html:96
|
||||
|
@ -154,9 +155,7 @@ msgstr ""
|
|||
msgid ""
|
||||
"These cookies serve your sole convenience, we don't use these cookies to "
|
||||
"track you."
|
||||
msgstr ""
|
||||
"Ces cookies existent pour votre confort d'utilisation, nous ne les "
|
||||
"utilisons pas pour vous espionner."
|
||||
msgstr "Ces cookies existent pour votre confort d'utilisation, nous ne les utilisons pas pour vous espionner."
|
||||
|
||||
#: searx/templates/courgette/preferences.html:97
|
||||
#: searx/templates/default/preferences.html:99
|
||||
|
@ -213,19 +212,19 @@ msgstr "Statistiques du moteur"
|
|||
|
||||
#: searx/templates/default/categories.html:8
|
||||
msgid "Click on the magnifier to perform search"
|
||||
msgstr ""
|
||||
msgstr "Cliquez sur la loupe pour effectuer une recherche"
|
||||
|
||||
#: searx/templates/default/preferences.html:72
|
||||
msgid "Localization"
|
||||
msgstr ""
|
||||
msgstr "Localisation"
|
||||
|
||||
#: searx/templates/default/preferences.html:82
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
msgstr "Oui"
|
||||
|
||||
#: searx/templates/default/preferences.html:82
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
msgstr "Non"
|
||||
|
||||
#: searx/templates/default/results.html:34
|
||||
msgid "Answers"
|
||||
|
@ -274,10 +273,7 @@ msgid ""
|
|||
"Change how forms are submited, <a "
|
||||
"href=\"http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods\""
|
||||
" rel=\"external\">learn more about request methods</a>"
|
||||
msgstr ""
|
||||
"Permet de choisir comment la recherche est envoyée, <a "
|
||||
"href=\"https://fr.wikipedia.org/wiki/Hypertext_Transfer_Protocol#M.C3.A9thodes\""
|
||||
" rel=\"external\">en savoir plus sur les méthodes HTTP</a>"
|
||||
msgstr "Permet de choisir comment la recherche est envoyée, <a href=\"https://fr.wikipedia.org/wiki/Hypertext_Transfer_Protocol#M.C3.A9thodes\" rel=\"external\">en savoir plus sur les méthodes HTTP</a>"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:84
|
||||
msgid "Change searx layout"
|
||||
|
@ -291,7 +287,8 @@ msgstr "Résultats de recherche"
|
|||
msgid "Links"
|
||||
msgstr "Liens"
|
||||
|
||||
#: searx/templates/oscar/search.html:6 searx/templates/oscar/search_full.html:7
|
||||
#: searx/templates/oscar/search.html:6
|
||||
#: searx/templates/oscar/search_full.html:7
|
||||
msgid "Start search"
|
||||
msgstr "Lancer une recherche"
|
||||
|
||||
|
@ -329,9 +326,7 @@ msgstr "Attention !"
|
|||
|
||||
#: searx/templates/oscar/messages/js_disabled.html:3
|
||||
msgid "Please enable JavaScript to use full functionality of this site."
|
||||
msgstr ""
|
||||
"Merci d'activer JavaScript pour utiliser toutes les fonctionnalités de ce"
|
||||
" site."
|
||||
msgstr "Merci d'activer JavaScript pour utiliser toutes les fonctionnalités de ce site."
|
||||
|
||||
#: searx/templates/oscar/messages/no_data_available.html:4
|
||||
msgid "There is currently no data available. "
|
||||
|
@ -345,9 +340,7 @@ msgstr "Désolé !"
|
|||
msgid ""
|
||||
"we didn't find any results. Please use another query or search in more "
|
||||
"categories."
|
||||
msgstr ""
|
||||
"nous n'avons trouvé aucun résultat. Effectuez une autre recherche ou "
|
||||
"changez de catégorie."
|
||||
msgstr "nous n'avons trouvé aucun résultat. Effectuez une autre recherche ou changez de catégorie."
|
||||
|
||||
#: searx/templates/oscar/messages/save_settings_successfull.html:7
|
||||
msgid "Well done!"
|
||||
|
@ -432,4 +425,3 @@ msgstr "actus"
|
|||
|
||||
msgid "map"
|
||||
msgstr "carte"
|
||||
|
||||
|
|
Binary file not shown.
|
@ -1,24 +1,24 @@
|
|||
# English translations for .
|
||||
# English translations for PROJECT.
|
||||
# Copyright (C) 2014 ORGANIZATION
|
||||
# This file is distributed under the same license as the project.
|
||||
#
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
#
|
||||
# Translators:
|
||||
# Adam Tauber <asciimoo@gmail.com>, 2014
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: searx\n"
|
||||
"Project-Id-Version: searx\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2014-11-26 20:41+0100\n"
|
||||
"PO-Revision-Date: 2014-09-07 21:30+0000\n"
|
||||
"PO-Revision-Date: 2014-12-22 16:11+0000\n"
|
||||
"Last-Translator: Adam Tauber <asciimoo@gmail.com>\n"
|
||||
"Language-Team: Hungarian "
|
||||
"(http://www.transifex.com/projects/p/searx/language/hu/)\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"Language-Team: Hungarian (http://www.transifex.com/projects/p/searx/language/hu/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 1.3\n"
|
||||
"Language: hu\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: searx/webapp.py:308
|
||||
msgid "{minutes} minute(s) ago"
|
||||
|
@ -93,19 +93,19 @@ msgstr "Felület nyelve"
|
|||
#: searx/templates/default/preferences.html:36
|
||||
#: searx/templates/oscar/preferences.html:53
|
||||
msgid "Autocomplete"
|
||||
msgstr ""
|
||||
msgstr "Automatikus kiegészítés"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:47
|
||||
#: searx/templates/default/preferences.html:47
|
||||
#: searx/templates/oscar/preferences.html:66
|
||||
msgid "Method"
|
||||
msgstr ""
|
||||
msgstr "Method"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:56
|
||||
#: searx/templates/default/preferences.html:56
|
||||
#: searx/templates/oscar/preferences.html:76
|
||||
msgid "Themes"
|
||||
msgstr ""
|
||||
msgstr "Megjelenés"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:66
|
||||
#: searx/templates/default/preferences.html:66
|
||||
|
@ -142,8 +142,8 @@ msgstr "Tiltás"
|
|||
#: searx/templates/default/preferences.html:94
|
||||
#: searx/templates/oscar/preferences.html:132
|
||||
msgid ""
|
||||
"These settings are stored in your cookies, this allows us not to store "
|
||||
"this data about you."
|
||||
"These settings are stored in your cookies, this allows us not to store this "
|
||||
"data about you."
|
||||
msgstr "Ezek a beállítások csak a böngésző cookie-jaiban tárolódnak."
|
||||
|
||||
#: searx/templates/courgette/preferences.html:94
|
||||
|
@ -152,9 +152,7 @@ msgstr "Ezek a beállítások csak a böngésző cookie-jaiban tárolódnak."
|
|||
msgid ""
|
||||
"These cookies serve your sole convenience, we don't use these cookies to "
|
||||
"track you."
|
||||
msgstr ""
|
||||
"Ezek a cookie-k csak kényelmi funkciókat látnak el, nem használjuk a "
|
||||
"felhasználók követésére."
|
||||
msgstr "Ezek a cookie-k csak kényelmi funkciókat látnak el, nem használjuk a felhasználók követésére."
|
||||
|
||||
#: searx/templates/courgette/preferences.html:97
|
||||
#: searx/templates/default/preferences.html:99
|
||||
|
@ -211,189 +209,190 @@ msgstr "Kereső statisztikák"
|
|||
|
||||
#: searx/templates/default/categories.html:8
|
||||
msgid "Click on the magnifier to perform search"
|
||||
msgstr ""
|
||||
msgstr "A nagyítóra kattintva indítható a keresés"
|
||||
|
||||
#: searx/templates/default/preferences.html:72
|
||||
msgid "Localization"
|
||||
msgstr ""
|
||||
msgstr "Nyelv"
|
||||
|
||||
#: searx/templates/default/preferences.html:82
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
msgstr "Igen"
|
||||
|
||||
#: searx/templates/default/preferences.html:82
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
msgstr "Nem"
|
||||
|
||||
#: searx/templates/default/results.html:34
|
||||
msgid "Answers"
|
||||
msgstr ""
|
||||
msgstr "Válaszok"
|
||||
|
||||
#: searx/templates/oscar/base.html:69
|
||||
msgid "Powered by"
|
||||
msgstr ""
|
||||
msgstr "Az oldalt kiszolgálja: "
|
||||
|
||||
#: searx/templates/oscar/base.html:69
|
||||
msgid "a privacy-respecting, hackable metasearch engine"
|
||||
msgstr ""
|
||||
msgstr "egy privátszféra tisztelő, könnyen módosítható metakereső"
|
||||
|
||||
#: searx/templates/oscar/navbar.html:6
|
||||
msgid "Toggle navigation"
|
||||
msgstr ""
|
||||
msgstr "Navigáció megjelenítés"
|
||||
|
||||
#: searx/templates/oscar/navbar.html:15
|
||||
msgid "home"
|
||||
msgstr ""
|
||||
msgstr "főoldal"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:11
|
||||
#: searx/templates/oscar/preferences.html:17
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "Általános"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:12
|
||||
#: searx/templates/oscar/preferences.html:99
|
||||
msgid "Engines"
|
||||
msgstr ""
|
||||
msgstr "Kereső motorok"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:39
|
||||
msgid "What language do you prefer for search?"
|
||||
msgstr ""
|
||||
msgstr "Preferált keresési nyelv"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:50
|
||||
msgid "Change the language of the layout"
|
||||
msgstr ""
|
||||
msgstr "Felület nyelve"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:63
|
||||
msgid "Find stuff as you type"
|
||||
msgstr ""
|
||||
msgstr "Autómatikus kereső kifejezés kiegészítés"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:73
|
||||
msgid ""
|
||||
"Change how forms are submited, <a "
|
||||
"href=\"http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods\""
|
||||
" rel=\"external\">learn more about request methods</a>"
|
||||
msgstr ""
|
||||
msgstr "Keresés metódusa (<a href=\"http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods\" rel=\"external\">bővebben</a>)"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:84
|
||||
msgid "Change searx layout"
|
||||
msgstr ""
|
||||
msgstr "Megjelenés"
|
||||
|
||||
#: searx/templates/oscar/results.html:6
|
||||
msgid "Search results"
|
||||
msgstr ""
|
||||
msgstr "Keresési eredmények"
|
||||
|
||||
#: searx/templates/oscar/results.html:73
|
||||
msgid "Links"
|
||||
msgstr ""
|
||||
msgstr "Linkek"
|
||||
|
||||
#: searx/templates/oscar/search.html:6 searx/templates/oscar/search_full.html:7
|
||||
#: searx/templates/oscar/search.html:6
|
||||
#: searx/templates/oscar/search_full.html:7
|
||||
msgid "Start search"
|
||||
msgstr ""
|
||||
msgstr "Keresés indítása"
|
||||
|
||||
#: searx/templates/oscar/search_full.html:11
|
||||
msgid "Show search filters"
|
||||
msgstr ""
|
||||
msgstr "Keresési szűrők megjelenítése"
|
||||
|
||||
#: searx/templates/oscar/search_full.html:11
|
||||
msgid "Hide search filters"
|
||||
msgstr ""
|
||||
msgstr "Keresési szűrők elrejtése"
|
||||
|
||||
#: searx/templates/oscar/stats.html:2
|
||||
msgid "stats"
|
||||
msgstr ""
|
||||
msgstr "statisztikák"
|
||||
|
||||
#: searx/templates/oscar/messages/first_time.html:4
|
||||
#: searx/templates/oscar/messages/no_results.html:5
|
||||
#: searx/templates/oscar/messages/save_settings_successfull.html:5
|
||||
#: searx/templates/oscar/messages/unknow_error.html:5
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
msgstr "Bezár"
|
||||
|
||||
#: searx/templates/oscar/messages/first_time.html:6
|
||||
#: searx/templates/oscar/messages/no_data_available.html:3
|
||||
msgid "Heads up!"
|
||||
msgstr ""
|
||||
msgstr "Figyelem!"
|
||||
|
||||
#: searx/templates/oscar/messages/first_time.html:7
|
||||
msgid "It look like you are using searx first time."
|
||||
msgstr ""
|
||||
msgstr "Úgy tűnik először használod a keresőt."
|
||||
|
||||
#: searx/templates/oscar/messages/js_disabled.html:2
|
||||
msgid "Warning!"
|
||||
msgstr ""
|
||||
msgstr "Figyelem!"
|
||||
|
||||
#: searx/templates/oscar/messages/js_disabled.html:3
|
||||
msgid "Please enable JavaScript to use full functionality of this site."
|
||||
msgstr ""
|
||||
msgstr "Engedélyezze a javascript-et a teljes funkcionalitás használathoz"
|
||||
|
||||
#: searx/templates/oscar/messages/no_data_available.html:4
|
||||
msgid "There is currently no data available. "
|
||||
msgstr ""
|
||||
msgstr "Nincs megjeleníthető adat."
|
||||
|
||||
#: searx/templates/oscar/messages/no_results.html:7
|
||||
msgid "Sorry!"
|
||||
msgstr ""
|
||||
msgstr "Elnézést!"
|
||||
|
||||
#: searx/templates/oscar/messages/no_results.html:8
|
||||
msgid ""
|
||||
"we didn't find any results. Please use another query or search in more "
|
||||
"categories."
|
||||
msgstr ""
|
||||
msgstr "Nincs megjeleníthető találat."
|
||||
|
||||
#: searx/templates/oscar/messages/save_settings_successfull.html:7
|
||||
msgid "Well done!"
|
||||
msgstr ""
|
||||
msgstr "Siker!"
|
||||
|
||||
#: searx/templates/oscar/messages/save_settings_successfull.html:8
|
||||
msgid "Settings saved successfully."
|
||||
msgstr ""
|
||||
msgstr "Beállítások mentve"
|
||||
|
||||
#: searx/templates/oscar/messages/unknow_error.html:7
|
||||
msgid "Oh snap!"
|
||||
msgstr ""
|
||||
msgstr "Oh!"
|
||||
|
||||
#: searx/templates/oscar/messages/unknow_error.html:8
|
||||
msgid "Something went wrong."
|
||||
msgstr ""
|
||||
msgstr "Hiba történt"
|
||||
|
||||
#: searx/templates/oscar/result_templates/default.html:6
|
||||
#: searx/templates/oscar/result_templates/map.html:7
|
||||
#: searx/templates/oscar/result_templates/torrent.html:6
|
||||
#: searx/templates/oscar/result_templates/videos.html:6
|
||||
msgid "cached"
|
||||
msgstr ""
|
||||
msgstr "tárolt"
|
||||
|
||||
#: searx/templates/oscar/result_templates/images.html:21
|
||||
msgid "Get image"
|
||||
msgstr ""
|
||||
msgstr "Kép megjelenítése"
|
||||
|
||||
#: searx/templates/oscar/result_templates/images.html:22
|
||||
msgid "View source"
|
||||
msgstr ""
|
||||
msgstr "Forrás megtekintése"
|
||||
|
||||
#: searx/templates/oscar/result_templates/map.html:10
|
||||
msgid "show map"
|
||||
msgstr ""
|
||||
msgstr "Térkép"
|
||||
|
||||
#: searx/templates/oscar/result_templates/map.html:10
|
||||
msgid "hide map"
|
||||
msgstr ""
|
||||
msgstr "Térkép elrejtése"
|
||||
|
||||
#: searx/templates/oscar/result_templates/map.html:14
|
||||
msgid "show details"
|
||||
msgstr ""
|
||||
msgstr "Részletek"
|
||||
|
||||
#: searx/templates/oscar/result_templates/map.html:14
|
||||
msgid "hide details"
|
||||
msgstr ""
|
||||
msgstr "Részletek elrejtése"
|
||||
|
||||
#: searx/templates/oscar/result_templates/torrent.html:8
|
||||
msgid "Seeder"
|
||||
msgstr ""
|
||||
msgstr "Seeder"
|
||||
|
||||
#: searx/templates/oscar/result_templates/torrent.html:8
|
||||
msgid "Leecher"
|
||||
msgstr ""
|
||||
msgstr "Leecher"
|
||||
|
||||
# categories - manually added
|
||||
# TODO - automatically add
|
||||
|
@ -423,4 +422,3 @@ msgstr "hírek"
|
|||
|
||||
msgid "map"
|
||||
msgstr "térkép"
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,23 +1,23 @@
|
|||
# English translations for .
|
||||
# English translations for PROJECT.
|
||||
# Copyright (C) 2014 ORGANIZATION
|
||||
# This file is distributed under the same license as the project.
|
||||
#
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
#
|
||||
# Translators:
|
||||
# André Koot <meneer@tken.net>, 2014
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: searx\n"
|
||||
"Project-Id-Version: searx\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2014-11-26 20:41+0100\n"
|
||||
"PO-Revision-Date: 2014-09-09 15:33+0000\n"
|
||||
"PO-Revision-Date: 2014-12-11 13:50+0000\n"
|
||||
"Last-Translator: André Koot <meneer@tken.net>\n"
|
||||
"Language-Team: Dutch "
|
||||
"(http://www.transifex.com/projects/p/searx/language/nl/)\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"Language-Team: Dutch (http://www.transifex.com/projects/p/searx/language/nl/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 1.3\n"
|
||||
"Language: nl\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: searx/webapp.py:308
|
||||
msgid "{minutes} minute(s) ago"
|
||||
|
@ -92,19 +92,19 @@ msgstr "Interfacetaal"
|
|||
#: searx/templates/default/preferences.html:36
|
||||
#: searx/templates/oscar/preferences.html:53
|
||||
msgid "Autocomplete"
|
||||
msgstr ""
|
||||
msgstr "Auto-aanvullen"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:47
|
||||
#: searx/templates/default/preferences.html:47
|
||||
#: searx/templates/oscar/preferences.html:66
|
||||
msgid "Method"
|
||||
msgstr ""
|
||||
msgstr "Methode"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:56
|
||||
#: searx/templates/default/preferences.html:56
|
||||
#: searx/templates/oscar/preferences.html:76
|
||||
msgid "Themes"
|
||||
msgstr ""
|
||||
msgstr "Thema's"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:66
|
||||
#: searx/templates/default/preferences.html:66
|
||||
|
@ -141,11 +141,9 @@ msgstr "Blokkeren"
|
|||
#: searx/templates/default/preferences.html:94
|
||||
#: searx/templates/oscar/preferences.html:132
|
||||
msgid ""
|
||||
"These settings are stored in your cookies, this allows us not to store "
|
||||
"this data about you."
|
||||
msgstr ""
|
||||
"Deze instellingen worden bewaard in je cookies. Hierdoor hoeven wij niets"
|
||||
" over jou te bewaren."
|
||||
"These settings are stored in your cookies, this allows us not to store this "
|
||||
"data about you."
|
||||
msgstr "Deze instellingen worden bewaard in je cookies. Hierdoor hoeven wij niets over jou te bewaren."
|
||||
|
||||
#: searx/templates/courgette/preferences.html:94
|
||||
#: searx/templates/default/preferences.html:96
|
||||
|
@ -153,9 +151,7 @@ msgstr ""
|
|||
msgid ""
|
||||
"These cookies serve your sole convenience, we don't use these cookies to "
|
||||
"track you."
|
||||
msgstr ""
|
||||
"Deze cookies zijn alleen voor je eigen gemak, we gebruiken deze cookies "
|
||||
"niet om je te volgen."
|
||||
msgstr "Deze cookies zijn alleen voor je eigen gemak, we gebruiken deze cookies niet om je te volgen."
|
||||
|
||||
#: searx/templates/courgette/preferences.html:97
|
||||
#: searx/templates/default/preferences.html:99
|
||||
|
@ -212,189 +208,190 @@ msgstr "Zoekmachinestatistieken"
|
|||
|
||||
#: searx/templates/default/categories.html:8
|
||||
msgid "Click on the magnifier to perform search"
|
||||
msgstr ""
|
||||
msgstr "Klik op het vergrootglas om te zoeken"
|
||||
|
||||
#: searx/templates/default/preferences.html:72
|
||||
msgid "Localization"
|
||||
msgstr ""
|
||||
msgstr "Vertaling"
|
||||
|
||||
#: searx/templates/default/preferences.html:82
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
msgstr "Ja"
|
||||
|
||||
#: searx/templates/default/preferences.html:82
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
msgstr "Nee"
|
||||
|
||||
#: searx/templates/default/results.html:34
|
||||
msgid "Answers"
|
||||
msgstr ""
|
||||
msgstr "Antwoorden"
|
||||
|
||||
#: searx/templates/oscar/base.html:69
|
||||
msgid "Powered by"
|
||||
msgstr ""
|
||||
msgstr "Powered by"
|
||||
|
||||
#: searx/templates/oscar/base.html:69
|
||||
msgid "a privacy-respecting, hackable metasearch engine"
|
||||
msgstr ""
|
||||
msgstr "een privacy eerbiedigende, aanpasbare metazoekmachine"
|
||||
|
||||
#: searx/templates/oscar/navbar.html:6
|
||||
msgid "Toggle navigation"
|
||||
msgstr ""
|
||||
msgstr "Omschakelen navigatie"
|
||||
|
||||
#: searx/templates/oscar/navbar.html:15
|
||||
msgid "home"
|
||||
msgstr ""
|
||||
msgstr "thuis"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:11
|
||||
#: searx/templates/oscar/preferences.html:17
|
||||
msgid "General"
|
||||
msgstr ""
|
||||
msgstr "Algemeen"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:12
|
||||
#: searx/templates/oscar/preferences.html:99
|
||||
msgid "Engines"
|
||||
msgstr ""
|
||||
msgstr "Zoekmachines"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:39
|
||||
msgid "What language do you prefer for search?"
|
||||
msgstr ""
|
||||
msgstr "Welke taal wil je gebruiken voor het zoeken?"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:50
|
||||
msgid "Change the language of the layout"
|
||||
msgstr ""
|
||||
msgstr "Wijzig de taal van de layout"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:63
|
||||
msgid "Find stuff as you type"
|
||||
msgstr ""
|
||||
msgstr "Zoek tijdens het typen"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:73
|
||||
msgid ""
|
||||
"Change how forms are submited, <a "
|
||||
"href=\"http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods\""
|
||||
" rel=\"external\">learn more about request methods</a>"
|
||||
msgstr ""
|
||||
msgstr "Bepaal hoe de formulieren worden ingestuurd, <a href=\"http://nl.wikipedia.org/wiki/Hypertext_Transfer_Protocol#HTTP-requests\" rel=\"external\">lees meer over request methodes</a>"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:84
|
||||
msgid "Change searx layout"
|
||||
msgstr ""
|
||||
msgstr "Wijzig searx layout"
|
||||
|
||||
#: searx/templates/oscar/results.html:6
|
||||
msgid "Search results"
|
||||
msgstr ""
|
||||
msgstr "Zoekresultaten"
|
||||
|
||||
#: searx/templates/oscar/results.html:73
|
||||
msgid "Links"
|
||||
msgstr ""
|
||||
msgstr "Links"
|
||||
|
||||
#: searx/templates/oscar/search.html:6 searx/templates/oscar/search_full.html:7
|
||||
#: searx/templates/oscar/search.html:6
|
||||
#: searx/templates/oscar/search_full.html:7
|
||||
msgid "Start search"
|
||||
msgstr ""
|
||||
msgstr "Start zoeken"
|
||||
|
||||
#: searx/templates/oscar/search_full.html:11
|
||||
msgid "Show search filters"
|
||||
msgstr ""
|
||||
msgstr "Toon zoekfilters"
|
||||
|
||||
#: searx/templates/oscar/search_full.html:11
|
||||
msgid "Hide search filters"
|
||||
msgstr ""
|
||||
msgstr "Verberg zoekfilters"
|
||||
|
||||
#: searx/templates/oscar/stats.html:2
|
||||
msgid "stats"
|
||||
msgstr ""
|
||||
msgstr "stats"
|
||||
|
||||
#: searx/templates/oscar/messages/first_time.html:4
|
||||
#: searx/templates/oscar/messages/no_results.html:5
|
||||
#: searx/templates/oscar/messages/save_settings_successfull.html:5
|
||||
#: searx/templates/oscar/messages/unknow_error.html:5
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
msgstr "Sluiten"
|
||||
|
||||
#: searx/templates/oscar/messages/first_time.html:6
|
||||
#: searx/templates/oscar/messages/no_data_available.html:3
|
||||
msgid "Heads up!"
|
||||
msgstr ""
|
||||
msgstr "Heads up!"
|
||||
|
||||
#: searx/templates/oscar/messages/first_time.html:7
|
||||
msgid "It look like you are using searx first time."
|
||||
msgstr ""
|
||||
msgstr "Het lijkt erop dat je searx voor de eerste keer gebruikt."
|
||||
|
||||
#: searx/templates/oscar/messages/js_disabled.html:2
|
||||
msgid "Warning!"
|
||||
msgstr ""
|
||||
msgstr "Waarschuwing!"
|
||||
|
||||
#: searx/templates/oscar/messages/js_disabled.html:3
|
||||
msgid "Please enable JavaScript to use full functionality of this site."
|
||||
msgstr ""
|
||||
msgstr "Activeer JavaScript om alle functionaliteit van deze site te gebruiken."
|
||||
|
||||
#: searx/templates/oscar/messages/no_data_available.html:4
|
||||
msgid "There is currently no data available. "
|
||||
msgstr ""
|
||||
msgstr "Er zijn momenteel geen gegevens beschikbaar."
|
||||
|
||||
#: searx/templates/oscar/messages/no_results.html:7
|
||||
msgid "Sorry!"
|
||||
msgstr ""
|
||||
msgstr "Sorry!"
|
||||
|
||||
#: searx/templates/oscar/messages/no_results.html:8
|
||||
msgid ""
|
||||
"we didn't find any results. Please use another query or search in more "
|
||||
"categories."
|
||||
msgstr ""
|
||||
msgstr "we kregen geen resultaat. Probeer een andere opvraag of zoek in meer categorieën."
|
||||
|
||||
#: searx/templates/oscar/messages/save_settings_successfull.html:7
|
||||
msgid "Well done!"
|
||||
msgstr ""
|
||||
msgstr "Goed gedaan!"
|
||||
|
||||
#: searx/templates/oscar/messages/save_settings_successfull.html:8
|
||||
msgid "Settings saved successfully."
|
||||
msgstr ""
|
||||
msgstr "Instellingen succesvol opgeslagen."
|
||||
|
||||
#: searx/templates/oscar/messages/unknow_error.html:7
|
||||
msgid "Oh snap!"
|
||||
msgstr ""
|
||||
msgstr "Verdraaid!"
|
||||
|
||||
#: searx/templates/oscar/messages/unknow_error.html:8
|
||||
msgid "Something went wrong."
|
||||
msgstr ""
|
||||
msgstr "Er ging iets fout."
|
||||
|
||||
#: searx/templates/oscar/result_templates/default.html:6
|
||||
#: searx/templates/oscar/result_templates/map.html:7
|
||||
#: searx/templates/oscar/result_templates/torrent.html:6
|
||||
#: searx/templates/oscar/result_templates/videos.html:6
|
||||
msgid "cached"
|
||||
msgstr ""
|
||||
msgstr "gecached"
|
||||
|
||||
#: searx/templates/oscar/result_templates/images.html:21
|
||||
msgid "Get image"
|
||||
msgstr ""
|
||||
msgstr "Toon afbeelding"
|
||||
|
||||
#: searx/templates/oscar/result_templates/images.html:22
|
||||
msgid "View source"
|
||||
msgstr ""
|
||||
msgstr "Bekijk bron"
|
||||
|
||||
#: searx/templates/oscar/result_templates/map.html:10
|
||||
msgid "show map"
|
||||
msgstr ""
|
||||
msgstr "toon kaart"
|
||||
|
||||
#: searx/templates/oscar/result_templates/map.html:10
|
||||
msgid "hide map"
|
||||
msgstr ""
|
||||
msgstr "verberg kaart"
|
||||
|
||||
#: searx/templates/oscar/result_templates/map.html:14
|
||||
msgid "show details"
|
||||
msgstr ""
|
||||
msgstr "toon details"
|
||||
|
||||
#: searx/templates/oscar/result_templates/map.html:14
|
||||
msgid "hide details"
|
||||
msgstr ""
|
||||
msgstr "verberg details"
|
||||
|
||||
#: searx/templates/oscar/result_templates/torrent.html:8
|
||||
msgid "Seeder"
|
||||
msgstr ""
|
||||
msgstr "Aanbieder"
|
||||
|
||||
#: searx/templates/oscar/result_templates/torrent.html:8
|
||||
msgid "Leecher"
|
||||
msgstr ""
|
||||
msgstr "Ophaler"
|
||||
|
||||
# categories - manually added
|
||||
# TODO - automatically add
|
||||
|
@ -424,4 +421,3 @@ msgstr "nieuws"
|
|||
|
||||
msgid "map"
|
||||
msgstr "kaart"
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
|
|||
|
||||
# version of searx
|
||||
VERSION_MAJOR = 0
|
||||
VERSION_MINOR = 5
|
||||
VERSION_MINOR = 6
|
||||
VERSION_BUILD = 0
|
||||
|
||||
VERSION_STRING = "{0}.{1}.{2}".format(VERSION_MAJOR,
|
||||
|
|
|
@ -41,15 +41,12 @@ from searx.utils import (
|
|||
UnicodeWriter, highlight_content, html_to_text, get_themes
|
||||
)
|
||||
from searx.version import VERSION_STRING
|
||||
from searx.https_rewrite import https_rules
|
||||
from searx.languages import language_codes
|
||||
from searx.https_rewrite import https_url_rewrite
|
||||
from searx.search import Search
|
||||
from searx.query import Query
|
||||
from searx.autocomplete import backends as autocomplete_backends
|
||||
|
||||
from urlparse import urlparse
|
||||
import re
|
||||
|
||||
|
||||
static_path, templates_path, themes =\
|
||||
get_themes(settings['themes_path']
|
||||
|
@ -68,9 +65,12 @@ app.secret_key = settings['server']['secret_key']
|
|||
|
||||
babel = Babel(app)
|
||||
|
||||
#TODO configurable via settings.yml
|
||||
favicons = ['wikipedia', 'youtube', 'vimeo', 'dailymotion', 'soundcloud',
|
||||
'twitter', 'stackoverflow', 'github', 'deviantart']
|
||||
global_favicons = []
|
||||
for indice, theme in enumerate(themes):
|
||||
global_favicons.append([])
|
||||
theme_img_path = searx_dir+"/static/"+theme+"/img/"
|
||||
for (dirpath, dirnames, filenames) in os.walk(theme_img_path):
|
||||
global_favicons[indice].extend(filenames)
|
||||
|
||||
cookie_max_age = 60 * 60 * 24 * 365 * 23 # 23 years
|
||||
|
||||
|
@ -215,59 +215,7 @@ def index():
|
|||
if settings['server']['https_rewrite']\
|
||||
and result['parsed_url'].scheme == 'http':
|
||||
|
||||
skip_https_rewrite = False
|
||||
|
||||
# check if HTTPS rewrite is possible
|
||||
for target, rules, exclusions in https_rules:
|
||||
|
||||
# check if target regex match with url
|
||||
if target.match(result['url']):
|
||||
# process exclusions
|
||||
for exclusion in exclusions:
|
||||
# check if exclusion match with url
|
||||
if exclusion.match(result['url']):
|
||||
skip_https_rewrite = True
|
||||
break
|
||||
|
||||
# skip https rewrite if required
|
||||
if skip_https_rewrite:
|
||||
break
|
||||
|
||||
# process rules
|
||||
for rule in rules:
|
||||
try:
|
||||
# TODO, precompile rule
|
||||
p = re.compile(rule[0])
|
||||
|
||||
# rewrite url if possible
|
||||
new_result_url = p.sub(rule[1], result['url'])
|
||||
except:
|
||||
break
|
||||
|
||||
# parse new url
|
||||
new_parsed_url = urlparse(new_result_url)
|
||||
|
||||
# continiue if nothing was rewritten
|
||||
if result['url'] == new_result_url:
|
||||
continue
|
||||
|
||||
# get domainname from result
|
||||
# TODO, does only work correct with TLD's like
|
||||
# asdf.com, not for asdf.com.de
|
||||
# TODO, using publicsuffix instead of this rewrite rule
|
||||
old_result_domainname = '.'.join(
|
||||
result['parsed_url'].hostname.split('.')[-2:])
|
||||
new_result_domainname = '.'.join(
|
||||
new_parsed_url.hostname.split('.')[-2:])
|
||||
|
||||
# check if rewritten hostname is the same,
|
||||
# to protect against wrong or malicious rewrite rules
|
||||
if old_result_domainname == new_result_domainname:
|
||||
# set new url
|
||||
result['url'] = new_result_url
|
||||
|
||||
# target has matched, do not search over the other rules
|
||||
break
|
||||
result = https_url_rewrite(result)
|
||||
|
||||
if search.request_data.get('format', 'html') == 'html':
|
||||
if 'content' in result:
|
||||
|
@ -288,10 +236,6 @@ def index():
|
|||
else:
|
||||
result['pretty_url'] = result['url']
|
||||
|
||||
for engine in result['engines']:
|
||||
if engine in favicons:
|
||||
result['favicon'] = engine
|
||||
|
||||
# TODO, check if timezone is calculated right
|
||||
if 'publishedDate' in result:
|
||||
result['pubdate'] = result['publishedDate'].strftime('%Y-%m-%d %H:%M:%S%z')
|
||||
|
@ -344,7 +288,8 @@ def index():
|
|||
suggestions=search.suggestions,
|
||||
answers=search.answers,
|
||||
infoboxes=search.infoboxes,
|
||||
theme=get_current_theme_name()
|
||||
theme=get_current_theme_name(),
|
||||
favicons=global_favicons[themes.index(get_current_theme_name())]
|
||||
)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue