mirror of https://github.com/searx/searx
commit
d800e3fcfa
|
@ -0,0 +1,31 @@
|
|||
comment: false
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
# basic
|
||||
target: auto
|
||||
threshold: null
|
||||
base: auto
|
||||
# advanced
|
||||
branches: null
|
||||
if_no_uploads: error
|
||||
if_not_found: success
|
||||
if_ci_failed: error
|
||||
only_pulls: false
|
||||
flags: null
|
||||
paths: null
|
||||
patch:
|
||||
default:
|
||||
# basic
|
||||
target: auto
|
||||
threshold: null
|
||||
base: auto
|
||||
# advanced
|
||||
branches: null
|
||||
if_no_uploads: error
|
||||
if_not_found: success
|
||||
if_ci_failed: error
|
||||
only_pulls: false
|
||||
flags: null
|
||||
paths: null
|
|
@ -13,21 +13,21 @@ python:
|
|||
before_install:
|
||||
- "export DISPLAY=:99.0"
|
||||
- "sh -e /etc/init.d/xvfb start"
|
||||
- npm install less less-plugin-clean-css grunt-cli
|
||||
- npm install less@2.7 less-plugin-clean-css grunt-cli
|
||||
- export PATH=`pwd`/node_modules/.bin:$PATH
|
||||
- ./manage.sh install_geckodriver ~/drivers
|
||||
- export PATH=~/drivers:$PATH
|
||||
install:
|
||||
- ./manage.sh npm_packages
|
||||
- ./manage.sh update_dev_packages
|
||||
- pip install coveralls
|
||||
- pip install codecov
|
||||
script:
|
||||
- ./manage.sh styles
|
||||
- ./manage.sh grunt_build
|
||||
- ./manage.sh tests
|
||||
after_success:
|
||||
- ./manage.sh py_test_coverage
|
||||
- coveralls
|
||||
- codecov
|
||||
notifications:
|
||||
irc:
|
||||
channels:
|
||||
|
|
12
README.rst
12
README.rst
|
@ -9,7 +9,8 @@ instances <https://github.com/asciimoo/searx/wiki/Searx-instances>`__.
|
|||
|
||||
See the `documentation <https://asciimoo.github.io/searx>`__ and the `wiki <https://github.com/asciimoo/searx/wiki>`__ for more information.
|
||||
|
||||
|Flattr searx|
|
||||
|OpenCollective searx backers|
|
||||
|OpenCollective searx sponsors|
|
||||
|
||||
Installation
|
||||
~~~~~~~~~~~~
|
||||
|
@ -41,5 +42,10 @@ More about searx
|
|||
- `twitter <https://twitter.com/Searx_engine>`__
|
||||
- IRC: #searx @ freenode
|
||||
|
||||
.. |Flattr searx| image:: http://api.flattr.com/button/flattr-badge-large.png
|
||||
:target: https://flattr.com/submit/auto?user_id=asciimoo&url=https://github.com/asciimoo/searx&title=searx&language=&tags=github&category=software
|
||||
|
||||
.. |OpenCollective searx backers| image:: https://opencollective.com/searx/backers/badge.svg
|
||||
:target: https://opencollective.com/searx#backer
|
||||
|
||||
|
||||
.. |OpenCollective searx sponsors| image:: https://opencollective.com/searx/sponsors/badge.svg
|
||||
:target: https://opencollective.com/searx#sponsor
|
||||
|
|
74
manage.sh
74
manage.sh
|
@ -1,11 +1,11 @@
|
|||
#!/bin/sh
|
||||
|
||||
BASE_DIR=$(dirname "`readlink -f "$0"`")
|
||||
PYTHONPATH=$BASE_DIR
|
||||
BASE_DIR="$(dirname -- "`readlink -f -- "$0"`")"
|
||||
PYTHONPATH="$BASE_DIR"
|
||||
SEARX_DIR="$BASE_DIR/searx"
|
||||
ACTION=$1
|
||||
ACTION="$1"
|
||||
|
||||
cd "$BASE_DIR"
|
||||
cd -- "$BASE_DIR"
|
||||
|
||||
update_packages() {
|
||||
pip install --upgrade pip
|
||||
|
@ -22,40 +22,40 @@ install_geckodriver() {
|
|||
echo '[!] Checking geckodriver'
|
||||
# TODO : check the current geckodriver version
|
||||
set -e
|
||||
geckodriver -V 2>1 > /dev/null || NOTFOUND=1
|
||||
geckodriver -V > /dev/null 2>&1 || NOTFOUND=1
|
||||
set +e
|
||||
if [ -z $NOTFOUND ]; then
|
||||
return
|
||||
if [ -z "$NOTFOUND" ]; then
|
||||
return
|
||||
fi
|
||||
GECKODRIVER_VERSION="v0.18.0"
|
||||
PLATFORM=`python -c "import six; import platform; six.print_(platform.system().lower(), platform.architecture()[0])"`
|
||||
case $PLATFORM in
|
||||
"linux 32bit" | "linux2 32bit") ARCH="linux32";;
|
||||
"linux 64bit" | "linux2 64bit") ARCH="linux64";;
|
||||
"windows 32 bit") ARCH="win32";;
|
||||
"windows 64 bit") ARCH="win64";;
|
||||
"mac 64bit") ARCH="macos";;
|
||||
PLATFORM="`python -c "import six; import platform; six.print_(platform.system().lower(), platform.architecture()[0])"`"
|
||||
case "$PLATFORM" in
|
||||
"linux 32bit" | "linux2 32bit") ARCH="linux32";;
|
||||
"linux 64bit" | "linux2 64bit") ARCH="linux64";;
|
||||
"windows 32 bit") ARCH="win32";;
|
||||
"windows 64 bit") ARCH="win64";;
|
||||
"mac 64bit") ARCH="macos";;
|
||||
esac
|
||||
GECKODRIVER_URL="https://github.com/mozilla/geckodriver/releases/download/$GECKODRIVER_VERSION/geckodriver-$GECKODRIVER_VERSION-$ARCH.tar.gz";
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
if [ -z "$VIRTUAL_ENV" ]; then
|
||||
echo "geckodriver can't be installed because VIRTUAL_ENV is not set, you should download it from\n $GECKODRIVER_URL"
|
||||
exit
|
||||
else
|
||||
GECKODRIVER_DIR="$VIRTUAL_ENV/bin"
|
||||
fi
|
||||
if [ -z "$VIRTUAL_ENV" ]; then
|
||||
echo "geckodriver can't be installed because VIRTUAL_ENV is not set, you should download it from\n $GECKODRIVER_URL"
|
||||
exit
|
||||
else
|
||||
GECKODRIVER_DIR="$VIRTUAL_ENV/bin"
|
||||
fi
|
||||
else
|
||||
GECKODRIVER_DIR="$1"
|
||||
mkdir -p "$GECKODRIVER_DIR"
|
||||
GECKODRIVER_DIR="$1"
|
||||
mkdir -p -- "$GECKODRIVER_DIR"
|
||||
fi
|
||||
|
||||
echo "Installing $GECKODRIVER_DIR/geckodriver from\n $GECKODRIVER_URL"
|
||||
|
||||
FILE=`mktemp`
|
||||
wget "$GECKODRIVER_URL" -qO $FILE && tar xz -C "$GECKODRIVER_DIR" -f $FILE geckodriver
|
||||
rm $FILE
|
||||
chmod 777 "$GECKODRIVER_DIR/geckodriver"
|
||||
|
||||
FILE="`mktemp`"
|
||||
wget -qO "$FILE" -- "$GECKODRIVER_URL" && tar xz -C "$GECKODRIVER_DIR" -f "$FILE" geckodriver
|
||||
rm -- "$FILE"
|
||||
chmod 777 -- "$GECKODRIVER_DIR/geckodriver"
|
||||
}
|
||||
|
||||
pep8_check() {
|
||||
|
@ -73,14 +73,14 @@ unit_tests() {
|
|||
|
||||
py_test_coverage() {
|
||||
echo '[!] Running python test coverage'
|
||||
PYTHONPATH=`pwd` python -m nose2 -C --coverage "$SEARX_DIR" -s "$BASE_DIR/tests/unit"
|
||||
coverage report
|
||||
coverage html
|
||||
PYTHONPATH="`pwd`" python -m nose2 -C --log-capture --with-coverage --coverage "$SEARX_DIR" -s "$BASE_DIR/tests/unit" \
|
||||
&& coverage report \
|
||||
&& coverage html
|
||||
}
|
||||
|
||||
robot_tests() {
|
||||
echo '[!] Running robot tests'
|
||||
PYTHONPATH=`pwd` python "$SEARX_DIR/testing.py" robot
|
||||
PYTHONPATH="`pwd`" python "$SEARX_DIR/testing.py" robot
|
||||
}
|
||||
|
||||
tests() {
|
||||
|
@ -113,18 +113,18 @@ styles() {
|
|||
|
||||
npm_packages() {
|
||||
echo '[!] install NPM packages for oscar theme'
|
||||
cd $BASE_DIR/searx/static/themes/oscar
|
||||
cd -- "$BASE_DIR/searx/static/themes/oscar"
|
||||
npm install
|
||||
|
||||
echo '[!] install NPM packages for simple theme'
|
||||
cd $BASE_DIR/searx/static/themes/simple
|
||||
echo '[!] install NPM packages for simple theme'
|
||||
cd -- "$BASE_DIR/searx/static/themes/simple"
|
||||
npm install
|
||||
}
|
||||
|
||||
grunt_build() {
|
||||
echo '[!] Grunt build : oscar theme'
|
||||
grunt --gruntfile "$SEARX_DIR/static/themes/oscar/gruntfile.js"
|
||||
echo '[!] Grunt build : simple theme'
|
||||
echo '[!] Grunt build : simple theme'
|
||||
grunt --gruntfile "$SEARX_DIR/static/themes/simple/gruntfile.js"
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ locales() {
|
|||
}
|
||||
|
||||
help() {
|
||||
[ -z "$1" ] || printf "Error: $1\n"
|
||||
[ -z "$1" ] || printf 'Error: %s\n' "$1"
|
||||
echo "Searx manage.sh help
|
||||
|
||||
Commands
|
||||
|
@ -156,4 +156,4 @@ Commands
|
|||
|
||||
[ "$(command -V "$ACTION" | grep ' function$')" = "" ] \
|
||||
&& help "action not found" \
|
||||
|| $ACTION "$2"
|
||||
|| "$ACTION" "$2"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
babel==2.3.4
|
||||
mock==2.0.0
|
||||
nose2[coverage-plugin]
|
||||
cov-core==1.15.0
|
||||
pep8==1.7.0
|
||||
plone.testing==5.0.0
|
||||
splinter==0.7.5
|
||||
|
|
|
@ -7,4 +7,4 @@ pygments==2.1.3
|
|||
pyopenssl==17.2.0
|
||||
python-dateutil==2.6.1
|
||||
pyyaml==3.12
|
||||
requests[socks]==2.14.2
|
||||
requests[socks]==2.18.4
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -18,7 +18,6 @@
|
|||
from lxml import html
|
||||
from json import loads
|
||||
import re
|
||||
from searx.engines.bing import _fetch_supported_languages, supported_languages_url
|
||||
from searx.url_utils import urlencode
|
||||
|
||||
# engine dependent config
|
||||
|
@ -26,6 +25,8 @@ categories = ['images']
|
|||
paging = True
|
||||
safesearch = True
|
||||
time_range_support = True
|
||||
language_support = True
|
||||
supported_languages_url = 'https://www.bing.com/account/general'
|
||||
|
||||
# search-url
|
||||
base_url = 'https://www.bing.com/'
|
||||
|
@ -45,23 +46,41 @@ safesearch_types = {2: 'STRICT',
|
|||
_quote_keys_regex = re.compile('({|,)([a-z][a-z0-9]*):(")', re.I | re.U)
|
||||
|
||||
|
||||
# get supported region code
|
||||
def get_region_code(lang, lang_list=None):
|
||||
region = None
|
||||
if lang in (lang_list or supported_languages):
|
||||
region = lang
|
||||
elif lang.startswith('no'):
|
||||
region = 'nb-NO'
|
||||
else:
|
||||
# try to get a supported country code with language
|
||||
lang = lang.split('-')[0]
|
||||
for lc in (lang_list or supported_languages):
|
||||
if lang == lc.split('-')[0]:
|
||||
region = lc
|
||||
break
|
||||
if region:
|
||||
return region.lower()
|
||||
else:
|
||||
return 'en-us'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
offset = (params['pageno'] - 1) * 10 + 1
|
||||
|
||||
# required for cookie
|
||||
if params['language'] == 'all':
|
||||
language = 'en-US'
|
||||
else:
|
||||
language = params['language']
|
||||
|
||||
search_path = search_string.format(
|
||||
query=urlencode({'q': query}),
|
||||
offset=offset)
|
||||
|
||||
language = get_region_code(params['language'])
|
||||
|
||||
params['cookies']['SRCHHPGUSR'] = \
|
||||
'NEWWND=0&NRSLT=-1&SRCHLANG=' + language.split('-')[0] +\
|
||||
'&ADLT=' + safesearch_types.get(params['safesearch'], 'DEMOTE')
|
||||
'ADLT=' + safesearch_types.get(params['safesearch'], 'DEMOTE')
|
||||
|
||||
params['cookies']['_EDGE_S'] = 'mkt=' + language +\
|
||||
'&ui=' + language + '&F=1'
|
||||
|
||||
params['url'] = base_url + search_path
|
||||
if params['time_range'] in time_range_dict:
|
||||
|
@ -106,3 +125,22 @@ def response(resp):
|
|||
|
||||
# return results
|
||||
return results
|
||||
|
||||
|
||||
# get supported languages from their site
|
||||
def _fetch_supported_languages(resp):
|
||||
supported_languages = []
|
||||
dom = html.fromstring(resp.text)
|
||||
|
||||
regions_xpath = '//div[@id="region-section-content"]' \
|
||||
+ '//ul[@class="b_vList"]/li/a/@href'
|
||||
|
||||
regions = dom.xpath(regions_xpath)
|
||||
for region in regions:
|
||||
code = re.search('setmkt=[^\&]+', region).group()[7:]
|
||||
if code == 'nb-NO':
|
||||
code = 'no-NO'
|
||||
|
||||
supported_languages.append(code)
|
||||
|
||||
return supported_languages
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
from json import loads
|
||||
from lxml import html
|
||||
from searx.engines.bing_images import _fetch_supported_languages, supported_languages_url, get_region_code
|
||||
from searx.engines.xpath import extract_text
|
||||
from searx.url_utils import urlencode
|
||||
|
||||
|
@ -21,6 +22,7 @@ paging = True
|
|||
safesearch = True
|
||||
time_range_support = True
|
||||
number_of_results = 10
|
||||
language_support = True
|
||||
|
||||
search_url = 'https://www.bing.com/videos/asyncv2?{query}&async=content&'\
|
||||
'first={offset}&count={number_of_results}&CW=1366&CH=25&FORM=R5VR5'
|
||||
|
@ -45,7 +47,8 @@ def request(query, params):
|
|||
'ADLT=' + safesearch_types.get(params['safesearch'], 'DEMOTE')
|
||||
|
||||
# language cookie
|
||||
params['cookies']['_EDGE_S'] = 'mkt=' + params['language'].lower() + '&F=1'
|
||||
region = get_region_code(params['language'], lang_list=supported_languages)
|
||||
params['cookies']['_EDGE_S'] = 'mkt=' + region + '&F=1'
|
||||
|
||||
# query and paging
|
||||
params['url'] = search_url.format(query=urlencode({'q': query}),
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
"""
|
||||
Blekko (Images)
|
||||
|
||||
@website https://blekko.com
|
||||
@provide-api yes (inofficial)
|
||||
|
||||
@using-api yes
|
||||
@results JSON
|
||||
@stable yes
|
||||
@parse url, title, img_src
|
||||
"""
|
||||
|
||||
from json import loads
|
||||
from searx.url_utils import urlencode
|
||||
|
||||
# engine dependent config
|
||||
categories = ['images']
|
||||
paging = True
|
||||
safesearch = True
|
||||
|
||||
# search-url
|
||||
base_url = 'https://blekko.com'
|
||||
search_url = '/api/images?{query}&c={c}'
|
||||
|
||||
# safesearch definitions
|
||||
safesearch_types = {2: '1',
|
||||
1: '',
|
||||
0: '0'}
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
c = (params['pageno'] - 1) * 48
|
||||
|
||||
params['url'] = base_url +\
|
||||
search_url.format(query=urlencode({'q': query}),
|
||||
c=c)
|
||||
|
||||
if params['pageno'] != 1:
|
||||
params['url'] += '&page={pageno}'.format(pageno=(params['pageno'] - 1))
|
||||
|
||||
# let Blekko know we wan't have profiling
|
||||
params['cookies']['tag_lesslogging'] = '1'
|
||||
|
||||
# parse safesearch argument
|
||||
params['cookies']['safesearch'] = safesearch_types.get(params['safesearch'], '')
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
search_results = loads(resp.text)
|
||||
|
||||
# return empty array if there are no results
|
||||
if not search_results:
|
||||
return []
|
||||
|
||||
for result in search_results:
|
||||
# append result
|
||||
results.append({'url': result['page_url'],
|
||||
'title': result['title'],
|
||||
'content': '',
|
||||
'img_src': result['url'],
|
||||
'template': 'images.html'})
|
||||
|
||||
# return results
|
||||
return results
|
|
@ -10,6 +10,8 @@
|
|||
@parse url, title, content, publishedDate, thumbnail
|
||||
"""
|
||||
|
||||
import random
|
||||
import string
|
||||
from dateutil import parser
|
||||
from json import loads
|
||||
from lxml import html
|
||||
|
@ -30,12 +32,17 @@ title_xpath = './/h2//a//text()'
|
|||
content_xpath = './/p//text()'
|
||||
pubdate_xpath = './/time'
|
||||
|
||||
digg_cookie_chars = string.ascii_uppercase + string.ascii_lowercase +\
|
||||
string.digits + "+_"
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
offset = (params['pageno'] - 1) * 10
|
||||
params['url'] = search_url.format(position=offset,
|
||||
query=quote_plus(query))
|
||||
params['cookies']['frontend.auid'] = ''.join(random.choice(
|
||||
digg_cookie_chars) for _ in range(22))
|
||||
return params
|
||||
|
||||
|
||||
|
|
|
@ -134,4 +134,4 @@ def _fetch_supported_languages(resp):
|
|||
regions_json = loads(response_page)
|
||||
supported_languages = map((lambda x: x[3:] + '-' + x[:2].upper()), regions_json.keys())
|
||||
|
||||
return supported_languages
|
||||
return list(supported_languages)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
@website http://www.faroo.com
|
||||
@provide-api yes (http://www.faroo.com/hp/api/api.html), require API-key
|
||||
|
||||
@using-api yes
|
||||
@using-api no
|
||||
@results JSON
|
||||
@stable yes
|
||||
@parse url, title, content, publishedDate, img_src
|
||||
|
@ -20,18 +20,16 @@ categories = ['general', 'news']
|
|||
paging = True
|
||||
language_support = True
|
||||
number_of_results = 10
|
||||
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}' # noqa
|
||||
search_url = url + 'instant.json?{query}'\
|
||||
'&start={offset}'\
|
||||
'&length={number_of_results}'\
|
||||
'&l={language}'\
|
||||
'&src={categorie}'\
|
||||
'&i=false'\
|
||||
'&c=false'
|
||||
|
||||
search_category = {'general': 'web',
|
||||
'news': 'news'}
|
||||
|
@ -57,21 +55,15 @@ def request(query, params):
|
|||
number_of_results=number_of_results,
|
||||
query=urlencode({'q': query}),
|
||||
language=language,
|
||||
categorie=categorie,
|
||||
api_key=api_key)
|
||||
categorie=categorie)
|
||||
|
||||
# using searx User-Agent
|
||||
params['headers']['User-Agent'] = searx_useragent()
|
||||
params['headers']['Referer'] = url
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
# HTTP-Code 401: api-key is not valide
|
||||
if resp.status_code == 401:
|
||||
raise Exception("API key is not valide")
|
||||
|
||||
# HTTP-Code 429: rate limit exceeded
|
||||
if resp.status_code == 429:
|
||||
raise Exception("rate limit has been exceeded!")
|
||||
|
@ -86,31 +78,19 @@ def response(resp):
|
|||
|
||||
# parse results
|
||||
for result in search_res['results']:
|
||||
publishedDate = None
|
||||
result_json = {'url': result['url'], 'title': result['title'],
|
||||
'content': result['kwic']}
|
||||
if result['news']:
|
||||
# timestamp (milliseconds since 1970)
|
||||
publishedDate = datetime.datetime.fromtimestamp(result['date'] / 1000.0) # noqa
|
||||
|
||||
# append news result
|
||||
results.append({'url': result['url'],
|
||||
'title': result['title'],
|
||||
'publishedDate': publishedDate,
|
||||
'content': result['kwic']})
|
||||
|
||||
else:
|
||||
# append general result
|
||||
# TODO, publishedDate correct?
|
||||
results.append({'url': result['url'],
|
||||
'title': result['title'],
|
||||
'content': result['kwic']})
|
||||
result_json['publishedDate'] = \
|
||||
datetime.datetime.fromtimestamp(result['date'] / 1000.0)
|
||||
|
||||
# append image result if image url is set
|
||||
# TODO, show results with an image like in faroo
|
||||
if result['iurl']:
|
||||
results.append({'template': 'images.html',
|
||||
'url': result['url'],
|
||||
'title': result['title'],
|
||||
'content': result['kwic'],
|
||||
'img_src': result['iurl']})
|
||||
result_json['template'] = 'videos.html'
|
||||
result_json['thumbnail'] = result['iurl']
|
||||
|
||||
results.append(result_json)
|
||||
|
||||
# return results
|
||||
return results
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
"""
|
||||
General Files (Files)
|
||||
|
||||
@website http://www.general-files.org
|
||||
@provide-api no (nothing found)
|
||||
|
||||
@using-api no (because nothing found)
|
||||
@results HTML (using search portal)
|
||||
@stable no (HTML can change)
|
||||
@parse url, title, content
|
||||
|
||||
@todo detect torrents?
|
||||
"""
|
||||
|
||||
from lxml import html
|
||||
|
||||
# engine dependent config
|
||||
categories = ['files']
|
||||
paging = True
|
||||
|
||||
# search-url
|
||||
base_url = 'http://www.general-file.com'
|
||||
search_url = base_url + '/files-{letter}/{query}/{pageno}'
|
||||
|
||||
# specific xpath variables
|
||||
result_xpath = '//table[@class="block-file"]'
|
||||
title_xpath = './/h2/a//text()'
|
||||
url_xpath = './/h2/a/@href'
|
||||
content_xpath = './/p//text()'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
|
||||
params['url'] = search_url.format(query=query,
|
||||
letter=query[0],
|
||||
pageno=params['pageno'])
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
dom = html.fromstring(resp.text)
|
||||
|
||||
# parse results
|
||||
for result in dom.xpath(result_xpath):
|
||||
url = result.xpath(url_xpath)[0]
|
||||
|
||||
# skip fast download links
|
||||
if not url.startswith('/'):
|
||||
continue
|
||||
|
||||
# append result
|
||||
results.append({'url': base_url + url,
|
||||
'title': ''.join(result.xpath(title_xpath)),
|
||||
'content': ''.join(result.xpath(content_xpath))})
|
||||
|
||||
# return results
|
||||
return results
|
|
@ -10,6 +10,7 @@
|
|||
@parse url, title, content
|
||||
"""
|
||||
|
||||
import random
|
||||
from json import loads
|
||||
from time import time
|
||||
from lxml.html import fromstring
|
||||
|
@ -32,7 +33,8 @@ search_string = 'search?{query}'\
|
|||
'&qh=0'\
|
||||
'&qlang={lang}'\
|
||||
'&ff={safesearch}'\
|
||||
'&rxikd={rxikd}' # random number - 9 digits
|
||||
'&rxieu={rxieu}'\
|
||||
'&rand={rxikd}' # current unix timestamp
|
||||
|
||||
# specific xpath variables
|
||||
results_xpath = '//response//result'
|
||||
|
@ -59,10 +61,12 @@ def request(query, params):
|
|||
else:
|
||||
safesearch = 0
|
||||
|
||||
# rxieu is some kind of hash from the search query, but accepts random atm
|
||||
search_path = search_string.format(query=urlencode({'q': query}),
|
||||
offset=offset,
|
||||
number_of_results=number_of_results,
|
||||
rxikd=str(time())[:9],
|
||||
rxikd=int(time() * 1000),
|
||||
rxieu=random.randint(1000000000, 9999999999),
|
||||
lang=language,
|
||||
safesearch=safesearch)
|
||||
|
||||
|
|
|
@ -67,8 +67,8 @@ def response(resp):
|
|||
for result in dom.xpath('//div[@class="g"]|//div[@class="g _cy"]'):
|
||||
try:
|
||||
r = {
|
||||
'url': result.xpath('.//div[@class="_cnc"]//a/@href')[0],
|
||||
'title': ''.join(result.xpath('.//div[@class="_cnc"]//h3//text()')),
|
||||
'url': result.xpath('.//a[@class="l _PMs"]')[0].attrib.get("href"),
|
||||
'title': ''.join(result.xpath('.//a[@class="l _PMs"]//text()')),
|
||||
'content': ''.join(result.xpath('.//div[@class="st"]//text()')),
|
||||
}
|
||||
except:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
Nyaa.se (Anime Bittorrent tracker)
|
||||
Nyaa.si (Anime Bittorrent tracker)
|
||||
|
||||
@website http://www.nyaa.se/
|
||||
@website http://www.nyaa.si/
|
||||
@provide-api no
|
||||
@using-api no
|
||||
@results HTML
|
||||
|
@ -12,50 +12,25 @@
|
|||
from lxml import html
|
||||
from searx.engines.xpath import extract_text
|
||||
from searx.url_utils import urlencode
|
||||
from searx.utils import get_torrent_size, int_or_zero
|
||||
|
||||
# engine dependent config
|
||||
categories = ['files', 'images', 'videos', 'music']
|
||||
paging = True
|
||||
|
||||
# search-url
|
||||
base_url = 'http://www.nyaa.se/'
|
||||
base_url = 'http://www.nyaa.si/'
|
||||
search_url = base_url + '?page=search&{query}&offset={offset}'
|
||||
|
||||
# xpath queries
|
||||
xpath_results = '//table[@class="tlist"]//tr[contains(@class, "tlistrow")]'
|
||||
xpath_category = './/td[@class="tlisticon"]/a'
|
||||
xpath_title = './/td[@class="tlistname"]/a'
|
||||
xpath_torrent_file = './/td[@class="tlistdownload"]/a'
|
||||
xpath_filesize = './/td[@class="tlistsize"]/text()'
|
||||
xpath_seeds = './/td[@class="tlistsn"]/text()'
|
||||
xpath_leeches = './/td[@class="tlistln"]/text()'
|
||||
xpath_downloads = './/td[@class="tlistdn"]/text()'
|
||||
|
||||
|
||||
# convert a variable to integer or return 0 if it's not a number
|
||||
def int_or_zero(num):
|
||||
if isinstance(num, list):
|
||||
if len(num) < 1:
|
||||
return 0
|
||||
num = num[0]
|
||||
if num.isdigit():
|
||||
return int(num)
|
||||
return 0
|
||||
|
||||
|
||||
# get multiplier to convert torrent size to bytes
|
||||
def get_filesize_mul(suffix):
|
||||
return {
|
||||
'KB': 1024,
|
||||
'MB': 1024 ** 2,
|
||||
'GB': 1024 ** 3,
|
||||
'TB': 1024 ** 4,
|
||||
|
||||
'KIB': 1024,
|
||||
'MIB': 1024 ** 2,
|
||||
'GIB': 1024 ** 3,
|
||||
'TIB': 1024 ** 4
|
||||
}[str(suffix).upper()]
|
||||
xpath_results = '//table[contains(@class, "torrent-list")]//tr[not(th)]'
|
||||
xpath_category = './/td[1]/a[1]'
|
||||
xpath_title = './/td[2]/a[last()]'
|
||||
xpath_torrent_links = './/td[3]/a'
|
||||
xpath_filesize = './/td[4]/text()'
|
||||
xpath_seeds = './/td[6]/text()'
|
||||
xpath_leeches = './/td[7]/text()'
|
||||
xpath_downloads = './/td[8]/text()'
|
||||
|
||||
|
||||
# do search-request
|
||||
|
@ -72,25 +47,32 @@ def response(resp):
|
|||
dom = html.fromstring(resp.text)
|
||||
|
||||
for result in dom.xpath(xpath_results):
|
||||
# defaults
|
||||
filesize = 0
|
||||
magnet_link = ""
|
||||
torrent_link = ""
|
||||
|
||||
# category in which our torrent belongs
|
||||
category = result.xpath(xpath_category)[0].attrib.get('title')
|
||||
try:
|
||||
category = result.xpath(xpath_category)[0].attrib.get('title')
|
||||
except:
|
||||
pass
|
||||
|
||||
# torrent title
|
||||
page_a = result.xpath(xpath_title)[0]
|
||||
title = extract_text(page_a)
|
||||
|
||||
# link to the page
|
||||
href = page_a.attrib.get('href')
|
||||
href = base_url + page_a.attrib.get('href')
|
||||
|
||||
# link to the torrent file
|
||||
torrent_link = result.xpath(xpath_torrent_file)[0].attrib.get('href')
|
||||
|
||||
# torrent size
|
||||
try:
|
||||
file_size, suffix = result.xpath(xpath_filesize)[0].split(' ')
|
||||
file_size = int(float(file_size) * get_filesize_mul(suffix))
|
||||
except:
|
||||
file_size = None
|
||||
for link in result.xpath(xpath_torrent_links):
|
||||
url = link.attrib.get('href')
|
||||
if 'magnet' in url:
|
||||
# link to the magnet
|
||||
magnet_link = url
|
||||
else:
|
||||
# link to the torrent file
|
||||
torrent_link = url
|
||||
|
||||
# seed count
|
||||
seed = int_or_zero(result.xpath(xpath_seeds))
|
||||
|
@ -101,6 +83,14 @@ def response(resp):
|
|||
# torrent downloads count
|
||||
downloads = int_or_zero(result.xpath(xpath_downloads))
|
||||
|
||||
# let's try to calculate the torrent size
|
||||
try:
|
||||
filesize_info = result.xpath(xpath_filesize)[0]
|
||||
filesize, filesize_multiplier = filesize_info.split()
|
||||
filesize = get_torrent_size(filesize, filesize_multiplier)
|
||||
except:
|
||||
pass
|
||||
|
||||
# content string contains all information not included into template
|
||||
content = 'Category: "{category}". Downloaded {downloads} times.'
|
||||
content = content.format(category=category, downloads=downloads)
|
||||
|
@ -110,8 +100,9 @@ def response(resp):
|
|||
'content': content,
|
||||
'seed': seed,
|
||||
'leech': leech,
|
||||
'filesize': file_size,
|
||||
'filesize': filesize,
|
||||
'torrentfile': torrent_link,
|
||||
'magnetlink': magnet_link,
|
||||
'template': 'torrent.html'})
|
||||
|
||||
return results
|
||||
|
|
|
@ -118,7 +118,7 @@ def _fetch_supported_languages(resp):
|
|||
dom = fromstring(resp.text)
|
||||
options = dom.xpath('//div[@id="regions-popup"]//ul/li/a')
|
||||
for option in options:
|
||||
code = option.xpath('./@data-val')[0]
|
||||
code = option.xpath('./@data-search-language')[0]
|
||||
if code.startswith('nb-'):
|
||||
code = code.replace('nb', 'no', 1)
|
||||
supported_languages.append(code)
|
||||
|
|
|
@ -14,8 +14,8 @@ import re
|
|||
from lxml import html
|
||||
from searx.engines.xpath import extract_text
|
||||
from datetime import datetime
|
||||
from searx.engines.nyaa import int_or_zero, get_filesize_mul
|
||||
from searx.url_utils import urlencode
|
||||
from searx.utils import get_torrent_size, int_or_zero
|
||||
|
||||
# engine dependent config
|
||||
categories = ['files', 'videos', 'music']
|
||||
|
@ -76,8 +76,7 @@ def response(resp):
|
|||
try:
|
||||
# ('1.228', 'GB')
|
||||
groups = size_re.match(item).groups()
|
||||
multiplier = get_filesize_mul(groups[1])
|
||||
params['filesize'] = int(multiplier * float(groups[0]))
|
||||
params['filesize'] = get_torrent_size(groups[0], groups[1])
|
||||
except:
|
||||
pass
|
||||
elif item.startswith('Date:'):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
Torrentz.eu (BitTorrent meta-search engine)
|
||||
Torrentz2.eu (BitTorrent meta-search engine)
|
||||
|
||||
@website https://torrentz.eu/
|
||||
@website https://torrentz2.eu/
|
||||
@provide-api no
|
||||
|
||||
@using-api no
|
||||
|
@ -14,24 +14,24 @@
|
|||
import re
|
||||
from lxml import html
|
||||
from datetime import datetime
|
||||
from searx.engines.nyaa import int_or_zero, get_filesize_mul
|
||||
from searx.engines.xpath import extract_text
|
||||
from searx.url_utils import urlencode
|
||||
from searx.utils import get_torrent_size
|
||||
|
||||
# engine dependent config
|
||||
categories = ['files', 'videos', 'music']
|
||||
paging = True
|
||||
|
||||
# search-url
|
||||
# https://torrentz.eu/search?f=EXAMPLE&p=6
|
||||
base_url = 'https://torrentz.eu/'
|
||||
# https://torrentz2.eu/search?f=EXAMPLE&p=6
|
||||
base_url = 'https://torrentz2.eu/'
|
||||
search_url = base_url + 'search?{query}'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
page = params['pageno'] - 1
|
||||
query = urlencode({'q': query, 'p': page})
|
||||
query = urlencode({'f': query, 'p': page})
|
||||
params['url'] = search_url.format(query=query)
|
||||
return params
|
||||
|
||||
|
@ -54,22 +54,29 @@ def response(resp):
|
|||
# extract url and remove a slash in the beginning
|
||||
link = links[0].attrib.get('href').lstrip('/')
|
||||
|
||||
seed = result.xpath('./dd/span[@class="u"]/text()')[0].replace(',', '')
|
||||
leech = result.xpath('./dd/span[@class="d"]/text()')[0].replace(',', '')
|
||||
seed = 0
|
||||
leech = 0
|
||||
try:
|
||||
seed = int(result.xpath('./dd/span[4]/text()')[0].replace(',', ''))
|
||||
leech = int(result.xpath('./dd/span[5]/text()')[0].replace(',', ''))
|
||||
except:
|
||||
pass
|
||||
|
||||
params = {
|
||||
'url': base_url + link,
|
||||
'title': title,
|
||||
'seed': int_or_zero(seed),
|
||||
'leech': int_or_zero(leech),
|
||||
'seed': seed,
|
||||
'leech': leech,
|
||||
'template': 'torrent.html'
|
||||
}
|
||||
|
||||
# let's try to calculate the torrent size
|
||||
try:
|
||||
size_str = result.xpath('./dd/span[@class="s"]/text()')[0]
|
||||
size, suffix = size_str.split()
|
||||
params['filesize'] = int(size) * get_filesize_mul(suffix)
|
||||
filesize_info = result.xpath('./dd/span[3]/text()')[0]
|
||||
filesize, filesize_multiplier = filesize_info.split()
|
||||
filesize = get_torrent_size(filesize, filesize_multiplier)
|
||||
|
||||
params['filesize'] = filesize
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -80,9 +87,8 @@ def response(resp):
|
|||
|
||||
# extract and convert creation date
|
||||
try:
|
||||
date_str = result.xpath('./dd/span[@class="a"]/span')[0].attrib.get('title')
|
||||
# Fri, 25 Mar 2016 16:29:01
|
||||
date = datetime.strptime(date_str, '%a, %d %b %Y %H:%M:%S')
|
||||
date_ts = result.xpath('./dd/span[2]')[0].attrib.get('title')
|
||||
date = datetime.fromtimestamp(float(date_ts))
|
||||
params['publishedDate'] = date
|
||||
except:
|
||||
pass
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
language_codes = (
|
||||
(u"ar-SA", u"العربية", u"", u"Arabic"),
|
||||
(u"bg-BG", u"Български", u"", u"Bulgarian"),
|
||||
(u"ca", u"Català", u"", u"Catalan"),
|
||||
(u"ca-AD", u"Català", u"Andorra", u"Catalan"),
|
||||
(u"ca-CT", u"Català", u"", u"Catalan"),
|
||||
(u"ca-ES", u"Català", u"Espanya", u"Catalan"),
|
||||
(u"ca-FR", u"Català", u"França", u"Catalan"),
|
||||
(u"cs-CZ", u"Čeština", u"", u"Czech"),
|
||||
(u"da-DK", u"Dansk", u"", u"Danish"),
|
||||
(u"de", u"Deutsch", u"", u"German"),
|
||||
|
@ -15,9 +20,7 @@ language_codes = (
|
|||
(u"en", u"English", u"", u"English"),
|
||||
(u"en-AU", u"English", u"Australia", u"English"),
|
||||
(u"en-CA", u"English", u"Canada", u"English"),
|
||||
(u"en-CY", u"English", u"Cyprus", u"English"),
|
||||
(u"en-GB", u"English", u"United Kingdom", u"English"),
|
||||
(u"en-GD", u"English", u"Grenada", u"English"),
|
||||
(u"en-ID", u"English", u"Indonesia", u"English"),
|
||||
(u"en-IE", u"English", u"Ireland", u"English"),
|
||||
(u"en-IN", u"English", u"India", u"English"),
|
||||
|
@ -28,6 +31,7 @@ language_codes = (
|
|||
(u"en-US", u"English", u"United States", u"English"),
|
||||
(u"en-ZA", u"English", u"South Africa", u"English"),
|
||||
(u"es", u"Español", u"", u"Spanish"),
|
||||
(u"es-AD", u"Español", u"Andorra", u"Spanish"),
|
||||
(u"es-AR", u"Español", u"Argentina", u"Spanish"),
|
||||
(u"es-CL", u"Español", u"Chile", u"Spanish"),
|
||||
(u"es-CO", u"Español", u"Colombia", u"Spanish"),
|
||||
|
@ -38,38 +42,32 @@ language_codes = (
|
|||
(u"et-EE", u"Eesti", u"", u"Estonian"),
|
||||
(u"fi-FI", u"Suomi", u"", u"Finnish"),
|
||||
(u"fr", u"Français", u"", u"French"),
|
||||
(u"fr-AD", u"Français", u"Andorre", u"French"),
|
||||
(u"fr-BE", u"Français", u"Belgique", u"French"),
|
||||
(u"fr-CA", u"Français", u"Canada", u"French"),
|
||||
(u"fr-CH", u"Français", u"Suisse", u"French"),
|
||||
(u"fr-FR", u"Français", u"France", u"French"),
|
||||
(u"he-IL", u"עברית", u"", u"Hebrew"),
|
||||
(u"hr-HR", u"Hrvatski", u"", u"Croatian"),
|
||||
(u"hu-HU", u"Magyar", u"", u"Hungarian"),
|
||||
(u"id-ID", u"Bahasa Indonesia", u"", u"Indonesian"),
|
||||
(u"it", u"Italiano", u"", u"Italian"),
|
||||
(u"it-CH", u"Italiano", u"Svizzera", u"Italian"),
|
||||
(u"it-IT", u"Italiano", u"Italia", u"Italian"),
|
||||
(u"ja-JP", u"日本語", u"", u"Japanese"),
|
||||
(u"ko-KR", u"한국어", u"", u"Korean"),
|
||||
(u"lt-LT", u"Lietuvių", u"", u"Lithuanian"),
|
||||
(u"lv-LV", u"Latviešu", u"", u"Latvian"),
|
||||
(u"ms-MY", u"Bahasa Melayu", u"", u"Malay"),
|
||||
(u"nl", u"Nederlands", u"", u"Dutch"),
|
||||
(u"nl-BE", u"Nederlands", u"België", u"Dutch"),
|
||||
(u"nl-NL", u"Nederlands", u"Nederland", u"Dutch"),
|
||||
(u"no-NO", u"Norsk", u"", u"Norwegian"),
|
||||
(u"pl-PL", u"Polski", u"", u"Polish"),
|
||||
(u"pt", u"Português", u"", u"Portuguese"),
|
||||
(u"pt-AD", u"Português", u"Andorra", u"Portuguese"),
|
||||
(u"pt-BR", u"Português", u"Brasil", u"Portuguese"),
|
||||
(u"pt-PT", u"Português", u"Portugal", u"Portuguese"),
|
||||
(u"ro-RO", u"Română", u"", u"Romanian"),
|
||||
(u"ru-RU", u"Русский", u"", u"Russian"),
|
||||
(u"sk-SK", u"Slovenčina", u"", u"Slovak"),
|
||||
(u"sl", u"Slovenščina", u"", u"Slovenian"),
|
||||
(u"sv-SE", u"Svenska", u"", u"Swedish"),
|
||||
(u"th-TH", u"ไทย", u"", u"Thai"),
|
||||
(u"tr-TR", u"Türkçe", u"", u"Turkish"),
|
||||
(u"vi-VN", u"Tiếng Việt", u"", u"Vietnamese"),
|
||||
(u"zh", u"中文", u"", u"Chinese"),
|
||||
(u"zh-CN", u"中文", u"中国", u"Chinese"),
|
||||
(u"zh-HK", u"中文", u"香港", u"Chinese"),
|
||||
|
|
|
@ -189,11 +189,10 @@ engines:
|
|||
shortcut : et
|
||||
disabled : True
|
||||
|
||||
# api-key required: http://www.faroo.com/hp/api/api.html#key
|
||||
# - name : faroo
|
||||
# engine : faroo
|
||||
# shortcut : fa
|
||||
# api_key : 'apikey' # required!
|
||||
- name : faroo
|
||||
engine : faroo
|
||||
shortcut : fa
|
||||
disabled : True
|
||||
|
||||
- name : 500px
|
||||
engine : www500px
|
||||
|
@ -247,15 +246,16 @@ engines:
|
|||
disabled: True
|
||||
|
||||
- name : gitlab
|
||||
engine : xpath
|
||||
engine : json_engine
|
||||
paging : True
|
||||
search_url : https://gitlab.com/search?page={pageno}&search={query}
|
||||
url_xpath : //li[@class="project-row"]//a[@class="project"]/@href
|
||||
title_xpath : //li[@class="project-row"]//span[contains(@class, "project-full-name")]
|
||||
content_xpath : //li[@class="project-row"]//div[@class="description"]/p
|
||||
search_url : https://gitlab.com/api/v4/projects?search={query}&page={pageno}
|
||||
url_query : web_url
|
||||
title_query : name_with_namespace
|
||||
content_query : description
|
||||
page_size : 20
|
||||
categories : it
|
||||
shortcut : gl
|
||||
timeout : 5.0
|
||||
timeout : 10.0
|
||||
disabled : True
|
||||
|
||||
- name : github
|
||||
|
@ -326,9 +326,9 @@ engines:
|
|||
engine : xpath
|
||||
paging : True
|
||||
search_url : https://geektimes.ru/search/page{pageno}/?q={query}
|
||||
url_xpath : //div[@class="search_results"]//a[@class="post__title_link"]/@href
|
||||
title_xpath : //div[@class="search_results"]//a[@class="post__title_link"]
|
||||
content_xpath : //div[@class="search_results"]//div[contains(@class, "content")]
|
||||
url_xpath : //article[contains(@class, "post")]//a[@class="post__title_link"]/@href
|
||||
title_xpath : //article[contains(@class, "post")]//a[@class="post__title_link"]
|
||||
content_xpath : //article[contains(@class, "post")]//div[contains(@class, "post__text")]
|
||||
categories : it
|
||||
timeout : 4.0
|
||||
disabled : True
|
||||
|
@ -338,9 +338,9 @@ engines:
|
|||
engine : xpath
|
||||
paging : True
|
||||
search_url : https://habrahabr.ru/search/page{pageno}/?q={query}
|
||||
url_xpath : //div[@class="search_results"]//a[contains(@class, "post__title_link")]/@href
|
||||
title_xpath : //div[@class="search_results"]//a[contains(@class, "post__title_link")]
|
||||
content_xpath : //div[@class="search_results"]//div[contains(@class, "content")]
|
||||
url_xpath : //article[contains(@class, "post")]//a[@class="post__title_link"]/@href
|
||||
title_xpath : //article[contains(@class, "post")]//a[@class="post__title_link"]
|
||||
content_xpath : //article[contains(@class, "post")]//div[contains(@class, "post__text")]
|
||||
categories : it
|
||||
timeout : 4.0
|
||||
disabled : True
|
||||
|
@ -556,6 +556,12 @@ engines:
|
|||
timeout : 6.0
|
||||
disabled : True
|
||||
|
||||
- name : torrentz
|
||||
engine : torrentz
|
||||
shortcut : tor
|
||||
url: https://torrentz2.eu/
|
||||
timeout : 3.0
|
||||
|
||||
- name : twitter
|
||||
engine : twitter
|
||||
shortcut : tw
|
||||
|
@ -579,6 +585,7 @@ engines:
|
|||
- name : yahoo
|
||||
engine : yahoo
|
||||
shortcut : yh
|
||||
disabled : True
|
||||
|
||||
- name : yandex
|
||||
engine : yandex
|
||||
|
@ -639,10 +646,10 @@ engines:
|
|||
engine: xpath
|
||||
shortcut: vo
|
||||
categories: social media
|
||||
search_url : https://voat.co/search?q={query}
|
||||
url_xpath : //p[contains(@class, "title")]/a/@href
|
||||
title_xpath : //p[contains(@class, "title")]/a
|
||||
content_xpath : //span[@class="domain"]
|
||||
search_url : https://searchvoat.co/?t={query}
|
||||
url_xpath : //div[@class="entry"]/p/a[@class="title"]/@href
|
||||
title_xpath : //div[@class="entry"]/p/a[@class="title"]
|
||||
content_xpath : //div[@class="entry"]/p/span[@class="domain"]
|
||||
timeout : 10.0
|
||||
disabled : True
|
||||
|
||||
|
@ -651,12 +658,6 @@ engines:
|
|||
shortcut : 1337x
|
||||
disabled : True
|
||||
|
||||
#The blekko technology and team have joined IBM Watson! -> https://blekko.com/
|
||||
# - name : blekko images
|
||||
# engine : blekko_images
|
||||
# locale : en-US
|
||||
# shortcut : bli
|
||||
|
||||
# - name : yacy
|
||||
# engine : yacy
|
||||
# shortcut : ya
|
||||
|
@ -676,7 +677,6 @@ locales:
|
|||
bg : Български (Bulgarian)
|
||||
cs : Čeština (Czech)
|
||||
de : Deutsch (German)
|
||||
de_DE : Deutsch (German_Germany)
|
||||
el_GR : Ελληνικά (Greek_Greece)
|
||||
eo : Esperanto (Esperanto)
|
||||
es : Español (Spanish)
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,2 +1,2 @@
|
|||
/*! oscar/searx.min.js | 25-07-2016 | https://github.com/asciimoo/searx */
|
||||
/*! oscar/searx.min.js | 06-10-2017 | https://github.com/asciimoo/searx */
|
||||
requirejs.config({baseUrl:"./static/themes/oscar/js",paths:{app:"../app"}}),searx.autocompleter&&(searx.searchResults=new Bloodhound({datumTokenizer:Bloodhound.tokenizers.obj.whitespace("value"),queryTokenizer:Bloodhound.tokenizers.whitespace,remote:"./autocompleter?q=%QUERY"}),searx.searchResults.initialize()),$(document).ready(function(){searx.autocompleter&&$("#q").typeahead(null,{name:"search-results",displayKey:function(a){return a},source:searx.searchResults.ttAdapter()})}),$(document).ready(function(){$("#q.autofocus").focus(),$(".select-all-on-click").click(function(){$(this).select()}),$(".btn-collapse").click(function(){var a=$(this).data("btn-text-collapsed"),b=$(this).data("btn-text-not-collapsed");""!==a&&""!==b&&($(this).hasClass("collapsed")?new_html=$(this).html().replace(a,b):new_html=$(this).html().replace(b,a),$(this).html(new_html))}),$(".btn-toggle .btn").click(function(){var a="btn-"+$(this).data("btn-class"),b=$(this).data("btn-label-default"),c=$(this).data("btn-label-toggled");""!==c&&($(this).hasClass("btn-default")?new_html=$(this).html().replace(b,c):new_html=$(this).html().replace(c,b),$(this).html(new_html)),$(this).toggleClass(a),$(this).toggleClass("btn-default")}),$(".media-loader").click(function(){var a=$(this).data("target"),b=$(a+" > iframe"),c=b.attr("src");void 0!==c&&c!==!1||b.attr("src",b.data("src"))}),$(".btn-sm").dblclick(function(){var a="btn-"+$(this).data("btn-class");$(this).hasClass("btn-default")?($(".btn-sm > input").attr("checked","checked"),$(".btn-sm > input").prop("checked",!0),$(".btn-sm").addClass(a),$(".btn-sm").addClass("active"),$(".btn-sm").removeClass("btn-default")):($(".btn-sm > input").attr("checked",""),$(".btn-sm > input").removeAttr("checked"),$(".btn-sm > input").checked=!1,$(".btn-sm").removeClass(a),$(".btn-sm").removeClass("active"),$(".btn-sm").addClass("btn-default"))})}),$(document).ready(function(){$(".searx_overpass_request").on("click",function(a){var b="https://overpass-api.de/api/interpreter?data=",c=b+"[out:json][timeout:25];(",d=");out meta;",e=$(this).data("osm-id"),f=$(this).data("osm-type"),g=$(this).data("result-table"),h="#"+$(this).data("result-table-loadicon"),i=["addr:city","addr:country","addr:housenumber","addr:postcode","addr:street"];if(e&&f&&g){g="#"+g;var j=null;switch(f){case"node":j=c+"node("+e+");"+d;break;case"way":j=c+"way("+e+");"+d;break;case"relation":j=c+"relation("+e+");"+d}if(j){$.ajax(j).done(function(a){if(a&&a.elements&&a.elements[0]){var b=a.elements[0],c=$(g).html();for(var d in b.tags)if(null===b.tags.name||i.indexOf(d)==-1){switch(c+="<tr><td>"+d+"</td><td>",d){case"phone":case"fax":c+='<a href="tel:'+b.tags[d].replace(/ /g,"")+'">'+b.tags[d]+"</a>";break;case"email":c+='<a href="mailto:'+b.tags[d]+'">'+b.tags[d]+"</a>";break;case"website":case"url":c+='<a href="'+b.tags[d]+'">'+b.tags[d]+"</a>";break;case"wikidata":c+='<a href="https://www.wikidata.org/wiki/'+b.tags[d]+'">'+b.tags[d]+"</a>";break;case"wikipedia":if(b.tags[d].indexOf(":")!=-1){c+='<a href="https://'+b.tags[d].substring(0,b.tags[d].indexOf(":"))+".wikipedia.org/wiki/"+b.tags[d].substring(b.tags[d].indexOf(":")+1)+'">'+b.tags[d]+"</a>";break}default:c+=b.tags[d]}c+="</td></tr>"}$(g).html(c),$(g).removeClass("hidden"),$(h).addClass("hidden")}}).fail(function(){$(h).html($(h).html()+'<p class="text-muted">could not load data!</p>')})}}$(this).off(a)}),$(".searx_init_map").on("click",function(a){var b=$(this).data("leaflet-target"),c=$(this).data("map-lon"),d=$(this).data("map-lat"),e=$(this).data("map-zoom"),f=$(this).data("map-boundingbox"),g=$(this).data("map-geojson");require(["leaflet-0.7.3.min"],function(a){f&&(southWest=L.latLng(f[0],f[2]),northEast=L.latLng(f[1],f[3]),map_bounds=L.latLngBounds(southWest,northEast)),L.Icon.Default.imagePath="./static/themes/oscar/img/map";var h=L.map(b),i="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",j='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors',k=new L.TileLayer(i,{minZoom:1,maxZoom:19,attribution:j}),l="https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png",m='Wikimedia maps beta | Maps data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors';new L.TileLayer(l,{minZoom:1,maxZoom:19,attribution:m});map_bounds?setTimeout(function(){h.fitBounds(map_bounds,{maxZoom:17})},0):c&&d&&(e?h.setView(new L.LatLng(d,c),e):h.setView(new L.LatLng(d,c),8)),h.addLayer(k);var n={"OSM Mapnik":k};L.control.layers(n).addTo(h),g&&L.geoJson(g).addTo(h)}),$(this).off(a)})});
|
|
@ -19,3 +19,5 @@
|
|||
@import "cursor.less";
|
||||
|
||||
@import "code.less";
|
||||
|
||||
@import "preferences.less";
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
.table > tbody > tr > td, .table > tbody > tr > th {
|
||||
vertical-align: middle !important;
|
||||
}
|
|
@ -17,3 +17,5 @@
|
|||
@import "code.less";
|
||||
|
||||
@import "navbar.less";
|
||||
|
||||
@import "preferences.less";
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
.table > tbody > tr > td, .table > tbody > tr > th {
|
||||
vertical-align: middle !important;
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
<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" alt="{{result['favicon']}}" />{% endif %}<a href="{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.title|safe }}</a></h3>
|
||||
{% if result.publishedDate %}<span class="published_date">{{ result.publishedDate }}</span>{% endif %}
|
||||
<p class="content">{% if result.img_src %}<img src="{{ image_proxify(result.img_src) }}" class="image" />{% endif %}{% if result.content %}{{ result.content|safe }}<br class="last"/>{% endif %}</p>
|
||||
{% if result.repository %}<p class="content"><a href="{{ result.repository|safe }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.repository }}</a></p>{% endif %}
|
||||
<div dir="ltr">
|
||||
{{ result.codelines|code_highlighter(result.code_language)|safe }}
|
||||
</div>
|
||||
|
||||
<p class="url">{{ result.pretty_url }}‎</p>
|
||||
</div>
|
||||
<div class="result {{ result.class }}">
|
||||
<h3 class="result_title"><a href="{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.title|safe }}</a></h3>
|
||||
{% if result.publishedDate %}<span class="published_date">{{ result.publishedDate }}</span>{% endif %}
|
||||
<p class="content">{% if result.img_src %}<img src="{{ image_proxify(result.img_src) }}" class="image" />{% endif %}{% if result.content %}{{ result.content|safe }}<br class="last"/>{% endif %}</p>
|
||||
{% if result.repository %}<p class="content"><a href="{{ result.repository|safe }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.repository }}</a></p>{% endif %}
|
||||
<div dir="ltr">
|
||||
{{ result.codelines|code_highlighter(result.code_language)|safe }}
|
||||
</div>
|
||||
|
||||
<p class="url">{{ result.pretty_url }}‎</p>
|
||||
</div>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<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" alt="{{result['favicon']}}" />{% endif %}<a href="{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.title|safe }}</a></h3>
|
||||
<p class="url">{{ result.pretty_url }}‎ <a class="cache_link" href="https://web.archive.org/web/{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ _('cached') }}</a></p>
|
||||
{% if result.publishedDate %}<p class="published_date">{{ result.publishedDate }}</p>{% endif %}
|
||||
<p class="content">{% if result.img_src %}<img src="{{ image_proxify(result.img_src) }}" class="image" />{% endif %}{% if result.content %}{{ result.content|safe }}<br class="last"/>{% endif %}</p>
|
||||
{% if result.repository %}<p class="result-content"><a href="{{ result.repository|safe }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.repository }}</a></p>{% endif %}
|
||||
|
||||
<div dir="ltr">
|
||||
{{ result.codelines|code_highlighter(result.code_language)|safe }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="result {{ result.class }}">
|
||||
<h3 class="result_title"><a href="{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.title|safe }}</a></h3>
|
||||
<p class="url">{{ result.pretty_url }}‎ <a class="cache_link" href="https://web.archive.org/web/{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ _('cached') }}</a></p>
|
||||
{% if result.publishedDate %}<p class="published_date">{{ result.publishedDate }}</p>{% endif %}
|
||||
<p class="content">{% if result.img_src %}<img src="{{ image_proxify(result.img_src) }}" class="image" />{% endif %}{% if result.content %}{{ result.content|safe }}<br class="last"/>{% endif %}</p>
|
||||
{% if result.repository %}<p class="result-content"><a href="{{ result.repository|safe }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.repository }}</a></p>{% endif %}
|
||||
|
||||
<div dir="ltr">
|
||||
{{ result.codelines|code_highlighter(result.code_language)|safe }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,88 +1,99 @@
|
|||
<!-- Draw glyphicon icon from bootstrap-theme -->
|
||||
{% macro icon(action) -%}
|
||||
<span class="glyphicon glyphicon-{{ action }}"></span>
|
||||
{%- endmacro %}
|
||||
|
||||
<!-- Draw favicon -->
|
||||
<!-- TODO: using url_for methode -->
|
||||
{% macro draw_favicon(favicon) -%}
|
||||
<img width="32" height="32" class="favicon" src="static/themes/oscar/img/icons/{{ favicon }}.png" alt="{{ favicon }}" />
|
||||
{%- endmacro %}
|
||||
|
||||
{%- macro result_link(url, title, classes='') -%}
|
||||
<a href="{{ url }}" {% if classes %}class="{{ classes }}" {% endif %}{% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ title }}</a>
|
||||
{%- endmacro -%}
|
||||
|
||||
<!-- Draw result header -->
|
||||
{% macro result_header(result, favicons) -%}
|
||||
<h4 class="result_header">{% if result.engine~".png" in favicons %}{{ draw_favicon(result.engine) }} {% endif %}{{ result_link(result.url, result.title|safe) }}</h4>
|
||||
{%- endmacro %}
|
||||
|
||||
<!-- Draw result sub header -->
|
||||
{% macro result_sub_header(result) -%}
|
||||
{% if result.publishedDate %}<time class="text-muted" datetime="{{ result.pubdate }}" >{{ result.publishedDate }}</time>{% endif %}
|
||||
{% if result.magnetlink %}<small> • {{ result_link(result.magnetlink, icon('magnet') + _('magnet link'), "magnetlink") }}</small>{% endif %}
|
||||
{% if result.torrentfile %}<small> • {{ result_link(result.torrentfile, icon('download-alt') + _('torrent file'), "torrentfile") }}</small>{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
<!-- Draw result footer -->
|
||||
{% macro result_footer(result) -%}
|
||||
<div class="clearfix"></div>
|
||||
<div class="pull-right">
|
||||
{% for engine in result.engines %}
|
||||
<span class="label label-default">{{ engine }}</span>
|
||||
{% endfor %}
|
||||
<small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info") }}</small>
|
||||
{% if proxify %}
|
||||
<small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="external-link">{{ result.pretty_url }}</div>
|
||||
{%- endmacro %}
|
||||
|
||||
<!-- Draw result footer -->
|
||||
{% macro result_footer_rtl(result) -%}
|
||||
<div class="clearfix"></div>
|
||||
{% for engine in result.engines %}
|
||||
<span class="label label-default">{{ engine }}</span>
|
||||
{% endfor %}
|
||||
<small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info") }}</small>
|
||||
{% if proxify %}
|
||||
<small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small>
|
||||
{% endif %}
|
||||
<div class="external-link">{{ result.pretty_url }}</div>
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro preferences_item_header(info, label, rtl) -%}
|
||||
{% if rtl %}
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-3 col-md-2 pull-right">{{ label }}</label>
|
||||
<span class="col-sm-5 col-md-6 help-block pull-left">{{ info }}</span>
|
||||
<div class="col-sm-4 col-md-4">
|
||||
{% else %}
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-3 col-md-2">{{ label }}</label>
|
||||
<div class="col-sm-4 col-md-4">
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro preferences_item_footer(info, label, rtl) -%}
|
||||
{% if rtl %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
</div>
|
||||
<span class="col-sm-5 col-md-6 help-block">{{ info }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro checkbox_toggle(id, blocked) -%}
|
||||
<div class="onoffswitch">
|
||||
<input type="checkbox" id="{{ id }}" name="{{ id }}"{% if blocked %} checked="checked"{% endif %} class="onoffswitch-checkbox">
|
||||
<label class="onoffswitch-label" for="{{ id }}">
|
||||
<span class="onoffswitch-inner"></span>
|
||||
<span class="onoffswitch-switch"></span>
|
||||
</label>
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
<!-- Draw glyphicon icon from bootstrap-theme -->
|
||||
{% macro icon(action) -%}
|
||||
<span class="glyphicon glyphicon-{{ action }}"></span>
|
||||
{%- endmacro %}
|
||||
|
||||
<!-- Draw favicon -->
|
||||
{% macro draw_favicon(favicon) -%}
|
||||
<img width="32" height="32" class="favicon" src="{{ url_for('static', filename='themes/oscar/img/icons/' + favicon + '.png') }}" alt="{{ favicon }}" />
|
||||
{%- endmacro %}
|
||||
|
||||
{%- macro result_link(url, title, classes='') -%}
|
||||
<a href="{{ url }}" {% if classes %}class="{{ classes }}" {% endif %}{% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ title }}</a>
|
||||
{%- endmacro -%}
|
||||
|
||||
<!-- Draw result header -->
|
||||
{% macro result_header(result, favicons) -%}
|
||||
<h4 class="result_header">{% if result.engine~".png" in favicons %}{{ draw_favicon(result.engine) }} {% endif %}{{ result_link(result.url, result.title|safe) }}</h4>
|
||||
{%- endmacro %}
|
||||
|
||||
<!-- Draw result sub header -->
|
||||
{% macro result_sub_header(result) -%}
|
||||
{% if result.publishedDate %}<time class="text-muted" datetime="{{ result.pubdate }}" >{{ result.publishedDate }}</time>{% endif %}
|
||||
{% if result.magnetlink %}<small> • {{ result_link(result.magnetlink, icon('magnet') + _('magnet link'), "magnetlink") }}</small>{% endif %}
|
||||
{% if result.torrentfile %}<small> • {{ result_link(result.torrentfile, icon('download-alt') + _('torrent file'), "torrentfile") }}</small>{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
<!-- Draw result footer -->
|
||||
{% macro result_footer(result) -%}
|
||||
<div class="clearfix"></div>
|
||||
<div class="pull-right">
|
||||
{% for engine in result.engines %}
|
||||
<span class="label label-default">{{ engine }}</span>
|
||||
{% endfor %}
|
||||
<small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info") }}</small>
|
||||
{% if proxify %}
|
||||
<small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="external-link">{{ result.pretty_url }}</div>
|
||||
{%- endmacro %}
|
||||
|
||||
<!-- Draw result footer -->
|
||||
{% macro result_footer_rtl(result) -%}
|
||||
<div class="clearfix"></div>
|
||||
{% for engine in result.engines %}
|
||||
<span class="label label-default">{{ engine }}</span>
|
||||
{% endfor %}
|
||||
<small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info") }}</small>
|
||||
{% if proxify %}
|
||||
<small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small>
|
||||
{% endif %}
|
||||
<div class="external-link">{{ result.pretty_url }}</div>
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro preferences_item_header(info, label, rtl) -%}
|
||||
{% if rtl %}
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-3 col-md-2 pull-right">{{ label }}</label>
|
||||
<span class="col-sm-5 col-md-6 help-block pull-left">{{ info }}</span>
|
||||
<div class="col-sm-4 col-md-4">
|
||||
{% else %}
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-3 col-md-2">{{ label }}</label>
|
||||
<div class="col-sm-4 col-md-4">
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro preferences_item_footer(info, label, rtl) -%}
|
||||
{% if rtl %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
</div>
|
||||
<span class="col-sm-5 col-md-6 help-block">{{ info }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro checkbox_toggle(id, blocked) -%}
|
||||
<div class="onoffswitch">
|
||||
<input type="checkbox" id="{{ id }}" name="{{ id }}"{% if blocked %} checked="checked"{% endif %} class="onoffswitch-checkbox">
|
||||
<label class="onoffswitch-label" for="{{ id }}">
|
||||
<span class="onoffswitch-inner"></span>
|
||||
<span class="onoffswitch-switch"></span>
|
||||
</label>
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro support_toggle(supports) -%}
|
||||
{% if supports %}
|
||||
<span class="label label-success">
|
||||
{{ _("supported") }}
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="label label-danger">
|
||||
{{ _("not supported") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{% from 'oscar/macros.html' import preferences_item_header, preferences_item_header_rtl, preferences_item_footer, preferences_item_footer_rtl, checkbox_toggle %}
|
||||
{% from 'oscar/macros.html' import preferences_item_header, preferences_item_header_rtl, preferences_item_footer, preferences_item_footer_rtl, checkbox_toggle, support_toggle %}
|
||||
{% extends "oscar/base.html" %}
|
||||
{% block title %}{{ _('preferences') }} - {% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<div>
|
||||
|
||||
<h1>{{ _('Preferences') }}</h1>
|
||||
|
@ -148,7 +149,7 @@
|
|||
<th>{{ _("Allow") }}</th>
|
||||
<th>{{ _("Engine name") }}</th>
|
||||
<th>{{ _("Shortcut") }}</th>
|
||||
<th>{{ _("Supports selected language") }}</th>
|
||||
<th>{{ _("Selected language") }}</th>
|
||||
<th>{{ _("SafeSearch") }}</th>
|
||||
<th>{{ _("Time range") }}</th>
|
||||
<th>{{ _("Avg. time") }}</th>
|
||||
|
@ -156,8 +157,9 @@
|
|||
{% else %}
|
||||
<th>{{ _("Max time") }}</th>
|
||||
<th>{{ _("Avg. time") }}</th>
|
||||
<th>{{ _("Time range") }}</th>
|
||||
<th>{{ _("SafeSearch") }}</th>
|
||||
<th>{{ _("Supports selected language") }}</th>
|
||||
<th>{{ _("Selected language") }}</th>
|
||||
<th>{{ _("Shortcut") }}</th>
|
||||
<th>{{ _("Engine name") }}</th>
|
||||
<th>{{ _("Allow") }}</th>
|
||||
|
@ -172,17 +174,18 @@
|
|||
</td>
|
||||
<th>{{ search_engine.name }}</th>
|
||||
<td class="name">{{ shortcuts[search_engine.name] }}</td>
|
||||
<td><input type="checkbox" {{ "checked" if current_language == 'all' or current_language in search_engine.supported_languages or current_language.split('-')[0] in search_engine.supported_languages else ""}} readonly="readonly" disabled="disabled"></td>
|
||||
<td><input type="checkbox" {{ "checked" if search_engine.safesearch==True else ""}} readonly="readonly" disabled="disabled"></td>
|
||||
<td><input type="checkbox" {{ "checked" if search_engine.time_range_support==True else ""}} readonly="readonly" disabled="disabled"></td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_time'] else '' }}">{{ 'N/A' if stats[search_engine.name].time==None else stats[search_engine.name].time }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td>
|
||||
{% else %}
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_time'] else '' }}">{{ 'N/A' if stats[search_engine.name].time==None else stats[search_engine.name].time }}</td>
|
||||
<td><input type="checkbox" {{ "checked" if search_engine.safesearch==True else ""}} readonly="readonly" disabled="disabled"></td>
|
||||
<td><input type="checkbox" {{ "checked" if current_language == 'all' or current_language in search_engine.supported_languages or current_language.split('-')[0] in search_engine.supported_languages else ""}} readonly="readonly" disabled="disabled"></td>
|
||||
<td>{{ shortcuts[search_engine.name] }}</td>
|
||||
<td>{{ support_toggle(current_language == 'all' or current_language in search_engine.supported_languages or current_language.split('-')[0] in search_engine.supported_languages) }}</td>
|
||||
<td>{{ support_toggle(search_engine.safesearch==True) }}</td>
|
||||
<td>{{ support_toggle(search_engine.time_range_support==True) }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_time'] else '' }}">{{ 'N/A' if stats[search_engine.name].time==None else stats[search_engine.name].time }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td>
|
||||
{% else %}
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_time'] else '' }}">{{ 'N/A' if stats[search_engine.name].time==None else stats[search_engine.name].time }}</td>
|
||||
<td>{{ support_toggle(search_engine.time_range_support==True) }}</td>
|
||||
<td>{{ support_toggle(search_engine.safesearch==True) }}</td>
|
||||
<td>{{ support_toggle(current_language == 'all' or current_language in search_engine.supported_languages or current_language.split('-')[0] in search_engine.supported_languages) }}</td>
|
||||
<td>{{ shortcuts[search_engine.name] }}</td>
|
||||
<th>{{ search_engine.name }}</th>
|
||||
<td class="onoff-checkbox">
|
||||
{{ checkbox_toggle('engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_'), (search_engine.name, categ) in disabled_engines) }}
|
||||
|
|
|
@ -8,9 +8,8 @@
|
|||
{%- endmacro %}
|
||||
|
||||
<!-- Draw favicon -->
|
||||
<!-- TODO: using url_for methode -->
|
||||
{% macro draw_favicon(favicon) -%}
|
||||
<img width="14" height="14" class="favicon" src="static/themes/simple/img/icons/{{ favicon }}.png" alt="{{ favicon }}" />
|
||||
<img width="14" height="14" class="favicon" src="{{ url_for('static', filename='themes/simple/img/icons/' + favicon + '.png') }}" alt="{{ favicon }}" />
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro result_open_link(url, classes='') -%}
|
||||
|
|
Binary file not shown.
|
@ -1,844 +0,0 @@
|
|||
# Translations template for PROJECT.
|
||||
# Copyright (C) 2016 ORGANIZATION
|
||||
# This file is distributed under the same license as the PROJECT project.
|
||||
#
|
||||
# Translators:
|
||||
# Bamstam, 2016-2017
|
||||
# Benjamin Richter <benjamin@hacktherack.de>, 2015
|
||||
# cy8aer <cybaer42@web.de>, 2016-2017
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: searx\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2016-12-29 10:42+0100\n"
|
||||
"PO-Revision-Date: 2017-05-19 20:17+0000\n"
|
||||
"Last-Translator: cy8aer <cybaer42@web.de>\n"
|
||||
"Language-Team: German (Germany) (http://www.transifex.com/asciimoo/searx/language/de_DE/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.3.4\n"
|
||||
"Language: de_DE\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: searx/webapp.py:123
|
||||
msgid "files"
|
||||
msgstr "Dateien"
|
||||
|
||||
#: searx/webapp.py:124
|
||||
msgid "general"
|
||||
msgstr "Allgemein"
|
||||
|
||||
#: searx/webapp.py:125
|
||||
msgid "music"
|
||||
msgstr "Musik"
|
||||
|
||||
#: searx/webapp.py:126
|
||||
msgid "social media"
|
||||
msgstr "Soziale Medien"
|
||||
|
||||
#: searx/webapp.py:127
|
||||
msgid "images"
|
||||
msgstr "Fotos"
|
||||
|
||||
#: searx/webapp.py:128
|
||||
msgid "videos"
|
||||
msgstr "Videos"
|
||||
|
||||
#: searx/webapp.py:129
|
||||
msgid "it"
|
||||
msgstr "IT"
|
||||
|
||||
#: searx/webapp.py:130
|
||||
msgid "news"
|
||||
msgstr "Nachrichten"
|
||||
|
||||
#: searx/webapp.py:131
|
||||
msgid "map"
|
||||
msgstr "Karten"
|
||||
|
||||
#: searx/webapp.py:132
|
||||
msgid "science"
|
||||
msgstr "Wissenschaft"
|
||||
|
||||
#: searx/webapp.py:384 searx/webapp.py:594
|
||||
msgid "Invalid settings, please edit your preferences"
|
||||
msgstr "Ungültige Auswahl, bitte überprüfen Sie die Einstellungen"
|
||||
|
||||
#: searx/webapp.py:425
|
||||
msgid "search error"
|
||||
msgstr "Fehler bei der Suche"
|
||||
|
||||
#: searx/webapp.py:467
|
||||
msgid "{minutes} minute(s) ago"
|
||||
msgstr "vor {minutes} Minute(n)"
|
||||
|
||||
#: searx/webapp.py:469
|
||||
msgid "{hours} hour(s), {minutes} minute(s) ago"
|
||||
msgstr "vor {hours} Stunde(n). {minutes} Minute(n)"
|
||||
|
||||
#: searx/answerers/random/answerer.py:48
|
||||
msgid "Random value generator"
|
||||
msgstr "Zufallswertgenerator"
|
||||
|
||||
#: searx/answerers/random/answerer.py:49
|
||||
msgid "Generate different random values"
|
||||
msgstr "Zufallswerte generieren"
|
||||
|
||||
#: searx/answerers/statistics/answerer.py:49
|
||||
msgid "Statistics functions"
|
||||
msgstr "Statistik-Funktionen"
|
||||
|
||||
#: searx/answerers/statistics/answerer.py:50
|
||||
msgid "Compute {functions} of the arguments"
|
||||
msgstr "{functions} der Argumente berechnen"
|
||||
|
||||
#: searx/engines/__init__.py:192
|
||||
msgid "Engine time (sec)"
|
||||
msgstr "Zeitbedarf (s)"
|
||||
|
||||
#: searx/engines/__init__.py:196
|
||||
msgid "Page loads (sec)"
|
||||
msgstr "Ladezeit (s)"
|
||||
|
||||
#: searx/engines/__init__.py:200 searx/templates/oscar/results.html:88
|
||||
msgid "Number of results"
|
||||
msgstr "Anzahl Ergebnisse"
|
||||
|
||||
#: searx/engines/__init__.py:204
|
||||
msgid "Scores"
|
||||
msgstr "Punktwerte"
|
||||
|
||||
#: searx/engines/__init__.py:208
|
||||
msgid "Scores per result"
|
||||
msgstr "Punktwerte pro Ergebnis"
|
||||
|
||||
#: searx/engines/__init__.py:212
|
||||
msgid "Errors"
|
||||
msgstr "Fehler"
|
||||
|
||||
#: searx/engines/pdbe.py:87
|
||||
msgid "{title} (OBSOLETE)"
|
||||
msgstr "{title} (OBSOLET)"
|
||||
|
||||
#: searx/engines/pdbe.py:91
|
||||
msgid "This entry has been superseded by"
|
||||
msgstr "Dieser Eintrag wurde ersetzt durch"
|
||||
|
||||
#: searx/plugins/doai_rewrite.py:7
|
||||
msgid "DOAI rewrite"
|
||||
msgstr "DOAI-Umgehung"
|
||||
|
||||
#: searx/plugins/doai_rewrite.py:8
|
||||
msgid ""
|
||||
"Avoid paywalls by redirecting to open-access versions of publications when "
|
||||
"available"
|
||||
msgstr "Paywalls umgehen, indem wenn möglich auf Open-Access-Versionen von Publikationen umgeleitet wird"
|
||||
|
||||
#: searx/plugins/https_rewrite.py:29
|
||||
msgid "Rewrite HTTP links to HTTPS if possible"
|
||||
msgstr "Umschreiben von HTTP-Links nach HTTPS, wenn möglich"
|
||||
|
||||
#: searx/plugins/infinite_scroll.py:3
|
||||
msgid "Infinite scroll"
|
||||
msgstr "Unbegrenztes Scrollen"
|
||||
|
||||
#: searx/plugins/infinite_scroll.py:4
|
||||
msgid "Automatically load next page when scrolling to bottom of current page"
|
||||
msgstr "Nächste Seite automatisch laden, wenn zum Seitenende gescrollt wird"
|
||||
|
||||
#: searx/plugins/open_results_on_new_tab.py:18
|
||||
#: searx/templates/oscar/preferences.html:113
|
||||
msgid "Open result links on new browser tabs"
|
||||
msgstr "Öffne Links in einem neuen Browser-Tab"
|
||||
|
||||
#: searx/plugins/open_results_on_new_tab.py:19
|
||||
msgid ""
|
||||
"Results are opened in the same window by default. This plugin overwrites the"
|
||||
" default behaviour to open links on new tabs/windows. (JavaScript required)"
|
||||
msgstr "Suchergebnisse werden standardmäßig im gleichen Fenster geöffnet. Dieses Plug-in überschreibt dieses Standardverhalten und öffnet Links in neuen Tabs/Fenstern (benötigt JavaScript)."
|
||||
|
||||
#: searx/plugins/search_on_category_select.py:18
|
||||
msgid "Search on category select"
|
||||
msgstr "Suchen nach Kategorie"
|
||||
|
||||
#: searx/plugins/search_on_category_select.py:19
|
||||
msgid ""
|
||||
"Perform search immediately if a category selected. Disable to select "
|
||||
"multiple categories. (JavaScript required)"
|
||||
msgstr "Suche sofort durchführen, wenn eine Kategorie ausgewählt wird. Deaktivieren Sie diese Option, um mehrere Kategorien auswählen zu können (benötigt JavaScript)."
|
||||
|
||||
#: searx/plugins/self_info.py:20
|
||||
msgid ""
|
||||
"Displays your IP if the query is \"ip\" and your user agent if the query "
|
||||
"contains \"user agent\"."
|
||||
msgstr "Zeigt Ihre IP-Adresse an, wenn \"ip\" als Suchanfrage eingegeben wird und den User Agent bzw. das verwendete Client-Programm, wenn die Suchanfrage den Ausdruck \"user agent\" enthält."
|
||||
|
||||
#: searx/plugins/tracker_url_remover.py:26
|
||||
msgid "Tracker URL remover"
|
||||
msgstr "Tracking-URLs bereinigen"
|
||||
|
||||
#: searx/plugins/tracker_url_remover.py:27
|
||||
msgid "Remove trackers arguments from the returned URL"
|
||||
msgstr "Tracker-Argumente der erhaltenen URL entfernen"
|
||||
|
||||
#: searx/plugins/vim_hotkeys.py:3
|
||||
msgid "Vim-like hotkeys"
|
||||
msgstr "Vim-ähnliche Hotkeys"
|
||||
|
||||
#: searx/plugins/vim_hotkeys.py:4
|
||||
msgid ""
|
||||
"Navigate search results with Vim-like hotkeys (JavaScript required). Press "
|
||||
"\"h\" key on main or result page to get help."
|
||||
msgstr "Durch Suchergebnisse navigieren mit Vim-ähnlichen Hotkeys (benötigt JavaScript). \"h\" drücken auf der Hauptseite oder der Ergebnisseite, um Hilfe zu erhalten."
|
||||
|
||||
#: searx/templates/courgette/404.html:4 searx/templates/legacy/404.html:4
|
||||
#: searx/templates/oscar/404.html:4 searx/templates/pix-art/404.html:4
|
||||
msgid "Page not found"
|
||||
msgstr "Seite nicht gefunden"
|
||||
|
||||
#: searx/templates/courgette/404.html:6 searx/templates/legacy/404.html:6
|
||||
#: searx/templates/oscar/404.html:6 searx/templates/pix-art/404.html:6
|
||||
#, python-format
|
||||
msgid "Go to %(search_page)s."
|
||||
msgstr "Gehe zu %(search_page)s."
|
||||
|
||||
#: searx/templates/courgette/404.html:6 searx/templates/legacy/404.html:6
|
||||
#: searx/templates/oscar/404.html:6 searx/templates/pix-art/404.html:6
|
||||
msgid "search page"
|
||||
msgstr "Seite durchsuchen"
|
||||
|
||||
#: searx/templates/courgette/index.html:9
|
||||
#: searx/templates/courgette/index.html:13
|
||||
#: searx/templates/courgette/results.html:5
|
||||
#: searx/templates/legacy/index.html:8 searx/templates/legacy/index.html:12
|
||||
#: searx/templates/oscar/navbar.html:12
|
||||
#: searx/templates/oscar/preferences.html:3
|
||||
#: searx/templates/pix-art/index.html:8
|
||||
msgid "preferences"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
#: searx/templates/courgette/index.html:11
|
||||
#: searx/templates/legacy/index.html:10 searx/templates/oscar/about.html:2
|
||||
#: searx/templates/oscar/navbar.html:11 searx/templates/pix-art/index.html:7
|
||||
msgid "about"
|
||||
msgstr "Über uns"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:5
|
||||
#: searx/templates/legacy/preferences.html:5
|
||||
#: searx/templates/oscar/preferences.html:7
|
||||
#: searx/templates/pix-art/preferences.html:5
|
||||
msgid "Preferences"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:9
|
||||
#: searx/templates/legacy/preferences.html:9
|
||||
#: searx/templates/oscar/preferences.html:32
|
||||
#: searx/templates/oscar/preferences.html:34
|
||||
msgid "Default categories"
|
||||
msgstr "Standardkategorien"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:13
|
||||
#: searx/templates/legacy/preferences.html:14
|
||||
#: searx/templates/oscar/preferences.html:40
|
||||
#: searx/templates/pix-art/preferences.html:9
|
||||
msgid "Search language"
|
||||
msgstr "Suchsprache"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:16
|
||||
#: searx/templates/legacy/preferences.html:17
|
||||
#: searx/templates/oscar/languages.html:6
|
||||
#: searx/templates/pix-art/preferences.html:12
|
||||
msgid "Default language"
|
||||
msgstr "Standardsprache"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:24
|
||||
#: searx/templates/legacy/preferences.html:25
|
||||
#: searx/templates/oscar/preferences.html:46
|
||||
#: searx/templates/pix-art/preferences.html:20
|
||||
msgid "Interface language"
|
||||
msgstr "Sprache der Benutzeroberfläche"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:34
|
||||
#: searx/templates/legacy/preferences.html:35
|
||||
#: searx/templates/oscar/preferences.html:56
|
||||
msgid "Autocomplete"
|
||||
msgstr "Autovervollständigen"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:45
|
||||
#: searx/templates/legacy/preferences.html:46
|
||||
#: searx/templates/oscar/preferences.html:67
|
||||
msgid "Image proxy"
|
||||
msgstr "Proxy-Server für Bilder"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:48
|
||||
#: searx/templates/legacy/preferences.html:49
|
||||
#: searx/templates/oscar/preferences.html:71
|
||||
msgid "Enabled"
|
||||
msgstr "Aktiviert"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:49
|
||||
#: searx/templates/legacy/preferences.html:50
|
||||
#: searx/templates/oscar/preferences.html:72
|
||||
msgid "Disabled"
|
||||
msgstr "Deaktiviert"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:54
|
||||
#: searx/templates/legacy/preferences.html:55
|
||||
#: searx/templates/oscar/preferences.html:76
|
||||
#: searx/templates/pix-art/preferences.html:30
|
||||
msgid "Method"
|
||||
msgstr "Methode"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:63
|
||||
#: searx/templates/legacy/preferences.html:64
|
||||
#: searx/templates/oscar/preferences.html:85
|
||||
#: searx/templates/oscar/preferences.html:152
|
||||
#: searx/templates/oscar/preferences.html:159
|
||||
msgid "SafeSearch"
|
||||
msgstr "SafeSearch"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:66
|
||||
#: searx/templates/legacy/preferences.html:67
|
||||
#: searx/templates/oscar/preferences.html:89
|
||||
msgid "Strict"
|
||||
msgstr "Streng"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:67
|
||||
#: searx/templates/legacy/preferences.html:68
|
||||
#: searx/templates/oscar/preferences.html:90
|
||||
msgid "Moderate"
|
||||
msgstr "Moderat"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:68
|
||||
#: searx/templates/legacy/preferences.html:69
|
||||
#: searx/templates/oscar/preferences.html:91
|
||||
msgid "None"
|
||||
msgstr "Keine"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:73
|
||||
#: searx/templates/legacy/preferences.html:74
|
||||
#: searx/templates/oscar/preferences.html:95
|
||||
#: searx/templates/pix-art/preferences.html:39
|
||||
msgid "Themes"
|
||||
msgstr "Oberflächen"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:83
|
||||
msgid "Color"
|
||||
msgstr "Farbe"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:86
|
||||
msgid "Blue (default)"
|
||||
msgstr "Blau (Standard)"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:87
|
||||
msgid "Violet"
|
||||
msgstr "Violett"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:88
|
||||
msgid "Green"
|
||||
msgstr "Grün"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:89
|
||||
msgid "Cyan"
|
||||
msgstr "Türkis"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:90
|
||||
msgid "Orange"
|
||||
msgstr "Orange"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:91
|
||||
msgid "Red"
|
||||
msgstr "Rot"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:96
|
||||
#: searx/templates/legacy/preferences.html:93
|
||||
#: searx/templates/pix-art/preferences.html:49
|
||||
msgid "Currently used search engines"
|
||||
msgstr "Momentan genutzte Suchmaschinen"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:100
|
||||
#: searx/templates/legacy/preferences.html:97
|
||||
#: searx/templates/oscar/preferences.html:149
|
||||
#: searx/templates/oscar/preferences.html:162
|
||||
#: searx/templates/pix-art/preferences.html:53
|
||||
msgid "Engine name"
|
||||
msgstr "Suchmaschinen-Name"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:101
|
||||
#: searx/templates/legacy/preferences.html:98
|
||||
msgid "Category"
|
||||
msgstr "Kategorie"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:102
|
||||
#: searx/templates/courgette/preferences.html:113
|
||||
#: searx/templates/legacy/preferences.html:99
|
||||
#: searx/templates/legacy/preferences.html:110
|
||||
#: searx/templates/oscar/preferences.html:148
|
||||
#: searx/templates/oscar/preferences.html:163
|
||||
#: searx/templates/pix-art/preferences.html:54
|
||||
#: searx/templates/pix-art/preferences.html:64
|
||||
msgid "Allow"
|
||||
msgstr "Zulassen"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:102
|
||||
#: searx/templates/courgette/preferences.html:114
|
||||
#: searx/templates/legacy/preferences.html:99
|
||||
#: searx/templates/legacy/preferences.html:111
|
||||
#: searx/templates/pix-art/preferences.html:54
|
||||
#: searx/templates/pix-art/preferences.html:65
|
||||
msgid "Block"
|
||||
msgstr "Blockieren"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:122
|
||||
#: searx/templates/legacy/preferences.html:119
|
||||
#: searx/templates/oscar/preferences.html:282
|
||||
#: searx/templates/pix-art/preferences.html:73
|
||||
msgid ""
|
||||
"These settings are stored in your cookies, this allows us not to store this "
|
||||
"data about you."
|
||||
msgstr "Diese Einstellungen werden in Ihren Cookies gespeichert, deshalb müssen wir diese persönlichen Daten nicht bei uns speichern."
|
||||
|
||||
#: searx/templates/courgette/preferences.html:124
|
||||
#: searx/templates/legacy/preferences.html:121
|
||||
#: searx/templates/oscar/preferences.html:284
|
||||
#: searx/templates/pix-art/preferences.html:75
|
||||
msgid ""
|
||||
"These cookies serve your sole convenience, we don't use these cookies to "
|
||||
"track you."
|
||||
msgstr "Diese Cookies ermöglichen lediglich eine komfortablere Nutzung, wir verwenden diese Cookies nicht, um Sie zu tracken."
|
||||
|
||||
#: searx/templates/courgette/preferences.html:127
|
||||
#: searx/templates/legacy/preferences.html:124
|
||||
#: searx/templates/oscar/preferences.html:287
|
||||
#: searx/templates/pix-art/preferences.html:78
|
||||
msgid "save"
|
||||
msgstr "speichern"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:128
|
||||
#: searx/templates/legacy/preferences.html:125
|
||||
#: searx/templates/oscar/preferences.html:289
|
||||
msgid "Reset defaults"
|
||||
msgstr "Voreinstellungen wiederherstellen"
|
||||
|
||||
#: searx/templates/courgette/preferences.html:129
|
||||
#: searx/templates/legacy/preferences.html:126
|
||||
#: searx/templates/oscar/preferences.html:288
|
||||
#: searx/templates/pix-art/preferences.html:79
|
||||
msgid "back"
|
||||
msgstr "zurück"
|
||||
|
||||
#: searx/templates/courgette/results.html:12
|
||||
#: searx/templates/legacy/results.html:13
|
||||
#: searx/templates/oscar/results.html:124
|
||||
msgid "Search URL"
|
||||
msgstr "Such-URL"
|
||||
|
||||
#: searx/templates/courgette/results.html:16
|
||||
#: searx/templates/legacy/results.html:17
|
||||
#: searx/templates/oscar/results.html:129
|
||||
msgid "Download results"
|
||||
msgstr "Suchergebnisse herunterladen"
|
||||
|
||||
#: searx/templates/courgette/results.html:34
|
||||
#: searx/templates/legacy/results.html:35
|
||||
msgid "Answers"
|
||||
msgstr "Antworten"
|
||||
|
||||
#: searx/templates/courgette/results.html:42
|
||||
#: searx/templates/legacy/results.html:43
|
||||
#: searx/templates/oscar/results.html:104
|
||||
msgid "Suggestions"
|
||||
msgstr "Vorschläge"
|
||||
|
||||
#: searx/templates/courgette/results.html:70
|
||||
#: searx/templates/legacy/results.html:81
|
||||
#: searx/templates/oscar/results.html:53 searx/templates/oscar/results.html:66
|
||||
msgid "previous page"
|
||||
msgstr "vorherige Seite"
|
||||
|
||||
#: searx/templates/courgette/results.html:81
|
||||
#: searx/templates/legacy/results.html:92
|
||||
#: searx/templates/oscar/results.html:45 searx/templates/oscar/results.html:75
|
||||
msgid "next page"
|
||||
msgstr "nächste Seite"
|
||||
|
||||
#: searx/templates/courgette/search.html:3
|
||||
#: searx/templates/legacy/search.html:3 searx/templates/oscar/search.html:4
|
||||
#: searx/templates/oscar/search_full.html:9
|
||||
#: searx/templates/pix-art/search.html:3
|
||||
msgid "Search for..."
|
||||
msgstr "Suchen nach ..."
|
||||
|
||||
#: searx/templates/courgette/stats.html:4 searx/templates/legacy/stats.html:4
|
||||
#: searx/templates/oscar/stats.html:5 searx/templates/pix-art/stats.html:4
|
||||
msgid "Engine stats"
|
||||
msgstr "Suchmaschinen-Statistiken"
|
||||
|
||||
#: searx/templates/courgette/result_templates/images.html:4
|
||||
#: searx/templates/legacy/result_templates/images.html:4
|
||||
#: searx/templates/pix-art/result_templates/images.html:4
|
||||
msgid "original context"
|
||||
msgstr "Ursprünglicher Kontext"
|
||||
|
||||
#: searx/templates/courgette/result_templates/torrent.html:7
|
||||
#: searx/templates/legacy/result_templates/torrent.html:11
|
||||
#: searx/templates/oscar/result_templates/torrent.html:6
|
||||
msgid "Seeder"
|
||||
msgstr "Seeder"
|
||||
|
||||
#: searx/templates/courgette/result_templates/torrent.html:7
|
||||
#: searx/templates/legacy/result_templates/torrent.html:11
|
||||
#: searx/templates/oscar/result_templates/torrent.html:6
|
||||
msgid "Leecher"
|
||||
msgstr "Leecher"
|
||||
|
||||
#: searx/templates/courgette/result_templates/torrent.html:9
|
||||
#: searx/templates/legacy/result_templates/torrent.html:9
|
||||
#: searx/templates/oscar/macros.html:24
|
||||
msgid "magnet link"
|
||||
msgstr "Magnet-Link"
|
||||
|
||||
#: searx/templates/courgette/result_templates/torrent.html:10
|
||||
#: searx/templates/legacy/result_templates/torrent.html:10
|
||||
#: searx/templates/oscar/macros.html:25
|
||||
msgid "torrent file"
|
||||
msgstr "Torrent-Datei"
|
||||
|
||||
#: searx/templates/legacy/categories.html:8
|
||||
msgid "Click on the magnifier to perform search"
|
||||
msgstr "Klicken Sie auf das Vergrößerungsglas, um die Suche zu starten"
|
||||
|
||||
#: searx/templates/legacy/preferences.html:84
|
||||
#: searx/templates/oscar/preferences.html:112
|
||||
msgid "Results on new tabs"
|
||||
msgstr "Ergebnisse in neuen Tabs"
|
||||
|
||||
#: searx/templates/legacy/preferences.html:87
|
||||
#: searx/templates/oscar/preferences.html:116
|
||||
msgid "On"
|
||||
msgstr "An"
|
||||
|
||||
#: searx/templates/legacy/preferences.html:88
|
||||
#: searx/templates/oscar/preferences.html:117
|
||||
msgid "Off"
|
||||
msgstr "Aus"
|
||||
|
||||
#: searx/templates/legacy/result_templates/code.html:3
|
||||
#: searx/templates/legacy/result_templates/default.html:3
|
||||
#: searx/templates/legacy/result_templates/map.html:9
|
||||
#: searx/templates/oscar/macros.html:35 searx/templates/oscar/macros.html:49
|
||||
msgid "cached"
|
||||
msgstr "im Cache"
|
||||
|
||||
#: searx/templates/oscar/advanced.html:4
|
||||
msgid "Advanced settings"
|
||||
msgstr "Erweiterte Einstellungen"
|
||||
|
||||
#: searx/templates/oscar/base.html:62
|
||||
#: 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 "Schließen"
|
||||
|
||||
#: searx/templates/oscar/base.html:64
|
||||
msgid "Error!"
|
||||
msgstr "Fehler!"
|
||||
|
||||
#: searx/templates/oscar/base.html:90
|
||||
msgid "Powered by"
|
||||
msgstr "Bereitgestellt von"
|
||||
|
||||
#: searx/templates/oscar/base.html:90
|
||||
msgid "a privacy-respecting, hackable metasearch engine"
|
||||
msgstr "eine die Privatsphäre respektierende, hackbare Meta-Suchmaschine"
|
||||
|
||||
#: searx/templates/oscar/macros.html:37 searx/templates/oscar/macros.html:51
|
||||
msgid "proxied"
|
||||
msgstr "via Proxy-Server"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:12
|
||||
#: searx/templates/oscar/preferences.html:21
|
||||
msgid "General"
|
||||
msgstr "Allgemein"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:13
|
||||
#: searx/templates/oscar/preferences.html:133
|
||||
msgid "Engines"
|
||||
msgstr "Suchmaschinen"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:14
|
||||
#: searx/templates/oscar/preferences.html:204
|
||||
msgid "Plugins"
|
||||
msgstr "Plug-ins"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:15
|
||||
#: searx/templates/oscar/preferences.html:230
|
||||
msgid "Answerers"
|
||||
msgstr "Instant Answers/Sofortantworten"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:16
|
||||
#: searx/templates/oscar/preferences.html:257
|
||||
msgid "Cookies"
|
||||
msgstr "Cookies"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:41
|
||||
msgid "What language do you prefer for search?"
|
||||
msgstr "Welche Sprache möchten Sie für die Suche verwenden?"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:47
|
||||
msgid "Change the language of the layout"
|
||||
msgstr "Sprache des Layouts ändern"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:57
|
||||
msgid "Find stuff as you type"
|
||||
msgstr "Bereits während der Eingabe suchen"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:68
|
||||
msgid "Proxying image results through searx"
|
||||
msgstr "Bilder-Suchergebnisse über den searx-Proxy-Server laden"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:77
|
||||
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 "HTTP-Anfragemethode ändern <a href=\"https://de.wikipedia.org/wiki/Hypertext_Transfer_Protocol#HTTP-Anfragemethoden\" rel=\"external\">(weiterführende Informationen zu HTTP-Anfragemethoden)</a>"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:86
|
||||
msgid "Filter content"
|
||||
msgstr "Inhalte filtern"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:96
|
||||
msgid "Change searx layout"
|
||||
msgstr "searx-Layout ändern"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:105
|
||||
#: searx/templates/oscar/preferences.html:110
|
||||
msgid "Choose style for this theme"
|
||||
msgstr "Stilrichtung für diese Benutzeroberfläche auswählen"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:105
|
||||
#: searx/templates/oscar/preferences.html:110
|
||||
msgid "Style"
|
||||
msgstr "Stilrichtung"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:150
|
||||
#: searx/templates/oscar/preferences.html:161
|
||||
msgid "Shortcut"
|
||||
msgstr "Kürzel"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:151
|
||||
#: searx/templates/oscar/preferences.html:160
|
||||
msgid "Supports selected language"
|
||||
msgstr "Unterstützt die ausgewähle Sprache"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:153
|
||||
msgid "Time range"
|
||||
msgstr "Zeitraum"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:154
|
||||
#: searx/templates/oscar/preferences.html:158
|
||||
msgid "Avg. time"
|
||||
msgstr "Durchschn. Zeit"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:155
|
||||
#: searx/templates/oscar/preferences.html:157
|
||||
msgid "Max time"
|
||||
msgstr "Maximale Zeit"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:233
|
||||
msgid "This is the list of searx's instant answering modules."
|
||||
msgstr "Auflistung der searx-Module für Sofortantworten:"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:237
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:238
|
||||
msgid "Keywords"
|
||||
msgstr "Schlüsselwörter"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:239
|
||||
msgid "Description"
|
||||
msgstr "Beschreibung"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:240
|
||||
msgid "Examples"
|
||||
msgstr "Beispiele"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:260
|
||||
msgid ""
|
||||
"This is the list of cookies and their values searx is storing on your "
|
||||
"computer."
|
||||
msgstr "Hier werden die Cookies und die gespeicherten Cookie-Informationen aufgelistet, die searx auf Ihrem Computer speichert."
|
||||
|
||||
#: searx/templates/oscar/preferences.html:261
|
||||
msgid "With that list, you can assess searx transparency."
|
||||
msgstr "Mit Hilfe dieser Auflistung können Sie die Transparenz der searx-Suche einschätzen."
|
||||
|
||||
#: searx/templates/oscar/preferences.html:266
|
||||
msgid "Cookie name"
|
||||
msgstr "Cookie-Name"
|
||||
|
||||
#: searx/templates/oscar/preferences.html:267
|
||||
msgid "Value"
|
||||
msgstr "Wert"
|
||||
|
||||
#: searx/templates/oscar/results.html:7
|
||||
msgid "Search results"
|
||||
msgstr "Durchsuche Ergebnisse"
|
||||
|
||||
#: searx/templates/oscar/results.html:119
|
||||
msgid "Links"
|
||||
msgstr "Links"
|
||||
|
||||
#: searx/templates/oscar/search.html:6
|
||||
#: searx/templates/oscar/search_full.html:11
|
||||
msgid "Start search"
|
||||
msgstr "Suche starten"
|
||||
|
||||
#: searx/templates/oscar/stats.html:2
|
||||
msgid "stats"
|
||||
msgstr "Statistiken"
|
||||
|
||||
#: searx/templates/oscar/time-range.html:3
|
||||
msgid "Anytime"
|
||||
msgstr "Beliebiger Zeitunkt"
|
||||
|
||||
#: searx/templates/oscar/time-range.html:6
|
||||
msgid "Last day"
|
||||
msgstr "Gestern"
|
||||
|
||||
#: searx/templates/oscar/time-range.html:9
|
||||
msgid "Last week"
|
||||
msgstr "Letzte Woche"
|
||||
|
||||
#: searx/templates/oscar/time-range.html:12
|
||||
msgid "Last month"
|
||||
msgstr "Letzter Monat"
|
||||
|
||||
#: searx/templates/oscar/time-range.html:15
|
||||
msgid "Last year"
|
||||
msgstr "Letztes Jahr"
|
||||
|
||||
#: searx/templates/oscar/messages/first_time.html:6
|
||||
#: searx/templates/oscar/messages/no_data_available.html:3
|
||||
msgid "Heads up!"
|
||||
msgstr "Aufgepasst!"
|
||||
|
||||
#: searx/templates/oscar/messages/first_time.html:7
|
||||
msgid "It look like you are using searx first time."
|
||||
msgstr "Anscheinend benutzen Sie searx zum ersten Mal."
|
||||
|
||||
#: searx/templates/oscar/messages/no_cookies.html:3
|
||||
msgid "Information!"
|
||||
msgstr "Zur Information!"
|
||||
|
||||
#: searx/templates/oscar/messages/no_cookies.html:4
|
||||
msgid "currently, there are no cookies defined."
|
||||
msgstr "Zur Zeit sind keine Cookies definiert."
|
||||
|
||||
#: searx/templates/oscar/messages/no_data_available.html:4
|
||||
msgid "There is currently no data available. "
|
||||
msgstr "Zur Zeit sind keine Daten verfügbar."
|
||||
|
||||
#: searx/templates/oscar/messages/no_results.html:7
|
||||
msgid "Sorry!"
|
||||
msgstr "Entschuldigung!"
|
||||
|
||||
#: 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 "Leider konnten wir keine Suchergebnisse finden. Bitte verwenden Sie eine andere Suchabfrage oder erweitern Sie die Suche auf mehr Kategorien."
|
||||
|
||||
#: searx/templates/oscar/messages/save_settings_successfull.html:7
|
||||
msgid "Well done!"
|
||||
msgstr "Gut gemacht!"
|
||||
|
||||
#: searx/templates/oscar/messages/save_settings_successfull.html:8
|
||||
msgid "Settings saved successfully."
|
||||
msgstr "Einstellungen erfolgreich gespeichert."
|
||||
|
||||
#: searx/templates/oscar/messages/unknow_error.html:7
|
||||
msgid "Oh snap!"
|
||||
msgstr "Hoppla!"
|
||||
|
||||
#: searx/templates/oscar/messages/unknow_error.html:8
|
||||
msgid "Something went wrong."
|
||||
msgstr "Ein Fehler ist aufgetreten."
|
||||
|
||||
#: searx/templates/oscar/result_templates/default.html:7
|
||||
msgid "show media"
|
||||
msgstr "Medien anzeigen"
|
||||
|
||||
#: searx/templates/oscar/result_templates/default.html:7
|
||||
msgid "hide media"
|
||||
msgstr "Medien verbergen"
|
||||
|
||||
#: searx/templates/oscar/result_templates/images.html:30
|
||||
msgid "Get image"
|
||||
msgstr "Bild herunterladen"
|
||||
|
||||
#: searx/templates/oscar/result_templates/images.html:33
|
||||
msgid "View source"
|
||||
msgstr "Quelle anzeigen"
|
||||
|
||||
#: searx/templates/oscar/result_templates/map.html:7
|
||||
msgid "show map"
|
||||
msgstr "Karte anzeigen"
|
||||
|
||||
#: searx/templates/oscar/result_templates/map.html:7
|
||||
msgid "hide map"
|
||||
msgstr "Karte verbergen"
|
||||
|
||||
#: searx/templates/oscar/result_templates/map.html:11
|
||||
msgid "show details"
|
||||
msgstr "Details anzeigen"
|
||||
|
||||
#: searx/templates/oscar/result_templates/map.html:11
|
||||
msgid "hide details"
|
||||
msgstr "Details verbergen"
|
||||
|
||||
#: searx/templates/oscar/result_templates/torrent.html:7
|
||||
msgid "Filesize"
|
||||
msgstr "Dateigröße"
|
||||
|
||||
#: searx/templates/oscar/result_templates/torrent.html:9
|
||||
msgid "Bytes"
|
||||
msgstr "Bytes"
|
||||
|
||||
#: searx/templates/oscar/result_templates/torrent.html:10
|
||||
msgid "kiB"
|
||||
msgstr "kiB"
|
||||
|
||||
#: searx/templates/oscar/result_templates/torrent.html:11
|
||||
msgid "MiB"
|
||||
msgstr "MiB"
|
||||
|
||||
#: searx/templates/oscar/result_templates/torrent.html:12
|
||||
msgid "GiB"
|
||||
msgstr "GiB"
|
||||
|
||||
#: searx/templates/oscar/result_templates/torrent.html:13
|
||||
msgid "TiB"
|
||||
msgstr "TiB"
|
||||
|
||||
#: searx/templates/oscar/result_templates/torrent.html:15
|
||||
msgid "Number of Files"
|
||||
msgstr "Anzahl Dateien"
|
||||
|
||||
#: searx/templates/oscar/result_templates/videos.html:7
|
||||
msgid "show video"
|
||||
msgstr "Video anzeigen"
|
||||
|
||||
#: searx/templates/oscar/result_templates/videos.html:7
|
||||
msgid "hide video"
|
||||
msgstr "Video verbergen"
|
||||
|
||||
#: searx/templates/pix-art/results.html:28
|
||||
msgid "Load more..."
|
||||
msgstr "Mehr anzeigen ..."
|
|
@ -1,4 +1,6 @@
|
|||
import csv
|
||||
import hashlib
|
||||
import hmac
|
||||
import os
|
||||
import re
|
||||
|
||||
|
@ -290,6 +292,15 @@ def convert_str_to_int(number_str):
|
|||
return 0
|
||||
|
||||
|
||||
# convert a variable to integer or return 0 if it's not a number
|
||||
def int_or_zero(num):
|
||||
if isinstance(num, list):
|
||||
if len(num) < 1:
|
||||
return 0
|
||||
num = num[0]
|
||||
return convert_str_to_int(num)
|
||||
|
||||
|
||||
def is_valid_lang(lang):
|
||||
is_abbr = (len(lang) == 2)
|
||||
if is_abbr:
|
||||
|
@ -312,3 +323,10 @@ def load_module(filename, module_dir):
|
|||
module = load_source(modname, filepath)
|
||||
module.name = modname
|
||||
return module
|
||||
|
||||
|
||||
def new_hmac(secret_key, url):
|
||||
if sys.version_info[0] == 2:
|
||||
return hmac.new(bytes(secret_key), url, hashlib.sha256).hexdigest()
|
||||
else:
|
||||
return hmac.new(bytes(secret_key, 'utf-8'), url, hashlib.sha256).hexdigest()
|
||||
|
|
|
@ -69,6 +69,7 @@ from searx.plugins import plugins
|
|||
from searx.preferences import Preferences, ValidationException
|
||||
from searx.answerers import answerers
|
||||
from searx.url_utils import urlencode, urlparse, urljoin
|
||||
from searx.utils import new_hmac
|
||||
|
||||
# check if the pyopenssl package is installed.
|
||||
# It is needed for SSL connection without trouble, see #298
|
||||
|
@ -290,7 +291,7 @@ def image_proxify(url):
|
|||
if settings.get('result_proxy'):
|
||||
return proxify(url)
|
||||
|
||||
h = hmac.new(settings['server']['secret_key'], url.encode('utf-8'), hashlib.sha256).hexdigest()
|
||||
h = new_hmac(settings['server']['secret_key'], url.encode('utf-8'))
|
||||
|
||||
return '{0}?{1}'.format(url_for('image_proxy'),
|
||||
urlencode(dict(url=url.encode('utf-8'), h=h)))
|
||||
|
@ -704,7 +705,7 @@ def image_proxy():
|
|||
if not url:
|
||||
return '', 400
|
||||
|
||||
h = hmac.new(settings['server']['secret_key'], url, hashlib.sha256).hexdigest()
|
||||
h = new_hmac(settings['server']['secret_key'], url)
|
||||
|
||||
if h != request.args.get('h'):
|
||||
return '', 400
|
||||
|
@ -731,7 +732,7 @@ def image_proxy():
|
|||
logger.debug('image-proxy: wrong content-type: {0}'.format(resp.headers.get('content-type')))
|
||||
return '', 400
|
||||
|
||||
img = ''
|
||||
img = b''
|
||||
chunk_counter = 0
|
||||
|
||||
for chunk in resp.iter_content(1024 * 1024):
|
||||
|
@ -792,7 +793,8 @@ def opensearch():
|
|||
@app.route('/favicon.ico')
|
||||
def favicon():
|
||||
return send_from_directory(os.path.join(app.root_path,
|
||||
'static/themes',
|
||||
static_path,
|
||||
'themes',
|
||||
get_current_theme_name(),
|
||||
'img'),
|
||||
'favicon.png',
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from collections import defaultdict
|
||||
import mock
|
||||
from searx.engines import base
|
||||
from searx.testing import SearxTestCase
|
||||
|
||||
|
||||
class TestBaseEngine(SearxTestCase):
|
||||
|
||||
def test_request(self):
|
||||
query = 'test_query'
|
||||
dicto = defaultdict(dict)
|
||||
dicto['pageno'] = 1
|
||||
params = base.request(query, dicto)
|
||||
self.assertIn('url', params)
|
||||
self.assertIn('base-search.net', params['url'])
|
||||
|
||||
def test_response(self):
|
||||
self.assertRaises(AttributeError, base.response, None)
|
||||
self.assertRaises(AttributeError, base.response, [])
|
||||
self.assertRaises(AttributeError, base.response, '')
|
||||
self.assertRaises(AttributeError, base.response, '[]')
|
||||
|
||||
response = mock.Mock(text='<response></response>')
|
||||
self.assertEqual(base.response(response), [])
|
||||
|
||||
xml_mock = """<?xml version="1.0"?>
|
||||
<response>
|
||||
<lst name="responseHeader">
|
||||
<int name="status">0</int>
|
||||
<int name="QTime">1</int>
|
||||
</lst>
|
||||
<result name="response" numFound="1" start="0">
|
||||
<doc>
|
||||
<date name="dchdate">2000-01-01T01:01:01Z</date>
|
||||
<str name="dcdocid">1</str>
|
||||
<str name="dccontinent">cna</str>
|
||||
<str name="dccountry">us</str>
|
||||
<str name="dccollection">ftciteseerx</str>
|
||||
<str name="dcprovider">CiteSeerX</str>
|
||||
<str name="dctitle">Science and more</str>
|
||||
<arr name="dccreator">
|
||||
<str>Someone</str>
|
||||
</arr>
|
||||
<arr name="dcperson">
|
||||
<str>Someone</str>
|
||||
</arr>
|
||||
<arr name="dcsubject">
|
||||
<str>Science and more</str>
|
||||
</arr>
|
||||
<str name="dcdescription">Science, and even more.</str>
|
||||
<arr name="dccontributor">
|
||||
<str>The neighbour</str>
|
||||
</arr>
|
||||
<str name="dcdate">2001</str>
|
||||
<int name="dcyear">2001</int>
|
||||
<arr name="dctype">
|
||||
<str>text</str>
|
||||
</arr>
|
||||
<arr name="dctypenorm">
|
||||
<str>1</str>
|
||||
</arr>
|
||||
<arr name="dcformat">
|
||||
<str>application/pdf</str>
|
||||
</arr>
|
||||
<arr name="dccontenttype">
|
||||
<str>application/pdf</str>
|
||||
</arr>
|
||||
<arr name="dcidentifier">
|
||||
<str>http://example.org/</str>
|
||||
</arr>
|
||||
<str name="dclink">http://example.org</str>
|
||||
<str name="dcsource">http://example.org</str>
|
||||
<arr name="dclanguage">
|
||||
<str>en</str>
|
||||
</arr>
|
||||
<str name="dcrights">Under the example.org licence</str>
|
||||
<int name="dcoa">1</int>
|
||||
<arr name="dclang">
|
||||
<str>eng</str>
|
||||
</arr>
|
||||
</doc>
|
||||
</result>
|
||||
</response>"""
|
||||
|
||||
response = mock.Mock(text=xml_mock.encode('utf-8'))
|
||||
results = base.response(response)
|
||||
self.assertEqual(type(results), list)
|
||||
self.assertEqual(len(results), 1)
|
||||
self.assertEqual(results[0]['title'], 'Science and more')
|
||||
self.assertEqual(results[0]['content'], 'Science, and even more.')
|
|
@ -8,10 +8,12 @@ from searx.testing import SearxTestCase
|
|||
class TestBingImagesEngine(SearxTestCase):
|
||||
|
||||
def test_request(self):
|
||||
bing_images.supported_languages = ['fr-FR', 'en-US']
|
||||
|
||||
query = 'test_query'
|
||||
dicto = defaultdict(dict)
|
||||
dicto['pageno'] = 1
|
||||
dicto['language'] = 'fr_FR'
|
||||
dicto['language'] = 'fr-FR'
|
||||
dicto['safesearch'] = 1
|
||||
dicto['time_range'] = ''
|
||||
params = bing_images.request(query, dicto)
|
||||
|
@ -19,12 +21,19 @@ class TestBingImagesEngine(SearxTestCase):
|
|||
self.assertTrue(query in params['url'])
|
||||
self.assertTrue('bing.com' in params['url'])
|
||||
self.assertTrue('SRCHHPGUSR' in params['cookies'])
|
||||
self.assertTrue('fr' in params['cookies']['SRCHHPGUSR'])
|
||||
self.assertTrue('DEMOTE' in params['cookies']['SRCHHPGUSR'])
|
||||
self.assertTrue('_EDGE_S' in params['cookies'])
|
||||
self.assertTrue('fr-fr' in params['cookies']['_EDGE_S'])
|
||||
|
||||
dicto['language'] = 'fr'
|
||||
params = bing_images.request(query, dicto)
|
||||
self.assertTrue('_EDGE_S' in params['cookies'])
|
||||
self.assertTrue('fr-fr' in params['cookies']['_EDGE_S'])
|
||||
|
||||
dicto['language'] = 'all'
|
||||
params = bing_images.request(query, dicto)
|
||||
self.assertIn('SRCHHPGUSR', params['cookies'])
|
||||
self.assertIn('en', params['cookies']['SRCHHPGUSR'])
|
||||
self.assertTrue('_EDGE_S' in params['cookies'])
|
||||
self.assertTrue('en-us' in params['cookies']['_EDGE_S'])
|
||||
|
||||
def test_response(self):
|
||||
self.assertRaises(AttributeError, bing_images.response, None)
|
||||
|
@ -82,3 +91,28 @@ class TestBingImagesEngine(SearxTestCase):
|
|||
self.assertEqual(results[0]['content'], '')
|
||||
self.assertEqual(results[0]['thumbnail_src'], 'thumb_url')
|
||||
self.assertEqual(results[0]['img_src'], 'img_url')
|
||||
|
||||
def test_fetch_supported_languages(self):
|
||||
html = """
|
||||
<div>
|
||||
<div id="region-section-content">
|
||||
<ul class="b_vList">
|
||||
<li>
|
||||
<a href="https://bing...&setmkt=de-DE&s...">Germany</a>
|
||||
<a href="https://bing...&setmkt=nb-NO&s...">Norway</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="b_vList">
|
||||
<li>
|
||||
<a href="https://bing...&setmkt=es-AR&s...">Argentina</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
response = mock.Mock(text=html)
|
||||
languages = list(bing_images._fetch_supported_languages(response))
|
||||
self.assertEqual(len(languages), 3)
|
||||
self.assertIn('de-DE', languages)
|
||||
self.assertIn('no-NO', languages)
|
||||
self.assertIn('es-AR', languages)
|
||||
|
|
|
@ -8,6 +8,8 @@ from searx.testing import SearxTestCase
|
|||
class TestBingVideosEngine(SearxTestCase):
|
||||
|
||||
def test_request(self):
|
||||
bing_videos.supported_languages = ['fr-FR', 'en-US']
|
||||
|
||||
query = 'test_query'
|
||||
dicto = defaultdict(dict)
|
||||
dicto['pageno'] = 1
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
from collections import defaultdict
|
||||
import mock
|
||||
from searx.engines import blekko_images
|
||||
from searx.testing import SearxTestCase
|
||||
|
||||
|
||||
class TestBlekkoImagesEngine(SearxTestCase):
|
||||
|
||||
def test_request(self):
|
||||
query = 'test_query'
|
||||
dicto = defaultdict(dict)
|
||||
dicto['pageno'] = 0
|
||||
dicto['safesearch'] = 1
|
||||
params = blekko_images.request(query, dicto)
|
||||
self.assertIn('url', params)
|
||||
self.assertIn(query, params['url'])
|
||||
self.assertIn('blekko.com', params['url'])
|
||||
self.assertIn('page', params['url'])
|
||||
|
||||
dicto['pageno'] = 1
|
||||
params = blekko_images.request(query, dicto)
|
||||
self.assertNotIn('page', params['url'])
|
||||
|
||||
def test_response(self):
|
||||
self.assertRaises(AttributeError, blekko_images.response, None)
|
||||
self.assertRaises(AttributeError, blekko_images.response, [])
|
||||
self.assertRaises(AttributeError, blekko_images.response, '')
|
||||
self.assertRaises(AttributeError, blekko_images.response, '[]')
|
||||
|
||||
response = mock.Mock(text='[]')
|
||||
self.assertEqual(blekko_images.response(response), [])
|
||||
|
||||
json = """
|
||||
[
|
||||
{
|
||||
"c": 1,
|
||||
"page_url": "http://result_url.html",
|
||||
"title": "Photo title",
|
||||
"tn_url": "http://ts1.mm.bing.net/th?id=HN.608050619474382748&pid=15.1",
|
||||
"url": "http://result_image.jpg"
|
||||
},
|
||||
{
|
||||
"c": 2,
|
||||
"page_url": "http://companyorange.simpsite.nl/OSM",
|
||||
"title": "OSM",
|
||||
"tn_url": "http://ts2.mm.bing.net/th?id=HN.608048068264919461&pid=15.1",
|
||||
"url": "http://simpsite.nl/userdata2/58985/Home/OSM.bmp"
|
||||
},
|
||||
{
|
||||
"c": 3,
|
||||
"page_url": "http://invincible.webklik.nl/page/osm",
|
||||
"title": "OSM",
|
||||
"tn_url": "http://ts1.mm.bing.net/th?id=HN.608024514657649476&pid=15.1",
|
||||
"url": "http://www.webklik.nl/user_files/2009_09/65324/osm.gif"
|
||||
},
|
||||
{
|
||||
"c": 4,
|
||||
"page_url": "http://www.offshorenorway.no/event/companyDetail/id/12492",
|
||||
"title": "Go to OSM Offshore AS homepage",
|
||||
"tn_url": "http://ts2.mm.bing.net/th?id=HN.608054265899847285&pid=15.1",
|
||||
"url": "http://www.offshorenorway.no/firmalogo/OSM-logo.png"
|
||||
}
|
||||
]
|
||||
"""
|
||||
response = mock.Mock(text=json)
|
||||
results = blekko_images.response(response)
|
||||
self.assertEqual(type(results), list)
|
||||
self.assertEqual(len(results), 4)
|
||||
self.assertEqual(results[0]['title'], 'Photo title')
|
||||
self.assertEqual(results[0]['url'], 'http://result_url.html')
|
||||
self.assertEqual(results[0]['img_src'], 'http://result_image.jpg')
|
|
@ -40,9 +40,6 @@ class TestFarooEngine(SearxTestCase):
|
|||
response = mock.Mock(text='{"data": []}')
|
||||
self.assertEqual(faroo.response(response), [])
|
||||
|
||||
response = mock.Mock(text='{"data": []}', status_code=401)
|
||||
self.assertRaises(Exception, faroo.response, response)
|
||||
|
||||
response = mock.Mock(text='{"data": []}', status_code=429)
|
||||
self.assertRaises(Exception, faroo.response, response)
|
||||
|
||||
|
@ -98,14 +95,14 @@ class TestFarooEngine(SearxTestCase):
|
|||
response = mock.Mock(text=json)
|
||||
results = faroo.response(response)
|
||||
self.assertEqual(type(results), list)
|
||||
self.assertEqual(len(results), 4)
|
||||
self.assertEqual(len(results), 3)
|
||||
self.assertEqual(results[0]['title'], 'This is the title')
|
||||
self.assertEqual(results[0]['url'], 'http://this.is.the.url/')
|
||||
self.assertEqual(results[0]['content'], 'This is the content')
|
||||
self.assertEqual(results[1]['title'], 'This is the title2')
|
||||
self.assertEqual(results[1]['url'], 'http://this.is.the.url2/')
|
||||
self.assertEqual(results[1]['content'], 'This is the content2')
|
||||
self.assertEqual(results[3]['img_src'], 'http://upload.wikimedia.org/optimized.jpg')
|
||||
self.assertEqual(results[2]['thumbnail'], 'http://upload.wikimedia.org/optimized.jpg')
|
||||
|
||||
json = """
|
||||
{}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -13,38 +13,92 @@ class TestNyaaEngine(SearxTestCase):
|
|||
params = nyaa.request(query, dic)
|
||||
self.assertTrue('url' in params)
|
||||
self.assertTrue(query in params['url'])
|
||||
self.assertTrue('nyaa.se' in params['url'])
|
||||
self.assertTrue('nyaa.si' in params['url'])
|
||||
|
||||
def test_response(self):
|
||||
resp = mock.Mock(text='<html></html>')
|
||||
self.assertEqual(nyaa.response(resp), [])
|
||||
|
||||
html = """
|
||||
<table class="tlist">
|
||||
<tbody>
|
||||
<tr class="trusted tlistrow">
|
||||
<td class="tlisticon">
|
||||
<a href="//www.nyaa.se" title="English-translated Anime">
|
||||
<img src="//files.nyaa.se" alt="English-translated Anime">
|
||||
</a>
|
||||
</td>
|
||||
<td class="tlistname">
|
||||
<a href="//www.nyaa.se/?page3">
|
||||
Sample torrent title
|
||||
</a>
|
||||
</td>
|
||||
<td class="tlistdownload">
|
||||
<a href="//www.nyaa.se/?page_dl" title="Download">
|
||||
<img src="//files.nyaa.se/www-dl.png" alt="DL">
|
||||
</a>
|
||||
</td>
|
||||
<td class="tlistsize">10 MiB</td>
|
||||
<td class="tlistsn">1</td>
|
||||
<td class="tlistln">3</td>
|
||||
<td class="tlistdn">666</td>
|
||||
<td class="tlistmn">0</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<table class="table table-bordered table-hover table-striped torrent-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="hdr-category text-center" style="width:80px;">
|
||||
<div>Category</div>
|
||||
</th>
|
||||
<th class="hdr-name" style="width:auto;">
|
||||
<div>Name</div>
|
||||
</th>
|
||||
<th class="hdr-comments sorting text-center" title="Comments" style="width:50px;">
|
||||
<a href="/?f=0&c=0_0&q=Death+Parade&s=comments&o=desc"></a>
|
||||
<i class="fa fa-comments-o"></i>
|
||||
</th>
|
||||
<th class="hdr-link text-center" style="width:70px;">
|
||||
<div>Link</div>
|
||||
</th>
|
||||
<th class="hdr-size sorting text-center" style="width:100px;">
|
||||
<a href="/?f=0&c=0_0&q=Death+Parade&s=size&o=desc"></a>
|
||||
<div>Size</div>
|
||||
</th>
|
||||
<th class="hdr-date sorting_desc text-center" title="In local time" style="width:140px;">
|
||||
<a href="/?f=0&c=0_0&q=Death+Parade&s=id&o=asc"></a>
|
||||
<div>Date</div>
|
||||
</th>
|
||||
<th class="hdr-seeders sorting text-center" title="Seeders" style="width:50px;">
|
||||
<a href="/?f=0&c=0_0&q=Death+Parade&s=seeders&o=desc"></a>
|
||||
<i class="fa fa-arrow-up" aria-hidden="true"></i>
|
||||
</th>
|
||||
<th class="hdr-leechers sorting text-center" title="Leechers" style="width:50px;">
|
||||
<a href="/?f=0&c=0_0&q=Death+Parade&s=leechers&o=desc"></a>
|
||||
<i class="fa fa-arrow-down" aria-hidden="true"></i>
|
||||
</th>
|
||||
<th class="hdr-downloads sorting text-center" title="Completed downloads" style="width:50px;">
|
||||
<a href="/?f=0&c=0_0&q=Death+Parade&s=downloads&o=desc"></a>
|
||||
<i class="fa fa-check" aria-hidden="true"></i>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="default">
|
||||
<td style="padding:0 4px;">
|
||||
<a href="/?c=1_2" title="Anime - English-translated">
|
||||
<img src="/static/img/icons/nyaa/1_2.png" alt="Anime - English-translated">
|
||||
</a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<a href="/view/1" title="Sample title 1">Sample title 1</a>
|
||||
</td>
|
||||
<td class="text-center" style="white-space: nowrap;">
|
||||
<a href="/download/1.torrent"><i class="fa fa-fw fa-download"></i></a>
|
||||
<a href="magnet:?xt=urn:btih:2"><i class="fa fa-fw fa-magnet"></i></a>
|
||||
</td>
|
||||
<td class="text-center">723.7 MiB</td>
|
||||
<td class="text-center" data-timestamp="1503307456" title="1 week 3
|
||||
days 9 hours 44 minutes 39 seconds ago">2017-08-21 11:24</td>
|
||||
<td class="text-center" style="color: green;">1</td>
|
||||
<td class="text-center" style="color: red;">3</td>
|
||||
<td class="text-center">12</td>
|
||||
</tr>
|
||||
<tr class="default">
|
||||
<td style="padding:0 4px;">
|
||||
<a href="/?c=1_2" title="Anime - English-translated">
|
||||
<img src="/static/img/icons/nyaa/1_2.png" alt="Anime - English-translated">
|
||||
</a>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<a href="/view/2" title="Sample title 2">Sample title 2</a>
|
||||
</td>
|
||||
<td class="text-center" style="white-space: nowrap;">
|
||||
<a href="magnet:?xt=urn:btih:2"><i class="fa fa-fw fa-magnet"></i></a>
|
||||
</td>
|
||||
<td class="text-center">8.2 GiB</td>
|
||||
<td class="text-center" data-timestamp="1491608400" title="4 months 3
|
||||
weeks 4 days 19 hours 28 minutes 55 seconds ago">2017-04-08 01:40</td>
|
||||
<td class="text-center" style="color: green;">10</td>
|
||||
<td class="text-center" style="color: red;">1</td>
|
||||
<td class="text-center">206</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
"""
|
||||
|
||||
|
@ -52,15 +106,19 @@ class TestNyaaEngine(SearxTestCase):
|
|||
results = nyaa.response(resp)
|
||||
|
||||
self.assertEqual(type(results), list)
|
||||
self.assertEqual(len(results), 1)
|
||||
self.assertEqual(len(results), 2)
|
||||
|
||||
r = results[0]
|
||||
self.assertTrue(r['url'].find('www.nyaa.se/?page3') >= 0)
|
||||
self.assertTrue(r['torrentfile'].find('www.nyaa.se/?page_dl') >= 0)
|
||||
self.assertTrue(r['content'].find('English-translated Anime') >= 0)
|
||||
self.assertTrue(r['content'].find('Downloaded 666 times.') >= 0)
|
||||
self.assertTrue(r['url'].find('1') >= 0)
|
||||
self.assertTrue(r['torrentfile'].find('1.torrent') >= 0)
|
||||
self.assertTrue(r['content'].find('Anime - English-translated') >= 0)
|
||||
self.assertTrue(r['content'].find('Downloaded 12 times.') >= 0)
|
||||
|
||||
self.assertEqual(r['title'], 'Sample torrent title')
|
||||
self.assertEqual(r['title'], 'Sample title 1')
|
||||
self.assertEqual(r['seed'], 1)
|
||||
self.assertEqual(r['leech'], 3)
|
||||
self.assertEqual(r['filesize'], 10 * 1024 * 1024)
|
||||
self.assertEqual(r['filesize'], 723700000)
|
||||
|
||||
r = results[1]
|
||||
self.assertTrue(r['url'].find('2') >= 0)
|
||||
self.assertTrue(r['magnetlink'].find('magnet:') >= 0)
|
||||
|
|
|
@ -139,9 +139,9 @@ class TestSwisscowsEngine(SearxTestCase):
|
|||
<div id="regions-popup">
|
||||
<div>
|
||||
<ul>
|
||||
<li><a data-val="browser"></a></li>
|
||||
<li><a data-val="de-CH"></a></li>
|
||||
<li><a data-val="fr-CH"></a></li>
|
||||
<li><a data-search-language="browser"></a></li>
|
||||
<li><a data-search-language="de-CH"></a></li>
|
||||
<li><a data-search-language="fr-CH"></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -14,7 +14,7 @@ class TestTorrentzEngine(SearxTestCase):
|
|||
params = torrentz.request(query, dic)
|
||||
self.assertTrue('url' in params)
|
||||
self.assertTrue(query in params['url'])
|
||||
self.assertTrue('torrentz.eu' in params['url'])
|
||||
self.assertTrue('torrentz2.eu' in params['url'])
|
||||
|
||||
def test_response(self):
|
||||
resp = mock.Mock(text='<html></html>')
|
||||
|
@ -30,13 +30,11 @@ class TestTorrentzEngine(SearxTestCase):
|
|||
books ebooks
|
||||
</dt>
|
||||
<dd>
|
||||
<span class="v">1</span>
|
||||
<span class="a">
|
||||
<span title="Sun, 22 Nov 2015 03:01:42">4 months</span>
|
||||
</span>
|
||||
<span class="s">30 MB</span>
|
||||
<span class="u">14</span>
|
||||
<span class="d">1</span>
|
||||
<span>1</span>
|
||||
<span title="1503595924">5 hours</span>
|
||||
<span>30 MB</span>
|
||||
<span>14</span>
|
||||
<span>1</span>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
@ -48,13 +46,11 @@ class TestTorrentzEngine(SearxTestCase):
|
|||
books ebooks
|
||||
</dt>
|
||||
<dd>
|
||||
<span class="v">1</span>
|
||||
<span class="a">
|
||||
<span title="Sun, 2124091j0j190gm42">4 months</span>
|
||||
</span>
|
||||
<span class="s">30MB</span>
|
||||
<span class="u">5,555</span>
|
||||
<span class="d">1,234,567</span>
|
||||
<span>1</span>
|
||||
<span title="1503595924 aaa">5 hours</span>
|
||||
<span>30MB</span>
|
||||
<span>5,555</span>
|
||||
<span>1,234,567</span>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
@ -68,10 +64,10 @@ class TestTorrentzEngine(SearxTestCase):
|
|||
|
||||
# testing against the first result
|
||||
r = results[0]
|
||||
self.assertEqual(r['url'], 'https://torrentz.eu/4362e08b1d80e1820fb2550b752f9f3126fe76d6')
|
||||
self.assertEqual(r['url'], 'https://torrentz2.eu/4362e08b1d80e1820fb2550b752f9f3126fe76d6')
|
||||
self.assertEqual(r['title'], 'Completely valid info books ebooks')
|
||||
# 22 Nov 2015 03:01:42
|
||||
self.assertEqual(r['publishedDate'], datetime(2015, 11, 22, 3, 1, 42))
|
||||
self.assertEqual(r['publishedDate'], datetime.fromtimestamp(1503595924))
|
||||
self.assertEqual(r['seed'], 14)
|
||||
self.assertEqual(r['leech'], 1)
|
||||
self.assertEqual(r['filesize'], 30 * 1024 * 1024)
|
||||
|
@ -79,7 +75,7 @@ class TestTorrentzEngine(SearxTestCase):
|
|||
|
||||
# testing against the second result
|
||||
r = results[1]
|
||||
self.assertEqual(r['url'], 'https://torrentz.eu/poaskdpokaspod')
|
||||
self.assertEqual(r['url'], 'https://torrentz2.eu/poaskdpokaspod')
|
||||
self.assertEqual(r['title'], 'Invalid hash and date and filesize books ebooks')
|
||||
self.assertEqual(r['seed'], 5555)
|
||||
self.assertEqual(r['leech'], 1234567)
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
# are written in current directory to avoid overwriting in case something goes wrong.
|
||||
|
||||
from requests import get
|
||||
from urllib import urlencode
|
||||
from lxml.html import fromstring
|
||||
from json import loads, dumps
|
||||
from json import loads, dump
|
||||
import io
|
||||
from sys import path
|
||||
path.append('../searx') # noqa
|
||||
from searx import settings
|
||||
from searx.url_utils import urlencode
|
||||
from searx.engines import initialize_engines, engines
|
||||
|
||||
# Geonames API for country names.
|
||||
|
@ -70,7 +70,7 @@ def get_country_name(locale):
|
|||
json = loads(response.text)
|
||||
content = json.get('geonames', None)
|
||||
if content is None or len(content) != 1:
|
||||
print "No country name found for " + locale[0] + "-" + locale[1]
|
||||
print("No country name found for " + locale[0] + "-" + locale[1])
|
||||
return ''
|
||||
|
||||
return content[0].get('countryName', '')
|
||||
|
@ -84,11 +84,11 @@ def fetch_supported_languages():
|
|||
try:
|
||||
engines_languages[engine_name] = engines[engine_name].fetch_supported_languages()
|
||||
except Exception as e:
|
||||
print e
|
||||
print(e)
|
||||
|
||||
# write json file
|
||||
with io.open(engines_languages_file, "w", encoding="utf-8") as f:
|
||||
f.write(unicode(dumps(engines_languages, ensure_ascii=False, encoding="utf-8")))
|
||||
dump(engines_languages, f, ensure_ascii=False)
|
||||
|
||||
|
||||
# Join all language lists.
|
||||
|
@ -97,7 +97,7 @@ def join_language_lists():
|
|||
global languages
|
||||
# include wikipedia first for more accurate language names
|
||||
languages = {code: lang for code, lang
|
||||
in engines_languages['wikipedia'].iteritems()
|
||||
in engines_languages['wikipedia'].items()
|
||||
if valid_code(code)}
|
||||
|
||||
for engine_name in engines_languages:
|
||||
|
@ -121,7 +121,7 @@ def join_language_lists():
|
|||
# filter list to include only languages supported by most engines
|
||||
min_supported_engines = int(0.70 * len(engines_languages))
|
||||
languages = {code: lang for code, lang
|
||||
in languages.iteritems()
|
||||
in languages.items()
|
||||
if len(lang.get('counter', [])) >= min_supported_engines or
|
||||
len(languages.get(code.split('-')[0], {}).get('counter', [])) >= min_supported_engines}
|
||||
|
||||
|
@ -165,7 +165,7 @@ def filter_single_country_languages():
|
|||
|
||||
# Write languages.py.
|
||||
def write_languages_file():
|
||||
new_file = open(languages_file, 'w')
|
||||
new_file = open(languages_file, 'wb')
|
||||
file_content = '# -*- coding: utf-8 -*-\n'\
|
||||
+ '# list of language codes\n'\
|
||||
+ '# this file is generated automatically by utils/update_search_languages.py\n'\
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
SEARX_DIR='searx'
|
||||
|
||||
pybabel extract -F babel.cfg -o messages.pot $SEARX_DIR
|
||||
for f in `ls $SEARX_DIR'/translations/'`; do
|
||||
pybabel update -N -i messages.pot -d $SEARX_DIR'/translations/' -l $f
|
||||
pybabel extract -F babel.cfg -o messages.pot "$SEARX_DIR"
|
||||
for f in `ls "$SEARX_DIR"'/translations/'`; do
|
||||
pybabel update -N -i messages.pot -d "$SEARX_DIR"'/translations/' -l "$f"
|
||||
done
|
||||
|
||||
echo '[!] update done, edit .po files if required and run pybabel compile -d searx/translations/'
|
||||
|
|
Loading…
Reference in New Issue