| Index: third_party/buildbot_7_12/buildbot/status/web/status_json.py
|
| diff --git a/third_party/buildbot_7_12/buildbot/status/web/status_json.py b/third_party/buildbot_7_12/buildbot/status/web/status_json.py
|
| deleted file mode 100644
|
| index 6c272a60fe9ce083df4dc56b6fc0872fcf86df69..0000000000000000000000000000000000000000
|
| --- a/third_party/buildbot_7_12/buildbot/status/web/status_json.py
|
| +++ /dev/null
|
| @@ -1,723 +0,0 @@
|
| -# -*- test-case-name: buildbot.test.test_web_status_json -*-
|
| -# Original Copyright (c) 2010 The Chromium Authors.
|
| -
|
| -"""Simple JSON exporter."""
|
| -
|
| -import datetime
|
| -import os
|
| -import re
|
| -
|
| -try:
|
| - import simplejson as json
|
| -except ImportError:
|
| - import json
|
| -
|
| -from buildbot.status.web.base import HtmlResource, StaticHTML
|
| -from twisted.web import error, html, resource
|
| -
|
| -
|
| -_IS_INT = re.compile('^[-+]?\d+$')
|
| -
|
| -
|
| -FLAGS = """Flags:
|
| - - as_text
|
| - - By default, application/json is used. Setting as_text=1 change the type
|
| - to text/plain and implicitly sets compact=0 and filter=1. Mainly useful to
|
| - look at the result in a web browser.
|
| - - compact
|
| - - By default, the json data is compact and defaults to 1. For easier to read
|
| - indented output, set compact=0.
|
| - - select
|
| - - By default, most children data is listed. You can do a random selection
|
| - of data by using select=<sub-url> multiple times to coagulate data.
|
| - "select=" includes the actual url otherwise it is skipped.
|
| - - filter
|
| - - Filters out null, false, and empty string, list and dict. This reduce the
|
| - amount of useless data sent.
|
| - - callback
|
| - - Enable uses of JSONP as described in
|
| - http://en.wikipedia.org/wiki/JSON#JSONP. Note that
|
| - Access-Control-Allow-Origin:* is set in the HTTP response header so you
|
| - can use this in compatible browsers.
|
| -"""
|
| -
|
| -EXAMPLES = """Examples:
|
| - - /json
|
| - - Root node, that *doesn't* mean all the data. Many things (like logs) must
|
| - be explicitly queried for performance reasons.
|
| - - /json/builders/
|
| - - All builders.
|
| - - /json/builders/<A_BUILDER>
|
| - - A specific builder as compact text.
|
| - - /json/builders/<A_BUILDER>/builds
|
| - - All *cached* builds.
|
| - - /json/builders/<A_BUILDER>/builds/_all
|
| - - All builds. Warning, reads all previous build data.
|
| - - /json/builders/<A_BUILDER>/builds/<A_BUILD>
|
| - - Where <A_BUILD> is either positive, a build number, or negative, a past
|
| - build.
|
| - - /json/builders/<A_BUILDER>/builds/-1/source_stamp/changes
|
| - - Build changes
|
| - - /json/builders/<A_BUILDER>/builds?select=-1&select=-2
|
| - - Two last builds on '<A_BUILDER>' builder.
|
| - - /json/builders/<A_BUILDER>/builds?select=-1/source_stamp/changes&select=-2/source_stamp/changes
|
| - - Changes of the two last builds on '<A_BUILDER>' builder.
|
| - - /json/builders/<A_BUILDER>/slaves
|
| - - Slaves associated to this builder.
|
| - - /json/builders/<A_BUILDER>?select=&select=slaves
|
| - - Builder information plus details information about its slaves. Neat eh?
|
| - - /json/slaves/<A_SLAVE>
|
| - - A specific slave.
|
| - - /json?select=slaves/<A_SLAVE>/&select=project&select=builders/<A_BUILDER>/builds/<A_BUILD>
|
| - - A selection of random unrelated stuff as an random example. :)
|
| -"""
|
| -
|
| -
|
| -def RequestArg(request, arg, default):
|
| - return request.args.get(arg, [default])[0]
|
| -
|
| -
|
| -def RequestArgToBool(request, arg, default):
|
| - value = RequestArg(request, arg, default)
|
| - if value in (False, True):
|
| - return value
|
| - value = value.lower()
|
| - if value in ('1', 'true'):
|
| - return True
|
| - if value in ('0', 'false'):
|
| - return False
|
| - # Ignore value.
|
| - return default
|
| -
|
| -
|
| -def TwistedWebErrorAsDict(self, request):
|
| - """Additional method for twisted.web.error.Error."""
|
| - result = {}
|
| - result['http_error'] = self.status
|
| - result['response'] = self.response
|
| - return result
|
| -
|
| -
|
| -def TwistedWebErrorPageAsDict(self, request):
|
| - """Additional method for twisted.web.error.Error."""
|
| - result = {}
|
| - result['http_error'] = self.code
|
| - result['response'] = self.brief
|
| - result['detail'] = self.detail
|
| - return result
|
| -
|
| -
|
| -# Add .asDict() method to twisted.web.error.Error to simplify the code below.
|
| -error.Error.asDict = TwistedWebErrorAsDict
|
| -error.PageRedirect.asDict = TwistedWebErrorAsDict
|
| -error.ErrorPage.asDict = TwistedWebErrorPageAsDict
|
| -error.NoResource.asDict = TwistedWebErrorPageAsDict
|
| -error.ForbiddenResource.asDict = TwistedWebErrorPageAsDict
|
| -
|
| -
|
| -def FilterOut(data):
|
| - """Returns a copy with None, False, "", [], () and {} removed.
|
| - Warning: converts tuple to list."""
|
| - if isinstance(data, (list, tuple)):
|
| - # Recurse in every items and filter them out.
|
| - items = map(FilterOut, data)
|
| - if not filter(lambda x: not x in ('', False, None, [], {}, ()), items):
|
| - return None
|
| - return items
|
| - elif isinstance(data, dict):
|
| - return dict(filter(lambda x: not x[1] in ('', False, None, [], {}, ()),
|
| - [(k, FilterOut(v)) for (k, v) in data.iteritems()]))
|
| - else:
|
| - return data
|
| -
|
| -
|
| -class JsonResource(resource.Resource):
|
| - """Base class for json data."""
|
| -
|
| - contentType = "application/json"
|
| - cache_seconds = 60
|
| - help = None
|
| - title = None
|
| - level = 0
|
| -
|
| - def __init__(self, status):
|
| - """Adds transparent lazy-child initialization."""
|
| - resource.Resource.__init__(self)
|
| - # buildbot.status.builder.Status
|
| - self.status = status
|
| - if self.help:
|
| - title = ''
|
| - if self.title:
|
| - title = self.title + ' help'
|
| - self.putChild('help',
|
| - HelpResource(self.help, title=title, parent_node=self))
|
| -
|
| - def getChildWithDefault(self, path, request):
|
| - """Adds transparent support for url ending with /"""
|
| - if path == "" and len(request.postpath) == 0:
|
| - return self
|
| - # Equivalent to resource.Resource.getChildWithDefault()
|
| - if self.children.has_key(path):
|
| - return self.children[path]
|
| - return self.getChild(path, request)
|
| -
|
| - def putChild(self, name, res):
|
| - """Adds the resource's level for help links generation."""
|
| -
|
| - def RecurseFix(res, level):
|
| - res.level = level + 1
|
| - for c in res.children.itervalues():
|
| - RecurseFix(c, res.level)
|
| -
|
| - RecurseFix(res, self.level)
|
| - resource.Resource.putChild(self, name, res)
|
| -
|
| - def render_GET(self, request):
|
| - """Renders a HTTP GET at the http request level."""
|
| - data = self.content(request)
|
| - if isinstance(data, unicode):
|
| - data = data.encode("utf-8")
|
| - request.setHeader("Access-Control-Allow-Origin", "*")
|
| - if RequestArgToBool(request, 'as_text', False):
|
| - request.setHeader("content-type", 'text/plain')
|
| - else:
|
| - request.setHeader("content-type", self.contentType)
|
| - request.setHeader("content-disposition",
|
| - "attachment; filename=\"%s.json\"" % request.path)
|
| - # Make sure we get fresh pages.
|
| - if self.cache_seconds:
|
| - now = datetime.datetime.utcnow()
|
| - expires = now + datetime.timedelta(seconds=self.cache_seconds)
|
| - request.setHeader("Expires",
|
| - expires.strftime("%a, %d %b %Y %H:%M:%S GMT"))
|
| - request.setHeader("Pragma", "no-cache")
|
| - return data
|
| -
|
| - def content(self, request):
|
| - """Renders the json dictionaries."""
|
| - # Supported flags.
|
| - select = request.args.get('select')
|
| - as_text = RequestArgToBool(request, 'as_text', False)
|
| - filter_out = RequestArgToBool(request, 'filter', as_text)
|
| - compact = RequestArgToBool(request, 'compact', not as_text)
|
| - callback = request.args.get('callback')
|
| -
|
| - # Implement filtering at global level and every child.
|
| - if select is not None:
|
| - del request.args['select']
|
| - # Do not render self.asDict()!
|
| - data = {}
|
| - # Remove superfluous /
|
| - select = [s.strip('/') for s in select]
|
| - select.sort(cmp=lambda x,y: cmp(x.count('/'), y.count('/')),
|
| - reverse=True)
|
| - for item in select:
|
| - # Start back at root.
|
| - node = data
|
| - # Implementation similar to twisted.web.resource.getChildForRequest
|
| - # but with a hacked up request.
|
| - child = self
|
| - prepath = request.prepath[:]
|
| - postpath = request.postpath[:]
|
| - request.postpath = filter(None, item.split('/'))
|
| - while request.postpath and not child.isLeaf:
|
| - pathElement = request.postpath.pop(0)
|
| - node[pathElement] = {}
|
| - node = node[pathElement]
|
| - request.prepath.append(pathElement)
|
| - child = child.getChildWithDefault(pathElement, request)
|
| - node.update(child.asDict(request))
|
| - request.prepath = prepath
|
| - request.postpath = postpath
|
| - else:
|
| - data = self.asDict(request)
|
| - if filter_out:
|
| - data = FilterOut(data)
|
| - if compact:
|
| - data = json.dumps(data, sort_keys=True, separators=(',',':'))
|
| - else:
|
| - data = json.dumps(data, sort_keys=True, indent=2)
|
| - if callback:
|
| - callback = callback[0]
|
| - if re.match(r'^[a-zA-Z$][a-zA-Z$0-9.]*$', callback):
|
| - data = '%s(%s);' % (callback, data)
|
| - return data
|
| -
|
| - def asDict(self, request):
|
| - """Generates the json dictionary.
|
| -
|
| - By default, renders every childs."""
|
| - if self.children:
|
| - data = {}
|
| - for name in self.children:
|
| - child = self.getChildWithDefault(name, request)
|
| - if isinstance(child, JsonResource):
|
| - data[name] = child.asDict(request)
|
| - # else silently pass over non-json resources.
|
| - return data
|
| - else:
|
| - raise NotImplementedError()
|
| -
|
| -
|
| -def ToHtml(text):
|
| - """Convert a string in a wiki-style format into HTML."""
|
| - indent = 0
|
| - in_item = False
|
| - output = []
|
| - for line in text.splitlines(False):
|
| - match = re.match(r'^( +)\- (.*)$', line)
|
| - if match:
|
| - if indent < len(match.group(1)):
|
| - output.append('<ul>')
|
| - indent = len(match.group(1))
|
| - elif indent > len(match.group(1)):
|
| - while indent > len(match.group(1)):
|
| - output.append('</ul>')
|
| - indent -= 2
|
| - if in_item:
|
| - # Close previous item
|
| - output.append('</li>')
|
| - output.append('<li>')
|
| - in_item = True
|
| - line = match.group(2)
|
| - elif indent:
|
| - if line.startswith((' ' * indent) + ' '):
|
| - # List continuation
|
| - line = line.strip()
|
| - else:
|
| - # List is done
|
| - if in_item:
|
| - output.append('</li>')
|
| - in_item = False
|
| - while indent > 0:
|
| - output.append('</ul>')
|
| - indent -= 2
|
| -
|
| - if line.startswith('/'):
|
| - if not '?' in line:
|
| - line_full = line + '?as_text=1'
|
| - else:
|
| - line_full = line + '&as_text=1'
|
| - output.append('<a href="' + html.escape(line_full) + '">' +
|
| - html.escape(line) + '</a>')
|
| - else:
|
| - output.append(html.escape(line).replace(' ', ' '))
|
| - if not in_item:
|
| - output.append('<br>')
|
| -
|
| - if in_item:
|
| - output.append('</li>')
|
| - while indent > 0:
|
| - output.append('</ul>')
|
| - indent -= 2
|
| - return '\n'.join(output)
|
| -
|
| -
|
| -class HelpResource(HtmlResource):
|
| - def __init__(self, text, title, parent_node):
|
| - HtmlResource.__init__(self)
|
| - self.text = text
|
| - self.title = title
|
| - self.parent_node = parent_node
|
| - self.rendered = False
|
| -
|
| - def body(self, request):
|
| - if not self.rendered:
|
| - self.text = ToHtml(self.text) + '<p>\n'
|
| - more_text = '<a href="../help">Parent\'s help</a><p>'
|
| - if len(self.parent_node.children) > 1:
|
| - more_text += '<p>Child nodes are:<ul>\n'
|
| - for (name, child) in self.parent_node.children.iteritems():
|
| - if name == 'help':
|
| - continue
|
| - name = html.escape(name)
|
| - more_text += (
|
| - '<li><a href="%s">%s</a> (<a href="%s/help">%s/help</a>)</li>\n' %
|
| - (name + '?as_text=1', name, name, name))
|
| - more_text += '</ul>\n'
|
| - self.text += more_text
|
| - examples = ToHtml(EXAMPLES).replace(
|
| - 'href="/json',
|
| - 'href="%sjson' % (self.level * '../'))
|
| - self.text += ToHtml(FLAGS) + '<p>' + examples
|
| - self.rendered = True
|
| - return self.text
|
| -
|
| -
|
| -class BuilderPendingBuildsJsonResource(JsonResource):
|
| - help = """Describe pending builds for a builder.
|
| -"""
|
| - title = 'Builder'
|
| -
|
| - def __init__(self, status, builder_status):
|
| - JsonResource.__init__(self, status)
|
| - self.builder_status = builder_status
|
| -
|
| - def asDict(self, request):
|
| - # buildbot.status.builder.BuilderStatus
|
| - return [b.asDict() for b in self.builder_status.getPendingBuilds()]
|
| -
|
| -
|
| -class BuilderJsonResource(JsonResource):
|
| - help = """Describe a single builder.
|
| -"""
|
| - title = 'Builder'
|
| -
|
| - def __init__(self, status, builder_status):
|
| - JsonResource.__init__(self, status)
|
| - self.builder_status = builder_status
|
| - self.putChild('builds', BuildsJsonResource(status, builder_status))
|
| - self.putChild('slaves', BuilderSlavesJsonResources(status,
|
| - builder_status))
|
| - self.putChild(
|
| - 'pendingBuilds',
|
| - BuilderPendingBuildsJsonResource(status, builder_status))
|
| -
|
| - def asDict(self, request):
|
| - # buildbot.status.builder.BuilderStatus
|
| - return self.builder_status.asDict()
|
| -
|
| -
|
| -class BuildersJsonResource(JsonResource):
|
| - help = """List of all the builders defined on a master.
|
| -"""
|
| - title = 'Builders'
|
| -
|
| - def __init__(self, status):
|
| - JsonResource.__init__(self, status)
|
| - for builder_name in self.status.getBuilderNames():
|
| - self.putChild(builder_name,
|
| - BuilderJsonResource(status,
|
| - status.getBuilder(builder_name)))
|
| -
|
| -
|
| -class BuilderSlavesJsonResources(JsonResource):
|
| - help = """Describe the slaves attached to a single builder.
|
| -"""
|
| - title = 'BuilderSlaves'
|
| -
|
| - def __init__(self, status, builder_status):
|
| - JsonResource.__init__(self, status)
|
| - self.builder_status = builder_status
|
| - for slave_name in self.builder_status.slavenames:
|
| - self.putChild(slave_name,
|
| - SlaveJsonResource(status,
|
| - self.status.getSlave(slave_name)))
|
| -
|
| -
|
| -class BuildJsonResource(JsonResource):
|
| - help = """Describe a single build.
|
| -"""
|
| - title = 'Build'
|
| -
|
| - def __init__(self, status, build_status):
|
| - JsonResource.__init__(self, status)
|
| - self.build_status = build_status
|
| - self.putChild('source_stamp',
|
| - SourceStampJsonResource(status,
|
| - build_status.getSourceStamp()))
|
| - self.putChild('steps', BuildStepsJsonResource(status, build_status))
|
| -
|
| - def asDict(self, request):
|
| - return self.build_status.asDict()
|
| -
|
| -
|
| -class AllBuildsJsonResource(JsonResource):
|
| - help = """All the builds that were run on a builder.
|
| -"""
|
| - title = 'AllBuilds'
|
| -
|
| - def __init__(self, status, builder_status):
|
| - JsonResource.__init__(self, status)
|
| - self.builder_status = builder_status
|
| -
|
| - def getChild(self, path, request):
|
| - # Dynamic childs.
|
| - if isinstance(path, int) or _IS_INT.match(path):
|
| - build_status = self.builder_status.getBuild(int(path))
|
| - if build_status:
|
| - build_status_number = str(build_status.getNumber())
|
| - # Happens with negative numbers.
|
| - child = self.children.get(build_status_number)
|
| - if child:
|
| - return child
|
| - # Create it on-demand.
|
| - child = BuildJsonResource(self.status, build_status)
|
| - # Cache it. Never cache negative numbers.
|
| - # TODO(maruel): Cleanup the cache once it's too heavy!
|
| - self.putChild(build_status_number, child)
|
| - return child
|
| - return JsonResource.getChild(self, path, request)
|
| -
|
| - def asDict(self, request):
|
| - results = {}
|
| - # If max > buildCacheSize, it'll trash the cache...
|
| - max = int(RequestArg(request, 'max',
|
| - self.builder_status.buildCacheSize))
|
| - for i in range(0, max):
|
| - child = self.getChildWithDefault(-i, request)
|
| - if not isinstance(child, BuildJsonResource):
|
| - continue
|
| - results[child.build_status.getNumber()] = child.asDict(request)
|
| - return results
|
| -
|
| -
|
| -class BuildsJsonResource(AllBuildsJsonResource):
|
| - help = """Builds that were run on a builder.
|
| -"""
|
| - title = 'Builds'
|
| -
|
| - def __init__(self, status, builder_status):
|
| - AllBuildsJsonResource.__init__(self, status, builder_status)
|
| - self.putChild('_all', AllBuildsJsonResource(status, builder_status))
|
| -
|
| - def getChild(self, path, request):
|
| - # Transparently redirects to _all if path is not ''.
|
| - return self.children['_all'].getChildWithDefault(path, request)
|
| -
|
| - def asDict(self, request):
|
| - # This would load all the pickles and is way too heavy, especially that
|
| - # it would trash the cache:
|
| - # self.children['builds'].asDict(request)
|
| - # TODO(maruel) This list should also need to be cached but how?
|
| - builds = dict([
|
| - (int(file), None)
|
| - for file in os.listdir(self.builder_status.basedir)
|
| - if _IS_INT.match(file)
|
| - ])
|
| - return builds
|
| -
|
| -
|
| -class BuildStepJsonResource(JsonResource):
|
| - help = """A single build step.
|
| -"""
|
| - title = 'BuildStep'
|
| -
|
| - def __init__(self, status, build_step_status):
|
| - # buildbot.status.builder.BuildStepStatus
|
| - JsonResource.__init__(self, status)
|
| - self.build_step_status = build_step_status
|
| - # TODO self.putChild('logs', LogsJsonResource())
|
| -
|
| - def asDict(self, request):
|
| - return self.build_step_status.asDict()
|
| -
|
| -
|
| -class BuildStepsJsonResource(JsonResource):
|
| - help = """A list of build steps that occurred during a build.
|
| -"""
|
| - title = 'BuildSteps'
|
| -
|
| - def __init__(self, status, build_status):
|
| - JsonResource.__init__(self, status)
|
| - self.build_status = build_status
|
| - # The build steps are constantly changing until the build is done so
|
| - # keep a reference to build_status instead
|
| -
|
| - def getChild(self, path, request):
|
| - # Dynamic childs.
|
| - build_set_status = None
|
| - if isinstance(path, int) or _IS_INT.match(path):
|
| - build_set_status = self.build_status.getSteps[int(path)]
|
| - else:
|
| - steps_dict = dict([(step.getName(), step)
|
| - for step in self.build_status.getStep()])
|
| - build_set_status = steps_dict.get(path)
|
| - if build_set_status:
|
| - # Create it on-demand.
|
| - child = BuildStepJsonResource(status, build_step_status)
|
| - # Cache it.
|
| - index = self.build_status.getSteps().index(build_step_status)
|
| - self.putChild(str(index), child)
|
| - self.putChild(build_set_status.getName(), child)
|
| - return child
|
| - return JsonResource.getChild(self, path, request)
|
| -
|
| - def asDict(self, request):
|
| - # Only use the number and not the names!
|
| - results = {}
|
| - index = 0
|
| - for step in self.build_status.getStep():
|
| - results[index] = step
|
| - index += 1
|
| - return results
|
| -
|
| -
|
| -class ChangeJsonResource(JsonResource):
|
| - help = """Describe a single change that originates from a change source.
|
| -"""
|
| - title = 'Change'
|
| -
|
| - def __init__(self, status, change):
|
| - # buildbot.changes.changes.Change
|
| - JsonResource.__init__(self, status)
|
| - self.change = change
|
| -
|
| - def asDict(self, request):
|
| - return self.change.asDict()
|
| -
|
| -
|
| -class ChangesJsonResource(JsonResource):
|
| - help = """List of changes.
|
| -"""
|
| - title = 'Changes'
|
| -
|
| - def __init__(self, status, changes):
|
| - JsonResource.__init__(self, status)
|
| - for c in changes:
|
| - # c.number can be None or clash another change if the change was
|
| - # generated inside buildbot or if using multiple pollers.
|
| - if c.number is not None and str(c.number) not in self.children:
|
| - self.putChild(str(c.number), ChangeJsonResource(status, c))
|
| - else:
|
| - # Temporary hack since it creates information exposure.
|
| - self.putChild(str(id(c)), ChangeJsonResource(status, c))
|
| -
|
| - def asDict(self, request):
|
| - """Don't throw an exception when there is no child."""
|
| - if not self.children:
|
| - return {}
|
| - return JsonResource.asDict(self, request)
|
| -
|
| -
|
| -class ChangeSourcesJsonResource(JsonResource):
|
| - help = """Describe a change source.
|
| -"""
|
| - title = 'ChangeSources'
|
| -
|
| - def asDict(self, request):
|
| - result = {}
|
| - n = 0
|
| - for c in self.status.getChangeSources():
|
| - # buildbot.changes.changes.ChangeMaster
|
| - change = {}
|
| - change['description'] = c.describe()
|
| - result[n] = change
|
| - n += 1
|
| - return result
|
| -
|
| -
|
| -class ProjectJsonResource(JsonResource):
|
| - help = """Project-wide settings.
|
| -"""
|
| - title = 'Project'
|
| -
|
| - def asDict(self, request):
|
| - return self.status.asDict()
|
| -
|
| -
|
| -class SlaveJsonResource(JsonResource):
|
| - help = """Describe a slave.
|
| -"""
|
| - title = 'Slave'
|
| -
|
| - def __init__(self, status, slave_status):
|
| - JsonResource.__init__(self, status)
|
| - self.slave_status = slave_status
|
| - self.name = self.slave_status.getName()
|
| - self.builders = None
|
| -
|
| - def getBuilders(self):
|
| - if self.builders is None:
|
| - # Figure out all the builders to which it's attached
|
| - self.builders = []
|
| - for builderName in self.status.getBuilderNames():
|
| - if self.name in self.status.getBuilder(builderName).slavenames:
|
| - self.builders.append(builderName)
|
| - return self.builders
|
| -
|
| - def asDict(self, request):
|
| - results = self.slave_status.asDict()
|
| - # Enhance it by adding more informations.
|
| - results['builders'] = {}
|
| - for builderName in self.getBuilders():
|
| - builds = []
|
| - builder_status = self.status.getBuilder(builderName)
|
| - for i in range(1, builder_status.buildCacheSize - 1):
|
| - build_status = builder_status.getBuild(-i)
|
| - if not build_status or not build_status.isFinished():
|
| - # If not finished, it will appear in runningBuilds.
|
| - break
|
| - if build_status.getSlavename() == self.name:
|
| - builds.append(build_status.getNumber())
|
| - results['builders'][builderName] = builds
|
| - return results
|
| -
|
| -
|
| -class SlavesJsonResource(JsonResource):
|
| - help = """List the registered slaves.
|
| -"""
|
| - title = 'Slaves'
|
| -
|
| - def __init__(self, status):
|
| - JsonResource.__init__(self, status)
|
| - for slave_name in status.getSlaveNames():
|
| - self.putChild(slave_name,
|
| - SlaveJsonResource(status,
|
| - status.getSlave(slave_name)))
|
| -
|
| -
|
| -class SourceStampJsonResource(JsonResource):
|
| - help = """Describe the sources for a BuildRequest.
|
| -"""
|
| - title = 'SourceStamp'
|
| -
|
| - def __init__(self, status, source_stamp):
|
| - # buildbot.sourcestamp.SourceStamp
|
| - JsonResource.__init__(self, status)
|
| - self.source_stamp = source_stamp
|
| - self.putChild('changes',
|
| - ChangesJsonResource(status, source_stamp.changes))
|
| - # TODO(maruel): Should redirect to the patch's url instead.
|
| - #if source_stamp.patch:
|
| - # self.putChild('patch', StaticHTML(source_stamp.path))
|
| -
|
| - def asDict(self, request):
|
| - return self.source_stamp.asDict()
|
| -
|
| -
|
| -class JsonStatusResource(JsonResource):
|
| - """Retrieves all json data."""
|
| - help = """JSON status
|
| -
|
| -Root page to give a fair amount of information in the current buildbot master
|
| -status. You may want to use a child instead to reduce the load on the server.
|
| -
|
| -For help on any sub directory, use url /child/help
|
| -"""
|
| - title = 'Buildbot JSON'
|
| -
|
| - def __init__(self, status):
|
| - JsonResource.__init__(self, status)
|
| - self.level = 1
|
| - self.putChild('builders', BuildersJsonResource(status))
|
| - self.putChild('change_sources', ChangeSourcesJsonResource(status))
|
| - self.putChild('project', ProjectJsonResource(status))
|
| - self.putChild('slaves', SlavesJsonResource(status))
|
| - # This needs to be called before the first HelpResource().body call.
|
| - self.HackExamples()
|
| -
|
| - def content(self, request):
|
| - result = JsonResource.content(self, request)
|
| - # This is done to hook the downloaded filename.
|
| - request.path = 'buildbot'
|
| - return result
|
| -
|
| - def HackExamples(self):
|
| - global EXAMPLES
|
| - # Find the first builder with a previous build or select the last one.
|
| - builder = None
|
| - for b in self.status.getBuilderNames():
|
| - builder = self.status.getBuilder(b)
|
| - if builder.getBuild(-1):
|
| - break
|
| - if not builder:
|
| - return
|
| - EXAMPLES = EXAMPLES.replace('<A_BUILDER>', builder.getName())
|
| - build = builder.getBuild(-1)
|
| - if build:
|
| - EXAMPLES = EXAMPLES.replace('<A_BUILD>', str(build.getNumber()))
|
| - if builder.slavenames:
|
| - EXAMPLES = EXAMPLES.replace('<A_SLAVE>', builder.slavenames[0])
|
| -
|
| -# vim: set ts=4 sts=4 sw=4 et:
|
|
|