| OLD | NEW |
| (Empty) |
| 1 | |
| 2 from twisted.web import html | |
| 3 | |
| 4 import urllib | |
| 5 from buildbot.status.web.base import HtmlResource, path_to_builder, \ | |
| 6 path_to_build | |
| 7 from buildbot.status.web.logs import LogsResource | |
| 8 from buildbot import util | |
| 9 from time import ctime | |
| 10 | |
| 11 # /builders/$builder/builds/$buildnum/steps/$stepname | |
| 12 class StatusResourceBuildStep(HtmlResource): | |
| 13 title = "Build Step" | |
| 14 addSlash = True | |
| 15 | |
| 16 def __init__(self, build_status, step_status): | |
| 17 HtmlResource.__init__(self) | |
| 18 self.status = build_status | |
| 19 self.step_status = step_status | |
| 20 | |
| 21 def body(self, req): | |
| 22 s = self.step_status | |
| 23 b = s.getBuild() | |
| 24 builder_name = b.getBuilder().getName() | |
| 25 build_num = b.getNumber() | |
| 26 data = "" | |
| 27 data += ('<h1>BuildStep <a href="%s">%s</a>:' % | |
| 28 (path_to_builder(req, b.getBuilder()), builder_name)) | |
| 29 data += '<a href="%s">#%d</a>' % (path_to_build(req, b), build_num) | |
| 30 data += ":%s</h1>\n" % s.getName() | |
| 31 | |
| 32 if s.isFinished(): | |
| 33 data += ("<h2>Finished</h2>\n" | |
| 34 "<p>%s</p>\n" % html.escape("%s" % s.getText())) | |
| 35 else: | |
| 36 data += ("<h2>Not Finished</h2>\n" | |
| 37 "<p>ETA %s seconds</p>\n" % s.getETA()) | |
| 38 | |
| 39 exp = s.getExpectations() | |
| 40 if exp: | |
| 41 data += ("<h2>Expectations</h2>\n" | |
| 42 "<ul>\n") | |
| 43 for e in exp: | |
| 44 data += "<li>%s: current=%s, target=%s</li>\n" % \ | |
| 45 (html.escape(e[0]), e[1], e[2]) | |
| 46 data += "</ul>\n" | |
| 47 | |
| 48 (start, end) = s.getTimes() | |
| 49 if not start: | |
| 50 start_text = end_text = elapsed = "Not Started" | |
| 51 else: | |
| 52 start_text = ctime(start) | |
| 53 if end: | |
| 54 end_text = ctime(end) | |
| 55 elapsed = util.formatInterval(end - start) | |
| 56 else: | |
| 57 end_text = "Not Finished" | |
| 58 elapsed = util.formatInterval(util.now() - start) | |
| 59 | |
| 60 data += "<h2>Timing</h2>\n" | |
| 61 data += "<table>\n" | |
| 62 data += "<tr><td>Start</td><td>%s</td></tr>\n" % start_text | |
| 63 data += "<tr><td>End</td><td>%s</td></tr>\n" % end_text | |
| 64 data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % elapsed | |
| 65 data += "</table>\n" | |
| 66 | |
| 67 logs = s.getLogs() | |
| 68 if logs: | |
| 69 data += ("<h2>Logs</h2>\n" | |
| 70 "<ul>\n") | |
| 71 for logfile in logs: | |
| 72 logname = logfile.getName() | |
| 73 if logfile.hasContents(): | |
| 74 # FIXME: If the step name has a / in it, this is broken | |
| 75 # either way. If we quote it but say '/'s are safe, | |
| 76 # it chops up the step name. If we quote it and '/'s | |
| 77 # are not safe, it escapes the / that separates the | |
| 78 # step name from the log number. | |
| 79 logurl = req.childLink("logs/%s" % urllib.quote(logname)) | |
| 80 data += ('<li><a href="%s">%s</a></li>\n' % | |
| 81 (logurl, html.escape(logname))) | |
| 82 else: | |
| 83 data += '<li>%s</li>\n' % html.escape(logname) | |
| 84 data += "</ul>\n" | |
| 85 | |
| 86 return data | |
| 87 | |
| 88 def getChild(self, path, req): | |
| 89 if path == "logs": | |
| 90 return LogsResource(self.step_status) | |
| 91 return HtmlResource.getChild(self, path, req) | |
| 92 | |
| 93 | |
| 94 | |
| 95 # /builders/$builder/builds/$buildnum/steps | |
| 96 class StepsResource(HtmlResource): | |
| 97 addSlash = True | |
| 98 | |
| 99 def __init__(self, build_status): | |
| 100 HtmlResource.__init__(self) | |
| 101 self.build_status = build_status | |
| 102 | |
| 103 def getChild(self, path, req): | |
| 104 for s in self.build_status.getSteps(): | |
| 105 if s.getName() == path: | |
| 106 return StatusResourceBuildStep(self.build_status, s) | |
| 107 return HtmlResource.getChild(self, path, req) | |
| OLD | NEW |