/[collab-qa]/udd/web/bapase.cgi
ViewVC logotype

Contents of /udd/web/bapase.cgi

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1921 - (show annotations) (download)
Sat Mar 26 07:04:44 2011 UTC (2 years, 1 month ago) by lucas
File size: 11874 byte(s)
bapase: display last modification
1 #!/usr/bin/ruby -w
2 require 'dbi'
3 require 'cgi'
4
5 tstart = Time::now
6
7 class Actions
8 attr_reader :actions, :act_todo, :act_status, :act_comment
9 def initialize
10 @actions = []
11 @act_status = ""
12 @act_todo = false
13 @act_comment = ""
14 end
15
16 def add(desc)
17 desc.chomp!
18 date, who, act, comment = desc.split(' ', 4)
19 date = Date::parse(date)
20 if act =~ /^(.+)\((.+)\)$/
21 act_name, act_arg = $1, $2
22 if [ 'PROP_RM', 'PROP_RM_O', 'PROP_O', 'O', 'REQ_RM', 'RM', 'SEC_RM', 'O_PROP_RM' ].include?(act_name)
23 # FIXME check bug
24 elsif act_name == 'WAIT'
25 act_arg = act_arg.to_i
26 else
27 puts "Unknown action: #{act} (#{desc})"
28 end
29 @actions << [date, who, [act_name, act_arg], comment]
30 elsif act == 'OK'
31 act_name = 'OK'
32 act_arg = nil
33 @actions << [date, who, [act_name, act_arg], comment]
34 else
35 puts "Unparseable action: #{act} (#{desc})"
36 exit(1)
37 end
38 end
39
40 def analyze_actions
41 @actions.sort! { |a,b| b[0] <=> a[0] }
42 idx = 0
43 rm_o = false
44 while idx < @actions.length
45 if @actions[idx][2][0] == 'OK'
46 @act_status = ""
47 @act_comment = @actions[idx][3] if not @actions[idx][3].nil?
48 break
49 elsif @actions[idx][2][0] == 'WAIT'
50 if @actions[idx][0] + @actions[idx][2][1] <= CURDATE
51 idx += 1
52 next # OK not valid anymore, consider next action
53 else
54 # nothing to do except waiting
55 @act_status = "Waiting until #{@actions[idx][0] + @actions[idx][2][1]}"
56 @act_comment = @actions[idx][3] if not @actions[idx][3].nil?
57 break
58 end
59 elsif @actions[idx][2][0] == 'REQ_RM' or @actions[idx][2][0] == 'RM'
60 @act_status = "<a href=\"http://bugs.debian.org/#{@actions[idx][2][1]}\">Removal was requested</a>"
61 @act_comment = @actions[idx][3] if not @actions[idx][3].nil?
62 break
63 elsif @actions[idx][2][0] == 'O'
64 @act_status = "<a href=\"http://bugs.debian.org/#{@actions[idx][2][1]}\">Was orphaned</a>"
65 @act_comment = @actions[idx][3] if not @actions[idx][3].nil?
66 break
67 elsif @actions[idx][2][0] == 'PROP_RM_O'
68 @act_status = "<a href=\"http://bugs.debian.org/#{@actions[idx][2][1]}\">Was orphaned, will need removal</a>"
69 rm_o = true
70 idx += 1
71 @act_comment = @actions[idx][3] if not @actions[idx][3].nil?
72 next
73 elsif @actions[idx][2][0] == 'PROP_RM'
74 ok = false
75 if @actions[idx][0] + WAIT_RM_O <= CURDATE and !rm_o
76 @act_status = "<a href=\"http://bugs.debian.org/#{@actions[idx][2][1]}\">Should be orphaned before removal (since #{@actions[idx][0] + 50})</a>"
77 @act_todo = true
78 ok = true
79 end
80 if @actions[idx][0] + WAIT_RM_RM <= CURDATE
81 @act_status = "<a href=\"http://bugs.debian.org/#{@actions[idx][2][1]}\">Should be removed (since #{@actions[idx][0] + 100})</a>"
82 @act_todo = true
83 ok = true
84 end
85 if !ok
86 @act_status = "<a href=\"http://bugs.debian.org/#{@actions[idx][2][1]}\">Removal suggested (since #{@actions[idx][0]})</a>"
87 end
88 @act_comment = @actions[idx][3] if not @actions[idx][3].nil?
89 break
90 elsif @actions[idx][2][0] == 'PROP_O'
91 if @actions[idx][0] + WAIT_O_O <= CURDATE
92 @act_status = "<a href=\"http://bugs.debian.org/#{@actions[idx][2][1]}\">Should be orphaned (since #{@actions[idx][0] + 50})</a>"
93 @act_todo = true
94 else
95 @act_status = "<a href=\"http://bugs.debian.org/#{@actions[idx][2][1]}\">Orphaning suggested (since #{@actions[idx][0]})</a>"
96 end
97 @act_comment = @actions[idx][3] if not @actions[idx][3].nil?
98 break
99 elsif @actions[idx][2][0] == 'O_PROP_RM'
100 if @actions[idx][0] + WAIT_ORM_RM <= CURDATE
101 @act_status = "<a href=\"http://bugs.debian.org/#{@actions[idx][2][1]}\">Should be removed (O pkg) (since #{@actions[idx][0] + 50})</a>"
102 @act_todo = true
103 else
104 @act_status = "<a href=\"http://bugs.debian.org/#{@actions[idx][2][1]}\">Removal suggested (O pkg) (since #{@actions[idx][0]})</a>"
105 end
106 @act_comment = @actions[idx][3] if not @actions[idx][3].nil?
107 break
108 else
109 puts "Unknown act: #{@actions[idx][2][0]}"
110 end
111 end
112 end
113
114 def Actions::fetch
115 d = IO::popen("svn cat svn://svn.debian.org/collab-qa/bapase/package-actions.txt")
116 f = d.read
117 d.close
118 return Actions::read(f)
119 end
120
121 def Actions::read(data)
122 pkgs = {}
123 data.each_line do |l|
124 next if l =~/^\s*#/ or l =~/^\s*$/
125 pkg, rest = l.split(' ',2)
126 if pkgs[pkg].nil?
127 pkgs[pkg] = Actions::new
128 end
129 pkgs[pkg].add(rest)
130 end
131 pkgs.each_pair { |k, v| v.analyze_actions }
132 end
133 end
134
135 puts "Content-type: text/html\n\n"
136
137 WAIT_RM_O = 50
138 WAIT_RM_RM = 100
139 WAIT_O_O = 50
140 WAIT_ORM_RM = 50
141
142 DATEZERO = Date::parse('0000-01-01')
143 CURDATE = Date::today
144
145 dbh = DBI::connect('DBI:Pg:dbname=udd;port=5441;host=localhost', 'guest')
146 cgi = CGI.new
147
148 type = cgi.params['t']
149 if not type.nil?
150 type = type[0]
151 end
152
153 if type == 'o'
154 orphaned = true
155 query = "select * from bapase where type is not null and type in ('O', 'ITA') order by orphaned_age desc"
156 elsif type == 'o2'
157 orphaned = true
158 query = "select * from bapase where type is not null and type in ('O', 'ITA') and orphaned_age >= 600 and orphaned_age < 730 and insts < 300 and last_modified_age > 60 order by last_modified_age desc"
159 elsif type == 'rfa'
160 orphaned = true
161 query = "select * from bapase where type is not null and type in ('RFA') order by orphaned_age desc"
162 elsif type == 'nmu'
163 orphaned = true
164 query = "select * from bapase where nmu and nmus > 1 order by nmus desc"
165 elsif type == 'testing'
166 orphaned = true
167 query = "select * from bapase where source not in (select source from sources where distribution='debian' and release='wheezy') order by testing_age desc, first_seen asc"
168 elsif type == 'nodd'
169 orphaned = true
170 query = <<EOF
171 WITH active_emails AS (SELECT email FROM carnivore_emails, active_dds WHERE active_dds.id = carnivore_emails.id)
172 select * from bapase where source in (
173 SELECT source
174 FROM sources
175 WHERE distribution = 'debian' AND release = 'sid'
176 AND sources.source NOT IN (
177 SELECT sources.source
178 FROM sources
179 LEFT OUTER JOIN uploaders ON (sources.source = uploaders.source AND sources.version = uploaders.version AND sources.distribution = uploaders.distribution AND sources.release = uploaders.release AND sources.component = uploaders.component)
180 WHERE sources.distribution = 'debian' AND sources.release = 'sid'
181 AND (maintainer_email in (select email from active_emails)
182 OR email in (SELECT email FROM active_emails)
183 OR maintainer_email ~ '.*@lists.(alioth.)?debian.org'
184 OR email ~ '.*@lists.(alioth.)?debian.org'))
185 ) order by upload_age desc
186 EOF
187 elsif type == 'maintnmu'
188 orphaned = true
189 query = <<EOF
190 select * from bapase where source in (
191 select source from sources where distribution='debian' and release='wheezy' and maintainer_email in (
192 select nmus.email from
193 (select email, count(*) as tot from
194 (select maintainer_email as email, source from sources_uniq
195 where release = 'sid'
196 and distribution = 'debian'
197 and component = 'main'
198 union
199 select email, source from uploaders
200 where release = 'sid'
201 and distribution = 'debian'
202 and component = 'main') as foo
203 group by email) as tot,
204 (select email, count(*) as nmus from
205 (select sources.maintainer_email as email, sources.source from sources_uniq sources, upload_history uh
206 where release = 'sid'
207 and distribution = 'debian'
208 and component = 'main'
209 and sources.source = uh.source and sources.version = uh.version
210 and uh.nmu
211 union
212 select email, uploaders.source from uploaders, upload_history uh
213 where release = 'sid'
214 and distribution = 'debian'
215 and component = 'main'
216 and uploaders.source = uh.source and uploaders.version = uh.version
217 and uh.nmu
218 ) as foo
219 group by email) as nmus
220 where nmus * 100 / tot >= 100
221 and nmus.email = tot.email)
222 union (select source from uploaders where distribution='debian' and release='wheezy' and email in (
223 select nmus.email from
224 (select email, count(*) as tot from
225 (select maintainer_email as email, source from sources_uniq sources
226 where release = 'sid'
227 and distribution = 'debian'
228 and component = 'main'
229 union
230 select email, source from uploaders
231 where release = 'sid'
232 and distribution = 'debian'
233 and component = 'main') as foo
234 group by email) as tot,
235 (select email, count(*) as nmus from
236 (select sources.maintainer_email as email, sources.source from sources_uniq sources, upload_history uh
237 where release = 'sid'
238 and distribution = 'debian'
239 and component = 'main'
240 and sources.source = uh.source and sources.version = uh.version
241 and uh.nmu
242 union
243 select email, uploaders.source from uploaders, upload_history uh
244 where release = 'sid'
245 and distribution = 'debian'
246 and component = 'main'
247 and uploaders.source = uh.source and uploaders.version = uh.version
248 and uh.nmu
249 ) as foo
250 group by email) as nmus
251 where nmus * 100 / tot >= 100
252 and nmus.email = tot.email
253 ))) order by nmus
254 EOF
255 else
256 puts <<-EOF
257 <h1>Bapase</h1>
258 <ul>
259 <li><a href="bapase.cgi?t=o">Orphaned packages</a></li>
260 <li><a href="bapase.cgi?t=rfa">RFAed packages</a></li>
261 <li><a href="bapase.cgi?t=nmu">Packages maintained with NMUs</a></li>
262 <li><a href="bapase.cgi?t=testing">Packages not in testing</a></li>
263 <li><a href="bapase.cgi?t=nodd">Packages not maintained by DDs</a></li>
264 <li><a href="bapase.cgi?t=maintnmu">Packages maintained or co-maintained by people with lots of NMUs</a></li>
265 </ul>
266 </body></html>
267 EOF
268 exit(0)
269 end
270
271 # FIXME add case where type is uknown
272
273 $actions = Actions::fetch
274
275 puts <<-EOF
276 <html><head>
277 <style type="text/css">
278 td, th {
279 border: 1px solid gray;
280 padding-left: 2px;
281 padding-right: 2px;
282 }
283 th {
284 font-size: 8pt;
285 }
286 tr:hover {
287 background-color: #ccc;
288 }
289 table {
290 border-collapse: collapse;
291 }
292 </style>
293 <title>Bapase</title>
294 </head><body>
295 <table border="1"><tr>
296 <th></th><th>Package</th><th>Action</th>
297 EOF
298 puts "<th>Orphaned</th>" if orphaned
299 puts <<-EOF
300 <th>Testing</th>
301 <th>Migrate</th>
302 <th>Popcon</th>
303 <th>Bugs</th>
304 <th>Last upload</th>
305 <th>NMUs</th>
306 <th>Comments</th>
307 </tr>
308 EOF
309 tqs = Time::now
310 sth = dbh.prepare(query)
311 sth.execute
312 tqe = Time::now
313 res = sth.fetch_all
314 n = 0
315 res.each do |r|
316 n += 1
317 pkg = r['source']
318 puts "<tr><td>#{n}</td>"
319 puts "<td><a href=\"http://packages.qa.debian.org/#{pkg}\">#{pkg}</a>"
320 # FIXME removals
321 if $actions[pkg]
322 if $actions[pkg].act_todo
323 puts "<td><b>#{$actions[pkg].act_status}</b></td>"
324 else
325 puts "<td>#{$actions[pkg].act_status}</td>"
326 end
327 else
328 puts "<td></td>"
329 end
330 if orphaned
331 if r['type']
332 puts "<td><a href=\"http://bugs.debian.org/#{r['bug']}\">#{r['type']}</a>&nbsp;(#{r['orphaned_age']},&nbsp;#{r['last_modified_age']})</td>"
333 else
334 puts "<td></td>"
335 end
336 end
337 if r['testing_age'] and r['testing_age'] > 1
338 puts "<td>#{r['testing_age']}</td>"
339 else
340 puts "<td></td>"
341 end
342 if r['sync_age'] and r['sync_age'] > 1
343 puts "<td>#{r['sync_age']}</td>"
344 else
345 puts "<td></td>"
346 end
347 puts "<td>#{r['insts']}&nbsp;/&nbsp;#{r['vote']}</td>"
348 puts "<td><a href=\"http://bugs.debian.org/src:#{pkg}\">#{r['rc_bugs']}&nbsp;/&nbsp;#{r['all_bugs']}</a></td>"
349 puts "<td>#{r['upload_age']}</td>"
350 puts "<td>#{r['nmus']}</td>"
351 if $actions[pkg]
352 comment = $actions[pkg].act_comment.gsub(/#\d+/) do |bug|
353 bugn = bug.gsub(/^#/, '')
354 "<a href=\"http://bugs.debian.org/#{bugn}\">#{bug}</a>"
355 end
356 puts "<td>#{comment}</td>"
357 else
358 puts "<td></td>"
359 end
360 puts "</tr>"
361 end
362 puts "</table>"
363
364 tstop = Time::now
365 puts " -- #{res.length} packages listed. Page generated in #{tstop - tstart} seconds. Query took #{tqe - tqs} seconds."
366 puts "</body></html>"
367
368
369
370
371 #sth.finish

Properties

Name Value
svn:executable *
svn:mergeinfo

  ViewVC Help
Powered by ViewVC 1.1.5