def GenStepBox(stepstatus): """Generates a box for one step.""" class_ = build_get_class(stepstatus) style = '' if class_ and class_ in styles: style = styles[class_] stepname = stepstatus.getName() text = stepstatus.getText() or [] text = text[:] base_url = '%sbuilders/%s/builds/%d/steps' % ( waterfall_url, urllib.quote(stepstatus.getBuild().getBuilder().getName(), safe=''), stepstatus.getBuild().getNumber()) for steplog in stepstatus.getLogs(): name = steplog.getName() log.msg('name = %s' % name) url = '%s/%s/logs/%s' % ( base_url, urllib.quote(stepname, safe=''), urllib.quote(name)) text.append('<a href="%s">%s</a>' % (url, html.escape(name))) for name, target in stepstatus.getURLs().iteritems(): text.append('<a href="%s">%s</a>' % (target, html.escape(name))) fmt = '<tr><td style="%s">%s</td></tr>' return fmt % (style, '<br/>'.join(text))
def getBox(self, req): urlbase = path_to_step(req, self.original) text = self.original.getText() if text is None: log.msg("getText() gave None", urlbase) text = [] text = text[:] logs = self.original.getLogs() cxt = dict(text=text, logs=[], urls=[]) for num in range(len(logs)): name = logs[num].getName() if logs[num].hasContents(): url = urlbase + "/logs/%s" % urllib.quote(name) else: url = None cxt['logs'].append(dict(name=name, url=url)) for name, target in self.original.getURLs().items(): cxt['urls'].append(dict(link=target,name=name)) template = req.site.buildbot_service.templates.get_template("box_macros.html") text = template.module.step_box(**cxt) class_ = "BuildStep " + build_get_class(self.original) return Box(text, class_=class_)
def body(self, req): status = self.getStatus(req) control = self.getControl(req) builders = req.args.get("builder", status.getBuilderNames()) branches = [b for b in req.args.get("branch", []) if b] data = "" data += "<h2>Latest builds: %s</h2>\n" % ", ".join(branches) data += "<table>\n" building = False online = 0 base_builders_url = self.path_to_root(req) + "builders/" for bn in builders: base_builder_url = base_builders_url + urllib.quote(bn, safe='') builder = status.getBuilder(bn) data += "<tr>\n" data += '<td class="box"><a href="%s">%s</a></td>\n' \ % (base_builder_url, html.escape(bn)) builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if builds: b = builds[0] url = (base_builder_url + "/builds/%d" % b.getNumber()) try: label = b.getProperty("got_revision") except KeyError: label = None if not label or len(str(label)) > 20: label = "#%d" % b.getNumber() text = ['<a href="%s">%s</a>' % (url, label)] text.extend(b.getText()) box = Box(text, b.getColor(), class_="LastBuild box %s" % build_get_class(b)) data += box.td(align="center") else: data += '<td class="LastBuild box" >no build</td>\n' current_box = ICurrentBox(builder).getBox(status) data += current_box.td(align="center") builder_status = builder.getState()[0] if builder_status == "building": building = True online += 1 elif builder_status != "offline": online += 1 data += "</table>\n" if control is not None: if building: stopURL = "builders/_all/stop" data += make_stop_form(stopURL, True, "Builds") if online: forceURL = "builders/_all/force" data += make_force_build_form(forceURL, True) return data
def getBox(self, req): urlbase = path_to_step(req, self.original) text = self.original.getText() if text is None: log.msg("getText() gave None", urlbase) text = [] text = text[:] def native_link_fn(l): if l.hasContents(): url = urlbase + "/logs/%s" % urllib.quote(l.getName()) else: url = None return url logs, urls, _ = getStepLogsURLsAndAliases( self.original, False, native_link_fn, ) cxt = dict(text=text, logs=logs, urls=urls) template = req.site.buildbot_service.templates.get_template( "box_macros.html") text = template.module.step_box(**unicodify(cxt)) class_ = "BuildStep " + build_get_class(self.original) return Box(text, class_=class_, buildNumber=self.original.build_number, builder=self.original.builder.getName(), stepName=self.original.getName())
def content(self, req, cxt): status = self.getStatus(req) builders = req.args.get("builder", status.getBuilderNames()) branches = [b for b in req.args.get("branch", []) if b] # get counts of pending builds for each builder brstatus_ds = [] brcounts = {} def keep_count(statuses, builderName): brcounts[builderName] = len(statuses) for builderName in builders: builder_status = status.getBuilder(builderName) d = builder_status.getPendingBuildRequestStatuses() d.addCallback(keep_count, builderName) brstatus_ds.append(d) yield defer.gatherResults(brstatus_ds) cxt['branches'] = branches bs = cxt['builders'] = [] building = 0 online = 0 base_builders_url = path_to_root(req) + "builders/" for bn in builders: bld = { 'link': base_builders_url + urllib.quote(bn, safe=''), 'name': bn } bs.append(bld) builder = status.getBuilder(bn) builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if builds: b = builds[0] bld['build_url'] = (bld['link'] + "/builds/%d" % b.getNumber()) label = b.getProperty("got_revision") if not label or len(str(label)) > 20: label = "#%d" % b.getNumber() bld['build_label'] = label bld['build_text'] = " ".join(b.getText()) bld['build_css_class'] = build_get_class(b) current_box = ICurrentBox(builder).getBox(status, brcounts) bld['current_box'] = current_box.td() builder_status = builder.getState()[0] if builder_status == "building": building += 1 online += 1 elif builder_status != "offline": online += 1 cxt['authz'] = self.getAuthz(req) cxt['num_building'] = building cxt['num_online'] = online buildForceContext(cxt, req, self.getBuildmaster(req)) template = req.site.buildbot_service.templates.get_template("builders.html") defer.returnValue(template.render(**cxt))
def builder_row(self, bn, req, branches, num_builds): status = self.getStatus(req) builder = status.getBuilder(bn) state = builder.getState()[0] if state == 'building': state = 'idle' row = tags.tr() builderLink = path_to_builder(req, builder) row(tags.td(class_="box %s" % (state, ))(tags.a(href=builderLink)(bn))) builds = sorted([ build for build in builder.getCurrentBuilds() if set(map_branches(branches)) & builder._getBuildBranches(build) ], key=lambda build: build.getNumber(), reverse=True) builds.extend( builder.generateFinishedBuilds(map_branches(branches), num_builds=num_builds)) if builds: for b in builds: url = path_to_build(req, b) try: label = b.getProperty("got_revision") except KeyError: label = None # Label should never be "None", but sometimes # buildbot has disgusting bugs. if not label or label == "None" or len(str(label)) > 20: label = "#%d" % b.getNumber() if b.isFinished(): text = b.getText() else: when = b.getETA() if when: text = [ "%s" % (formatInterval(when), ), "%s" % (time.strftime( "%H:%M:%S", time.localtime(time.time() + when)), ) ] else: text = [] row( tags.td(align="center", bgcolor=_backgroundColors[b.getResults()], class_=("LastBuild box ", build_get_class(b)))([ (element, tags.br) for element in [tags.a(href=url)(label)] + text ])) else: row(tags.td(class_="LastBuild box")("no build")) return row
def content(self, req, cxt): status = self.getStatus(req) control = self.getControl(req) builders = req.args.get("builder", status.getBuilderNames()) branches = [b for b in req.args.get("branch", []) if b] cxt['branches'] = branches bs = cxt['builders'] = [] building = False online = 0 base_builders_url = path_to_root(req) + "builders/" for bn in builders: bld = { 'link': base_builders_url + urllib.quote(bn, safe=''), 'name': bn } bs.append(bld) builder = status.getBuilder(bn) builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if builds: b = builds[0] bld['build_url'] = (bld['link'] + "/builds/%d" % b.getNumber()) try: label = b.getProperty("got_revision") except KeyError: label = None if not label or len(str(label)) > 20: label = "#%d" % b.getNumber() bld['build_label'] = label bld['build_text'] = " ".join(b.getText()) bld['build_css_class'] = build_get_class(b) current_box = ICurrentBox(builder).getBox(status) bld['current_box'] = current_box.td() builder_status = builder.getState()[0] if builder_status == "building": building = True online += 1 elif builder_status != "offline": online += 1 if control is not None: cxt['use_user_passwd'] = self.isUsingUserPasswd(req) if building: cxt['stop_url'] = "builders/_all/stop" if online: cxt['force_url'] = "builders/_all/force" template = req.site.buildbot_service.templates.get_template("oneboxperbuilder.html") return template.render(**cxt)
def content(self, req, cxt): status = self.getStatus(req) builders = req.args.get("builder", status.getBuilderNames()) branches = [b for b in req.args.get("branch", []) if b] cxt['branches'] = branches bs = cxt['builders'] = [] building = 0 online = 0 base_builders_url = path_to_root(req) + "builders/" for bn in builders: bld = { 'link': base_builders_url + urllib.quote(bn, safe=''), 'name': bn } bs.append(bld) builder = status.getBuilder(bn) builds = list( builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if builds: b = builds[0] bld['build_url'] = (bld['link'] + "/builds/%d" % b.getNumber()) try: label = b.getProperty("got_revision") except KeyError: label = None if not label or len(str(label)) > 20: label = "#%d" % b.getNumber() bld['build_label'] = label bld['build_text'] = " ".join(b.getText()) bld['build_css_class'] = build_get_class(b) current_box = ICurrentBox(builder).getBox(status) bld['current_box'] = current_box.td() builder_status = builder.getState()[0] if builder_status == "building": building += 1 online += 1 elif builder_status != "offline": online += 1 cxt['authz'] = self.getAuthz(req) cxt['num_building'] = building cxt['num_online'] = online template = req.site.buildbot_service.templates.get_template( "builders.html") return template.render(**cxt)
def builder_row(self, bn, req, branches, num_builds): status = self.getStatus(req) builder = status.getBuilder(bn) state = builder.getState()[0] if state == 'building': state = 'idle' row = tags.tr() builderLink = path_to_builder(req, builder) row(tags.td(class_="box %s" % (state,)) (tags.a(href=builderLink)(bn))) builds = sorted([ build for build in builder.getCurrentBuilds() if set(map_branches(branches)) & builder._getBuildBranches(build) ], key=lambda build: build.getNumber(), reverse=True) builds.extend(builder.generateFinishedBuilds( map_branches(branches), num_builds=num_builds)) if builds: for b in builds: url = path_to_build(req, b) try: label = b.getProperty("got_revision") except KeyError: label = None # Label should never be "None", but sometimes # buildbot has disgusting bugs. if not label or label == "None" or len(str(label)) > 20: label = "#%d" % b.getNumber() if b.isFinished(): text = b.getText() else: when = b.getETA() if when: text = [ "%s" % (formatInterval(when),), "%s" % (time.strftime( "%H:%M:%S", time.localtime(time.time() + when)),) ] else: text = [] row(tags.td( align="center", bgcolor=_backgroundColors[b.getResults()], class_=("LastBuild box ", build_get_class(b)))([ (element, tags.br) for element in [tags.a(href=url)(label)] + text])) else: row(tags.td(class_="LastBuild box")("no build")) return row
def getBox(self, req): b = self.original number = b.getNumber() url = path_to_build(req, b) reason = b.getReason() template = req.site.buildbot_service.templates.get_template("box_macros.html") text = template.module.build_box(reason=reason,url=url,number=number) class_ = "start" if b.isFinished() and not b.getSteps(): # the steps have been pruned, so there won't be any indication # of whether it succeeded or failed. class_ = build_get_class(b) return Box([text], class_="BuildStep " + class_)
def getBox(self, req): b = self.original number = b.getNumber() url = path_to_build(req, b) reason = b.getReason() text = ('<a title="Reason: %s" href="%s">Build %d</a>' % (html.escape(reason), url, number)) class_ = "start" if b.isFinished() and not b.getSteps(): # the steps have been pruned, so there won't be any indication # of whether it succeeded or failed. class_ = build_get_class(b) return Box([text], class_="BuildStep " + class_)
def GenBuildBox(buildstatus): """Generates a box for one build.""" class_ = build_get_class(buildstatus) style = '' if class_ and class_ in styles: style = styles[class_] reason = html.escape(buildstatus.getReason()) url = '%sbuilders/%s/builds/%d' % ( waterfall_url, urllib.quote(buildstatus.getBuilder().getName(), safe=''), buildstatus.getNumber()) fmt = ('<tr><td style="%s"><a title="Reason: %s" href="%s">' 'Build %d' '</a></td></tr>') return fmt % (style, reason, url, buildstatus.getNumber())
def content(self, req, cxt): status = self.getStatus(req) builders = req.args.get("builder", status.getBuilderNames()) branches = [b for b in req.args.get("branch", []) if b] cxt["branches"] = branches bs = cxt["builders"] = [] building = 0 online = 0 base_builders_url = path_to_root(req) + "builders/" for bn in builders: bld = {"link": base_builders_url + urllib.quote(bn, safe=""), "name": bn} bs.append(bld) builder = status.getBuilder(bn) builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if builds: b = builds[0] bld["build_url"] = bld["link"] + "/builds/%d" % b.getNumber() try: label = b.getProperty("got_revision") except KeyError: label = None if not label or len(str(label)) > 20: label = "#%d" % b.getNumber() bld["build_label"] = label bld["build_text"] = " ".join(b.getText()) bld["build_css_class"] = build_get_class(b) current_box = ICurrentBox(builder).getBox(status) bld["current_box"] = current_box.td() builder_status = builder.getState()[0] if builder_status == "building": building += 1 online += 1 elif builder_status != "offline": online += 1 cxt["authz"] = self.getAuthz(req) cxt["num_building"] = online cxt["num_online"] = online template = req.site.buildbot_service.templates.get_template("builders.html") return template.render(**cxt)
def getBox(self, req): assert interfaces.IBuilderStatus(self.original) branches = [b for b in req.args.get("branch", []) if b] builder = self.original builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if not builds: return Box(["none"], class_="LastBuild") b = builds[0] url = path_to_build(req, b) text = b.getText() tests_failed = b.getSummaryStatistic('tests-failed', operator.add, 0) if tests_failed: text.extend(["Failed tests: %d" % tests_failed]) # TODO: maybe add logs? class_ = build_get_class(b) return Box(text, urlbase=url, class_="LastBuild %s" % class_)
def build_cxt(self, request, build): if not build: return {} if build.isFinished(): # get the text and annotate the first line with a link text = build.getText() if not text: text = [ "(no information)" ] if text == [ "build", "successful" ]: text = [ "OK" ] else: text = [ 'building' ] name = build.getBuilder().getName() cxt = {} cxt['name'] = name cxt['got_revision'] = build.getProperty("got_revision") cxt['DEST'] = build.getProperty("DEST") cxt['url'] = path_to_build(request, build) cxt['text'] = text cxt['class'] = build_get_class(build) if build.getProperty("repourl_poky"): if build.getProperty("repourl_poky") == "git://git.yoctoproject.org/poky": cxt['repository'] = "poky" cxt['cgiturl'] = "http://git.yoctoproject.org/cgit/cgit.cgi/poky/commit/?h=" elif "git://git.yoctoproject.org/poky-contrib" in build.getProperty("repourl_poky"): cxt['repository'] = "poky-contrib" cxt['cgiturl'] = "http://git.yoctoproject.org/cgit/cgit.cgi/poky-contrib/commit/?h=" else: cxt['repository'] = build.getProperty("repourl_poky") if build.getProperty("branch_poky"): if build.getProperty("branch_poky") == "stage/master_under_test": cxt['branchshortname']="mut" else: cxt['branchshortname']=build.getProperty("branch_poky") cxt['branch'] = build.getProperty("branch_poky") if 'cgiturl' in cxt and 'got_revision' in cxt and cxt['cgiturl'] is not None and cxt['got_revision'] is not None: cxt['cgiturl'] = cxt['cgiturl'] + build.getProperty("branch_poky") + "&id=" + cxt['got_revision'] if build.getProperty("custom_release_name_nightly"): cxt['release_name'] = build.getProperty("custom_release_name_nightly") else: cxt['commit_desc'] = build.getProperty("commit-description") return cxt
def getBox(self, req): assert interfaces.IBuilderStatus(self.original) branches = [b for b in req.args.get("branch", []) if b] builder = self.original builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if not builds: return Box(["none"], "white", class_="LastBuild") b = builds[0] name = b.getBuilder().getName() number = b.getNumber() url = path_to_build(req, b) text = b.getText() # TODO: maybe add logs? # TODO: add link to the per-build page at 'url' c = b.getColor() class_ = build_get_class(b) return Box(text, c, class_="LastBuild %s" % class_)
def getBox(self, req): assert interfaces.IBuilderStatus(self.original) branches = [b for b in req.args.get("branch", []) if b] builder = self.original builds = list( builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if not builds: return Box(["none"], "white", class_="LastBuild") b = builds[0] name = b.getBuilder().getName() number = b.getNumber() url = path_to_build(req, b) text = b.getText() # TODO: maybe add logs? # TODO: add link to the per-build page at 'url' c = b.getColor() class_ = build_get_class(b) return Box(text, c, class_="LastBuild %s" % class_)
def build_td(self, request, build): if not build: return '<td class="build"> </td>\n' if build.isFinished(): # get the text and annotate the first line with a link text = build.getText() if not text: text = ["(no information)"] if text == ["build", "successful"]: text = ["OK"] else: text = ['building'] name = build.getBuilder().getName() number = build.getNumber() url = "builders/%s/builds/%d" % (name, number) text[0] = '<a href="%s">%s</a>' % (url, text[0]) text = '<br />\n'.join(text) class_ = build_get_class(build) return '<td class="build %s">%s</td>\n' % (class_, text)
def build_td(self, request, build): if not build: return '<td class="build"> </td>\n' if build.isFinished(): # get the text and annotate the first line with a link text = build.getText() if not text: text = [ "(no information)" ] if text == [ "build", "successful" ]: text = [ "OK" ] else: text = [ 'building' ] name = build.getBuilder().getName() number = build.getNumber() url = "builders/%s/builds/%d" % (name, number) text[0] = '<a href="%s">%s</a>' % (url, text[0]) text = '<br />\n'.join(text) class_ = build_get_class(build) return '<td class="build %s">%s</td>\n' % (class_, text)
def getBox(self, req): b = self.original number = b.getNumber() url = base.path_to_build(req, b) reason = b.getReason() if reason: text = (('%s<br><a href="%s">Build %d</a><br>%s') % (b.getBuilder().getName(), url, number, html.escape(reason))) else: text = ('%s<br><a href="%s">Build %d</a>' % (b.getBuilder().getName(), url, number)) color = "yellow" class_ = "start" if b.isFinished() and not b.getSteps(): # the steps have been pruned, so there won't be any indication # of whether it succeeded or failed. Color the box red or green # to show its status color = b.getColor() class_ = base.build_get_class(b) return base.Box([text], color=color, class_="BuildStep " + class_)
def build_cxt(self, request, build): if not build: return {} if build.isFinished(): # get the text and annotate the first line with a link text = build.getText() if not text: text = [ "(no information)" ] if text == [ "build", "successful" ]: text = [ "OK" ] else: text = [ 'building' ] name = build.getBuilder().getName() cxt = {} cxt['name'] = name cxt['url'] = path_to_build(request, build) cxt['text'] = text cxt['class'] = build_get_class(build) return cxt
def build_cxt(self, request, build): if not build: return {} if build.isFinished(): # get the text and annotate the first line with a link text = build.getText() if not text: text = ["(no information)"] if text == ["build", "successful"]: text = ["OK"] else: text = ['building'] name = build.getBuilder().getName() cxt = {} cxt['name'] = name cxt['url'] = path_to_build(request, build) cxt['text'] = text cxt['class'] = build_get_class(build) return cxt
def get_line_values(self, req, build, include_builder=True): """ Append more information to the base.BuildLineMixIn ones """ # builder_name = build.getBuilder().getName() # results = build.getResults() values = super(BuildsMatrix, self).get_line_values(req=req, build=build, include_builder=include_builder) # now, append the tests ;) values["test_results"] = {} values["test_result_order"] = [] values["class_b"] = "build%s" % build_get_class(build) for tres in build.getTestResultsOrd(): name0 = tres.name and tres.name[0] or "" if name0 not in values["test_result_order"]: values["test_result_order"].append(name0) values["test_results"].setdefault(name0, []).append( {"name": tres.name, "results": tres.results, "text": tres.text} ) # TODO: perhaps filter? return values
def getBox(self, req): b = self.original number = b.getNumber() url = path_to_build(req, b) reason = b.getReason() # Update the buildbot BuildStatus so that it displays the hg revision number as the build number changedesc='(%d)' % number revision=b.getSourceStamp().revision if (len(b.changes)>0): changedesc='%s (%d)' % (b.changes[0].revision,number) if (revision): changedesc="%s (%d)" % (revision,number) text = ('<a title="Reason: %s" href="%s">Build %s</a>' % (html.escape(reason), url, changedesc)) class_ = "start" if b.isFinished() and not b.getSteps(): # the steps have been pruned, so there won't be any indication # of whether it succeeded or failed. class_ = build_get_class(b) return Box([text], class_="BuildStep " + class_)
def getBox(self, req): urlbase = path_to_step(req, self.original) text = self.original.getText() if text is None: log.msg("getText() gave None", urlbase) text = [] text = text[:] logs = self.original.getLogs() for num in range(len(logs)): name = logs[num].getName() if logs[num].hasContents(): url = urlbase + "/logs/%s" % urllib.quote(name) text.append("<a href=\"%s\">%s</a>" % (url, html.escape(name))) else: text.append(html.escape(name)) 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))) class_ = "BuildStep " + build_get_class(self.original) return Box(text, class_=class_)
def getBox(self, req): b = self.original number = b.getNumber() url = path_to_build(req, b) reason = b.getReason() # Update the buildbot BuildStatus so that it displays the hg revision number as the build number changedesc = '(%d)' % number revision = b.getSourceStamp().revision if (len(b.changes) > 0): changedesc = '%s (%d)' % (b.changes[0].revision, number) if (revision): changedesc = "%s (%d)" % (revision, number) text = ('<a title="Reason: %s" href="%s">Build %s</a>' % (html.escape(reason), url, changedesc)) class_ = "start" if b.isFinished() and not b.getSteps(): # the steps have been pruned, so there won't be any indication # of whether it succeeded or failed. class_ = build_get_class(b) return Box([text], class_="BuildStep " + class_)
def GenStepBox(stepstatus): """Generates a box for one step.""" class_ = build_get_class(stepstatus) style = '' if class_ and class_ in styles: style = styles[class_] stepname = stepstatus.getName() text = stepstatus.getText() or [] text = text[:] base_url = '%sbuilders/%s/builds/%d/steps' % ( waterfall_url, urllib.quote(stepstatus.getBuild().getBuilder().getName(), safe=''), stepstatus.getBuild().getNumber()) for steplog in stepstatus.getLogs(): name = steplog.getName() log.msg('name = %s' % name) url = '%s/%s/logs/%s' % (base_url, urllib.quote( stepname, safe=''), urllib.quote(name)) text.append('<a href="%s">%s</a>' % (url, html.escape(name))) for name, target in stepstatus.getURLs().iteritems(): text.append('<a href="%s">%s</a>' % (target, html.escape(name))) fmt = '<tr><td style="%s">%s</td></tr>' return fmt % (style, '<br/>'.join(text))
def get_line_values(self, req, build, include_builder=True): ''' Append more information to the base.BuildLineMixIn ones ''' # builder_name = build.getBuilder().getName() # results = build.getResults() values = super(BuildsMatrix, self).get_line_values(req=req, build=build, include_builder=include_builder) # now, append the tests ;) values['test_results'] = {} values['test_result_order'] = [] values['class_b'] = "build%s" % build_get_class(build) for tres in build.getTestResultsOrd(): name0 = tres.name and tres.name[0] or '' if name0 not in values['test_result_order']: values['test_result_order'].append(name0) values['test_results'].setdefault(name0,[]).append( { 'name': tres.name , 'results': tres.results, 'text': tres.text }) # TODO: perhaps filter? return values
def body(self, req): status = self.getStatus(req) authz = self.getAuthz(req) builders = req.args.get("builder", status.getBuilderNames(categories=self.categories)) branches = [b for b in req.args.get("branch", []) if b] if not branches: branches = ["trunk"] if branches and "trunk" not in branches: defaultCount = "1" else: defaultCount = "10" num_builds = int(req.args.get("num_builds", [defaultCount])[0]) tag = tags.div() tag(tags.script(src="txbuildbot.js")) tag(tags.h2(style="float:left; margin-top:0")("Latest builds: ", ", ".join(branches))) form = tags.form(method="get", action="", style="float:right", onsubmit="return checkBranch(branch.value)") form(tags.input(type="test", name="branch", placeholder=branches[0], size="40")) form(tags.input(type="submit", value="View")) if (yield authz.actionAllowed('forceAllBuilds', req)): # XXX: Unsafe interpolation form(tags.button(type="button", onclick="forceBranch(branch.value || %r, %r)" % (branches[0], self.categories,) )("Force")) tag(form) table = tags.table(style="clear:both") tag(table) for bn in builders: builder = status.getBuilder(bn) state = builder.getState()[0] if state == 'building': state = 'idle' row = tags.tr() table(row) builderLink = path_to_builder(req, builder) row(tags.td(class_="box %s" % (state,))(tags.a(href=builderLink)(bn))) builds = sorted([ build for build in builder.getCurrentBuilds() if build.getSourceStamps()[0].branch in map_branches(branches) ], key=lambda build: build.getNumber(), reverse=True) builds.extend(builder.generateFinishedBuilds(map_branches(branches), num_builds=num_builds)) if builds: for b in builds: url = path_to_build(req, b) try: label = b.getProperty("got_revision") except KeyError: label = None # Label should never be "None", but sometimes # buildbot has disgusting bugs. if not label or label == "None" or len(str(label)) > 20: label = "#%d" % b.getNumber() if b.isFinished(): text = b.getText() else: when = b.getETA() if when: text = [ "%s" % (formatInterval(when),), "%s" % (time.strftime("%H:%M:%S", time.localtime(time.time() + when)),) ] else: text = [] row(tags.td( align="center", bgcolor=_backgroundColors[b.getResults()], class_=("LastBuild box ", build_get_class(b)))([ (element, tags.br) for element in [tags.a(href=url)(label)] + text]) ) else: row(tags.td(class_="LastBuild box")("no build")) defer.returnValue((yield flattenString(req, tag)))
def content(self, req, cxt): status = self.getStatus(req) # building = False # online = 0 req.setHeader('Cache-Control', 'no-cache') # base_builders_url = "buildersresource/" base_builders_url = "builders/" cats = req.args.get('groups', False) if cats is not False: cats = cats.split(',') else: cats = None builders = req.args.get("builder", status.getBuilderNames(cats)) branches = [b for b in req.args.get("branch", []) if b] num_cols = get_args_int(req.args, 'num', 5) cxt['num_cols'] = num_cols cxt['builders'] = [] builders_grouped = {} groups_seq = {} # sequence of groups for bn in builders: base_builder_url = base_builders_url + urllib.quote(bn, safe='') builder = status.getBuilder(bn) bld_props = status.botmaster.builders[bn].properties # hack into the structure categ = builder.category bname = bn if categ and bn.startswith(categ + '-'): bname = bname[len(categ)+1:] bname = html.escape(bname.replace('-',' ', 1)) bldr_cxt = { 'name': bname , 'url': base_builder_url, 'builds': [], 'sequence': bld_props.get('sequence', 10) } if categ: if bld_props.get('group_public', True): builders_grouped.setdefault(categ, []).append(bldr_cxt) if 'group_seq' in bld_props: groups_seq[categ] = bld_props['group_seq'] else: cxt['builders'].append(bldr_cxt) # It is difficult to do paging here, because we are already iterating over the # builders, so won't have the same build names or rev-ids. builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=num_cols)) # builds.reverse() bldr_cxt['builds'] = [] for build in builds[:num_cols]: url = (base_builder_url + "/builds/%d" % build.getNumber()) build_cxt = {'url': url} bldr_cxt['builds'].append(build_cxt) try: ss = build.getSourceStamp() commiter = "" if list(build.getResponsibleUsers()): for who in build.getResponsibleUsers(): commiter += "%s" % html.escape(reduce_eml(who)) else: commiter += "No Commiter Found !" if ss.revision: revision = ss.revision label = '%s-%s: %s' % (str(revision), commiter, ''.join(build.text)) except Exception: label = None if not label: label = "#%d" % build.getNumber() tftime = time.strftime('%a %d, %H:%M:%S', time.localtime(build.getTimes()[1])) ttitle = 'Test at: %s\n%s' %(ustr(tftime), html.escape(ustr(build.getReason()))) class_b = "build%s" % build_get_class(build) build_cxt.update({ 'label': label, 'commiter': commiter, 'tftime': tftime, 'ttitle': ttitle, 'last_t': ustr(last_change(ss, True)), 'class_b': class_b }) builder_status = builder.getState()[0] bldr_cxt['status'] = builder_status # Now, sort the builders and grouped: cxt['builders'].sort(key=lambda bld: bld['sequence']) for bldrs in builders_grouped.values(): bldrs.sort(key=lambda bld: bld['sequence']) cxt['builders_grouped'] = [] # will be list of tuples for gk, bldrs in builders_grouped.items(): cxt['builders_grouped'].append((groups_seq.get(gk,10), gk, bldrs)) template = req.site.buildbot_service.templates.get_template(self.tpl_page) return template.render(**cxt)
def body(self, req): from twisted.web import html status = self.getStatus(req) control = self.getControl(req) builders = req.args.get("builder", status.getBuilderNames()) branches = [b for b in req.args.get("branch", []) if b] building = False online = 0 base_builders_url = self.path_to_root(req) + "builders/" all_builders = [html.escape(bn) for bn in builders] trunk_builders = [bn for bn in all_builders if bn.startswith('trunk')] stable_builders = [bn for bn in all_builders if bn.startswith('stable')] trunk_builders_link = 'waterfall?builder='+'&builder='.join(trunk_builders) stable_builders_link = 'waterfall?builder=' + '&builder='.join(stable_builders) tr_b = False st_b = False data = "" data += "<table class='grid' id='latest_builds'>" for bn in all_builders: if (bn.startswith('stable')) and (not st_b): st_b = True data += "<table class='grid' id='stable_builds'>\n" data += "<tr class='grid-header'><td class='grid-cell'><span>Latest Stable</span></td><td class='grid-cell'><a href=%s>Stable Tests</a></td><td class='grid-cell'><a href='Changelog/5.0'>Changelog</a></td></tr><\n>"[:-3]%(stable_builders_link) if (bn.startswith('trunk')) and (not tr_b): tr_b = True data += "<tr id='trunk_builds'><td colspan='3'></td>" data += "<tr class='grid-header'><td class='grid-cell'><span>Latest Trunk</span></td><td class='grid-cell'><a href='%s'>Trunk Tests</a></td><td class='grid-cell'><a href='Changelog/trunk'>Changelog</a></td></tr><\n>"[:-3]%(trunk_builders_link) base_builder_url = base_builders_url + urllib.quote(bn, safe='') builder = status.getBuilder(bn) data += "<tr class='grid-row'>\n" data += '<td class="grid-cell"><a href="%s">%s</a></td>\n' \ % (base_builder_url, html.escape(bn)) builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if builds: b = builds[0] url = (base_builder_url + "/builds/%d" % b.getNumber()) try: label = b.getProperty("got_revision") except KeyError: label = None if not label or len(str(label)) > 20: label = "#%d" % b.getNumber() text = ['<a href="%s">%s</a>' % (url, label)] text.append(' '.join(b.getText())) box = Box(text, b.getColor(), class_="LastBuild box %s" % build_get_class(b)) data += box.td(class_="grid-cell",align="center") else: data += '<td class="grid-cell" align="center">no build</td>\n' current_box = ICurrentBox(builder).getBox(status) data += current_box.td(class_="grid-cell",align="center") data+='</tr>' builder_status = builder.getState()[0] if builder_status == "building": building = True online += 1 elif builder_status != "offline": online += 1 data += "</table></table>\n" if control is not None: if building: stopURL = "builders/_all/stop" data += make_stop_form(stopURL, True, "Builds") if online: forceURL = "builders/_all/force" data += make_force_build_form(forceURL, True) return data
def body(self, request): parent = request.site.buildbot_service status = self.getStatus(request) result = '' result += '<table class="ProjectSummary">\n' # Headers slave_status = {} for slave in parent.slaves: for module in parent.modules: builder = status.getBuilder("%s-%s" % (module, slave)) state, builds = builder.getState() if state == 'offline': slave_status[slave] = ('offline', []) break elif state == 'building': if slave in slave_status: modules = slave_status[slave][1] or [] slave_status[slave] = (state, modules + [module]) else: slave_status[slave] = (state, [module]) else: if not slave in slave_status: slave_status[slave] = ('idle', None) if type(parent.moduleset) is list: moduleset = ', '.join(parent.moduleset) else: moduleset = parent.moduleset result += '<thead><tr><td> </td><th>' + moduleset + '</td>' for name in parent.slaves: if len(name) > 25: name = name[:25] + '(...)' klass, modules = slave_status.get(name) if klass == 'building': title = 'Building %s' % ', '.join(modules) else: title = klass result += '<th class="%s" title="%s"><a href="bots/%s">%s</a></th>' % ( klass, title, name, name) result += '</tr>' thead = result # stop it here as a row with totals will be added here once every rows # have been handled # Contents result = '<tbody>' slave_results = {} for slave in parent.slaves: slave_results[slave] = [0, 0, 0] for module in parent.modules: result += '<tr>' result += '<td class="feed"><a href="%s/atom">' % module result += '<img src="/feed.png" alt="Atom"></a></td>\n' result += '<th><a href="%s">%s</a></td>' % (module, module) for slave in parent.slaves: builder = status.getBuilder("%s-%s" % (module, slave)) box = ITopBox(builder).getBox(request) lastbuild = '' for bt in box.text: if bt == 'successful' or bt == 'failed': lastbuild = bt if lastbuild == 'successful': last_build = builder.getLastFinishedBuild() if last_build: class_ = build_get_class(last_build) else: class_ = 'success' lastbuild_label = 'Success' if last_build and class_: # use a different class/label if make check failed steps = last_build.getSteps() for step in reversed(steps): if step.name.split()[-1] == 'check': if step.results == WARNINGS: # make check failed class_ = 'failedchecks' lastbuild_label = 'Failed Checks' break elif lastbuild == 'failed': lastbuild_label = 'Failed' last_build = builder.getLastFinishedBuild() if last_build: class_ = build_get_class(last_build) else: class_ = 'failure' else: class_ = '' lastbuild_label = lastbuild state, builds = builder.getState() if state == 'building': result += '<td class="%s">%s</td>' % (state, state) else: result += '<td class="%s">%s</td>' % (class_, lastbuild_label) if lastbuild in ('failed', 'successful'): slave_results[slave][2] += 1 if class_ == 'failedchecks': slave_results[slave][1] += 1 elif lastbuild == 'successful': slave_results[slave][0] += 1 slave_results[slave][1] += 1 result += '</tr>\n' result += '</tbody>\n' result += '<tfoot><tr class="totals"><td colspan="2"></td>' thead += '<tr class="totals"><td colspan="2"></td>' for slave in parent.slaves: td = '<td><span title="Successful builds">%s</span> '\ '<span title="(ignoring test suites failures)">(%s)</span> / '\ '<span title="Total">%s</span></td>' % tuple(slave_results[slave]) thead += td result += td thead += '</tr>\n</thead>\n' result += '</tr></tfoot>\n' result += '</table>' return thead+result
def body(self, request): parent = request.site.buildbot_service status = self.getStatus(request) result = '' result += '<table class="ProjectSummary">\n' # Headers slave_status = {} for slave in parent.slaves: for module in parent.modules: builder = status.getBuilder("%s-%s" % (module, slave)) state, builds = builder.getState() if state == 'offline': slave_status[slave] = ('offline', []) break elif state == 'building': if slave in slave_status: modules = slave_status[slave][1] or [] slave_status[slave] = (state, modules + [module]) else: slave_status[slave] = (state, [module]) else: if not slave in slave_status: slave_status[slave] = ('idle', None) if type(parent.moduleset) is list: moduleset = ', '.join(parent.moduleset) else: moduleset = parent.moduleset result += '<thead><tr><td> </td><th>' + moduleset + '</td>' for name in parent.slaves: if len(name) > 25: name = name[:25] + '(...)' klass, modules = slave_status.get(name) if klass == 'building': title = 'Building %s' % ', '.join(modules) else: title = klass result += '<th class="%s" title="%s"><a href="bots/%s">%s</a></th>' % ( klass, title, name, name) result += '</tr>' thead = result # stop it here as a row with totals will be added here once every rows # have been handled # Contents result = '<tbody>' slave_results = {} for slave in parent.slaves: slave_results[slave] = [0, 0, 0] for module in parent.modules: result += '<tr>' result += '<td class="feed"><a href="%s/atom">' % module result += '<img src="/feed.png" alt="Atom"></a></td>\n' result += '<th><a href="%s">%s</a></td>' % (module, module) for slave in parent.slaves: builder = status.getBuilder("%s-%s" % (module, slave)) box = ITopBox(builder).getBox(request) lastbuild = '' for bt in box.text: if bt == 'successful' or bt == 'failed': lastbuild = bt if lastbuild == 'successful': last_build = builder.getLastFinishedBuild() if last_build: class_ = build_get_class(last_build) else: class_ = 'success' lastbuild_label = 'Success' if last_build and class_: # use a different class/label if make check failed steps = last_build.getSteps() for step in reversed(steps): if step.name.split()[-1] == 'check': if step.results == WARNINGS: # make check failed class_ = 'failedchecks' lastbuild_label = 'Failed Checks' break elif lastbuild == 'failed': lastbuild_label = 'Failed' last_build = builder.getLastFinishedBuild() if last_build: class_ = build_get_class(last_build) else: class_ = 'failure' else: class_ = '' lastbuild_label = lastbuild state, builds = builder.getState() if state == 'building': result += '<td class="%s">%s</td>' % (state, state) else: result += '<td class="%s">%s</td>' % (class_, lastbuild_label) if lastbuild in ('failed', 'successful'): slave_results[slave][2] += 1 if class_ == 'failedchecks': slave_results[slave][1] += 1 elif lastbuild == 'successful': slave_results[slave][0] += 1 slave_results[slave][1] += 1 result += '</tr>\n' result += '</tbody>\n' result += '<tfoot><tr class="totals"><td colspan="2"></td>' thead += '<tr class="totals"><td colspan="2"></td>' for slave in parent.slaves: td = '<td><span title="Successful builds">%s</span> '\ '<span title="(ignoring test suites failures)">(%s)</span> / '\ '<span title="Total">%s</span></td>' % tuple(slave_results[slave]) thead += td result += td thead += '</tr>\n</thead>\n' result += '</tr></tfoot>\n' result += '</table>' return thead + result
def content(self, req, cxt): status = self.getStatus(req) # building = False # online = 0 req.setHeader("Cache-Control", "no-cache") # base_builders_url = "buildersresource/" base_builders_url = "builders/" cats = req.args.get("groups", False) if cats is not False: cats = cats.split(",") else: cats = None builders = req.args.get("builder", status.getBuilderNames(cats)) branches = [b for b in req.args.get("branch", []) if b] num_cols = get_args_int(req.args, "num", 5) cxt["num_cols"] = num_cols cxt["builders"] = [] builders_grouped = {} groups_seq = {} # sequence of groups for bn in builders: base_builder_url = base_builders_url + urllib.quote(bn, safe="") builder = status.getBuilder(bn) bld_props = status.botmaster.builders[bn].properties # hack into the structure categ = builder.category bname = bn if categ and bn.startswith(categ + "-"): bname = bname[len(categ) + 1 :] bname = html.escape(bname.replace("-", " ", 1)) bldr_cxt = {"name": bname, "url": base_builder_url, "builds": [], "sequence": bld_props.get("sequence", 10)} if categ: if bld_props.get("group_public", True): builders_grouped.setdefault(categ, []).append(bldr_cxt) if "group_seq" in bld_props: groups_seq[categ] = bld_props["group_seq"] else: cxt["builders"].append(bldr_cxt) # It is difficult to do paging here, because we are already iterating over the # builders, so won't have the same build names or rev-ids. builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=num_cols)) # builds.reverse() bldr_cxt["builds"] = [] for build in builds[:num_cols]: url = base_builder_url + "/builds/%d" % build.getNumber() build_cxt = {"url": url} bldr_cxt["builds"].append(build_cxt) try: ss = build.getSourceStamp() commiter = "" if list(build.getResponsibleUsers()): for who in build.getResponsibleUsers(): commiter += "%s" % html.escape(reduce_eml(who)) else: commiter += "No Commiter Found !" if ss.revision: revision = ss.revision label = "%s-%s: %s" % (str(revision), commiter, "".join(build.text)) except Exception: label = None if not label: label = "#%d" % build.getNumber() tftime = time.strftime("%a %d, %H:%M:%S", time.localtime(build.getTimes()[1])) ttitle = "Test at: %s\n%s" % (ustr(tftime), html.escape(ustr(build.getReason()))) class_b = "build%s" % build_get_class(build) build_cxt.update( { "label": label, "commiter": commiter, "tftime": tftime, "ttitle": ttitle, "last_t": ustr(last_change(ss, True)), "class_b": class_b, } ) builder_status = builder.getState()[0] bldr_cxt["status"] = builder_status # Now, sort the builders and grouped: cxt["builders"].sort(key=lambda bld: bld["sequence"]) for bldrs in builders_grouped.values(): bldrs.sort(key=lambda bld: bld["sequence"]) cxt["builders_grouped"] = [] # will be list of tuples for gk, bldrs in builders_grouped.items(): cxt["builders_grouped"].append((groups_seq.get(gk, 10), gk, bldrs)) template = req.site.buildbot_service.templates.get_template(self.tpl_page) return template.render(**cxt)
def content(self, req, cxt): status = self.getStatus(req) encoding = getRequestCharset(req) builders = req.args.get("builder", status.getBuilderNames()) branches = [b.decode(encoding) for b in req.args.get("branch", []) if b] # get counts of pending builds for each builder brstatus_ds = [] brcounts = {} def keep_count(statuses, builderName): brcounts[builderName] = len(statuses) for builderName in builders: builder_status = status.getBuilder(builderName) d = builder_status.getPendingBuildRequestStatuses() d.addCallback(keep_count, builderName) brstatus_ds.append(d) yield defer.gatherResults(brstatus_ds) cxt["branches"] = branches bs = cxt["builders"] = [] building = 0 online = 0 base_builders_url = path_to_root(req) + "builders/" for bn in builders: bld = {"link": base_builders_url + urllib.quote(bn, safe=""), "name": bn} bs.append(bld) builder = status.getBuilder(bn) builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if builds: b = builds[0] bld["build_url"] = bld["link"] + "/builds/%d" % b.getNumber() label = None all_got_revisions = b.getAllGotRevisions() # If len = 1 then try if revision can be used as label. if len(all_got_revisions) == 1: label = all_got_revisions[all_got_revisions.keys()[0]] if not label or len(str(label)) > 20: label = "#%d" % b.getNumber() bld["build_label"] = label bld["build_text"] = " ".join(b.getText()) bld["build_css_class"] = build_get_class(b) current_box = ICurrentBox(builder).getBox(status, brcounts) bld["current_box"] = current_box.td() builder_status = builder.getState()[0] if builder_status == "building": building += 1 online += 1 elif builder_status != "offline": online += 1 cxt["authz"] = self.getAuthz(req) cxt["num_building"] = building cxt["num_online"] = online buildForceContext(cxt, req, self.getBuildmaster(req)) template = req.site.buildbot_service.templates.get_template("builders.html") defer.returnValue(template.render(**cxt))
def body(self, req): status = self.getStatus(req) authz = self.getAuthz(req) builders = req.args.get( "builder", status.getBuilderNames(categories=self.categories)) branches = [b for b in req.args.get("branch", []) if b] if not branches: branches = ["trunk"] if branches and "trunk" not in branches: defaultCount = "1" else: defaultCount = "10" num_builds = int(req.args.get("num_builds", [defaultCount])[0]) tag = tags.div() tag(tags.script(src="txbuildbot.js")) tag( tags.h2(style="float:left; margin-top:0")("Latest builds: ", ", ".join(branches))) form = tags.form(method="get", action="", style="float:right", onsubmit="return checkBranch(branch.value)") form( tags.input(type="test", name="branch", placeholder=branches[0], size="40")) form(tags.input(type="submit", value="View")) if (yield authz.actionAllowed('forceAllBuilds', req)): # XXX: Unsafe interpolation form( tags.button(type="button", onclick="forceBranch(branch.value || %r, %r)" % ( branches[0], self.categories, ))("Force")) tag(form) table = tags.table(style="clear:both") tag(table) for bn in builders: builder = status.getBuilder(bn) state = builder.getState()[0] if state == 'building': state = 'idle' row = tags.tr() table(row) builderLink = path_to_builder(req, builder) row( tags.td(class_="box %s" % (state, ))( tags.a(href=builderLink)(bn))) builds = sorted([ build for build in builder.getCurrentBuilds() if build.getSourceStamp().branch in map_branches(branches) ], key=lambda build: build.getNumber(), reverse=True) builds.extend( builder.generateFinishedBuilds(map_branches(branches), num_builds=num_builds)) if builds: for b in builds: url = path_to_build(req, b) try: label = b.getProperty("got_revision") except KeyError: label = None # Label should never be "None", but sometimes # buildbot has disgusting bugs. if not label or label == "None" or len(str(label)) > 20: label = "#%d" % b.getNumber() if b.isFinished(): text = b.getText() else: when = b.getETA() if when: text = [ "%s" % (formatInterval(when), ), "%s" % (time.strftime( "%H:%M:%S", time.localtime(time.time() + when)), ) ] else: text = [] row( tags.td( align="center", bgcolor=_backgroundColors[b.getResults()], class_=("LastBuild box ", build_get_class(b)))([ (element, tags.br) for element in [tags.a(href=url)(label)] + text ])) else: row(tags.td(class_="LastBuild box")("no build")) defer.returnValue((yield flattenString(req, tag)))
def content(self, req, cxt): status = self.getStatus(req) encoding = getRequestCharset(req) showTags = req.args.get("tag", []) if not showTags: showTags = req.args.get("category", []) if not showTags: showTags = None builders = req.args.get("builder", status.getBuilderNames(tags=showTags)) branches = [ b.decode(encoding) for b in req.args.get("branch", []) if b ] # get counts of pending builds for each builder brstatus_ds = [] brcounts = {} def keep_count(statuses, builderName): brcounts[builderName] = len(statuses) for builderName in builders: builder_status = status.getBuilder(builderName) d = builder_status.getPendingBuildRequestStatuses() d.addCallback(keep_count, builderName) brstatus_ds.append(d) yield defer.gatherResults(brstatus_ds) cxt['branches'] = branches bs = cxt['builders'] = [] building = 0 online = 0 base_builders_url = path_to_root(req) + "builders/" for bn in builders: bld = { 'link': base_builders_url + urllib.quote(bn, safe=''), 'tags': status.getBuilder(bn).tags, 'name': bn } bs.append(bld) builder = status.getBuilder(bn) builds = list( builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if builds: b = builds[0] bld['build_url'] = (bld['link'] + "/builds/%d" % b.getNumber()) label = None all_got_revisions = b.getAllGotRevisions() # If len = 1 then try if revision can be used as label. if len(all_got_revisions) == 1: label = all_got_revisions[all_got_revisions.keys()[0]] if not label or len(str(label)) > 20: label = "#%d" % b.getNumber() bld['build_label'] = label bld['build_text'] = " ".join(b.getText()) bld['build_css_class'] = build_get_class(b) current_box = ICurrentBox(builder).getBox(status, brcounts) bld['current_box'] = current_box.td() builder_status = builder.getState()[0] if builder_status == "building": building += 1 online += 1 elif builder_status != "offline": online += 1 cxt['authz'] = self.getAuthz(req) cxt['num_building'] = building cxt['num_online'] = online buildForceContext(cxt, req, self.getBuildmaster(req)) template = req.site.buildbot_service.templates.get_template( "builders.html") defer.returnValue(template.render(**cxt))
def body(self, req): status = self.getStatus(req) control = self.getControl(req) builders = req.args.get("builder", status.getBuilderNames()) branches = [b for b in req.args.get("branch", []) if b] data = "" data += "<h2>Latest builds: %s</h2>\n" % ", ".join(branches) data += "<table>\n" building = False online = 0 base_builders_url = self.path_to_root(req) + "builders/" for bn in builders: base_builder_url = base_builders_url + urllib.quote(bn, safe='') builder = status.getBuilder(bn) data += "<tr>\n" data += '<td class="box"><a href="%s">%s</a></td>\n' \ % (base_builder_url, html.escape(bn)) builds = list( builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if builds: b = builds[0] url = (base_builder_url + "/builds/%d" % b.getNumber()) try: label = b.getProperty("got_revision") except KeyError: label = None if not label or len(str(label)) > 20: label = "#%d" % b.getNumber() text = ['<a href="%s">%s</a>' % (url, label)] text.extend(b.getText()) box = Box(text, b.getColor(), class_="LastBuild box %s" % build_get_class(b)) data += box.td(align="center") else: data += '<td class="LastBuild box" >no build</td>\n' current_box = ICurrentBox(builder).getBox(status) data += current_box.td(align="center") builder_status = builder.getState()[0] if builder_status == "building": building = True online += 1 elif builder_status != "offline": online += 1 data += "</table>\n" if control is not None: if building: stopURL = "builders/_all/stop" data += make_stop_form(stopURL, True, "Builds") if online: forceURL = "builders/_all/force" data += make_force_build_form(forceURL, True) return data
def content(self, req, cxt): status = self.getStatus(req) builders = req.args.get("builder", status.getBuilderNames()) branches = [b for b in req.args.get("branch", []) if b] # get counts of pending builds for each builder brstatus_ds = [] brcounts = {} def keep_count(statuses, builderName): brcounts[builderName] = len(statuses) for builderName in builders: builder_status = status.getBuilder(builderName) d = builder_status.getPendingBuildRequestStatuses() d.addCallback(keep_count, builderName) brstatus_ds.append(d) wfd = defer.waitForDeferred( defer.gatherResults(brstatus_ds)) yield wfd wfd.getResult() cxt['branches'] = branches bs = cxt['builders'] = [] building = 0 online = 0 base_builders_url = path_to_root(req) + "builders/" for bn in builders: bld = { 'link': base_builders_url + urllib.quote(bn, safe=''), 'name': bn } bs.append(bld) builder = status.getBuilder(bn) builds = list(builder.generateFinishedBuilds(map_branches(branches), num_builds=1)) if builds: b = builds[0] bld['build_url'] = (bld['link'] + "/builds/%d" % b.getNumber()) try: label = b.getProperty("got_revision") except KeyError: label = None if not label or len(str(label)) > 20: label = "#%d" % b.getNumber() bld['build_label'] = label bld['build_text'] = " ".join(b.getText()) bld['build_css_class'] = build_get_class(b) current_box = ICurrentBox(builder).getBox(status, brcounts) bld['current_box'] = current_box.td() builder_status = builder.getState()[0] if builder_status == "building": building += 1 online += 1 elif builder_status != "offline": online += 1 cxt['authz'] = self.getAuthz(req) cxt['num_building'] = building cxt['num_online'] = online template = req.site.buildbot_service.templates.get_template("builders.html") yield template.render(**cxt)