#!/usr/bin/python """Check the origin of all packages""" # LICENSE FOR this file # ================================ # This notice is a simplified BSD license. # Copyright 2010 Jean-Christophe Dubacq. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # THIS SOFTWARE IS PROVIDED BY JEAN-CHRISTOPHE DUBACQ ``AS IS'' AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JEAN-CHRISTOPHE DUBACQ OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import getopt,sys import apt_pkg import apt.progress.text import os shortoptions=["h","l","c","t","C:","L:","o:"] longoptions=["help", "list","count","tabular","columns=","lines=","order="] argstype=['','','','','integer','integer','string'] explanation=['This help text', 'Just list available distributions', 'Just display package count by origin', 'Use tabular output format for origin display', 'Set the number of columns of the output', 'Set the maximal number of packages that can be displayed', 'Set the order in which packages are in the distributions.\n This is a space-jointed string of stanzas like alias1=site1/archive1\n where alias1 is the display name of a distribution of name archive1\n at site1. "none" will purge the preceding sources.' ] def usage(): print "package_origins [options]" for k in range(len(longoptions)): if k1: xsources.append(line.rstrip('\n')) f.close() except IOError: True for o,a in opts: if o in ("-h","--help"): usage() sys.exit() elif o in ("-l","--list"): justlist=True elif o in ("-c","--count"): justcount=True elif o in ("-t","--total"): optiontabular=True elif o in ("-L","--lines"): xlimit=int(a) elif o in ("-C","--columns"): cols=int(a) elif o in ("-o","--order"): if (a=='none'): xsources=[] else: xsources.extend(a.split(' ')) else: assert False, "unhandled option" apt_pkg.init_system() f = open('/dev/null', 'w') cache=apt_pkg.Cache(apt.progress.text.OpProgress(f)) f.close() origin={} best={} xsources.append('other=other') xsources.append('installed=/now') out=len(xsources) count=[] packages=[] sources=[] naming={} for i in range(out): count.append(0) packages.append([]) sources.append(0) for v in xsources: k=xsources.index(v) if v.find('='): a,b,c=v.partition('=') else: c=v a=v sources[k]=c naming[c]=a for pkg in sorted(cache.packages, key=lambda pkg: pkg.name): version=pkg.current_ver if version != None and pkg.current_state == apt_pkg.CURSTATE_INSTALLED: for pfile,_ in version.file_list: cpt=pfile.site+'/'+pfile.archive # print pkg.name+':'+cpt if not(cpt in naming): naming[cpt]=cpt if cpt in sources: where=sources.index(cpt) else: where=out-2 if pkg.name in best: if best[pkg.name]>where: best[pkg.name]=where else: best[pkg.name]=where if justlist: print "#other and installed are always added by this program" print "#other: downloadable packages from unnamed repositories" print "#installed: packages installed but not downloadable" for s in sorted(naming.keys(), key=lambda x: naming[x]): if naming[s]!='installed' and naming[s]!='other': print naming[s]+'='+s sys.exit() for s in best.keys(): count[best[s]]=1+count[best[s]] packages[best[s]].append(s) if justcount: for k in sources: kk=sources.index(k) if count[kk]>0: print '%s:%d' % (naming[k],count[kk]) sys.exit() else: if optiontabular: for k in sources: kk=sources.index(k) for u in sorted(packages[kk]): print k+':'+u else: for k in sources: new='' kk=sources.index(k) if len(packages[kk])>0: print ','+("-" * (cols-2))+'.' print '|'+naming[k].center(cols-2)+'|' print '`'+("-" * (cols-2))+'\'' if len(packages[kk])<=xlimit: for u in sorted(packages[kk]): if len(new)+len(u)<=cols: if new!='': new=new+' '+u else: new=u else: print new new=u if len(new)>0: print new else: print 'Too many packages (%d). Use --tabular or --lines=X (x>=%d).' % (len(packages[kk]),len(packages[kk])) if __name__ == '__main__': main()