diff options
author | Helmut Grohne <helmut@subdivi.de> | 2014-05-11 15:25:46 +0200 |
---|---|---|
committer | Helmut Grohne <helmut@subdivi.de> | 2014-05-11 15:27:56 +0200 |
commit | 6a62d49350d44176de08afa980a47017007f4a3c (patch) | |
tree | 194976d0d1a1f82dbdea0292f422c3e6af61d384 | |
parent | 03d6cc0a5ac4d546f234d8326551f2ee35e0f1a5 (diff) | |
download | debian-dedup-6a62d49350d44176de08afa980a47017007f4a3c.tar.gz |
webapp: allow git-like hash truncation
-rwxr-xr-x | webapp.py | 30 |
1 files changed, 23 insertions, 7 deletions
@@ -8,7 +8,8 @@ from wsgiref.simple_server import make_server import jinja2 from werkzeug.exceptions import HTTPException, NotFound -from werkzeug.routing import Map, Rule, RequestRedirect +from werkzeug.routing import Map, Rule +from werkzeug.utils import redirect from werkzeug.wrappers import Request, Response from werkzeug.wsgi import SharedDataMiddleware @@ -61,6 +62,12 @@ def html_response(unicode_iterator, max_age=24 * 60 * 60): resp.expires = datetime.datetime.now() + datetime.timedelta(seconds=max_age) return resp +class InternalRedirect(Exception): + def __init__(self, target, code=301): + Exception.__init__(self) + self.target = target + self.code = code + class Application(object): def __init__(self, db): self.db = db @@ -84,17 +91,18 @@ class Application(object): elif endpoint == "hash": if args["function"] == "image_sha512": # backwards compatibility - raise RequestRedirect("%s/hash/png_sha512/%s" % - (request.environ["SCRIPT_NAME"], - args["hashvalue"])) + raise InternalRedirect("/hash/png_sha512/%s" % + args["hashvalue"]) return self.show_hash(args["function"], args["hashvalue"]) elif endpoint == "index": if not request.environ["PATH_INFO"]: - raise RequestRedirect(request.environ["SCRIPT_NAME"] + "/") + raise InternalRedirect("/") return html_response(index_template.render(dict(urlroot=""))) elif endpoint == "source": return self.show_source(args["package"]) raise NotFound() + except InternalRedirect as r: + return redirect(request.environ["SCRIPT_NAME"] + r.target, r.code) except HTTPException as e: return e @@ -214,8 +222,16 @@ class Application(object): entries = [dict(package=package, filename=filename, size=size, function=otherfunc) for package, filename, size, otherfunc in fetchiter(cur)] - if not entries: - raise NotFound() + if not entries: + # Assumption: '~' serves as an infinite character larger than + # any other character in the hash column. + cur.execute("SELECT DISTINCT hash.hash FROM hash JOIN function ON hash.fid = function.id WHERE function.name = ? AND hash.hash >= ? AND hash.hash <= ? LIMIT 2;", + (function, hashvalue, hashvalue + '~')) + values = cur.fetchall() + if len(values) == 1: + raise InternalRedirect("/hash/%s/%s" % + (function, values[0][0]), 302) + raise NotFound() params = dict(function=function, hashvalue=hashvalue, entries=entries, urlroot="../..") return html_response(hash_template.render(params)) |