summaryrefslogtreecommitdiff
path: root/webapp.py
diff options
context:
space:
mode:
Diffstat (limited to 'webapp.py')
-rwxr-xr-xwebapp.py79
1 files changed, 53 insertions, 26 deletions
diff --git a/webapp.py b/webapp.py
index 9612c38..e173d60 100755
--- a/webapp.py
+++ b/webapp.py
@@ -106,25 +106,28 @@ class Application(object):
except HTTPException as e:
return e
- def get_details(self, package):
+ def guess_package(self, package):
with contextlib.closing(self.db.cursor()) as cur:
- cur.execute("SELECT id, version, architecture FROM package WHERE name = ?;",
+ cur.execute("SELECT architecture, id FROM package WHERE name = ?;",
(package,))
+ ret = dict(cur.fetchall())
+ if not ret:
+ raise NotFound()
+ return ret
+
+ def get_details(self, package, architecture):
+ with contextlib.closing(self.db.cursor()) as cur:
+ cur.execute("SELECT package.id, package.version, count(content.filename), sum(content.size) FROM package JOIN content ON package.id = content.pid WHERE name = ? AND architecture = ? GROUP BY package.id;",
+ (package, architecture))
row = cur.fetchone()
- if not row:
- raise NotFound()
- pid, version, architecture = row
- details = dict(pid=pid,
- package=package,
- version=version,
- architecture=architecture)
- cur.execute("SELECT count(filename), sum(size) FROM content WHERE pid = ?;",
- (pid,))
- num_files, total_size = cur.fetchone()
+ if not row:
+ raise NotFound()
+ pid, version, num_files, total_size = row
if total_size is None:
total_size = 0
- details.update(dict(num_files=num_files, total_size=total_size))
- return details
+ return dict(pid=pid, package=package, version=version,
+ architecture=architecture, num_files=num_files,
+ total_size=total_size)
def get_dependencies(self, pid):
with contextlib.closing(self.db.cursor()) as cur:
@@ -135,19 +138,27 @@ class Application(object):
def cached_sharedstats(self, pid):
sharedstats = {}
with contextlib.closing(self.db.cursor()) as cur:
- cur.execute("SELECT pid2, package.name, f1.name, f2.name, files, size FROM sharing JOIN package ON sharing.pid2 = package.id JOIN function AS f1 ON sharing.fid1 = f1.id JOIN function AS f2 ON sharing.fid2 = f2.id WHERE pid1 = ? AND f1.eqclass = f2.eqclass;",
+ cur.execute("SELECT pid2, package.name, package.architecture, f1.name, f2.name, files, size FROM sharing JOIN package ON sharing.pid2 = package.id JOIN function AS f1 ON sharing.fid1 = f1.id JOIN function AS f2 ON sharing.fid2 = f2.id WHERE pid1 = ? AND f1.eqclass = f2.eqclass;",
(pid,))
- for pid2, package2, func1, func2, files, size in fetchiter(cur):
+ for pid2, package2, architecture2, func1, func2, files, size in fetchiter(cur):
curstats = sharedstats.setdefault(
function_combination(func1, func2), list())
if pid2 == pid:
package2 = None
- curstats.append(dict(package=package2, duplicate=files,
- savable=size))
+ architecture2 = None
+ curstats.append(dict(package=package2,
+ architecture=architecture2,
+ duplicate=files, savable=size))
return sharedstats
def show_package(self, package):
- params = self.get_details(package)
+ if ':' in package:
+ package, architecture = package.split(':', 1)
+ else:
+ architecture = min(self.guess_package(package))
+ raise InternalRedirect("/binary/%s:%s" % (package, architecture),
+ code=302)
+ params = self.get_details(package, architecture)
params["dependencies"] = self.get_dependencies(params["pid"])
params["shared"] = self.cached_sharedstats(params["pid"])
params["urlroot"] = ".."
@@ -203,9 +214,24 @@ class Application(object):
yield entry
def show_detail(self, package1, package2):
- details1 = details2 = self.get_details(package1)
- if package1 != package2:
- details2 = self.get_details(package2)
+ guessed = False
+ if ':' in package1:
+ package1, architecture1 = package1.split(':', 1)
+ else:
+ architecture1 = min(self.guess_package(package1))
+ guessed = True
+ if ':' in package2:
+ package2, architecture2 = package2.split(':', 1)
+ else:
+ architecture2 = min(self.guess_package(package2))
+ guessed = True
+ if guessed:
+ raise InternalRedirect("/compare/%s:%s/%s:%s" %
+ (package1, architecture1, package2,
+ architecture2), code=302)
+ details1 = details2 = self.get_details(package1, architecture1)
+ if package1 != package2 or architecture1 != architecture2:
+ details2 = self.get_details(package2, architecture2)
shared = self.compute_comparison(details1["pid"], details2["pid"])
params = dict(
@@ -217,11 +243,12 @@ class Application(object):
def show_hash(self, function, hashvalue):
with contextlib.closing(self.db.cursor()) as cur:
- cur.execute("SELECT package.name, content.filename, content.size, f2.name FROM hash JOIN content ON hash.cid = content.id JOIN package ON content.pid = package.id JOIN function AS f2 ON hash.fid = f2.id JOIN function AS f1 ON f2.eqclass = f1.eqclass WHERE f1.name = ? AND hash = ?;",
+ cur.execute("SELECT package.name, package.architecture, content.filename, content.size, f2.name FROM hash JOIN content ON hash.cid = content.id JOIN package ON content.pid = package.id JOIN function AS f2 ON hash.fid = f2.id JOIN function AS f1 ON f2.eqclass = f1.eqclass WHERE f1.name = ? AND hash = ?;",
(function, hashvalue,))
- entries = [dict(package=package, filename=filename, size=size,
- function=otherfunc)
- for package, filename, size, otherfunc in fetchiter(cur)]
+ entries = [dict(package=package, architecture=architecture,
+ filename=filename, size=size, function=otherfunc)
+ for package, architecture, filename, size, otherfunc
+ in fetchiter(cur)]
if not entries:
# Assumption: '~' serves as an infinite character larger than
# any other character in the hash column.