Author: fw Date: 2011-04-24 15:02:36 +0000 (Sun, 24 Apr 2011) New Revision: 16578 Modified: bin/list-queue Log: bin/list-queue: export contents of .changes files Modified: bin/list-queue ==================================================================--- bin/list-queue 2011-04-24 14:25:18 UTC (rev 16577) +++ bin/list-queue 2011-04-24 15:02:36 UTC (rev 16578) @@ -45,6 +45,7 @@ import json from debian.debfile import DebFile +from debian.deb822 import Changes import debian_support def createdb(): @@ -65,34 +66,59 @@ source TEXT NOT NULL, source_version TEXT NOT NULL )""") + db.execute("""CREATE TABLE IF NOT EXISTS changes ( + path TEXT NOT NULL PRIMARY KEY, + size INTEGER NOT NULL CHECK (size >= 0), + mtime INTEGER NOT NULL CHECK (size >= 0), + dist TEXT NOT NULL, + debs TEXT NOT NULL +)""") return db def readdirs(): - result = {} + """Returns two dicts, mapping paths to pairs (SIZE, MTIME). + + First dict is for .deb files, second is for .changes files.""" + debs = {} + changes = {} for path in DIRECTORIES: for entry in os.listdir(path): - if entry.startswith(".") or not entry.endswith(".deb"): + if entry.startswith("."): continue name = os.path.join(path, entry) stat = os.stat(name) - result[name] = (stat.st_size, stat.st_mtime) - return result + where = None + if entry.endswith(".deb"): + where = debs + elif entry.endswith(".changes"): + where = changes + if where is not None: + where[name] = (stat.st_size, stat.st_mtime) + return (debs, changes) def readpackages(db): result = {} - c = db.cursor() - for row in c.execute("SELECT * FROM package"): + for row in db.execute("SELECT * FROM package"): name, size, mtime = row[0:3] pkg = debian_support.BinaryPackage(row[3:]) result[name] = (size, mtime, pkg) return result -def updatepackages(db): +def readchanges(db): + result = {} + for name, size, mtime, dist, debs in db.execute("SELECT * FROM changes"): + result[name] = (size, mtime, dist, set(debs.split())) + return result + +def computeupdate(ondisk, indb): + return [(path, stat) for (path, stat) in ondisk.items() + if path not in indb or stat <> tuple(indb[path][0:2])] + +def updatepackages(db, ondisk): """Updates the package table from the file system. Returns the current list of package objects, in arbitary order. """ - ondisk = readdirs() indb = readpackages(db) # Expire old entries @@ -100,8 +126,7 @@ db.executemany("DELETE FROM package WHERE path = ?", need_delete) # Update the cache in indb and the database - need_update = [(path, stat) for (path, stat) in ondisk.items() - if path not in indb or stat <> tuple(indb[path][0:2])] + need_update = computeupdate(ondisk, indb) db.executemany("DELETE FROM package WHERE path = ?", ((path,) for path, _ in need_update)) def do_update(): @@ -117,12 +142,48 @@ # Return a list of BinaryPackage objects return [item[2] for item in indb.values()] +def updatechanges(db, ondisk): + """Updates the package table from the file system. + + Returns the current list of changes objects, in arbitary order. + Change objects are pairs (DISTRIBUTION, SET-OF-DEBS) + """ + indb = readchanges(db) + + # Expire old entries + need_delete = ((path,) for path in indb if path not in ondisk) + db.executemany("DELETE FROM changes WHERE path = ?", need_delete) + + # Update the cache in indb and the database + need_update = computeupdate(ondisk, indb) + db.executemany("DELETE FROM changes WHERE path = ?", + ((path,) for path, _ in need_update)) + def do_update(): + for (path, stat) in need_update: + changes = Changes(file(path)) + try: + dist = changes["Distribution"] + debs = set(pkg["name"] for pkg in changes["Checksums-Sha1"]) + except KeyError, e: + raise IOError("missing key in " + repr(path) + ": " + + repr(e.args[0])) + indb[path] = stat + (dist, debs) + yield (path,) + stat + (dist, " ".join(sorted(debs)),) + db.executemany("INSERT INTO changes VALUES (?, ?, ?, ?, ?)", do_update()) + + return [tuple(row[2:]) for row in indb.values()] + def main(): db = createdb() - pkgs = updatepackages(db) + debs, changes = readdirs() + debs = updatepackages(db, debs) + changes = updatechanges(db, changes) + for c in changes: + print repr(c) result = { "version" : 1, - "binary" : [pkg.astuple() for pkg in pkgs], + "binary" : [pkg.astuple() for pkg in debs], + "changes" : [[dist, sorted(debs)] for dist, debs in changes], } db.commit() print json.dumps(result)