Merge lp:~rockstar/laika/foolin into lp:laika

Proposed by Paul Hummer on 2010-07-16
Status: Merged
Approved by: Alex Chiang on 2010-07-16
Approved revision: 10
Merged at revision: 4
Proposed branch: lp:~rockstar/laika/foolin
Merge into: lp:laika
Diff against target: 315 lines (+152/-137)
1 file modified
laika.py (+152/-137)
To merge this branch: bzr merge lp:~rockstar/laika/foolin
Reviewer Review Type Date Requested Status
Alex Chiang 2010-07-16 Approve on 2010-07-16
Review via email: mp+30129@code.launchpad.net

Description of the change

This branch just refactors some of the functionality of laika into a Report class. It's just moving code around really. I haven't changed any of the functionality of laika itself. It's merely contained in a class instance now.

To post a comment you must log in.
Alex Chiang (achiang) wrote :

Commit #5 in your branch was a little large for my taste, but I did review it and verify that there was not really any functional change.

Thanks for the patches; they're awesome!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'laika.py'
2--- laika.py 2010-05-24 22:24:25 +0000
3+++ laika.py 2010-07-16 16:33:22 +0000
4@@ -7,14 +7,18 @@
5 # http://en.wikipedia.org/wiki/Laika
6 #
7 # Copyright 2010 Alex Chiang <achiang@canonical.com>
8-#
9+#
10 # This program is distributed under the terms of the
11 # GNU General Public License version 2.
12
13+import datetime
14+import getopt
15 import os
16 import re
17 import sys
18-import datetime
19+
20+from launchpadlib.launchpad import Launchpad
21+
22
23 # Number of days prior to search for Launchpad activity
24 window = 8
25@@ -23,144 +27,155 @@
26 now = datetime.datetime.utcnow()
27 my_bugs = {}
28
29-def print_header(header):
30- print "==", header, "=="
31-
32-# Here be side-effects. Using this interface adds the bug to global bug list.
33-def print_bugid(task):
34- ago = ""
35- my_bugs[task.bug.id] = 1
36- delta = now - task.bug.date_last_updated.replace(tzinfo=None)
37- if delta.days > 0:
38- ago = "%d day%s" % (delta.days, "s" if delta.days > 1 else "")
39-
40- hours = delta.seconds / 3600
41- if hours > 0:
42- ago += ", " if ago else ""
43- ago += "%d hour%s" % (hours, "s" if hours > 1 else "")
44-
45- minutes = (delta.seconds - (hours * 3600)) / 60
46- if minutes > 0:
47- ago += ", " if ago else ""
48- ago += "%d minute%s" % (minutes, "s" if minutes > 1 else "")
49-
50- print task.title
51- print "https://launchpad.net/bugs/" + str(task.bug.id)
52- print "last updated", ago, "ago"
53-
54-# heh.
55-# Timezones do not exist, all datetime objects have to be naive.
56-# aware means broken.
57-# http://www.enricozini.org/2009/debian/using-python-datetime/
58-def in_window(date):
59- win = datetime.timedelta(window)
60- date = date.replace(tzinfo=None)
61- delta = now - date
62- return delta <= win
63-
64-def my_assignments(me):
65- statuses = ['closed', 'fix_released', 'fix_committed',
66- 'in_progress', 'triaged', 'confirmed', 'created']
67-
68- tasks = me.searchTasks(assignee=me)
69- print_header("Assigned Bugs")
70-
71- for t in tasks:
72- if my_bugs.has_key(t.bug.id):
73- continue
74- updates = []
75- for s in statuses:
76- attr = 'date_' + s
77- date = getattr(t, attr)
78- if not date:
79- continue
80- if in_window(date):
81- updates.append("\t" + s + ": " + re.sub("\s.*$", "", str(date)))
82-
83- if updates:
84- print_bugid(t)
85- for u in updates:
86- print u
87- print
88- print
89-
90-def my_comments(me):
91- tasks = me.searchTasks(bug_commenter=me)
92- print_header("Commented Bugs")
93- for t in tasks:
94- if my_bugs.has_key(t.bug.id):
95- continue
96- for m in t.bug.messages:
97- if m.owner_link != me.self_link:
98- continue
99- if in_window(m.date_created):
100- print_bugid(t)
101- print
102- break
103- print
104-
105-def my_reported(me):
106- tasks = me.searchTasks(bug_reporter=me)
107- print_header("Reported Bugs")
108- for t in tasks:
109- if my_bugs.has_key(t.bug.id):
110- continue
111- if in_window(t.bug.date_created):
112- print_bugid(t)
113- print
114-
115-# In order of decreasing importance, search and display activity on
116-# bugs assigned to me, then on bugs that I actually commented upon,
117-# and finally bugs that I just opened, but did nothing further with.
118-#
119-# Avoids duplication of activity. So if the status was changed on
120-# a bug assigned to you and you also commented on it, only report the
121-# status change.
122-def launch(lp):
123- me = lp.me
124- my_assignments(me)
125- my_comments(me)
126- my_reported(me)
127+
128+class Report(object):
129+ '''An activity report for a specified Launchpad user.
130+
131+ In order of decreasing importance, search and display activity on
132+ bugs assigned to me, then on bugs that I actually commented upon,
133+ and finally bugs that I just opened, but did nothing further with.
134+
135+ Avoids duplication of activity. So if the status was changed on
136+ a bug assigned to you and you also commented on it, only report the
137+ status change.
138+ '''
139+
140+ def __init__(self, user):
141+ self.user = user
142+
143+ def print_header(self, header):
144+ print "==", header, "=="
145+
146+ def in_window(self, date):
147+ '''Timezones do not exist, all datetime objects have to be naive.
148+
149+ Time zone aware means broken.
150+ http://www.enricozini.org/2009/debian/using-python-datetime/
151+ '''
152+ win = datetime.timedelta(window)
153+ date = date.replace(tzinfo=None)
154+ delta = now - date
155+ return delta <= win
156+
157+ def print_bugid(self, task):
158+ '''Using this interface adds the bug to global bug list.'''
159+ ago = ""
160+ my_bugs[task.bug.id] = 1
161+ delta = now - task.bug.date_last_updated.replace(tzinfo=None)
162+ if delta.days > 0:
163+ ago = "%d day%s" % (delta.days, "s" if delta.days > 1 else "")
164+
165+ hours = delta.seconds / 3600
166+ if hours > 0:
167+ ago += ", " if ago else ""
168+ ago += "%d hour%s" % (hours, "s" if hours > 1 else "")
169+
170+ minutes = (delta.seconds - (hours * 3600)) / 60
171+ if minutes > 0:
172+ ago += ", " if ago else ""
173+ ago += "%d minute%s" % (minutes, "s" if minutes > 1 else "")
174+
175+ print task.title
176+ print "https://launchpad.net/bugs/" + str(task.bug.id)
177+ print "last updated", ago, "ago"
178+
179+ def print_assignments(self):
180+ statuses = ['closed', 'fix_released', 'fix_committed',
181+ 'in_progress', 'triaged', 'confirmed', 'created']
182+
183+ tasks = self.user.searchTasks(assignee=self.user)
184+ self.print_header("Assigned Bugs")
185+
186+ for t in tasks:
187+ if my_bugs.has_key(t.bug.id):
188+ continue
189+ updates = []
190+ for s in statuses:
191+ attr = 'date_' + s
192+ date = getattr(t, attr)
193+ if not date:
194+ continue
195+ if self.in_window(date):
196+ updates.append(
197+ "\t" + s + ": " + re.sub("\s.*$", "", str(date)))
198+
199+ if updates:
200+ self.print_bugid(t)
201+ for u in updates:
202+ print u
203+ print
204+ print
205+
206+ def print_comments(self):
207+ tasks = self.user.searchTasks(bug_commenter=self.user)
208+ self.print_header("Commented Bugs")
209+ for t in tasks:
210+ if my_bugs.has_key(t.bug.id):
211+ continue
212+ for m in t.bug.messages:
213+ if m.owner_link != self.user.self_link:
214+ continue
215+ if self.in_window(m.date_created):
216+ self.print_bugid(t)
217+ print
218+ break
219+ print
220+
221+ def print_reported(self):
222+ tasks = self.user.searchTasks(bug_reporter=self.user)
223+ self.print_header("Reported Bugs")
224+ for t in tasks:
225+ if my_bugs.has_key(t.bug.id):
226+ continue
227+ if self.in_window(t.bug.date_created):
228+ self.print_bugid(t)
229+ print
230+
231+ def render(self):
232+ self.print_assignments()
233+ self.print_comments()
234+ self.print_reported()
235+
236
237 def usage():
238- print "Usage:"
239- print "\tlaika [-u <login>] [-w <window>] [-h]"
240- print
241- print "\t-u <login>"
242- print "\t\tSpecify your Launchpad user id."
243- print "\t\tIf not specified, defaults to: %s." % (user)
244- print
245- print "\t-w <num>"
246- print "\t\tLook for activity within the past <num> days."
247- print "\t\tIf not specified, defaults to %d." % (window)
248- print
249- print "\t-h"
250- print "\t\tDisplay this message."
251+ print "Usage:"
252+ print "\tlaika [-u <login>] [-w <window>] [-h]"
253+ print
254+ print "\t-u <login>"
255+ print "\t\tSpecify your Launchpad user id."
256+ print "\t\tIf not specified, defaults to: %s." % (user)
257+ print
258+ print "\t-w <num>"
259+ print "\t\tLook for activity within the past <num> days."
260+ print "\t\tIf not specified, defaults to %d." % (window)
261+ print
262+ print "\t-h"
263+ print "\t\tDisplay this message."
264
265 def main(argv):
266- import getopt
267- from launchpadlib.launchpad import Launchpad
268-
269- try:
270- opts, args = getopt.getopt(argv, "hu:w:")
271- except getopt.GetoptError:
272- usage()
273- sys.exit(2)
274-
275- for opt, arg in opts:
276- if opt == '-h':
277- usage()
278- sys.exit()
279- elif opt == '-u':
280- global user
281- user = arg
282- elif opt == '-w':
283- global window
284- window = int(arg)
285-
286- cachedir = "/home/" + user + "/.launchpadlib/cache/"
287- lp = Launchpad.login_with('laika', 'production', cachedir)
288- launch(lp)
289+
290+ try:
291+ opts, args = getopt.getopt(argv, "hu:w:")
292+ except getopt.GetoptError:
293+ usage()
294+ sys.exit(2)
295+
296+ for opt, arg in opts:
297+ if opt == '-h':
298+ usage()
299+ sys.exit()
300+ elif opt == '-u':
301+ global user
302+ user = arg
303+ elif opt == '-w':
304+ global window
305+ window = int(arg)
306+
307+ cachedir = "/home/" + user + "/.launchpadlib/cache/"
308+ lp = Launchpad.login_with('laika', 'production', cachedir)
309+
310+ report = Report(lp.me)
311+ report.render()
312
313 if __name__ == "__main__":
314- main(sys.argv[1:])
315+ main(sys.argv[1:])

Subscribers

People subscribed via source and target branches

to all changes: