[Buildbot-devel] HTML Mail notifier
Andy Howell
AndyHowell at austin.rr.com
Sun Aug 1 08:35:10 UTC 2010
I was having problems making a an html mail formatter based on the one in the docs. That
one does not work as written. The 'changes' do not have a method asHTML.
I got the one below working. The utf-8 problems I was having with the GCC error messages
were solved by passing the logfile lines through unicode(line,'utf-8')
I think the log lines are coming from the BZ2File module. I couldn't find a way to set the
encoding there.
There is probably a better way to handle the unicode conversion, but this works.
I'm happy to make a patch to the docs with this if its deemed suitable.
Thanks,
Andy
def html_message_formatter(mode, name, build, results, master_status):
"""Provide a customized message to BuildBot's MailNotifier.
The last 300 lines of the log are provided as well as the changes
relevant to the build. Message content is formatted as html.
"""
result = Results[results]
limit_lines = 300
text = list()
text.append(u'<h4>Build status: %s</h4>' % result.upper())
text.append(u'<table cellspacing="10"><tr>')
text.append(u"<td>Buildslave for this Build:</td><td><b>%s</b></td></tr>" %
build.getSlavename())
if master_status.getURLForThing(build):
text.append(u'<tr><td>Complete logs for all build steps:</td><td><a
href="%s">%s</a></td></tr>'
% (master_status.getURLForThing(build),
master_status.getURLForThing(build))
)
text.append(u'<tr><td>Build Reason:</td><td>%s</td></tr>' % build.getReason())
source = u""
ss = build.getSourceStamp()
if ss.branch:
source += u"[branch %s] " % ss.branch
if ss.revision:
source += ss.revision
else:
source += u"HEAD"
if ss.patch:
source += u" (plus patch)"
text.append(u"<tr><td>Build Source Stamp:</td><td><b>%s</b></td></tr>" % source)
text.append(u"<tr><td>Blamelist:</td><td>%s</td></tr>" %
",".join(build.getResponsibleUsers()))
text.append(u'</table>')
if ss.changes:
text.append(u'<h4>Recent Changes:</h4>')
for c in ss.changes:
cd = c.asDict()
when = datetime.datetime.fromtimestamp(cd['when'] ).ctime()
text.append(u'<table cellspacing="10">')
text.append(u'<tr><td>Repository:</td><td>%s</td></tr>' % cd['repository'] )
text.append(u'<tr><td>Project:</td><td>%s</td></tr>' % cd['project'] )
text.append(u'<tr><td>Time:</td><td>%s</td></tr>' % when)
text.append(u'<tr><td>Changed by:</td><td>%s</td></tr>' % cd['who'] )
text.append(u'<tr><td>Comments:</td><td>%s</td></tr>' % cd['comments'] )
text.append(u'</table>')
files = cd['files']
if files:
text.append(u'<table cellspacing="10"><tr><th
align="left">Files</th><th>URL</th></tr>')
for file in files:
text.append(u'<tr><td>%s:</td><td>%s</td></tr>' % (file['name'],
file['url']))
text.append(u'</table>')
text.append(u'<br>')
# get log for last step
logs = build.getLogs()
# logs within a step are in reverse order. Search back until we find stdio
for log in reversed(logs):
if log.getName() == 'stdio':
break
name = "%s.%s" % (log.getStep().getName(), log.getName())
status, dummy = log.getStep().getResults()
content = log.getText().splitlines() # Note: can be VERY LARGE
url = u'%s/steps/%s/logs/%s' % (master_status.getURLForThing(build),
log.getStep().getName(),
log.getName())
text.append(u'<i>Detailed log of last build step:</i> <a href="%s">%s</a>'
% (url, url))
text.append(u'<br>')
text.append(u'<h4>Last %d lines of "%s"</h4>' % (limit_lines, name))
unilist = list()
for line in content[len(content)-limit_lines:]:
try:
unilist.append(cgi.escape(unicode(line,'utf-8')))
except:
unilist.append(hexdump(line,16))
text.append(u'<pre>'.join([uniline for uniline in unilist]))
text.append(u'</pre>')
text.append(u'<br><br>')
text.append(u'<b>-The BuildBot</b>')
return {
'body': u"\n".join(text),
'type': 'html'
}
More information about the devel
mailing list