Trigger custom comment events on comment add/remove/reply

Conflicts:
	plone/app/discussion/interfaces.py
This commit is contained in:
Alin Voinea 2014-04-16 18:54:19 +03:00
parent 5a9bfdf876
commit 4343197209
7 changed files with 450 additions and 1 deletions

View File

@ -10,6 +10,7 @@ from smtplib import SMTPException
from zope.annotation.interfaces import IAnnotatable from zope.annotation.interfaces import IAnnotatable
from zope.event import notify
from zope.component.factory import Factory from zope.component.factory import Factory
from zope.component import queryUtility from zope.component import queryUtility
@ -32,6 +33,11 @@ from OFS.Traversable import Traversable
from plone.registry.interfaces import IRegistry from plone.registry.interfaces import IRegistry
from plone.app.discussion.events import CommentAddedEvent
from plone.app.discussion.events import CommentRemovedEvent
from plone.app.discussion.events import ReplyAddedEvent
from plone.app.discussion.events import ReplyRemovedEvent
from plone.app.discussion import PloneAppDiscussionMessageFactory as _ from plone.app.discussion import PloneAppDiscussionMessageFactory as _
from plone.app.discussion.interfaces import IComment from plone.app.discussion.interfaces import IComment
from plone.app.discussion.interfaces import IConversation from plone.app.discussion.interfaces import IConversation
@ -232,7 +238,6 @@ def notify_content_object(obj, event):
'last_comment_date', 'last_comment_date',
'commentators')) 'commentators'))
def notify_content_object_deleted(obj, event): def notify_content_object_deleted(obj, event):
"""Remove all comments of a content object when the content object has been """Remove all comments of a content object when the content object has been
deleted. deleted.
@ -242,6 +247,19 @@ def notify_content_object_deleted(obj, event):
while conversation: while conversation:
del conversation[conversation.keys()[0]] del conversation[conversation.keys()[0]]
def notify_comment_added(obj, event):
""" Notify custom discussion events when a comment is added or replied
"""
if getattr(obj, 'in_reply_to', None):
return notify(ReplyAddedEvent(obj))
return notify(CommentAddedEvent(obj))
def notify_comment_removed(obj, event):
""" Notify custom discussion events when a comment or reply is removed
"""
if getattr(obj, 'in_reply_to', None):
return notify(ReplyRemovedEvent(obj))
return notify(CommentRemovedEvent(obj))
def notify_content_object_moved(obj, event): def notify_content_object_moved(obj, event):
"""Update all comments of a content object that has been moved. """Update all comments of a content object that has been moved.

View File

@ -14,6 +14,7 @@
<include package="plone.uuid" /> <include package="plone.uuid" />
<include package="plone.app.uuid" /> <include package="plone.app.uuid" />
<include file="contentrules.zcml" />
<include file="permissions.zcml" /> <include file="permissions.zcml" />
<include file="notifications.zcml" /> <include file="notifications.zcml" />
<include file="subscribers.zcml" /> <include file="subscribers.zcml" />

View File

@ -0,0 +1,42 @@
""" Content rules handlers
"""
from Acquisition import aq_parent
from plone.app.contentrules.handlers import execute
from plone.stringinterp import adapters
def execute_comment(event):
""" Execute comment content rules
"""
execute(event.object, event)
#
# String interp for comment's content rules
#
class Mixin(object):
""" Override context
"""
@property
def context(self):
""" Getter
"""
conversation = aq_parent(self._context)
return aq_parent(conversation)
@context.setter
def context(self, value):
""" Setter
"""
self._context = value
class CommentUrlSubstitution(adapters.UrlSubstitution, Mixin):
""" Override context to be used for URL substitution
"""
class CommentParentUrlSubstitution(adapters.ParentUrlSubstitution, Mixin):
""" Override context to be used for Parent URL substitution
"""
class CommentIdSubstitution(adapters.IdSubstitution, Mixin):
""" Override context to be used for Id substitution
"""

View File

