update searx 0.7
|
@ -6,6 +6,7 @@ Major contributing authors:
|
|||
- Matej Cotman
|
||||
- Thomas Pointhuber
|
||||
- Alexandre Flament
|
||||
- @Cqoicebordel
|
||||
|
||||
People who have submitted patches/translates, reported bugs, consulted features or
|
||||
generally made searx better:
|
||||
|
@ -27,8 +28,8 @@ generally made searx better:
|
|||
- Martin Zimmermann
|
||||
- @courgette
|
||||
- @kernc
|
||||
- @Cqoicebordel
|
||||
- @Reventl0v
|
||||
- Caner Başaran
|
||||
- Benjamin Sonntag
|
||||
- @opi
|
||||
- @dimqua
|
||||
|
|
|
@ -1,3 +1,35 @@
|
|||
0.7.0 2015.02.03
|
||||
================
|
||||
|
||||
- New engines
|
||||
|
||||
- Digg
|
||||
- Google Play Store
|
||||
- Deezer
|
||||
- Btdigg
|
||||
- Mixcloud
|
||||
- 1px
|
||||
- Image proxy
|
||||
- Search speed improvements
|
||||
- Autocompletition of engines, shortcuts and supported languages
|
||||
- Translation updates (New locales: Turkish, Russian)
|
||||
- Default theme changed to oscar
|
||||
- Settings option to disable engines by default
|
||||
- UI code cleanup and restructure
|
||||
- Engine tests
|
||||
- Multiple engine bug fixes and tweaks
|
||||
- Config option to set default interface locale
|
||||
- Flexible result template handling
|
||||
- Application logging and sophisticated engine exception tracebacks
|
||||
- Kickass torrent size display (oscar theme)
|
||||
|
||||
|
||||
New dependencies
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
- pygments - http://pygments.org/
|
||||
|
||||
|
||||
0.6.0 - 2014.12.25
|
||||
==================
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ minimal: bin/buildout minimal.cfg setup.py
|
|||
|
||||
styles:
|
||||
@lessc -x searx/static/themes/default/less/style.less > searx/static/themes/default/css/style.css
|
||||
@lessc -x searx/static/themes/courgette/less/style.less > searx/static/themes/courgette/css/style.css
|
||||
@lessc -x searx/static/less/bootstrap/bootstrap.less > searx/static/css/bootstrap.min.css
|
||||
@lessc -x searx/static/themes/oscar/less/oscar/oscar.less > searx/static/themes/oscar/css/oscar.min.css
|
||||
|
||||
|
|
|
@ -3,4 +3,5 @@ flask-babel
|
|||
requests
|
||||
lxml
|
||||
pyyaml
|
||||
pygments
|
||||
python-dateutil
|
||||
|
|
|
@ -17,13 +17,13 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
|
|||
|
||||
|
||||
from lxml import etree
|
||||
from requests import get
|
||||
from json import loads
|
||||
from urllib import urlencode
|
||||
from searx.languages import language_codes
|
||||
from searx.engines import (
|
||||
categories, engines, engine_shortcuts
|
||||
)
|
||||
from searx.poolrequests import get
|
||||
|
||||
|
||||
def searx_bang(full_query):
|
||||
|
@ -35,33 +35,34 @@ def searx_bang(full_query):
|
|||
results = []
|
||||
|
||||
# check if current query stats with !bang
|
||||
if full_query.getSearchQuery()[0] == '!':
|
||||
first_char = full_query.getSearchQuery()[0]
|
||||
if first_char == '!' or first_char == '?':
|
||||
if len(full_query.getSearchQuery()) == 1:
|
||||
# show some example queries
|
||||
# TODO, check if engine is not avaliable
|
||||
results.append("!images")
|
||||
results.append("!wikipedia")
|
||||
results.append("!osm")
|
||||
results.append(first_char + "images")
|
||||
results.append(first_char + "wikipedia")
|
||||
results.append(first_char + "osm")
|
||||
else:
|
||||
engine_query = full_query.getSearchQuery()[1:]
|
||||
|
||||
# check if query starts with categorie name
|
||||
for categorie in categories:
|
||||
if categorie.startswith(engine_query):
|
||||
results.append('!{categorie}'.format(categorie=categorie))
|
||||
results.append(first_char+'{categorie}'.format(categorie=categorie))
|
||||
|
||||
# check if query starts with engine name
|
||||
for engine in engines:
|
||||
if engine.startswith(engine_query.replace('_', ' ')):
|
||||
results.append('!{engine}'.format(engine=engine.replace(' ', '_')))
|
||||
results.append(first_char+'{engine}'.format(engine=engine.replace(' ', '_')))
|
||||
|
||||
# check if query starts with engine shortcut
|
||||
for engine_shortcut in engine_shortcuts:
|
||||
if engine_shortcut.startswith(engine_query):
|
||||
results.append('!{engine_shortcut}'.format(engine_shortcut=engine_shortcut))
|
||||
results.append(first_char+'{engine_shortcut}'.format(engine_shortcut=engine_shortcut))
|
||||
|
||||
# check if current query stats with :bang
|
||||
elif full_query.getSearchQuery()[0] == ':':
|
||||
elif first_char == ':':
|
||||
if len(full_query.getSearchQuery()) == 1:
|
||||
# show some example queries
|
||||
results.append(":en")
|
||||
|
|
|
@ -69,17 +69,17 @@ def load_engine(engine_data):
|
|||
engine.categories = ['general']
|
||||
|
||||
if not hasattr(engine, 'language_support'):
|
||||
# engine.language_support = False
|
||||
engine.language_support = True
|
||||
|
||||
if not hasattr(engine, 'timeout'):
|
||||
# engine.language_support = False
|
||||
engine.timeout = settings['server']['request_timeout']
|
||||
|
||||
if not hasattr(engine, 'shortcut'):
|
||||
# engine.shortcut = '''
|
||||
engine.shortcut = ''
|
||||
|
||||
if not hasattr(engine, 'disabled'):
|
||||
engine.disabled = False
|
||||
|
||||
# checking required variables
|
||||
for engine_attr in dir(engine):
|
||||
if engine_attr.startswith('_'):
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
from urllib import urlencode
|
||||
from cgi import escape
|
||||
from lxml import html
|
||||
from searx.engines.xpath import extract_text
|
||||
|
||||
# engine dependent config
|
||||
categories = ['general']
|
||||
|
@ -55,8 +56,8 @@ def response(resp):
|
|||
for result in dom.xpath('//div[@class="sa_cc"]'):
|
||||
link = result.xpath('.//h3/a')[0]
|
||||
url = link.attrib.get('href')
|
||||
title = ' '.join(link.xpath('.//text()'))
|
||||
content = escape(' '.join(result.xpath('.//p//text()')))
|
||||
title = extract_text(link)
|
||||
content = escape(extract_text(result.xpath('.//p')))
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
|
@ -71,8 +72,8 @@ def response(resp):
|
|||
for result in dom.xpath('//li[@class="b_algo"]'):
|
||||
link = result.xpath('.//h2/a')[0]
|
||||
url = link.attrib.get('href')
|
||||
title = ' '.join(link.xpath('.//text()'))
|
||||
content = escape(' '.join(result.xpath('.//p//text()')))
|
||||
title = extract_text(link)
|
||||
content = escape(extract_text(result.xpath('.//p')))
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
|
|
|
@ -25,6 +25,7 @@ paging = True
|
|||
# search-url
|
||||
base_url = 'https://www.bing.com/'
|
||||
search_string = 'images/search?{query}&count=10&first={offset}'
|
||||
thumb_url = "http://ts1.mm.bing.net/th?id={ihk}"
|
||||
|
||||
|
||||
# do search-request
|
||||
|
@ -32,7 +33,10 @@ def request(query, params):
|
|||
offset = (params['pageno'] - 1) * 10 + 1
|
||||
|
||||
# required for cookie
|
||||
language = 'en-US'
|
||||
if params['language'] == 'all':
|
||||
language = 'en-US'
|
||||
else:
|
||||
language = params['language'].replace('_', '-')
|
||||
|
||||
search_path = search_string.format(
|
||||
query=urlencode({'q': query}),
|
||||
|
@ -63,6 +67,8 @@ def response(resp):
|
|||
yaml_data = load(p.sub(r'\1\2: \3', link.attrib.get('m')))
|
||||
|
||||
title = link.attrib.get('t1')
|
||||
ihk = link.attrib.get('ihk')
|
||||
|
||||
#url = 'http://' + link.attrib.get('t3')
|
||||
url = yaml_data.get('surl')
|
||||
img_src = yaml_data.get('imgurl')
|
||||
|
@ -72,6 +78,7 @@ def response(resp):
|
|||
'url': url,
|
||||
'title': title,
|
||||
'content': '',
|
||||
'thumbnail_src': thumb_url.format(ihk=ihk),
|
||||
'img_src': img_src})
|
||||
|
||||
# TODO stop parsing if 10 images are found
|
||||
|
|
|
@ -15,6 +15,7 @@ from lxml import html
|
|||
from datetime import datetime, timedelta
|
||||
from dateutil import parser
|
||||
import re
|
||||
from searx.engines.xpath import extract_text
|
||||
|
||||
# engine dependent config
|
||||
categories = ['news']
|
||||
|
@ -39,10 +40,10 @@ def request(query, params):
|
|||
query=urlencode({'q': query, 'setmkt': language}),
|
||||
offset=offset)
|
||||
|
||||
params['cookies']['SRCHHPGUSR'] = \
|
||||
'NEWWND=0&NRSLT=-1&SRCHLANG=' + language.split('-')[0]
|
||||
params['cookies']['_FP'] = "ui=en-US"
|
||||
|
||||
params['url'] = base_url + search_path
|
||||
|
||||
return params
|
||||
|
||||
|
||||
|
@ -56,44 +57,35 @@ def response(resp):
|
|||
for result in dom.xpath('//div[@class="sn_r"]'):
|
||||
link = result.xpath('.//div[@class="newstitle"]/a')[0]
|
||||
url = link.attrib.get('href')
|
||||
title = ' '.join(link.xpath('.//text()'))
|
||||
contentXPath = result.xpath('.//div[@class="sn_txt"]/div'
|
||||
'//span[@class="sn_snip"]//text()')
|
||||
if contentXPath is not None:
|
||||
content = escape(' '.join(contentXPath))
|
||||
title = extract_text(link)
|
||||
contentXPath = result.xpath('.//div[@class="sn_txt"]/div//span[@class="sn_snip"]')
|
||||
content = escape(extract_text(contentXPath))
|
||||
|
||||
# parse publishedDate
|
||||
publishedDateXPath = result.xpath('.//div[@class="sn_txt"]/div'
|
||||
'//span[contains(@class,"sn_ST")]'
|
||||
'//span[contains(@class,"sn_tm")]'
|
||||
'//text()')
|
||||
if publishedDateXPath is not None:
|
||||
publishedDate = escape(' '.join(publishedDateXPath))
|
||||
'//span[contains(@class,"sn_tm")]')
|
||||
|
||||
publishedDate = escape(extract_text(publishedDateXPath))
|
||||
|
||||
if re.match("^[0-9]+ minute(s|) ago$", publishedDate):
|
||||
timeNumbers = re.findall(r'\d+', publishedDate)
|
||||
publishedDate = datetime.now()\
|
||||
- timedelta(minutes=int(timeNumbers[0]))
|
||||
publishedDate = datetime.now() - timedelta(minutes=int(timeNumbers[0]))
|
||||
elif re.match("^[0-9]+ hour(s|) ago$", publishedDate):
|
||||
timeNumbers = re.findall(r'\d+', publishedDate)
|
||||
publishedDate = datetime.now()\
|
||||
- timedelta(hours=int(timeNumbers[0]))
|
||||
elif re.match("^[0-9]+ hour(s|),"
|
||||
" [0-9]+ minute(s|) ago$", publishedDate):
|
||||
publishedDate = datetime.now() - timedelta(hours=int(timeNumbers[0]))
|
||||
elif re.match("^[0-9]+ hour(s|), [0-9]+ minute(s|) ago$", publishedDate):
|
||||
timeNumbers = re.findall(r'\d+', publishedDate)
|
||||
publishedDate = datetime.now()\
|
||||
- timedelta(hours=int(timeNumbers[0]))\
|
||||
- timedelta(minutes=int(timeNumbers[1]))
|
||||
elif re.match("^[0-9]+ day(s|) ago$", publishedDate):
|
||||
timeNumbers = re.findall(r'\d+', publishedDate)
|
||||
publishedDate = datetime.now()\
|
||||
- timedelta(days=int(timeNumbers[0]))
|
||||
publishedDate = datetime.now() - timedelta(days=int(timeNumbers[0]))
|
||||
else:
|
||||
try:
|
||||
# FIXME use params['language'] to parse either mm/dd or dd/mm
|
||||
publishedDate = parser.parse(publishedDate, dayfirst=False)
|
||||
except TypeError:
|
||||
# FIXME
|
||||
publishedDate = datetime.now()
|
||||
|
||||
# append result
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
## BTDigg (Videos, Music, Files)
|
||||
#
|
||||
# @website https://btdigg.org
|
||||
# @provide-api yes (on demand)
|
||||
#
|
||||
# @using-api no
|
||||
# @results HTML (using search portal)
|
||||
# @stable no (HTML can change)
|
||||
# @parse url, title, content, seed, leech, magnetlink
|
||||
|
||||
from urlparse import urljoin
|
||||
from cgi import escape
|
||||
from urllib import quote
|
||||
from lxml import html
|
||||
from operator import itemgetter
|
||||
from searx.engines.xpath import extract_text
|
||||
|
||||
# engine dependent config
|
||||
categories = ['videos', 'music', 'files']
|
||||
paging = True
|
||||
|
||||
# search-url
|
||||
url = 'https://btdigg.org'
|
||||
search_url = url + '/search?q={search_term}&p={pageno}'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
params['url'] = search_url.format(search_term=quote(query),
|
||||
pageno=params['pageno']-1)
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
dom = html.fromstring(resp.text)
|
||||
|
||||
search_res = dom.xpath('//div[@id="search_res"]/table/tr')
|
||||
|
||||
# return empty array if nothing is found
|
||||
if not search_res:
|
||||
return []
|
||||
|
||||
# parse results
|
||||
for result in search_res:
|
||||
link = result.xpath('.//td[@class="torrent_name"]//a')[0]
|
||||
href = urljoin(url, link.attrib.get('href'))
|
||||
title = escape(extract_text(link))
|
||||
content = escape(extract_text(result.xpath('.//pre[@class="snippet"]')[0]))
|
||||
content = "<br />".join(content.split("\n"))
|
||||
|
||||
filesize = result.xpath('.//span[@class="attr_val"]/text()')[0].split()[0]
|
||||
filesize_multiplier = result.xpath('.//span[@class="attr_val"]/text()')[0].split()[1]
|
||||
files = result.xpath('.//span[@class="attr_val"]/text()')[1]
|
||||
seed = result.xpath('.//span[@class="attr_val"]/text()')[2]
|
||||
|
||||
# convert seed to int if possible
|
||||
if seed.isdigit():
|
||||
seed = int(seed)
|
||||
else:
|
||||
seed = 0
|
||||
|
||||
leech = 0
|
||||
|
||||
# convert filesize to byte if possible
|
||||
try:
|
||||
filesize = float(filesize)
|
||||
|
||||
# convert filesize to byte
|
||||
if filesize_multiplier == 'TB':
|
||||
filesize = int(filesize * 1024 * 1024 * 1024 * 1024)
|
||||
elif filesize_multiplier == 'GB':
|
||||
filesize = int(filesize * 1024 * 1024 * 1024)
|
||||
elif filesize_multiplier == 'MB':
|
||||
filesize = int(filesize * 1024 * 1024)
|
||||
elif filesize_multiplier == 'KB':
|
||||
filesize = int(filesize * 1024)
|
||||
except:
|
||||
filesize = None
|
||||
|
||||
# convert files to int if possible
|
||||
if files.isdigit():
|
||||
files = int(files)
|
||||
else:
|
||||
files = None
|
||||
|
||||
magnetlink = result.xpath('.//td[@class="ttth"]//a')[0].attrib['href']
|
||||
|
||||
# append result
|
||||
results.append({'url': href,
|
||||
'title': title,
|
||||
'content': content,
|
||||
'seed': seed,
|
||||
'leech': leech,
|
||||
'filesize': filesize,
|
||||
'files': files,
|
||||
'magnetlink': magnetlink,
|
||||
'template': 'torrent.html'})
|
||||
|
||||
# return results sorted by seeder
|
||||
return sorted(results, key=itemgetter('seed'), reverse=True)
|
|
@ -6,13 +6,15 @@
|
|||
# @using-api no (TODO, rewrite to api)
|
||||
# @results HTML
|
||||
# @stable no (HTML can change)
|
||||
# @parse url, title, thumbnail, img_src
|
||||
# @parse url, title, thumbnail_src, img_src
|
||||
#
|
||||
# @todo rewrite to api
|
||||
|
||||
from urllib import urlencode
|
||||
from urlparse import urljoin
|
||||
from lxml import html
|
||||
import re
|
||||
from searx.engines.xpath import extract_text
|
||||
|
||||
# engine dependent config
|
||||
categories = ['images']
|
||||
|
@ -43,18 +45,22 @@ def response(resp):
|
|||
|
||||
dom = html.fromstring(resp.text)
|
||||
|
||||
regex = re.compile('\/200H\/')
|
||||
|
||||
# parse results
|
||||
for result in dom.xpath('//div[contains(@class, "tt-a tt-fh")]'):
|
||||
link = result.xpath('.//a[contains(@class, "thumb")]')[0]
|
||||
url = urljoin(base_url, link.attrib.get('href'))
|
||||
title_links = result.xpath('.//span[@class="details"]//a[contains(@class, "t")]') # noqa
|
||||
title = ''.join(title_links[0].xpath('.//text()'))
|
||||
img_src = link.xpath('.//img')[0].attrib['src']
|
||||
title_links = result.xpath('.//span[@class="details"]//a[contains(@class, "t")]')
|
||||
title = extract_text(title_links[0])
|
||||
thumbnail_src = link.xpath('.//img')[0].attrib.get('src')
|
||||
img_src = regex.sub('/', thumbnail_src)
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
'img_src': img_src,
|
||||
'thumbnail_src': thumbnail_src,
|
||||
'template': 'images.html'})
|
||||
|
||||
# return results
|
||||
|
|
|
@ -44,7 +44,7 @@ def response(resp):
|
|||
|
||||
search_result = loads(resp.text)
|
||||
|
||||
if search_result['html'] == '':
|
||||
if 'html' not in search_result or search_result['html'] == '':
|
||||
return results
|
||||
|
||||
dom = html.fromstring(search_result['html'])
|
||||
|
|
|
@ -23,7 +23,7 @@ api_key = None
|
|||
|
||||
url = 'https://api.flickr.com/services/rest/?method=flickr.photos.search' +\
|
||||
'&api_key={api_key}&{text}&sort=relevance' +\
|
||||
'&extras=description%2C+owner_name%2C+url_o%2C+url_z' +\
|
||||
'&extras=description%2C+owner_name%2C+url_o%2C+url_n%2C+url_z' +\
|
||||
'&per_page={nb_per_page}&format=json&nojsoncallback=1&page={page}'
|
||||
photo_url = 'https://www.flickr.com/photos/{userid}/{photoid}'
|
||||
|
||||
|
@ -65,6 +65,14 @@ def response(resp):
|
|||
else:
|
||||
continue
|
||||
|
||||
# For a bigger thumbnail, keep only the url_z, not the url_n
|
||||
if 'url_n' in photo:
|
||||
thumbnail_src = photo['url_n']
|
||||
elif 'url_z' in photo:
|
||||
thumbnail_src = photo['url_z']
|
||||
else:
|
||||
thumbnail_src = img_src
|
||||
|
||||
url = build_flickr_url(photo['owner'], photo['id'])
|
||||
|
||||
title = photo['title']
|
||||
|
@ -80,6 +88,7 @@ def response(resp):
|
|||
results.append({'url': url,
|
||||
'title': title,
|
||||
'img_src': img_src,
|
||||
'thumbnail_src': thumbnail_src,
|
||||
'content': content,
|
||||
'template': 'images.html'})
|
||||
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Flickr (Images)
|
||||
#
|
||||
# @website https://www.flickr.com
|
||||
# @provide-api yes (https://secure.flickr.com/services/api/flickr.photos.search.html)
|
||||
#
|
||||
# @using-api no
|
||||
# @results HTML
|
||||
# @stable no
|
||||
# @parse url, title, thumbnail, img_src
|
||||
|
||||
from urllib import urlencode
|
||||
from json import loads
|
||||
import re
|
||||
from searx.engines import logger
|
||||
|
||||
|
||||
logger = logger.getChild('flickr-noapi')
|
||||
|
||||
categories = ['images']
|
||||
|
||||
url = 'https://secure.flickr.com/'
|
||||
search_url = url + 'search/?{query}&page={page}'
|
||||
photo_url = 'https://www.flickr.com/photos/{userid}/{photoid}'
|
||||
regex = re.compile(r"\"search-photos-models\",\"photos\":(.*}),\"totalItems\":", re.DOTALL)
|
||||
image_sizes = ('o', 'k', 'h', 'b', 'c', 'z', 'n', 'm', 't', 'q', 's')
|
||||
|
||||
paging = True
|
||||
|
||||
|
||||
def build_flickr_url(user_id, photo_id):
|
||||
return photo_url.format(userid=user_id, photoid=photo_id)
|
||||
|
||||
|
||||
def request(query, params):
|
||||
params['url'] = search_url.format(query=urlencode({'text': query}),
|
||||
page=params['pageno'])
|
||||
return params
|
||||
|
||||
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
matches = regex.search(resp.text)
|
||||
|
||||
if matches is None:
|
||||
return results
|
||||
|
||||
match = matches.group(1)
|
||||
search_results = loads(match)
|
||||
|
||||
if '_data' not in search_results:
|
||||
return []
|
||||
|
||||
photos = search_results['_data']
|
||||
|
||||
for photo in photos:
|
||||
|
||||
# In paged configuration, the first pages' photos
|
||||
# are represented by a None object
|
||||
if photo is None:
|
||||
continue
|
||||
|
||||
img_src = None
|
||||
# From the biggest to the lowest format
|
||||
for image_size in image_sizes:
|
||||
if image_size in photo['sizes']:
|
||||
img_src = photo['sizes'][image_size]['url']
|
||||
break
|
||||
|
||||
if not img_src:
|
||||
logger.debug('cannot find valid image size: {0}'.format(repr(photo)))
|
||||
continue
|
||||
|
||||
if 'id' not in photo['owner']:
|
||||
continue
|
||||
|
||||
# For a bigger thumbnail, keep only the url_z, not the url_n
|
||||
if 'n' in photo['sizes']:
|
||||
thumbnail_src = photo['sizes']['n']['url']
|
||||
elif 'z' in photo['sizes']:
|
||||
thumbnail_src = photo['sizes']['z']['url']
|
||||
else:
|
||||
thumbnail_src = img_src
|
||||
|
||||
url = build_flickr_url(photo['owner']['id'], photo['id'])
|
||||
|
||||
title = photo.get('title', '')
|
||||
|
||||
content = '<span class="photo-author">' +\
|
||||
photo['owner']['username'] +\
|
||||
'</span><br />'
|
||||
|
||||
if 'description' in photo:
|
||||
content = content +\
|
||||
'<span class="description">' +\
|
||||
photo['description'] +\
|
||||
'</span>'
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
'img_src': img_src,
|
||||
'thumbnail_src': thumbnail_src,
|
||||
'content': content,
|
||||
'template': 'images.html'})
|
||||
|
||||
return results
|
|
@ -11,6 +11,7 @@
|
|||
from urllib import urlencode
|
||||
from urlparse import urlparse, parse_qsl
|
||||
from lxml import html
|
||||
from searx.poolrequests import get
|
||||
from searx.engines.xpath import extract_text, extract_url
|
||||
|
||||
# engine dependent config
|
||||
|
@ -39,6 +40,17 @@ images_xpath = './/div/a'
|
|||
image_url_xpath = './@href'
|
||||
image_img_src_xpath = './img/@src'
|
||||
|
||||
pref_cookie = ''
|
||||
|
||||
|
||||
# see https://support.google.com/websearch/answer/873?hl=en
|
||||
def get_google_pref_cookie():
|
||||
global pref_cookie
|
||||
if pref_cookie == '':
|
||||
resp = get('https://www.google.com/ncr', allow_redirects=False)
|
||||
pref_cookie = resp.cookies["PREF"]
|
||||
return pref_cookie
|
||||
|
||||
|
||||
# remove google-specific tracking-url
|
||||
def parse_url(url_string):
|
||||
|
@ -64,6 +76,7 @@ def request(query, params):
|
|||
query=urlencode({'q': query}))
|
||||
|
||||
params['headers']['Accept-Language'] = language
|
||||
params['cookies']['PREF'] = get_google_pref_cookie()
|
||||
|
||||
return params
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ paging = True
|
|||
|
||||
# search-url
|
||||
url = 'https://ajax.googleapis.com/'
|
||||
search_url = url + 'ajax/services/search/images?v=1.0&start={offset}&rsz=large&safe=off&filter=off&{query}' # noqa
|
||||
search_url = url + 'ajax/services/search/images?v=1.0&start={offset}&rsz=large&safe=off&filter=off&{query}'
|
||||
|
||||
|
||||
# do search-request
|
||||
|
@ -45,13 +45,15 @@ def response(resp):
|
|||
for result in search_res['responseData']['results']:
|
||||
href = result['originalContextUrl']
|
||||
title = result['title']
|
||||
if not result['url']:
|
||||
if 'url' not in result:
|
||||
continue
|
||||
thumbnail_src = result['tbUrl']
|
||||
|
||||
# append result
|
||||
results.append({'url': href,
|
||||
'title': title,
|
||||
'content': '',
|
||||
'content': result['content'],
|
||||
'thumbnail_src': thumbnail_src,
|
||||
'img_src': unquote(result['url']),
|
||||
'template': 'images.html'})
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ language_support = True
|
|||
|
||||
# engine dependent config
|
||||
url = 'https://ajax.googleapis.com/'
|
||||
search_url = url + 'ajax/services/search/news?v=2.0&start={offset}&rsz=large&safe=off&filter=off&{query}&hl={language}' # noqa
|
||||
search_url = url + 'ajax/services/search/news?v=2.0&start={offset}&rsz=large&safe=off&filter=off&{query}&hl={lang}'
|
||||
|
||||
|
||||
# do search-request
|
||||
|
@ -33,7 +33,7 @@ def request(query, params):
|
|||
|
||||
params['url'] = search_url.format(offset=offset,
|
||||
query=urlencode({'q': query}),
|
||||
language=language)
|
||||
lang=language)
|
||||
|
||||
return params
|
||||
|
||||
|
@ -52,6 +52,8 @@ def response(resp):
|
|||
for result in search_res['responseData']['results']:
|
||||
# parse publishedDate
|
||||
publishedDate = parser.parse(result['publishedDate'])
|
||||
if 'url' not in result:
|
||||
continue
|
||||
|
||||
# append result
|
||||
results.append({'url': result['unescapedUrl'],
|
||||
|
|
|
@ -13,6 +13,7 @@ from cgi import escape
|
|||
from urllib import quote
|
||||
from lxml import html
|
||||
from operator import itemgetter
|
||||
from searx.engines.xpath import extract_text
|
||||
|
||||
# engine dependent config
|
||||
categories = ['videos', 'music', 'files']
|
||||
|
@ -56,9 +57,8 @@ def response(resp):
|
|||
for result in search_res[1:]:
|
||||
link = result.xpath('.//a[@class="cellMainLink"]')[0]
|
||||
href = urljoin(url, link.attrib['href'])
|
||||
title = ' '.join(link.xpath('.//text()'))
|
||||
content = escape(html.tostring(result.xpath(content_xpath)[0],
|
||||
method="text"))
|
||||
title = extract_text(link)
|
||||
content = escape(extract_text(result.xpath(content_xpath)))
|
||||
seed = result.xpath('.//td[contains(@class, "green")]/text()')[0]
|
||||
leech = result.xpath('.//td[contains(@class, "red")]/text()')[0]
|
||||
filesize = result.xpath('.//td[contains(@class, "nobr")]/text()')[0]
|
||||
|
@ -88,7 +88,7 @@ def response(resp):
|
|||
filesize = int(filesize * 1024 * 1024 * 1024)
|
||||
elif filesize_multiplier == 'MB':
|
||||
filesize = int(filesize * 1024 * 1024)
|
||||
elif filesize_multiplier == 'kb':
|
||||
elif filesize_multiplier == 'KB':
|
||||
filesize = int(filesize * 1024)
|
||||
except:
|
||||
filesize = None
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
## Mixcloud (Music)
|
||||
#
|
||||
# @website https://http://www.mixcloud.com/
|
||||
# @provide-api yes (http://www.mixcloud.com/developers/
|
||||
#
|
||||
# @using-api yes
|
||||
# @results JSON
|
||||
# @stable yes
|
||||
# @parse url, title, content, embedded, publishedDate
|
||||
|
||||
from json import loads
|
||||
from urllib import urlencode
|
||||
from dateutil import parser
|
||||
|
||||
# engine dependent config
|
||||
categories = ['music']
|
||||
paging = True
|
||||
|
||||
# search-url
|
||||
url = 'http://api.mixcloud.com/'
|
||||
search_url = url + 'search/?{query}&type=cloudcast&limit=10&offset={offset}'
|
||||
|
||||
embedded_url = '<iframe scrolling="no" frameborder="0" allowTransparency="true" ' +\
|
||||
'data-src="https://www.mixcloud.com/widget/iframe/?feed={url}" width="300" height="300"></iframe>'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
offset = (params['pageno'] - 1) * 10
|
||||
|
||||
params['url'] = search_url.format(query=urlencode({'q': query}),
|
||||
offset=offset)
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
search_res = loads(resp.text)
|
||||
|
||||
# parse results
|
||||
for result in search_res.get('data', []):
|
||||
title = result['name']
|
||||
url = result['url']
|
||||
content = result['user']['name']
|
||||
embedded = embedded_url.format(url=url)
|
||||
publishedDate = parser.parse(result['created_time'])
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
'embedded': embedded,
|
||||
'publishedDate': publishedDate,
|
||||
'content': content})
|
||||
|
||||
# return results
|
||||
return results
|
|
@ -13,13 +13,14 @@ from cgi import escape
|
|||
from urllib import quote
|
||||
from lxml import html
|
||||
from operator import itemgetter
|
||||
from searx.engines.xpath import extract_text
|
||||
|
||||
# engine dependent config
|
||||
categories = ['videos', 'music', 'files']
|
||||
paging = True
|
||||
|
||||
# search-url
|
||||
url = 'https://thepiratebay.cr/'
|
||||
url = 'https://thepiratebay.se/'
|
||||
search_url = url + 'search/{search_term}/{pageno}/99/{search_type}'
|
||||
|
||||
# piratebay specific type-definitions
|
||||
|
@ -29,7 +30,8 @@ search_types = {'files': '0',
|
|||
|
||||
# specific xpath variables
|
||||
magnet_xpath = './/a[@title="Download this torrent using magnet"]'
|
||||
content_xpath = './/font[@class="detDesc"]//text()'
|
||||
torrent_xpath = './/a[@title="Download this torrent"]'
|
||||
content_xpath = './/font[@class="detDesc"]'
|
||||
|
||||
|
||||
# do search-request
|
||||
|
@ -59,8 +61,8 @@ def response(resp):
|
|||
for result in search_res[1:]:
|
||||
link = result.xpath('.//div[@class="detName"]//a')[0]
|
||||
href = urljoin(url, link.attrib.get('href'))
|
||||
title = ' '.join(link.xpath('.//text()'))
|
||||
content = escape(' '.join(result.xpath(content_xpath)))
|
||||
title = extract_text(link)
|
||||
content = escape(extract_text(result.xpath(content_xpath)))
|
||||
seed, leech = result.xpath('.//td[@align="right"]/text()')[:2]
|
||||
|
||||
# convert seed to int if possible
|
||||
|
@ -76,6 +78,7 @@ def response(resp):
|
|||
leech = 0
|
||||
|
||||
magnetlink = result.xpath(magnet_xpath)[0]
|
||||
torrentfile = result.xpath(torrent_xpath)[0]
|
||||
|
||||
# append result
|
||||
results.append({'url': href,
|
||||
|
@ -83,7 +86,8 @@ def response(resp):
|
|||
'content': content,
|
||||
'seed': seed,
|
||||
'leech': leech,
|
||||
'magnetlink': magnetlink.attrib['href'],
|
||||
'magnetlink': magnetlink.attrib.get('href'),
|
||||
'torrentfile': torrentfile.attrib.get('href'),
|
||||
'template': 'torrent.html'})
|
||||
|
||||
# return results sorted by seeder
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
from urllib import urlencode
|
||||
from json import loads
|
||||
import cgi
|
||||
|
||||
|
||||
# engine dependent config
|
||||
categories = ['it']
|
||||
|
@ -20,6 +20,12 @@ paging = True
|
|||
url = 'https://searchcode.com/'
|
||||
search_url = url+'api/codesearch_I/?{query}&p={pageno}'
|
||||
|
||||
# special code-endings which are not recognised by the file ending
|
||||
code_endings = {'cs': 'c#',
|
||||
'h': 'c',
|
||||
'hpp': 'cpp',
|
||||
'cxx': 'cpp'}
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
|
@ -36,30 +42,27 @@ def response(resp):
|
|||
search_results = loads(resp.text)
|
||||
|
||||
# parse results
|
||||
for result in search_results['results']:
|
||||
for result in search_results.get('results', []):
|
||||
href = result['url']
|
||||
title = "" + result['name'] + " - " + result['filename']
|
||||
content = result['repo'] + "<br />"
|
||||
repo = result['repo']
|
||||
|
||||
lines = dict()
|
||||
for line, code in result['lines'].items():
|
||||
lines[int(line)] = code
|
||||
|
||||
content = content + '<pre class="code-formatter"><table class="code">'
|
||||
for line, code in sorted(lines.items()):
|
||||
content = content + '<tr><td class="line-number" style="padding-right:5px;">'
|
||||
content = content + str(line) + '</td><td class="code-snippet">'
|
||||
# Replace every two spaces with ' &nbps;' to keep formatting
|
||||
# while allowing the browser to break the line if necessary
|
||||
content = content + cgi.escape(code).replace('\t', ' ').replace(' ', ' ').replace(' ', ' ')
|
||||
content = content + "</td></tr>"
|
||||
|
||||
content = content + "</table></pre>"
|
||||
code_language = code_endings.get(
|
||||
result['filename'].split('.')[-1].lower(),
|
||||
result['filename'].split('.')[-1].lower())
|
||||
|
||||
# append result
|
||||
results.append({'url': href,
|
||||
'title': title,
|
||||
'content': content})
|
||||
'content': '',
|
||||
'repository': repo,
|
||||
'codelines': sorted(lines.items()),
|
||||
'code_language': code_language,
|
||||
'template': 'code.html'})
|
||||
|
||||
# return results
|
||||
return results
|
||||
|
|
|
@ -35,7 +35,7 @@ def response(resp):
|
|||
search_results = loads(resp.text)
|
||||
|
||||
# parse results
|
||||
for result in search_results['results']:
|
||||
for result in search_results.get('results', []):
|
||||
href = result['url']
|
||||
title = "[" + result['type'] + "] " +\
|
||||
result['namespace'] +\
|
||||
|
|
|
@ -12,6 +12,7 @@ from urlparse import urljoin
|
|||
from cgi import escape
|
||||
from urllib import urlencode
|
||||
from lxml import html
|
||||
from searx.engines.xpath import extract_text
|
||||
|
||||
# engine dependent config
|
||||
categories = ['it']
|
||||
|
@ -24,8 +25,7 @@ search_url = url+'search?{query}&page={pageno}'
|
|||
# specific xpath variables
|
||||
results_xpath = '//div[contains(@class,"question-summary")]'
|
||||
link_xpath = './/div[@class="result-link"]//a|.//div[@class="summary"]//h3//a'
|
||||
title_xpath = './/text()'
|
||||
content_xpath = './/div[@class="excerpt"]//text()'
|
||||
content_xpath = './/div[@class="excerpt"]'
|
||||
|
||||
|
||||
# do search-request
|
||||
|
@ -46,8 +46,8 @@ def response(resp):
|
|||
for result in dom.xpath(results_xpath):
|
||||
link = result.xpath(link_xpath)[0]
|
||||
href = urljoin(url, link.attrib.get('href'))
|
||||
title = escape(' '.join(link.xpath(title_xpath)))
|
||||
content = escape(' '.join(result.xpath(content_xpath)))
|
||||
title = escape(extract_text(link))
|
||||
content = escape(extract_text(result.xpath(content_xpath)))
|
||||
|
||||
# append result
|
||||
results.append({'url': href,
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#
|
||||
# @todo paging
|
||||
|
||||
from urllib import urlencode
|
||||
from lxml import html
|
||||
from cgi import escape
|
||||
import re
|
||||
|
@ -38,7 +37,6 @@ link_xpath = './/h3/a'
|
|||
# do search-request
|
||||
def request(query, params):
|
||||
offset = (params['pageno'] - 1) * 10
|
||||
query = urlencode({'q': query})[2:]
|
||||
|
||||
params['url'] = search_url
|
||||
params['method'] = 'POST'
|
||||
|
|
|
@ -59,8 +59,7 @@ def response(resp):
|
|||
url = base_url + videoid
|
||||
title = p.unescape(extract_text(result.xpath(title_xpath)))
|
||||
thumbnail = extract_text(result.xpath(content_xpath)[0])
|
||||
publishedDate = parser.parse(extract_text(
|
||||
result.xpath(publishedDate_xpath)[0]))
|
||||
publishedDate = parser.parse(extract_text(result.xpath(publishedDate_xpath)[0]))
|
||||
embedded = embedded_url.format(videoid=videoid)
|
||||
|
||||
# append result
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import json
|
||||
from requests import get
|
||||
from urllib import urlencode
|
||||
from searx.poolrequests import get
|
||||
from searx.utils import format_date_by_locale
|
||||
|
||||
result_count = 1
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
## 1x (Images)
|
||||
#
|
||||
# @website http://1x.com/
|
||||
# @provide-api no
|
||||
#
|
||||
# @using-api no
|
||||
# @results HTML
|
||||
# @stable no (HTML can change)
|
||||
# @parse url, title, thumbnail, img_src, content
|
||||
|
||||
|
||||
from urllib import urlencode
|
||||
from urlparse import urljoin
|
||||
from lxml import html
|
||||
import string
|
||||
import re
|
||||
|
||||
# engine dependent config
|
||||
categories = ['images']
|
||||
paging = False
|
||||
|
||||
# search-url
|
||||
base_url = 'http://1x.com'
|
||||
search_url = base_url+'/backend/search.php?{query}'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
params['url'] = search_url.format(query=urlencode({'q': query}))
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
# get links from result-text
|
||||
regex = re.compile('(</a>|<a)')
|
||||
results_parts = re.split(regex, resp.text)
|
||||
|
||||
cur_element = ''
|
||||
|
||||
# iterate over link parts
|
||||
for result_part in results_parts:
|
||||
# processed start and end of link
|
||||
if result_part == '<a':
|
||||
cur_element = result_part
|
||||
continue
|
||||
elif result_part != '</a>':
|
||||
cur_element += result_part
|
||||
continue
|
||||
|
||||
cur_element += result_part
|
||||
|
||||
# fix xml-error
|
||||
cur_element = string.replace(cur_element, '"></a>', '"/></a>')
|
||||
|
||||
dom = html.fromstring(cur_element)
|
||||
link = dom.xpath('//a')[0]
|
||||
|
||||
url = urljoin(base_url, link.attrib.get('href'))
|
||||
title = link.attrib.get('title', '')
|
||||
|
||||
thumbnail_src = urljoin(base_url, link.xpath('.//img')[0].attrib['src'])
|
||||
# TODO: get image with higher resolution
|
||||
img_src = thumbnail_src
|
||||
|
||||
# check if url is showing to a photo
|
||||
if '/photo/' not in url:
|
||||
continue
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
'img_src': img_src,
|
||||
'content': '',
|
||||
'thumbnail_src': thumbnail_src,
|
||||
'template': 'images.html'})
|
||||
|
||||
# return results
|
||||
return results
|
|
@ -0,0 +1,64 @@
|
|||
## 500px (Images)
|
||||
#
|
||||
# @website https://500px.com
|
||||
# @provide-api yes (https://developers.500px.com/)
|
||||
#
|
||||
# @using-api no
|
||||
# @results HTML
|
||||
# @stable no (HTML can change)
|
||||
# @parse url, title, thumbnail, img_src, content
|
||||
#
|
||||
# @todo rewrite to api
|
||||
|
||||
|
||||
from urllib import urlencode
|
||||
from urlparse import urljoin
|
||||
from lxml import html
|
||||
import re
|
||||
from searx.engines.xpath import extract_text
|
||||
|
||||
# engine dependent config
|
||||
categories = ['images']
|
||||
paging = True
|
||||
|
||||
# search-url
|
||||
base_url = 'https://500px.com'
|
||||
search_url = base_url + '/search?search?page={pageno}&type=photos&{query}'
|
||||
|
||||
|
||||
# do search-request
|
||||
def request(query, params):
|
||||
params['url'] = search_url.format(pageno=params['pageno'],
|
||||
query=urlencode({'q': query}))
|
||||
|
||||
return params
|
||||
|
||||
|
||||
# get response from search-request
|
||||
def response(resp):
|
||||
results = []
|
||||
|
||||
dom = html.fromstring(resp.text)
|
||||
regex = re.compile('3\.jpg.*$')
|
||||
|
||||
# parse results
|
||||
for result in dom.xpath('//div[@class="photo"]'):
|
||||
link = result.xpath('.//a')[0]
|
||||
url = urljoin(base_url, link.attrib.get('href'))
|
||||
title = extract_text(result.xpath('.//div[@class="title"]'))
|
||||
thumbnail_src = link.xpath('.//img')[0].attrib.get('src')
|
||||
# To have a bigger thumbnail, uncomment the next line
|
||||
# thumbnail_src = regex.sub('4.jpg', thumbnail_src)
|
||||
content = extract_text(result.xpath('.//div[@class="info"]'))
|
||||
img_src = regex.sub('2048.jpg', thumbnail_src)
|
||||
|
||||
# append result
|
||||
results.append({'url': url,
|
||||
'title': title,
|
||||
'img_src': img_src,
|
||||
'content': content,
|
||||
'thumbnail_src': thumbnail_src,
|
||||
'template': 'images.html'})
|
||||
|
||||
# return results
|
||||
return results
|
|
@ -28,13 +28,13 @@ def extract_text(xpath_results):
|
|||
result = ''
|
||||
for e in xpath_results:
|
||||
result = result + extract_text(e)
|
||||
return result
|
||||
return result.strip()
|
||||
elif type(xpath_results) in [_ElementStringResult, _ElementUnicodeResult]:
|
||||
# it's a string
|
||||
return ''.join(xpath_results)
|
||||
else:
|
||||
# it's a element
|
||||
return html_to_text(xpath_results.text_content())
|
||||
return html_to_text(xpath_results.text_content()).strip()
|
||||
|
||||
|
||||
def extract_url(xpath_results, search_url):
|
||||
|
|
|
@ -68,9 +68,18 @@ def response(resp):
|
|||
|
||||
search_results = raw_search_results.get('channels', {})[0].get('items', [])
|
||||
|
||||
if resp.search_params['category'] == 'general':
|
||||
for result in search_results:
|
||||
# parse image results
|
||||
if result.get('image'):
|
||||
# append result
|
||||
results.append({'url': result['url'],
|
||||
'title': result['title'],
|
||||
'content': '',
|
||||
'img_src': result['image'],
|
||||
'template': 'images.html'})
|
||||
|
||||
# parse general results
|
||||
for result in search_results:
|
||||
else:
|
||||
publishedDate = parser.parse(result['pubDate'])
|
||||
|
||||
# append result
|
||||
|
@ -79,17 +88,7 @@ def response(resp):
|
|||
'content': result['description'],
|
||||
'publishedDate': publishedDate})
|
||||
|
||||
elif resp.search_params['category'] == 'images':
|
||||
# parse image results
|
||||
for result in search_results:
|
||||
# append result
|
||||
results.append({'url': result['url'],
|
||||
'title': result['title'],
|
||||
'content': '',
|
||||
'img_src': result['image'],
|
||||
'template': 'images.html'})
|
||||
|
||||
#TODO parse video, audio and file results
|
||||
#TODO parse video, audio and file results
|
||||
|
||||
# return results
|
||||
return results
|
||||
|
|
|
@ -57,7 +57,7 @@ def response(resp):
|
|||
url = [x['href'] for x in result['link'] if x['type'] == 'text/html']
|
||||
|
||||
if not url:
|
||||
return
|
||||
continue
|
||||
|
||||
# remove tracking
|
||||
url = url[0].replace('feature=youtube_gdata', '')
|
||||
|
@ -73,7 +73,7 @@ def response(resp):
|
|||
pubdate = result['published']['$t']
|
||||
publishedDate = parser.parse(pubdate)
|
||||
|
||||
if result['media$group']['media$thumbnail']:
|
||||
if 'media$thumbnail' in result['media$group']:
|
||||
thumbnail = result['media$group']['media$thumbnail'][0]['url']
|
||||
|
||||
content = result['content']['$t']
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
import requests
|
||||
|
||||
|
||||
the_http_adapter = requests.adapters.HTTPAdapter(pool_connections=100)
|
||||
the_https_adapter = requests.adapters.HTTPAdapter(pool_connections=100)
|
||||
|
||||
|
||||
class SessionSinglePool(requests.Session):
|
||||
|
||||
def __init__(self):
|
||||
global the_https_adapter, the_http_adapter
|
||||
super(SessionSinglePool, self).__init__()
|
||||
|
||||
# reuse the same adapters
|
||||
self.adapters.clear()
|
||||
self.mount('https://', the_https_adapter)
|
||||
self.mount('http://', the_http_adapter)
|
||||
|
||||
def close(self):
|
||||
"""Call super, but clear adapters since there are managed globaly"""
|
||||
self.adapters.clear()
|
||||
super(SessionSinglePool, self).close()
|
||||
|
||||
|
||||
def request(method, url, **kwargs):
|
||||
"""same as requests/requests/api.py request(...) except it use SessionSinglePool"""
|
||||
session = SessionSinglePool()
|
||||
response = session.request(method=method, url=url, **kwargs)
|
||||
session.close()
|
||||
return response
|
||||
|
||||
|
||||
def get(url, **kwargs):
|
||||
kwargs.setdefault('allow_redirects', True)
|
||||
return request('get', url, **kwargs)
|
||||
|
||||
|
||||
def options(url, **kwargs):
|
||||
kwargs.setdefault('allow_redirects', True)
|
||||
return request('options', url, **kwargs)
|
||||
|
||||
|
||||
def head(url, **kwargs):
|
||||
kwargs.setdefault('allow_redirects', False)
|
||||
return request('head', url, **kwargs)
|
||||
|
||||
|
||||
def post(url, data=None, **kwargs):
|
||||
return request('post', url, data=data, **kwargs)
|
||||
|
||||
|
||||
def put(url, data=None, **kwargs):
|
||||
return request('put', url, data=data, **kwargs)
|
||||
|
||||
|
||||
def patch(url, data=None, **kwargs):
|
||||
return request('patch', url, data=data, **kwargs)
|
||||
|
||||
|
||||
def delete(url, **kwargs):
|
||||
return request('delete', url, **kwargs)
|
|
@ -88,18 +88,16 @@ class Query(object):
|
|||
prefix = query_part[1:].replace('_', ' ')
|
||||
|
||||
# check if prefix is equal with engine shortcut
|
||||
if prefix in engine_shortcuts\
|
||||
and not engine_shortcuts[prefix] in self.blocked_engines:
|
||||
if prefix in engine_shortcuts:
|
||||
parse_next = True
|
||||
self.engines.append({'category': 'none',
|
||||
'name': engine_shortcuts[prefix]})
|
||||
|
||||
# check if prefix is equal with engine name
|
||||
elif prefix in engines\
|
||||
and prefix not in self.blocked_engines:
|
||||
elif prefix in engines:
|
||||
parse_next = True
|
||||
self.engines.append({'category': 'none',
|
||||
'name': prefix})
|
||||
'name': prefix})
|
||||
|
||||
# check if prefix is equal with categorie name
|
||||
elif prefix in categories:
|
||||
|
@ -107,9 +105,9 @@ class Query(object):
|
|||
# are declared under that categorie name
|
||||
parse_next = True
|
||||
self.engines.extend({'category': prefix,
|
||||
'name': engine.name}
|
||||
'name': engine.name}
|
||||
for engine in categories[prefix]
|
||||
if engine not in self.blocked_engines)
|
||||
if (engine.name, prefix) not in self.blocked_engines)
|
||||
|
||||
if query_part[0] == '!':
|
||||
self.specific = True
|
||||
|
|
|
@ -15,9 +15,9 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
|
|||
(C) 2013- by Adam Tauber, <asciimoo@gmail.com>
|
||||
'''
|
||||
|
||||
import requests as requests_lib
|
||||
import threading
|
||||
import re
|
||||
import searx.poolrequests as requests_lib
|
||||
from itertools import izip_longest, chain
|
||||
from operator import itemgetter
|
||||
from Queue import Queue
|
||||
|
@ -27,11 +27,10 @@ from searx.engines import (
|
|||
categories, engines
|
||||
)
|
||||
from searx.languages import language_codes
|
||||
from searx.utils import gen_useragent
|
||||
from searx.utils import gen_useragent, get_blocked_engines
|
||||
from searx.query import Query
|
||||
from searx import logger
|
||||
|
||||
|
||||
logger = logger.getChild('search')
|
||||
|
||||
number_of_searches = 0
|
||||
|
@ -321,10 +320,7 @@ class Search(object):
|
|||
self.lang = 'all'
|
||||
|
||||
# set blocked engines
|
||||
if request.cookies.get('blocked_engines'):
|
||||
self.blocked_engines = request.cookies['blocked_engines'].split(',') # noqa
|
||||
else:
|
||||
self.blocked_engines = []
|
||||
self.blocked_engines = get_blocked_engines(engines, request.cookies)
|
||||
|
||||
self.results = []
|
||||
self.suggestions = []
|
||||
|
@ -384,12 +380,17 @@ class Search(object):
|
|||
for pd_name, pd in self.request_data.items():
|
||||
if pd_name.startswith('category_'):
|
||||
category = pd_name[9:]
|
||||
|
||||
# if category is not found in list, skip
|
||||
if category not in categories:
|
||||
continue
|
||||
|
||||
# add category to list
|
||||
self.categories.append(category)
|
||||
if pd != 'off':
|
||||
# add category to list
|
||||
self.categories.append(category)
|
||||
elif category in self.categories:
|
||||
# remove category from list if property is set to 'off'
|
||||
self.categories.remove(category)
|
||||
|
||||
# if no category is specified for this search,
|
||||
# using user-defined default-configuration which
|
||||
|
@ -410,9 +411,9 @@ class Search(object):
|
|||
# declared under the specific categories
|
||||
for categ in self.categories:
|
||||
self.engines.extend({'category': categ,
|
||||
'name': x.name}
|
||||
for x in categories[categ]
|
||||
if x.name not in self.blocked_engines)
|
||||
'name': engine.name}
|
||||
for engine in categories[categ]
|
||||
if (engine.name, categ) not in self.blocked_engines)
|
||||
|
||||
# do search-request
|
||||
def search(self, request):
|
||||
|
|
|
@ -4,10 +4,12 @@ server:
|
|||
debug : False # Debug mode, only for development
|
||||
request_timeout : 2.0 # seconds
|
||||
base_url : False # Set custom base_url. Possible values: False or "https://your.custom.host/location/"
|
||||
themes_path : "" # Custom ui themes path
|
||||
default_theme : default # ui theme
|
||||
themes_path : "" # Custom ui themes path - leave it blank if you didn't change
|
||||
default_theme : oscar # ui theme
|
||||
https_rewrite : True # Force rewrite result urls. See searx/https_rewrite.py
|
||||
useragent_suffix : "" # suffix of searx_useragent, could contain informations like an email address to the administrator
|
||||
image_proxy : False # Proxying image results through searx
|
||||
default_locale : "" # Default interface locale - leave blank to detect from browser information or use codes from the 'locales' config section
|
||||
|
||||
engines:
|
||||
- name : wikipedia
|
||||
|
@ -31,11 +33,15 @@ engines:
|
|||
locale : en-US
|
||||
shortcut : bin
|
||||
|
||||
- name : btdigg
|
||||
engine : btdigg
|
||||
shortcut : bt
|
||||
|
||||
- name : currency
|
||||
engine : currency_convert
|
||||
categories : general
|
||||
shortcut : cc
|
||||
|
||||
|
||||
- name : deezer
|
||||
engine : deezer
|
||||
shortcut : dz
|
||||
|
@ -48,7 +54,7 @@ engines:
|
|||
- name : ddg definitions
|
||||
engine : duckduckgo_definitions
|
||||
shortcut : ddd
|
||||
|
||||
|
||||
- name : digg
|
||||
engine : digg
|
||||
shortcut : dg
|
||||
|
@ -72,11 +78,16 @@ engines:
|
|||
# engine : filecrop
|
||||
# categories : files
|
||||
# shortcut : fc
|
||||
|
||||
|
||||
- name : 500px
|
||||
engine : 500px
|
||||
engine : www500px
|
||||
shortcut : px
|
||||
|
||||
- name : 1x
|
||||
engine : www1x
|
||||
shortcut : 1x
|
||||
disabled : True
|
||||
|
||||
- name : flickr
|
||||
categories : images
|
||||
shortcut : fl
|
||||
|
@ -85,11 +96,12 @@ engines:
|
|||
# engine : flickr
|
||||
# api_key: 'apikey' # required!
|
||||
# Or you can use the html non-stable engine, activated by default
|
||||
engine : flickr-noapi
|
||||
engine : flickr_noapi
|
||||
|
||||
- name : general-file
|
||||
engine : generalfile
|
||||
shortcut : gf
|
||||
disabled : True
|
||||
|
||||
- name : github
|
||||
engine : github
|
||||
|
@ -115,7 +127,8 @@ engines:
|
|||
content_xpath : //a[@class="subtitle"]
|
||||
categories : files
|
||||
shortcut : gpa
|
||||
|
||||
disabled : True
|
||||
|
||||
- name : google play movies
|
||||
engine : xpath
|
||||
search_url : https://play.google.com/store/search?q={query}&c=movies
|
||||
|
@ -124,7 +137,8 @@ engines:
|
|||
content_xpath : //a[@class="subtitle"]
|
||||
categories : videos
|
||||
shortcut : gpm
|
||||
|
||||
disabled : True
|
||||
|
||||
- name : google play music
|
||||
engine : xpath
|
||||
search_url : https://play.google.com/store/search?q={query}&c=music
|
||||
|
@ -133,7 +147,12 @@ engines:
|
|||
content_xpath : //a[@class="subtitle"]
|
||||
categories : music
|
||||
shortcut : gps
|
||||
|
||||
disabled : True
|
||||
|
||||
- name : mixcloud
|
||||
engine : mixcloud
|
||||
shortcut : mc
|
||||
|
||||
- name : openstreetmap
|
||||
engine : openstreetmap
|
||||
shortcut : osm
|
||||
|
@ -142,9 +161,9 @@ engines:
|
|||
engine : photon
|
||||
shortcut : ph
|
||||
|
||||
# - name : piratebay
|
||||
# engine : piratebay
|
||||
# shortcut : tpb
|
||||
- name : piratebay
|
||||
engine : piratebay
|
||||
shortcut : tpb
|
||||
|
||||
- name : kickass
|
||||
engine : kickass
|
||||
|
@ -157,14 +176,15 @@ engines:
|
|||
- name : stackoverflow
|
||||
engine : stackoverflow
|
||||
shortcut : st
|
||||
|
||||
|
||||
- name : searchcode doc
|
||||
engine : searchcode_doc
|
||||
shortcut : scd
|
||||
|
||||
|
||||
- name : searchcode code
|
||||
engine : searchcode_code
|
||||
shortcut : scc
|
||||
disabled : True
|
||||
|
||||
- name : subtitleseeker
|
||||
engine : subtitleseeker
|
||||
|
@ -229,7 +249,7 @@ engines:
|
|||
# shortcut : ya
|
||||
# base_url : 'http://localhost:8090'
|
||||
# number_of_results : 5
|
||||
# timeout: 3.0
|
||||
# timeout : 3.0
|
||||
|
||||
locales:
|
||||
en : English
|
||||
|
@ -241,3 +261,4 @@ locales:
|
|||
nl : Nederlands
|
||||
ja : 日本語 (Japanese)
|
||||
tr : Türkçe
|
||||
ru : Russian
|
||||
|
|
|
@ -7,6 +7,7 @@ server:
|
|||
themes_path : ""
|
||||
default_theme : default
|
||||
https_rewrite : True
|
||||
image_proxy : False
|
||||
|
||||
engines:
|
||||
- name : general_dummy
|
||||
|
|
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 5.3 KiB |
|
@ -0,0 +1,691 @@
|
|||
|
||||
@color-main: #3498DB;
|
||||
@color-focus: #0665A2;
|
||||
@color-other-links: #666;
|
||||
@color-fonts: #333;
|
||||
@center-width: 70em;
|
||||
|
||||
|
||||
|
||||
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
input[type="search"] {
|
||||
-webkit-appearance: textfield;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: @color-other-links;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
background: #EEE;
|
||||
}
|
||||
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
color: @color-other-links;
|
||||
}
|
||||
|
||||
.title h1 {
|
||||
font-size:7em;
|
||||
color:@color-main;
|
||||
margin:0 auto;
|
||||
line-height:100px;
|
||||
margin-top:-20px;
|
||||
padding-bottom:20px;
|
||||
}
|
||||
|
||||
.center {
|
||||
max-width: @center-width;
|
||||
text-align: center;
|
||||
background: rgba(255,255,255,0.6);
|
||||
padding: 2em;
|
||||
margin: 7% auto 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.center.search {
|
||||
position: static;
|
||||
width: auto;
|
||||
background: none;
|
||||
margin: auto;
|
||||
padding-top: 1.8em;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1001px) {
|
||||
.center:after {
|
||||
content: "";
|
||||
z-index: -1;
|
||||
background: url(../img/bg-body-index.jpg) no-repeat;
|
||||
background-size: cover;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
}
|
||||
.center.search:after {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
|
||||
.autocompleter-choices {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #FFF;
|
||||
}
|
||||
|
||||
.autocompleter-choices li {
|
||||
padding: 0.5em 1em;
|
||||
}
|
||||
|
||||
.autocompleter-choices li:hover {
|
||||
background: @color-main;
|
||||
color: #FFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#categories {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.top_margin {
|
||||
position: absolute;
|
||||
bottom: -3.5em;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.top_margin a {
|
||||
display: inline-block;
|
||||
margin-right: 1em;
|
||||
color: #FFF;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top_margin a:hover,
|
||||
.top_margin a:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1000px) {
|
||||
.center { background: none; }
|
||||
.top_margin a {
|
||||
color: @color-fonts;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox_container { margin-top: 1.5em; }
|
||||
.checkbox_container label {
|
||||
padding: 0.5em 1em;
|
||||
color: @color-fonts;
|
||||
cursor: pointer;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.checkbox_container label:hover {
|
||||
background: @color-main;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.checkbox_container input[type="checkbox"] {
|
||||
position: absolute;
|
||||
top: -9999px;
|
||||
}
|
||||
|
||||
.checkbox_container input[type="checkbox"]:checked + label {
|
||||
background: @color-main;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
#categories_container > div {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#categories .hidden {
|
||||
display: none;
|
||||
position: absolute;
|
||||
bottom: 1em;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
font-size: 0.9em;
|
||||
font-style: italic;
|
||||
color: @color-fonts;
|
||||
}
|
||||
|
||||
#categories:hover .hidden {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
#categories_container { letter-spacing: -5px; }
|
||||
#categories_container > div {
|
||||
letter-spacing: normal;
|
||||
margin-top: 1em;
|
||||
}
|
||||
.checkbox_container {
|
||||
margin: 0;
|
||||
}
|
||||
.checkbox_container label {
|
||||
display: block;
|
||||
background: #CCC;
|
||||
padding: 1em;
|
||||
border: 1px solid #FFF;
|
||||
}
|
||||
.top_margin { position: static; }
|
||||
#categories .hidden {
|
||||
position: static;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) and (min-width: 501px) {
|
||||
#categories_container > div {
|
||||
width: 31%;
|
||||
margin-left: 2.333%;
|
||||
}
|
||||
#categories_container > div:nth-child(3n+1) { margin-left: 0; }
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
#categories_container > div {
|
||||
width: 48%;
|
||||
margin-left: 2%;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
#categories_container > div:nth-child(2n+1) { margin-left: 0; }
|
||||
.title h1 {
|
||||
background: url(../img/searx-mobile.png) no-repeat;
|
||||
width: 200px;
|
||||
height: 39px;
|
||||
}
|
||||
}
|
||||
|
||||
#search_wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.q {
|
||||
padding: 0.5em 3em 0.5em 1em;
|
||||
width: 100%;
|
||||
font-size: 1.5em;
|
||||
border: 0;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#search_submit {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
border: 0;
|
||||
background:url("../img/search-icon.png") no-repeat scroll center center / 65% auto @color-main;
|
||||
text-indent: -9999px;
|
||||
width: 5em;
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#search_submit:hover,
|
||||
#search_submit:focus {
|
||||
background-color: @color-focus;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
background: @color-main;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 15em;
|
||||
height: 100%;
|
||||
padding: 1.5em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.right {
|
||||
position: fixed;
|
||||
bottom: 1.5em;
|
||||
width: 15em;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
padding: 0 1.5em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.right a {
|
||||
color: #FFF;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.right a:hover,
|
||||
.right a:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#preferences {
|
||||
background: url(../img/preference-icon.png) no-repeat right 0 / 12% auto;
|
||||
padding-right: 1.8em;
|
||||
}
|
||||
|
||||
#preferences:hover,
|
||||
#preferences:focus {
|
||||
|
||||
}
|
||||
|
||||
#search_url input {
|
||||
border: 0;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
#sidebar > div {
|
||||
margin-bottom: 1em;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
#sidebar form {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#sidebar input[type="submit"] {
|
||||
background: #CCC;
|
||||
border: 0;
|
||||
padding: 0.5em 1em;
|
||||
cursor: pointer;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
#sidebar input[type="submit"]:hover,
|
||||
#sidebar input[type="submit"]:focus {
|
||||
color: #FFF;
|
||||
background-color: @color-focus;
|
||||
}
|
||||
|
||||
#results {
|
||||
padding-right: 17em;
|
||||
padding-left: 2em;
|
||||
padding: 0 17em 0 2em;
|
||||
}
|
||||
|
||||
.result p {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.result .content {
|
||||
margin: 0;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.result .url {
|
||||
margin-top: 0;
|
||||
color: #FF6530;
|
||||
}
|
||||
|
||||
.result .favicon {
|
||||
float: left;
|
||||
position: relative;
|
||||
top: 0.5em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.definition_result {
|
||||
background: #CCC;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.definition_result .result_title,
|
||||
.definition_result p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.result_title {
|
||||
margin-bottom: 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.result_title a {
|
||||
color: @color-main;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.result_title a:hover,
|
||||
.result_title a:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.cache_link {
|
||||
color: #666;
|
||||
font-size: 0.9em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.search.center {
|
||||
padding-right: 17em;
|
||||
}
|
||||
|
||||
#answers {
|
||||
border: 2px solid @color-main;
|
||||
padding: 20px;
|
||||
color:#666;
|
||||
text-align: center;
|
||||
max-width:@center-width;
|
||||
margin:0 auto 20px;
|
||||
}
|
||||
|
||||
#suggestions { margin-bottom: 1em; }
|
||||
|
||||
#suggestions span { color: #666; }
|
||||
|
||||
#suggestions form {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
#suggestions input[type="submit"] {
|
||||
color: @color-fonts;
|
||||
padding: 0.5em 1em;
|
||||
border: 0;
|
||||
background: #CCC;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
#suggestions input[type="submit"]:hover,
|
||||
#suggestions input[type="submit"]:focus {
|
||||
background: @color-main;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
#pagination {
|
||||
margin: 1.5em 0 2em;
|
||||
}
|
||||
|
||||
#pagination form + form {
|
||||
float: right;
|
||||
margin-top: -2em;
|
||||
}
|
||||
|
||||
input[type="submit"] {
|
||||
display: inline-block;
|
||||
background: @color-main;
|
||||
color: #FFF;
|
||||
border: 0;
|
||||
padding: 0.6em 1em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type="submit"]:hover,
|
||||
input[type="submit"]:focus {
|
||||
background: @color-focus;
|
||||
}
|
||||
|
||||
.row {
|
||||
max-width: 60em;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.row a {
|
||||
color: @color-main;
|
||||
}
|
||||
|
||||
.row form {
|
||||
letter-spacing: -5px;
|
||||
}
|
||||
|
||||
.row form > * { letter-spacing: normal; }
|
||||
|
||||
.row p { margin: 0; }
|
||||
|
||||
.row fieldset {
|
||||
display: inline-block;
|
||||
width: 48%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.row fieldset:last-of-type {
|
||||
display: block;
|
||||
width: auto;
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.row fieldset:nth-child(odd) {
|
||||
margin-right: 2%;
|
||||
}
|
||||
|
||||
.row fieldset:nth-child(2) {
|
||||
min-height: 10.5em;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
.row {
|
||||
margin: 0 1em;
|
||||
}
|
||||
|
||||
.row fieldset { width: 49%; }
|
||||
.row fieldset,
|
||||
.row fieldset:nth-child(odd) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.row fieldset:first-child {
|
||||
width: 100%;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.row fieldset:nth-child(even) {
|
||||
margin-right: 2%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
.row fieldset { width: 100%; }
|
||||
|
||||
select { width: 100%; }
|
||||
|
||||
table { font-size: 0.8em; }
|
||||
.right {display: none;}
|
||||
#sidebar { display: none; }
|
||||
#results { padding: 0 2em; }
|
||||
.search.center {
|
||||
padding-right: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 400px) {
|
||||
.row #categories_container > div {
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
fieldset {
|
||||
border: 0;
|
||||
margin: 1em 0;
|
||||
background: #CCC;
|
||||
padding: 1.5em;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
border: 1px solid #CCC;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table th {
|
||||
background: #999;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
table tr:nth-child(odd) {
|
||||
background: #CCC;
|
||||
}
|
||||
|
||||
table th,
|
||||
table td {
|
||||
padding: 0.5em 1em;
|
||||
border: 1px solid #FFF;
|
||||
}
|
||||
|
||||
.engine_checkbox label {
|
||||
padding: 0.5em;
|
||||
background: @color-main;
|
||||
color: #FFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.engine_checkbox .deny {
|
||||
background: @color-main;
|
||||
}
|
||||
|
||||
.engine_checkbox .allow {
|
||||
display: none;
|
||||
background: #666;
|
||||
}
|
||||
|
||||
.engine_checkbox input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.engine_checkbox input:checked + .allow {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.engine_checkbox input:checked + .allow + .deny{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.row input[type="submit"] {
|
||||
font-size: 1em;
|
||||
margin: 1em 0 2em;
|
||||
}
|
||||
|
||||
.row .right {
|
||||
position: static;
|
||||
display: inline-block;
|
||||
|
||||
}
|
||||
|
||||
.row .right a {
|
||||
color: @color-fonts;
|
||||
width: auto;
|
||||
text-align: left;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.small_font {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
table th {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
legend {
|
||||
background: #EEE;
|
||||
padding: 0 1em;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
select {
|
||||
border: 1px solid #DDD;
|
||||
padding: 0.5em 0.8em;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.highlight .hll { background-color: #ffffcc }
|
||||
.highlight { background: #f8f8f8; }
|
||||
.highlight .c { color: #408080; font-style: italic } /* Comment */
|
||||
.highlight .err { border: 1px solid #FF0000 } /* Error */
|
||||
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
|
||||
.highlight .o { color: #666666 } /* Operator */
|
||||
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
|
||||
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
|
||||
.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
|
||||
.highlight .gd { color: #A00000 } /* Generic.Deleted */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #FF0000 } /* Generic.Error */
|
||||
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.highlight .gi { color: #00A000 } /* Generic.Inserted */
|
||||
.highlight .go { color: #888888 } /* Generic.Output */
|
||||
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
.highlight .gt { color: #0044DD } /* Generic.Traceback */
|
||||
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
||||
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #B00040 } /* Keyword.Type */
|
||||
.highlight .m { color: #666666 } /* Literal.Number */
|
||||
.highlight .s { color: #BA2121 } /* Literal.String */
|
||||
.highlight .na { color: #7D9029 } /* Name.Attribute */
|
||||
.highlight .nb { color: #008000 } /* Name.Builtin */
|
||||
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
.highlight .no { color: #880000 } /* Name.Constant */
|
||||
.highlight .nd { color: #AA22FF } /* Name.Decorator */
|
||||
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
||||
.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
||||
.highlight .nf { color: #0000FF } /* Name.Function */
|
||||
.highlight .nl { color: #A0A000 } /* Name.Label */
|
||||
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
|
||||
.highlight .nv { color: #19177C } /* Name.Variable */
|
||||
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.highlight .mf { color: #666666 } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
|
||||
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
|
||||
.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #008000 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #19177C } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #19177C } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
|
||||
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
|
||||
|
||||
.highlight pre { overflow: auto; }
|
||||
|
||||
.highlight .lineno {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.highlight .lineno::selection { background: transparent; } /* WebKit/Blink Browsers */
|
||||
.highlight .lineno::-moz-selection { background: transparent; } /* Gecko Browsers */
|
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 5.3 KiB |
|
@ -0,0 +1,83 @@
|
|||
.highlight .hll { background-color: #ffffcc }
|
||||
.highlight { background: #f8f8f8; }
|
||||
.highlight .c { color: #408080; font-style: italic } /* Comment */
|
||||
.highlight .err { border: 1px solid #FF0000 } /* Error */
|
||||
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
|
||||
.highlight .o { color: #666666 } /* Operator */
|
||||
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
|
||||
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
|
||||
.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
|
||||
.highlight .gd { color: #A00000 } /* Generic.Deleted */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #FF0000 } /* Generic.Error */
|
||||
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.highlight .gi { color: #00A000 } /* Generic.Inserted */
|
||||
.highlight .go { color: #888888 } /* Generic.Output */
|
||||
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
.highlight .gt { color: #0044DD } /* Generic.Traceback */
|
||||
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
||||
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #B00040 } /* Keyword.Type */
|
||||
.highlight .m { color: #666666 } /* Literal.Number */
|
||||
.highlight .s { color: #BA2121 } /* Literal.String */
|
||||
.highlight .na { color: #7D9029 } /* Name.Attribute */
|
||||
.highlight .nb { color: #008000 } /* Name.Builtin */
|
||||
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
.highlight .no { color: #880000 } /* Name.Constant */
|
||||
.highlight .nd { color: #AA22FF } /* Name.Decorator */
|
||||
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
||||
.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
||||
.highlight .nf { color: #0000FF } /* Name.Function */
|
||||
.highlight .nl { color: #A0A000 } /* Name.Label */
|
||||
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
|
||||
.highlight .nv { color: #19177C } /* Name.Variable */
|
||||
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.highlight .mf { color: #666666 } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
|
||||
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
|
||||
.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #008000 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #19177C } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #19177C } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
|
||||
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
|
||||
|
||||
.highlight pre {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.highlight .lineno {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
|
||||
&::selection {
|
||||
background: transparent; /* WebKit/Blink Browsers */
|
||||
}
|
||||
&::-moz-selection {
|
||||
background: transparent; /* Gecko Browsers */
|
||||
}
|
||||
}
|
|
@ -15,6 +15,9 @@
|
|||
/// General
|
||||
|
||||
@color-font: #444;
|
||||
@color-font-light: #888;
|
||||
|
||||
@color-red: #C0392B;
|
||||
|
||||
@color-url-font: #1a11be;
|
||||
@color-url-visited-font: #8E44AD;
|
||||
|
@ -44,6 +47,9 @@
|
|||
|
||||
@color-autocompleter-choices-font: #444;
|
||||
|
||||
/// Answers
|
||||
@color-answers-border: @color-base-dark;
|
||||
|
||||
// Selected
|
||||
@color-autocompleter-selected-background: #444;
|
||||
@color-autocompleter-selected-font: #FFF;
|
||||
|
@ -78,10 +84,10 @@
|
|||
@color-result-link-visited-font: @color-url-visited-font;
|
||||
|
||||
// Url to result
|
||||
@color-result-url-font: #C0392B;
|
||||
@color-result-url-font: @color-red;
|
||||
|
||||
// Publish Date
|
||||
@color-result-publishdate-font: #888;
|
||||
@color-result-publishdate-font: @color-font-light;
|
||||
|
||||
// Images
|
||||
@color-result-image-span-background-hover: rgba(0, 0, 0, 0.6);
|
||||
|
@ -109,5 +115,5 @@
|
|||
|
||||
/// Other
|
||||
|
||||
@color-engines-font: #888;
|
||||
@color-engines-font: @color-font-light;
|
||||
@color-percentage-div-background: #444;
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
@import "mixins.less";
|
||||
|
||||
@import "code.less";
|
||||
|
||||
// Main LESS-Code
|
||||
|
||||
html {
|
||||
|
@ -342,6 +344,18 @@ a {
|
|||
margin: 3px;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: @color-result-link-font;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&:visited {
|
||||
color: @color-result-link-visited-font;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.definition_result {
|
||||
|
@ -434,6 +448,20 @@ tr {
|
|||
|
||||
}
|
||||
|
||||
#suggestions-title {
|
||||
|
||||
color: @color-font-light;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#answers {
|
||||
|
||||
border: 2px solid @color-answers-border;
|
||||
padding: 20px;
|
||||
|
||||
}
|
||||
|
||||
#answers, #infoboxes {
|
||||
form {
|
||||
min-width: 210px;
|
||||
|
|
|
@ -1,22 +1 @@
|
|||
html{position:relative;min-height:100%}
|
||||
body{margin-bottom:80px}
|
||||
.footer{position:absolute;bottom:0;width:100%;height:60px}
|
||||
input[type=checkbox]:checked~.label_hide_if_checked{display:none}
|
||||
input[type=checkbox]:not(:checked)~.label_hide_if_not_checked{display:none}
|
||||
.result_header{margin-bottom:5px;margin-top:20px}.result_header .favicon{margin-bottom:-3px}
|
||||
.result_header a{vertical-align:bottom}.result_header a .highlight{font-weight:bold}
|
||||
.result-content{margin-top:5px}.result-content .highlight{font-weight:bold}
|
||||
.result-default{clear:both}
|
||||
.result-images{float:left !important}
|
||||
.img-thumbnail{margin:5px;max-height:128px;min-height:128px}
|
||||
.result-videos{clear:both}
|
||||
.result-torrents{clear:both}
|
||||
.result-map{clear:both}
|
||||
.suggestion_item{margin:2px 5px}
|
||||
.result_download{margin-right:5px}
|
||||
#pagination{margin-top:30px;padding-bottom:50px}
|
||||
.infobox .infobox_part{margin-bottom:20px}
|
||||
.infobox .infobox_part:last-child{margin-bottom:0}
|
||||
.search_categories{margin:10px 0;text-transform:capitalize}
|
||||
.cursor-text{cursor:text !important}
|
||||
.cursor-pointer{cursor:pointer !important}
|
||||
html{position:relative;min-height:100%}body{margin-bottom:80px}.footer{position:absolute;bottom:0;width:100%;height:60px}input[type=checkbox]:checked+.label_hide_if_checked,input[type=checkbox]:checked+.label_hide_if_not_checked+.label_hide_if_checked{display:none}input[type=checkbox]:not(:checked)+.label_hide_if_not_checked,input[type=checkbox]:not(:checked)+.label_hide_if_checked+.label_hide_if_not_checked{display:none}.result_header{margin-bottom:5px;margin-top:20px}.result_header .favicon{margin-bottom:-3px}.result_header a{vertical-align:bottom}.result_header a .highlight{font-weight:bold}.result-content{margin-top:5px;word-wrap:break-word}.result-content .highlight{font-weight:bold}.result-default{clear:both}.result-images{float:left !important}.img-thumbnail{margin:5px;max-height:128px;min-height:128px}.result-videos{clear:both}.result-torrents{clear:both}.result-map{clear:both}.result-code{clear:both}.suggestion_item{margin:2px 5px}.result_download{margin-right:5px}#pagination{margin-top:30px;padding-bottom:50px}.infobox .infobox_part{margin-bottom:20px;word-wrap:break-word}.infobox .infobox_part:last-child{margin-bottom:0}.search_categories{margin:10px 0;text-transform:capitalize}.cursor-text{cursor:text !important}.cursor-pointer{cursor:pointer !important}.highlight .hll{background-color:#ffc}.highlight{background:#f8f8f8}.highlight .c{color:#408080;font-style:italic}.highlight .err{border:1px solid #f00}.highlight .k{color:#008000;font-weight:bold}.highlight .o{color:#666}.highlight .cm{color:#408080;font-style:italic}.highlight .cp{color:#bc7a00}.highlight .c1{color:#408080;font-style:italic}.highlight .cs{color:#408080;font-style:italic}.highlight .gd{color:#a00000}.highlight .ge{font-style:italic}.highlight .gr{color:#f00}.highlight .gh{color:#000080;font-weight:bold}.highlight .gi{color:#00a000}.highlight .go{color:#888}.highlight .gp{color:#000080;font-weight:bold}.highlight .gs{font-weight:bold}.highlight .gu{color:#800080;font-weight:bold}.highlight .gt{color:#04d}.highlight .kc{color:#008000;font-weight:bold}.highlight .kd{color:#008000;font-weight:bold}.highlight .kn{color:#008000;font-weight:bold}.highlight .kp{color:#008000}.highlight .kr{color:#008000;font-weight:bold}.highlight .kt{color:#b00040}.highlight .m{color:#666}.highlight .s{color:#ba2121}.highlight .na{color:#7d9029}.highlight .nb{color:#008000}.highlight .nc{color:#00f;font-weight:bold}.highlight .no{color:#800}.highlight .nd{color:#a2f}.highlight .ni{color:#999;font-weight:bold}.highlight .ne{color:#d2413a;font-weight:bold}.highlight .nf{color:#00f}.highlight .nl{color:#a0a000}.highlight .nn{color:#00f;font-weight:bold}.highlight .nt{color:#008000;font-weight:bold}.highlight .nv{color:#19177c}.highlight .ow{color:#a2f;font-weight:bold}.highlight .w{color:#bbb}.highlight .mf{color:#666}.highlight .mh{color:#666}.highlight .mi{color:#666}.highlight .mo{color:#666}.highlight .sb{color:#ba2121}.highlight .sc{color:#ba2121}.highlight .sd{color:#ba2121;font-style:italic}.highlight .s2{color:#ba2121}.highlight .se{color:#b62;font-weight:bold}.highlight .sh{color:#ba2121}.highlight .si{color:#b68;font-weight:bold}.highlight .sx{color:#008000}.highlight .sr{color:#b68}.highlight .s1{color:#ba2121}.highlight .ss{color:#19177c}.highlight .bp{color:#008000}.highlight .vc{color:#19177c}.highlight .vg{color:#19177c}.highlight .vi{color:#19177c}.highlight .il{color:#666}.highlight .lineno{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.highlight .lineno::selection{background:transparent}.highlight .lineno::-moz-selection{background:transparent}
|
|
@ -33,9 +33,43 @@ module.exports = function(grunt) {
|
|||
}
|
||||
}
|
||||
},
|
||||
less: {
|
||||
development: {
|
||||
options: {
|
||||
paths: ["less/oscar"]
|
||||
//banner: '/*! less/oscar/oscar.css | <%= grunt.template.today("dd-mm-yyyy") %> | https://github.com/asciimoo/searx */\n'
|
||||
},
|
||||
files: {"css/oscar.css": "less/oscar/oscar.less"}
|
||||
},
|
||||
production: {
|
||||
options: {
|
||||
paths: ["less/oscar"],
|
||||
//banner: '/*! less/oscar/oscar.css | <%= grunt.template.today("dd-mm-yyyy") %> | https://github.com/asciimoo/searx */\n',
|
||||
cleancss: true
|
||||
},
|
||||
files: {"css/oscar.min.css": "less/oscar/oscar.less"}
|
||||
},
|
||||
bootstrap: {
|
||||
options: {
|
||||
paths: ["less/bootstrap"],
|
||||
cleancss: true
|
||||
},
|
||||
files: {"css/bootstrap.min.css": "less/bootstrap/bootstrap.less"}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
files: ['<%= jshint.files %>'],
|
||||
tasks: ['jshint']
|
||||
scripts: {
|
||||
files: ['<%= jshint.files %>'],
|
||||
tasks: ['jshint', 'concat', 'uglify']
|
||||
},
|
||||
oscar_styles: {
|
||||
files: ['less/oscar/**/*.less'],
|
||||
tasks: ['less:development', 'less:production']
|
||||
},
|
||||
bootstrap_styles: {
|
||||
files: ['less/bootstrap/**/*.less'],
|
||||
tasks: ['less:bootstrap']
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -43,9 +77,12 @@ module.exports = function(grunt) {
|
|||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-contrib-less');
|
||||
|
||||
grunt.registerTask('test', ['jshint']);
|
||||
|
||||
grunt.registerTask('default', ['jshint', 'concat', 'uglify']);
|
||||
grunt.registerTask('default', ['jshint', 'concat', 'uglify', 'less']);
|
||||
|
||||
grunt.registerTask('styles', ['less']);
|
||||
|
||||
};
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// Hide element if checkbox is checked
|
||||
input[type=checkbox]:checked ~ .label_hide_if_checked {
|
||||
input[type=checkbox]:checked + .label_hide_if_checked, input[type=checkbox]:checked + .label_hide_if_not_checked + .label_hide_if_checked {
|
||||
display:none;
|
||||
}
|
||||
|
||||
// Hide element if checkbox is not checked
|
||||
input[type=checkbox]:not(:checked) ~ .label_hide_if_not_checked {
|
||||
input[type=checkbox]:not(:checked) + .label_hide_if_not_checked, input[type=checkbox]:not(:checked) + .label_hide_if_checked + .label_hide_if_not_checked {
|
||||
display:none;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
.highlight .hll { background-color: #ffffcc }
|
||||
.highlight { background: #f8f8f8; }
|
||||
.highlight .c { color: #408080; font-style: italic } /* Comment */
|
||||
.highlight .err { border: 1px solid #FF0000 } /* Error */
|
||||
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
|
||||
.highlight .o { color: #666666 } /* Operator */
|
||||
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
|
||||
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
|
||||
.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
|
||||
.highlight .gd { color: #A00000 } /* Generic.Deleted */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #FF0000 } /* Generic.Error */
|
||||
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.highlight .gi { color: #00A000 } /* Generic.Inserted */
|
||||
.highlight .go { color: #888888 } /* Generic.Output */
|
||||
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
.highlight .gt { color: #0044DD } /* Generic.Traceback */
|
||||
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
||||
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #B00040 } /* Keyword.Type */
|
||||
.highlight .m { color: #666666 } /* Literal.Number */
|
||||
.highlight .s { color: #BA2121 } /* Literal.String */
|
||||
.highlight .na { color: #7D9029 } /* Name.Attribute */
|
||||
.highlight .nb { color: #008000 } /* Name.Builtin */
|
||||
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
.highlight .no { color: #880000 } /* Name.Constant */
|
||||
.highlight .nd { color: #AA22FF } /* Name.Decorator */
|
||||
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
||||
.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
||||
.highlight .nf { color: #0000FF } /* Name.Function */
|
||||
.highlight .nl { color: #A0A000 } /* Name.Label */
|
||||
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
|
||||
.highlight .nv { color: #19177C } /* Name.Variable */
|
||||
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.highlight .mf { color: #666666 } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
|
||||
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
|
||||
.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #008000 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #19177C } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #19177C } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
|
||||
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
|
||||
|
||||
.highlight .lineno {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
|
||||
&::selection {
|
||||
background: transparent; /* WebKit/Blink Browsers */
|
||||
}
|
||||
&::-moz-selection {
|
||||
background: transparent; /* Gecko Browsers */
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
.infobox {
|
||||
.infobox_part {
|
||||
margin-bottom: 20px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.infobox_part:last-child {
|
||||
|
|
|
@ -9,3 +9,5 @@
|
|||
@import "search.less";
|
||||
|
||||
@import "cursor.less";
|
||||
|
||||
@import "code.less";
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
.result-content {
|
||||
margin-top: 5px;
|
||||
word-wrap: break-word;
|
||||
|
||||
.highlight {
|
||||
font-weight:bold;
|
||||
|
@ -55,6 +56,11 @@
|
|||
clear: both;
|
||||
}
|
||||
|
||||
// code formating of results
|
||||
.result-code {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
// suggestion
|
||||
.suggestion_item {
|
||||
margin: 2px 5px;
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
"grunt-contrib-uglify": "~0.6.0",
|
||||
"grunt-contrib-watch" : "~0.6.1",
|
||||
"grunt-contrib-concat" : "~0.5.0",
|
||||
"grunt-contrib-jshint" : "~0.10.0"
|
||||
"grunt-contrib-jshint" : "~0.10.0",
|
||||
"grunt-contrib-less" : "~0.11.0"
|
||||
},
|
||||
|
||||
"scripts": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends 'default/base.html' %}
|
||||
{% extends 'courgette/base.html' %}
|
||||
{% block content %}
|
||||
{% include 'default/github_ribbon.html' %}
|
||||
{% include 'courgette/github_ribbon.html' %}
|
||||
<div class="row">
|
||||
<h1>About <a href="{{ url_for('index') }}">searx</a></h1>
|
||||
|
||||
|
|
|
@ -1,33 +1,39 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="Searx - a privacy-respecting, hackable metasearch engine" />
|
||||
<meta name="keywords" content="searx, search, search engine, metasearch, meta search" />
|
||||
<meta name="generator" content="searx/{{ searx_version }}">
|
||||
<meta name="viewport" content="width=device-width, maximum-scale=1.0, user-scalable=1" />
|
||||
<title>{% block title %}{% endblock %}searx</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}" type="text/css" media="screen" />
|
||||
<link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.png') }}?v=2" />
|
||||
{% block styles %}
|
||||
{% endblock %}
|
||||
{% block head %}
|
||||
<link title="searx" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
|
||||
{% endblock %}
|
||||
<script type="text/javascript">
|
||||
searx = {};
|
||||
searx.autocompleter = {% if autocomplete %}true{% else %}false{% endif %};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
{% if autocomplete %}
|
||||
<script src="{{ url_for('static', filename='js/mootools-core-1.4.5-min.js') }}" ></script>
|
||||
<script src="{{ url_for('static', filename='js/mootools-autocompleter-1.1.2-min.js') }}" ></script>
|
||||
{% endif %}
|
||||
<script src="{{ url_for('static', filename='js/searx.js') }}" ></script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="Searx - a privacy-respecting, hackable metasearch engine" />
|
||||
<meta name="keywords" content="searx, search, search engine, metasearch, meta search" />
|
||||
<meta name="generator" content="searx/{{ searx_version }}">
|
||||
<meta name="viewport" content="width=device-width, maximum-scale=1.0, user-scalable=1" />
|
||||
<title>{% block title %}{% endblock %}searx</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}" type="text/css" media="screen" />
|
||||
{% if cookies['courgette-color'] %}
|
||||
<style type="text/css">
|
||||
{% include 'courgette/color.css' %}
|
||||
</style>
|
||||
{% endif %}
|
||||
<link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.png') }}?v=2" />
|
||||
{% block styles %}
|
||||
{% endblock %}
|
||||
{% block meta %}{% endblock %}
|
||||
{% block head %}
|
||||
<link title="searx" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
|
||||
{% endblock %}
|
||||
<script type="text/javascript">
|
||||
searx = {};
|
||||
searx.autocompleter = {% if autocomplete %}true{% else %}false{% endif %};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
{% if autocomplete %}
|
||||
<script src="{{ url_for('static', filename='js/mootools-core-1.4.5-min.js') }}" ></script>
|
||||
<script src="{{ url_for('static', filename='js/mootools-autocompleter-1.1.2-min.js') }}" ></script>
|
||||
{% endif %}
|
||||
<script src="{{ url_for('static', filename='js/searx.js') }}" ></script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,7 +1,9 @@
|
|||
<div id="categories">
|
||||
{% for category in categories %}
|
||||
<div class="checkbox_container">
|
||||
<input type="checkbox" id="checkbox_{{ category|replace(' ', '_') }}" name="category_{{ category }}" {% if category in selected_categories %}checked="checked"{% endif %} /><label for="checkbox_{{ category|replace(' ', '_') }}">{{ _(category) }}</label>
|
||||
<div id="categories_container">
|
||||
{% for category in categories %}
|
||||
<div class="checkbox_container">
|
||||
<input type="checkbox" id="checkbox_{{ category|replace(' ', '_') }}" name="category_{{ category }}" {% if category in selected_categories %}checked="checked"{% endif %} /><label for="checkbox_{{ category|replace(' ', '_') }}">{{ _(category) }}</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,34 @@
|
|||
.autocompleter-choices li:hover,
|
||||
.checkbox_container label:hover,
|
||||
.checkbox_container input[type="checkbox"]:checked + label,
|
||||
#sidebar,
|
||||
#suggestions input[type="submit"]:hover,
|
||||
#suggestions input[type="submit"]:focus,
|
||||
input[type="submit"],
|
||||
.engine_checkbox label,
|
||||
.engine_checkbox .deny,
|
||||
#search_submit{
|
||||
background-color: {{ cookies['courgette-color'].split()[0] }};
|
||||
}
|
||||
|
||||
.result_title a,
|
||||
.row a,
|
||||
.title h1{
|
||||
color: {{ cookies['courgette-color'].split()[0] }};
|
||||
}
|
||||
|
||||
#answers {
|
||||
border-color: {{ cookies['courgette-color'].split()[0] }};
|
||||
}
|
||||
|
||||
#search_submit:hover,
|
||||
#search_submit:focus,
|
||||
#sidebar input[type="submit"]:hover,
|
||||
#sidebar input[type="submit"]:focus {
|
||||
background-color: {{ cookies['courgette-color'].split()[1] }};
|
||||
}
|
||||
|
||||
input[type="submit"]:hover,
|
||||
input[type="submit"]:focus {
|
||||
background: {{ cookies['courgette-color'].split()[1] }};
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
<a href="https://github.com/asciimoo/searx" class="github">
|
||||
<img style="position: absolute; top: 0; right: 0; border: 0;" src="{{ url_for('static', filename='img/github_ribbon.png') }}" alt="Fork me on GitHub" class="github"/>
|
||||
</a>
|
||||
</a>
|
|
@ -1,12 +1,12 @@
|
|||
{% extends "default/base.html" %}
|
||||
{% extends "courgette/base.html" %}
|
||||
{% block content %}
|
||||
{% include 'default/github_ribbon.html' %}
|
||||
{% include 'courgette/github_ribbon.html' %}
|
||||
<div class="center">
|
||||
<div class="title"><h1>searx</h1></div>
|
||||
{% include 'default/search.html' %}
|
||||
{% include 'courgette/search.html' %}
|
||||
<p class="top_margin">
|
||||
<a href="{{ url_for('about') }}" class="hmarg">{{ _('about') }}</a>
|
||||
<a href="{{ url_for('preferences') }}" class="hmarg">{{ _('preferences') }}</a>
|
||||
</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends "default/base.html" %}
|
||||
{% extends "courgette/base.html" %}
|
||||
{% block head %} {% endblock %}
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
|
@ -7,95 +7,115 @@
|
|||
<form method="post" action="{{ url_for('preferences') }}" id="search_form">
|
||||
<fieldset>
|
||||
<legend>{{ _('Default categories') }}</legend>
|
||||
<p>
|
||||
{% include 'default/categories.html' %}
|
||||
</p>
|
||||
{% include 'courgette/categories.html' %}
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{{ _('Search language') }}</legend>
|
||||
<p>
|
||||
<select name='language'>
|
||||
<option value="all" {% if current_language == 'all' %}selected="selected"{% endif %}>{{ _('Automatic') }}</option>
|
||||
{% for lang_id,lang_name,country_name in language_codes %}
|
||||
<option value="{{ lang_id }}" {% if lang_id == current_language %}selected="selected"{% endif %}>{{ lang_name }} ({{ country_name }}) - {{ lang_id }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<select name='language'>
|
||||
<option value="all" {% if current_language == 'all' %}selected="selected"{% endif %}>{{ _('Automatic') }}</option>
|
||||
{% for lang_id,lang_name,country_name in language_codes %}
|
||||
<option value="{{ lang_id }}" {% if lang_id == current_language %}selected="selected"{% endif %}>{{ lang_name }} ({{ country_name }}) - {{ lang_id }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{{ _('Interface language') }}</legend>
|
||||
<p>
|
||||
<select name='locale'>
|
||||
{% for locale_id,locale_name in locales.items() %}
|
||||
<option value="{{ locale_id }}" {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<select name='locale'>
|
||||
{% for locale_id,locale_name in locales.items() %}
|
||||
<option value="{{ locale_id }}" {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{{ _('Autocomplete') }}</legend>
|
||||
<p>
|
||||
<select name="autocomplete">
|
||||
<option value=""> - </option>
|
||||
{% for backend in autocomplete_backends %}
|
||||
<option value="{{ backend }}" {% if backend == autocomplete %}selected="selected"{% endif %}>{{ backend }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<select name="autocomplete">
|
||||
<option value=""> - </option>
|
||||
{% for backend in autocomplete_backends %}
|
||||
<option value="{{ backend }}" {% if backend == autocomplete %}selected="selected"{% endif %}>{{ backend }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{{ _('Image proxy') }}</legend>
|
||||
<p>
|
||||
<select name='image_proxy'>
|
||||
<option value="1" {% if image_proxy %}selected="selected"{% endif %}>{{ _('Enabled') }}</option>
|
||||
<option value="" {% if not image_proxy %}selected="selected"{% endif %}>{{ _('Disabled') }}</option>
|
||||
</select>
|
||||
</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{{ _('Method') }}</legend>
|
||||
<p>
|
||||
<select name='method'>
|
||||
<option value="POST" {% if method == 'POST' %}selected="selected"{% endif %}>POST</option>
|
||||
<option value="GET" {% if method == 'GET' %}selected="selected"{% endif %}>GET</option>
|
||||
</select>
|
||||
<select name='method'>
|
||||
<option value="POST" {% if method == 'POST' %}selected="selected"{% endif %}>POST</option>
|
||||
<option value="GET" {% if method == 'GET' %}selected="selected"{% endif %}>GET</option>
|
||||
</select>
|
||||
</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{{ _('Themes') }}</legend>
|
||||
<p>
|
||||
<select name="theme">
|
||||
{% for name in themes %}
|
||||
<option value="{{ name }}" {% if name == theme %}selected="selected"{% endif %}>{{ name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<select name="theme">
|
||||
{% for name in themes %}
|
||||
<option value="{{ name }}" {% if name == theme %}selected="selected"{% endif %}>{{ name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{{ _('Currently used search engines') }}</legend>
|
||||
<legend>{{ _('Color') }}</legend>
|
||||
<p>
|
||||
<select name="courgette-color">
|
||||
<option value="#3498DB #0665A2" {% if cookies['courgette-color'] and cookies['courgette-color'] == '#3498DB #0665A2' %}selected="selected"{% endif %}>{{ _('Blue (default)') }}</option>
|
||||
<option value="#6F5499 #563D7C" {% if cookies['courgette-color'] and cookies['courgette-color'] == '#6F5499 #563D7C' %}selected="selected"{% endif %}>{{ _('Violet') }}</option>
|
||||
<option value="#5CB85C #449D44" {% if cookies['courgette-color'] and cookies['courgette-color'] == '#5CB85C #449D44' %}selected="selected"{% endif %}>{{ _('Green') }}</option>
|
||||
<option value="#5BC0DE #31B0D5" {% if cookies['courgette-color'] and cookies['courgette-color'] == '#5BC0DE #31B0D5' %}selected="selected"{% endif %}>{{ _('Cyan') }}</option>
|
||||
<option value="#F0AD4E #EC971F" {% if cookies['courgette-color'] and cookies['courgette-color'] == '#F0AD4E #EC971F' %}selected="selected"{% endif %}>{{ _('Orange') }}</option>
|
||||
<option value="#D9534F #C9302C" {% if cookies['courgette-color'] and cookies['courgette-color'] == '#D9534F #C9302C' %}selected="selected"{% endif %}>{{ _('Red') }}</option>
|
||||
</select>
|
||||
</p>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{{ _('Currently used search engines') }}</legend>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>{{ _('Engine name') }}</th>
|
||||
<th>{{ _('Category') }}</th>
|
||||
<th>{{ _('Allow') }} / {{ _('Block') }}</th>
|
||||
</tr>
|
||||
{% for (categ,search_engines) in categs %}
|
||||
{% for search_engine in search_engines %}
|
||||
|
||||
{% if not search_engine.private %}
|
||||
<table>
|
||||
<tr>
|
||||
<td>{{ search_engine.name }} ({{ shortcuts[search_engine.name] }})</td>
|
||||
<td>{{ _(categ) }}</td>
|
||||
<td class="engine_checkbox">
|
||||
<input type="checkbox" id="engine_{{ categ }}_{{ search_engine.name|replace(' ', '_') }}" name="engine_{{ search_engine.name }}"{% if search_engine.name in blocked_engines %} checked="checked"{% endif %} />
|
||||
<label class="allow" for="engine_{{ categ }}_{{ search_engine.name|replace(' ', '_') }}">{{ _('Allow') }}</label>
|
||||
<label class="deny" for="engine_{{ categ }}_{{ search_engine.name|replace(' ', '_') }}">{{ _('Block') }}</label>
|
||||
</td>
|
||||
<th>{{ _('Engine name') }}</th>
|
||||
<th>{{ _('Category') }}</th>
|
||||
<th>{{ _('Allow') }} / {{ _('Block') }}</th>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% for (categ,search_engines) in categs %}
|
||||
{% for search_engine in search_engines %}
|
||||
|
||||
{% if not search_engine.private %}
|
||||
<tr>
|
||||
<td>{{ search_engine.name }} ({{ shortcuts[search_engine.name] }})</td>
|
||||
<td>{{ _(categ) }}</td>
|
||||
<td class="engine_checkbox">
|
||||
<input type="checkbox" id="engine_{{ categ|replace(' ', '_') }}_{{ search_engine.name|replace(' ', '_') }}" name="engine_{{ search_engine.name }}__{{ categ }}"{% if (search_engine.name, categ) in blocked_engines %} checked="checked"{% endif %} />
|
||||
<label class="allow" for="engine_{{ categ|replace(' ', '_') }}_{{ search_engine.name|replace(' ', '_') }}">{{ _('Allow') }}</label>
|
||||
<label class="deny" for="engine_{{ categ|replace(' ', '_') }}_{{ search_engine.name|replace(' ', '_') }}">{{ _('Block') }}</label>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</table>
|
||||
</table>
|
||||
</fieldset>
|
||||
<p class="small_font">{{ _('These settings are stored in your cookies, this allows us not to store this data about you.') }}
|
||||
<br />
|
||||
{{ _("These cookies serve your sole convenience, we don't use these cookies to track you.") }}
|
||||
<br />
|
||||
{{ _("These cookies serve your sole convenience, we don't use these cookies to track you.") }}
|
||||
</p>
|
||||
|
||||
<input type="submit" value="{{ _('save') }}" />
|
||||
<div class="right preferences_back"><a href="{{ url_for('index') }}">{{ _('back') }}</a></div>
|
||||
<div class="right preferences_back"><a href="{{ url_for('index') }}">{{ _('back') }}</a></div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<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 }}">{{ 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 }}">{{ result.repository }}</a></p>{% endif %}
|
||||
{{ result.codelines|code_highlighter(result.code_language)|safe }}
|
||||
|
||||
<p class="url">{{ result.pretty_url }}</p>
|
||||
</div>
|
|
@ -1,13 +1,13 @@
|
|||
<div class="result {{ result.class }}">
|
||||
|
||||
{% if "icon_"~result.engine~".ico" in favicons %}
|
||||
{% if "icon_"~result.engine~".ico" in favicons %}
|
||||
<img width="14" height="14" class="favicon" src="{{ url_for('static', filename='img/icons/icon_'+result.engine+'.ico') }}" alt="{{result.engine}}" />
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
<h3 class="result_title"><a href="{{ result.url }}">{{ result.title|safe }}</a></h3>
|
||||
{% if result.publishedDate %}<p class="published_date">{{ result.publishedDate }}</p>{% endif %}
|
||||
<p class="content">{% if result.content %}{{ result.content|safe }}<br />{% endif %}</p>
|
||||
<p class="url">{{ result.pretty_url }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="result_title"><a href="{{ result.url }}">{{ result.title|safe }}</a></h3>
|
||||
{% if result.publishedDate %}<span class="published_date">{{ result.publishedDate }}</span>{% endif %}
|
||||
<p class="content">{% if result.content %}{{ result.content|safe }}<br />{% endif %}</p>
|
||||
<p class="url">{{ result.pretty_url }}</p>
|
||||
</div>
|
||||
</div>
|
|
@ -1,6 +1,6 @@
|
|||
<div class="image_result">
|
||||
<p>
|
||||
<a href="{{ result.img_src }}"><img src="{{ result.img_src }}" title="{{ result.title|striptags }}" alt="{{ result.title|striptags }}"/></a>
|
||||
<span class="url"><a href="{{ result.url }}" class="small_font">original context</a></span>
|
||||
<a href="{{ result.img_src }}"><img src="{% if result.thumbnail_src %}{{ image_proxify(result.thumbnail_src) }}{% else %}{{ image_proxify(result.img_src) }}{% endif %}" title="{{ result.title|striptags }}" alt="{{ result.title|striptags }}"/></a>
|
||||
<span class="url"><a href="{{ result.url }}" class="small_font">{{ _('original context') }}</a></span>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<div class="result {{ result.class }}">
|
||||
|
||||
{% if "icon_"~result.engine~".ico" in favicons %}
|
||||
<img width="14" height="14" class="favicon" src="{{ url_for('static', filename='img/icons/icon_'+result.engine+'.ico') }}" alt="{{result.engine}}" />
|
||||
{% endif %}
|
||||
{% if "icon_"~result.engine~".ico" in favicons %}
|
||||
<img width="14" height="14" class="favicon" src="{{ url_for('static', filename='img/icons/icon_'+result.engine+'.ico') }}" alt="{{result.engine}}" />
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
<h3 class="result_title"><a href="{{ result.url }}">{{ result.title|safe }}</a></h3>
|
||||
{% if result.publishedDate %}<p class="published_date">{{ result.publishedDate }}</p>{% endif %}
|
||||
<p class="content">{% if result.content %}{{ result.content|safe }}<br />{% endif %}</p>
|
||||
<p class="url">{{ result.pretty_url }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="result_title"><a href="{{ result.url }}">{{ result.title|safe }}</a></h3>
|
||||
{% if result.publishedDate %}<span class="published_date">{{ result.publishedDate }}</span>{% endif %}
|
||||
<p class="content">{% if result.content %}{{ result.content|safe }}<br />{% endif %}</p>
|
||||
<p class="url">{{ result.pretty_url }}</p>
|
||||
</div>
|
||||
</div>
|
|
@ -1,7 +1,13 @@
|
|||
<div class="result torrent_result">
|
||||
{% if "icon_"~result.engine~".ico" in favicons %}
|
||||
<img width="14" height="14" class="favicon" src="{{ url_for('static', filename='img/icons/icon_'+result.engine+'.ico') }}" alt="{{result.engine}}" />
|
||||
{% endif %}
|
||||
<h3 class="result_title"><a href="{{ result.url }}">{{ result.title|safe }}</a></h3>
|
||||
{% if result.content %}<p class="content">{{ result.content|safe }}</p>{% endif %}
|
||||
<p class="stats">Seed: {{ result.seed }}, Leech: {{ result.leech }}</p>
|
||||
<p><a href="{{ result.magnetlink }}" class="magnetlink">magnet link</a></p>
|
||||
{% if result.content %}<span class="content">{{ result.content|safe }}</span><br />{% endif %}
|
||||
<span class="stats">{{ _('Seeder') }} : {{ result.seed }}, {{ _('Leecher') }} : {{ result.leech }}</span><br />
|
||||
<span>
|
||||
{% if result.magnetlink %}<a href="{{ result.magnetlink }}" class="magnetlink">{{ _('magnet link') }}</a>{% endif %}
|
||||
{% if result.torrentfile %}<a href="{{ result.torrentfile }}" class="torrentfile">{{ _('torrent file') }}</a>{% endif %}
|
||||
</span>
|
||||
<p class="url">{{ result.pretty_url }}</p>
|
||||
</div>
|
||||
</div>
|