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 body(self, request): # summary of changes between this method and the overriden one: # - more structural markup and CSS # - removal of the phase stuff, only keep one "This method builds the main waterfall display." status = self.getStatus(request) data = '' projectName = status.getProjectName() projectURL = status.getProjectURL() # 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] (changeNames, builderNames, timestamps, eventGrid, sourceEvents) = \ self.buildGrid(request, builders) # start the table: top-header material data += '<table class="waterfall">\n' data += '<thead>\n' data += '<tr>\n' data += '<td colspan="2"></td>' for b in builders: state, builds = b.getState() builder_name = b.name[len(self.module_name) + 1:] data += '<th class="%s" title="%s"><a href="%s">%s</a></th>' % ( state, state, request.childLink('../builders/%s' % urllib.quote(b.name, safe='')), builder_name) data += '</tr>\n' data += '<tr>' data += '<th>time<br/>(%s)</th>' % time.tzname[time.localtime()[-1]] data += '<th class="Change">changes</th>' for b in builders: box = ITopBox(b).getBox(request) data += box.td(align="center") data += '</tr>' data += '</thead>' data += '<tbody>' data += self.phase2(request, changeNames + builderNames, timestamps, eventGrid, sourceEvents) data += '</tbody>\n' data += '<tfoot>\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: data += '<tr>' bottom = timestamps[-1] nextpage = with_args(request, ["last_time"], [("last_time", str(int(bottom)))]) data += '<td class="Time"><a href="%s">next page</a></td>\n' % nextpage data += '</tr>' data += '</tfoot>\n' data += "</table>\n" 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] # 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)] 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 data
def body(self, request): # summary of changes between this method and the overriden one: # - more structural markup and CSS # - removal of the phase stuff, only keep one "This method builds the main waterfall display." status = self.getStatus(request) data = "" projectName = status.getProjectName() projectURL = status.getProjectURL() # 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] (changeNames, builderNames, timestamps, eventGrid, sourceEvents) = self.buildGrid(request, builders) # start the table: top-header material data += '<table class="waterfall">\n' data += "<thead>\n" data += "<tr>\n" data += '<td colspan="2"></td>' for b in builders: state, builds = b.getState() builder_name = b.name[len(self.module_name) + 1 :] data += '<th class="%s" title="%s"><a href="%s">%s</a></th>' % ( state, state, request.childLink("../builders/%s" % urllib.quote(b.name, safe="")), builder_name, ) data += "</tr>\n" data += "<tr>" data += "<th>time<br/>(%s)</th>" % time.tzname[time.localtime()[-1]] data += '<th class="Change">changes</th>' for b in builders: box = ITopBox(b).getBox(request) data += box.td(align="center") data += "</tr>" data += "</thead>" data += "<tbody>" data += self.phase2(request, changeNames + builderNames, timestamps, eventGrid, sourceEvents) data += "</tbody>\n" data += "<tfoot>\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: data += "<tr>" bottom = timestamps[-1] nextpage = with_args(request, ["last_time"], [("last_time", str(int(bottom)))]) data += '<td class="Time"><a href="%s">next page</a></td>\n' % nextpage data += "</tr>" data += "</tfoot>\n" data += "</table>\n" return data