]> git.decadent.org.uk Git - dak.git/blob - shania
auric implementation
[dak.git] / shania
1 #!/usr/bin/env python
2
3 # Clean incoming of old unused files
4 # Copyright (C) 2000  James Troup <james@nocrew.org>
5 # $Id: shania,v 1.1 2000-12-13 03:18:50 troup Exp $
6
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.
11
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.
16
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
20
21 # Caveat Emptor: If run with -m/--mail argument, expects to be in
22 # Incoming/REJECT or somewhere with .reason files.
23
24 ################################################################################
25
26 import os, re, stat, string, sys, time
27 import utils
28 import apt_pkg;
29
30 ################################################################################
31
32 re_ischanges = re.compile(r"\.changes$")
33 re_isdsc = re.compile(r"\.dsc$")
34
35 ################################################################################
36
37 def file_to_string (filename):
38     try:
39         file = utils.open_file(filename, 'r');
40     except utils.cant_open_exc:
41         return "";
42
43     contents = "";
44     for line in file.readlines():
45         contents = contents + line;
46     return contents;
47
48 ################################################################################
49
50 def main ():
51     Cnf = None;
52     all_files = {};
53     changes_files = [];
54
55     apt_pkg.init();
56     
57     Cnf = apt_pkg.newConfiguration();
58     apt_pkg.ReadConfigFileISC(Cnf,utils.which_conf_file());
59
60     Arguments = [('D',"debug","Shania::Options::Debug", "IntVal"),
61                  ('h',"help","Shania::Options::Help"),
62                  ('V',"version","Shania::Options::Version"),
63                  ('d',"days","Shania::Options::Days", "IntVal"),
64                  ('i',"incoming","Shania::Options::Incoming", "HasArg"),
65                  ('m',"mail","Shania::Options::Mail"),
66                  ('n',"no-action","Shania::Options::No-Action"),
67                  ('v',"verbose","Shania::Options::Verbose")];
68
69     apt_pkg.ParseCommandLine(Cnf,Arguments,sys.argv);
70
71     delete_date = int(time.time())-(int(Cnf["Shania::Options::Days"])*84600);
72     del_dir = Cnf["Dir::Morgue"] + '/' + Cnf["Shania::MorgueSubDir"];
73
74     if not os.path.exists(del_dir):
75         sys.stderr.write("W: Creating morgue directory '%s'.\n" % (del_dir));
76         os.mkdir(del_dir);
77     elif not os.path.isdir(del_dir):
78         sys.stderr.write("E: %s must be a directory.\n" % (del_dir));
79
80     incoming = Cnf["Shania::Options::Incoming"];
81     if incoming == "":
82         incoming = Cnf["Dir::IncomingDir"];
83
84     os.chdir(incoming);
85
86     # Build up the list of all files in the directory
87     for i in os.listdir('.'):
88         if os.path.isfile(i):
89             all_files[i] = 1;
90             if re_ischanges.search(i) != None:
91                 changes_files.append(i);
92
93     # Proces all .changes and .dsc files.
94     for changes_filename in changes_files:
95         try:
96             changes = utils.parse_changes(changes_filename)
97         except:
98             continue;
99         try:
100             files = utils.build_file_list(changes, "");
101         except:
102             continue;
103
104         dsc_files = {};
105         for file in files.keys():
106             if re_isdsc.search(file) != None:
107                 try:
108                     dsc = utils.parse_changes(file)
109                 except:
110                     continue;
111                 try:
112                     dsc_files = utils.build_file_list(dsc, 1)
113                 except:
114                     continue;
115
116         # If passed -m/--mail, assume in REJECT/ and send appropriate mails
117         if Cnf["Shania::Options::Mail"]:
118             reason_filename = re_ischanges.sub('.reason', changes_filename);
119             if not os.access(reason_filename, os.R_OK):
120                 sys.stderr.write("W: %s lacks a (readable) reason file ('%s').\n" % (changes_filename, reason_filename));
121                 continue;
122             
123             if os.stat(reason_filename)[stat.ST_MTIME] > delete_date:
124                 # Ensure the files aren't later deleted.
125                 for keys in (files.keys(), dsc_files.keys(), changes_filename, reason_filename):
126                     for i in keys:
127                         if all_files.has_key(i):
128                             del all_files[i];
129             
130                 # Grab a copy of the .changes and .reason files for inclusion in the mail
131                 try:
132                     changes_contents = file_to_string(changes_filename);
133                 except utils.cant_open_exc:
134                     sys.stderr.write("W: %s lacks a (readable) changes file ('%s').\n" % (changes_filename, changes_filename));
135                     continue;
136
137                 reason_contents = file_to_string(reason_filename);
138
139                 # Fix the maintainer address to be RFC-822 compatible
140                 (changes["maintainer822"], changes["maintainername"], changes["maintaineremail"]) = utils.fix_maintainer (changes["maintainer"])
141
142                 if Cnf["Shania::Options::No-Action"]:
143                     print "Would send a reminder email to %s." % (changes["maintainer822"]);
144                 else: # FIXME: need msg to be configurable
145                     mail_message = """Return-Path: %s
146 From: %s
147 To: %s
148 Bcc: troup@auric.debian.org
149 Subject: Reminder: %s was rejected
150
151 This is an automated reminder.  Your Debian upload was rejected.  Its
152 files are in %s/REJECT on %s.
153
154 If the upload has been superceded, please delete it.  If not, please
155 correct the error.  You do not have to reupload good files; simply
156 move them from incoming/REJECT to incoming.  Do erase any bad files.
157 This reminder is sent on Monday mornings.  After two reminders, the
158 upload is deleted.
159
160 ----------------------------------------------------------------------
161 %s
162 ----------------------------------------------------------------------
163
164 ----------------------------------------------------------------------
165 %s
166 ----------------------------------------------------------------------
167
168 --
169 Debian distribution maintenance software
170 """ % (Cnf["Dinstall::MyEmailAddress"], Cnf["Dinstall::MyEmailAddress"], changes["maintainer822"], changes_filename, Cnf["Dir::IncomingDir"], Cnf["Archive::%s::OriginServer" % (utils.where_am_i())], changes_contents, reason_contents)
171                     utils.send_mail(mail_message, "");
172                     if Cnf["Shania::Options::Verbose"]:
173                         print "Sent reminder email to %s." % (changes["maintainer822"]);
174         else:
175             # Ensure the files aren't deleted
176             for keys in (files.keys(), dsc_files.keys(), changes_filename):
177                 for i in keys:
178                     if all_files.has_key(i):
179                         del all_files[i];
180
181     # Anthing left at this stage is not referenced by a .changes or
182     # .dsc and should be deleted if old enough.
183     for file in all_files.keys():
184         if os.stat(file)[stat.ST_MTIME] < delete_date:
185             if Cnf["Shania::Options::No-Action"]:
186                 print "Would delete '%s'." % (os.path.basename(file));
187             else:
188                 if Cnf["Shania::Options::Verbose"]:
189                     print "Removing '%s' (to '%s')."  % (os.path.basename(file), del_dir);
190                 utils.move(file, del_dir);
191         else:
192             if Cnf["Shania::Options::Verbose"]:
193                 print "Skipping, too new, '%s'." % (os.path.basename(file));
194
195 #######################################################################################
196
197 if __name__ == '__main__':
198     main()