OLD | NEW |
---|---|
(Empty) | |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | |
2 # Use of this source code is governed by a BSD-style license that can be | |
3 # found in the LICENSE file. | |
4 | |
5 """Utility functions to query the chromium issue tracker. | |
6 | |
7 Note that documentation for the Issue Tracker API says it's DEPRECATED, however | |
8 it seems to be in use in other places like the performance dashboard. Also, | |
9 this module attempts to handle most exceptions thrown by querying the tracker | |
10 so that when and if this api is turned off no impact is caused to the bisection | |
11 process.""" | |
12 | |
13 import json | |
14 import urllib2 | |
15 | |
16 SINGLE_ISSUE_URL = ('https://code.google.com/feeds/issues/p/chromium/issues' | |
17 '/full?id=%s&alt=json') | |
18 | |
19 | |
20 class IssueTrackerQueryException(Exception): | |
21 pass | |
22 | |
23 | |
24 def querySingleIssue(issueId, urlTemplate=SINGLE_ISSUE_URL): | |
qyearsley
2014/11/01 16:56:56
Chromium style:
- Function and method names have
RobertoCN
2014/11/02 07:48:34
Done.
| |
25 """Queries the tracker for a specific issue. Returns a dict. | |
26 | |
27 This uses the deprecated Issue Tracker API to fetch a json representation of | |
qyearsley
2014/11/01 16:56:56
I personally like capitalizing abbreviations like
RobertoCN
2014/11/02 07:48:35
Done.
| |
28 the issue details. | |
29 | |
30 Args: | |
31 issueId: An int or string representing the issue id. | |
32 urlTemplate (optional): to override the url to request from. | |
qyearsley
2014/11/01 16:56:56
No need to say (optional) here. You could say "The
RobertoCN
2014/11/02 07:48:34
Done.
| |
33 Returns: | |
qyearsley
2014/11/01 16:56:56
Style: blank line between Args and Returns section
RobertoCN
2014/11/02 07:48:34
Done.
| |
34 A dictionary as parsed by the json library from the tracker response. | |
qyearsley
2014/11/01 16:56:57
After the Returns section, you could also put a "R
RobertoCN
2014/11/02 07:48:34
Done.
| |
35 """ | |
36 issueId = str(issueId) | |
qyearsley
2014/11/01 16:56:57
It will also be implicitly converted to a string w
RobertoCN
2014/11/02 07:48:34
Done.
| |
37 assert issueId.isdigit() | |
qyearsley
2014/11/01 16:56:56
Cool, I didn't know that isdigit would check all t
RobertoCN
2014/11/02 07:48:34
They are slightly different, current implementatio
| |
38 response = urllib2.urlopen(urlTemplate % issueId).read() | |
39 return json.loads(response) | |
40 | |
41 | |
42 def getIssueState(issueId): | |
qyearsley
2014/11/01 16:56:56
What are the possible values of state? It's just "
RobertoCN
2014/11/02 07:48:34
Done.
| |
43 try: | |
44 queryResponse = querySingleIssue(issueId) | |
45 # We assume the query returns a single result hence the [0] | |
46 issueDetail = queryResponse['feed']['entry'][0] | |
47 state = issueDetail['issues$state']['$t'] | |
48 return state | |
49 except urllib2.URLError: | |
50 raise IssueTrackerQueryException( | |
51 'Could not fetch the details form the issue tracker.' | |
52 ) | |
qyearsley
2014/11/01 16:56:56
Style: closing parenthesis goes on the same line w
RobertoCN
2014/11/02 07:48:34
Done.
| |
53 except ValueError: | |
54 raise IssueTrackerQueryException( | |
55 'Could not parse the issue tracker\'s response as a json doc.' | |
56 ) | |
57 except KeyError: | |
58 raise IssueTrackerQueryException( | |
59 'The data from the issue tracker is not in the expected format.' | |
60 ) | |
61 | |
62 | |
63 def checkIssueClosed(issueId): | |
64 """Checks if a given issue is closed. Returns False when in doubt.""" | |
65 try: | |
66 return getIssueState(issueId) == u'closed' | |
qyearsley
2014/11/01 16:56:56
No need to explicitly use a unicode string, u"clos
RobertoCN
2014/11/02 07:48:34
You are right. I just wondered if I should made th
| |
67 except IssueTrackerQueryException: | |
68 # When we can't be sure we return false | |
69 return False | |
OLD | NEW |