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