📄 waterfall.py
字号:
show_events_input = ('<p>' '<input type="checkbox" name="show_events" ' 'value="false" %s>' 'Hide non-Build events' '</p>\n' ) % showEvents_checked branches = [b for b in request.args.get("branch", []) if b] branches.append('') show_branches_input = '<table>\n' for b in branches: show_branches_input += ('<tr>' '<td>Show Branch: ' '<input type="text" name="branch" ' 'value="%s">' '</td></tr>\n' ) % (b,) show_branches_input += '</table>\n' # this has a set of toggle-buttons to let the user choose the # builders showBuilders = request.args.get("show", []) showBuilders.extend(request.args.get("builder", [])) allBuilders = status.getBuilderNames(categories=self.categories) show_builders_input = '<table>\n' for bn in allBuilders: checked = "" if bn in showBuilders: checked = 'checked="checked"' show_builders_input += ('<tr>' '<td><input type="checkbox"' ' name="builder" ' 'value="%s" %s></td> ' '<td>%s</td></tr>\n' ) % (bn, checked, bn) show_builders_input += '</table>\n' # a couple of radio-button selectors for refresh time will appear # just after that text show_reload_input = '<table>\n' times = [("none", "None"), ("60", "60 seconds"), ("300", "5 minutes"), ("600", "10 minutes"), ] current_reload_time = request.args.get("reload", ["none"]) if current_reload_time: current_reload_time = current_reload_time[0] if current_reload_time not in [t[0] for t in times]: times.insert(0, (current_reload_time, current_reload_time) ) for value, name in times: checked = "" if value == current_reload_time: checked = 'checked="checked"' show_reload_input += ('<tr>' '<td><input type="radio" name="reload" ' 'value="%s" %s></td> ' '<td>%s</td></tr>\n' ) % (value, checked, name) show_reload_input += '</table>\n' fields = {"show_events_input": show_events_input, "show_branches_input": show_branches_input, "show_builders_input": show_builders_input, "show_reload_input": show_reload_input, } data += HELP % fields return dataclass WaterfallStatusResource(HtmlResource): """This builds the main status page, with the waterfall display, and all child pages.""" def __init__(self, categories=None): HtmlResource.__init__(self) self.categories = categories self.putChild("help", WaterfallHelp(categories)) def getTitle(self, request): status = self.getStatus(request) p = status.getProjectName() if p: return "BuildBot: %s" % p else: return "BuildBot" def getChangemaster(self, request): # TODO: this wants to go away, access it through IStatus return request.site.buildbot_service.getChangeSvc() def get_reload_time(self, request): if "reload" in request.args: try: reload_time = int(request.args["reload"][0]) return max(reload_time, 15) except ValueError: pass return None def head(self, request): head = '' reload_time = self.get_reload_time(request) if reload_time is not None: head += '<meta http-equiv="refresh" content="%d">\n' % reload_time return head 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 data def body0(self, request, builders): # build the waterfall display data = "" data += "<h2>Basic display</h2>\n" data += '<p>See <a href="%s">here</a>' % request.childLink("../waterfall") data += " for the waterfall display</p>\n" data += '<table border="0" cellspacing="0">\n' names = map(lambda builder: builder.name, builders) # the top row is two blank spaces, then the top-level status boxes data += " <tr>\n" data += td("", colspan=2) for b in builders: text = "" state, builds = b.getState() if state != "offline": text += "%s<br />\n" % state #b.getCurrentBig().text[0] else: text += "OFFLINE<br />\n" data += td(text, align="center") # the next row has the column headers: time, changes, builder names data += " <tr>\n" data += td("Time", align="center") data += td("Changes", align="center") for name in names: data += td('<a href="%s">%s</a>' % (request.childLink("../" + urllib.quote(name)), name), align="center") data += " </tr>\n" # all further rows involve timestamps, commit events, and build events data += " <tr>\n" data += td("04:00", align="bottom") data += td("fred", align="center") for name in names: data += td("stuff", align="center") data += " </tr>\n" data += "</table>\n" return data def buildGrid(self, request, builders): debug = False # TODO: see if we can use a cached copy showEvents = False if request.args.get("show_events", ["true"])[0].lower() == "true": showEvents = True filterBranches = [b for b in request.args.get("branch", []) if b] filterBranches = map_branches(filterBranches) maxTime = int(request.args.get("last_time", [util.now()])[0]) if "show_time" in request.args: minTime = maxTime - int(request.args["show_time"][0]) elif "first_time" in request.args: minTime = int(request.args["first_time"][0]) else: minTime = None
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -