3 # rhona, cleans up unassociated binary (and source) packages
4 # Copyright (C) 2000 James Troup <james@nocrew.org>
5 # $Id: rhona,v 1.3 2000-12-13 03:18:50 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");
147 def clean_binaries():
148 date = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time()-int(Cnf["Rhona::StayOfExecution"])));
149 print projectB.query("DELETE FROM binaries WHERE file IN (SELECT id FROM files WHERE last_used < '%s')" % (date));
152 date = time.strftime("%Y-%m-%d %H:%M", time.localtime(time.time()-int(Cnf["Rhona::StayOfExecution"])));
153 # Delete from source + dsc_files
154 q = projectB.query("SELECT l.path, f.filename FROM location l, files f WHERE f.last_used < '%s' AND l.id = f.location" % (date));
155 for i in q.getresult():
156 filename = i[0] + i[1];
157 if not os.path.exists(filename):
158 sys.stderr.write("E: can not find %s.\n" % (filename));
160 dest = Cnf["Dir::Morgue"] + '/' + Cnf["Rhona::MorgueSubDir"];
161 print "Cleaning %s to %s..." % (filename, dest);
162 #utils.move(filename, dest);
166 global Cnf, projectB;
168 projectB = pg.connect('projectb', 'localhost');
172 Cnf = apt_pkg.newConfiguration();
173 apt_pkg.ReadConfigFileISC(Cnf,utils.which_conf_file());
175 print "Checking for orphaned binary packages..."
177 print "Cleaning binaries from the DB..."
179 print "Checking for orphaned source packages..."
181 print "Cleaning orphaned packages..."
184 if __name__ == '__main__':