Code

Removed generation of change note from "sendmessage" in roundupdb.py.
authorrochecompaan <rochecompaan@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 5 Dec 2001 14:26:44 +0000 (14:26 +0000)
committerrochecompaan <rochecompaan@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 5 Dec 2001 14:26:44 +0000 (14:26 +0000)
The change note is now generated when the message is created.

git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@446 57a73879-2fb5-44c3-a270-3262357dd7e2

roundup/cgi_client.py
roundup/mailgw.py
roundup/roundupdb.py
roundup/templates/classic/detectors/nosyreaction.py
roundup/templates/extended/detectors/nosyreaction.py

index d33e7f16a0f27e0ec1ec185b647477692a3e0384..06cd0d31e3b72ab28290f4c11538ba0f4581aabd 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: cgi_client.py,v 1.75 2001-12-04 01:25:08 richard Exp $
+# $Id: cgi_client.py,v 1.76 2001-12-05 14:26:44 rochecompaan Exp $
 
 __doc__ = """
 WWW request handler (also used in the stand-alone server).
@@ -313,7 +313,7 @@ class Client:
                     self.nodeid)
 
                 # set status to chatting if 'unread' or 'resolved'
-                if 'status' not in changed:
+                if 'status' not in changed.keys():
                     try:
                         # determine the id of 'unread','resolved' and 'chatting'
                         unread_id = self.db.status.lookup('unread')
@@ -326,18 +326,21 @@ class Client:
                                 props['status'] == unread_id or
                                 props['status'] == resolved_id):
                             props['status'] = chatting_id
-                            changed.append('status')
+                            changed['status'] = chatting_id
+
+                # get the change note
+                change_note = cl.generateChangeNote(self.nodeid, changed)
 
                 # make the changes
                 cl.set(self.nodeid, **props)
 
                 # handle linked nodes and change message generation
-                self._post_editnode(self.nodeid, changed)
+                self._post_editnode(self.nodeid, change_note)
 
                 # and some nice feedback for the user
                 if changed:
                     message = _('%(changes)s edited ok')%{'changes':
-                        ', '.join(changed)}
+                        ', '.join(changed.keys())}
                 else:
                     message = _('nothing changed')
             except:
@@ -395,10 +398,10 @@ class Client:
                         del props['password']
                         del changed[changed.index('password')]
                 user.set(self.nodeid, **props)
-                self._post_editnode(self.nodeid, changed)
+                self._post_editnode(self.nodeid)
                 # and some feedback for the user
                 message = _('%(changes)s edited ok')%{'changes':
-                    ', '.join(changed)}
+                    ', '.join(changed.keys())}
             except:
                 self.db.rollback()
                 s = StringIO.StringIO()
@@ -437,9 +440,19 @@ class Client:
         '''
         cl = self.db.classes[self.classname]
         props, dummy = parsePropsFromForm(self.db, cl, self.form)
+
+        # set status to 'unread' if not specified - a status of '- no
+        # selection -' doesn't make sense
+        if not props.has_key('status'):
+            try:
+                unread_id = self.db.status.lookup('unread')
+            except KeyError:
+                pass
+            else:
+                props['status'] = unread_id
         return cl.create(**props)
 
-    def _post_editnode(self, nid, changes=None):
+    def _post_editnode(self, nid, change_note=None):
         ''' do the linking and message sending part of the node creation
         '''
         cn = self.classname
@@ -479,8 +492,6 @@ class Client:
                     name=file.filename, content=file.file.read()))
                 # and save the reference
                 cl.set(nid, files=files)
-                if changes is not None and 'file' not in changes:
-                    changes.append('file')
 
         #
         # generate an edit message
@@ -513,7 +524,8 @@ class Client:
                 ' the web.\n')%{'classname': cn}
             m = [summary]
 
-        # TODO: append the change note!
+        # append the change note
+        m.append(change_note)
 
         # now create the message
         content = '\n'.join(m)
@@ -1002,7 +1014,7 @@ def parsePropsFromForm(db, cl, form, nodeid=0):
     '''Pull properties for the given class out of the form.
     '''
     props = {}
-    changed = []
+    changed = {}
     keys = form.keys()
     num_re = re.compile('^\d+$')
     for key in keys:
@@ -1042,6 +1054,7 @@ def parsePropsFromForm(db, cl, form, nodeid=0):
             link = cl.properties[key].classname
             l = []
             for entry in map(str, value):
+                if entry == '': continue
                 if not num_re.match(entry):
                     try:
                         entry = db.classes[link].lookup(entry)
@@ -1065,12 +1078,16 @@ def parsePropsFromForm(db, cl, form, nodeid=0):
 
         # if changed, set it
         if nodeid and value != existing:
-            changed.append(key)
+            changed[key] = value
             props[key] = value
     return props, changed
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.75  2001/12/04 01:25:08  richard
+# Added some rollbacks where we were catching exceptions that would otherwise
+# have stopped committing.
+#
 # Revision 1.74  2001/12/02 05:06:16  richard
 # . We now use weakrefs in the Classes to keep the database reference, so
 #   the close() method on the database is no longer needed.
index f3c1f4c7dfdf715478f8e05918dd8f60ceebe3fd..54de2499c4e4854bdf422f1595068caa2c5ab3ee 100644 (file)
@@ -73,7 +73,7 @@ are calling the create() method to create a new node). If an auditor raises
 an exception, the original message is bounced back to the sender with the
 explanatory message given in the exception. 
 
-$Id: mailgw.py,v 1.39 2001-12-02 05:06:16 richard Exp $
+$Id: mailgw.py,v 1.40 2001-12-05 14:26:44 rochecompaan Exp $
 '''
 
 
@@ -342,9 +342,26 @@ Error was: %s
 Subject was: "%s"
 '''%(key, message, subject)
                 elif isinstance(proptype, hyperdb.Link):
-                    props[key] = value.strip()
+                    link = self.db.classes[proptype.classname]
+                    propkey = link.labelprop(default_to_id=1)
+                    try:
+                        props[key] = link.get(value.strip(), propkey)
+                    except:
+                        props[key] = link.lookup(value.strip())
                 elif isinstance(proptype, hyperdb.Multilink):
-                    props[key] = [x.strip() for x in value.split(',')]
+                    link = self.db.classes[proptype.classname]
+                    propkey = link.labelprop(default_to_id=1)
+                    l = [x.strip() for x in value.split(',')]
+                    for item in l:
+                        try:
+                            v = link.get(item, propkey)
+                        except:
+                            v = link.lookup(item)
+                        if props.has_key(key):
+                            props[key].append(v)
+                        else:
+                            props[key] = [v]
+
 
         #
         # handle the users
@@ -459,20 +476,6 @@ not find a text/plain part to use.
             # the newly created "msg" node is added to the "messages" property
             # for that item, and any new "file" nodes are added to the "files" 
             # property for the item. 
-            message_id = self.db.msg.create(author=author,
-                recipients=recipients, date=date.Date('.'), summary=summary,
-                content=content, files=files)
-            try:
-                messages = cl.get(nodeid, 'messages')
-            except IndexError:
-                raise MailUsageError, '''
-The node specified by the designator in the subject of your message ("%s")
-does not exist.
-
-Subject was: "%s"
-'''%(nodeid, subject)
-            messages.append(message_id)
-            props['messages'] = messages
 
             # if the message is currently 'unread' or 'resolved', then set
             # it to 'chatting'
@@ -490,22 +493,43 @@ Subject was: "%s"
                             props['status'] == resolved_id):
                         props['status'] = chatting_id
 
-            # add nosy in arguments to issue's nosy list, don't replace
-            if props.has_key('nosy'):
-                n = {}
-                for nid in cl.get(nodeid, 'nosy'):
-                    n[nid] = 1
-                for value in props['nosy']:
-                    if self.db.hasnode('user', value):
-                        nid = value
-                    else:
-                        try:
-                            nid = self.db.user.lookup(value)
-                        except:
-                            continue
-                    if n.has_key(nid): continue
-                    n[nid] = 1
-                props['nosy'] = n.keys()
+            # add nosy in arguments to issue's nosy list
+            if not props.has_key('nosy'): props['nosy'] = []
+            n = {}
+            for nid in cl.get(nodeid, 'nosy'):
+                n[nid] = 1
+            for value in props['nosy']:
+                if self.db.hasnode('user', value):
+                    nid = value
+                else: 
+                    continue
+                if n.has_key(nid): continue
+                n[nid] = 1
+            props['nosy'] = n.keys()
+            try:
+                assignedto = self.db.user.lookup(props['assignedto'])
+                if assignedto not in props['nosy']:
+                    props['nosy'].append(assignedto)
+            except:
+                pass
+                
+            change_note = cl.generateChangeNote(nodeid, props)
+            content += change_note
+            
+            message_id = self.db.msg.create(author=author,
+                recipients=recipients, date=date.Date('.'), summary=summary,
+                content=content, files=files)
+            try:
+                messages = cl.get(nodeid, 'messages')
+            except IndexError:
+                raise MailUsageError, '''
+The node specified by the designator in the subject of your message ("%s")
+does not exist.
+
+Subject was: "%s"
+'''%(nodeid, subject)
+            messages.append(message_id)
+            props['messages'] = messages
 
             # now apply the changes
             try:
@@ -542,9 +566,22 @@ There was a problem with the message you sent:
 
             # pre-load the messages list and nosy list
             props['messages'] = [message_id]
-            props['nosy'] = props.get('nosy', []) + recipients
-            props['nosy'].append(author)
-            props['nosy'].sort()
+            nosy = props.get('nosy', [])
+            n = {}
+            for value in nosy:
+                if self.db.hasnode('user', value):
+                    nid = value
+                else:
+                    try:
+                        nid = self.db.user.lookup(value)
+                    except:
+                        continue
+                if n.has_key(nid): continue
+                n[nid] = 1
+            props['nosy'] = n.keys() + recipients
+            if not n.has_key(author):
+                props['nosy'].append(author)
+                n[author] = 1
 
             # and attempt to create the new node
             try:
@@ -598,6 +635,20 @@ def parseContent(content, blank_line=re.compile(r'[\r\n]+\s*[\r\n]+'),
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.39  2001/12/02 05:06:16  richard
+# . We now use weakrefs in the Classes to keep the database reference, so
+#   the close() method on the database is no longer needed.
+#   I bumped the minimum python requirement up to 2.1 accordingly.
+# . #487480 ] roundup-server
+# . #487476 ] INSTALL.txt
+#
+# I also cleaned up the change message / post-edit stuff in the cgi client.
+# There's now a clearly marked "TODO: append the change note" where I believe
+# the change note should be added there. The "changes" list will obviously
+# have to be modified to be a dict of the changes, or somesuch.
+#
+# More testing needed.
+#
 # Revision 1.38  2001/12/01 07:17:50  richard
 # . We now have basic transaction support! Information is only written to
 #   the database when the commit() method is called. Only the anydbm
index c0b6201294c8e625cdf43793efbb3de71da3488d..a359c58eaee7d5bff0db3100e9818f8fa822adc2 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-# $Id: roundupdb.py,v 1.25 2001-11-30 20:28:10 rochecompaan Exp $
+# $Id: roundupdb.py,v 1.26 2001-12-05 14:26:44 rochecompaan Exp $
 
 __doc__ = """
 Extending hyperdb with types specific to issue-tracking.
