##// END OF EJS Templates
Improve stats script to better summarize pull requests.
Fernando Perez -
Show More
@@ -1,17 +1,40 b''
1 #!/usr/bin/env python
2 """Simple tools to query github.com and gather stats about issues.
3 """
4 from __future__ import print_function
5
1 import json
6 import json
2 from datetime import datetime, timedelta
3 import sys
7 import sys
8
9 from datetime import datetime, timedelta
4 from urllib import urlopen
10 from urllib import urlopen
5
11
12
6 def get_issues(project="ipython/ipython/", state="open"):
13 def get_issues(project="ipython/ipython/", state="open"):
7 """Get a list of the issues from the Github API."""
14 """Get a list of the issues from the Github API."""
8 f = urlopen("http://github.com/api/v2/json/issues/list/%s%s" % (project, state))
15 f = urlopen("http://github.com/api/v2/json/issues/list/%s%s" % (project,
16 state))
9 return json.load(f)['issues']
17 return json.load(f)['issues']
10
18
19
11 def _parse_datetime(s):
20 def _parse_datetime(s):
12 """Parse dates in the format returned by the Github API."""
21 """Parse dates in the format returned by the Github API."""
13 return datetime.strptime(s.rpartition(" ")[0], "%Y/%m/%d %H:%M:%S")
22 return datetime.strptime(s.rpartition(" ")[0], "%Y/%m/%d %H:%M:%S")
14
23
24
25 def issues2dict(issues):
26 """Convert a list of issues to a dict, keyed by issue number."""
27 idict = {}
28 for i in issues:
29 idict[i['number']] = i
30 return idict
31
32
33 def is_pull_request(issue):
34 """Return True if the given issue is a pull request."""
35 return 'pull_request_url' in issue
36
37
15 def issues_closed_since(period=timedelta(days=365), project="ipython/ipython/"):
38 def issues_closed_since(period=timedelta(days=365), project="ipython/ipython/"):
16 """Get all issues closed since a particular point in time. period
39 """Get all issues closed since a particular point in time. period
17 can either be a datetime object, or a timedelta object. In the
40 can either be a datetime object, or a timedelta object. In the
@@ -21,11 +44,47 b' latter case, it is used as a time before the present."""'
21 period = datetime.now() - period
44 period = datetime.now() - period
22 return [i for i in allclosed if _parse_datetime(i['closed_at']) > period]
45 return [i for i in allclosed if _parse_datetime(i['closed_at']) > period]
23
46
47
48 def sorted_by_field(issues, field='closed_at', reverse=False):
49 """Return a list of issues sorted by closing date date."""
50 return sorted(issues, key = lambda i:i[field], reverse=reverse)
51
52
53 def report(issues, show_urls=False):
54 """Summary report about a list of issues, printing number and title.
55 """
56 # titles may have unicode in them, so we must encode everything below
57 if show_urls:
58 for i in issues:
59 print('* `%d <%s>`_: %s' % (i['number'],
60 i['html_url'].encode('utf-8'),
61 i['title'].encode('utf-8')))
62 else:
63 for i in issues:
64 print('* %d: %s' % (i['number'], i['title'].encode('utf-8')))
65
66
24 if __name__ == "__main__":
67 if __name__ == "__main__":
25 # Demo
68 # Demo, search one year back
69 show_urls = True
26 if len(sys.argv) > 1:
70 if len(sys.argv) > 1:
27 days = int(sys.argv[1])
71 days = int(sys.argv[1])
28 else:
72 else:
29 days = 365
73 days = 365
30 n = len(issues_closed_since(timedelta(days=days)))
74
31 print "%d issues closed in the last %d days." % (n, days)
75 if 1:
76 issues = sorted_by_field(issues_closed_since(timedelta(days=days)),
77 reverse=True)
78
79 pulls = filter(is_pull_request, issues)
80 regular = filter(lambda i: not is_pull_request(i), issues)
81 n = len(issues)
82
83 print("%d total issues closed in the last %d days." % (n, days))
84 print("%d pull requests and %d regular issues." % (len(pulls), len(regular)))
85 print()
86 print('Pull requests (%d):\n' % len(pulls))
87 report(pulls, show_urls)
88 print()
89 print('Regular issues (%d):\n' % len(regular))
90 report(regular, show_urls)
General Comments 0
You need to be logged in to leave comments. Login now