@ -0,0 +1,313 @@
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:zcml="http://namespaces.zope.org/zcml">
<configure zcml:condition="installed plone.contentrules">
<!-- Content Rules events -->
<interface
interface="plone.app.discussion.interfaces.ICommentAddedEvent"
type="plone.contentrules.rule.interfaces.IRuleEventType"
name="Comment added"
/>
<interface
interface="plone.app.discussion.interfaces.ICommentRemovedEvent"
type="plone.contentrules.rule.interfaces.IRuleEventType"
name="Comment removed"
/>
<interface
interface="plone.app.discussion.interfaces.IReplyAddedEvent"
type="plone.contentrules.rule.interfaces.IRuleEventType"
name="Comment reply added"
/>
<interface
interface="plone.app.discussion.interfaces.IReplyRemovedEvent"
type="plone.contentrules.rule.interfaces.IRuleEventType"
name="Comment reply removed"
/>
</configure>
<configure zcml:condition="installed plone.app.contentrules">
<!-- Content rules subscribers -->
<subscriber
for="plone.app.discussion.interfaces.ICommentAddedEvent"
handler=".contentrules.execute_comment"
/>
<subscriber
for="plone.app.discussion.interfaces.ICommentRemovedEvent"
handler=".contentrules.execute_comment"
/>
<subscriber
for="plone.app.discussion.interfaces.IReplyAddedEvent"
handler=".contentrules.execute_comment"
/>
<subscriber
for="plone.app.discussion.interfaces.IReplyRemovedEvent"
handler=".contentrules.execute_comment"
/>
<!-- Content rules string substitutions -->
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentUrlSubstitution"
name="absolute_url"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentUrlSubstitution"
name="url"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentParentUrlSubstitution"
name="parent_url"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentIdSubstitution"
name="id"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentTitleSubstitution"
name="title"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentParentTitleSubstitution"
name="parent_title"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentDescriptionSubstitution"
name="description"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentTypeSubstitution"
name="type"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentReviewStateSubstitution"
name="review_state"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentReviewStateTitleSubstitution"
name="review_state_title"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentCreatedSubstitution"
name="created"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentEffectiveSubstitution"
name="effective"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentExpiresSubstitution"
name="expires"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentModifiedSubstitution"
name="modified"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentCreatorsSubstitution"
name="creators"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentContributorsSubstitution"
name="contributors"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentSubjectSubstitution"
name="subject"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentSubjectSubstitution"
name="keywords"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentFormatSubstitution"
name="format"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentLanguageSubstitution"
name="language"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentRightsSubstitution"
name="rights"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentIdentifierSubstitution"
name="identifier"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentOwnerEmailSubstitution"
name="owner_emails"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentReviewerEmailSubstitution"
name="reviewer_emails"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentReaderEmailSubstitution"
name="reader_emails"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentEditorEmailSubstitution"
name="editor_emails"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentContributorEmailSubstitution"
name="contributor_emails"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentManagerEmailSubstitution"
name="manager_emails"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentMemberEmailSubstitution"
name="member_emails"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentUserEmailSubstitution"
name="user_email"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentUserFullNameSubstitution"
name="user_fullname"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentUserIdSubstitution"
name="user_id"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentLastChangeCommentSubstitution"
name="change_comment"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentLastChangeTitleSubstitution"
name="change_title"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentLastChangeTypeSubstitution"
name="change_type"
/>
<adapter
for="plone.app.discussion.interfaces.IComment"
provides="plone.stringinterp.interfaces.IStringSubstitution"
factory=".contentrules.CommentLastChangeActorIdSubstitution"
name="change_authorid"
/>
</configure>
</configure>

View File

@ -0,0 +1,38 @@
""" Custom discussion events
"""
from zope.interface import implements
from plone.app.discussion.interfaces import IDiscussionEvent
from plone.app.discussion.interfaces import ICommentAddedEvent
from plone.app.discussion.interfaces import ICommentRemovedEvent
from plone.app.discussion.interfaces import IReplyAddedEvent
from plone.app.discussion.interfaces import IReplyRemovedEvent
class DiscussionEvent(object):
""" Custom event
"""
implements(IDiscussionEvent)
def __init__(self, context, **kwargs):
self.object = context
for key, value in kwargs.items():
setattr(self, key, value)
class CommentAddedEvent(DiscussionEvent):
""" Event to be triggered when a Comment is added
"""
implements(ICommentAddedEvent)
class CommentRemovedEvent(DiscussionEvent):
""" Event to be triggered when a Comment is removed
"""
implements(ICommentRemovedEvent)
class ReplyAddedEvent(DiscussionEvent):
""" Event to be triggered when a Comment reply is added
"""
implements(IReplyAddedEvent)
class ReplyRemovedEvent(DiscussionEvent):
""" Event to be triggered when a Comment reply is removed
"""
implements(IReplyRemovedEvent)

View File

@ -4,6 +4,7 @@
from zope.interface import Interface from zope.interface import Interface
from zope.interface.common.mapping import IIterableMapping from zope.interface.common.mapping import IIterableMapping
from zope.component.interfaces import IObjectEvent
from zope import schema from zope import schema
from plone.app.discussion import PloneAppDiscussionMessageFactory as _ from plone.app.discussion import PloneAppDiscussionMessageFactory as _
@ -345,3 +346,27 @@ class ICommentingTool(Interface):
This can be removed once we no longer support upgrading from versions This can be removed once we no longer support upgrading from versions
of Plone that had a portal_discussion tool. of Plone that had a portal_discussion tool.
""" """
#
# Custom events
#
class IDiscussionEvent(IObjectEvent):
""" Discussion custom event
"""
class ICommentAddedEvent(IDiscussionEvent):
""" Comment added
"""
class ICommentRemovedEvent(IDiscussionEvent):
""" Comment removed
"""
class IReplyAddedEvent(IDiscussionEvent):
""" Comment reply added
"""
class IReplyRemovedEvent(IDiscussionEvent):
""" Comment reply removed
"""

View File

@ -15,12 +15,24 @@
handler=".comment.notify_content_object" handler=".comment.notify_content_object"
/> />
<subscriber
for="plone.app.discussion.interfaces.IComment
zope.lifecycleevent.interfaces.IObjectAddedEvent"
handler=".comment.notify_comment_added"
/>
<subscriber <subscriber
for="plone.app.discussion.interfaces.IComment for="plone.app.discussion.interfaces.IComment
zope.lifecycleevent.interfaces.IObjectRemovedEvent" zope.lifecycleevent.interfaces.IObjectRemovedEvent"
handler=".comment.notify_content_object" handler=".comment.notify_content_object"
/> />
<subscriber
for="plone.app.discussion.interfaces.IComment
zope.lifecycleevent.interfaces.IObjectRemovedEvent"
handler=".comment.notify_comment_removed"
/>
<subscriber <subscriber
for="plone.app.discussion.interfaces.IComment for="plone.app.discussion.interfaces.IComment
zope.lifecycleevent.interfaces.IObjectAddedEvent" zope.lifecycleevent.interfaces.IObjectAddedEvent"