@@ -268,7 +268,7 @@ class IssueClass(Class):
         appended to the "messages" field of the specified issue.
         """
 
-    def sendmessage(self, nodeid, msgid, oldvalues):
+    def sendmessage(self, nodeid, msgid):
         """Send a message to the members of an issue's nosy list.
 
         The message is sent only to users on the nosy list who are not
@@ -310,19 +310,8 @@ class IssueClass(Class):
         if rlen == len(recipients):
             return
 
-        # get the change note
-        if oldvalues:
-            change_note = self.generateChangeNote(nodeid, oldvalues)
-        else:
-            change_note = ''
-
-        # add the change note to the message content
-        content = self.db.msg.get(msgid, 'content')
-        content += change_note
-
         # update the message's recipients list
         self.db.msg.set(msgid, recipients=recipients)
-        self.db.msg.setcontent('msg', msgid, content)
 
         # send an email to the people who missed out
         sendto = [self.db.user.get(i, 'address') for i in recipients]
@@ -346,14 +335,14 @@ class IssueClass(Class):
             m.append(self.email_signature(nodeid, msgid))
 
         # add author information
-        if oldvalues:
-            m.append("%s%s added the comment:"%(authname, authaddr))
-        else:
+        if len(self.get(nodeid,'messages')) == 1:
             m.append("New submission from %s%s:"%(authname, authaddr))
