#!/usr/bin/env python import sys, os, commands, glob, md5, bz2 REPO = ['hnd', 'hnd-dev'] TYPE = 'main' ARCH = 'binary-iphoneos-arm' def notify(lvl, message): print " * %s%s" % (" "*lvl, message) def clean(): for ext in ('','.gz','.bz2'): for r in REPO: if os.path.isfile('dists/%s/%s/%s/Packages%s' % (r, TYPE, ARCH, ext)): notify(0, "Removing Packages%s of %s/%s" % (ext, r, TYPE)) os.unlink('dists/%s/%s/%s/Packages%s' % (r, TYPE, ARCH, ext)) def get_info(deb): err, c = commands.getstatusoutput('dpkg-deb -I %s control' % deb) if err != 0: notify(0, "Error processing %s info: %d" % (deb, err)) return None info = {} for i in c.split('\n'): k,v = i.split(': ',1) info[k] = v return info __compare_versions_cache = {} def compare_versions(a, b): global __compare_versions_cache if not (a,b) in __compare_versions_cache: ret = os.system("dpkg --compare-versions %s le %s" % (a,b)) != 0 __compare_versions_cache[(a,b)] = ret return __compare_versions_cache[(a,b)] def build_deblist(): pkgs = {} paths = glob.glob('debs/*/*.deb') cnt = 0 for pkg in paths: cnt += 1 notify(0, "Processing %s [%d/%d]" % (pkg, cnt, len(paths))) info = get_info(pkg) if not info: continue if not 'Package' in info: notify(2, "%s is missing 'Package' field, skipping" % (pkg)) continue if not 'Version' in info: notify(2, "%s is missing 'Version' field, skipping" % (pkg)) continue info['Filename'] = pkg pkgrepo = pkg.split('/',2)[1] info['__repotype'] = pkgrepo if not pkgrepo in pkgs: pkgs[pkgrepo] = {} pp = pkgs[pkgrepo] if not info['Package'] in pp: #notify(2, "added new package %s" % (pkg)) pp[info['Package']] = info else: if compare_versions(info['Version'], pp[info['Package']]['Version']): #notify(2, "%s > *%s, (* dropped)" % (pkg, pkgs[info['Package']]['Filename'])) pp[info['Package']] = info else: pass #notify(2, "*%s <= %s, (* dropped)" % (pkg, pkgs[info['Package']]['Filename'])) notify(0, "Pending packages:") pkglist = [] for pp in pkgs.itervalues(): for n,pkg in pp.iteritems(): pkg['Size'] = os.stat(pkg['Filename'])[6] m = md5.new(open(pkg['Filename']).read()) pkg['MD5Sum'] = m.hexdigest() notify(2, "%s %s [%s]" % (pkg['Package'], pkg['Version'], pkg['__repotype'])) pkglist.append(pkg) return pkglist def write_pkgs(pkgs): for r in REPO: notify(0, "Writing Packages and Packages.bz2 of %s/%s" % (r, TYPE)) f = open('dists/%s/%s/%s/Packages' % (r, TYPE, ARCH), 'w') fbz = bz2.BZ2File('dists/%s/%s/%s/Packages.bz2' % (r, TYPE, ARCH), 'w') for pkg in pkgs: if (not '__repotype' in pkg) or (pkg['__repotype'] != r): continue else: del pkg['__repotype'] notify(2, "%s" % (pkg['Package'])) for k,v in pkg.iteritems(): f.write("%s: %s\n" % (k,v)) fbz.write("%s: %s\n" % (k,v)) f.write('\n') fbz.write('\n') f.close() fbz.close() def update_release_md5(): for r in REPO: msz = [] for ext in '', '.bz2': d = {} fn = '%s/%s/Packages%s' % (TYPE, ARCH, ext) fullfn = 'dists/%s/%s' % (r, fn) d['fn'] = fn d['md5'] = md5.new(open(fullfn).read()).hexdigest() d['sz'] = os.stat(fullfn)[6] msz.append(d) release = open('dists/%s/Release' % (r,), 'r').readlines() f = open('dists/%s/Release' % (r,), 'w') notify(0, "Updating %s Release information" % (r,)) for i in release: if not i.startswith('MD5Sum:'): f.write('%s\n' % (i.strip())) else: break f.write('MD5Sum:\n') for d in msz: f.write(' %s %s %s\n' % (d['md5'], d['sz'], d['fn'])) f.close() if __name__ == '__main__': if (not os.path.isdir('dists')) or (not os.path.isdir('debs')): sys.exit(2) clean() pkgs = build_deblist() write_pkgs(pkgs) update_release_md5() for r in REPO: os.system('cd dists/%s; gpg2 -abs -o Release.gpg Release' % (r,))