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.4 2005-04-04 08:47:14 richard Exp $ 19 20 # Python 2.3 ... 2.6 compatibility: 21 from roundup.anypy.sets_ import set 22 23 from roundup import roundupdb, hyperdb 24 25 def nosyreaction(db, cl, nodeid, oldvalues): 26 ''' A standard detector is provided that watches for additions to the 27 "messages" property. 28 29 When a new message is added, the detector sends it to all the users on 30 the "nosy" list for the issue that are not already on the "recipients" 31 list of the message. 32 33 Those users are then appended to the "recipients" property on the 34 message, so multiple copies of a message are never sent to the same 35 user. 36 37 The journal recorded by the hyperdatabase on the "recipients" property 38 then provides a log of when the message was sent to whom. 39 ''' 40 # send a copy of all new messages to the nosy list 41 for msgid in determineNewMessages(cl, nodeid, oldvalues): 42 try: 43 cl.nosymessage(nodeid, msgid, oldvalues) 44 except roundupdb.MessageSendError, message: 45 raise roundupdb.DetectorError, message 46 47 def determineNewMessages(cl, nodeid, oldvalues): 48 ''' Figure a list of the messages that are being added to the given 49 node in this transaction. 50 ''' 51 messages = [] 52 if oldvalues is None: 53 # the action was a create, so use all the messages in the create 54 messages = cl.get(nodeid, 'messages') 55 elif oldvalues.has_key('messages'): 56 # the action was a set (so adding new messages to an existing issue) 57 m = {} 58 for msgid in oldvalues['messages']: 59 m[msgid] = 1 60 messages = [] 61 # figure which of the messages now on the issue weren't there before 62 for msgid in cl.get(nodeid, 'messages'): 63 if not m.has_key(msgid): 64 messages.append(msgid) 65 return messages 66 67 def updatenosy(db, cl, nodeid, newvalues): 68 '''Update the nosy list for changes to the assignedto 69 ''' 70 # nodeid will be None if this is a new node 71 current_nosy = set() 72 if nodeid is None: 73 ok = ('new', 'yes') 74 else: 75 ok = ('yes',) 76 # old node, get the current values from the node if they haven't 77 # changed 78 if not newvalues.has_key('nosy'): 79 nosy = cl.get(nodeid, 'nosy') 80 for value in nosy: 81 current_nosy.add(value) 82 83 # if the nosy list changed in this transaction, init from the new value 84 if newvalues.has_key('nosy'): 85 nosy = newvalues.get('nosy', []) 86 for value in nosy: 87 if not db.hasnode('user', value): 88 continue 89 current_nosy.add(value) 90 91 new_nosy = set(current_nosy) 92 93 # add assignedto(s) to the nosy list 94 if newvalues.has_key('assignedto') and newvalues['assignedto'] is not None: 95 propdef = cl.getprops() 96 if isinstance(propdef['assignedto'], hyperdb.Link): 97 assignedto_ids = [newvalues['assignedto']] 98 elif isinstance(propdef['assignedto'], hyperdb.Multilink): 99 assignedto_ids = newvalues['assignedto'] 100 for assignedto_id in assignedto_ids: 101 new_nosy.add(assignedto_id) 102 103 # see if there's any new messages - if so, possibly add the author and 104 # recipient to the nosy 105 if newvalues.has_key('messages'): 106 if nodeid is None: 107 ok = ('new', 'yes') 108 messages = newvalues['messages'] 109 else: 110 ok = ('yes',) 111 # figure which of the messages now on the issue weren't 112 oldmessages = cl.get(nodeid, 'messages') 113 messages = [] 114 for msgid in newvalues['messages']: 115 if msgid not in oldmessages: 116 messages.append(msgid) 117 118 # configs for nosy modifications 119 add_author = getattr(db.config, 'ADD_AUTHOR_TO_NOSY', 'new') 120 add_recips = getattr(db.config, 'ADD_RECIPIENTS_TO_NOSY', 'new') 121 122 # now for each new message: 123 msg = db.msg 124 for msgid in messages: 125 if add_author in ok: 126 authid = msg.get(msgid, 'author') 127 new_nosy.add(authid) 128 129 # add on the recipients of the message 130 if add_recips in ok: 131 for recipient in msg.get(msgid, 'recipients'): 132 new_nosy.add(recipient) 133 134 if current_nosy != new_nosy: 135 # that's it, save off the new nosy list 136 newvalues['nosy'] = list(new_nosy) 137 138 def init(db): 139 db.issue.react('create', nosyreaction) 140 db.issue.react('set', nosyreaction) 141 db.issue.audit('create', updatenosy) 142 db.issue.audit('set', updatenosy) 143 144 # vim: set filetype=python ts=4 sw=4 et si