]> git.decadent.org.uk Git - dak.git/blobdiff - dak/show_deferred.py
Merge remote-tracking branch 'nthykier/auto-decruft'
[dak.git] / dak / show_deferred.py
index 8c13d677befdf1d6d4f56db80ed9cbdcb4f7c819..57e9c8a3780d443cf49b7ecd235487ffcefc36be 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 
-# based on queue-report
+""" Overview of the DEFERRED queue, based on queue-report """
 #    Copyright (C) 2001, 2002, 2003, 2005, 2006  James Troup <james@nocrew.org>
 # Copyright (C) 2008 Thomas Viehmann <tv@beamnet.de>
 
 
 import sys, os, re, time
 import apt_pkg
-import tempfile
-from debian_bundle import deb822
-from daklib import database
-from daklib import queue
+import rrdtool
+
+from debian import deb822
+
+from daklib.dbconn import *
+from daklib.gpg import SignedFile
 from daklib import utils
 from daklib.regexes import re_html_escaping, html_escaping
 
@@ -51,32 +53,32 @@ def header():
         <html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
         <title>Deferred uploads to Debian</title>
         <link type="text/css" rel="stylesheet" href="style.css">
-        <link rel="shortcut icon" href="http://www.debian.org/favicon.ico">
+        <link rel="shortcut icon" href="https://www.debian.org/favicon.ico">
         </head>
         <body>
         <div align="center">
-        <a href="http://www.debian.org/">
-     <img src="http://www.debian.org/logos/openlogo-nd-50.png" border="0" hspace="0" vspace="0" alt=""></a>
-        <a href="http://www.debian.org/">
-     <img src="http://www.debian.org/Pics/debian.png" border="0" hspace="0" vspace="0" alt="Debian Project"></a>
+        <a href="https://www.debian.org/">
+     <img src="https://www.debian.org/logos/openlogo-nd-50.png" border="0" hspace="0" vspace="0" alt=""></a>
+        <a href="https://www.debian.org/">
+     <img src="https://www.debian.org/Pics/debian.png" border="0" hspace="0" vspace="0" alt="Debian Project"></a>
         </div>
         <br />
         <table class="reddy" width="100%">
         <tr>
         <td class="reddy">
-    <img src="http://www.debian.org/Pics/red-upperleft.png" align="left" border="0" hspace="0" vspace="0"
+    <img src="https://www.debian.org/Pics/red-upperleft.png" align="left" border="0" hspace="0" vspace="0"
      alt="" width="15" height="16"></td>
         <td rowspan="2" class="reddy">Deferred uploads to Debian</td>
         <td class="reddy">
-    <img src="http://www.debian.org/Pics/red-upperright.png" align="right" border="0" hspace="0" vspace="0"
+    <img src="https://www.debian.org/Pics/red-upperright.png" align="right" border="0" hspace="0" vspace="0"
      alt="" width="16" height="16"></td>
         </tr>
         <tr>
         <td class="reddy">
-    <img src="http://www.debian.org/Pics/red-lowerleft.png" align="left" border="0" hspace="0" vspace="0"
+    <img src="https://www.debian.org/Pics/red-lowerleft.png" align="left" border="0" hspace="0" vspace="0"
      alt="" width="16" height="16"></td>
         <td class="reddy">
-    <img src="http://www.debian.org/Pics/red-lowerright.png" align="right" border="0" hspace="0" vspace="0"
+    <img src="https://www.debian.org/Pics/red-lowerright.png" align="right" border="0" hspace="0" vspace="0"
      alt="" width="15" height="16"></td>
         </tr>
         </table>
@@ -84,14 +86,9 @@ def header():
 
 def footer():
     res = "<p class=\"validate\">Timestamp: %s (UTC)</p>" % (time.strftime("%d.%m.%Y / %H:%M:%S", time.gmtime()))
-    res += """<a href="http://validator.w3.org/check?uri=referer">
-    <img border="0" src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" height="31" width="88"></a>
-        <a href="http://jigsaw.w3.org/css-validator/check/referer">
-    <img border="0" src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"
-     height="31" width="88"></a>
-    """
+    res += "<p class=\"timestamp\">There are <a href=\"/stat.html\">graphs about the queues</a> available.</p>"
     res += "</body></html>"
-    return res
+    return res.encode('utf-8')
 
 def table_header():
     return """<h1>Deferred uploads</h1>
@@ -103,22 +100,75 @@ def table_header():
           <th align="center">Closes</th>
         </tr>
         """
-    return res
 
 def table_footer():
     return '</table><br/><p>non-NEW uploads are <a href="/deferred/">available</a>, see the <a href="ftp://ftp-master.debian.org/pub/UploadQueue/README">UploadQueue-README</a> for more information.</p></center><br/>\n'
 
-def table_row(changesname, delay, changed_by, closes):
+def table_row(changesname, delay, changed_by, closes, fingerprint):
     global row_number
 
     res = '<tr class="%s">'%((row_number%2) and 'odd' or 'even')
