Mercurial > bzapi
annotate bzapi.py @ 1:f2147b34d6af
Use pymongo instead of pickling
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Wed, 23 Dec 2009 02:23:11 -0800 |
parents | 78e4757601ec |
children | 6a0ad0463a89 |
rev | line source |
---|---|
0 | 1 import urllib2 |
2 import urllib | |
3 from datetime import datetime | |
4 | |
1
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
5 import pymongo |
0 | 6 import simplejson as json |
7 | |
1
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
8 def datetime_to_iso(dt): |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
9 return "%sZ" % (dt.replace(microsecond=0).isoformat('T')) |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
10 |
0 | 11 def datetime_from_iso(timestamp): |
12 return datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ') | |
13 | |
1
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
14 def sanitize(obj): |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
15 if type(obj) == dict: |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
16 bad_names = [name for name in obj |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
17 if "." in name] |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
18 for name in bad_names: |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
19 new_name = name.replace('.', '_DOT_') |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
20 obj[new_name] = obj[name] |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
21 del obj[name] |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
22 for name in obj: |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
23 sanitize(obj[name]) |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
24 elif type(obj) == list: |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
25 for item in obj: |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
26 sanitize(item) |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
27 |
0 | 28 class CachedSearch(object): |
1
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
29 def __init__(self, api, collection, **kwargs): |
0 | 30 self.options = kwargs |
1
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
31 |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
32 self.bugs = collection |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
33 self.api = api |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
34 self._update_last_update() |
0 | 35 |
1
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
36 def _update_last_update(self): |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
37 bugs = self.bugs.find().sort("last_change_time", |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
38 pymongo.DESCENDING).limit(1) |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
39 if bugs.count() == 0: |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
40 self.last_update = None |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
41 else: |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
42 self.last_update = bugs[0]['last_change_time'] |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
43 |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
44 def update(self): |
0 | 45 params = {} |
46 params.update(self.options) | |
47 if self.last_update: | |
48 params['changed_after'] = self.last_update | |
1
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
49 bugs = self.api.get('/bug', **params)['bugs'] |
0 | 50 for bug in bugs: |
1
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
51 for name in ['last_change_time', 'creation_time']: |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
52 bug[name] = datetime_from_iso(bug[name]) |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
53 bug['_id'] = bug['id'] |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
54 self.bugs.save(bug) |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
55 self._update_last_update() |
0 | 56 |
57 class BugzillaApi(object): | |
1
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
58 def __init__(self, base_url, collection, username=None, password=None): |
0 | 59 self.base_url = base_url |
60 self.username = username | |
61 self.password = password | |
1
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
62 config = collection.find_one() |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
63 if not config: |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
64 config = self.get('/configuration') |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
65 sanitize(config) |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
66 collection.insert(config) |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
67 self.config = config |
0 | 68 |
69 def _validate_component(self, product, component=None): | |
70 products = self.config['product'] | |
71 if product not in products: | |
72 msg = 'product %s not in configuration' % repr(product) | |
73 raise ValueError(msg) | |
74 if component and component not in products[product]['component']: | |
75 msg = 'component %s of product %s not in configuration' % ( | |
76 repr(component), | |
77 repr(product) | |
78 ) | |
79 raise ValueError(msg) | |
80 | |
81 def get(self, url, **kwargs): | |
82 for name, value in kwargs.items(): | |
83 if isinstance(value, datetime): | |
1
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
84 kwargs[name] = datetime_to_iso(value) |
0 | 85 |
1
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
86 params = {} |
0 | 87 if self.username and self.password: |
1
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
88 params.update({'username': self.username, |
f2147b34d6af
Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents:
0
diff
changeset
|
89 'password': self.password}) |
0 | 90 params.update(kwargs) |
91 | |
92 if 'product' in params: | |
93 self._validate_component(params['product'], | |
94 params.get('component')) | |
95 | |
96 full_url = "%s%s?%s" % (self.base_url, | |
97 url, | |
98 urllib.urlencode(params)) | |
99 | |
100 request = urllib2.Request(full_url) | |
101 request.add_header('Accept', 'application/json') | |
102 request.add_header('Content-Type', 'application/json') | |
103 | |
104 response = urllib2.urlopen(request) | |
105 | |
106 return json.loads(response.read()) |