Skip to content

Commit

Permalink
Add asDict() member function to many status classes
Browse files Browse the repository at this point in the history
This is to ease json output generation.

Conflicts:

	buildbot/sourcestamp.py
  • Loading branch information
maruel committed Feb 9, 2010
1 parent 251205c commit 4c019d6
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 2 deletions.
20 changes: 19 additions & 1 deletion buildbot/changes/changes.py
Expand Up @@ -130,13 +130,29 @@ def getFileContents(self):
for f in self.files:
data += " %s\n" % f
return data

def getProperties(self):
data = ""
for prop in self.properties.asList():
data += " %s: %s" % (prop[0], prop[1])
return data

def asDict(self):
result = {}
# Constant
result['number'] = self.number
result['branch'] = self.branch
result['category'] = self.category
result['who'] = self.getShortAuthor()
result['comments'] = self.comments
result['revision'] = self.revision
result['when'] = self.when
result['files'] = self.files
result['revlink'] = self.revlink
result['properties'] = self.properties.asList()
return result


class ChangeMaster(service.MultiService):

"""This is the master-side service which receives file change
Expand Down Expand Up @@ -280,3 +296,5 @@ class TestChangeMaster(ChangeMaster):
"""A ChangeMaster for use in tests that does not save itself"""
def stopService(self):
return service.MultiService.stopService(self)

# vim: set ts=4 sts=4 sw=4 et:
14 changes: 13 additions & 1 deletion buildbot/sourcestamp.py
Expand Up @@ -94,7 +94,7 @@ def getText(self):
if self.patch:
text.append("[patch]")
return text

def getHTMLDict(self):
if self.revision is None:
return dict(rev='latest')
Expand All @@ -104,3 +104,15 @@ def getHTMLDict(self):
if self.patch:
d['patch'] = True
return d

def asDict(self):
result = {}
# Constant
result['revision'] = self.revision
# TODO(maruel): Make the patch content a suburl.
result['patch'] = self.patch
result['branch'] = self.branch
result['changes'] = [c.asDict() for c in getattr(self, 'changes', [])]
return result

# vim: set ts=4 sts=4 sw=4 et:
106 changes: 106 additions & 0 deletions buildbot/status/builder.py
Expand Up @@ -774,6 +774,17 @@ def getSubmitTime(self):
def setSubmitTime(self, t):
self.submittedAt = t

def asDict(self):
result = {}
# Constant
result['source'] = self.source.asDict()
result['builderName'] = self.getBuilderName()
result['submittedAt'] = self.getSubmitTime()

# Transient
result['builds'] = [build.asDict() for build in self.getBuilds()]
return result


class BuildStepStatus(styles.Versioned):
"""
Expand Down Expand Up @@ -1069,6 +1080,26 @@ def upgradeToVersion2(self):
if not hasattr(self, "statistics"):
self.statistics = {}

def asDict(self):
result = {}
# Constant
result['name'] = self.getName()

# Transient
result['text'] = self.getText()
result['results'] = self.getResults()
result['is_started'] = self.isStarted()
result['is_finished'] = self.isFinished()
result['statistics'] = self.statistics
result['times'] = self.getTimes()
result['expectations'] = self.getExpectations()
result['eta'] = self.getETA()
result['urls'] = self.getURLs()
# TODO(maruel): Move that to a sub-url or just publish the log_url
# instead.
#result['logs'] = self.getLogs()
return result


class BuildStatus(styles.Versioned):
implements(interfaces.IBuildStatus, interfaces.IStatusEvent)
Expand Down Expand Up @@ -1478,6 +1509,34 @@ def saveYourself(self):
self.number))
log.err()

def asDict(self):
result = {}
# Constant
result['number'] = self.getNumber()
result['source_stamp'] = self.getSourceStamp().asDict()
result['reason'] = self.getReason()
result['requests'] = [r.asDict() for r in self.getRequests()]
result['blame'] = self.getResponsibleUsers()
result['changes'] = [c.asText() for c in self.getChanges()]