-    res += (3*'<td valign="top">%s</td>')%tuple(map(html_escape,(changesname,delay,changed_by)))
+    res += (2*'<td valign="top">%s</td>')%tuple(map(html_escape,(changesname,delay)))
+    res += '<td valign="top">%s<br><span class=\"deferredfp\">Fingerprint: %s</span></td>' % (html_escape(changed_by), fingerprint)
     res += ('<td valign="top">%s</td>' %
-             ''.join(map(lambda close:  '<a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s">#%s</a><br>' % (close, close),closes)))
+             ''.join(map(lambda close:  '<a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s">#%s</a><br>' % (close, close),closes)))
     res += '</tr>\n'
     row_number+=1
     return res
 
+def update_graph_database(rrd_dir, *counts):
+    if not rrd_dir:
+        return
+
+    rrd_file = os.path.join(rrd_dir, 'deferred.rrd')
+    counts = [str(count) for count in counts]
+    update = [rrd_file, "N:"+":".join(counts)]
+
+    try:
+        rrdtool.update(*update)
+    except rrdtool.error:
+        create = [rrd_file]+"""
+--step
+300
+--start
+0
+DS:day0:GAUGE:7200:0:1000
+DS:day1:GAUGE:7200:0:1000
+DS:day2:GAUGE:7200:0:1000
+DS:day3:GAUGE:7200:0:1000
+DS:day4:GAUGE:7200:0:1000
+DS:day5:GAUGE:7200:0:1000
+DS:day6:GAUGE:7200:0:1000
+DS:day7:GAUGE:7200:0:1000
+DS:day8:GAUGE:7200:0:1000
+DS:day9:GAUGE:7200:0:1000
+DS:day10:GAUGE:7200:0:1000
+DS:day11:GAUGE:7200:0:1000
+DS:day12:GAUGE:7200:0:1000
+DS:day13:GAUGE:7200:0:1000
+DS:day14:GAUGE:7200:0:1000
+DS:day15:GAUGE:7200:0:1000
+RRA:AVERAGE:0.5:1:599
+RRA:AVERAGE:0.5:6:700
+RRA:AVERAGE:0.5:24:775
+RRA:AVERAGE:0.5:288:795
+RRA:MIN:0.5:1:600
+RRA:MIN:0.5:6:700
+RRA:MIN:0.5:24:775
+RRA:MIN:0.5:288:795
+RRA:MAX:0.5:1:600
+RRA:MAX:0.5:6:700
+RRA:MAX:0.5:24:775
+RRA:MAX:0.5:288:795
+""".strip().split("\n")
+        try:
+            rc = rrdtool.create(*create)
+            ru = rrdtool.update(*update)
+        except rrdtool.error as e:
+            print('warning: queue_report: rrdtool error, skipping %s.rrd: %s' % (type, e))
+    except NameError:
+        pass
+
 def get_upload_data(changesfn):
     achanges = deb822.Changes(file(changesfn))
     changesname = os.path.basename(changesfn)
@@ -129,19 +179,24 @@ def get_upload_data(changesfn):
         remainingtime = (delaydays>0)*max(0,24*60*60+os.stat(changesfn).st_mtime-time.time())
         delay = "%d days %02d:%02d" %(max(delaydays-1,0), int(remainingtime/3600),int(remainingtime/60)%60)
     else:
+        delaydays = 0
         remainingtime = 0
 
     uploader = achanges.get('changed-by')
     uploader = re.sub(r'^\s*(\S.*)\s+<.*>',r'\1',uploader)
+    with utils.open_file(changesfn) as f:
+        fingerprint = SignedFile(f.read(), keyrings=get_active_keyring_paths(), require_signature=False).fingerprint
     if Cnf.has_key("Show-Deferred::LinkPath"):
         isnew = 0
-        suites = database.get_suites(achanges['source'],src=1)
+        suites = get_suites_source_in(achanges['source'])
         if 'unstable' not in suites and 'experimental' not in suites:
             isnew = 1
+
         for b in achanges['binary'].split():
-            suites = database.get_suites(b)
+            suites = get_suites_binary_in(b)
             if 'unstable' not in suites and 'experimental' not in suites:
                 isnew = 1
+
         if not isnew:
             # we don't link .changes because we don't want other people to
             # upload it with the existing signature.
@@ -152,17 +207,17 @@ def get_upload_data(changesfn):
                     os.unlink(lfn)
                 if os.path.exists(qfn):
                     os.symlink(qfn,lfn)
-                    os.chmod(qfn, 0644)
-    return (max(delaydays-1,0)*24*60*60+remainingtime, changesname, delay, uploader, achanges.get('closes','').split(),achanges)
+                    os.chmod(qfn, 0o644)
+    return (max(delaydays-1,0)*24*60*60+remainingtime, changesname, delay, uploader, achanges.get('closes','').split(), fingerprint, achanges, delaydays)
 
