3 # rhona, cleans up unassociated binary (and source) packages
4 # Copyright (C) 2000 James Troup <james@nocrew.org>
5 # $Id: rhona,v 1.2 2000-11-24 04:04:23 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 # 07:05|<elmo> well.. *shrug*.. no, probably not.. but to fix it,
22 # | we're going to have to implement reference counting
23 # | through dependencies.. do we really want to go down
26 # 07:05|<Culus> elmo: Augh! <brain jumps out of skull>
28 import pg, string, os, sys, time
36 # A nicer way to do this would be `SELECT bin FROM
37 # bin_associations EXCEPT SELECT id from binaries WHERE
38 # last_update IS NULL', but it seems postgresql can't handle that
39 # query as it hadn't return after I left it running for 20 minutes
43 q = projectB.query("SELECT bin FROM bin_associations");
46 linked_binaries[i[0]] = "";
49 q = projectB.query("SELECT b.id, b.file FROM binaries b, files f WHERE f.last_used IS NULL AND f.id = b.file")
52 all_binaries[i[0]] = i[1];
54 projectB.query("BEGIN WORK");
55 for id in all_binaries.keys():
56 if not linked_binaries.has_key(id):
57 date = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time()-(4*(24*60*60))))
58 projectB.query("UPDATE files SET last_used = '%s' WHERE id = %s" % (date, all_binaries[id]))
59 projectB.query("COMMIT WORK");
61 # Check for any binaries which are marked for eventual deletion but are now used again.
63 all_marked_binaries = {};
64 q = projectB.query("SELECT b.id, b.file FROM binaries b, files f WHERE f.last_used IS NOT NULL AND f.id = b.file")
67 all_marked_binaries[i[0]] = i[1];
68 projectB.query("BEGIN WORK");
69 for id in all_marked_binaries.keys():
70 if linked_binaries.has_key(id):
71 # Can't imagine why this would happen, so warn about it for now.
72 print "W: %s has released %s from the target list." % (id, all_marked_binaries[id]);
73 projectB.query("UPDATE files SET last_used = NULL WHERE id = %s" % (all_marked_binaries[id]));
74 projectB.query("COMMIT WORK");
77 # A nicer way to do this would be using `EXCEPT', but see the
78 # commeint in process_binary.
81 q = projectB.query("SELECT source FROM binaries WHERE source is not null");
84 linked_sources[i[0]] = "";
87 q = projectB.query("SELECT s.id, s.file FROM source s, files f WHERE f.last_used IS NULL AND f.id = s.file")
90 all_sources[i[0]] = i[1];
92 projectB.query("BEGIN WORK");
93 for id in all_sources.keys():
94 if not linked_sources.has_key(id):
95 date = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time()-(4*(24*60*60))))
96 projectB.query("UPDATE files SET last_used = '%s' WHERE id = %s" % (date, all_sources[id]))
97 # Delete all other files references by .dsc too if they're not used by anyone else
98 q = projectB.query("SELECT f.id FROM files f, dsc_files d WHERE d.source = %d AND d.file = f.id" % (id));
101 q_others = projectB.query("SELECT file FROM dsc_files d WHERE file = %s" % (i[0]));
102 ql_others = q.getresult();
104 projectB.query("UPDATE files SET last_used = '%s' WHERE id = %s" % (date, i[0]));
105 projectB.query("COMMIT WORK");
107 # Check for any sources which are marked for eventual deletion but are now used again.
108 all_marked_sources = {};
109 q = projectB.query("SELECT s.id, s.file FROM source s, files f WHERE f.last_used IS NOT NULL AND f.id = s.file");
112 all_marked_sources[i[0]] = i[1];
113 projectB.query("BEGIN WORK");
114 for id in all_marked_sources.keys():
115 if linked_sources.has_key(id):
116 # Can't imagine why this would happen, so warn about it for now.
117 print "W: %s has released %s from the target list." % (id, all_marked_sources[id]);
118 projectB.query("UPDATE files SET last_used = NULL WHERE id = %s" % (all_marked_sources[id]));
119 # Unmark all other files references by .dsc too
120 q = projectB.query("SELECT file FROM dsc_files WHERE source = %d" % (id));
123 projectB.query("UPDATE files SET last_used = NULL WHERE id = %s" % (i[0]));
124 projectB.query("COMMIT WORK");
126 # Whee, check for any source files (i.e. non .dsc) which are
127 # marked for eventual deletion but are now used by a source
129 all_marked_dsc_files = {}
130 q = projectB.query("SELECT s.id, s.file FROM source s, files f, dsc_files d WHERE f.last_used IS NOT NULL AND f.id = d.file AND d.source = s.id");
133 all_marked_dsc_files[i[0]] = i[1];
134 projectB.query("BEGIN WORK");
135 for id in all_marked_dsc_files.keys():
136 if linked_sources.has_key(id):
137 # Can't imagine why this would happen, so warn about it for now.
138 print "W: %s has released %s from the target list." % (id, all_marked_sources[id]);
139 projectB.query("UPDATE files SET last_used = NULL WHERE id = %s" % (all_marked_sources[id]));
140 # Unmark all other files references by .dsc too
141 q = projectB.query("SELECT file FROM dsc_files WHERE source = %d" % (id));
144 projectB.query("UPDATE files SET last_used = NULL WHERE id = %s" % (i[0]));
145 projectB.query("COMMIT WORK");
148 date = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time()-int(Cnf["Rhona::StayOfExecution"])));
149 q = projectB.query("SELECT l.path, f.filename FROM location l, files f WHERE f.last_used < '%s' AND l.id = f.location" % (date))
152 filename = i[0] + i[1];
153 dest = Cnf["Rhona::Morgue"]+os.path.basename(filename);
154 if not os.path.exists(filename):
155 sys.stderr.write("E: can not find %s.\n" % (filename));
157 print "Cleaning %s to %s..." % (filename, dest)
158 #utils.move(filename, dest);
159 #projectB.query("DELETE FROM binaries WHERE id = %s" % (i[0]));
160 #FIXME: need to remove from "or source" + files + dsc_files.. etc.
163 global Cnf, projectB;
165 projectB = pg.connect('projectb', 'localhost');
169 Cnf = apt_pkg.newConfiguration();
170 apt_pkg.ReadConfigFileISC(Cnf,utils.which_conf_file());
172 print "Checking for orphaned binary packages..."
174 print "Checking for orphaned source packages..."
176 print "Cleaning orphaned packages..."
179 if __name__ == '__main__':