+        else:
+            m.append("%s%s added the comment:"%(authname, authaddr))
         m.append('')
 
         # add the content
-        m.append(content)
+        m.append(self.db.msg.get(msgid, 'content'))
 
         # put in roundup's signature
         if self.EMAIL_SIGNATURE_POSITION == 'bottom':
@@ -426,7 +415,7 @@ class IssueClass(Class):
         line = '_' * max(len(web), len(email))
         return '%s\n%s\n%s\n%s'%(line, email, web, line)
 
-    def generateChangeNote(self, nodeid, oldvalues):
+    def generateChangeNote(self, nodeid, newvalues):
         """Generate a change note that lists property changes
         """
         cn = self.classname
@@ -435,26 +424,25 @@ class IssueClass(Class):
         props = cl.getprops(protected=0)
 
         # determine what changed
-        for key in props.keys():
+        for key in newvalues.keys():
             if key in ['files','messages']: continue
-            new_value = cl.get(nodeid, key)
+            new_value = newvalues[key]
             # the old value might be non existent
             try:
-                old_value = oldvalues[key]
+                old_value = cl.get(nodeid, key)
                 if type(old_value) is type([]):
                     old_value.sort()
                     new_value.sort()
                 if old_value != new_value:
-                    changed[key] = old_value
+                    changed[key] = new_value
             except:
