Merge branch 'master' of https://github.com/asciimoo/searx into code_results
Conflicts: searx/engines/searchcode_code.py searx/engines/searchcode_doc.py searx/static/oscar/js/searx.min.js searx/templates/oscar/result_templates/default.html searx/templates/oscar/result_templates/images.html searx/templates/oscar/result_templates/map.html searx/templates/oscar/result_templates/torrent.html searx/templates/oscar/result_templates/videos.htmlpull/1/head
@ -0,0 +1,27 @@
|
|||||||
|
0.6.0 - 2014.12.25
|
||||||
|
==================
|
||||||
|
|
||||||
|
- Changelog added
|
||||||
|
- New engines
|
||||||
|
|
||||||
|
- Flickr (api)
|
||||||
|
- Subtitleseeker
|
||||||
|
- photon
|
||||||
|
- 500px
|
||||||
|
- Searchcode
|
||||||
|
- Searchcode doc
|
||||||
|
- Kickass torrent
|
||||||
|
- Precise search request timeout handling
|
||||||
|
- Better favicon support
|
||||||
|
- Stricter config parsing
|
||||||
|
- Translation updates
|
||||||
|
- Multiple ui fixes
|
||||||
|
- Flickr (noapi) engine fix
|
||||||
|
- Pep8 fixes
|
||||||
|
|
||||||
|
|
||||||
|
News
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
Health status of searx instances and engines: http://stats.searx.oe5tpo.com
|
||||||
|
(source: https://github.com/pointhi/searx_stats)
|
@ -0,0 +1,61 @@
|
|||||||
|
## Deezer (Music)
|
||||||
|
#
|
||||||
|
# @website https://deezer.com
|
||||||
|
# @provide-api yes (http://developers.deezer.com/api/)
|
||||||
|
#
|
||||||
|
# @using-api yes
|
||||||
|
# @results JSON
|
||||||
|
# @stable yes
|
||||||
|
# @parse url, title, content, embedded
|
||||||
|
|
||||||
|
from json import loads
|
||||||
|
from urllib import urlencode
|
||||||
|
|
||||||
|
# engine dependent config
|
||||||
|
categories = ['music']
|
||||||
|
paging = True
|
||||||
|
|
||||||
|
# search-url
|
||||||
|
url = 'http://api.deezer.com/'
|
||||||
|
search_url = url + 'search?{query}&index={offset}'
|
||||||
|
|
||||||
|
embedded_url = '<iframe scrolling="no" frameborder="0" allowTransparency="true" ' +\
|
||||||
|
'data-src="http://www.deezer.com/plugins/player?type=tracks&id={audioid}" ' +\
|
||||||
|
'width="540" height="80"></iframe>'
|
||||||
|
|
||||||
|
|
||||||
|
# do search-request
|
||||||
|
def request(query, params):
|
||||||
|
offset = (params['pageno'] - 1) * 25
|
||||||
|
|
||||||
|
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', []):
|
||||||
|
if result['type'] == 'track':
|
||||||
|
title = result['title']
|
||||||
|
url = result['link']
|
||||||
|
content = result['artist']['name'] +\
|
||||||
|
" • " +\
|
||||||
|
result['album']['title'] +\
|
||||||
|
" • " + result['title']
|
||||||
|
embedded = embedded_url.format(audioid=result['id'])
|
||||||
|
|
||||||
|
# append result
|
||||||
|
results.append({'url': url,
|
||||||
|
'title': title,
|
||||||
|
'embedded': embedded,
|
||||||
|
'content': content})
|
||||||
|
|
||||||
|
# return results
|
||||||
|
return results
|
@ -0,0 +1,70 @@
|
|||||||
|
## Digg (News, Social media)
|
||||||
|
#
|
||||||
|
# @website https://digg.com/
|
||||||
|
# @provide-api no
|
||||||
|
#
|
||||||
|
# @using-api no
|
||||||
|
# @results HTML (using search portal)
|
||||||
|
# @stable no (HTML can change)
|
||||||
|
# @parse url, title, content, publishedDate, thumbnail
|
||||||
|
|
||||||
|
from urllib import quote_plus
|
||||||
|
from json import loads
|
||||||
|
from lxml import html
|
||||||
|
from cgi import escape
|
||||||
|
from dateutil import parser
|
||||||
|
|
||||||
|
# engine dependent config
|
||||||
|
categories = ['news', 'social media']
|
||||||
|
paging = True
|
||||||
|
|
||||||
|
# search-url
|
||||||
|
base_url = 'https://digg.com/'
|
||||||
|
search_url = base_url+'api/search/{query}.json?position={position}&format=html'
|
||||||
|
|
||||||
|
# specific xpath variables
|
||||||
|
results_xpath = '//article'
|
||||||
|
link_xpath = './/small[@class="time"]//a'
|
||||||
|
title_xpath = './/h2//a//text()'
|
||||||
|
content_xpath = './/p//text()'
|
||||||
|
pubdate_xpath = './/time'
|
||||||
|
|
||||||
|
|
||||||
|
# do search-request
|
||||||
|
def request(query, params):
|
||||||
|
offset = (params['pageno'] - 1) * 10
|
||||||
|
params['url'] = search_url.format(position=offset,
|
||||||
|
query=quote_plus(query))
|
||||||
|
return params
|
||||||
|
|
||||||
|
|
||||||
|
# get response from search-request
|
||||||
|
def response(resp):
|
||||||
|
results = []
|
||||||
|
|
||||||
|
search_result = loads(resp.text)
|
||||||
|
|
||||||
|
if search_result['html'] == '':
|
||||||
|
return results
|
||||||
|
|
||||||
|
dom = html.fromstring(search_result['html'])
|
||||||
|
|
||||||
|
# parse results
|
||||||
|
for result in dom.xpath(results_xpath):
|
||||||
|
url = result.attrib.get('data-contenturl')
|
||||||
|
thumbnail = result.xpath('.//img')[0].attrib.get('src')
|
||||||
|
title = ''.join(result.xpath(title_xpath))
|
||||||
|
content = escape(''.join(result.xpath(content_xpath)))
|
||||||
|
pubdate = result.xpath(pubdate_xpath)[0].attrib.get('datetime')
|
||||||
|
publishedDate = parser.parse(pubdate)
|
||||||
|
|
||||||
|
# append result
|
||||||
|
results.append({'url': url,
|
||||||
|
'title': title,
|
||||||
|
'content': content,
|
||||||
|
'template': 'videos.html',
|
||||||
|
'publishedDate': publishedDate,
|
||||||
|
'thumbnail': thumbnail})
|
||||||
|
|
||||||
|
# return results
|
||||||
|
return results
|
@ -0,0 +1,95 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Flickr (Images)
|
||||||
|
#
|
||||||
|
# @website https://www.flickr.com
|
||||||
|
# @provide-api yes (https://secure.flickr.com/services/api/flickr.photos.search.html)
|
||||||
|
#
|
||||||
|
# @using-api no
|
||||||
|
# @results HTML
|
||||||
|
# @stable no
|
||||||
|
# @parse url, title, thumbnail, img_src
|
||||||
|
|
||||||
|
from urllib import urlencode
|
||||||
|
from json import loads
|
||||||
|
import re
|
||||||
|
|
||||||
|
categories = ['images']
|
||||||
|
|
||||||
|
url = 'https://secure.flickr.com/'
|
||||||
|
search_url = url+'search/?{query}&page={page}'
|
||||||
|
photo_url = 'https://www.flickr.com/photos/{userid}/{photoid}'
|
||||||
|
regex = re.compile(r"\"search-photos-models\",\"photos\":(.*}),\"totalItems\":", re.DOTALL)
|
||||||
|
image_sizes = ('o', 'k', 'h', 'b', 'c', 'z', 'n', 'm', 't', 'q', 's')
|
||||||
|
|
||||||
|
paging = True
|
||||||
|
|
||||||
|
|
||||||
|
def build_flickr_url(user_id, photo_id):
|
||||||
|
return photo_url.format(userid=user_id, photoid=photo_id)
|
||||||
|
|
||||||
|
|
||||||
|
def request(query, params):
|
||||||
|
params['url'] = search_url.format(query=urlencode({'text': query}),
|
||||||
|
page=params['pageno'])
|
||||||
|
return params
|
||||||
|
|
||||||
|
|
||||||
|
def response(resp):
|
||||||
|
results = []
|
||||||
|
|
||||||
|
matches = regex.search(resp.text)
|
||||||
|
|
||||||
|
if matches is None:
|
||||||
|
return results
|
||||||
|
|
||||||
|
match = matches.group(1)
|
||||||
|
search_results = loads(match)
|
||||||
|
|
||||||
|
if '_data' not in search_results:
|
||||||
|
return []
|
||||||
|
|
||||||
|
photos = search_results['_data']
|
||||||
|
|
||||||
|
for photo in photos:
|
||||||
|
|
||||||
|
# In paged configuration, the first pages' photos
|
||||||
|
# are represented by a None object
|
||||||
|
if photo is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
img_src = None
|
||||||
|
# From the biggest to the lowest format
|
||||||
|
for image_size in image_sizes:
|
||||||
|
if image_size in photo['sizes']:
|
||||||
|
img_src = photo['sizes'][image_size]['displayUrl']
|
||||||
|
break
|
||||||
|
|
||||||
|
if not img_src:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if 'id' not in photo['owner']:
|
||||||
|
continue
|
||||||
|
|
||||||
|
url = build_flickr_url(photo['owner']['id'], photo['id'])
|
||||||
|
|
||||||
|
title = photo['title']
|
||||||
|
|
||||||
|
content = '<span class="photo-author">' +\
|
||||||
|
photo['owner']['username'] +\
|
||||||
|
'</span><br />'
|
||||||
|
|
||||||
|
if 'description' in photo:
|
||||||
|
content = content +\
|
||||||
|
'<span class="description">' +\
|
||||||
|
photo['description'] +\
|
||||||
|
'</span>'
|
||||||
|
|
||||||
|
# append result
|
||||||
|
results.append({'url': url,
|
||||||
|
'title': title,
|
||||||
|
'img_src': img_src,
|
||||||
|
'content': content,
|
||||||
|
'template': 'images.html'})
|
||||||
|
|
||||||
|
return results
|
@ -1,54 +1,87 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
## Flickr (Images)
|
||||||
|
#
|
||||||
|
# @website https://www.flickr.com
|
||||||
|
# @provide-api yes (https://secure.flickr.com/services/api/flickr.photos.search.html)
|
||||||
|
#
|
||||||
|
# @using-api yes
|
||||||
|
# @results JSON
|
||||||
|
# @stable yes
|
||||||
|
# @parse url, title, thumbnail, img_src
|
||||||
|
#More info on api-key : https://www.flickr.com/services/apps/create/
|
||||||
|
|
||||||
from urllib import urlencode
|
from urllib import urlencode
|
||||||
#from json import loads
|
from json import loads
|
||||||
from urlparse import urljoin
|
|
||||||
from lxml import html
|
|
||||||
from time import time
|
|
||||||
|
|
||||||
categories = ['images']
|
categories = ['images']
|
||||||
|
|
||||||
url = 'https://secure.flickr.com/'
|
nb_per_page = 15
|
||||||
search_url = url+'search/?{query}&page={page}'
|
paging = True
|
||||||
results_xpath = '//div[@class="view display-item-tile"]/figure/div'
|
api_key = None
|
||||||
|
|
||||||
|
|
||||||
|
url = 'https://api.flickr.com/services/rest/?method=flickr.photos.search' +\
|
||||||
|
'&api_key={api_key}&{text}&sort=relevance' +\
|
||||||
|
'&extras=description%2C+owner_name%2C+url_o%2C+url_z' +\
|
||||||
|
'&per_page={nb_per_page}&format=json&nojsoncallback=1&page={page}'
|
||||||
|
photo_url = 'https://www.flickr.com/photos/{userid}/{photoid}'
|
||||||
|
|
||||||
paging = True
|
paging = True
|
||||||
|
|
||||||
|
|
||||||
|
def build_flickr_url(user_id, photo_id):
|
||||||
|
return photo_url.format(userid=user_id, photoid=photo_id)
|
||||||
|
|
||||||
|
|
||||||
def request(query, params):
|
def request(query, params):
|
||||||
params['url'] = search_url.format(query=urlencode({'text': query}),
|
params['url'] = url.format(text=urlencode({'text': query}),
|
||||||
page=params['pageno'])
|
api_key=api_key,
|
||||||
time_string = str(int(time())-3)
|
nb_per_page=nb_per_page,
|
||||||
params['cookies']['BX'] = '3oqjr6d9nmpgl&b=3&s=dh'
|
page=params['pageno'])
|
||||||
params['cookies']['xb'] = '421409'
|
|
||||||
params['cookies']['localization'] = 'en-us'
|
|
||||||
params['cookies']['flrbp'] = time_string +\
|
|
||||||
'-3a8cdb85a427a33efda421fbda347b2eaf765a54'
|
|
||||||
params['cookies']['flrbs'] = time_string +\
|
|
||||||
'-ed142ae8765ee62c9ec92a9513665e0ee1ba6776'
|
|
||||||
params['cookies']['flrb'] = '9'
|
|
||||||
return params
|
return params
|
||||||
|
|
||||||
|
|
||||||
def response(resp):
|
def response(resp):
|
||||||
results = []
|
results = []
|
||||||
dom = html.fromstring(resp.text)
|
|
||||||
for result in dom.xpath(results_xpath):
|
|
||||||
img = result.xpath('.//img')
|
|
||||||
|
|
||||||
if not img:
|
search_results = loads(resp.text)
|
||||||
continue
|
|
||||||
|
|
||||||
img = img[0]
|
# return empty array if there are no results
|
||||||
img_src = 'https:'+img.attrib.get('src')
|
if not 'photos' in search_results:
|
||||||
|
return []
|
||||||
|
|
||||||
if not img_src:
|
if not 'photo' in search_results['photos']:
|
||||||
|
return []
|
||||||
|
|
||||||
|
photos = search_results['photos']['photo']
|
||||||
|
|
||||||
|
# parse results
|
||||||
|
for photo in photos:
|
||||||
|
if 'url_o' in photo:
|
||||||
|
img_src = photo['url_o']
|
||||||
|
elif 'url_z' in photo:
|
||||||
|
img_src = photo['url_z']
|
||||||
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
href = urljoin(url, result.xpath('.//a')[0].attrib.get('href'))
|
url = build_flickr_url(photo['owner'], photo['id'])
|
||||||
title = img.attrib.get('alt', '')
|
|
||||||
results.append({'url': href,
|
title = photo['title']
|
||||||
|
|
||||||
|
content = '<span class="photo-author">' +\
|
||||||
|
photo['ownername'] +\
|
||||||
|
'</span><br />' +\
|
||||||
|
'<span class="description">' +\
|
||||||
|
photo['description']['_content'] +\
|
||||||
|
'</span>'
|
||||||
|
|
||||||
|
# append result
|
||||||
|
results.append({'url': url,
|
||||||
'title': title,
|
'title': title,
|
||||||
'img_src': img_src,
|
'img_src': img_src,
|
||||||
|
'content': content,
|
||||||
'template': 'images.html'})
|
'template': 'images.html'})
|
||||||
|
|
||||||
|
# return results
|
||||||
return results
|
return results
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
## Subtitleseeker (Video)
|
||||||
|
#
|
||||||
|
# @website http://www.subtitleseeker.com
|
||||||
|
# @provide-api no
|
||||||
|
#
|
||||||
|
# @using-api no
|
||||||
|
# @results HTML
|
||||||
|
# @stable no (HTML can change)
|
||||||
|
# @parse url, title, content
|
||||||
|
|
||||||
|
from cgi import escape
|
||||||
|
from urllib import quote_plus
|
||||||
|
from lxml import html
|
||||||
|
from searx.languages import language_codes
|
||||||
|
|
||||||
|
# engine dependent config
|
||||||
|
categories = ['videos']
|
||||||
|
paging = True
|
||||||
|
language = ""
|
||||||
|
|
||||||
|
# search-url
|
||||||
|
url = 'http://www.subtitleseeker.com/'
|
||||||
|
search_url = url+'search/TITLES/{query}&p={pageno}'
|
||||||
|
|
||||||
|
# specific xpath variables
|
||||||
|
results_xpath = '//div[@class="boxRows"]'
|
||||||
|
|
||||||
|
|
||||||
|
# do search-request
|
||||||
|
def request(query, params):
|
||||||
|
params['url'] = search_url.format(query=quote_plus(query),
|
||||||
|
pageno=params['pageno'])
|
||||||
|
return params
|
||||||
|
|
||||||
|
|
||||||
|
# get response from search-request
|
||||||
|
def response(resp):
|
||||||
|
results = []
|
||||||
|
|
||||||
|
dom = html.fromstring(resp.text)
|
||||||
|
|
||||||
|
search_lang = ""
|
||||||
|
|
||||||
|
if resp.search_params['language'] != 'all':
|
||||||
|
search_lang = [lc[1]
|
||||||
|
for lc in language_codes
|
||||||
|
if lc[0][:2] == resp.search_params['language']][0]
|
||||||
|
|
||||||
|
# parse results
|
||||||
|
for result in dom.xpath(results_xpath):
|
||||||
|
link = result.xpath(".//a")[0]
|
||||||
|
href = link.attrib.get('href')
|
||||||
|
|
||||||
|
if language is not "":
|
||||||
|
href = href + language + '/'
|
||||||
|
elif search_lang:
|
||||||
|
href = href + search_lang + '/'
|
||||||
|
|
||||||
|
title = escape(link.xpath(".//text()")[0])
|
||||||
|
|
||||||
|
content = result.xpath('.//div[contains(@class,"red")]//text()')[0]
|
||||||
|
content = content + " - "
|
||||||
|
text = result.xpath('.//div[contains(@class,"grey-web")]')[0]
|
||||||
|
content = content + html.tostring(text, method='text')
|
||||||
|
|
||||||
|
if result.xpath(".//span") != []:
|
||||||
|
content = content +\
|
||||||
|
" - (" +\
|
||||||
|
result.xpath(".//span//text()")[0].strip() +\
|
||||||
|
")"
|
||||||
|
|
||||||
|
# append result
|
||||||
|
results.append({'url': href,
|
||||||
|
'title': title,
|
||||||
|
'content': escape(content)})
|
||||||
|
|
||||||
|
# return results
|
||||||
|
return results
|
@ -1,2 +0,0 @@
|
|||||||
/*! oscar/searx.min.js | 22-12-2014 | https://github.com/asciimoo/searx */
|
|
||||||
requirejs.config({baseUrl:"./static/oscar/js",paths:{app:"../app"}}),searx.autocompleter&&(searx.searchResults=new Bloodhound({datumTokenizer:Bloodhound.tokenizers.obj.whitespace("value"),queryTokenizer:Bloodhound.tokenizers.whitespace,remote:"/autocompleter?q=%QUERY"}),searx.searchResults.initialize()),$(document).ready(function(){searx.autocompleter&&$("#q").typeahead(null,{name:"search-results",displayKey:function(a){return a},source:searx.searchResults.ttAdapter()})}),$(document).ready(function(){$("#q.autofocus").focus(),$(".select-all-on-click").click(function(){$(this).select()}),$(".btn-collapse").click(function(){var a=$(this).data("btn-text-collapsed"),b=$(this).data("btn-text-not-collapsed");""!==a&&""!==b&&(new_html=$(this).hasClass("collapsed")?$(this).html().replace(a,b):$(this).html().replace(b,a),$(this).html(new_html))}),$(".btn-toggle .btn").click(function(){var a="btn-"+$(this).data("btn-class"),b=$(this).data("btn-label-default"),c=$(this).data("btn-label-toggled");""!==c&&(new_html=$(this).hasClass("btn-default")?$(this).html().replace(b,c):$(this).html().replace(c,b),$(this).html(new_html)),$(this).toggleClass(a),$(this).toggleClass("btn-default")}),$(".btn-sm").dblclick(function(){var a="btn-"+$(this).data("btn-class");$(this).hasClass("btn-default")?($(".btn-sm > input").attr("checked","checked"),$(".btn-sm > input").prop("checked",!0),$(".btn-sm").addClass(a),$(".btn-sm").addClass("active"),$(".btn-sm").removeClass("btn-default")):($(".btn-sm > input").attr("checked",""),$(".btn-sm > input").removeAttr("checked"),$(".btn-sm > input").checked=!1,$(".btn-sm").removeClass(a),$(".btn-sm").removeClass("active"),$(".btn-sm").addClass("btn-default"))})}),$(document).ready(function(){$(".searx_overpass_request").on("click",function(a){var b="https://overpass-api.de/api/interpreter?data=",c=b+"[out:json][timeout:25];(",d=");out meta;",e=$(this).data("osm-id"),f=$(this).data("osm-type"),g=$(this).data("result-table"),h="#"+$(this).data("result-table-loadicon"),i=["addr:city","addr:country","addr:housenumber","addr:postcode","addr:street"];if(e&&f&&g){g="#"+g;var j=null;switch(f){case"node":j=c+"node("+e+");"+d;break;case"way":j=c+"way("+e+");"+d;break;case"relation":j=c+"relation("+e+");"+d}if(j){$.ajax(j).done(function(a){if(a&&a.elements&&a.elements[0]){var b=a.elements[0],c=$(g).html();for(var d in b.tags)if(null===b.tags.name||-1==i.indexOf(d)){switch(c+="<tr><td>"+d+"</td><td>",d){case"phone":case"fax":c+='<a href="tel:'+b.tags[d].replace(/ /g,"")+'">'+b.tags[d]+"</a>";break;case"email":c+='<a href="mailto:'+b.tags[d]+'">'+b.tags[d]+"</a>";break;case"website":case"url":c+='<a href="'+b.tags[d]+'">'+b.tags[d]+"</a>";break;case"wikidata":c+='<a href="https://www.wikidata.org/wiki/'+b.tags[d]+'">'+b.tags[d]+"</a>";break;case"wikipedia":if(-1!=b.tags[d].indexOf(":")){c+='<a href="https://'+b.tags[d].substring(0,b.tags[d].indexOf(":"))+".wikipedia.org/wiki/"+b.tags[d].substring(b.tags[d].indexOf(":")+1)+'">'+b.tags[d]+"</a>";break}default:c+=b.tags[d]}c+="</td></tr>"}$(g).html(c),$(g).removeClass("hidden"),$(h).addClass("hidden")}}).fail(function(){$(h).html($(h).html()+'<p class="text-muted">could not load data!</p>')})}}$(this).off(a)}),$(".searx_init_map").on("click",function(a){var b=$(this).data("leaflet-target"),c=$(this).data("map-lon"),d=$(this).data("map-lat"),e=$(this).data("map-zoom"),f=$(this).data("map-boundingbox"),g=$(this).data("map-geojson");require(["leaflet-0.7.3.min"],function(){f&&(southWest=L.latLng(f[0],f[2]),northEast=L.latLng(f[1],f[3]),map_bounds=L.latLngBounds(southWest,northEast)),L.Icon.Default.imagePath="./static/oscar/img/map";{var a=L.map(b),h="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",i='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors',j=new L.TileLayer(h,{minZoom:1,maxZoom:19,attribution:i}),k="http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpg",l='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors | Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png">',m=new L.TileLayer(k,{minZoom:1,maxZoom:18,subdomains:"1234",attribution:l}),n="http://otile{s}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg",o='Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors | Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="https://developer.mapquest.com/content/osm/mq_logo.png"> | Portions Courtesy NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency';new L.TileLayer(n,{minZoom:1,maxZoom:11,subdomains:"1234",attribution:o})}map_bounds?setTimeout(function(){a.fitBounds(map_bounds,{maxZoom:17})},0):c&&d&&(e?a.setView(new L.LatLng(d,c),e):a.setView(new L.LatLng(d,c),8)),a.addLayer(m);var p={"OSM Mapnik":j,MapQuest:m};L.control.layers(p).addTo(a),g&&L.geoJson(g).addTo(a)}),$(this).off(a)})});
|
|
Before Width: | Height: | Size: 342 KiB After Width: | Height: | Size: 342 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 603 B After Width: | Height: | Size: 603 B |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
@ -1,14 +1,14 @@
|
|||||||
install dependencies
|
install dependencies
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
run this command in the directory ``searx/static/oscar``
|
run this command in the directory ``searx/static/themes/oscar``
|
||||||
|
|
||||||
``npm install``
|
``npm install``
|
||||||
|
|
||||||
compile sources
|
compile sources
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
run this command in the directory ``searx/static/oscar``
|
run this command in the directory ``searx/static/themes/oscar``
|
||||||
|
|
||||||
``grunt``
|
``grunt``
|
||||||
|
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |