#!/usr/bin/env python # Produces a report on NEW and BYHAND packages # Copyright (C) 2001, 2002, 2003 James Troup # $Id: helena,v 1.5 2003-07-15 17:29:26 troup Exp $ # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ################################################################################ # XP runs GCC, XFREE86, SSH etc etc,.,, I feel almost like linux.... # I am very confident that I can replicate any Linux application on XP # o-o: *boggle* # building from source. # Viiru: I already run GIMP under XP # o-o: why do you capitalise the names of all pieces of software? # willy: because I want the EMPHASIZE them.... # grr s/the/to/ # o-o: it makes you look like ZIPPY the PINHEAD # willy: no idea what you are talking about. # o-o: do some research # willy: for what reason? ################################################################################ import copy, glob, os, stat, sys, time; import apt_pkg; import katie, utils; Cnf = None; Katie = None; ################################################################################ def usage(exit_code=0): print """Usage: helena Prints a report of packages in queue directories (usually new and byhand). -h, --help show this help and exit.""" sys.exit(exit_code) ################################################################################ def plural(x): if x > 1: return "s"; else: return ""; ################################################################################ def time_pp(x): if x < 60: unit="second"; elif x < 3600: x /= 60; unit="minute"; elif x < 86400: x /= 3600; unit="hour"; elif x < 604800: x /= 86400; unit="day"; elif x < 2419200: x /= 604800; unit="week"; elif x < 29030400: x /= 2419200; unit="month"; else: x /= 29030400; unit="year"; x = int(x); return "%s %s%s" % (x, unit, plural(x)); ################################################################################ def sg_compare (a, b): a = a[1]; b = b[1]; """Sort by have note, time of oldest upload.""" # Sort by have note a_note_state = a["note_state"]; b_note_state = b["note_state"]; if a_note_state < b_note_state: return -1; elif a_note_state > b_note_state: return 1; # Sort by time of oldest upload return cmp(a["oldest"], b["oldest"]); ############################################################ def process_changes_files(changes_files, type): msg = ""; cache = {}; # Read in all the .changes files for filename in changes_files: try: Katie.pkg.changes_file = filename; Katie.init_vars(); Katie.update_vars(); cache[filename] = copy.copy(Katie.pkg.changes); cache[filename]["filename"] = filename; except: break; # Divide the .changes into per-source groups per_source = {}; for filename in cache.keys(): source = cache[filename]["source"]; if not per_source.has_key(source): per_source[source] = {}; per_source[source]["list"] = []; per_source[source]["list"].append(cache[filename]); # Determine oldest time and have note status for each source group for source in per_source.keys(): source_list = per_source[source]["list"]; first = source_list[0]; oldest = os.stat(first["filename"])[stat.ST_CTIME]; have_note = 0; for d in per_source[source]["list"]: ctime = os.stat(d["filename"])[stat.ST_CTIME]; if ctime < oldest: oldest = ctime; have_note += (d.has_key("lisa note")); per_source[source]["oldest"] = oldest; if not have_note: per_source[source]["note_state"] = 0; # none elif have_note < len(source_list): per_source[source]["note_state"] = 1; # some else: per_source[source]["note_state"] = 2; # all per_source_items = per_source.items(); per_source_items.sort(sg_compare); entries = []; max_source_len = 0; max_version_len = 0; max_arch_len = 0; for i in per_source_items: last_modified = time.time()-i[1]["oldest"]; source = i[1]["list"][0]["source"]; if len(source) > max_source_len: max_source_len = len(source); arches = {}; versions = {}; for j in i[1]["list"]: for arch in j["architecture"].keys(): arches[arch] = ""; version = j["version"]; versions[version] = ""; arches_list = arches.keys(); arches_list.sort(utils.arch_compare_sw); arch_list = " ".join(arches_list); version_list = " ".join(versions.keys()); if len(version_list) > max_version_len: max_version_len = len(version_list); if len(arch_list) > max_arch_len: max_arch_len = len(arch_list); if i[1]["note_state"]: note = " | [N]"; else: note = ""; entries.append([source, version_list, arch_list, note, time_pp(last_modified)]); format="%%-%ds | %%-%ds | %%-%ds%%s | %%s old\n" % (max_source_len, max_version_len, max_arch_len) msg = ""; for entry in entries: (source, version_list, arch_list, note, last_modified) = entry; msg += format % (source, version_list, arch_list, note, last_modified); if msg: total_count = len(changes_files); source_count = len(per_source_items); print type.upper(); print "-"*len(type); print print msg; print "%s %s source package%s / %s %s package%s in total." % (source_count, type, plural(source_count), total_count, type, plural(total_count)); print ################################################################################ def main(): global Cnf, Katie; Cnf = utils.get_conf(); Arguments = [('h',"help","Helena::Options::Help")]; for i in [ "help" ]: if not Cnf.has_key("Helena::Options::%s" % (i)): Cnf["Helena::Options::%s" % (i)] = ""; apt_pkg.ParseCommandLine(Cnf, Arguments, sys.argv); Options = Cnf.SubTree("Helena::Options") if Options["Help"]: usage(); Katie = katie.Katie(Cnf); directories = Cnf.ValueList("Helena::Directories"); if not directories: directories = [ "byhand", "new" ]; for directory in directories: changes_files = glob.glob("%s/*.changes" % (Cnf["Dir::Queue::%s" % (directory)])); process_changes_files(changes_files, directory); ################################################################################ if __name__ == '__main__': main();