-                old_value = None
-                changed[key] = old_value
+                changed[key] = new_value
 
         # list the changes
         m = ['','----------']
-        for propname, oldvalue in changed.items():
+        for propname, value in changed.items():
             prop = cl.properties[propname]
-            value = cl.get(nodeid, propname, None)
+            oldvalue = cl.get(nodeid, propname, None)
             change = '%s -> %s'%(oldvalue, value)
             if isinstance(prop, hyperdb.Link):
                 link = self.db.classes[prop.classname]
@@ -472,10 +460,10 @@ class IssueClass(Class):
             elif isinstance(prop, hyperdb.Multilink):
                 change = ''
                 if value is None: value = []
+                if oldvalue is None: oldvalue = []
                 l = []
                 link = self.db.classes[prop.classname]
                 key = link.labelprop(default_to_id=1)
-                if oldvalue is None: oldvalue = []
                 # check for additions
                 for entry in value:
                     if entry in oldvalue: continue
@@ -500,6 +488,10 @@ class IssueClass(Class):
 
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.25  2001/11/30 20:28:10  rochecompaan
+# Property changes are now completely traceable, whether changes are
+# made through the web or by email
+#
 # Revision 1.24  2001/11/30 11:29:04  rochecompaan
 # Property changes are now listed in emails generated by Roundup
 #
index c942e8389cc93237befe5562d136caf81ec54066..b81e587ce801a9913fcca7eac7a08a2b5822036f 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-#$Id: nosyreaction.py,v 1.7 2001-11-30 11:29:04 rochecompaan Exp $
+#$Id: nosyreaction.py,v 1.8 2001-12-05 14:26:44 rochecompaan Exp $
 
 from roundup import roundupdb
 
@@ -54,7 +54,7 @@ def nosyreaction(db, cl, nodeid, oldvalues):
     # send a copy to the nosy list
     for msgid in messages:
         try:
-            cl.sendmessage(nodeid, msgid, oldvalues)
+            cl.sendmessage(nodeid, msgid)
         except roundupdb.MessageSendError, message:
             raise roundupdb.DetectorError, message
 
@@ -89,6 +89,9 @@ def init(db):
 
 #
 #$Log: not supported by cvs2svn $
+#Revision 1.7  2001/11/30 11:29:04  rochecompaan
+#Property changes are now listed in emails generated by Roundup
+#
 #Revision 1.6  2001/11/26 22:55:56  richard
 #Feature:
 # . Added INSTANCE_NAME to configuration - used in web and email to identify
index dc2b84c7efef8f027305f072116e7e31ae445dfb..4643ed99a37eefba41cae70ae4164bb0425b9192 100644 (file)
@@ -15,7 +15,7 @@
 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 # 
-#$Id: nosyreaction.py,v 1.7 2001-11-30 11:29:04 rochecompaan Exp $
+#$Id: nosyreaction.py,v 1.8 2001-12-05 14:26:44 rochecompaan Exp $
 
 from roundup import roundupdb
 
@@ -54,7 +54,7 @@ def nosyreaction(db, cl, nodeid, oldvalues):
     # send a copy to the nosy list
     for msgid in messages:
         try:
-            cl.sendmessage(nodeid, msgid, oldvalues)
+            cl.sendmessage(nodeid, msgid)
         except roundupdb.MessageSendError, message:
             raise roundupdb.DetectorError, message
 
@@ -89,6 +89,9 @@ def init(db):
 
 #
 #$Log: not supported by cvs2svn $
+#Revision 1.7  2001/11/30 11:29:04  rochecompaan
+#Property changes are now listed in emails generated by Roundup
+#
 #Revision 1.6  2001/11/26 22:55:56  richard
 #Feature:
 # . Added INSTANCE_NAME to configuration - used in web and email to identify