paul@2 | 1 | # |
paul@2 | 2 | # Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/) |
paul@2 | 3 | # This module is free software, and you may redistribute it and/or modify |
paul@2 | 4 | # under the same terms as Python, so long as this copyright message and |
paul@2 | 5 | # disclaimer are retained in their original form. |
paul@2 | 6 | # |
paul@2 | 7 | # IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR |
paul@2 | 8 | # DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING |
paul@2 | 9 | # OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE |
paul@2 | 10 | # POSSIBILITY OF SUCH DAMAGE. |
paul@2 | 11 | # |
paul@2 | 12 | # BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
paul@2 | 13 | # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
paul@2 | 14 | # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" |
paul@2 | 15 | # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, |
paul@2 | 16 | # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
paul@2 | 17 | # |
paul@2 | 18 | #$Id: nosyreaction.py,v 1.4 2005-04-04 08:47:14 richard Exp $ |
paul@2 | 19 | |
paul@2 | 20 | # Python 2.3 ... 2.6 compatibility: |
paul@2 | 21 | from roundup.anypy.sets_ import set |
paul@2 | 22 | |
paul@2 | 23 | from roundup import roundupdb, hyperdb |
paul@2 | 24 | |
paul@2 | 25 | def nosyreaction(db, cl, nodeid, oldvalues): |
paul@2 | 26 | ''' A standard detector is provided that watches for additions to the |
paul@2 | 27 | "messages" property. |
paul@2 | 28 | |
paul@2 | 29 | When a new message is added, the detector sends it to all the users on |
paul@2 | 30 | the "nosy" list for the issue that are not already on the "recipients" |
paul@2 | 31 | list of the message. |
paul@2 | 32 | |
paul@2 | 33 | Those users are then appended to the "recipients" property on the |
paul@2 | 34 | message, so multiple copies of a message are never sent to the same |
paul@2 | 35 | user. |
paul@2 | 36 | |
paul@2 | 37 | The journal recorded by the hyperdatabase on the "recipients" property |
paul@2 | 38 | then provides a log of when the message was sent to whom. |
paul@2 | 39 | ''' |
paul@2 | 40 | # send a copy of all new messages to the nosy list |
paul@2 | 41 | for msgid in determineNewMessages(cl, nodeid, oldvalues): |
paul@2 | 42 | try: |
paul@2 | 43 | cl.nosymessage(nodeid, msgid, oldvalues) |
paul@2 | 44 | except roundupdb.MessageSendError, message: |
paul@2 | 45 | raise roundupdb.DetectorError, message |
paul@2 | 46 | |
paul@2 | 47 | def determineNewMessages(cl, nodeid, oldvalues): |
paul@2 | 48 | ''' Figure a list of the messages that are being added to the given |
paul@2 | 49 | node in this transaction. |
paul@2 | 50 | ''' |
paul@2 | 51 | messages = [] |
paul@2 | 52 | if oldvalues is None: |
paul@2 | 53 | # the action was a create, so use all the messages in the create |
paul@2 | 54 | messages = cl.get(nodeid, 'messages') |
paul@2 | 55 | elif oldvalues.has_key('messages'): |
paul@2 | 56 | # the action was a set (so adding new messages to an existing issue) |
paul@2 | 57 | m = {} |
paul@2 | 58 | for msgid in oldvalues['messages']: |
paul@2 | 59 | m[msgid] = 1 |
paul@2 | 60 | messages = [] |
paul@2 | 61 | # figure which of the messages now on the issue weren't there before |
paul@2 | 62 | for msgid in cl.get(nodeid, 'messages'): |
paul@2 | 63 | if not m.has_key(msgid): |
paul@2 | 64 | messages.append(msgid) |
paul@2 | 65 | return messages |
paul@2 | 66 | |
paul@2 | 67 | def updatenosy(db, cl, nodeid, newvalues): |
paul@2 | 68 | '''Update the nosy list for changes to the assignedto |
paul@2 | 69 | ''' |
paul@2 | 70 | # nodeid will be None if this is a new node |
paul@2 | 71 | current_nosy = set() |
paul@2 | 72 | if nodeid is None: |
paul@2 | 73 | ok = ('new', 'yes') |
paul@2 | 74 | else: |
paul@2 | 75 | ok = ('yes',) |
paul@2 | 76 | # old node, get the current values from the node if they haven't |
paul@2 | 77 | # changed |
paul@2 | 78 | if not newvalues.has_key('nosy'): |
paul@2 | 79 | nosy = cl.get(nodeid, 'nosy') |
paul@2 | 80 | for value in nosy: |
paul@2 | 81 | current_nosy.add(value) |
paul@2 | 82 | |
paul@2 | 83 | # if the nosy list changed in this transaction, init from the new value |
paul@2 | 84 | if newvalues.has_key('nosy'): |
paul@2 | 85 | nosy = newvalues.get('nosy', []) |
paul@2 | 86 | for value in nosy: |
paul@2 | 87 | if not db.hasnode('user', value): |
paul@2 | 88 | continue |
paul@2 | 89 | current_nosy.add(value) |
paul@2 | 90 | |
paul@2 | 91 | new_nosy = set(current_nosy) |
paul@2 | 92 | |
paul@2 | 93 | # add assignedto(s) to the nosy list |
paul@2 | 94 | if newvalues.has_key('assignedto') and newvalues['assignedto'] is not None: |
paul@2 | 95 | propdef = cl.getprops() |
paul@2 | 96 | if isinstance(propdef['assignedto'], hyperdb.Link): |
paul@2 | 97 | assignedto_ids = [newvalues['assignedto']] |
paul@2 | 98 | elif isinstance(propdef['assignedto'], hyperdb.Multilink): |
paul@2 | 99 | assignedto_ids = newvalues['assignedto'] |
paul@2 | 100 | for assignedto_id in assignedto_ids: |
paul@2 | 101 | new_nosy.add(assignedto_id) |
paul@2 | 102 | |
paul@2 | 103 | # see if there's any new messages - if so, possibly add the author and |
paul@2 | 104 | # recipient to the nosy |
paul@2 | 105 | if newvalues.has_key('messages'): |
paul@2 | 106 | if nodeid is None: |
paul@2 | 107 | ok = ('new', 'yes') |
paul@2 | 108 | messages = newvalues['messages'] |
paul@2 | 109 | else: |
paul@2 | 110 | ok = ('yes',) |
paul@2 | 111 | # figure which of the messages now on the issue weren't |
paul@2 | 112 | oldmessages = cl.get(nodeid, 'messages') |
paul@2 | 113 | messages = [] |
paul@2 | 114 | for msgid in newvalues['messages']: |
paul@2 | 115 | if msgid not in oldmessages: |
paul@2 | 116 | messages.append(msgid) |
paul@2 | 117 | |
paul@2 | 118 | # configs for nosy modifications |
paul@2 | 119 | add_author = getattr(db.config, 'ADD_AUTHOR_TO_NOSY', 'new') |
paul@2 | 120 | add_recips = getattr(db.config, 'ADD_RECIPIENTS_TO_NOSY', 'new') |
paul@2 | 121 | |
paul@2 | 122 | # now for each new message: |
paul@2 | 123 | msg = db.msg |
paul@2 | 124 | for msgid in messages: |
paul@2 | 125 | if add_author in ok: |
paul@2 | 126 | authid = msg.get(msgid, 'author') |
paul@2 | 127 | new_nosy.add(authid) |
paul@2 | 128 | |
paul@2 | 129 | # add on the recipients of the message |
paul@2 | 130 | if add_recips in ok: |
paul@2 | 131 | for recipient in msg.get(msgid, 'recipients'): |
paul@2 | 132 | new_nosy.add(recipient) |
paul@2 | 133 | |
paul@2 | 134 | if current_nosy != new_nosy: |
paul@2 | 135 | # that's it, save off the new nosy list |
paul@2 | 136 | newvalues['nosy'] = list(new_nosy) |
paul@2 | 137 | |
paul@2 | 138 | def init(db): |
paul@2 | 139 | db.issue.react('create', nosyreaction) |
paul@2 | 140 | db.issue.react('set', nosyreaction) |
paul@2 | 141 | db.issue.audit('create', updatenosy) |
paul@2 | 142 | db.issue.audit('set', updatenosy) |
paul@2 | 143 | |
paul@2 | 144 | # vim: set filetype=python ts=4 sw=4 et si |