OLD | NEW |
1 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 """Defines class Rietveld to easily access a rietveld instance. | 4 """Defines class Rietveld to easily access a rietveld instance. |
5 | 5 |
6 Security implications: | 6 Security implications: |
7 | 7 |
8 The following hypothesis are made: | 8 The following hypothesis are made: |
9 - Rietveld enforces: | 9 - Rietveld enforces: |
10 - Nobody else than issue owner can upload a patch set | 10 - Nobody else than issue owner can upload a patch set |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 ('message_only', 'True'), | 235 ('message_only', 'True'), |
236 ('send_mail', 'True'), | 236 ('send_mail', 'True'), |
237 ('no_redirect', 'True')]) | 237 ('no_redirect', 'True')]) |
238 | 238 |
239 def set_flag(self, issue, patchset, flag, value): | 239 def set_flag(self, issue, patchset, flag, value): |
240 return self.post('/%s/edit_flags' % issue, [ | 240 return self.post('/%s/edit_flags' % issue, [ |
241 ('last_patchset', str(patchset)), | 241 ('last_patchset', str(patchset)), |
242 ('xsrf_token', self.xsrf_token()), | 242 ('xsrf_token', self.xsrf_token()), |
243 (flag, value)]) | 243 (flag, value)]) |
244 | 244 |
| 245 def search( |
| 246 self, |
| 247 owner=None, reviewer=None, |
| 248 base=None, |
| 249 closed=None, private=None, commit=None, |
| 250 created_before=None, created_after=None, |
| 251 modified_before=None, modified_after=None, |
| 252 per_request=None, keys_only=False, |
| 253 with_messages=False): |
| 254 """Yields search results.""" |
| 255 # These are expected to be strings. |
| 256 string_keys = { |
| 257 'owner': owner, |
| 258 'reviewer': reviewer, |
| 259 'base': base, |
| 260 'created_before': created_before, |
| 261 'created_after': created_after, |
| 262 'modified_before': modified_before, |
| 263 'modified_after': modified_after, |
| 264 } |
| 265 # These are either None, False or True. |
| 266 three_state_keys = { |
| 267 'closed': closed, |
| 268 'private': private, |
| 269 'commit': commit, |
| 270 } |
| 271 |
| 272 url = '/search?format=json' |
| 273 # Sort the keys mainly to ease testing. |
| 274 for key in sorted(string_keys): |
| 275 value = string_keys[key] |
| 276 if value: |
| 277 url += '&%s=%s' % (key, urllib2.quote(value)) |
| 278 for key in sorted(three_state_keys): |
| 279 value = three_state_keys[key] |
| 280 if value is not None: |
| 281 url += '&%s=%d' % (key, int(value) + 1) |
| 282 |
| 283 if keys_only: |
| 284 url += '&keys_only=True' |
| 285 if with_messages: |
| 286 url += '&with_messages=True' |
| 287 if per_request: |
| 288 url += '&limit=%d' % per_request |
| 289 |
| 290 cursor = '' |
| 291 while True: |
| 292 output = self.get(url + cursor) |
| 293 if output.startswith('<'): |
| 294 # It's an error message. Return as no result. |
| 295 break |
| 296 data = json.loads(output) or {} |
| 297 if not data.get('results'): |
| 298 break |
| 299 for i in data['results']: |
| 300 yield i |
| 301 cursor = '&cursor=%s' % data['cursor'] |
| 302 |
245 def get(self, request_path, **kwargs): | 303 def get(self, request_path, **kwargs): |
246 kwargs.setdefault('payload', None) | 304 kwargs.setdefault('payload', None) |
247 return self._send(request_path, **kwargs) | 305 return self._send(request_path, **kwargs) |
248 | 306 |
249 def post(self, request_path, data, **kwargs): | 307 def post(self, request_path, data, **kwargs): |
250 ctype, body = upload.EncodeMultipartFormData(data, []) | 308 ctype, body = upload.EncodeMultipartFormData(data, []) |
251 return self._send(request_path, payload=body, content_type=ctype, **kwargs) | 309 return self._send(request_path, payload=body, content_type=ctype, **kwargs) |
252 | 310 |
253 def _send(self, request_path, **kwargs): | 311 def _send(self, request_path, **kwargs): |
254 """Sends a POST/GET to Rietveld. Returns the response body.""" | 312 """Sends a POST/GET to Rietveld. Returns the response body.""" |
(...skipping 14 matching lines...) Expand all Loading... |
269 if retry >= (maxtries - 1): | 327 if retry >= (maxtries - 1): |
270 raise | 328 raise |
271 if not 'Name or service not known' in e.reason: | 329 if not 'Name or service not known' in e.reason: |
272 # Usually internal GAE flakiness. | 330 # Usually internal GAE flakiness. |
273 raise | 331 raise |
274 # If reaching this line, loop again. Uses a small backoff. | 332 # If reaching this line, loop again. Uses a small backoff. |
275 time.sleep(1+maxtries*2) | 333 time.sleep(1+maxtries*2) |
276 | 334 |
277 # DEPRECATED. | 335 # DEPRECATED. |
278 Send = get | 336 Send = get |
OLD | NEW |