Commit 654d7568 authored by Antoine Beaupré's avatar Antoine Beaupré

ubuntu-like search engine prototype

parent c7c82b6b
......@@ -267,7 +267,7 @@ class ManpageRenderer(object):
'''abstract class to store the manpage regex pattern'''
#: default pattern for manpages
pattern = r'/(?P<path>man/(?:\w+/)?man[1-9]/.+\.[1-9]\w*(?:\.gz))?$'
pattern = r'/(?:(?P<suite>\w+)/)?(?P<path>man/(?:\w+/)?man[1-9]/(?P<name>.+)\.(?P<section>[1-9]\w*)(?:\.gz))?$'
class W3mRenderer(CommandRenderer, ManpageRenderer):
......
# coding: utf-8
'''search engine for debmans'''
# Copyright (C) 2016 Antoine Beaupré <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import division, absolute_import
from __future__ import print_function
import re
import click
from flask import Flask
app = Flask(__name__)
from jinja2 import Template
from debmans.utils import find_static_file
from debmans.renderer import find_files, ManpageRenderer
@app.route('/')
def hello_world():
return 'Hello, World!'
@app.route('/<pattern>')
def search(pattern):
'''respond to searches requests
.. todo:: messy use of Jinja directly because Flask expects
templates to be in templates/ here. just follow the
convention in `the flask manual
<http://flask.pocoo.org/docs/0.11/quickstart/#rendering-templates>`_
.. todo:: Flask also expects static files to be in static/, so we
should copy them there instead of at the root
.. todo:: unit test this: http://flask.pocoo.org/docs/0.11/testing/
.. note:: inspired by http://manpages.ubuntu.com/cgi-bin/search.py?q=man
'''
with open(find_static_file('static/template.html'), 'r') as tmpl:
r = Template(tmpl.read().decode('utf-8'))
# XXX: this is getting a tad ridiculous now
# we shouldn't have to hack at the pattern like this
#
# there is a similar problem in dispatch - maybe file list
# should include the match pattern?
pattern = re.sub('\(\?P<name>[^)]*\)',
pattern, # XXX: wildcard or not?
ManpageRenderer.pattern)
app.logger.debug('searching for pattern: %s', pattern)
patterns = {}
# XXX: this doesn't belong here? should be command-level patterns
patterns[re.compile(pattern)] = None
# XXX: not sure this is the best structure
manpages = {} # suite -> (name, section)
i = 0
for path in find_files(app.config['output'], patterns):
i += 1
# XXX: again
m = re.search(ManpageRenderer.pattern, path)
assert m
suite = m.group('suite')
name = m.group('name')
section = m.group('section')
if section not in manpages:
manpages[section] = set()
app.logger.debug('found manpage %s (%s) in %s', name, section, suite)
manpages[section].add((name, suite))
# XXX: should extend the normal template instead
# see http://flask.pocoo.org/docs/0.11/tutorial/templates/#login-html
# XXX: this should also know about all sections, probably?
t = Template('''
<table>
{% for section, mans in manpages.iteritems() %}
<tr>
{% for man, suite in mans %}
<td>{{ man }} ({{suite}})</td>
{% endfor %}
</tr>
{%endfor%}
</table>
''')
content = '%d manuals found' % i
content += t.render(manpages=manpages)
#for suite, mans in manpages.iteritems():
# content += 'suite: %s' % suite
# for man, sect in mans:
# app.logger.debug('go man: %s', man)
# content += 'man: %s sect %s' % (man, sect)
return r.render(content=content, suites={})
@click.command()
@click.pass_obj
def devsearch(obj):
'''search the given output directory
.. todo:: this should probably replace serve
obviously, a production setup would not have this as a click
command, but as a CGI or WSGI app. see:
http://flask.pocoo.org/docs/0.11/deploying/#self-hosted-options
simplest is probably to provide WSGI and CGI shims. WSGI works
well in apache (and also works in Nginx) according to this:
https://www.digitalocean.com/community/tutorials/django-server-comparison-the-development-server-mod_wsgi-uwsgi-and-gunicorn
and CGI works everywhere.
see also:
https://blog.pythonanywhere.com/36/ nginx+uWSGI vs Apache - why we switched.
'''
main(obj['output'])
def main(output):
# XXX: not sure this is right, see http://flask.pocoo.org/docs/0.11/config/
app.config['output'] = output
app.run(port=8000)
if __name__ == '__main__':
main(output='.')
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment