1 #
2 # Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
3 # This module is free software, and you may redistribute it and/or modify
4 # under the same terms as Python, so long as this copyright message and
5 # disclaimer are retained in their original form.
6 #
7 # IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
8 # DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
9 # OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
10 # POSSIBILITY OF SUCH DAMAGE.
11 #
12 # BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
17 #
18 #$Id: nosyreaction.py,v 1.13 2002-07-31 23:57:36 richard Exp $
20 from roundup import roundupdb, hyperdb
22 def nosyreaction(db, cl, nodeid, oldvalues):
23 ''' A standard detector is provided that watches for additions to the
24 "messages" property.
26 When a new message is added, the detector sends it to all the users on
27 the "nosy" list for the issue that are not already on the "recipients"
28 list of the message.
30 Those users are then appended to the "recipients" property on the
31 message, so multiple copies of a message are never sent to the same
32 user.
34 The journal recorded by the hyperdatabase on the "recipients" property
35 then provides a log of when the message was sent to whom.
36 '''
37 # send a copy of all new messages to the nosy list
38 for msgid in determineNewMessages(cl, nodeid, oldvalues):
39 try:
40 cl.nosymessage(nodeid, msgid, oldvalues)
41 except roundupdb.MessageSendError, message:
42 raise roundupdb.DetectorError, message
44 def determineNewMessages(cl, nodeid, oldvalues):
45 ''' Figure a list of the messages that are being added to the given
46 node in this transaction.
47 '''
48 messages = []
49 if oldvalues is None:
50 # the action was a create, so use all the messages in the create
51 messages = cl.get(nodeid, 'messages')
52 elif oldvalues.has_key('messages'):
53 # the action was a set (so adding new messages to an existing issue)
54 m = {}
55 for msgid in oldvalues['messages']:
56 m[msgid] = 1
57 messages = []
58 # figure which of the messages now on the issue weren't there before
59 for msgid in cl.get(nodeid, 'messages'):
60 if not m.has_key(msgid):
61 messages.append(msgid)
62 return messages
64 def updatenosy(db, cl, nodeid, newvalues):
65 '''Update the nosy list for changes to the assignedto
66 '''
67 # nodeid will be None if this is a new node
68 current = {}
69 if nodeid is None:
70 ok = ('new', 'yes')
71 else:
72 ok = ('yes',)
73 # old node, get the current values from the node if they haven't
74 # changed
75 if not newvalues.has_key('nosy'):
76 nosy = cl.get(nodeid, 'nosy')
77 for value in nosy:
78 if not current.has_key(value):
79 current[value] = 1
81 # if the nosy list changed in this transaction, init from the new value
82 if newvalues.has_key('nosy'):
83 nosy = newvalues.get('nosy', [])
84 for value in nosy:
85 if not db.hasnode('user', value):
86 continue
87 if not current.has_key(value):
88 current[value] = 1
90 # add assignedto(s) to the nosy list
91 if newvalues.has_key('assignedto') and newvalues['assignedto'] is not None:
92 propdef = cl.getprops()
93 if isinstance(propdef['assignedto'], hyperdb.Link):
94 assignedto_ids = [newvalues['assignedto']]
95 elif isinstance(propdef['assignedto'], hyperdb.Multilink):
96 assignedto_ids = newvalues['assignedto']
97 for assignedto_id in assignedto_ids:
98 if not current.has_key(assignedto_id):
99 current[assignedto_id] = 1
101 # see if there's any new messages - if so, possibly add the author and
102 # recipient to the nosy
103 if newvalues.has_key('messages'):
104 if nodeid is None:
105 ok = ('new', 'yes')
106 messages = newvalues['messages']
107 else:
108 ok = ('yes',)
109 # figure which of the messages now on the issue weren't
110 # there before - make sure we don't get a cached version!
111 oldmessages = cl.get(nodeid, 'messages', cache=0)
112 messages = []
113 for msgid in newvalues['messages']:
114 if msgid not in oldmessages:
115 messages.append(msgid)
117 # configs for nosy modifications
118 add_author = getattr(db.config, 'ADD_AUTHOR_TO_NOSY', 'new')
119 add_recips = getattr(db.config, 'ADD_RECIPIENTS_TO_NOSY', 'new')
121 # now for each new message:
122 msg = db.msg
123 for msgid in messages:
124 if add_author in ok:
125 authid = msg.get(msgid, 'author')
126 current[authid] = 1
128 # add on the recipients of the message
129 if add_recips in ok:
130 for recipient in msg.get(msgid, 'recipients'):
131 current[recipient] = 1
133 # that's it, save off the new nosy list
134 newvalues['nosy'] = current.keys()
136 def init(db):
137 db.issue.react('create', nosyreaction)
138 db.issue.react('set', nosyreaction)
139 db.issue.audit('create', updatenosy)
140 db.issue.audit('set', updatenosy)
142 #
143 #$Log: not supported by cvs2svn $
144 #Revision 1.12 2002/05/29 01:16:17 richard
145 #Sorry about this huge checkin! It's fixing a lot of related stuff in one go
146 #though.
147 #
148 #. #541941 ] changing multilink properties by mail
149 #. #526730 ] search for messages capability
150 #. #505180 ] split MailGW.handle_Message
151 # - also changed cgi client since it was duplicating the functionality
152 #. build htmlbase if tests are run using CVS checkout (removed note from
153 # installation.txt)
154 #. don't create an empty message on email issue creation if the email is empty
155 #
156 #Revision 1.11 2002/01/14 22:21:38 richard
157 ##503353 ] setting properties in initial email
158 #
159 #Revision 1.10 2002/01/11 23:22:29 richard
160 # . #502437 ] rogue reactor and unittest
161 # in short, the nosy reactor was modifying the nosy list. That code had
162 # been there for a long time, and I suspsect it was there because we
163 # weren't generating the nosy list correctly in other places of the code.
164 # We're now doing that, so the nosy-modifying code can go away from the
165 # nosy reactor.
166 #
167 #Revision 1.9 2001/12/15 19:24:39 rochecompaan
168 # . Modified cgi interface to change properties only once all changes are
169 # collected, files created and messages generated.
170 # . Moved generation of change note to nosyreactors.
171 # . We now check for changes to "assignedto" to ensure it's added to the
172 # nosy list.
173 #
174 #Revision 1.8 2001/12/05 14:26:44 rochecompaan
175 #Removed generation of change note from "sendmessage" in roundupdb.py.
176 #The change note is now generated when the message is created.
177 #
178 #Revision 1.7 2001/11/30 11:29:04 rochecompaan
179 #Property changes are now listed in emails generated by Roundup
180 #
181 #Revision 1.6 2001/11/26 22:55:56 richard
182 #Feature:
183 # . Added INSTANCE_NAME to configuration - used in web and email to identify
184 # the instance.
185 # . Added EMAIL_SIGNATURE_POSITION to indicate where to place the roundup
186 # signature info in e-mails.
187 # . Some more flexibility in the mail gateway and more error handling.
188 # . Login now takes you to the page you back to the were denied access to.
189 #
190 #Fixed:
191 # . Lots of bugs, thanks Roché and others on the devel mailing list!
192 #
193 #Revision 1.5 2001/11/12 22:01:07 richard
194 #Fixed issues with nosy reaction and author copies.
195 #
196 #Revision 1.4 2001/10/30 00:54:45 richard
197 #Features:
198 # . #467129 ] Lossage when username=e-mail-address
199 # . #473123 ] Change message generation for author
200 # . MailGW now moves 'resolved' to 'chatting' on receiving e-mail for an issue.
201 #
202 #Revision 1.3 2001/08/07 00:24:43 richard
203 #stupid typo
204 #
205 #Revision 1.2 2001/08/07 00:15:51 richard
206 #Added the copyright/license notice to (nearly) all files at request of
207 #Bizar Software.
208 #
209 #Revision 1.1 2001/07/23 23:29:10 richard
210 #Adding the classic template
211 #
212 #Revision 1.1 2001/07/23 03:50:47 anthonybaxter
213 #moved templates to proper location
214 #
215 #Revision 1.1 2001/07/22 12:09:32 richard
216 #Final commit of Grande Splite
217 #
218 #