comparison 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
comparison
equal deleted inserted replaced
491:f1be9657c1d2 492:93d66243bce7
1 #!/usr/bin/env python
2 # -*- coding: UTF-8 -*-
3 #
4 # Copyright (C) 2010 by Intevation GmbH
5 # Authors:
6 # Sascha L. Teichmann <sascha.teichmann@intevation.de>
7 #
8 # This program is free software under the GPL (>=v2)
9 # Read the file COPYING coming with the software for details.
10
11 import sys
12 import os
13 import re
14 import traceback
15
16 from datetime import datetime
17
18 from lxml import etree
19
20 import PyRSS2Gen as RSS2
21
22 BASE_URL = "http://saegewerk2.wald.intevation.org/buildlogs"
23 LINK_URL = "%s/details.py?treepkg=%%s" % BASE_URL
24 ITEM_URL = "%s/details.py?treepkg=%%s#%%s" % BASE_URL
25
26 TITLE = "Saegewerk - %s"
27 DESCRIPTION = "Build errors of '%s'"
28 MESSAGE = "%s: error building %s rev. %s"
29 TTL = 7
30
31 START = re.compile(
32 r"start:\s+(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})")
33 STATUS = re.compile(r"status:\s+(.+)")
34
35 INVALID_LABEL = re.compile(r"[^a-zA-Z0-9_]")
36
37 def make_valid_label(l):
38 return INVALID_LABEL.sub("_", l)
39
40 def to_datetime(m):
41 m = map(int, m.groups())
42 return datetime(
43 year=m[0], month=m[1], day=m[2],
44 hour=m[3], minute=m[4], second=m[5])
45
46 def usage(msg, code=1):
47 print >> sys.stderr, "%s <treepkgs directory>" % sys.argv[0]
48 print >> sys.stderr, "%s" % msg
49 sys.exit(code)
50
51 def main():
52 if len(sys.argv) < 2:
53 usage("missing treepkgs directory")
54
55 treepkgs_dir = sys.argv[1]
56 if not os.path.isdir(treepkgs_dir):
57 usage("'%s' is not a directory" % treepkgs_dir)
58
59 for treepkg in os.listdir(treepkgs_dir):
60 treepkg_dir = os.path.join(treepkgs_dir, treepkg)
61 if not os.path.isdir(treepkg_dir): continue
62 treepkg_xml = os.path.join(treepkg_dir, "treepkg.xml")
63 if not os.path.isfile(treepkg_xml): continue
64 try:
65 f = open(treepkg_xml, "rb")
66 try: treepkg_dom = etree.parse(f)
67 finally: f.close()
68 except:
69 traceback.print_exc(file=sys.stderr)
70 continue
71 description = ''.join(
72 treepkg_dom.xpath('/treepkg/description/text()'))
73
74 tracks_dir = os.path.join(treepkg_dir, "tracks")
75 if not os.path.isdir(tracks_dir): continue
76
77 items = []
78
79 for track in os.listdir(tracks_dir):
80 track_dir = os.path.join(tracks_dir, track, "pkg")
81 if not os.path.isdir(track_dir): continue
82
83 track_label = make_valid_label(track)
84
85 for revision in os.listdir(track_dir):
86 revision_dir = os.path.join(track_dir, revision)
87 if not os.path.isdir(revision_dir): continue
88 status_file = os.path.join(revision_dir, "status")
89 if not os.path.isfile(status_file): continue
90 start, status = None, None
91 try:
92 f = open(status_file, "r")
93 try:
94 while True:
95 line = f.readline()
96 if not line: break
97 m = STATUS.match(line)
98 if m: status = m.group(1); continue
99 m = START.match(line)
100 if m: start = to_datetime(m)
101 finally:
102 f.close()
103 except:
104 traceback.print_exc(file=sys.stderr)
105 continue
106 if status != "error" or not start: continue
107
108 label = ''.join([
109 track_label,
110 make_valid_label(revision),
111 start.strftime("%Y%m%d%H%M%S")])
112
113 link = ITEM_URL % (treepkg, label)
114 msg = MESSAGE % (description, track, revision)
115 item = RSS2.RSSItem(
116 title = msg,
117 link = link,
118 description = msg,
119 guid = RSS2.Guid(link, isPermaLink=0),
120 pubDate = start
121 )
122 items.append(item)
123
124 items.sort(key=lambda x: x.pubDate)
125
126 rss = RSS2.RSS2(
127 title = TITLE % description,
128 link = LINK_URL % treepkg,
129 description = DESCRIPTION % description,
130 pubDate = datetime.utcnow(),
131 ttl = TTL,
132 items = items)
133
134 pid, idx = os.getpid(), 0
135 while True:
136 tmp_f = os.path.join(
137 treepkg_dir, "rss.xml.tmp%d-%d" % (pid, idx))
138 if not os.path.exists(tmp_f): break
139 idx += 1
140
141 try:
142 f = open(tmp_f, "wb")
143 try: rss.write_xml(f, encoding="UTF-8")
144 finally: f.close()
145
146 rss_xml = os.path.join(treepkg_dir, "rss.xml")
147
148 os.rename(tmp_f, rss_xml)
149 except:
150 traceback.print_exc(file=sys.stderr)
151 if os.path.exists(tmp_f):
152 try: os.remove(tmp_f)
153 except: pass
154
155 if __name__ == '__main__':
156 main()
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)