Code

stupid typo
[roundup.git] / roundup / mailgw.py
index 94655476de3217461f77235d95ccb0bbd0dd9671..a2c15e30658c7a203d9e7c5efdeaa32ea12bdb00 100644 (file)
@@ -1,3 +1,20 @@
+#
+# Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
+# This module is free software, and you may redistribute it and/or modify
+# under the same terms as Python, so long as this copyright message and
+# disclaimer are retained in their original form.
+#
+# IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
+# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+# OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
+# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
+# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+# 
 '''
 An e-mail gateway for Roundup.
 
@@ -55,7 +72,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.5 2001-07-29 07:01:39 richard Exp $
+$Id: mailgw.py,v 1.10 2001-08-07 00:24:42 richard Exp $
 '''
 
 
@@ -243,51 +260,42 @@ class MailGW:
         else:
             content = message.fp.read()
 
-        # extract out the summary from the message
-        summary = []
-        for line in content.split('\n'):
-            line = line.strip()
-            if summary and not line:
-                break
-            if not line:
-                summary.append('')
-            elif line[0] not in '>|':
-                summary.append(line)
-        summary = '\n'.join(summary)
+        summary, content = parseContent(content)
 
         # handle the files
         files = []
         for (name, type, data) in attachments:
-            files.append(self.db.file.create(type=type, name=name, content=data))
+            files.append(self.db.file.create(type=type, name=name,
+                content=data))
 
         # now handle the db stuff
         if nodeid:
-            # If an item designator (class name and id number) is found there, the
-            # newly created "msg" node is added to the "messages" property for
-            # that item, and any new "file" nodes are added to the "files" 
+            # If an item designator (class name and id number) is found there,
+            # 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)
+            message_id = self.db.msg.create(author=author,
+                recipients=recipients, date=date.Date('.'), summary=summary,
+                content=content, files=files)
             messages = cl.get(nodeid, 'messages')
             messages.append(message_id)
             props['messages'] = messages
-            apply(cl.set, (nodeid, ), props)
+            cl.set(nodeid, **props)
         else:
             # If just an item class name is found there, we attempt to create a
             # new item of that class with its "messages" property initialized to
             # contain the new "msg" node and its "files" property initialized to
             # contain any new "file" nodes. 
-            message_id = self.db.msg.create(author=author, recipients=recipients,
-                date=date.Date('.'), summary=summary, content=content,
-                files=files)
-            if not props.has_key('assignedto'):
+            message_id = self.db.msg.create(author=author,
+                recipients=recipients, date=date.Date('.'), summary=summary,
+                content=content, files=files)
+            # fill out the properties with defaults where required
+            if properties.has_key('assignedto') and \
+                    not props.has_key('assignedto'):
                 props['assignedto'] = '1'             # "admin"
-            if not props.has_key('priority'):
-                props['priority'] = '1'               # "bug-fatal"
-            if not props.has_key('status'):
+            if properties.has_key('status') and not props.has_key('status'):
                 props['status'] = '1'                 # "unread"
-            if not props.has_key('title'):
+            if properties.has_key('title') and not props.has_key('title'):
                 props['title'] = title
             props['messages'] = [message_id]
             props['nosy'] = recipients[:]
@@ -295,8 +303,54 @@ class MailGW:
             props['nosy'].sort()
             nodeid = cl.create(**props)
 
+def parseContent(content, blank_line=re.compile(r'[\r\n]+\s*[\r\n]+'),
+        eol=re.compile(r'[\r\n]+'), signature=re.compile(r'^[>|\s]*[-_]+\s*$')):
+    ''' The message body is divided into sections by blank lines.
+    Sections where the second and all subsequent lines begin with a ">" or "|"
+    character are considered "quoting sections". The first line of the first
+    non-quoting section becomes the summary of the message. 
+    '''
+    sections = blank_line.split(content)
+    # extract out the summary from the message
+    summary = ''
+    l = []
+    for section in sections:
+        section = section.strip()
+        if not section:
+            continue
+        lines = eol.split(section)
+        if lines[0] and lines[0][0] in '>|':
+            continue
+        if len(lines) > 1 and lines[1] and lines[1][0] in '>|':
+            continue
+        if not summary:
+            summary = lines[0]
+            l.append(section)
+            continue
+        if signature.match(lines[0]):
+            break
+        l.append(section)
+    return summary, '\n'.join(l)
+
 #
 # $Log: not supported by cvs2svn $
+# Revision 1.9  2001/08/07 00:15:51  richard
+# Added the copyright/license notice to (nearly) all files at request of
+# Bizar Software.
+#
+# Revision 1.8  2001/08/05 07:06:07  richard
+# removed some print statements
+#
+# Revision 1.7  2001/08/03 07:18:22  richard
+# Implemented correct mail splitting (was taking a shortcut). Added unit
+# tests. Also snips signatures now too.
+#
+# Revision 1.6  2001/08/01 04:24:21  richard
+# mailgw was assuming certain properties existed on the issues being created.
+#
+# Revision 1.5  2001/07/29 07:01:39  richard
+# Added vim command to all source so that we don't get no steenkin' tabs :)
+#
 # Revision 1.4  2001/07/28 06:43:02  richard
 # Multipart message class has the getPart method now. Added some tests for it.
 #