[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