# HG changeset patch # User Thierry Florac # Date 1467984972 -7200 # Node ID 5f6b98be4c04f93e72bede6ecd37cc36b7f6b9e7 # Parent 06c4fcde82bc5b96f0dd982bf3df450994aaa670 Added notifications for new review comments diff -r 06c4fcde82bc -r 5f6b98be4c04 src/pyams_content/shared/common/review.py --- a/src/pyams_content/shared/common/review.py Fri Jul 08 15:35:48 2016 +0200 +++ b/src/pyams_content/shared/common/review.py Fri Jul 08 15:36:12 2016 +0200 @@ -20,15 +20,15 @@ # import interfaces from pyams_content.interfaces.review import IReviewManager, IReviewComment, IReviewComments, \ - REVIEW_COMMENTS_ANNOTATION_KEY + REVIEW_COMMENTS_ANNOTATION_KEY, CommentAddedEvent, ICommentAddedEvent from pyams_content.shared.common.interfaces import IWfSharedContent, IWfSharedContentRoles +from pyams_i18n.interfaces import II18n from pyams_mail.interfaces import IPrincipalMailInfo -from pyams_security.interfaces import ISecurityManager +from pyams_security.interfaces import ISecurityManager, IProtectedObject from pyams_security.interfaces.notification import INotificationSettings from pyramid_chameleon.interfaces import IChameleonTranslate from pyramid_mailer.interfaces import IMailer from zope.annotation.interfaces import IAnnotations -from zope.lifecycleevent.interfaces import IObjectCreatedEvent from zope.location.interfaces import ISublocations from zope.traversing.interfaces import ITraversable @@ -39,8 +39,10 @@ from pyams_utils.adapter import adapter_config, ContextAdapter from pyams_utils.container import BTreeOrderedContainer from pyams_utils.registry import query_utility -from pyams_utils.request import check_request +from pyams_utils.request import check_request, query_request +from pyams_utils.url import absolute_url from pyramid.events import subscriber +from pyramid.threadlocal import get_current_registry from pyramid_chameleon.zpt import PageTemplateFile from zope.container.contained import Contained from zope.interface import implementer @@ -70,6 +72,8 @@ class ReviewCommentsContainer(BTreeOrderedContainer): """Review comments container""" + reviewers = FieldProperty(IReviewComments['reviewers']) + def clear(self): for k in self.keys()[:]: del self[k] @@ -77,6 +81,10 @@ def add_comment(self, comment): uuid = str(uuid4()) self[uuid] = comment + reviewers = self.reviewers or set() + reviewers.add(comment.owner) + self.reviewers = reviewers + get_current_registry().notify(CommentAddedEvent(self.__parent__, comment)) @adapter_config(context=IWfSharedContent, provides=IReviewComments) @@ -167,3 +175,53 @@ IReviewComments(self.context).add_comment(review_comment) # return notifications count return notifications + + +# +# Review comment notification +# + +try: + from pyams_notify.interfaces import INotification, INotificationHandler + from pyams_notify.event import Notification +except ImportError: + pass +else: + + @subscriber(ICommentAddedEvent) + def handle_new_comment(event): + """Handle new review comment""" + request = query_request() + if request is None: + return + content = event.object + translate = request.localizer.translate + notification = Notification(request=request, + context=content, + source=event.comment.owner, + action='notify', + category='content.review', + message=translate(_("A new comment was added on content « {0} »")).format( + II18n(content).query_attribute('title', request=request)), + url=absolute_url(content, request, 'admin.html#review-comments.html'), + comments=IReviewComments(content)) + notification.send() + + + @adapter_config(name='content.review', context=INotification, provides=INotificationHandler) + class ContentReviewNotificationHandler(ContextAdapter): + """Content review notification handler""" + + def get_target(self): + context = self.context.context + principals = set() + protection = IProtectedObject(context, None) + if protection is not None: + principals |= protection.get_principals('pyams.Reader') + comments = self.context.user_data.get('comments') + if comments is not None: + principals |= comments.reviewers + source_id = self.context.source['id'] + if source_id in principals: + principals.remove(source_id) + return {'principals': tuple(principals)}