# Transient
result['properties'] = self.getProperties().asList()
result['times'] = self.getTimes()
result['text'] = self.getText()
result['results'] = self.getResults()
result['slave'] = self.getSlavename()
# TODO(maruel): Add.
#result['test_results'] = self.getTestResults()
# TODO(maruel): Include the url? It's too heavy otherwise.
#result['logs'] = self.getLogs()
result['eta'] = self.getETA()
result['steps'] = [bss.asDict() for bss in self.steps]
if self.getCurrentStep():
result['current_step'] = self.getCurrentStep().asDict()
else:
result['current_step'] = None
return result



class BuilderStatus(styles.Versioned):
Expand Down Expand Up @@ -2045,6 +2104,32 @@ def removeClient(self, client):
if client in self.subscribers:
self.subscribers.remove(client)

def asDict(self):
result = {}
# Constant
# TODO(maruel): Fix me. We don't want to leak the full path.
result['basedir'] = os.path.basename(self.basedir)
result['category'] = self.category
result['slaves'] = self.slavenames
#result['url'] = self.parent.getURLForThing(self)
# TODO(maruel): Add cache settings? Do we care?

# Transient
# Collect build numbers.
# Important: Only grab the *cached* builds numbers to reduce I/O.
current_builds = [b.getNumber() for b in self.currentBuilds]
cached_builds = list(set(self.buildCache.keys() + current_builds))
cached_builds.sort()
result['cached_builds'] = cached_builds
result['current_builds'] = current_builds
result['state'] = self.getState()[0]
# BuildRequestStatus doesn't have a number so display the SourceStamp.
result['pending_builds'] = [
b.getSourceStamp().asDict() for b in self.getPendingBuilds()
]
return result


class SlaveStatus:
implements(interfaces.ISlaveStatus)

Expand Down Expand Up @@ -2115,6 +2200,16 @@ def removeGracefulWatcher(self, watcher):
if watcher in self.graceful_callbacks:
self.graceful_callbacks.remove(watcher)

def asDict(self):
result = {}
# Transient
result['host'] = self.getHost()
result['admin'] = self.getAdmin()
result['version'] = self.getVersion()
result['connected'] = self.isConnected()
return result


class Status:
"""
I represent the status of the buildmaster.
Expand Down Expand Up @@ -2381,3 +2476,14 @@ def buildsetSubmitted(self, bss):
def changeAdded(self, change):
for t in self.watchers:
t.changeAdded(change)

def asDict(self):
result = {}
# Constant
result['name'] = self.getProjectName()
result['url'] = self.getProjectURL()
# TODO: self.getSchedulers()
# self.getChangeSources()
return result

# vim: set ts=4 sts=4 sw=4 et:

5 comments on commit 4c019d6

@marcus-sonestedt
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The htmlDict() function that many of these has wasn't good enough? It feels a bit silly to have two return-as-dict functions in change and sourcestamp.

Maybe the jinja-templates need some modification to suit the json-stuff, but surely we could re-use more code here, no?

Most WebStatus pages build plain dicts, and I had planned to implement some logic to optionally return a json string based on that.

@maruel
Copy link
Author

@maruel maruel commented on 4c019d6 Feb 12, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

html_dict() wasn't on 0.7.12 and I wrote it on top of that release since we're already using it.

I had standardized asDict() accross all the *Status objects. I don't mind either way. The json status is already written btw.

@djmitche
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marcus - you're right. Let's make this a task to take care of once everyone is on the Jinja bandwagon, as long as we can keep the json output essentially unchanged. I really like the built-in help for the JSON status!

@marcus-sonestedt
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maruel: right. But the json wasn't merged when I wrote the jinja-port ;)

Anyway, yeah, we should do what we can to keep it similar. I think it should be possible to have it rather similar anyway, as the data ought not to differ too much. Most of the filtering/escaping is done in the template at the moment, which is quite nice w.r.t. cooperation with the json-view.

@marcus-sonestedt
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to follow up, I've removed my htmldict()'s and used the asDict where appropriate, as listed on http://buildbot.net/trac/ticket/704

Please sign in to comment.