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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
1 import urllib2
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
2 import urllib
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
3 from datetime import datetime
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
4
1
f2147b34d6af Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
5 import pymongo
0
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
6 import simplejson as json
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
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
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
11 def datetime_from_iso(timestamp):
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
12 return datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ')
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
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
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
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
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
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
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
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
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
45 params = {}
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
46 params.update(self.options)
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
47 if self.last_update:
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
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
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
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
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
56
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
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
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
59 self.base_url = base_url
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
60 self.username = username
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
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
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
68
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
69 def _validate_component(self, product, component=None):
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
70 products = self.config['product']
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
71 if product not in products:
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
72 msg = 'product %s not in configuration' % repr(product)
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
73 raise ValueError(msg)
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
74 if component and component not in products[product]['component']:
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
75 msg = 'component %s of product %s not in configuration' % (
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
76 repr(component),
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
77 repr(product)
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
78 )
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
79 raise ValueError(msg)
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
80
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
81 def get(self, url, **kwargs):
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
82 for name, value in kwargs.items():
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
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
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
85
1
f2147b34d6af Use pymongo instead of pickling
Atul Varma <varmaa@toolness.com>
parents: 0
diff changeset
86 params = {}
0
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
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
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
90 params.update(kwargs)
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
91
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
92 if 'product' in params:
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
93 self._validate_component(params['product'],
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
94 params.get('component'))
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
95
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
96 full_url = "%s%s?%s" % (self.base_url,
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
97 url,
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
98 urllib.urlencode(params))
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
99
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
100 request = urllib2.Request(full_url)
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
101 request.add_header('Accept', 'application/json')
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
102 request.add_header('Content-Type', 'application/json')
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
103
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
104 response = urllib2.urlopen(request)
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
105
78e4757601ec origination
Atul Varma <varmaa@toolness.com>
parents:
diff changeset
106 return json.loads(response.read())