1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 import os
42 import re
43 import time
44 from twisted.web import resource
45 from buildbot.status import results
46
48 contentType = "text/xml; charset=UTF-8"
49 docType = ''
50
53
55 data = self.content(request)
56 request.setHeader("content-type", self.contentType)
57 if request.method == "HEAD":
58 request.setHeader("content-length", len(data))
59 return ''
60 return data
61
62 _abbr_day = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
63 _abbr_mon = ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',
64 'Sep', 'Oct', 'Nov', 'Dec']
65
67 res = time.strftime("%%s, %d %%s %Y %H:%M:%S GMT",
68 tstamp)
69 res = res % (tstamp.tm_wday, tstamp.tm_mon)
70 return res
71
73 pageTitle = None
74 link = 'http://dummylink'
75 language = 'en-us'
76 description = 'Dummy rss'
77 status = None
78
79 - def __init__(self, status, categories=None, pageTitle=None):
91
92 - def getEnv(self, keys, fallback):
93 for key in keys:
94 if key in os.environ:
95 return os.environ[key]
96 return fallback
97
99 builds = []
100
101
102
103
104
105
106 allBuilderNames = self.status.getBuilderNames(categories=self.categories)
107 builders = [self.status.getBuilder(name) for name in allBuilderNames]
108
109
110
111
112
113 showBuilders = request.args.get("show", [])
114 showBuilders.extend(request.args.get("builder", []))
115 if showBuilders:
116 builders = [b for b in builders if b.name in showBuilders]
117
118
119
120
121 showCategories = request.args.get("category", [])
122 if showCategories:
123 builders = [b for b in builders if b.category in showCategories]
124
125 failures_only = request.args.get("failures_only", ["false"])
126 failures_only = failures_only[0] not in ('false', '0', 'no', 'off')
127
128 maxFeeds = 25
129
130
131
132
133 for b in builders:
134 if failures_only:
135 res = (results.FAILURE,)
136 else:
137 res = None
138 builds.extend(b.generateFinishedBuilds(results=res, max_search=maxFeeds))
139
140
141
142
143 deco = [(build.getTimes(), build) for build in builds]
144 deco.sort()
145 deco.reverse()
146 builds = [build for (b1, build) in deco]
147
148 if builds:
149 builds = builds[:min(len(builds), maxFeeds)]
150 return builds
151
152 - def content(self, request):
153 builds = self.getBuilds(request)
154
155 build_cxts = []
156
157 for build in builds:
158 start, finished = build.getTimes()
159 finishedTime = time.gmtime(int(finished))
160 link = re.sub(r'index.html', "", self.status.getURLForThing(build))
161
162
163
164 ss_list = build.getSourceStamps()
165 all_got_revisions = build.getAllGotRevisions()
166 src_cxts = []
167 for ss in ss_list:
168 sc = {}
169 sc['codebase'] = ss.codebase
170 if (ss.branch is None and ss.revision is None and ss.patch is None
171 and not ss.changes):
172 sc['repository'] = None
173 sc['branch'] = None
174 sc['revision'] = "Latest revision"
175 else:
176 sc['repository'] = ss.repository
177 sc['branch'] = ss.branch
178 got_revision = all_got_revisions.get(ss.codebase, None)
179 if got_revision:
180 sc['revision'] = got_revision
181 else:
182 sc['revision'] = str(ss.revision)
183 if ss.patch:
184 sc['revision'] += " (plus patch)"
185 if ss.changes:
186 pass
187 src_cxts.append(sc)
188 res = build.getResults()
189 pageTitle = ('Builder "%s": %s' %
190 (build.getBuilder().getName(), results.Results[res]))
191
192
193 failed_steps = []
194 log_lines = []
195 for s in build.getSteps():
196 res = s.getResults()[0]
197 if res not in (results.SUCCESS, results.WARNINGS,
198 results.SKIPPED):
199 failed_steps.append(s.getName())
200
201
202 for log in s.getLogs():
203 log_lines.append('Last lines of build log "%s":' %
204 log.getName())
205 log_lines.append([])
206 try:
207 logdata = log.getText()
208 except IOError:
209
210 logdata ='** log file not available **'
211 unilist = list()
212 for line in logdata.split('\n')[-30:]:
213 unilist.append(unicode(line,'utf-8'))
214 log_lines.extend(unilist)
215
216 bc = {}
217 bc['sources'] = src_cxts
218 bc['date'] = rfc822_time(finishedTime)
219 bc['summary_link'] = ('%sbuilders/%s' %
220 (self.link,
221 build.getBuilder().getName()))
222 bc['name'] = build.getBuilder().getName()
223 bc['number'] = build.getNumber()
224 bc['responsible_users'] = build.getResponsibleUsers()
225 bc['failed_steps'] = failed_steps
226 bc['pageTitle'] = pageTitle
227 bc['link'] = link
228 bc['log_lines'] = log_lines
229
230 if finishedTime is not None:
231 bc['rfc822_pubdate'] = rfc822_time(finishedTime)
232 bc['rfc3339_pubdate'] = time.strftime("%Y-%m-%dT%H:%M:%SZ",
233 finishedTime)
234
235
236 guid = ('tag:%s@%s,%s:%s' %
237 (self.user, self.hostname,
238 time.strftime("%Y-%m-%d", finishedTime),
239 time.strftime("%Y%m%d%H%M%S", finishedTime)))
240 bc['guid'] = guid
241
242 build_cxts.append(bc)
243
244 pageTitle = self.pageTitle
245 if not pageTitle:
246 pageTitle = 'Build status of %s' % self.title
247
248 cxt = {}
249 cxt['pageTitle'] = pageTitle
250 cxt['title_url'] = self.link
251 cxt['title'] = self.title
252 cxt['language'] = self.language
253 cxt['description'] = self.description
254 if self.pubdate is not None:
255 cxt['rfc822_pubdate'] = rfc822_time( self.pubdate)
256 cxt['rfc3339_pubdate'] = time.strftime("%Y-%m-%dT%H:%M:%SZ",
257 self.pubdate)
258
259 cxt['builds'] = build_cxts
260 template = request.site.buildbot_service.templates.get_template(self.template_file)
261 return template.render(**cxt).encode('utf-8').strip()
262
269
271
272 template_file = 'feed_atom10.xml'
273
274 - def __init__(self, status, categories=None, pageTitle=None):
276