[Zope3-checkins] CVS: Products3/z3checkins - TODO:1.10 configure.zcml:1.13 folder.py:1.2 message.py:1.24

Gintautas Miliauskas gintas at pov.lt
Tue Feb 10 09:23:59 EST 2004


Update of /cvs-repository/Products3/z3checkins
In directory cvs.zope.org:/tmp/cvs-serv29167

Modified Files:
	TODO configure.zcml folder.py message.py 
Log Message:
* Now mbox files can be imported.
* Testing messages extracted into separate files.
* The message object's name is forced to be the same as the message's id.
* Updated unit tests.
* Now message ID's are stripped of angled brackets
* Fixed a bug with message subject parsing.


=== Products3/z3checkins/TODO 1.9 => 1.10 ===
--- Products3/z3checkins/TODO:1.9	Wed Sep 17 10:25:47 2003
+++ Products3/z3checkins/TODO	Tue Feb 10 09:23:27 2004
@@ -1,9 +1,6 @@
 I definitely want to do the following:
 
 - Make sure non-ASCII chars work both in headers and in bodies
-- A way to add multiple messages with a single upload (Unix mbox file)
-- Write a factory to create folders marked with ICheckinsFolder and containing
-  the appropriate Dublin Core metadata.
 
 I'm not sure I'll find time for these:
 


=== Products3/z3checkins/configure.zcml 1.12 => 1.13 ===
--- Products3/z3checkins/configure.zcml:1.12	Tue Jan 13 12:08:54 2004
+++ Products3/z3checkins/configure.zcml	Tue Feb 10 09:23:27 2004
@@ -52,6 +52,11 @@
            permission="zope.View"
            provides=".interfaces.IMessageArchive" />
 
+  <adapter for=".interfaces.ICheckinsFolder"
+           factory=".folder.MessageNameChooser"
+           permission="zope.View"
+           provides="zope.app.interfaces.container.INameChooser" />
+
   <utility factory=".message.CheckinMessageParser"
            permission="zope.View"
            provides=".interfaces.IMessageParser" />


=== Products3/z3checkins/folder.py 1.1 => 1.2 ===
--- Products3/z3checkins/folder.py:1.1	Tue Jan 13 12:08:54 2004
+++ Products3/z3checkins/folder.py	Tue Feb 10 09:23:27 2004
@@ -8,9 +8,27 @@
 
 from zope.interface import implements
 from zope.app.container.btree import BTreeContainer
+from zope.app.interfaces.container import INameChooser
+from zope.app.interfaces.container import IContainerNamesContainer
 from interfaces import ICheckinsFolder
 
 class CheckinsFolder(BTreeContainer):
-    """A message folder"""
+    """A message folder."""
     
-    implements(ICheckinsFolder)
+    implements(ICheckinsFolder, IContainerNamesContainer)
+
+
+class MessageNameChooser:
+    """An adapter to choose names for messages."""
+
+    implements(INameChooser)
+
+    def __init__(self, context):
+        pass
+
+    def chooseName(self, name, message):
+        return message.message_id
+    
+    def checkName(self, name, message):
+        return name == message.message_id
+


=== Products3/z3checkins/message.py 1.23 => 1.24 ===
--- Products3/z3checkins/message.py:1.23	Mon Feb  9 05:17:26 2004
+++ Products3/z3checkins/message.py	Tue Feb 10 09:23:27 2004
@@ -9,7 +9,9 @@
 
 import re
 import rfc822
+import mailbox
 import time
+
 from StringIO import StringIO
 from datetime import datetime, tzinfo, timedelta
 from persistence import Persistent
@@ -140,11 +142,14 @@
 
     body = property(_getBody)
 
-    def __cmp__(self, other):
+    def __eq__(self, other):
         """Messages with the same message_id compare identical."""
         if not IMessage.isImplementedBy(other):
-            raise NotImplementedError
-        return cmp(self.message_id, other.message_id)
+            return False
+        return self.message_id == other.message_id
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
 
 
 class CheckinMessage(Message):
@@ -181,8 +186,10 @@
             input = StringIO(full_text)
 
         m = rfc822.Message(input)
