[Zope3-checkins] CVS: Products3/demo/messageboard/step6 - __init__.py:1.1 configure.zcml:1.1 fields.py:1.1 interfaces.py:1.1 message.py:1.1 messageboard.py:1.1

Stephan Richter srichter@cosmos.phy.tufts.edu
Thu, 10 Jul 2003 16:34:00 -0400


Update of /cvs-repository/Products3/demo/messageboard/step6
In directory cvs.zope.org:/tmp/cvs-serv22326

Added Files:
	__init__.py configure.zcml fields.py interfaces.py message.py 
	messageboard.py 
Log Message:
Finished Step 6: I18n and L10n of the Message Board.


=== Added File Products3/demo/messageboard/step6/__init__.py ===


=== Added File Products3/demo/messageboard/step6/configure.zcml ===
<zopeConfigure 
   xmlns="http://namespaces.zope.org/zope"
   xmlns:translate="http://namespaces.zope.org/gts">
  <!-- Security definitions -->

  <role
      id="zopeproducts.messageboard.User"
      title="Message Board User"
      description="Users that actually use the Message Board."/>

  <role
      id="zopeproducts.messageboard.Editor"
      title="Message Board Editor"
      description="The Editor can edit and delete Messages."/>

  <permission
      id="zopeproducts.messageboard.View"
      title="View Message Board and Messages"
      description="View the Message Board and all its content."/>

  <grant
      permission="zopeproducts.messageboard.View"
      role="zopeproducts.messageboard.User"/>

  <permission
      id="zopeproducts.messageboard.Add"
      title="Add Message"
      description="Add Message."/>

  <grant
      permission="zopeproducts.messageboard.Add"
      role="zopeproducts.messageboard.User"/>

  <permission
      id="zopeproducts.messageboard.Edit"
      title="Edit Messages"
      description="Edit Messages."/>

  <grant
      permission="zopeproducts.messageboard.Edit"
      role="zopeproducts.messageboard.Editor"/>

  <permission
      id="zopeproducts.messageboard.Delete"
      title="Delete Message"
      description="Delete Message."/>

  <grant
      permission="zopeproducts.messageboard.Delete"
      role="zopeproducts.messageboard.Editor"/>


  <!-- Content declarations -->

  <content class=".messageboard.MessageBoard">

    <implements
       interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />

    <implements
       interface="zope.app.interfaces.container.IContentContainer" />

    <factory
        id="MessageBoard"
        permission="zope.ManageContent"
        description="Message Board" />

    <require
        permission="zopeproducts.messageboard.View"
        interface=".interfaces.IMessageBoard"/>

    <require
        permission="zopeproducts.messageboard.Edit"
        set_schema=".interfaces.IMessageBoard"/>

  </content>

  <content class=".message.Message">

    <implements
       interface="zope.app.interfaces.annotation.IAttributeAnnotatable" />

    <implements
       interface="zope.app.interfaces.container.IContentContainer" />

    <factory
        id="Message"
        permission="zopeproducts.messageboard.Add"
        description="Message" />

    <require
        permission="zopeproducts.messageboard.View"
        interface=".interfaces.IMessage"/>

    <require
        permission="zopeproducts.messageboard.Edit"
        set_schema=".interfaces.IMessage"/>

  </content>

  <adapter
      factory=".message.MessageSized"
      provides="zope.app.interfaces.size.ISized"
      for=".interfaces.IMessage"
      />

  <include package=".browser" />

  <translate:registerTranslations directory="locales" />

</zopeConfigure>


=== Added File Products3/demo/messageboard/step6/fields.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Module containing custom field definitions.

$Id: fields.py,v 1.1 2003/07/10 20:33:53 srichter Exp $
"""
import re

from zope.schema.interfaces import ValidationError
from zope.schema import Text

from zope.i18n import MessageIDFactory
_ = MessageIDFactory('messageboard')

ForbiddenTags = _('Forbidden HTML Tags used.')
forbidden_regex = r'</?(?:%s).*?/?>'
allowed_regex = r'</??(?!%s)[a-zA-Z0-9]*? ?(?:[a-z0-9]*?=?".*?")*/??>'

class HTML(Text):
    
    allowed_tags = ()
    forbidden_tags = ()

    def __init__(self, allowed_tags=(), forbidden_tags=(), **kw):
        self.allowed_tags = allowed_tags
        self.forbidden_tags = forbidden_tags
        super(HTML, self).__init__(**kw)

    def _validate(self, value):
        super(HTML, self)._validate(value)

        if self.forbidden_tags:
            regex = forbidden_regex %'|'.join(self.forbidden_tags)
            if re.findall(regex, value):
                raise ValidationError(
                    ForbiddenTags, value, self.forbidden_tags)

        if self.allowed_tags:
            regex = allowed_regex %'|'.join(self.allowed_tags)
            if re.findall(regex, value):
                raise ValidationError(
                    ForbiddenTags, value, self.allowed_tags)



=== Added File Products3/demo/messageboard/step6/interfaces.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Message Board Interfaces

Interfaces for the Zope 3 based Message Board Product 

$Id: interfaces.py,v 1.1 2003/07/10 20:33:53 srichter Exp $
"""
from zope.app.interfaces.container import IContainer
from zope.schema.interfaces import IText

