logo

searx

My custom branche(s) on searx, a meta-search engine
commit: ae9fb1d7dccf061032b5d4b167086838feb1463d
Author: asciimoo <asciimoo@gmail.com>
Date:   Mon, 14 Oct 2013 23:09:13 +0200

[enh] initial commit

Diffstat:

A.gitignore2++
AREADME.md4++++
Arequirements.txt3+++
Asearx/__init__.py0
Asearx/engines/__init__.py15+++++++++++++++
Asearx/engines/duckduckgo.py14++++++++++++++
Asearx/static/css/style.css0
Asearx/templates/base.html17+++++++++++++++++
Asearx/templates/index.html8++++++++
Asearx/templates/results.html7+++++++
Asearx/webapp.py69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11 files changed, 139 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,2 @@ +env +searx.conf diff --git a/README.md b/README.md @@ -0,0 +1,4 @@ +searx +===== + +Minimalistic web interface to different search engines. diff --git a/requirements.txt b/requirements.txt @@ -0,0 +1,3 @@ +flask +grequests +lxml diff --git a/searx/__init__.py b/searx/__init__.py diff --git a/searx/engines/__init__.py b/searx/engines/__init__.py @@ -0,0 +1,15 @@ + +from os.path import realpath, dirname, splitext, join +from os import listdir +from imp import load_source + +engine_dir = dirname(realpath(__file__)) + +engines = [] + +for filename in listdir(engine_dir): + modname = splitext(filename)[0] + if filename.startswith('_') or not filename.endswith('.py'): + continue + filepath = join(engine_dir, filename) + engines.append(load_source(modname, filepath)) diff --git a/searx/engines/duckduckgo.py b/searx/engines/duckduckgo.py @@ -0,0 +1,14 @@ +from lxml import html + + +def request(query, params): + params['method'] = 'POST' + params['url'] = 'https://duckduckgo.com/html' + params['data']['q'] = query + return params + + +def response(resp): + dom = html.fromstring(resp.text) + results = dom.xpath('//div[@class="results_links results_links_deep web-result"]') + return [html.tostring(x) for x in results] diff --git a/searx/static/css/style.css b/searx/static/css/style.css diff --git a/searx/templates/base.html b/searx/templates/base.html @@ -0,0 +1,17 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> +<head> + <meta http-equiv="content-type" content="text/html; charset=utf-8" /> + <meta http-equiv="content-language" content="en" /> + <meta name="description" content="" /> + <meta name="keywords" content="" /> + <title>searx {% block title %}{% endblock %}</title> + <link rel="stylesheet" href="/static/css/style.css" type="text/css" media="screen" charset="utf-8" /> + {% block styles %} + {% endblock %} +</head> +<body> +{% block content %} +{% endblock %} +</body> +</html> diff --git a/searx/templates/index.html b/searx/templates/index.html @@ -0,0 +1,8 @@ +{% extends "base.html" %} +{% block content %} +<h1>searx</h1> +<form method="post" action=""> + <input type="text" name="q" /> + <input type="submit" value="search" /> +</form> +{% endblock %} diff --git a/searx/templates/results.html b/searx/templates/results.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} +{% block content %} +<h1>searx</h1> +{% for result in results %} + <p>{{ result|safe }}</p> +{% endfor %} +{% endblock %} diff --git a/searx/webapp.py b/searx/webapp.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python + +if __name__ == "__main__": + from sys import path + from os.path import realpath, dirname + path.append(realpath(dirname(realpath(__file__))+'/../')) + +from flask import Flask, request, flash, render_template +import ConfigParser +from os import getenv +from searx.engines import engines +import grequests + +cfg = ConfigParser.SafeConfigParser() +cfg.read('/etc/searx.conf') +cfg.read(getenv('HOME')+'/.searxrc') +cfg.read(getenv('HOME')+'/.config/searx/searx.conf') +cfg.read('searx.conf') + + +app = Flask(__name__) +app.secret_key = cfg.get('app', 'secret_key') + +def default_request_params(): + return {'method': 'GET', 'headers': {}, 'data': {}, 'url': ''} + +def make_callback(results, callback): + def process_callback(response, **kwargs): + results.extend(callback(response)) + return process_callback + +@app.route('/', methods=['GET', 'POST']) +def index(): + if request.method=='POST': + if not request.form.get('q'): + flash('Wrong post data') + return render_template('index.html') + query = request.form['q'] + requests = [] + results = [] + for engine in engines: + request_params = engine.request(query, default_request_params()) + callback = make_callback(results, engine.response) + if request_params['method'] == 'GET': + req = grequests.get(request_params['url'] + ,headers=request_params['headers'] + ,hooks=dict(response=callback) + ) + else: + req = grequests.post(request_params['url'] + ,data=request_params['data'] + ,headers=request_params['headers'] + ,hooks=dict(response=callback) + ) + requests.append(req) + grequests.map(requests) + return render_template('results.html', results=results) + + + return render_template('index.html') + +if __name__ == "__main__": + from gevent import monkey + monkey.patch_all() + + app.run(debug = cfg.get('server', 'debug') + ,use_debugger = cfg.get('server', 'debug') + ,port = int(cfg.get('server', 'port')) + )