##// END OF EJS Templates
Cleanup stats script and make it print report in final, usable form.
Fernando Perez -
Show More
@@ -1,90 +1,109 b''
1 1 #!/usr/bin/env python
2 2 """Simple tools to query github.com and gather stats about issues.
3 3 """
4 #-----------------------------------------------------------------------------
5 # Imports
6 #-----------------------------------------------------------------------------
7
4 8 from __future__ import print_function
5 9
6 10 import json
7 11 import sys
8 12
9 13 from datetime import datetime, timedelta
10 14 from urllib import urlopen
11 15
16 #-----------------------------------------------------------------------------
17 # Functions
18 #-----------------------------------------------------------------------------
12 19
13 20 def get_issues(project="ipython/ipython/", state="open"):
14 21 """Get a list of the issues from the Github API."""
15 22 f = urlopen("http://github.com/api/v2/json/issues/list/%s%s" % (project,
16 23 state))
17 24 return json.load(f)['issues']
18 25
19 26
20 27 def _parse_datetime(s):
21 28 """Parse dates in the format returned by the Github API."""
22 29 return datetime.strptime(s.rpartition(" ")[0], "%Y/%m/%d %H:%M:%S")
23 30
24 31
25 32 def issues2dict(issues):
26 33 """Convert a list of issues to a dict, keyed by issue number."""
27 34 idict = {}
28 35 for i in issues:
29 36 idict[i['number']] = i
30 37 return idict
31 38
32 39
33 40 def is_pull_request(issue):
34 41 """Return True if the given issue is a pull request."""
35 42 return 'pull_request_url' in issue
36 43
37 44
38 45 def issues_closed_since(period=timedelta(days=365), project="ipython/ipython/"):
39 46 """Get all issues closed since a particular point in time. period
40 47 can either be a datetime object, or a timedelta object. In the
41 48 latter case, it is used as a time before the present."""
42 49 allclosed = get_issues(project=project, state='closed')
43 50 if isinstance(period, timedelta):
44 51 period = datetime.now() - period
45 52 return [i for i in allclosed if _parse_datetime(i['closed_at']) > period]
46 53
47 54
48 55 def sorted_by_field(issues, field='closed_at', reverse=False):
49 56 """Return a list of issues sorted by closing date date."""
50 57 return sorted(issues, key = lambda i:i[field], reverse=reverse)
51 58
52 59
53 60 def report(issues, show_urls=False):
54 61 """Summary report about a list of issues, printing number and title.
55 62 """
56 63 # titles may have unicode in them, so we must encode everything below
57 64 if show_urls:
58 65 for i in issues:
59 66 print('* `%d <%s>`_: %s' % (i['number'],
60 67 i['html_url'].encode('utf-8'),
61 68 i['title'].encode('utf-8')))
62 69 else:
63 70 for i in issues:
64 71 print('* %d: %s' % (i['number'], i['title'].encode('utf-8')))
65 72
73 #-----------------------------------------------------------------------------
74 # Main script
75 #-----------------------------------------------------------------------------
66 76
67 77 if __name__ == "__main__":
68 # Demo, search one year back
78 # Whether to add reST urls for all issues in printout.
69 79 show_urls = True
80
81 # By default, search one month back
70 82 if len(sys.argv) > 1:
71 83 days = int(sys.argv[1])
72 84 else:
73 days = 365
85 days = 30
74 86
87 # turn off to play interactively without redownloading, use %run -i
75 88 if 1:
76 issues = sorted_by_field(issues_closed_since(timedelta(days=days)),
77 reverse=True)
89 issues = issues_closed_since(timedelta(days=days))
90
91 # For regular reports, it's nice to show them in reverse chronological order
92 issues = sorted_by_field(issues, reverse=True)
78 93
94 # Break up into pull requests and regular issues
79 95 pulls = filter(is_pull_request, issues)
80 96 regular = filter(lambda i: not is_pull_request(i), issues)
81 n = len(issues)
97 n_issues, n_pulls, n_regular = map(len, (issues, pulls, regular))
82 98
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)))
99 # Print summary report we can directly include into release notes.
100 print("Github stats for the last %d days." % days)
101 print("We closed a total of %d issues, %d pull requests and %d regular \n"
102 "issues; this is the full list (generated with the script \n"
103 "`tools/github_stats.py`):" % (n_issues, n_pulls, n_regular))
85 104 print()
86 print('Pull requests (%d):\n' % len(pulls))
105 print('Pull requests (%d):\n' % n_pulls)
87 106 report(pulls, show_urls)
88 107 print()
89 print('Regular issues (%d):\n' % len(regular))
108 print('Regular issues (%d):\n' % n_regular)
90 109 report(regular, show_urls)
General Comments 0
You need to be logged in to leave comments. Login now