-def list_uploads(filelist):
+def list_uploads(filelist, rrd_dir):
     uploads = map(get_upload_data, filelist)
     uploads.sort()
     # print the summary page
     print header()
     if uploads:
         print table_header()
-        print ''.join(map(lambda x: table_row(*x[1:5]), uploads))
+        print ''.join(map(lambda x: table_row(*x[1:6]), uploads)).encode('utf-8')
         print table_footer()
     else:
         print '<h1>Currently no deferred uploads to Debian</h1>'
@@ -172,18 +227,23 @@ def list_uploads(filelist):
         fn = os.path.join(Cnf["Show-Deferred::LinkPath"],'.status.tmp')
         f = open(fn,"w")
         try:
+            counts = [0]*16
             for u in uploads:
-                print >> f, "Changes: %s"%u[1]
+                counts[u[7]] += 1
+                print >> f, "Changes-file: %s"%u[1]
                 fields = """Location: DEFERRED
 Delayed-Until: %s
-Delay-Remaining: %s"""%(time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(time.time()+u[0])),u[2])
+Delay-Remaining: %s
+Fingerprint: %s"""%(time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(time.time()+u[0])),u[2], u[5])
                 print >> f, fields
-                print >> f, str(u[5]).rstrip()
-                open(os.path.join(Cnf["Show-Deferred::LinkPath"],u[1]),"w").write(str(u[5])+fields+'\n')
+                encoded = unicode(u[6]).encode('utf-8')
+                print >> f, encoded.rstrip()
+                open(os.path.join(Cnf["Show-Deferred::LinkPath"],u[1]),"w").write(encoded+fields+'\n')
                 print >> f
             f.close()
             os.rename(os.path.join(Cnf["Show-Deferred::LinkPath"],'.status.tmp'),
                       os.path.join(Cnf["Show-Deferred::LinkPath"],'status'))
+            update_graph_database(rrd_dir, *counts)
         except:
             os.unlink(fn)
             raise
@@ -197,16 +257,18 @@ def usage (exit_code=0):
   -h, --help                    show this help and exit.
   -p, --link-path [path]        override output directory.
   -d, --deferred-queue [path]   path to the deferred queue
+  -r, --rrd=key                 Directory where rrd files to be updated are stored
   """
     sys.exit(exit_code)
 
 def init():
-    global Cnf, Options, Upload, projectB
+    global Cnf, Options
     Cnf = utils.get_conf()
     Arguments = [('h',"help","Show-Deferred::Options::Help"),
                  ("p","link-path","Show-Deferred::LinkPath","HasArg"),
-                 ("d","deferred-queue","Show-Deferred::DeferredQueue","HasArg")]
-    args = apt_pkg.ParseCommandLine(Cnf,Arguments,sys.argv)
+                 ("d","deferred-queue","Show-Deferred::DeferredQueue","HasArg"),
+                 ('r',"rrd","Show-Deferred::Options::Rrd", "HasArg")]
+    args = apt_pkg.parse_commandline(Cnf,Arguments,sys.argv)
     for i in ["help"]:
         if not Cnf.has_key("Show-Deferred::Options::%s" % (i)):
             Cnf["Show-Deferred::Options::%s" % (i)] = ""
@@ -215,11 +277,13 @@ def init():
             print >> sys.stderr, """Show-Deferred::%s is mandatory.
   set via config file or command-line option %s"""%(i,j)
 
-    Options = Cnf.SubTree("Show-Deferred::Options")
+    Options = Cnf.subtree("Show-Deferred::Options")
     if Options["help"]:
         usage()
-    Upload = queue.Upload(Cnf)
-    projectB = Upload.projectB
+
+    # Initialise database connection
+    DBConn()
+
     return args
 
 def main():
@@ -227,11 +291,18 @@ def main():
     if len(args)!=0:
         usage(1)
 
+    if Cnf.has_key("Show-Deferred::Options::Rrd"):
+        rrd_dir = Cnf["Show-Deferred::Options::Rrd"]
+    elif Cnf.has_key("Dir::Rrd"):
+        rrd_dir = Cnf["Dir::Rrd"]
+    else:
+        rrd_dir = None
+
     filelist = []
     for r,d,f  in os.walk(Cnf["Show-Deferred::DeferredQueue"]):
         filelist += map (lambda x: os.path.join(r,x),
                          filter(lambda x: x.endswith('.changes'), f))
-    list_uploads(filelist)
+    list_uploads(filelist, rrd_dir)
 
     available_changes = set(map(os.path.basename,filelist))
     if Cnf.has_key("Show-Deferred::LinkPath"):
@@ -242,3 +313,6 @@ def main():
                 if (not os.path.exists(afp) or
                     (af.endswith('.changes') and af not in available_changes)):
                     os.unlink(afp)
+
+if __name__ == '__main__':
+    main()