Mercurial > bzapi
changeset 29:9a7052db1045
added docs
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Thu, 24 Dec 2009 12:41:20 -0800 |
parents | ce19838a318d |
children | 6b0a17f31342 |
files | bzapi.py |
diffstat | 1 files changed, 69 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/bzapi.py Thu Dec 24 11:54:11 2009 -0800 +++ b/bzapi.py Thu Dec 24 12:41:20 2009 -0800 @@ -1,3 +1,23 @@ +""" + bzapi - Access to the Bugzilla REST API w/ MongoDB integration + + This module provides access to the Bugzilla REST API with fast + caching of search queries, configuration information and so forth + via MongoDB. + + For information on the Bugzilla REST API, see: + + https://wiki.mozilla.org/Bugzilla:REST_API + + For information on MongoDB, see: + + http://www.mongodb.org/ + + This module requires pymongo, which can be found here: + + http://pypi.python.org/pypi/pymongo/ +""" + import logging import urllib2 import urllib @@ -7,12 +27,22 @@ import simplejson as json def split_seq(seq, size): - """ Split up seq in pieces of size """ + """ + Split up the given sequence into pieces of the given size. - # Taken from http://code.activestate.com/recipes/425044/ + Taken from http://code.activestate.com/recipes/425044/. + """ + return [seq[i:i+size] for i in range(0, len(seq), size)] def open_url(url, headers, query_args=None, urllib2=urllib2): + """ + Open the given URL with the given request headers dictionary + and optional querystring arguments dictionary. + + Returns a urllib2.Response object. + """ + if query_args: full_url = "%s?%s" % (url, urllib.urlencode(query_args)) else: @@ -27,20 +57,53 @@ return urllib2.urlopen(request) def normalize_bug(bug): + """ + Converts all ISO-formatted date strings in the Bugzilla JSON + bug object [1] to Python datetime objects, and sets the MongoDB + primary key of the bug to the bug id number. + + [1] https://wiki.mozilla.org/Bugzilla:REST_API:Objects#Bug + """ + for name in ['last_change_time', 'creation_time']: bug[name] = datetime_from_iso(bug[name]) bug['_id'] = bug['id'] def datetime_from_rfc1123(timestamp): + """ + Converts a rfc 1123-formatted date string to a Python datetime + object. + """ + return datetime.strptime(timestamp, '%a, %d %b %Y %H:%M:%S GMT') def datetime_to_iso(dt): + """ + Converts a Python datetime object to an ISO 8601 formatted + string, also with a 'Z' at the end so that Bugzilla likes it. + """ + return "%sZ" % (dt.replace(microsecond=0).isoformat('T')) def datetime_from_iso(timestamp): + """ + Converts an ISO 8601 formatted string with a 'Z' at the end + of it (as provided by Bugzilla) to a Python datetime object. + """ + return datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ') -def sanitize(obj): +def sanitize_for_mongodb(obj): + """ + Sanitizes all dictionaries in the given Python object for + insertion into MongoDB, replacing any '.' in key names + in them with '_DOT_'. + + This function works 'deeply', recursing through sub-objects, + but it assumes that the given object doesn't contain + reference cycles. + """ + if type(obj) == dict: bad_names = [name for name in obj if "." in name] @@ -49,10 +112,10 @@ obj[new_name] = obj[name] del obj[name] for name in obj: - sanitize(obj[name]) + sanitize_for_mongodb(obj[name]) elif type(obj) == list: for item in obj: - sanitize(item) + sanitize_for_mongodb(item) class CachedSearch(object): MAX_BUG_BATCH_SIZE = 10 @@ -127,7 +190,7 @@ config = collection.find_one() if not config: config = self.get('/configuration')['data'] - sanitize(config) + sanitize_for_mongodb(config) collection.insert(config) self.config = config