diff options
Diffstat (limited to 'webapp.py')
-rwxr-xr-x | webapp.py | 79 |
1 files changed, 53 insertions, 26 deletions
@@ -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. |