summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHelmut Grohne <helmut@subdivi.de>2014-05-11 15:25:46 +0200
committerHelmut Grohne <helmut@subdivi.de>2014-05-11 15:27:56 +0200
commit6a62d49350d44176de08afa980a47017007f4a3c (patch)
tree194976d0d1a1f82dbdea0292f422c3e6af61d384
parent03d6cc0a5ac4d546f234d8326551f2ee35e0f1a5 (diff)
downloaddebian-dedup-6a62d49350d44176de08afa980a47017007f4a3c.tar.gz
webapp: allow git-like hash truncation
-rwxr-xr-xwebapp.py30
1 files changed, 23 insertions, 7 deletions
diff --git a/webapp.py b/webapp.py
index 2fd69bb..9612c38 100755
--- a/webapp.py
+++ b/webapp.py
@@ -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))