[Zope3-checkins] CVS: Products3/z3checkins - folder.py:1.1
README:1.5 configure.zcml:1.12 interfaces.py:1.7 message.py:1.22
Gintautas Miliauskas
gintas at pov.lt
Tue Jan 13 12:09:25 EST 2004
Update of /cvs-repository/Products3/z3checkins
In directory cvs.zope.org:/tmp/cvs-serv24299
Modified Files:
README configure.zcml interfaces.py message.py
Added Files:
folder.py
Log Message:
- Updated a number of places that had been broken by geddons.
- Properties are contained in Fields rather than in metadata.
- Made use of preconditions and other nice features.
- Uncommented a few assertions that seemed to apply.
=== Added File Products3/z3checkins/folder.py ===
"""
Python code for z3checkins product.
Checkin message folder handling.
$Id: folder.py,v 1.1 2004/01/13 17:08:54 gintautasm Exp $
"""
from zope.interface import implements
from zope.app.container.btree import BTreeContainer
from interfaces import ICheckinsFolder
class CheckinsFolder(BTreeContainer):
"""A message folder"""
implements(ICheckinsFolder)
=== Products3/z3checkins/README 1.4 => 1.5 ===
--- Products3/z3checkins/README:1.4 Wed Sep 17 09:35:11 2003
+++ Products3/z3checkins/README Tue Jan 13 12:08:54 2004
@@ -8,7 +8,7 @@
aggregator that supports RSS, e.g. Nautilus.
It is also quite usable for other checkin-tracking mailing lists. However
-since there is no single standard on how the messages should be formatted, so
+since there is no single standard on how the messages should be formatted,
your mileage may vary.
@@ -21,15 +21,11 @@
<include package='zopeproducts.z3checkins' />
3. Restart Zope 3.
-4. Create a Folder.
-5. Go to the Introspector tab, click on Modify, and mark the folder with
- zopeproducts.z3checkins.interfaces.ICheckinsFolder marker interface.
-6. Go to the Metadata tab and set the title and description. The description
- field is somewhat structured:
-
- - first paragraph is a description used for checkins.rss view
- - second paragraph is a URL to the traditional mailing list archive.
- - third paragraph is a list of icon definitions used for checkins to
+4. Create a Checkin Folder.
+
+ - first field is a description used for checkins.rss view
+ - second field is a URL to the traditional mailing list archive.
+ - third field is a list of icon definitions used for checkins to
different parts of the source trees. Each line should contain four
fields:
@@ -46,16 +42,20 @@
title is a longer description, usually shown in a tooltip
- Paragraphs are separated by double newlines (\r\n\r\n).
-
- Use the following description for zope3-checkins at zope.org:
+ Use the following configuration for zope3-checkins at zope.org:
+ RSS view description:
Latest Zope 3 Checkins
+ URL of mailing list:
http://mail.zope.org/pipermail/zope3-checkins/
+ Icon definitions:
Zope3 zope3.png Z3 Zope 3 core
* product.png Product Zope 3 product
+
+5. Go to the Metadata tab and set the title.
+
Now you can create Checkin Messages in that folder. In the rest of this
document I assume Zope 3 is accessible at http://localhost:8080/ and that you
=== Products3/z3checkins/configure.zcml 1.11 => 1.12 ===
--- Products3/z3checkins/configure.zcml:1.11 Wed Sep 17 09:15:35 2003
+++ Products3/z3checkins/configure.zcml Tue Jan 13 12:08:54 2004
@@ -26,6 +26,25 @@
</content>
+ <content class=".folder.CheckinsFolder">
+
+ <require permission="zope.View"
+ interface="zope.app.interfaces.container.IReadContainer" />
+
+ <require permission="zope.ManageContent"
+ interface="zope.app.interfaces.container.IWriteContainer" />
+
+ <require permission="zope.ManageContent"
+ set_schema=".interfaces.ICheckinsFolder" />
+
+ <require permission="zope.View"
+ interface=".interfaces.ICheckinsFolderSchema" />
+
+ <implements
+ interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />
+
+ </content>
+
<!-- Utilities -->
<adapter for="zope.app.interfaces.container.IReadContainer"
@@ -45,7 +64,7 @@
for="*"
name="rfc822"
factory=".message.RFCDateTimeFormatter"
- type="zope.publisher.interfaces.browser.IBrowserPresentation"
+ type="zope.publisher.interfaces.http.IHTTPRequest"
permission="zope.Public"
/>
@@ -53,7 +72,7 @@
for="*"
name="isodatetime"
factory=".message.ISODateTimeFormatter"
- type="zope.publisher.interfaces.browser.IBrowserPresentation"
+ type="zope.publisher.interfaces.http.IHTTPRequest"
permission="zope.Public"
/>
@@ -61,14 +80,51 @@
<browser:addform
name="CheckinMessage"
- menu="add_content"
- title="Checkin Message"
schema="zope.app.interfaces.content.file.IFile"
fields="data"
label="Upload a checkin message"
permission="zope.ManageContent"
class=".message.MessageUpload" />
+ <browser:addMenuItem
+ title="Checkin message"
+ class=".message.MessageUpload"
+ permission="zope.ManageContent"
+ view="CheckinMessage" />
+
+ <browser:addform
+ name="CheckinFolder"
+ schema=".interfaces.ICheckinsFolderSchema"
+ fields="description archive_url icons"
+ label="Create a checkin message folder"
+ permission="zope.ManageContent"
+ content_factory=".folder.CheckinsFolder" />
+
+ <browser:addMenuItem
+ title="Checkin Folder"
+ class=".folder.CheckinsFolder"
+ permission="zope.ManageContent"
+ view="CheckinFolder" />
+
+ <browser:view
+ name="+"
+ menu="zmi_actions" title="Add"
+ for=".interfaces.ICheckinsFolder"
+ permission="zope.ManageContent"
+ class="zope.app.browser.container.adding.Adding">
+
+ <page name="index.html" attribute="index" />
+ <page name="action.html" attribute="action" />
+
+ </browser:view>
+
+ <browser:editform
+ name="EditFolder"
+ schema=".interfaces.ICheckinsFolder"
+ label="Change properties of a checkin message folder"
+ menu="zmi_views" title="Edit"
+ permission="zope.ManageContent" />
+
<!-- Browser views: email message -->
<browser:page
=== Products3/z3checkins/interfaces.py 1.6 => 1.7 ===
--- Products3/z3checkins/interfaces.py:1.6 Tue Sep 9 18:16:33 2003
+++ Products3/z3checkins/interfaces.py Tue Jan 13 12:08:54 2004
@@ -6,6 +6,10 @@
from zope.interface import Interface, Attribute
from zope.app.interfaces.content.folder import IFolder
+from zope.app.interfaces.container import IContainer, IContained
+from zope.app.container.constraints import ContainerTypesConstraint
+from zope.app.container.constraints import ItemTypePrecondition
+from zope.schema import Field, Text, TextLine
class IMessage(Interface):
"""Mail message."""
@@ -50,8 +54,35 @@
May raise a FormatError if the message is ill-formed.
"""
-class ICheckinsFolder(IFolder):
+
+class ICheckinsFolderSchema(Interface):
+ """Checkin folder properties"""
+
+ description = TextLine(title=u"RSS view description",
+ required=False)
+ archive_url = TextLine(title=u"URL of mailing list archive",
+ required=False)
+ icons = Text(title=u"Icon definitions", required=False)
+
+
+class IMessageUpload(Interface):
+ pass
+
+
+class ICheckinsFolder(IFolder, ICheckinsFolderSchema):
"""A marker interface for the checkins folder."""
+
+ def __setitem__(name, object):
+ """Add a message"""
+
+ __setitem__.precondition = ItemTypePrecondition(IMessageUpload)
+
+
+class IMessageContained(IContained):
+ """A contained message."""
+
+ __parent__ = Field(constraint=ContainerTypesConstraint(ICheckinsFolder))
+
class IMessageArchive(Interface):
"""A chronologically ordered sequence of messages.
=== Products3/z3checkins/message.py 1.21 => 1.22 ===
--- Products3/z3checkins/message.py:1.21 Wed Oct 15 15:42:53 2003
+++ Products3/z3checkins/message.py Tue Jan 13 12:08:54 2004
@@ -17,7 +17,7 @@
from zope.component import getUtility, getAdapter, queryAdapter
from zope.app.browser.form.widget import FileWidget
from zope.app.form.widget import CustomWidget
-from zope.app.context import ContextWrapper
+from zope.context import Wrapper
from zope.context import getWrapperContainer
from zope.app.interfaces.container import IReadContainer
from zope.proxy import removeAllProxies
@@ -27,7 +27,8 @@
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.app.interfaces.dublincore import IZopeDublinCore
-from interfaces import IMessage, ICheckinMessage, IBookmark
+from interfaces import IMessage, ICheckinMessage, IBookmark, IMessageContained
+from interfaces import IMessageUpload
from interfaces import IMessageParser, IMessageArchive
from interfaces import FormatError
@@ -77,7 +78,7 @@
class ISODateTimeFormatter:
"""ISO 8601 view for datetime objects."""
- if time.daylight:
+ if time.localtime()[-1]:
userstz = FixedTimezone(-time.altzone / 60)
else:
userstz = FixedTimezone(-time.timezone / 60)
@@ -116,7 +117,9 @@
class Message(Persistent):
"""Persistent email message."""
- implements(IMessage)
+ implements(IMessage, IMessageContained)
+
+ __parent__ = __name__ = None
def __init__(self, message_id=None, author=None, author_name=None,
author_email=None, subject=None, date=None,
@@ -258,7 +261,7 @@
if IMessage.isImplementedBy(item):
items.append((item.date, key, item))
items.sort()
- self.messages = [ContextWrapper(item, self.context, name=key)
+ self.messages = [Wrapper(item, self.context, name=key)
for date, key, item in items]
def __len__(self):
@@ -289,6 +292,7 @@
class MessageUpload:
"""Adding view mixin for uploading checkin messages."""
+ implements(IMessageUpload, IMessageContained)
data_widget = CustomWidget(FileWidget)
def createAndAdd(self, data):
@@ -320,28 +324,13 @@
def description(self):
"""Returns the description of this archive.
-
- Description text is obtained from the first paragraph of Dublin Core
- description of the folder.
"""
- dc = queryAdapter(self.context, IZopeDublinCore)
- if dc is not None:
- description = dc.description.split('\r\n\r\n')
- if len(description) > 0:
- return description[0]
- return description
+ return self.context.description
def archive_url(self):
"""Returns the URL for mailing list archives.
-
- The URL is obtained from the second paragraph of Dublin Core
- description of the folder.
"""
- dc = queryAdapter(self.context, IZopeDublinCore)
- if dc is not None:
- description = dc.description.split('\r\n\r\n')
- if len(description) > 1:
- return description[1]
+ return self.context.archive_url
def bookmarks(self):
"""Returns a list of bookmarks from a cookie. Each bookmark is
@@ -529,14 +518,11 @@
if self._subtrees is not None:
return self._subtrees
self._subtrees = []
- container = getWrapperContainer(self.context)
- dc = queryAdapter(container, IZopeDublinCore)
- if dc is None:
- return self._subtrees
- description = dc.description.split('\r\n\r\n')
- if len(description) < 3:
+ container = self.context.__parent__
+ description = container.description
+ if not description:
return self._subtrees
- for line in description[2].splitlines():
+ for line in description.splitlines():
items = line.split(None, 3)
if len(items) < 4:
continue
More information about the Zope3-Checkins
mailing list