/[qa]/trunk/mia/status.py
ViewVC logotype

Contents of /trunk/mia/status.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 182 - (hide annotations) (download) (as text)
Mon May 7 18:05:25 2001 UTC (12 years ago) by tbm
File MIME type: text/x-python
File size: 6159 byte(s)
Happy Birthday, baby.  I will always love you, I fear.
1 tbm 161 # The module which forms the heart of the MIA scripts
2 tbm 5 # Copyright (C) 2001 Martin Michlmayr <tbm@cyrius.com>
3 tbm 21 # $Id$
4 tbm 5
5     # This program is free software; you can redistribute it and/or modify
6     # it under the terms of the GNU General Public License as published by
7     # the Free Software Foundation; either version 2 of the License, or
8     # (at your option) any later version.
9    
10     # This program is distributed in the hope that it will be useful,
11     # but WITHOUT ANY WARRANTY; without even the implied warranty of
12     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     # GNU General Public License for more details.
14    
15     # You should have received a copy of the GNU General Public License
16     # along with this program; if not, write to the Free Software
17     # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18    
19    
20     # This is a collection of software to track down developers who are
21     # Missing In Action (MIA).
22    
23     # To Veronika, who is missing in action -- action's not the same without her.
24     # -- tbm
25    
26 tbm 182 # Ex-Factor, by Lauryn Hill
27     #
28     # (Verse 1)
29     # It could all be so simple
30     # But you'd rather make it hard
31     # Loving you is like a battle
32     # And we both end up with scars
33     # Tell me who I have to be
34     # To get some reprocity
35     # No one loves you more than me
36     # And no one ever will
37     #
38     # (Verse 2)
39     # Is this just a silly game
40     # That forces you to act this way
41     # Forces you to scream my name
42     # Then pretend that you can't stay
43     # Tell me who I have to be
44     # To get some reprocity
45     # No one loves you more than me
46     # And no one ever will
47     #
48     # (Chorus)
49     # No matter how I think we grow
50     # You always seem to let me know
51     # It ain't working, it ain't working
52     # And when I try to walk away
53     # You'd hurt yourself to make me stay
54     # This is crazy, this is crazy
55     #
56     # (Verse 3)
57     # I keep letting you back in
58     # How can I explain myself
59     # As painful as this thing has been
60     # I just can't be with no one else
61     # See I know what we got to do
62     # You let go and I'll let go too
63     # 'Cause no one hurt me more than you
64     # And no one ever will
65     #
66     # (Repeat Chorus)
67     # Care for me, care for me
68     # I know you care for me
69     #
70     # There for me, there for me
71     # Said you'd be there for me
72     #
73     # Cry for me, cry for me
74     # You said you'd die for me
75     #
76     # Give to me, give to me
77     # Why won't you live for me
78     # (Repeat)
79     #
80 tbm 5
81 tbm 134 import os, stat, sys, re, time, string
82 tbm 5
83     days = 21
84     origin = '/org/qa.debian.org/mia/db'
85    
86     info = { }
87 tbm 154 matches = { }
88 tbm 5
89     def find_status(path=origin):
90     files = []
91    
92 tbm 164 try:
93     for file in os.listdir(path):
94     root, ext = os.path.splitext(file)
95     if ext == '.summary':
96     files.append(root)
97     except OSError:
98     print 'Cannot find directory of database: %s' % path
99     sys.exit(1)
100 tbm 5
101     return files
102    
103 tbm 150
104 tbm 5 def read_status(files):
105     for file in files:
106     try:
107     summary = open(origin + '/' + file + '.summary', 'r')
108     except IOError:
109     print 'Cannot open summary file %s' % file
110     sys.exit(1)
111    
112     info[file] = { }
113    
114     for line in summary.readlines():
115     result = re.search("(\d+):\s*(.*)", line)
116    
117     if result is not None:
118 tbm 155 info[file][int(result.group(1))] = result.group(2)
119 tbm 5 else:
120     print 'Error parsing file %s: %s' % (file, line)
121     sys.exit(1)
122    
123     summary.close()
124    
125    
126     def write_status(file, id, summary):
127     try:
128     status = open(origin + '/' + file + '.summary', 'a')
129     except IOError:
130     print 'Cannot open summary file to write!'
131     sys.exit(1)
132    
133 tbm 12 string = str(id) + ': ' + summary + '\n'
134 tbm 5 status.write(string)
135     status.close()
136    
137 tbm 150
138 tbm 158 def get_all_files():
139 tbm 159 files = info.keys()
140 tbm 158 files.sort()
141     return files
142    
143    
144 tbm 166 def get_selected_files(pattern):
145     files = get_all_files()
146     selection = [ ]
147     cpattern = re.compile(pattern, re.I)
148     for file in files:
149     if grep_items(file, cpattern):
150     selection.append(file)
151     return selection
152    
153    
154     def grep_items(file, cpattern):
155     for item in info[file].values():
156     if cpattern.search(item):
157     return 1
158    
159    
160 tbm 5 def print_history(file):
161     all_contacts = info[file].keys()
162     all_contacts.sort()
163     for when in all_contacts:
164     date = time.gmtime(int(when))
165     print ' %s: %.60s' % (time.strftime('%Y-%m-%d', date), info[file][when])
166    
167 tbm 134
168     def latest(file):
169 tbm 155 return max(info[file].keys())
170 tbm 134
171    
172 tbm 162 def should_check(file, ttl=days):
173     if (time.time() - latest(file)) > (ttl * 3600 * 24):
174 tbm 160 return 1
175    
176    
177 tbm 150 def compile_matches():
178 tbm 134 matches['ignore'] = [ 'willfix' ]
179 tbm 143 matches['in'] = [ 'S-V', 'FHS', 'RC', 'NMU', 'Hint' ]
180     matches['out'] = [ 'Fixed', 'Orphaned', 'Orphaning', 'Removed',
181     'Removing' ]
182 tbm 147 matches['latest'] = [ 'Maintainer has no packages anymore', 'Retired',
183     'Retiring' ]
184 tbm 134
185     for key in matches.keys():
186     matches[key] = map(string.lower, matches[key])
187    
188 tbm 150
189     def last_is_final(file):
190 tbm 155 if string.lower(info[file][latest(file)]) in matches['latest']:
191 tbm 150 return 1
192    
193    
194     def has_stuff_todo(file):
195     if last_is_final(file):
196 tbm 134 return
197    
198 tbm 154 found = { }
199     for key in matches.keys():
200     found[key] = { }
201    
202 tbm 134 for entry in info[file].values():
203     fields = re.split(':\s+', entry, 2)
204     if len(fields) > 1:
205 tbm 136 what = re.split('\s+|&', fields[0])[0]
206 tbm 171 packages = re.split(',\s*', string.lower(fields[1]))
207 tbm 134 for key in matches.keys():
208     if string.lower(what) in matches[key]:
209 tbm 148 for package in packages:
210     found[key][package] = 1
211 tbm 144 break
212 tbm 134 else:
213     print 'Error: do not know what to do with "%s"' % what
214     sys.exit(1)
215    
216 tbm 135 # temporary hack to show cases without any INs.
217 tbm 165 if not found['in']:
218 tbm 135 return [ 'no-todo-list' ]
219    
220 tbm 148 for item in found['out'].keys():
221 tbm 134 try:
222 tbm 148 del found['in'][item]
223     except KeyError:
224 tbm 134 print 'Warning: "%s" was not on the TODO list' % item
225    
226 tbm 165 if found['in']:
227 tbm 134 # something has not been dealt with yet
228 tbm 149 outstanding = found['in'].keys()
229     outstanding.sort()
230     return outstanding
231 tbm 134
232 tbm 151
233     # 'main()'
234    
235 tbm 153 compile_matches()
236 tbm 151

Properties

Name Value
svn:eol-style native
svn:executable *
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.5