Mercurial > treepkg
view contrib/sawmill/bin/generate-rss.py @ 492:93d66243bce7
sawmill: Added RSS feed generator.
author | Sascha Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 30 Sep 2010 22:51:45 +0000 |
parents | |
children |
line wrap: on
line source
#!/usr/bin/env python # -*- coding: UTF-8 -*- # # Copyright (C) 2010 by Intevation GmbH # Authors: # Sascha L. Teichmann <sascha.teichmann@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()