|
3 | 3 | # This script generates a simple report outlining the activity in one
|
4 | 4 | # tracker for the most recent week.
|
5 | 5 |
|
| 6 | +# A second argument is the negative interval to change period |
| 7 | +# of time. |
| 8 | + |
6 | 9 | # This script is free software, you may redistribute it
|
7 | 10 | # and/or modify under the same terms as Python.
|
8 | 11 |
|
| 12 | +#Example output |
| 13 | +#CREATED: |
| 14 | +#2702: new item |
| 15 | +# |
| 16 | +#RESOLVED: |
| 17 | +#1995: Where is my Power plugs |
| 18 | +#2501: Can you help me with Sanity |
| 19 | +#459: I need Sanity |
| 20 | +# |
| 21 | +#TOP TEN MOST DISCUSSED: |
| 22 | +#2 - 491: Can you help me with Sanity |
| 23 | +#1 - 1995: Where is my Power plugs |
| 24 | + |
9 | 25 | from __future__ import print_function
|
10 |
| -import sys, math |
11 |
| -from roundup import instance, date |
| 26 | + |
| 27 | +import sys |
| 28 | + |
| 29 | +from roundup import date, instance |
| 30 | + |
| 31 | +# position for arguments |
| 32 | +tracker_home_pos = 1 |
| 33 | +optional_interval_pos = 2 |
| 34 | + |
| 35 | +# gather args |
| 36 | +arg_len = len(sys.argv) |
| 37 | +# map pos to length by adding 1. |
| 38 | +if arg_len not in [tracker_home_pos + 1, optional_interval_pos + 1]: |
| 39 | + print('Usage: %s tracker-home [interval -1w]' % sys.argv[0]) |
| 40 | + if (arg_len < tracker_home_pos + 1 ): |
| 41 | + print(' You need to specify a tracker home directory') |
| 42 | + sys.exit(1) |
| 43 | +instance_home = sys.argv[tracker_home_pos] |
| 44 | +lookback_interval = sys.argv[optional_interval_pos] if \ |
| 45 | + len(sys.argv) == optional_interval_pos + 1 else '-1w' |
12 | 46 |
|
13 | 47 | # open the instance
|
14 |
| -if len(sys.argv) != 2: |
15 |
| - print('You need to specify an instance home dir') |
16 |
| -instance_home = sys.argv[1] |
17 | 48 | instance = instance.open(instance_home)
|
18 | 49 | db = instance.open('admin')
|
19 | 50 |
|
20 |
| -old = date.Date('-1w') |
| 51 | +old = date.Date(lookback_interval) |
21 | 52 |
|
22 |
| -created = [] |
23 |
| -summary = {} |
24 |
| -messages = [] |
| 53 | +created = [] # [issue_id_created_issue] |
| 54 | +summary = {} # {status_id: [issue_ids in that status]} |
| 55 | +messages = [] # [(number_of_messages, issue_id)] |
25 | 56 |
|
26 | 57 | # loop through all the recently-active issues
|
27 | 58 | for issue_id in db.issue.filter(None, {'activity': '-1w;'}):
|
28 |
| - num = 0 |
29 |
| - for x,ts,userid,action,data in db.issue.history(issue_id): |
30 |
| - if ts < old: continue |
| 59 | + message_count = 0 |
| 60 | + for _x,ts,_userid,action,data in db.issue.history(issue_id): |
| 61 | + if ts < old: # history occurred before our current window |
| 62 | + continue |
31 | 63 | if action == 'create':
|
32 | 64 | created.append(issue_id)
|
33 | 65 | elif action == 'set' and 'messages' in data:
|
34 |
| - num += 1 |
35 |
| - summary.setdefault(db.issue.get(issue_id, 'status'), []).append(issue_id) |
36 |
| - messages.append((num, issue_id)) |
| 66 | + message_count += 1 |
| 67 | + summary.setdefault(db.issue.get(issue_id, 'status'), |
| 68 | + []).append(issue_id) |
| 69 | + messages.append((message_count, issue_id)) |
37 | 70 |
|
38 |
| -#print 'STATUS SUMMARY:' |
| 71 | +#print('STATUS SUMMARY:') |
39 | 72 | #for k,v in summary.items():
|
40 |
| -# print k, len(v) |
| 73 | +# print(k, len(v)) |
41 | 74 |
|
42 | 75 | print('\nCREATED:')
|
43 |
| -print('\n'.join(['%s: %s'%(id, db.issue.get(id, 'title')) |
44 |
| - for id in created])) |
| 76 | +if created: |
| 77 | + print('\n'.join(['%s: %s'%(itemid, db.issue.get(itemid, 'title')) |
| 78 | + for itemid in created])) |
| 79 | +else: |
| 80 | + print("No issue created in interval %s" % lookback_interval) |
45 | 81 |
|
46 | 82 | print('\nRESOLVED:')
|
47 | 83 | resolved_id = db.status.lookup('resolved')
|
48 |
| -print('\n'.join(['%s: %s'%(id, db.issue.get(id, 'title')) |
49 |
| - for id in summary.get(resolved_id, [])])) |
| 84 | +if summary: |
| 85 | + # deduplicate - duplicates happen when issue with resolved status |
| 86 | + # has multiple history items (e.g. message or other |
| 87 | + # change after resolution) |
| 88 | + resolved_ids = sorted(set(summary.get(resolved_id, [])), key=int) |
| 89 | + print('\n'.join(['%s: %s' % (itemid, db.issue.get(itemid, 'title')) |
| 90 | + for itemid in resolved_ids ])) |
| 91 | +else: |
| 92 | + print("No issue resolved in interval %s" % lookback_interval) |
50 | 93 |
|
51 | 94 | print('\nTOP TEN MOST DISCUSSED:')
|
52 |
| -messages.sort() |
53 |
| -messages.reverse() |
54 |
| -nmax = messages[0][0] |
55 |
| -fmt = '%%%dd - %%s: %%s'%(int(math.log(nmax, 10)) + 1) |
56 |
| -print('\n'.join([fmt%(num, id, db.issue.get(id, 'title')) |
57 |
| - for num, id in messages[:10]])) |
| 95 | + |
| 96 | +# filter out issues with no messages |
| 97 | +messages = [ message for message in messages if message[0] > 0 ] |
| 98 | +if messages: |
| 99 | + messages.sort() |
| 100 | + messages.reverse() |
| 101 | + nmax = messages[0][0] or 1 |
| 102 | + fmt = '%%%dd - %%s: %%s'%(len(str(nmax))) |
| 103 | + print('\n'.join([fmt%(num, itemid, db.issue.get(itemid, 'title')) |
| 104 | + for num, itemid in messages[:10]])) |
| 105 | +else: |
| 106 | + print("No issues discussed in interval %s" % lookback_interval) |
58 | 107 |
|
59 | 108 | # vim: set filetype=python ts=4 sw=4 et si
|
0 commit comments