import os import errno from fnmatch import fnmatch from gzip import GzipFile from debian_bundle import deb822 import patchtracker.Conf as Conf class Archive: root = None distsdir = None def __init__(self, dir): self.root = dir self.distsdir = os.sep.join([dir, "dists"]) def suites(self): for s in os.listdir(self.distsdir): yield s def components(self, suite): f = file(self.distsdir + os.sep + os.sep.join([suite, "Release"])) rel = deb822.Release(f) for comp in rel['Components'].split(' '): yield comp def sourcepackages(self, suite, component): sfile=os.sep.join([self.distsdir,suite,component,"/source/Sources.gz"]) for ent in deb822.Sources.iter_paragraphs(GzipFile(sfile)): if fnmatch(ent['Package'], 'av*'): yield SourcePackage(ent) def __str__(self): return "Archive rooted at "+self.root class SourcePackage: name = None format = None diffgz = None loc = None type = "Native" version = None seriespatches = {} directpatches = [] # todo vcs = {} def __init__(self, info): self.name = info['Package'] self.format = info['Format'] self.loc = info['Directory'] self.version = info['Version'] for f in info['Files']: if fnmatch(f['name'], '*.diff.gz'): self.diffgz=f self.type = "Debian-diff" if self.diffgz != None: self.debianonlydiff = "_".join([self.name, self.version, "debianonly.diff"]) self.nondebiandiff = "_".join([self.name, self.version, "nondebian.diff"]) def idx(self): name = str(self) if len(name) < 4 or name[0:3] != "lib": return name[0] else: return name[0:4] ## XXX okay, all of this could be made quite a bit cleaner def diff_series(self, outdir): if self.diffgz: debdiff = os.sep.join([outdir, self.debianonlydiff]) seriesdir = os.sep.join([outdir, "series"]) try: os.mkdir(os.sep.join([outdir,"series"])) except OSError, e: if e.errno != errno.EEXIST: raise e # XXX better way to be idempotent else: return os.system("filterdiff -p 1 -i 'debian/patches/*' "+debdiff+"| ( cd "+ seriesdir+"; patch -s )") for (blah,blahblah,files) in os.walk(seriesdir): try: files.remove('series') files.remove('00list') except: pass for f in files: p = os.sep.join([seriesdir, f]) # get the info for summary generation fd = os.popen("diffstat "+p) self.seriespatches[f] = fd.read() fd.close() os.system("source-highlight -s diff -f xhtml -i "+p+" -o "+p+".html") def diff_debiandir(self, outdir): try: src = os.sep.join([Conf.archive_root, self.loc, self.diffgz['name']]) dst = os.sep.join([outdir, self.debianonlydiff]) try: os.stat(dst) return # XXX better way to be idempotent except OSError, e: pass os.system("filterdiff -z -p 1 -i 'debian/*' "+src+" > "+dst) os.system("source-highlight -s diff -f xhtml -i "+dst+" -o "+dst+".html") # in the case of native packages there is no diffgz except TypeError: pass def diff_nondebiandir(self, outdir): try: src = os.sep.join([Conf.archive_root, self.loc, self.diffgz['name']]) dst = os.sep.join([outdir, self.nondebiandiff]) try: os.stat(dst) return # XXX better way to be idempotent except OSError, e: pass os.system("filterdiff -z -p 1 -x 'debian/*' "+src+" > "+dst) os.system("source-highlight -s diff -f xhtml -i "+dst+" -o "+dst+".html") # in the case of native packages there is no diffgz except TypeError: pass def __str__(self): return self.name class SourcePackageIndex: pkgs = {} def ins(self, srcpkg, rel): idx = srcpkg.idx() if not self.pkgs.has_key(idx): self.pkgs[idx] = {} if not self.pkgs[idx].has_key(srcpkg.name): self.pkgs[idx][srcpkg.name] = {} if not self.pkgs[idx][srcpkg.name].has_key(rel): self.pkgs[idx][srcpkg.name][rel] = srcpkg def indices(self): for k,v in self.pkgs.iteritems(): yield (k,v)