Commit | Line | Data |
---|---|---|
c638d827 CR |
1 | #! /usr/bin/env python |
2 | # Copyright (c) 2002 ekit.com Inc (http://www.ekit-inc.com/) | |
3 | # | |
4 | # Permission is hereby granted, free of charge, to any person obtaining a copy | |
5 | # of this software and associated documentation files (the "Software"), to deal | |
6 | # in the Software without restriction, including without limitation the rights | |
7 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
8 | # copies of the Software, and to permit persons to whom the Software is | |
9 | # furnished to do so, subject to the following conditions: | |
10 | # | |
11 | # The above copyright notice and this permission notice shall be included in | |
12 | # all copies or substantial portions of the Software. | |
13 | # | |
14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
17 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
18 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
20 | # SOFTWARE. | |
21 | ||
22 | ''' | |
23 | Simple script that emails all users of a tracker with the issues that | |
24 | are currently assigned to them. | |
25 | ||
26 | TODO: introduce some structure ;) | |
27 | TODO: possibly make this more general and configurable... | |
28 | ''' | |
29 | ||
30 | import sys, cStringIO, MimeWriter, smtplib | |
31 | from roundup import instance, date | |
32 | from roundup.mailer import SMTPConnection | |
33 | ||
34 | # open the instance | |
35 | if len(sys.argv) != 2: | |
36 | print 'You need to specify an instance home dir' | |
37 | instance_home = sys.argv[1] | |
38 | instance = instance.open(instance_home) | |
39 | db = instance.open('admin') | |
40 | ||
41 | resolved_id = db.status.lookup('resolved') | |
42 | ||
43 | def listCompare(x, y): | |
44 | "compare two tuples such that order is positive on [0] and negative on [1]" | |
45 | if x[0] < y[0]: | |
46 | return -1 | |
47 | if x[0] > y[0]: | |
48 | return 1 | |
49 | if x[1] > y[1]: | |
50 | return -1 | |
51 | if x[1] < y[1]: | |
52 | return 1 | |
53 | return 0 | |
54 | ||
55 | # loop through all the users | |
56 | for user_id in db.user.list(): | |
57 | # make sure we care aboue this user | |
58 | name = db.user.get(user_id, 'realname') | |
59 | if name is None: | |
60 | name = db.user.get(user_id, 'username') | |
61 | address = db.user.get(user_id, 'address') | |
62 | if address is None: | |
63 | continue | |
64 | ||
65 | # extract this user's issues | |
66 | l = [] | |
67 | for issue_id in db.issue.find(assignedto=user_id): | |
68 | if db.issue.get(issue_id, 'status') == resolved_id: | |
69 | continue | |
70 | order = db.priority.get(db.issue.get(issue_id, 'priority'), 'order') | |
71 | l.append((order, db.issue.get(issue_id, 'activity'), | |
72 | db.issue.get(issue_id, 'creation'), issue_id)) | |
73 | ||
74 | # sort the issues by timeliness and creation date | |
75 | l.sort(listCompare) | |
76 | if not l: | |
77 | continue | |
78 | ||
79 | # generate the email message | |
80 | message = cStringIO.StringIO() | |
81 | writer = MimeWriter.MimeWriter(message) | |
82 | writer.addheader('Subject', 'Your active %s issues'%db.config.TRACKER_NAME) | |
83 | writer.addheader('To', address) | |
84 | writer.addheader('From', '%s <%s>'%(db.config.TRACKER_NAME, | |
85 | db.config.ADMIN_EMAIL)) | |
86 | writer.addheader('Reply-To', '%s <%s>'%(db.config.TRACKER_NAME, | |
87 | db.config.ADMIN_EMAIL)) | |
88 | writer.addheader('MIME-Version', '1.0') | |
89 | writer.addheader('X-Roundup-Name', db.config.TRACKER_NAME) | |
90 | ||
91 | # start the multipart | |
92 | part = writer.startmultipartbody('alternative') | |
93 | part = writer.nextpart() | |
94 | body = part.startbody('text/plain') | |
95 | ||
96 | # do the plain text bit | |
97 | print >>body, 'Created ID Activity Title' | |
98 | print >>body, '='*75 | |
99 | # '2 months 213 immediate cc_daemon barfage | |
100 | old_priority = None | |
101 | for priority_order, activity_date, creation_date, issue_id in l: | |
102 | priority = db.issue.get(issue_id, 'priority') | |
103 | if (priority != old_priority): | |
104 | old_priority = priority | |
105 | print >>body, ' ', db.priority.get(priority,'name') | |
106 | # pretty creation | |
107 | creation = (creation_date - date.Date('.')).pretty() | |
108 | if creation is None: | |
109 | creation = creation_date.pretty() | |
110 | activity = (activity_date - date.Date('.')).pretty() | |
111 | title = db.issue.get(issue_id, 'title') | |
112 | if len(title) > 42: | |
113 | title = title[:38] + ' ...' | |
114 | print >>body, '%-11s %-4s %-9s %-42s'%(creation, issue_id, | |
115 | activity, title) | |
116 | ||
117 | # some help to finish off | |
118 | print >>body, ''' | |
119 | To view or respond to any of the issues listed above, visit the URL | |
120 | ||
121 | %s | |
122 | ||
123 | and click on "My Issues". Do NOT respond to this message. | |
124 | '''%db.config.TRACKER_WEB | |
125 | ||
126 | ||
127 | # now the HTML one | |
128 | part = writer.nextpart() | |
129 | body = part.startbody('text/html') | |
130 | colours = { | |
131 | 'immediate': ' bgcolor="#ffcdcd"', | |
132 | 'day': ' bgcolor="#ffdecd"', | |
133 | 'week': ' bgcolor="#ffeecd"', | |
134 | 'month': ' bgcolor="#ffffcd"', | |
135 | 'whenever': ' bgcolor="#ffffff"', | |
136 | } | |
137 | print >>body, '''<table border> | |
138 | <tr><th>Created</th> <th>ID</th> <th>Activity</th> <th>Title</th></tr> | |
139 | ''' | |
140 | old_priority = None | |
141 | for priority_order, activity_date, creation_date, issue_id in l: | |
142 | priority = db.issue.get(issue_id,'priority') | |
143 | if (priority != old_priority): | |
144 | old_priority = priority | |
145 | print >>body, '<tr><td>-></td><td>-></td><td>-></td><td><b>%s</b></td></tr>'%db.priority.get(priority,'name') | |
146 | creation = (date.Date('.') - creation_date).pretty() | |
147 | if creation is None: | |
148 | creation = (creation_date - date.Date('.')).pretty() | |
149 | title = db.issue.get(issue_id, 'title') | |
150 | issue_id = '<a href="%sissue%s">%s</a>'%(db.config.TRACKER_WEB, | |
151 | issue_id, issue_id) | |
152 | activity = (activity_date - date.Date('.')).pretty() | |
153 | print >>body, '''<tr><td>%s</td><td>%s</td><td>%s</td> | |
154 | <td>%s</td></tr>'''%(creation, issue_id, activity, title) | |
155 | print >>body, '</table>' | |
156 | ||
157 | print >>body, '''<p>To view or respond to any of the issues listed | |
158 | above, simply click on the issue ID. Do <b>not</b> respond to | |
159 | this message.</p>''' | |
160 | ||
161 | # finish of the multipart | |
162 | writer.lastpart() | |
163 | ||
164 | # all done, send! | |
165 | smtp = SMTPConnection(db.config) | |
166 | smtp.sendmail(db.config.ADMIN_EMAIL, address, message.getvalue()) | |
167 | ||
168 | # vim: set filetype=python ts=4 sw=4 et si |