from zope.interface.implements import implements
from zope.schema import Text, TextLine, Container

from fields import HTML

from zope.i18n import MessageIDFactory
_ = MessageIDFactory('messageboard')


class IMessageBoard(IContainer):
    """The message board is the base object for our product. It can only
    contain IMessage objects."""

    description = Text(
        title=_("Description"),
        description=_("A detailed description of the content of the board."),
        default=u"",
        required=False)


class IMessage(IContainer):
    """A message object. It can contain its own responses."""

    title = TextLine(
        title=_("Title/Subject"),
        description=_("Title and/or subject of the message."),
        default=u"",
        required=True)

    body = HTML(
        title=_("Message Body"),
        description=_("This is the actual message. Type whatever!"),
        default=u"",
        allowed_tags=('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'img', 'a', 'br',
                      'b', 'i', 'u', 'em', 'sub', 'sup', 'table', 'tr', 'td',
                      'th', 'code', 'pre', 'center', 'div', 'span', 'p',
                      'font', 'ol', 'ul', 'li', 'q', 's', 'strong'),
        required=False)


class IHTML(IText):
    """A text field that is geared towards handeling HTML input."""

    allowed_tags = Container(
        title=_("Allowed HTML Tags"),
        description=_("""\
        Listed tags can be used in the value of the field.
        """),
        required=False)

    forbidden_tags = Container(
        title=_("Forbidden HTML Tags"),
        description=_("""\
        Listed tags cannot be used in the value of the field.
        """),
        required=False)

# To avoid recursive imports:
implements(HTML, IHTML)


=== Added File Products3/demo/messageboard/step6/message.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Message Implementation

An implementation of the Message using Folders as base.

$Id: message.py,v 1.1 2003/07/10 20:33:53 srichter Exp $
"""
from zope.app.interfaces.size import ISized

from zope.interface import implements
from zope.app.container.btree import BTreeContainer
from zopeproducts.messageboard.interfaces import IMessage

from zope.i18n import MessageIDFactory
_ = MessageIDFactory('messageboard')


class Message(BTreeContainer):
    __doc__ = IMessage.__doc__

    implements(IMessage)
    _title = u''
    _body = u''

    def getTitle(self):
        """Get the title of the board."""
        return self._title

    def setTitle(self, title):
        """Set the title of the board."""
        self._title = title

    # See zopeproducts.messageboard.interfaces.IMessage
    title = property(getTitle, setTitle)

    def getBody(self):
        """Get the body of the board."""
        return self._body

    def setBody(self, body):
        """Set the body of the board."""
        self._body = body
        
    # See zopeproducts.messageboard.interfaces.IMessage
    body = property(getBody, setBody)


class MessageSized:

    implements(ISized)

    def __init__(self, message):
        self._message = message

    def sizeForSorting(self):
        'See ISized'
        return ('item', len(self._message))

    def sizeForDisplay(self):
        'See ISized'
        messages = 0
        for obj in self._message.values():
            if IMessage.isImplementedBy(obj):
                messages += 1

        attach = len(self._message)-messages

        if messages == 1: size = '1 reply'
        else: size = '${messages} replies'

        if attach == 1: size += ', 1 attachment'
        else: size += ', ${attach} attachments'

        size = _(size)
        size.mapping = {'messages': `messages`, 'attach': `attach`}

        return size


=== Added File Products3/demo/messageboard/step6/messageboard.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Message Board Implementation

An implementation of the Message Board using Folders as base.

$Id: messageboard.py,v 1.1 2003/07/10 20:33:53 srichter Exp $
"""
from zope.interface import implements
from zope.app.container.btree import BTreeContainer
from zopeproducts.messageboard.interfaces import IMessageBoard

class MessageBoard(BTreeContainer):
    __doc__ = IMessageBoard.__doc__

    implements(IMessageBoard)

    _desc = u''

    def getDescription(self):
        """Get the description of the board."""
        return self._desc

    def setDescription(self, desc):
        """Set the description of the board."""
        self._desc = desc

    # See zopeproducts.messageboard.interfaces.IMessageBoard
    description = property(getDescription, setDescription)