3 # Produces a report on NEW and BYHAND packages
4 # Copyright (C) 2001, 2002, 2003 James Troup <james@nocrew.org>
5 # $Id: helena,v 1.5 2003-07-15 17:29:26 troup Exp $
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 ################################################################################
23 # <o-o> XP runs GCC, XFREE86, SSH etc etc,.,, I feel almost like linux....
24 # <o-o> I am very confident that I can replicate any Linux application on XP
25 # <willy> o-o: *boggle*
26 # <o-o> building from source.
27 # <o-o> Viiru: I already run GIMP under XP
28 # <willy> o-o: why do you capitalise the names of all pieces of software?
29 # <o-o> willy: because I want the EMPHASIZE them....
31 # <willy> o-o: it makes you look like ZIPPY the PINHEAD
32 # <o-o> willy: no idea what you are talking about.
33 # <willy> o-o: do some research
34 # <o-o> willy: for what reason?
36 ################################################################################
38 import copy, glob, os, stat, sys, time;
45 ################################################################################
47 def usage(exit_code=0):
48 print """Usage: helena
49 Prints a report of packages in queue directories (usually new and byhand).
51 -h, --help show this help and exit."""
54 ################################################################################
62 ################################################################################
86 return "%s %s%s" % (x, unit, plural(x));
88 ################################################################################
90 def sg_compare (a, b):
93 """Sort by have note, time of oldest upload."""
95 a_note_state = a["note_state"];
96 b_note_state = b["note_state"];
97 if a_note_state < b_note_state:
99 elif a_note_state > b_note_state:
102 # Sort by time of oldest upload
103 return cmp(a["oldest"], b["oldest"]);
105 ############################################################
107 def process_changes_files(changes_files, type):
110 # Read in all the .changes files
111 for filename in changes_files:
113 Katie.pkg.changes_file = filename;
116 cache[filename] = copy.copy(Katie.pkg.changes);
117 cache[filename]["filename"] = filename;
120 # Divide the .changes into per-source groups
122 for filename in cache.keys():
123 source = cache[filename]["source"];
124 if not per_source.has_key(source):
125 per_source[source] = {};
126 per_source[source]["list"] = [];
127 per_source[source]["list"].append(cache[filename]);
128 # Determine oldest time and have note status for each source group
129 for source in per_source.keys():
130 source_list = per_source[source]["list"];
131 first = source_list[0];
132 oldest = os.stat(first["filename"])[stat.ST_CTIME];
134 for d in per_source[source]["list"]:
135 ctime = os.stat(d["filename"])[stat.ST_CTIME];
138 have_note += (d.has_key("lisa note"));
139 per_source[source]["oldest"] = oldest;
141 per_source[source]["note_state"] = 0; # none
142 elif have_note < len(source_list):
143 per_source[source]["note_state"] = 1; # some
145 per_source[source]["note_state"] = 2; # all
146 per_source_items = per_source.items();
147 per_source_items.sort(sg_compare);
153 for i in per_source_items:
154 last_modified = time.time()-i[1]["oldest"];
155 source = i[1]["list"][0]["source"];
156 if len(source) > max_source_len:
157 max_source_len = len(source);
160 for j in i[1]["list"]:
161 for arch in j["architecture"].keys():
163 version = j["version"];
164 versions[version] = "";
165 arches_list = arches.keys();
166 arches_list.sort(utils.arch_compare_sw);
167 arch_list = " ".join(arches_list);
168 version_list = " ".join(versions.keys());
169 if len(version_list) > max_version_len:
170 max_version_len = len(version_list);
171 if len(arch_list) > max_arch_len:
172 max_arch_len = len(arch_list);
173 if i[1]["note_state"]:
177 entries.append([source, version_list, arch_list, note, time_pp(last_modified)]);
179 format="%%-%ds | %%-%ds | %%-%ds%%s | %%s old\n" % (max_source_len, max_version_len, max_arch_len)
181 for entry in entries:
182 (source, version_list, arch_list, note, last_modified) = entry;
183 msg += format % (source, version_list, arch_list, note, last_modified);
186 total_count = len(changes_files);
187 source_count = len(per_source_items);
192 print "%s %s source package%s / %s %s package%s in total." % (source_count, type, plural(source_count), total_count, type, plural(total_count));
195 ################################################################################
200 Cnf = utils.get_conf();
201 Arguments = [('h',"help","Helena::Options::Help")];
203 if not Cnf.has_key("Helena::Options::%s" % (i)):
204 Cnf["Helena::Options::%s" % (i)] = "";
206 apt_pkg.ParseCommandLine(Cnf, Arguments, sys.argv);
208 Options = Cnf.SubTree("Helena::Options")
212 Katie = katie.Katie(Cnf);
214 directories = Cnf.ValueList("Helena::Directories");
216 directories = [ "byhand", "new" ];
218 for directory in directories:
219 changes_files = glob.glob("%s/*.changes" % (Cnf["Dir::Queue::%s" % (directory)]));
220 process_changes_files(changes_files, directory);
222 ################################################################################
224 if __name__ == '__main__':