#!/usr/bin/env python # vi: encoding=utf-8 ts=8 sts=4 sw=4 et import sys, os, config, string, urllib, re errnum=0 def bailoutonerror(): if not errnum == 0: print "%d error(s) encountered... aborting" % errnum sys.exit(1) def perror(msg): global errnum errnum=errnum+1 print msg def rm(file): print 'rm: '+file def mv(src, dst): print "mv: %s %s" % (src, dst) class Build: def __init__(self): self.requester='' self.requester_email='' class Pkg: def __init__(self, name, tree): self.file={} self.info={} self.build={} self.tree=tree self.name=name self.loaded=False self.marked4removal=False self.marked4moving=True self.load() def __repr__(self): return self.name def mark4moving(self): if not self.marked4moving: self.tree.marked4moving.append(self) self.marked4moving=True def mark4removal(self): if not self.marked4removal: self.tree.marked4removal.append(self) self.marked4removal=True def load(self): f=open(self.tree.basedir+'/SRPMS/.metadata/'+self.name+'.src.rpm.info', 'r') for entry in f.readlines(): i=string.split(string.strip(entry), ':') if i[0] == 'info': if len(i)==3: self.info[i[1]]=i[2] elif i[1]=='build': if not self.build.has_key(i[2]): self.build[i[2]]=Build() if i[3]=='requester': self.build[i[2]].requester=i[4] elif i[3]=='requester_email': self.build[i[2]].requester_email=i[4] else: self.info[i[1]]=i[2:] elif i[0] == 'file': if not self.file.has_key(i[1]): self.file[i[1]]=[] self.file[i[1]].append(i[2]) f.close() self.loaded=True if self.info.has_key('move'): self.mark4moving() def writeinfo(self): f=open(self.tree.basedir+'/SRPMS/.metadata/'+name+'.src.rpm.info', 'w') for bid in self.build.keys(): f.write("info:build:%s:requester:%s\ninfo:build:%s:requester_email:%s\n" % (bid, self.build[bid].requester, bid, self.build[bid].requester_email)) for key in self.info.keys(): f.write("info:%s:%s\n" % (key, string.join(self.info[key], ':'))) for arch in self.file.keys(): for rpm in self.file[arch]: f.write("file:%s:%s\n" % (arch, rpm)) def remove(self): for arch in self.file.keys(): for rpm in self.file[arch]: rm(self.tree.basedir+'/'+arch+'/RPMS/'+rpm) rm(self.tree.basedir+'/SRPMS/.metadata/'+self.name+'.src.rpm.info') def move(self, dsttree): if dsttree.has_key(self.name): movedany=False for arch in self.file.keys(): if arch in dsttree[self.name].file.keys(): for rpm in self.file[arch]: rm(self.tree.basedir+'/'+arch+'/RPMS/'+rpm) else: movedany=True dsttree[self.name].file[arch]=self.file[arch] for rpm in self.file[arch]: mv(self.tree.basedir+'/'+arch+'/RPMS/'+rpm, dsttree.basedir+'/'+arch+'/RPMS/') if movedany: for bid in self.build.keys(): dsttree[self.name].build[bid]=self.build[bid] dsttree[self.name].writeinfo() rm(self.tree.basedir+'/SRPMS/.metadata/'+self.name+'.src.rpm.info') else: for arch in self.file.keys(): for rpm in self.file[arch]: mv(self.tree.basedir+'/'+arch+'/RPMS/'+rpm, dsttree.basedir+'/'+arch+'/RPMS/') mv(self.tree.basedir+'/SRPMS/.metadata/'+self.name+'.src.rpm.info', dsttree.basedir+'/SRPMS/.metadata/') class FtpTree: def __init__(self, tree, loadall=False): self.basedir=config.value['ftp_dir']+'/'+tree self.loadedpkgs={} self.marked4removal=[] self.marked4moving=[] def filter_pkgs(pkg): if not pkg[-13:]=='.src.rpm.info': return None else: return pkg[:-13] self.pkgnames=map(filter_pkgs, os.listdir(self.basedir+'/SRPMS/.metadata/')) if loadall: for i in self.pkgnames: self.loadedpkgs[i]=Pkg(i, self) def __getitem__(self, key): if self.loadedpkgs.has_key(key): return self.loadedpkgs[key] elif key in self.pkgnames: pkg=Pkg(key, self) self.loadedpkgs[key]=pkg return pkg else: raise KeyError, key def has_key(self, key): if key in self.pkgnames: return True else: return False def keys(self): return self.pkgnames def movepkgs(self, dsttree): self.__checkbuild() bailoutonerror() self.__checkarchs(dsttree) bailoutonerror() self.__rmolderfromsrc() self.__rmotherfromdst(dsttree) for pkg in self.marked4moving: pkg.move(dsttree) def removepkgs(self): for pkg in self.marked4removal: pkg.remove() def mark4removal(self, wannabepkgs): self.__mark4something(wannabepkgs, Pkg.mark4removal) def mark4moving(self, wannabepkgs): self.__mark4something(wannabepkgs, Pkg.mark4moving) # Internal functions below def __mark4something(self, wannabepkgs, markfunction): def chopoffextension(pkg): found=pkg.find('.src.rpm') if found==-1: return pkg else: return pkg[:found] for wannabepkg in wannabepkgs: pkgname=chopoffextension(wannabepkg) if pkgname in self.pkgnames: if not pkgname in self.loadedpkgs.keys(): self.loadedpkgs[pkgname]=Pkg(pkgname, self) markfunction(self.loadedpkgs[pkgname]) else: perror(pkgname+" was not found in source tree") bailoutonerror() def __checkbuild(self): #f=urllib.urlopen('http://ep09.pld-linux.org/~builderth/queue.txt') f=open('queue.txt') requests={} reid=re.compile(r'^.*id=(.*) pri.*$') regb=re.compile(r'^group:.*$|builders:.*$', re.M) for i in re.findall(regb, f.read()): if i[0]=='g': id=reid.sub(r'\1', i) requests[id]="" elif i[0]=='b': requests[id]=requests[id]+i f.close() for pkg in self.marked4moving: for bid in pkg.build.keys(): if requests.has_key(bid) and not requests[bid].find('?') == -1: perror("Building of package %s (buildid %s) not finished" % (pkg,bid)) def __checkarchs(self, dsttree): def find_other_pkgs(pkg, tree): ziewre=re.compile(string.join(pkg.name.split('-')[:-2], '-')+'-[^-]*-[^-]*$') def filter_other_pkgs(x): if ziewre.match(x) and not x == pkg.name: return x else: return None return filter(filter_other_pkgs, tree.pkgnames) self.find_other_pkgs=find_other_pkgs for pkg in self.marked4moving: otherpkgnames=find_other_pkgs(pkg, dsttree) curarchs=[] missingarchs=[] for somepkg in otherpkgnames: curarchs.extend(Pkg(somepkg, dsttree).file.keys()) for arch in curarchs: if arch not in pkg.file.keys(): missingarchs.append(arch) if missingarchs: perror('Moving pkg %s would remove archs: %s' % (pkg, missingarchs)) def __rmolderfromsrc(self): def find_older_pkgs(pkg): def filter_older_pkgs(x): ziew=x.split('-') cur=pkg.name.split('-') if ziew[-2]