-        subject = m.getheader('Subject')
+        subject = m.getheader('Subject').replace('\n', '')
         message_id = m.getheader('Message-Id')
+        if message_id[0] == "<" and message_id[-1] == ">":
+            message_id = message_id[1:-1]
         author = m.getheader('From')
         author_name, author_email = m.getaddr('From')
         date = m.getheader('Date')
@@ -201,36 +208,49 @@
         date = datetime(year, month, day, hours, minutes, seconds,
                         tzinfo=FixedTimezone(tzoffset / 60))
 
-        if (subject.startswith("Re:") or
-            subject.find("CVS:") == -1
-            and subject.find("rev ") == -1):
-            return Message(message_id=message_id, author=author,
-                           author_name=author_name,
-                           author_email=author_email, subject=subject,
-                           date=date, full_text=full_text)
-
-        if subject.find("CVS:") != -1:
-            subject = subject.split("CVS: ", 1)[1]
-            directory = subject.split(' - ')[0]
-        elif subject.find("rev ") != -1:
-            directory = subject.replace('\n', '').split(' - ')[1]
-
-        m.rewindbody()
-        body_lines = input.readlines()
-        log_message, branch = self.extract_log(body_lines)
-        # XXX perhaps if log message is not found (extract_log raises
-        #     FormatError), fall back to adding a simple Message
-        return CheckinMessage(message_id=message_id, author=author,
-                              author_name=author_name,
-                              author_email=author_email, subject=subject,
-                              date=date, full_text=full_text,
-                              directory=directory, log_message=log_message,
-                              branch=branch)
+        try:
+            if not (subject.startswith("Re:") or
+                subject.find("CVS:") == -1
+                and subject.find("rev ") == -1):
+            
+                    if subject.find("CVS:") != -1:
+                        parts = subject.split("CVS: ", 1)
+                        if len(parts) < 2:
+                            raise FormatError()
+                        subject = parts[1]
+                        directory = subject.split(' - ')[0]
+                    elif subject.find("rev ") != -1:
+                        parts = subject.split(' - ')
+                        if len(parts) < 2:
+                            raise FormatError()
+                        directory = parts[1]
+
+                    m.rewindbody()
+                    body_lines = input.readlines()
+                    # this might throw a FormatError on its own as well
+                    log_message, branch = self.extract_log(body_lines)
+                    return CheckinMessage(
+                        message_id=message_id, author=author,
+                        author_name=author_name,
+                        author_email=author_email, subject=subject,
+                        date=date, full_text=full_text,
+                        directory=directory, log_message=log_message,
+                        branch=branch)
+
+        except FormatError:
+            # fall back to adding a simple message
+            pass
+
+        return Message(message_id=message_id, author=author,
+                       author_name=author_name,
+                       author_email=author_email, subject=subject,
+                       date=date, full_text=full_text)
+
 
     def extract_log(self, lines):
         log_message = []
         branch = None
-        in_log_msg = 0
+        in_log_msg = False
         for line in lines:
             if in_log_msg:
                 if (line.startswith('=== ')
@@ -247,7 +267,7 @@
             else:
                 if (line.lower().startswith('log message:') or
                     line.startswith("Log:")):
-                    in_log_msg = 1
+                    in_log_msg = True
                 elif line.startswith('      Tag: '):
                     branch = line[len('      Tag: '):].strip()
         if not in_log_msg:
@@ -303,12 +323,17 @@
     data_widget = CustomWidget(FileWidget)
 
     def createAndAdd(self, data):
+        msg_raw = data['data']
         parser = getUtility(self.context, IMessageParser)
-        message = parser.parse(data['data'])
-        if not self.context.contentName:
-            self.context.contentName = message.message_id
-        self.add(message)
-
+        if msg_raw.startswith("From "):
+            # detected an mbox file
+            mbox = StringIO(msg_raw)
+            messages = mailbox.PortableUnixMailbox(mbox, factory=parser.parse)
+            for message in messages:
+                self.add(message)
+        else:
+            message = parser.parse(msg_raw)
+            self.add(message)
 
 
 class ContainerView:




More information about the Zope3-Checkins mailing list