web-refactoring: get most of the Waterfall sub-pages working again
[buildbot.git] / buildbot / status / web / step.py
blobacc2acb49c77a1c4cd12ccb9769a1aaca700806c
2 from twisted.web.error import NoResource
3 from twisted.web import html
5 import urllib
6 from buildbot import interfaces
7 from buildbot.status.web.base import HtmlResource, IHTMLLog
8 from buildbot.status.web.logs import LogsResource
10 # builders/$builder/builds/$buildnum/steps/$stepname
11 class StatusResourceBuildStep(HtmlResource):
12 title = "Build Step"
14 def __init__(self, build_status, step_status):
15 HtmlResource.__init__(self)
16 self.status = build_status
17 self.step_status = step_status
19 def body(self, req):
20 s = self.step_status
21 b = s.getBuild()
22 builder_name = b.getBuilder().getName()
23 build_num = b.getNumber()
24 data = ""
25 data += ("<h1>BuildStep <a href=\"../../../../%s\">%s</a>:" %
26 (urllib.quote(builder_name), builder_name))
27 data += "<a href=\"../../%d\">#%d</a>" % (build_num, build_num)
28 data += ":%s</h1>\n" % s.getName()
30 if s.isFinished():
31 data += ("<h2>Finished</h2>\n"
32 "<p>%s</p>\n" % html.escape("%s" % s.getText()))
33 else:
34 data += ("<h2>Not Finished</h2>\n"
35 "<p>ETA %s seconds</p>\n" % s.getETA())
37 exp = s.getExpectations()
38 if exp:
39 data += ("<h2>Expectations</h2>\n"
40 "<ul>\n")
41 for e in exp:
42 data += "<li>%s: current=%s, target=%s</li>\n" % \
43 (html.escape(e[0]), e[1], e[2])
44 data += "</ul>\n"
45 logs = s.getLogs()
46 if logs:
47 data += ("<h2>Logs</h2>\n"
48 "<ul>\n")
49 for logfile in logs:
50 if logfile.hasContents():
51 # FIXME: If the step name has a / in it, this is broken
52 # either way. If we quote it but say '/'s are safe,
53 # it chops up the step name. If we quote it and '/'s
54 # are not safe, it escapes the / that separates the
55 # step name from the log number.
56 logname = logfile.getName()
57 logurl = req.childLink("logs/%s" % urllib.quote(logname))
58 data += ('<li><a href="%s">%s</a></li>\n' %
59 (logurl, html.escape(logname)))
60 else:
61 data += '<li>%s</li>\n' % html.escape(logname)
62 data += "</ul>\n"
64 return data
66 def getChild(self, path, req):
67 if path == "logs":
68 return LogsResource(self.step_status)
69 logname = path
70 try:
71 log = self.step.getLogs()[int(logname)]
72 if log.hasContents():
73 return IHTMLLog(interfaces.IStatusLog(log))
74 return NoResource("Empty Log '%s'" % logname)
75 except (IndexError, ValueError):
76 return NoResource("No such Log '%s'" % logname)
80 class StepsResource(HtmlResource):
81 def __init__(self, build_status):
82 HtmlResource.__init__(self)
83 self.build_status = build_status
85 def getChild(self, path, req):
86 for s in self.build_status.getSteps():
87 if s.getName() == path:
88 return StatusResourceBuildStep(self.build_status, s)
89 return NoResource("No such BuildStep '%s'" % path)