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) 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 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 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"] = online cxt["num_online"] = online template = req.site.buildbot_service.templates.get_template("builders.html") return 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 body(self, request): "This method builds the main waterfall display." status = self.getStatus(request) data = '' projectName = status.getProjectName() projectURL = status.getProjectURL() phase = request.args.get("phase", ["2"]) phase = int(phase[0]) # we start with all Builders available to this Waterfall: this is # limited by the config-file -time categories= argument, and defaults # to all defined Builders. allBuilderNames = status.getBuilderNames(categories=self.categories) builders = [status.getBuilder(name) for name in allBuilderNames] # but if the URL has one or more builder= arguments (or the old show= # argument, which is still accepted for backwards compatibility), we # use that set of builders instead. We still don't show anything # outside the config-file time set limited by categories=. showBuilders = request.args.get("show", []) showBuilders.extend(request.args.get("builder", [])) if showBuilders: builders = [b for b in builders if b.name in showBuilders] # now, if the URL has one or category= arguments, use them as a # filter: only show those builders which belong to one of the given # categories. showCategories = request.args.get("category", []) if showCategories: builders = [b for b in builders if b.category in showCategories] builderNames = [b.name for b in builders] if phase == -1: return self.body0(request, builders) (changeNames, builderNames, timestamps, eventGrid, sourceEvents) = \ self.buildGrid(request, builders) if phase == 0: return self.phase0(request, (changeNames + builderNames), timestamps, eventGrid) # start the table: top-header material data += '<table border="0" cellspacing="0">\n' if projectName and projectURL: # TODO: this is going to look really ugly topleft = '<a href="%s">%s</a><br />last build' % \ (projectURL, projectName) else: topleft = "last build" data += ' <tr class="LastBuild">\n' data += td(topleft, align="right", colspan=2, class_="Project") for b in builders: box = ITopBox(b).getBox(request) data += box.td(align="center") data += " </tr>\n" data += ' <tr class="Activity">\n' data += td('current activity', align='right', colspan=2) for b in builders: box = ICurrentBox(b).getBox(status) data += box.td(align="center") data += " </tr>\n" data += " <tr>\n" TZ = time.tzname[time.localtime()[-1]] data += td("time (%s)" % TZ, align="center", class_="Time") data += td('<a href="%s">changes</a>' % request.childLink("../changes"), align="center", class_="Change") for name in builderNames: safename = urllib.quote(name, safe='') data += td('<a href="%s">%s</a>' % (request.childLink("../builders/%s" % safename), name), align="center", class_="Builder") data += " </tr>\n" if phase == 1: f = self.phase1 else: f = self.phase2 data += f(request, changeNames + builderNames, timestamps, eventGrid, sourceEvents) data += "</table>\n" data += '<hr /><div class="footer">\n' def with_args(req, remove_args=[], new_args=[], new_path=None): # sigh, nevow makes this sort of manipulation easier newargs = req.args.copy() for argname in remove_args: newargs[argname] = [] if "branch" in newargs: newargs["branch"] = [b for b in newargs["branch"] if b] for k, v in new_args: if k in newargs: newargs[k].append(v) else: newargs[k] = [v] newquery = "&".join( ["%s=%s" % (k, v) for k in newargs for v in newargs[k]]) if new_path: new_url = new_path elif req.prepath: new_url = req.prepath[-1] else: new_url = '' if newquery: new_url += "?" + newquery return new_url if timestamps: bottom = timestamps[-1] nextpage = with_args(request, ["last_time"], [("last_time", str(int(bottom)))]) data += '[<a href="%s">next page</a>]\n' % nextpage helpurl = self.path_to_root(request) + "waterfall/help" helppage = with_args(request, new_path=helpurl) data += '[<a href="%s">help</a>]\n' % helppage welcomeurl = self.path_to_root(request) + "index.html" data += '[<a href="%s">welcome</a>]\n' % welcomeurl if self.get_reload_time(request) is not None: no_reload_page = with_args(request, remove_args=["reload"]) data += '[<a href="%s">Stop Reloading</a>]\n' % no_reload_page data += "<br />\n" bburl = "http://buildbot.net/?bb-ver=%s" % urllib.quote(version) data += '<a href="%s">Buildbot-%s</a> ' % (bburl, 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" # TODO: push this to the right edge, if possible data += ("Page built: " + time.strftime( "%a %d %b %Y %H:%M:%S", time.localtime(util.now())) + "\n") data += '</div>\n' return "%s %s" % (self.GetAnnounce(), data)
def content_with_db_data(self, changes, brcounts, request, ctx): status = self.getStatus(request) ctx['refresh'] = self.get_reload_time(request) # we start with all Builders available to this Waterfall: this is # limited by the config-file -time categories= argument, and defaults # to all defined Builders. allBuilderNames = status.getBuilderNames(categories=self.categories) builders = [status.getBuilder(name) for name in allBuilderNames] # but if the URL has one or more builder= arguments (or the old show= # argument, which is still accepted for backwards compatibility), we # use that set of builders instead. We still don't show anything # outside the config-file time set limited by categories=. showBuilders = request.args.get("show", []) showBuilders.extend(request.args.get("builder", [])) if showBuilders: builders = [b for b in builders if b.name in showBuilders] # now, if the URL has one or category= arguments, use them as a # filter: only show those builders which belong to one of the given # categories. showCategories = request.args.get("category", []) if showCategories: builders = [b for b in builders if b.category in showCategories] # If the URL has the failures_only=true argument, we remove all the # builders that are not currently red or won't be turning red at the end # of their current run. failuresOnly = request.args.get("failures_only", ["false"])[0] if failuresOnly.lower() == "true": builders = [b for b in builders if not self.isSuccess(b)] (changeNames, builderNames, timestamps, eventGrid, sourceEvents) = \ self.buildGrid(request, builders, changes) # start the table: top-header material locale_enc = locale.getdefaultlocale()[1] if locale_enc is not None: locale_tz = unicode(time.tzname[time.localtime()[-1]], locale_enc) else: locale_tz = unicode(time.tzname[time.localtime()[-1]]) ctx['tz'] = locale_tz ctx['changes_url'] = request.childLink("../changes") bn = ctx['builders'] = [] for name in builderNames: builder = status.getBuilder(name) top_box = ITopBox(builder).getBox(request) current_box = ICurrentBox(builder).getBox(status, brcounts) bn.append({'name': name, 'url': request.childLink("../builders/%s" % urllib.quote(name, safe='')), 'top': top_box.text, 'top_class': top_box.class_, 'status': current_box.text, 'status_class': current_box.class_, }) ctx.update(self.phase2(request, changeNames + builderNames, timestamps, eventGrid, sourceEvents)) def with_args(req, remove_args=[], new_args=[], new_path=None): # sigh, nevow makes this sort of manipulation easier newargs = req.args.copy() for argname in remove_args: newargs[argname] = [] if "branch" in newargs: newargs["branch"] = [b for b in newargs["branch"] if b] for k,v in new_args: if k in newargs: newargs[k].append(v) else: newargs[k] = [v] newquery = "&".join(["%s=%s" % (urllib.quote(k), urllib.quote(v)) for k in newargs for v in newargs[k] ]) if new_path: new_url = new_path elif req.prepath: new_url = req.prepath[-1] else: new_url = '' if newquery: new_url += "?" + newquery return new_url if timestamps: bottom = timestamps[-1] ctx['nextpage'] = with_args(request, ["last_time"], [("last_time", str(int(bottom)))]) helpurl = path_to_root(request) + "waterfall/help" ctx['help_url'] = with_args(request, new_path=helpurl) if self.get_reload_time(request) is not None: ctx['no_reload_page'] = with_args(request, remove_args=["reload"]) template = request.site.buildbot_service.templates.get_template("waterfall.html") data = template.render(**ctx) return data
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 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)
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): 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