[Treepkg-commits] r452 - in trunk/contrib/sawmill: . bin
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Fri Oct 1 00:51:46 CEST 2010
Author: teichmann
Date: 2010-10-01 00:51:45 +0200 (Fri, 01 Oct 2010)
New Revision: 452
Added:
trunk/contrib/sawmill/bin/
trunk/contrib/sawmill/bin/generate-rss.py
Modified:
trunk/contrib/sawmill/README
Log:
sawmill: Added RSS feed generator.
Modified: trunk/contrib/sawmill/README
===================================================================
--- trunk/contrib/sawmill/README 2010-09-30 09:38:40 UTC (rev 451)
+++ trunk/contrib/sawmill/README 2010-09-30 22:51:45 UTC (rev 452)
@@ -28,3 +28,15 @@
--exclude 'debian' --exclude 'src' \
--exclude 'binary' --exclude '*checkout*' \
--exclude '*.html' $TREE_PKG/mill/tracks/ $DEST/tracks
+
+If you want to generate RSS feeds for the build errors:
+
+# apt-get install python-pyrss2gen
+
+copy bin/generate-rss.py to a place where it can be run as a cronjob.
+Adjust BASE_URL in the to fit your installation.
+
+---8<---
+*/7 * * * * /where/you/placed/generate-rss.py /where/you/placed/buildlogs/treepkgs
+--->8---
+
Added: trunk/contrib/sawmill/bin/generate-rss.py
===================================================================
--- trunk/contrib/sawmill/bin/generate-rss.py 2010-09-30 09:38:40 UTC (rev 451)
+++ trunk/contrib/sawmill/bin/generate-rss.py 2010-09-30 22:51:45 UTC (rev 452)
@@ -0,0 +1,156 @@
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+#
+# Copyright (C) 2010 by Intevation GmbH
+# Authors:
+# Sascha L. Teichmann <sascha.teichmann at intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with the software for details.
+
+import sys
+import os
+import re
+import traceback
+
+from datetime import datetime
+
+from lxml import etree
+
+import PyRSS2Gen as RSS2
+
+BASE_URL = "http://saegewerk2.wald.intevation.org/buildlogs"
+LINK_URL = "%s/details.py?treepkg=%%s" % BASE_URL
+ITEM_URL = "%s/details.py?treepkg=%%s#%%s" % BASE_URL
+
+TITLE = "Saegewerk - %s"
+DESCRIPTION = "Build errors of '%s'"
+MESSAGE = "%s: error building %s rev. %s"
+TTL = 7
+
+START = re.compile(
+ r"start:\s+(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})")
+STATUS = re.compile(r"status:\s+(.+)")
+
+INVALID_LABEL = re.compile(r"[^a-zA-Z0-9_]")
+
+def make_valid_label(l):
+ return INVALID_LABEL.sub("_", l)
+
+def to_datetime(m):
+ m = map(int, m.groups())
+ return datetime(
+ year=m[0], month=m[1], day=m[2],
+ hour=m[3], minute=m[4], second=m[5])
+
+def usage(msg, code=1):
+ print >> sys.stderr, "%s <treepkgs directory>" % sys.argv[0]
+ print >> sys.stderr, "%s" % msg
+ sys.exit(code)
+
+def main():
+ if len(sys.argv) < 2:
+ usage("missing treepkgs directory")
+
+ treepkgs_dir = sys.argv[1]
+ if not os.path.isdir(treepkgs_dir):
+ usage("'%s' is not a directory" % treepkgs_dir)
+
+ for treepkg in os.listdir(treepkgs_dir):
+ treepkg_dir = os.path.join(treepkgs_dir, treepkg)
+ if not os.path.isdir(treepkg_dir): continue
+ treepkg_xml = os.path.join(treepkg_dir, "treepkg.xml")
+ if not os.path.isfile(treepkg_xml): continue
+ try:
+ f = open(treepkg_xml, "rb")
+ try: treepkg_dom = etree.parse(f)
+ finally: f.close()
+ except:
+ traceback.print_exc(file=sys.stderr)
+ continue
+ description = ''.join(
+ treepkg_dom.xpath('/treepkg/description/text()'))
+
+ tracks_dir = os.path.join(treepkg_dir, "tracks")
+ if not os.path.isdir(tracks_dir): continue
+
+ items = []
+
+ for track in os.listdir(tracks_dir):
+ track_dir = os.path.join(tracks_dir, track, "pkg")
+ if not os.path.isdir(track_dir): continue
+
+ track_label = make_valid_label(track)
+
+ for revision in os.listdir(track_dir):
+ revision_dir = os.path.join(track_dir, revision)
+ if not os.path.isdir(revision_dir): continue
+ status_file = os.path.join(revision_dir, "status")
+ if not os.path.isfile(status_file): continue
+ start, status = None, None
+ try:
+ f = open(status_file, "r")
+ try:
+ while True:
+ line = f.readline()
+ if not line: break
+ m = STATUS.match(line)
+ if m: status = m.group(1); continue
+ m = START.match(line)
+ if m: start = to_datetime(m)
+ finally:
+ f.close()
+ except:
+ traceback.print_exc(file=sys.stderr)
+ continue
+ if status != "error" or not start: continue
+
+ label = ''.join([
+ track_label,
+ make_valid_label(revision),
+ start.strftime("%Y%m%d%H%M%S")])
+
+ link = ITEM_URL % (treepkg, label)
+ msg = MESSAGE % (description, track, revision)
+ item = RSS2.RSSItem(
+ title = msg,
+ link = link,
+ description = msg,
+ guid = RSS2.Guid(link, isPermaLink=0),
+ pubDate = start
+ )
+ items.append(item)
+
+ items.sort(key=lambda x: x.pubDate)
+
+ rss = RSS2.RSS2(
+ title = TITLE % description,
+ link = LINK_URL % treepkg,
+ description = DESCRIPTION % description,
+ pubDate = datetime.utcnow(),
+ ttl = TTL,
+ items = items)
+
+ pid, idx = os.getpid(), 0
+ while True:
+ tmp_f = os.path.join(
+ treepkg_dir, "rss.xml.tmp%d-%d" % (pid, idx))
+ if not os.path.exists(tmp_f): break
+ idx += 1
+
+ try:
+ f = open(tmp_f, "wb")
+ try: rss.write_xml(f, encoding="UTF-8")
+ finally: f.close()
+
+ rss_xml = os.path.join(treepkg_dir, "rss.xml")
+
+ os.rename(tmp_f, rss_xml)
+ except:
+ traceback.print_exc(file=sys.stderr)
+ if os.path.exists(tmp_f):
+ try: os.remove(tmp_f)
+ except: pass
+
+if __name__ == '__main__':
+ main()
Property changes on: trunk/contrib/sawmill/bin/generate-rss.py
___________________________________________________________________
Name: svn:executable
+ *
More information about the Treepkg-commits
mailing list