]> git.decadent.org.uk Git - dak.git/blobdiff - tools/queue_rss.py
Cope with empty queue
[dak.git] / tools / queue_rss.py
index ce72d65afd5e4fbaa2bba9d71ad8c7a7687c021b..4e8c7ca25e8282497c0dc6eb99e8f6864cd006ab 100755 (executable)
@@ -3,26 +3,29 @@
 
 # License: GPL v2 or later
 # Author: Filippo Giunchedi <filippo@debian.org>
-# Version: 0.4
+# Version: 0.5
 
+import cgi
 import os
 import os.path
 import cPickle
+import re
 import sys
-import encodings.ascii
+import time
 from optparse import OptionParser
 from datetime import datetime
 
 import PyRSS2Gen
 
-from debian_bundle.deb822 import Changes
+from debian.deb822 import Changes
 
-inrss_filename = "changes_in.rss"
-outrss_filename = "changes_out.rss"
+inrss_filename = "NEW_in.rss"
+outrss_filename = "NEW_out.rss"
 db_filename = "status.db"
 
 parser = OptionParser()
-parser.set_defaults(queuedir="queue", outdir="out", datadir="status", max_entries="30")
+parser.set_defaults(queuedir="queue", outdir="out", datadir="status",
+                    logdir="log", max_entries="30")
 
 parser.add_option("-q", "--queuedir", dest="queuedir",
         help="The queue dir (%default)")
@@ -30,6 +33,8 @@ parser.add_option("-o", "--outdir", dest="outdir",
         help="The output directory (%default)")
 parser.add_option("-d", "--datadir", dest="datadir",
         help="The data dir (%default)")
+parser.add_option("-l", "--logdir", dest="logdir",
+        help="The ACCEPT/REJECT dak log dir (%default)")
 parser.add_option("-m", "--max-entries", dest="max_entries", type="int",
         help="Max number of entries to keep (%default)")
 
@@ -47,14 +52,6 @@ class Status:
 
         self.queue = {}
 
-def utf2ascii(src):
-    """ Return an ASCII encoded copy of the input UTF-8 string """
-    try:
-        res = unicode(src, 'utf-8').encode('ascii', 'replace')
-    except UnicodeDecodeError:
-        res = None
-    return res
-
 def purge_old_items(feed, max):
     """ Purge RSSItem from feed, no more than max. """
     if feed.items is None or len(feed.items) == 0:
@@ -97,6 +94,28 @@ def parse_queuedir(dir):
 
     return res
 
+def parse_leave_reason(fname):
+    """ Parse a dak log file fname for ACCEPT/REJECT reason from process-new.
+
+    Return a dictionary {filename: reason}"""
+
+    reason_re = re.compile(".+\|process-new\|.+\|NEW (ACCEPT|REJECT): (\S+)")
+
+    try:
+        f = open(fname)
+    except IOError, e:
+        sys.stderr.write("Can't open %s: %s\n" % (fname, e))
+        return {}
+
+    res = {}
+    for l in f.readlines():
+        m = reason_re.search(l)
+        if m:
+            res[m.group(2)] = m.group(1)
+
+    f.close()
+    return res
+
 def add_rss_item(status, msg, direction):
     if direction == "in":
         feed = status.feed_in
@@ -104,29 +123,43 @@ def add_rss_item(status, msg, direction):
         pubdate = msg['Date']
     elif direction == "out":
         feed = status.feed_out
-        title = "%s %s left NEW" % (msg['Source'], msg['Version'])
+        if msg.has_key('Leave-Reason'):
+            title = "%s %s left NEW (%s)" % (msg['Source'], msg['Version'],
+                                             msg['Leave-Reason'])
+        else:
+            title = "%s %s left NEW" % (msg['Source'], msg['Version'])
+
+
         pubdate = datetime.utcnow()
     else:
         return False
 
     description = "<pre>Description: %s\nChanges: %s\n</pre>" % \
-            (utf2ascii(msg['Description']), utf2ascii(msg['Changes']))
+            (cgi.escape(msg['Description']),
+             cgi.escape(msg['Changes']))
+
+    link = "http://ftp-master.debian.org/new/%s_%s.html" % \
+            (msg['Source'], msg['Version'])
 
     feed.items.insert(0,
         PyRSS2Gen.RSSItem(
             title,
             pubDate = pubdate,
             description = description,
-            author = utf2ascii(msg['Maintainer']),
-            link = "http://ftp-master.debian.org/new/%s_%s.html" % \
-                    (msg['Source'], msg['Version'])
+            author = cgi.escape(msg['Maintainer']),
+            link = link,
+            guid = link
         )
     )
 
-def update_feeds(curqueue, status):
+def update_feeds(curqueue, status, settings):
     # inrss -> append all items in curqueue not in status.queue
     # outrss -> append all items in status.queue not in curqueue
 
+    leave_reason = None
+    # logfile from dak's process-new
+    reason_log = os.path.join(settings.logdir, time.strftime("%Y-%m"))
+
     for (name, parsed) in curqueue.items():
         if not status.queue.has_key(name):
             # new package
@@ -134,7 +167,11 @@ def update_feeds(curqueue, status):
 
     for (name, parsed) in status.queue.items():
         if not curqueue.has_key(name):
-            # removed package
+            # removed package, try to find out why
+            if leave_reason is None:
+                leave_reason = parse_leave_reason(reason_log)
+            if leave_reason and leave_reason.has_key(name):
+                parsed['Leave-Reason'] = leave_reason[name]
             add_rss_item(status, parsed, "out")
 
 
@@ -161,12 +198,8 @@ if __name__ == "__main__":
         status = Status()
 
     current_queue = parse_queuedir(settings.queuedir)
-    if not current_queue:
-        sys.stderr.write("Unable to scan queuedir '%s'\n" % settings.queuedir)
-        parser.print_help()
-        sys.exit(1)
 
-    update_feeds(current_queue, status)
+    update_feeds(current_queue, status, settings)
 
     purge_old_items(status.feed_in, settings.max_entries)
     purge_old_items(status.feed_out, settings.max_entries)