def body(self, req): b = self.build_status status = self.getStatus(req) projectURL = status.getProjectURL() projectName = status.getProjectName() data = ('<div class="title"><a href="%s">%s</a></div>\n' % (self.path_to_root(req), projectName)) builder_name = b.getBuilder().getName() data += ("<h1><a href=\"%s\">Builder %s</a>: Build #%d</h1>\n" % (path_to_builder(req, b.getBuilder()), builder_name, b.getNumber())) if not b.isFinished(): data += "<h2>Build In Progress</h2>" when = b.getETA() if when is not None: when_time = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) data += "<div>ETA %ds (%s)</div>\n" % (when, when_time) if self.build_control is not None: stopURL = urllib.quote(req.childLink("stop")) data += make_stop_form(stopURL, self.isUsingUserPasswd(req)) if b.isFinished(): # Results map loosely to css_classes results = b.getResults() data += "<h2>Results:</h2>\n" text = " ".join(b.getText()) data += '<span class="%s">%s</span>\n' % (css_classes[results], text) if b.getTestResults(): url = req.childLink("tests") data += "<h3><a href=\"%s\">test results</a></h3>\n" % url ss = b.getSourceStamp() data += "<h2>SourceStamp:</h2>\n" data += " <ul>\n" if ss.branch: data += " <li>Branch: %s</li>\n" % html.escape(ss.branch) if ss.revision: data += " <li>Revision: %s</li>\n" % html.escape(str(ss.revision)) if ss.patch: data += " <li>Patch: YES</li>\n" # TODO: provide link to .diff if ss.changes: data += " <li>Changes: see below</li>\n" if (ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes): data += " <li>build of most recent revision</li>\n" got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: got_revision = str(got_revision) if len(got_revision) > 40: got_revision = "[revision string too long]" data += " <li>Got Revision: %s</li>\n" % got_revision data += " </ul>\n" # TODO: turn this into a table, or some other sort of definition-list # that doesn't take up quite so much vertical space try: slaveurl = path_to_slave(req, status.getSlave(b.getSlavename())) data += "<h2>Buildslave:</h2>\n <a href=\"%s\">%s</a>\n" % (html.escape(slaveurl), html.escape(b.getSlavename())) except KeyError: data += "<h2>Buildslave:</h2>\n %s\n" % html.escape(b.getSlavename()) data += "<h2>Reason:</h2>\n%s\n" % html.escape(b.getReason()) data += "<h2>Steps and Logfiles:</h2>\n" # TODO: # urls = self.original.getURLs() # ex_url_class = "BuildStep external" # for name, target in urls.items(): # text.append('[<a href="%s" class="%s">%s</a>]' % # (target, ex_url_class, html.escape(name))) data += "<ol>\n" for s in b.getSteps(): name = s.getName() if s.isFinished(): css_class = css_classes[s.getResults()[0]] elif s.isStarted(): css_class = "running" else: css_class = "" data += (' <li><span class="%s"><a href=\"%s\">%s</a> [%s]</span>\n' % (css_class, req.childLink("steps/%s" % urllib.quote(name)), name, " ".join(s.getText()))) if s.getLogs(): data += " <ol>\n" for logfile in s.getLogs(): logname = logfile.getName() logurl = req.childLink("steps/%s/logs/%s" % (urllib.quote(name), urllib.quote(logname))) data += (" <li><a href=\"%s\">%s</a></li>\n" % (logurl, logfile.getName())) data += " </ol>\n" data += " </li>\n" data += "</ol>\n" data += "<h2>Build Properties:</h2>\n" data += "<table><tr><th valign=\"left\">Name</th><th valign=\"left\">Value</th><th valign=\"left\">Source</th></tr>\n" for name, value, source in b.getProperties().asList(): value = str(value) if len(value) > 500: value = value[:500] + " .. [property value too long]" data += "<tr>" data += "<td>%s</td>" % html.escape(name) data += "<td>%s</td>" % html.escape(value) data += "<td>%s</td>" % html.escape(source) data += "</tr>\n" data += "</table>" data += "<h2>Blamelist:</h2>\n" if list(b.getResponsibleUsers()): data += " <ol>\n" for who in b.getResponsibleUsers(): data += " <li>%s</li>\n" % html.escape(who) data += " </ol>\n" else: data += "<div>no responsible users</div>\n" (start, end) = b.getTimes() data += "<h2>Timing</h2>\n" data += "<table>\n" data += "<tr><td>Start</td><td>%s</td></tr>\n" % time.ctime(start) if end: data += "<tr><td>End</td><td>%s</td></tr>\n" % time.ctime(end) data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % util.formatInterval(end - start) data += "</table>\n" if ss.changes: data += "<h2>All Changes</h2>\n" data += "<ol>\n" for c in ss.changes: data += "<li>" + c.asHTML() + "</li>\n" data += "</ol>\n" #data += html.PRE(b.changesText()) # TODO if b.isFinished() and self.builder_control is not None: data += "<h3>Resubmit Build:</h3>\n" # can we rebuild it exactly? exactly = (ss.revision is not None) or b.getChanges() if exactly: data += ("<p>This tree was built from a specific set of \n" "source files, and can be rebuilt exactly</p>\n") else: data += ("<p>This tree was built from the most recent " "revision") if ss.branch: data += " (along some branch)" data += (" and thus it might not be possible to rebuild it \n" "exactly. Any changes that have been committed \n" "after this build was started <b>will</b> be \n" "included in a rebuild.</p>\n") rebuildURL = urllib.quote(req.childLink("rebuild")) data += ('<form action="%s" class="command rebuild">\n' % rebuildURL) data += make_name_user_passwd_form(self.isUsingUserPasswd(req)) data += make_row("Reason for re-running build:", "<input type='text' name='comments' />") data += '<input type="submit" value="Rebuild" />\n' data += '</form>\n' # TODO: this stuff should be generated by a template of some sort data += '<hr /><div class="footer">\n' welcomeurl = self.path_to_root(req) + "index.html" data += '[<a href="%s">welcome</a>]\n' % welcomeurl data += "<br />\n" data += '<a href="http://buildbot.sourceforge.net/">Buildbot</a>' data += "-%s " % version if projectName: data += "working for the " if projectURL: data += "<a href=\"%s\">%s</a> project." % (projectURL, projectName) else: data += "%s project." % projectName data += "<br />\n" data += ("Page built: " + time.strftime("%a %d %b %Y %H:%M:%S", time.localtime(util.now())) + "\n") data += '</div>\n' return data
def body(self, req): """ Overriden method from builders.StatusResourceBuilder. The only change in original behavior is added new checkbox for clobbering.""" b = self.builder_status control = self.builder_control status = self.getStatus(req) slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] projectName = status.getProjectName() data = '<a href="%s">%s</a>\n' % (self.path_to_root(req), projectName) data += ('<h1><a href="%swaterfall?builder=%s">Builder: %s</a></h1>\n' % (self.path_to_root(req), urllib.quote(b.getName(), safe=''), html.escape(b.getName()))) # the first section shows builds which are currently running, if any. current = b.getCurrentBuilds() if current: data += "<h2>Currently Building:</h2>\n" data += "<ul>\n" for build in current: data += " <li>" + self.build_line(build, req) + "</li>\n" data += "</ul>\n" else: data += "<h2>no current builds</h2>\n" # Then a section with the last 5 builds, with the most recent build # distinguished from the rest. data += "<h2>Recent Builds:</h2>\n" data += "<ul>\n" for i, build in enumerate(b.generateFinishedBuilds(num_builds=5)): data += " <li>" + self.make_line(req, build, False) + "</li>\n" if i == 0: data += "<br />\n" # separator # TODO: or empty list? data += "</ul>\n" data += "<h2>Buildslaves:</h2>\n" data += "<ol>\n" for slave in slaves: name = slave.getName() if not name: name = '' data += "<li><b>%s</b>: " % html.escape(name) if slave.isConnected(): data += "CONNECTED\n" if slave.getAdmin(): data += make_row("Admin:", html.escape(slave.getAdmin())) if slave.getHost(): data += "<span class='label'>Host info:</span>\n" data += html.PRE(slave.getHost()) else: data += ("NOT CONNECTED\n") data += "</li>\n" data += "</ol>\n" if control is not None and connected_slaves: forceURL = urllib.quote(req.childLink("force")) data += ( """ <form action='%(forceURL)s' class='command forcebuild'> <p>To force a build, fill out the following fields and push the 'Force Build' button</p> <table> <tr class='row' valign="bottom"> <td> <span class="label">Your name<br> (<span style="color: red;">please fill in at least this much</span>):</span> </td> <td> <span class="field"><input type='text' name='username' /></span> </td> </tr> <tr class='row'> <td> <span class="label">Reason for build:</span> </td> <td> <span class="field"><input type='text' name='comments' /></span> </td> </tr> <tr class='row'> <td> <span class="label">Branch to build:</span> </td> <td> <span class="field"><input type='text' name='branch' /></span> </td> </tr> <tr class='row'> <td> <span class="label">Revision to build:</span> </td> <td> <span class="field"><input type='text' name='revision' /></span> </td> </tr> <tr class='row'> <td> <span class="label">Slave to use:</span> </td> <td> <span class="field"><input type='text' name='slavename' /></span> </td> </tr> <tr class='row'> <td> <span class="label">Clobber:</span> </td> <td> <span class="field"><input type='checkbox' name='clobber' /> </span> </td> </tr> </table> <input type='submit' value='Force Build' /> </form> """) % {"forceURL": forceURL} elif control is not None: data += """ <p>All buildslaves appear to be offline, so it's not possible to force this build to execute at this time.</p> """ if control is not None: pingURL = urllib.quote(req.childLink("ping")) data += """ <form action="%s" class='command pingbuilder'> <p>To ping the buildslave(s), push the 'Ping' button</p> <input type="submit" value="Ping Builder" /> </form> """ % pingURL return data
def body(self, req): b = self.builder_status control = self.builder_control status = self.getStatus(req) slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] projectName = status.getProjectName() data = '<a href="%s">%s</a>\n' % (self.path_to_root(req), projectName) data += "<h1>Builder: %s</h1>\n" % html.escape(b.getName()) # the first section shows builds which are currently running, if any. current = b.getCurrentBuilds() if current: data += "<h2>Currently Building:</h2>\n" data += "<ul>\n" for build in current: data += " <li>" + self.build_line(build, req) + "</li>\n" data += "</ul>\n" else: data += "<h2>no current builds</h2>\n" # Then a section with the last 5 builds, with the most recent build # distinguished from the rest. data += "<h2>Recent Builds:</h2>\n" data += "<ul>\n" for i,build in enumerate(b.generateFinishedBuilds(num_builds=5)): data += " <li>" + self.make_line(req, build, False) + "</li>\n" if i == 0: data += "<br />\n" # separator # TODO: or empty list? data += "</ul>\n" data += "<h2>Buildslaves:</h2>\n" data += "<ol>\n" for slave in slaves: data += "<li><b>%s</b>: " % html.escape(slave.getName()) if slave.isConnected(): data += "CONNECTED\n" if slave.getAdmin(): data += make_row("Admin:", html.escape(slave.getAdmin())) if slave.getHost(): data += "<span class='label'>Host info:</span>\n" data += html.PRE(slave.getHost()) else: data += ("NOT CONNECTED\n") data += "</li>\n" data += "</ol>\n" if control is not None and connected_slaves: forceURL = urllib.quote(req.childLink("force")) data += make_force_build_form(forceURL) elif control is not None: data += """ <p>All buildslaves appear to be offline, so it's not possible to force this build to execute at this time.</p> """ if control is not None: pingURL = urllib.quote(req.childLink("ping")) data += """ <form action="%s" class='command pingbuilder'> <p>To ping the buildslave(s), push the 'Ping' button</p> <input type="submit" value="Ping Builder" /> </form> """ % pingURL return data
def body(self, req): b = self.builder_status control = self.builder_control status = self.getStatus(req) slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] projectName = status.getProjectName() data = '<a href="%s">%s</a>\n' % (self.path_to_root(req), projectName) data += "<h1>Builder: %s</h1>\n" % html.escape(b.getName()) # the first section shows builds which are currently running, if any. current = b.getCurrentBuilds() if current: data += "<h2>Currently Building:</h2>\n" data += "<ul>\n" for build in current: data += " <li>" + self.build_line(build, req) + "</li>\n" data += "</ul>\n" else: data += "<h2>no current builds</h2>\n" # Then a section with the last 5 builds, with the most recent build # distinguished from the rest. data += "<h2>Recent Builds:</h2>\n" data += "<ul>\n" for i, build in enumerate(b.generateFinishedBuilds(num_builds=5)): data += " <li>" + self.make_line(req, build, False) + "</li>\n" if i == 0: data += "<br />\n" # separator # TODO: or empty list? data += "</ul>\n" data += "<h2>Buildslaves:</h2>\n" data += "<ol>\n" for slave in slaves: slaveurl = path_to_slave(req, slave) data += "<li><b><a href=\"%s\">%s</a></b>: " % ( html.escape(slaveurl), html.escape(slave.getName())) if slave.isConnected(): data += "CONNECTED\n" if slave.getAdmin(): data += make_row("Admin:", html.escape(slave.getAdmin())) if slave.getHost(): data += "<span class='label'>Host info:</span>\n" data += html.PRE(slave.getHost()) else: data += ("NOT CONNECTED\n") data += "</li>\n" data += "</ol>\n" if control is not None and connected_slaves: forceURL = urllib.quote(req.childLink("force")) data += make_force_build_form(forceURL) elif control is not None: data += """ <p>All buildslaves appear to be offline, so it's not possible to force this build to execute at this time.</p> """ if control is not None: pingURL = urllib.quote(req.childLink("ping")) data += """ <form action="%s" class='command pingbuilder'> <p>To ping the buildslave(s), push the 'Ping' button</p> <input type="submit" value="Ping Builder" /> </form> """ % pingURL # TODO: this stuff should be generated by a template of some sort projectURL = status.getProjectURL() projectName = status.getProjectName() data += '<hr /><div class="footer">\n' welcomeurl = self.path_to_root(req) + "index.html" data += '[<a href="%s">welcome</a>]\n' % welcomeurl data += "<br />\n" data += '<a href="http://buildbot.sourceforge.net/">Buildbot</a>' data += "-%s " % version if projectName: data += "working for the " if projectURL: data += "<a href=\"%s\">%s</a> project." % (projectURL, projectName) else: data += "%s project." % projectName data += "<br />\n" data += ("Page built: " + time.strftime( "%a %d %b %Y %H:%M:%S", time.localtime(util.now())) + "\n") data += '</div>\n' return data
def body(self, req): b = self.build_status status = self.getStatus(req) projectURL = status.getProjectURL() projectName = status.getProjectName() data = '' if not b.isFinished(): data += '<h2>Build In Progress</h2>' when = b.getETA() if when is not None: when_time = time.strftime('%H:%M:%S', time.localtime(time.time() + when)) data += '<div>ETA %ds (%s)</div>\n' % (when, when_time) if self.build_control is not None: stopURL = urllib.quote(req.childLink("stop")) data += make_stop_form(stopURL, self.isUsingUserPasswd(req)) if b.isFinished(): results = b.getResults() data += "<h2>Results: " text = " ".join(b.getText()) data += '<span class="%s">%s</span>' % (css_classes[results], text) data += '</h2>\n' if b.getTestResults(): url = req.childLink("tests") data += "<h3><a href=\"%s\">test results</a></h3>\n" % url data += '<ul>\n' ss = b.getSourceStamp() data += " <li>SourceStamp: " data += " <ul>\n" if ss.branch: data += " <li>Branch: %s</li>\n" % html.escape(ss.branch) if ss.revision: data += " <li>Revision: %s</li>\n" % html.escape(str(ss.revision)) if ss.patch: data += " <li>Patch: YES</li>\n" # TODO: provide link to .diff if ss.changes: data += " <li>Changes: see below</li>\n" if (ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes): data += " <li>build of most recent revision</li>\n" got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: got_revision = str(got_revision) if len(got_revision) > 40: got_revision = "[revision string too long]" data += " <li>Got Revision: %s</li>\n" % got_revision data += " </ul>\n" data += "<li>Buildslave: %s</li>\n" % html.escape(b.getSlavename()) data += "<li>Reason: %s</li>\n" % html.escape(b.getReason()) if b.getLogs(): data += "<li>Steps and Logfiles:\n" data += "<ol>\n" for s in b.getSteps(): name = s.getName() data += (" <li><a href=\"%s\">%s</a> [%s]\n" % (req.childLink("steps/%s" % urllib.quote(name)), name, " ".join(s.getText()))) if s.getLogs(): data += " <ul>\n" for logfile in s.getLogs(): logname = logfile.getName() logurl = req.childLink("steps/%s/logs/%s" % (urllib.quote(name), urllib.quote(logname))) data += (" <li><a href=\"%s\">%s</a></li>\n" % (logurl, logfile.getName())) data += " </ul>\n" data += " </li>\n" data += "</ol>\n" data += "</li>\n" data += "<li>Blamelist: " if list(b.getResponsibleUsers()): data += " <ol>\n" for who in b.getResponsibleUsers(): data += " <li>%s</li>\n" % html.escape(who) data += " </ol>\n" else: data += "no responsible users\n" data += '</li>' if ss.changes: data += "<li>All changes\n" data += "<ol>\n" for c in ss.changes: data += '<li class="changeset">' + c.asHTML() + '</li>\n' data += "</ol></li>\n" data += '</ul>' if b.isFinished() and self.builder_control is not None: data += "<h3>Resubmit Build:</h3>\n" # can we rebuild it exactly? exactly = (ss.revision is not None) or b.getChanges() if exactly: data += ("<p>This tree was built from a specific set of \n" "source files, and can be rebuilt exactly</p>\n") else: data += ("<p>This tree was built from the most recent " "revision") if ss.branch: data += " (along some branch)" data += (" and thus it might not be possible to rebuild it \n" "exactly. Any changes that have been committed \n" "after this build was started <b>will</b> be \n" "included in a rebuild.</p>\n") rebuildURL = urllib.quote(req.childLink("rebuild")) data += ('<form method="post" action="%s" class="command rebuild">\n' % rebuildURL) data += make_name_user_passwd_form(self.isUsingUserPasswd(req)) data += make_row("Reason for re-running build:", "<input type='text' name='comments' />") data += '<input type="submit" value="Rebuild" />\n' data += '</form>\n' data += '</div>\n' return data
def body(self, req): b = self.build_status status = self.getStatus(req) projectURL = status.getProjectURL() projectName = status.getProjectName() data = '' if not b.isFinished(): data += '<h2>Build In Progress</h2>' when = b.getETA() if when is not None: when_time = time.strftime('%H:%M:%S', time.localtime(time.time() + when)) data += '<div>ETA %ds (%s)</div>\n' % (when, when_time) if self.build_control is not None: stopURL = urllib.quote(req.childLink("stop")) data += make_stop_form(stopURL, self.isUsingUserPasswd(req)) if b.isFinished(): results = b.getResults() data += "<h2>Results: " text = " ".join(b.getText()) data += '<span class="%s">%s</span>' % (css_classes[results], text) data += '</h2>\n' if b.getTestResults(): url = req.childLink("tests") data += "<h3><a href=\"%s\">test results</a></h3>\n" % url data += '<ul>\n' ss = b.getSourceStamp() data += " <li>SourceStamp: " data += " <ul>\n" if ss.branch: data += " <li>Branch: %s</li>\n" % html.escape(ss.branch) if ss.revision: data += " <li>Revision: %s</li>\n" % html.escape(str(ss.revision)) if ss.patch: data += " <li>Patch: YES</li>\n" # TODO: provide link to .diff if ss.changes: data += " <li>Changes: see below</li>\n" if (ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes): data += " <li>build of most recent revision</li>\n" got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: got_revision = str(got_revision) if len(got_revision) > 40: got_revision = "[revision string too long]" data += " <li>Got Revision: %s</li>\n" % got_revision data += " </ul>\n" data += "<li>Buildslave: %s</li>\n" % html.escape(b.getSlavename()) data += "<li>Reason: %s</li>\n" % html.escape(b.getReason()) if b.getLogs(): data += "<li>Steps and Logfiles:\n" data += "<ol>\n" for s in b.getSteps(): name = s.getName() data += (" <li><a href=\"%s\">%s</a> [%s]\n" % (req.childLink("steps/%s" % urllib.quote(name)), name, " ".join(s.getText()))) if s.getLogs(): data += " <ul>\n" for logfile in s.getLogs(): logname = logfile.getName() logurl = req.childLink( "steps/%s/logs/%s" % (urllib.quote(name), urllib.quote(logname))) data += (" <li><a href=\"%s\">%s</a></li>\n" % (logurl, logfile.getName())) data += " </ul>\n" data += " </li>\n" data += "</ol>\n" data += "</li>\n" data += "<li>Blamelist: " if list(b.getResponsibleUsers()): data += " <ol>\n" for who in b.getResponsibleUsers(): data += " <li>%s</li>\n" % html.escape(who) data += " </ol>\n" else: data += "no responsible users\n" data += '</li>' if ss.changes: data += "<li>All changes\n" data += "<ol>\n" for c in ss.changes: data += '<li class="changeset">' + c.asHTML() + '</li>\n' data += "</ol></li>\n" data += '</ul>' if b.isFinished() and self.builder_control is not None: data += "<h3>Resubmit Build:</h3>\n" # can we rebuild it exactly? exactly = (ss.revision is not None) or b.getChanges() if exactly: data += ("<p>This tree was built from a specific set of \n" "source files, and can be rebuilt exactly</p>\n") else: data += ("<p>This tree was built from the most recent " "revision") if ss.branch: data += " (along some branch)" data += (" and thus it might not be possible to rebuild it \n" "exactly. Any changes that have been committed \n" "after this build was started <b>will</b> be \n" "included in a rebuild.</p>\n") rebuildURL = urllib.quote(req.childLink("rebuild")) data += ( '<form method="post" action="%s" class="command rebuild">\n' % rebuildURL) data += make_name_user_passwd_form(self.isUsingUserPasswd(req)) data += make_row("Reason for re-running build:", "<input type='text' name='comments' />") data += '<input type="submit" value="Rebuild" />\n' data += '</form>\n' data += '</div>\n' return data
def body(self, req): b = self.builder_status control = self.builder_control status = self.getStatus(req) slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] projectName = status.getProjectName() data = '' # the first section shows builds which are currently running, if any. current = b.getCurrentBuilds() if current: data += "<h2>Currently Building:</h2>\n" data += "<ul>\n" for build in current: data += " <li>" + self.build_line(build, req) + "</li>\n" data += "</ul>\n" else: data += "<h2>No current builds</h2>\n" # Then a section with the last 5 builds, with the most recent build # distinguished from the rest. data += "<h2>Recent Builds</h2>\n" data += "<ul>\n" numbuilds = int(req.args.get('numbuilds', ['5'])[0]) for i, build in enumerate( b.generateFinishedBuilds(num_builds=int(numbuilds))): data += " <li>" + self.make_line(req, build, False) + "</li>\n" if i == 0: data += "<br />\n" # separator # TODO: or empty list? data += "</ul>\n" data += "<h2>Buildslaves:</h2>\n" data += "<ol>\n" for slave in slaves: slaveurl = path_to_slave(req, slave) data += "<li><b><a href=\"%s\">%s</a></b>: " % ( html.escape(slaveurl), html.escape(slave.getName())) if slave.isConnected(): data += "CONNECTED\n" if slave.getAdmin(): data += make_row("Admin:", html.escape(slave.getAdmin())) if slave.getHost(): data += "<span class='label'>Host info:</span>\n" data += html.PRE(html.escape(slave.getHost())) else: data += ("NOT CONNECTED\n") data += "</li>\n" data += "</ol>\n" if control is not None and connected_slaves: forceURL = path_to_builder(req, b) + '/force' data += make_force_build_form(forceURL, self.isUsingUserPasswd(req)) elif control is not None: data += """ <p>All buildslaves appear to be offline, so it's not possible to force this build to execute at this time.</p> """ if control is not None: pingURL = path_to_builder(req, b) + '/ping' data += """ <form method="post" action="%s" class='command pingbuilder'> <p>To ping the buildslave(s), push the 'Ping' button</p> <input type="submit" value="Ping Builder" /> </form> """ % pingURL return data
def body(self, req): b = self.build_status status = self.getStatus(req) projectURL = status.getProjectURL() projectName = status.getProjectName() data = ('<div class="title"><a href="%s">%s</a></div>\n' % (self.path_to_root(req), projectName)) builder_name = b.getBuilder().getName() data += ("<h1><a href=\"%s\">Builder %s</a>: Build #%d</h1>\n" % (path_to_builder( req, b.getBuilder()), builder_name, b.getNumber())) if not b.isFinished(): data += "<h2>Build In Progress</h2>" when = b.getETA() if when is not None: when_time = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) data += "<div>ETA %ds (%s)</div>\n" % (when, when_time) if self.build_control is not None: stopURL = urllib.quote(req.childLink("stop")) data += make_stop_form(stopURL) if b.isFinished(): results = b.getResults() data += "<h2>Results:</h2>\n" text = " ".join(b.getText()) data += '<span class="%s">%s</span>\n' % (css_classes[results], text) if b.getTestResults(): url = req.childLink("tests") data += "<h3><a href=\"%s\">test results</a></h3>\n" % url ss = b.getSourceStamp() data += "<h2>SourceStamp:</h2>\n" data += " <ul>\n" if ss.branch: data += " <li>Branch: %s</li>\n" % html.escape(ss.branch) if ss.revision: data += " <li>Revision: %s</li>\n" % html.escape(str(ss.revision)) if ss.patch: data += " <li>Patch: YES</li>\n" # TODO: provide link to .diff if ss.changes: data += " <li>Changes: see below</li>\n" if (ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes): data += " <li>build of most recent revision</li>\n" got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: got_revision = str(got_revision) if len(got_revision) > 40: got_revision = "[revision string too long]" data += " <li>Got Revision: %s</li>\n" % got_revision data += " </ul>\n" # TODO: turn this into a table, or some other sort of definition-list # that doesn't take up quite so much vertical space try: slaveurl = path_to_slave(req, status.getSlave(b.getSlavename())) data += "<h2>Buildslave:</h2>\n <a href=\"%s\">%s</a>\n" % ( html.escape(slaveurl), html.escape(b.getSlavename())) except KeyError: data += "<h2>Buildslave:</h2>\n %s\n" % html.escape( b.getSlavename()) data += "<h2>Reason:</h2>\n%s\n" % html.escape(b.getReason()) data += "<h2>Steps and Logfiles:</h2>\n" # TODO: # urls = self.original.getURLs() # ex_url_class = "BuildStep external" # for name, target in urls.items(): # text.append('[<a href="%s" class="%s">%s</a>]' % # (target, ex_url_class, html.escape(name))) if b.getLogs(): # track time firsttime = time.time() lasttime = 0 data += "<ol>\n" for s in b.getSteps(): name = s.getName() (started, finished) = s.getTimes() if started == None: eltime = "not started yet..." else: firsttime = min(firsttime, started) if finished == None: lasttime = max(lasttime, time.time()) eltime = "current running time..." + self.formatTime( time.time() - started) else: lasttime = max(lasttime, finished) eltime = "total time..." + self.formatTime(finished - started) data += (" <li><a href=\"%s\">%s</a> [%s] %s\n" % (req.childLink("steps/%s" % urllib.quote(name)), name, " ".join(s.getText()), eltime)) if s.getLogs(): data += " <ol>\n" for logfile in s.getLogs(): logname = logfile.getName() logurl = req.childLink( "steps/%s/logs/%s" % (urllib.quote(name), urllib.quote(logname))) data += (" <li><a href=\"%s\">%s</a></li>\n" % (logurl, logfile.getName())) data += " </ol>\n" data += " </li>\n" data += "</ol>\n" data += "total elapsed time: " + self.formatTime(lasttime - firsttime) data += "<h2>Build Properties:</h2>\n" data += "<table><tr><th valign=\"left\">Name</th><th valign=\"left\">Value</th><th valign=\"left\">Source</th></tr>\n" for name, value, source in b.getProperties().asList(): value = str(value) if len(value) > 500: value = value[:500] + " .. [property value too long]" data += "<tr>" data += "<td>%s</td>" % html.escape(name) data += "<td>%s</td>" % html.escape(value) data += "<td>%s</td>" % html.escape(source) data += "</tr>\n" data += "</table>" data += "<h2>Blamelist:</h2>\n" if list(b.getResponsibleUsers()): data += " <ol>\n" for who in b.getResponsibleUsers(): data += " <li>%s</li>\n" % html.escape(who) data += " </ol>\n" else: data += "<div>no responsible users</div>\n" (start, end) = b.getTimes() data += "<h2>Timing</h2>\n" data += "<table>\n" data += "<tr><td>Start</td><td>%s</td></tr>\n" % time.ctime(start) if end: data += "<tr><td>End</td><td>%s</td></tr>\n" % time.ctime(end) data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % util.formatInterval( end - start) data += "</table>\n" if ss.changes: data += "<h2>All Changes</h2>\n" data += "<ol>\n" for c in ss.changes: data += "<li>" + c.asHTML() + "</li>\n" data += "</ol>\n" #data += html.PRE(b.changesText()) # TODO if b.isFinished() and self.builder_control is not None: data += "<h3>Resubmit Build:</h3>\n" # can we rebuild it exactly? exactly = (ss.revision is not None) or b.getChanges() if exactly: data += ("<p>This tree was built from a specific set of \n" "source files, and can be rebuilt exactly</p>\n") else: data += ("<p>This tree was built from the most recent " "revision") if ss.branch: data += " (along some branch)" data += (" and thus it might not be possible to rebuild it \n" "exactly. Any changes that have been committed \n" "after this build was started <b>will</b> be \n" "included in a rebuild.</p>\n") rebuildURL = urllib.quote(req.childLink("rebuild")) data += ('<form action="%s" class="command rebuild">\n' % rebuildURL) data += make_row("Your name:", "<input type='text' name='username' />") data += make_row("Reason for re-running build:", "<input type='text' name='comments' />") data += '<input type="submit" value="Rebuild" />\n' data += '</form>\n' # TODO: this stuff should be generated by a template of some sort data += '<hr /><div class="footer">\n' welcomeurl = self.path_to_root(req) + "index.html" data += '[<a href="%s">welcome</a>]\n' % welcomeurl data += "<br />\n" data += '<a href="http://buildbot.sourceforge.net/">Buildbot</a>' data += "-%s " % version if projectName: data += "working for the " if projectURL: data += "<a href=\"%s\">%s</a> project." % (projectURL, projectName) else: data += "%s project." % projectName data += "<br />\n" data += ("Page built: " + time.strftime( "%a %d %b %Y %H:%M:%S", time.localtime(util.now())) + "\n") data += '</div>\n' return data
def body(self, req): b = self.builder_status control = self.builder_control status = self.getStatus(req) slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] projectName = status.getProjectName() data = '<a href="%s">%s</a>\n' % (self.path_to_root(req), projectName) data += "<h1>Builder: %s</h1>\n" % html.escape(b.getName()) # the first section shows builds which are currently running, if any. current = b.getCurrentBuilds() if current: data += "<h2>Currently Building:</h2>\n" data += "<ul>\n" for build in current: data += " <li>" + self.build_line(build, req) + "</li>\n" data += "</ul>\n" else: data += "<h2>no current builds</h2>\n" # Then a section with the last 5 builds, with the most recent build # distinguished from the rest. data += "<h2>Recent Builds:</h2>\n" data += "<ul>\n" for i,build in enumerate(b.generateFinishedBuilds(num_builds=5)): data += " <li>" + self.make_line(req, build, False) + "</li>\n" if i == 0: data += "<br />\n" # separator # TODO: or empty list? data += "</ul>\n" data += "<h2>Buildslaves:</h2>\n" data += "<ol>\n" for slave in slaves: slaveurl = path_to_slave(req, slave) data += "<li><b><a href=\"%s\">%s</a></b>: " % (html.escape(slaveurl), html.escape(slave.getName())) if slave.isConnected(): data += "CONNECTED\n" if slave.getAdmin(): data += make_row("Admin:", html.escape(slave.getAdmin())) if slave.getHost(): data += "<span class='label'>Host info:</span>\n" data += html.PRE(slave.getHost()) else: data += ("NOT CONNECTED\n") data += "</li>\n" data += "</ol>\n" if control is not None and connected_slaves: forceURL = urllib.quote(req.childLink("force")) data += make_force_build_form(forceURL) elif control is not None: data += """ <p>All buildslaves appear to be offline, so it's not possible to force this build to execute at this time.</p> """ if control is not None: pingURL = urllib.quote(req.childLink("ping")) data += """ <form action="%s" class='command pingbuilder'> <p>To ping the buildslave(s), push the 'Ping' button</p> <input type="submit" value="Ping Builder" /> </form> """ % pingURL # TODO: this stuff should be generated by a template of some sort projectURL = status.getProjectURL() projectName = status.getProjectName() data += '<hr /><div class="footer">\n' welcomeurl = self.path_to_root(req) + "index.html" data += '[<a href="%s">welcome</a>]\n' % welcomeurl data += "<br />\n" data += '<a href="http://buildbot.sourceforge.net/">Buildbot</a>' data += "-%s " % version if projectName: data += "working for the " if projectURL: data += "<a href=\"%s\">%s</a> project." % (projectURL, projectName) else: data += "%s project." % projectName data += "<br />\n" data += ("Page built: " + time.strftime("%a %d %b %Y %H:%M:%S", time.localtime(util.now())) + "\n") data += '</div>\n' return data
def body(self, req): b = self.build_status status = self.getStatus(req) projectName = status.getProjectName() data = ('<div class="title"><a href="%s">%s</a></div>\n' % (self.path_to_root(req), projectName)) # the color in the following line gives python-mode trouble builder_name = b.getBuilder().getName() data += ("<h1><a href=\"%s\">Builder %s</a>: Build #%d</h1>\n" % (path_to_builder(req, b.getBuilder()), builder_name, b.getNumber())) if not b.isFinished(): data += "<h2>Build In Progress</h2>" when = b.getETA() if when is not None: when_time = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) data += "<div>ETA %ds (%s)</div>\n" % (when, when_time) if self.build_control is not None: stopURL = urllib.quote(req.childLink("stop")) data += make_stop_form(stopURL) if b.isFinished(): results = b.getResults() data += "<h2>Results:</h2>\n" text = " ".join(b.getText()) data += '<span class="%s">%s</span>\n' % (css_classes[results], text) if b.getTestResults(): url = req.childLink("tests") data += "<h3><a href=\"%s\">test results</a></h3>\n" % url ss = b.getSourceStamp() data += "<h2>SourceStamp:</h2>\n" data += " <ul>\n" if ss.branch: data += " <li>Branch: %s</li>\n" % html.escape(ss.branch) if ss.revision: data += " <li>Revision: %s</li>\n" % html.escape(str(ss.revision)) if ss.patch: data += " <li>Patch: YES</li>\n" # TODO: provide link to .diff if ss.changes: data += " <li>Changes: see below</li>\n" if (ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes): data += " <li>build of most recent revision</li>\n" got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: got_revision = str(got_revision) if len(got_revision) > 40: got_revision = "[revision string too long]" data += " <li>Got Revision: %s</li>\n" % got_revision data += " </ul>\n" # TODO: turn this into a table, or some other sort of definition-list # that doesn't take up quite so much vertical space data += "<h2>Buildslave:</h2>\n %s\n" % html.escape(b.getSlavename()) data += "<h2>Reason:</h2>\n%s\n" % html.escape(b.getReason()) data += "<h2>Steps and Logfiles:</h2>\n" # TODO: # urls = self.original.getURLs() # ex_url_class = "BuildStep external" # for name, target in urls.items(): # text.append('[<a href="%s" class="%s">%s</a>]' % # (target, ex_url_class, html.escape(name))) if b.getLogs(): data += "<ol>\n" for s in b.getSteps(): name = s.getName() data += (" <li><a href=\"%s\">%s</a> [%s]\n" % (req.childLink("steps/%s" % urllib.quote(name)), name, " ".join(s.getText()))) if s.getLogs(): data += " <ol>\n" for logfile in s.getLogs(): logname = logfile.getName() logurl = req.childLink("steps/%s/logs/%s" % (urllib.quote(name), urllib.quote(logname))) data += (" <li><a href=\"%s\">%s</a></li>\n" % (logurl, logfile.getName())) data += " </ol>\n" data += " </li>\n" data += "</ol>\n" data += "<h2>Blamelist:</h2>\n" if list(b.getResponsibleUsers()): data += " <ol>\n" for who in b.getResponsibleUsers(): data += " <li>%s</li>\n" % html.escape(who) data += " </ol>\n" else: data += "<div>no responsible users</div>\n" if ss.changes: data += "<h2>All Changes</h2>\n" data += "<ol>\n" for c in ss.changes: data += "<li>" + c.asHTML() + "</li>\n" data += "</ol>\n" #data += html.PRE(b.changesText()) # TODO if b.isFinished() and self.builder_control is not None: data += "<h3>Resubmit Build:</h3>\n" # can we rebuild it exactly? exactly = (ss.revision is not None) or b.getChanges() if exactly: data += ("<p>This tree was built from a specific set of \n" "source files, and can be rebuilt exactly</p>\n") else: data += ("<p>This tree was built from the most recent " "revision") if ss.branch: data += " (along some branch)" data += (" and thus it might not be possible to rebuild it \n" "exactly. Any changes that have been committed \n" "after this build was started <b>will</b> be \n" "included in a rebuild.</p>\n") rebuildURL = urllib.quote(req.childLink("rebuild")) data += ('<form action="%s" class="command rebuild">\n' % rebuildURL) data += make_row("Your name:", "<input type='text' name='username' />") data += make_row("Reason for re-running build:", "<input type='text' name='comments' />") data += '<input type="submit" value="Rebuild" />\n' data += '</form>\n' return data
def body(self, req): """ Overriden method from builders.StatusResourceBuilder. The only change in original behavior is added new checkbox for clobbering.""" b = self.builder_status control = self.builder_control status = self.getStatus(req) slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] projectName = status.getProjectName() data = '<a href="%s">%s</a>\n' % (self.path_to_root(req), projectName) data += ( '<h1><a href="%swaterfall?builder=%s">Builder: %s</a></h1>\n' % (self.path_to_root(req), urllib.quote( b.getName(), safe=''), html.escape(b.getName()))) # the first section shows builds which are currently running, if any. current = b.getCurrentBuilds() if current: data += "<h2>Currently Building:</h2>\n" data += "<ul>\n" for build in current: data += " <li>" + self.build_line(build, req) + "</li>\n" data += "</ul>\n" else: data += "<h2>no current builds</h2>\n" # Then a section with the last 5 builds, with the most recent build # distinguished from the rest. data += "<h2>Recent Builds:</h2>\n" data += "<ul>\n" for i, build in enumerate(b.generateFinishedBuilds(num_builds=5)): data += " <li>" + self.make_line(req, build, False) + "</li>\n" if i == 0: data += "<br />\n" # separator # TODO: or empty list? data += "</ul>\n" data += "<h2>Buildslaves:</h2>\n" data += "<ol>\n" for slave in slaves: name = slave.getName() if not name: name = '' data += "<li><b>%s</b>: " % html.escape(name) if slave.isConnected(): data += "CONNECTED\n" if slave.getAdmin(): data += make_row("Admin:", html.escape(slave.getAdmin())) if slave.getHost(): data += "<span class='label'>Host info:</span>\n" data += html.PRE(slave.getHost()) else: data += ("NOT CONNECTED\n") data += "</li>\n" data += "</ol>\n" if control is not None and connected_slaves: forceURL = urllib.quote(req.childLink("force")) data += (""" <form action='%(forceURL)s' class='command forcebuild'> <p>To force a build, fill out the following fields and push the 'Force Build' button</p> <table> <tr class='row' valign="bottom"> <td> <span class="label">Your name<br> (<span style="color: red;">please fill in at least this much</span>):</span> </td> <td> <span class="field"><input type='text' name='username' /></span> </td> </tr> <tr class='row'> <td> <span class="label">Reason for build:</span> </td> <td> <span class="field"><input type='text' name='comments' /></span> </td> </tr> <tr class='row'> <td> <span class="label">Branch to build:</span> </td> <td> <span class="field"><input type='text' name='branch' /></span> </td> </tr> <tr class='row'> <td> <span class="label">Revision to build:</span> </td> <td> <span class="field"><input type='text' name='revision' /></span> </td> </tr> <tr class='row'> <td> <span class="label">Slave to use:</span> </td> <td> <span class="field"><input type='text' name='slavename' /></span> </td> </tr> <tr class='row'> <td> <span class="label">Clobber:</span> </td> <td> <span class="field"><input type='checkbox' name='clobber' /> </span> </td> </tr> </table> <input type='submit' value='Force Build' /> </form> """) % { "forceURL": forceURL } elif control is not None: data += """ <p>All buildslaves appear to be offline, so it's not possible to force this build to execute at this time.</p> """ if control is not None: pingURL = urllib.quote(req.childLink("ping")) data += """ <form action="%s" class='command pingbuilder'> <p>To ping the buildslave(s), push the 'Ping' button</p> <input type="submit" value="Ping Builder" /> </form> """ % pingURL return data
def body(self, req): b = self.builder_status control = self.builder_control status = self.getStatus(req) slaves = b.getSlaves() connected_slaves = [s for s in slaves if s.isConnected()] projectName = status.getProjectName() data = '<a href="%s">%s</a>\n' % (self.path_to_root(req), projectName) data += "<h1>Builder: %s</h1>\n" % html.escape(b.getName()) # the first section shows builds which are currently running, if any. current = b.getCurrentBuilds() if current: data += "<h2>Currently Building:</h2>\n" data += "<ul>\n" for build in current: data += " <li>" + self.build_line(build, req) + "</li>\n" data += "</ul>\n" else: data += "<h2>no current builds</h2>\n" pending = b.getPendingBuilds() if pending: data += "<h2>Pending Builds:</h2>\n" data += "<ul>\n" for request in pending: data += " <li>" + self.request_line(request, req) + "</li>\n" data += "</ul>\n" cancelURL = path_to_builder(req, self.builder_status) + '/cancelbuild' if self.builder_control is not None: data += ''' <form action="%s" class="command cancelbuild" style="display:inline" method="post"> <input type="hidden" name="id" value="all" /> <input type="submit" value="Cancel All" /> </form>''' % cancelURL else: data += "<h2>no pending builds</h2>\n" # Then a section with the last 5 builds, with the most recent build # distinguished from the rest. data += "<h2>Recent Builds:</h2>\n" data += "(<a href=\"%s\">view in waterfall</a>)\n" % (self.path_to_root(req)+"waterfall?show="+html.escape(b.getName())) data += "<ul>\n" numbuilds = req.args.get('numbuilds', ['5'])[0] for i,build in enumerate(b.generateFinishedBuilds(num_builds=int(numbuilds))): data += " <li>" + self.make_line(req, build, False) + "</li>\n" if i == 0: data += "<br />\n" # separator # TODO: or empty list? data += "</ul>\n" data += "<h2>Buildslaves:</h2>\n" data += "<ol>\n" for slave in slaves: slaveurl = path_to_slave(req, slave) data += "<li><b><a href=\"%s\">%s</a></b>: " % (html.escape(slaveurl), html.escape(slave.getName())) if slave.isConnected(): data += "CONNECTED\n" if slave.getAdmin(): data += make_row("Admin:", html.escape(slave.getAdmin())) if slave.getHost(): data += "<span class='label'>Host info:</span>\n" data += html.PRE(slave.getHost()) else: data += ("NOT CONNECTED\n") data += "</li>\n" data += "</ol>\n" if control is not None and connected_slaves: forceURL = path_to_builder(req, b) + '/force' data += make_force_build_form(forceURL, self.isUsingUserPasswd(req)) elif control is not None: data += """ <p>All buildslaves appear to be offline, so it's not possible to force this build to execute at this time.</p> """ if control is not None: pingURL = path_to_builder(req, b) + '/ping' data += """ <form method="post" action="%s" class='command pingbuilder'> <p>To ping the buildslave(s), push the 'Ping' button</p> <input type="submit" value="Ping Builder" /> </form> """ % pingURL data += self.footer(status, req) return data
def body(self, req): b = self.build_status status = self.getStatus(req) projectName = status.getProjectName() projectURL = status.getProjectURL() data = ('<div class="title"><a href="%s">%s</a></div>\n' % (self.path_to_root(req), projectName)) builder_name = b.getBuilder().getName() data += ("<h1><a href=\"%s\">Builder %s</a>: Build #%d</h1>\n" % (path_to_builder(req, b.getBuilder()), builder_name, b.getNumber())) if not b.isFinished(): data += "<h2>Build In Progress</h2>" when = b.getETA() if when is not None: when_time = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) data += "<div>ETA %ds (%s)</div>\n" % (when, when_time) if self.build_control is not None: stopURL = urllib.quote(req.childLink("stop")) data += make_stop_form(stopURL, self.isUsingUserPasswd(req)) if b.isFinished(): # Results map loosely to css_classes results = b.getResults() data += "<h2>Results:</h2>\n" text = " ".join(b.getText()) data += '<span class="%s">%s</span>\n' % (css_classes[results], text) if b.getTestResults(): url = req.childLink("tests") data += "<h3><a href=\"%s\">test results</a></h3>\n" % url ss = b.getSourceStamp() data += "<h2>SourceStamp:</h2>\n" data += " <ul>\n" if ss.branch: data += " <li>Branch: %s</li>\n" % html.escape(ss.branch) if ss.revision: data += " <li>Revision: %s</li>\n" % html.escape(str(ss.revision)) if ss.patch: data += " <li>Patch: YES</li>\n" # TODO: provide link to .diff if ss.changes: data += " <li>Changes: see below</li>\n" if (ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes): data += " <li>build of most recent revision</li>\n" got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: got_revision = str(got_revision) if len(got_revision) > 40: got_revision = "[revision string too long]" data += " <li>Got Revision: %s</li>\n" % got_revision data += " </ul>\n" # TODO: turn this into a table, or some other sort of definition-list # that doesn't take up quite so much vertical space try: slaveurl = path_to_slave(req, status.getSlave(b.getSlavename())) data += "<h2>Buildslave:</h2>\n <a href=\"%s\">%s</a>\n" % (html.escape(slaveurl), html.escape(b.getSlavename())) except KeyError: data += "<h2>Buildslave:</h2>\n %s\n" % html.escape(b.getSlavename()) data += "<h2>Reason:</h2>\n%s\n" % html.escape(b.getReason()) data += "<h2>Steps and Logfiles:</h2>\n" # TODO: # urls = self.original.getURLs() # ex_url_class = "BuildStep external" # for name, target in urls.items(): # text.append('[<a href="%s" class="%s">%s</a>]' % # (target, ex_url_class, html.escape(name))) data += "<ol>\n" for s in b.getSteps(): name = s.getName() time_to_run = 0 (start, end) = s.getTimes() if start and end: time_to_run = end - start if s.isFinished(): css_class = css_classes[s.getResults()[0]] elif s.isStarted(): css_class = "running" else: css_class = "" data += (' <li><span class="%s"><a href=\"%s\">%s</a> [%s] [%d seconds]</span>\n' % (css_class, req.childLink("steps/%s" % urllib.quote(name)), name, " ".join(s.getText()), time_to_run)) data += " <ol>\n" if s.getLogs(): for logfile in s.getLogs(): logname = logfile.getName() logurl = req.childLink("steps/%s/logs/%s" % (urllib.quote(name), urllib.quote(logname))) data += (" <li><a href=\"%s\">%s</a></li>\n" % (logurl, logfile.getName())) if s.getURLs(): for url in s.getURLs().items(): logname = url[0] logurl = url[1] data += (' <li><a href="%s">%s</a></li>\n' % (logurl, html.escape(logname))) data += "</ol>\n" data += " </li>\n" data += "</ol>\n" data += "<h2>Build Properties:</h2>\n" data += "<table><tr><th valign=\"left\">Name</th><th valign=\"left\">Value</th><th valign=\"left\">Source</th></tr>\n" for name, value, source in b.getProperties().asList(): value = str(value) if len(value) > 500: value = value[:500] + " .. [property value too long]" data += "<tr>" data += "<td>%s</td>" % html.escape(name) data += "<td>%s</td>" % html.escape(value) data += "<td>%s</td>" % html.escape(source) data += "</tr>\n" data += "</table>" data += "<h2>Blamelist:</h2>\n" if list(b.getResponsibleUsers()): data += " <ol>\n" for who in b.getResponsibleUsers(): data += " <li>%s</li>\n" % html.escape(who) data += " </ol>\n" else: data += "<div>no responsible users</div>\n" (start, end) = b.getTimes() data += "<h2>Timing</h2>\n" data += "<table>\n" data += "<tr><td>Start</td><td>%s</td></tr>\n" % time.ctime(start) if end: data += "<tr><td>End</td><td>%s</td></tr>\n" % time.ctime(end) data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % util.formatInterval(end - start) else: now = util.now() data += "<tr><td>Elapsed</td><td>%s</td></tr>\n" % util.formatInterval(now - start) data += "</table>\n" if ss.changes: data += "<h2>All Changes</h2>\n" data += "<ol>\n" for c in ss.changes: data += "<li>" + c.asHTML() + "</li>\n" data += "</ol>\n" #data += html.PRE(b.changesText()) # TODO if b.isFinished() and self.builder_control is not None: data += "<h3>Resubmit Build:</h3>\n" # can we rebuild it exactly? exactly = (ss.revision is not None) or b.getChanges() if exactly: data += ("<p>This tree was built from a specific set of \n" "source files, and can be rebuilt exactly</p>\n") else: data += ("<p>This tree was built from the most recent " "revision") if ss.branch: data += " (along some branch)" data += (" and thus it might not be possible to rebuild it \n" "exactly. Any changes that have been committed \n" "after this build was started <b>will</b> be \n" "included in a rebuild.</p>\n") rebuildURL = urllib.quote(req.childLink("rebuild")) data += ('<form method="post" action="%s" class="command rebuild">\n' % rebuildURL) data += make_name_user_passwd_form(self.isUsingUserPasswd(req)) data += make_extra_property_row(1) data += make_extra_property_row(2) data += make_extra_property_row(3) data += make_row("Reason for re-running build:", "<input type='text' name='comments' />") data += '<input type="submit" value="Rebuild" />\n' data += '</form>\n' data += self.footer(status, req) return data
def body(self, req): b = self.build_status status = self.getStatus(req) projectName = status.getProjectName() data = ('<div class="title"><a href="%s">%s</a></div>\n' % (self.path_to_root(req), projectName)) # the color in the following line gives python-mode trouble builder_name = b.getBuilder().getName() data += ("<h1><a href=\"%s\">Builder %s</a>: Build #%d</h1>\n" % (path_to_builder( req, b.getBuilder()), builder_name, b.getNumber())) if not b.isFinished(): data += "<h2>Build In Progress</h2>" when = b.getETA() if when is not None: when_time = time.strftime("%H:%M:%S", time.localtime(time.time() + when)) data += "<div>ETA %ds (%s)</div>\n" % (when, when_time) if self.build_control is not None: stopURL = urllib.quote(req.childLink("stop")) data += make_stop_form(stopURL) if b.isFinished(): results = b.getResults() data += "<h2>Results:</h2>\n" text = " ".join(b.getText()) data += '<span class="%s">%s</span>\n' % (css_classes[results], text) if b.getTestResults(): url = req.childLink("tests") data += "<h3><a href=\"%s\">test results</a></h3>\n" % url ss = b.getSourceStamp() data += "<h2>SourceStamp:</h2>\n" data += " <ul>\n" if ss.branch: data += " <li>Branch: %s</li>\n" % html.escape(ss.branch) if ss.revision: data += " <li>Revision: %s</li>\n" % html.escape(str(ss.revision)) if ss.patch: data += " <li>Patch: YES</li>\n" # TODO: provide link to .diff if ss.changes: data += " <li>Changes: see below</li>\n" if (ss.branch is None and ss.revision is None and ss.patch is None and not ss.changes): data += " <li>build of most recent revision</li>\n" got_revision = None try: got_revision = b.getProperty("got_revision") except KeyError: pass if got_revision: got_revision = str(got_revision) if len(got_revision) > 40: got_revision = "[revision string too long]" data += " <li>Got Revision: %s</li>\n" % got_revision data += " </ul>\n" # TODO: turn this into a table, or some other sort of definition-list # that doesn't take up quite so much vertical space data += "<h2>Buildslave:</h2>\n %s\n" % html.escape(b.getSlavename()) data += "<h2>Reason:</h2>\n%s\n" % html.escape(b.getReason()) data += "<h2>Steps and Logfiles:</h2>\n" # TODO: # urls = self.original.getURLs() # ex_url_class = "BuildStep external" # for name, target in urls.items(): # text.append('[<a href="%s" class="%s">%s</a>]' % # (target, ex_url_class, html.escape(name))) if b.getLogs(): data += "<ol>\n" for s in b.getSteps(): name = s.getName() data += (" <li><a href=\"%s\">%s</a> [%s]\n" % (req.childLink("steps/%s" % urllib.quote(name)), name, " ".join(s.getText()))) if s.getLogs(): data += " <ol>\n" for logfile in s.getLogs(): logname = logfile.getName() logurl = req.childLink( "steps/%s/logs/%s" % (urllib.quote(name), urllib.quote(logname))) data += (" <li><a href=\"%s\">%s</a></li>\n" % (logurl, logfile.getName())) data += " </ol>\n" data += " </li>\n" data += "</ol>\n" data += "<h2>Blamelist:</h2>\n" if list(b.getResponsibleUsers()): data += " <ol>\n" for who in b.getResponsibleUsers(): data += " <li>%s</li>\n" % html.escape(who) data += " </ol>\n" else: data += "<div>no responsible users</div>\n" if ss.changes: data += "<h2>All Changes</h2>\n" data += "<ol>\n" for c in ss.changes: data += "<li>" + c.asHTML() + "</li>\n" data += "</ol>\n" #data += html.PRE(b.changesText()) # TODO if b.isFinished() and self.builder_control is not None: data += "<h3>Resubmit Build:</h3>\n" # can we rebuild it exactly? exactly = (ss.revision is not None) or b.getChanges() if exactly: data += ("<p>This tree was built from a specific set of \n" "source files, and can be rebuilt exactly</p>\n") else: data += ("<p>This tree was built from the most recent " "revision") if ss.branch: data += " (along some branch)" data += (" and thus it might not be possible to rebuild it \n" "exactly. Any changes that have been committed \n" "after this build was started <b>will</b> be \n" "included in a rebuild.</p>\n") rebuildURL = urllib.quote(req.childLink("rebuild")) data += ('<form action="%s" class="command rebuild">\n' % rebuildURL) data += make_row("Your name:", "<input type='text' name='username' />") data += make_row("Reason for re-running build:", "<input type='text' name='comments' />") data += '<input type="submit" value="Rebuild" />\n' data += '</form>\n' return data