From 814af8d837bf6de00d119f76020d0cc9fc030d1d Mon Sep 17 00:00:00 2001 From: Maurits van Rees Date: Fri, 10 Jun 2016 02:14:45 +0200 Subject: [PATCH 1/3] Various flake8 fixes. - Removed tabs. - Fixed E731 do not assign a lambda expression, use a def. - avoid hasattr --- CHANGES.rst | 1 + plone/app/discussion/browser/comments.pt | 8 ++++---- plone/app/discussion/browser/conversation.py | 3 ++- .../discussion/browser/javascripts/comments.js | 16 ++++++++-------- plone/app/discussion/contentrules.py | 3 ++- .../app/discussion/profiles/default/registry.xml | 8 ++++---- .../app/discussion/profiles/default/rolemap.xml | 2 +- 7 files changed, 22 insertions(+), 19 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 2608f3a..ec4efc4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -29,6 +29,7 @@ Bug fixes: user to fill in the form without validation error. Or when in the control panel the field is set as not required anymore, that change would have no effect until the instance was restarted. [maurits] +- Cleaned code from flake8 errors. [maurits] 2.4.14 (2016-06-06) diff --git a/plone/app/discussion/browser/comments.pt b/plone/app/discussion/browser/comments.pt index 300b7a6..bf6671b 100644 --- a/plone/app/discussion/browser/comments.pt +++ b/plone/app/discussion/browser/comments.pt @@ -37,8 +37,8 @@ author_home_url python:view.get_commenter_home_url(username=reply.author_username); has_author_link python:author_home_url and not isAnon; portrait_url python:view.get_commenter_portrait(reply.author_username); - review_state python:wtool.getInfoFor(reply, 'review_state', 'none'); - canEdit python:view.can_edit(reply); + review_state python:wtool.getInfoFor(reply, 'review_state', 'none'); + canEdit python:view.can_edit(reply); canDelete python:view.can_delete(reply)" tal:attributes="class python:'comment replyTreeLevel'+str(depth)+' state-'+str(review_state); id string:${reply/getId}" @@ -92,9 +92,9 @@ action="" method="post" class="commentactionsform" - tal:condition="python:not canDelete and isDeleteOwnCommentAllowed and view.could_delete_own(reply)" + tal:condition="python:not canDelete and isDeleteOwnCommentAllowed and view.could_delete_own(reply)" tal:attributes="action string:${reply/absolute_url}/@@delete-own-comment; - style python:view.can_delete_own(reply) and 'display: inline' or 'display: none'"> + style python:view.can_delete_own(reply) and 'display: inline' or 'display: none'"> *' - }); - } + if($.fn.prepOverlay){ + $('form[name="edit"]').prepOverlay({ + cssclass: 'overlay-edit-comment', + width: '60%', + subtype: 'ajax', + filter: '#content>*' + }); + } /********************************************************************** * Delete a comment and its answers. diff --git a/plone/app/discussion/contentrules.py b/plone/app/discussion/contentrules.py index 390178b..c8f602a 100644 --- a/plone/app/discussion/contentrules.py +++ b/plone/app/discussion/contentrules.py @@ -17,7 +17,8 @@ except ImportError: try: from plone.app.contentrules.handlers import execute except ImportError: - execute = lambda context, event: False + def execute(context, event): + return False def execute_comment(event): diff --git a/plone/app/discussion/profiles/default/registry.xml b/plone/app/discussion/profiles/default/registry.xml index bd6aa5b..1e0d535 100644 --- a/plone/app/discussion/profiles/default/registry.xml +++ b/plone/app/discussion/profiles/default/registry.xml @@ -1,7 +1,7 @@ - - False - False - + + False + False + diff --git a/plone/app/discussion/profiles/default/rolemap.xml b/plone/app/discussion/profiles/default/rolemap.xml index 0410b29..e63aae6 100644 --- a/plone/app/discussion/profiles/default/rolemap.xml +++ b/plone/app/discussion/profiles/default/rolemap.xml @@ -22,7 +22,7 @@ - + From d496dfdddcf586a01f5c5ce75d3f832d0e32ddc9 Mon Sep 17 00:00:00 2001 From: Maurits van Rees Date: Fri, 10 Jun 2016 02:45:33 +0200 Subject: [PATCH 2/3] Split too complex handleComment. --- plone/app/discussion/browser/comments.py | 156 +++++++++++++---------- 1 file changed, 89 insertions(+), 67 deletions(-) diff --git a/plone/app/discussion/browser/comments.py b/plone/app/discussion/browser/comments.py index 7d9695c..8961316 100644 --- a/plone/app/discussion/browser/comments.py +++ b/plone/app/discussion/browser/comments.py @@ -143,6 +143,94 @@ class CommentForm(extensible.ExtensibleForm, form.Form): self.actions['cancel'].addClass('hide') self.actions['comment'].addClass('context') + def get_author(self, data): + context = aq_inner(self.context) + # some attributes are not always set + author_name = u'' + + # Make sure author_name/ author_email is properly encoded + if 'author_name' in data: + author_name = data['author_name'] + if isinstance(author_name, str): + author_name = unicode(author_name, 'utf-8') + if 'author_email' in data: + author_email = data['author_email'] + if isinstance(author_email, str): + author_email = unicode(author_email, 'utf-8') + + # Set comment author properties for anonymous users or members + portal_membership = getToolByName(context, 'portal_membership') + anon = portal_membership.isAnonymousUser() + if not anon and getSecurityManager().checkPermission( + 'Reply to item', context): + # Member + member = portal_membership.getAuthenticatedMember() + # memberdata is stored as utf-8 encoded strings + email = member.getProperty('email') + fullname = member.getProperty('fullname') + if not fullname or fullname == '': + fullname = member.getUserName() + elif isinstance(fullname, str): + fullname = unicode(fullname, 'utf-8') + author_name = fullname + if email and isinstance(email, str): + email = unicode(email, 'utf-8') + # XXX: according to IComment interface author_email must not be + # set for logged in users, cite: + # 'for anonymous comments only, set to None for logged in comments' + author_email = email + # /XXX + + return author_name, author_email + + def create_comment(self, data): + context = aq_inner(self.context) + comment = createObject('plone.Comment') + + registry = queryUtility(IRegistry) + settings = registry.forInterface(IDiscussionSettings, check=False) + anonymous_comments = settings.anonymous_comments + + # Set comment mime type to current setting in the discussion registry + comment.mime_type = settings.text_transform + + # Set comment attributes (including extended comment form attributes) + for attribute in self.fields.keys(): + setattr(comment, attribute, data[attribute]) + + # Set dates + comment.creation_date = datetime.utcnow() + comment.modification_date = datetime.utcnow() + + # Get author name and email + comment.author_name, comment.author_email = self.get_author(data) + + # Set comment author properties for anonymous users or members + portal_membership = getToolByName(context, 'portal_membership') + anon = portal_membership.isAnonymousUser() + if anon and anonymous_comments: + # Anonymous Users + comment.user_notification = None + elif not anon and getSecurityManager().checkPermission( + 'Reply to item', context): + # Member + member = portal_membership.getAuthenticatedMember() + memberid = member.getId() + user = member.getUser() + comment.changeOwnership(user, recursive=False) + comment.manage_setLocalRoles(memberid, ['Owner']) + comment.creator = memberid + comment.author_username = memberid + + else: # pragma: no cover + raise Unauthorized( + u'Anonymous user tries to post a comment, but anonymous ' + u'commenting is disabled. Or user does not have the ' + u"'reply to item' permission." + ) + + return comment + @button.buttonAndHandler(_(u'add_comment_button', default=u'Comment'), name='comment') def handleComment(self, action): @@ -178,74 +266,8 @@ class CommentForm(extensible.ExtensibleForm, form.Form): None) captcha.validate(data['captcha']) - # some attributes are not always set - author_name = u'' - # Create comment - comment = createObject('plone.Comment') - - # Set comment mime type to current setting in the discussion registry - comment.mime_type = settings.text_transform - - # Set comment attributes (including extended comment form attributes) - for attribute in self.fields.keys(): - setattr(comment, attribute, data[attribute]) - # Make sure author_name/ author_email is properly encoded - if 'author_name' in data: - author_name = data['author_name'] - if isinstance(author_name, str): - author_name = unicode(author_name, 'utf-8') - if 'author_email' in data: - author_email = data['author_email'] - if isinstance(author_email, str): - author_email = unicode(author_email, 'utf-8') - - # Set comment author properties for anonymous users or members - can_reply = getSecurityManager().checkPermission('Reply to item', - context) - portal_membership = getToolByName(self.context, 'portal_membership') - if anon and anonymous_comments: - # Anonymous Users - comment.author_name = author_name - comment.author_email = author_email - comment.user_notification = None - comment.creation_date = datetime.utcnow() - comment.modification_date = datetime.utcnow() - elif not portal_membership.isAnonymousUser() and can_reply: - # Member - member = portal_membership.getAuthenticatedMember() - memberid = member.getId() - user = member.getUser() - email = member.getProperty('email') - fullname = member.getProperty('fullname') - if not fullname or fullname == '': - fullname = member.getUserName() - # memberdata is stored as utf-8 encoded strings - elif isinstance(fullname, str): - fullname = unicode(fullname, 'utf-8') - if email and isinstance(email, str): - email = unicode(email, 'utf-8') - comment.changeOwnership(user, recursive=False) - comment.manage_setLocalRoles(memberid, ['Owner']) - comment.creator = memberid - comment.author_username = memberid - comment.author_name = fullname - - # XXX: according to IComment interface author_email must not be - # set for logged in users, cite: - # 'for anonymous comments only, set to None for logged in comments' - comment.author_email = email - # /XXX - - comment.creation_date = datetime.utcnow() - comment.modification_date = datetime.utcnow() - - else: # pragma: no cover - raise Unauthorized( - u'Anonymous user tries to post a comment, but anonymous ' - u'commenting is disabled. Or user does not have the ' - u"'reply to item' permission." - ) + comment = self.create_comment(data) # Add comment to conversation conversation = IConversation(self.__parent__) From 1e9909ab6f0e51dd0a54806a8c3dc03743fb160f Mon Sep 17 00:00:00 2001 From: Maurits van Rees Date: Fri, 10 Jun 2016 03:40:07 +0200 Subject: [PATCH 3/3] Split too complex _enabled_for_archetypes. --- CHANGES.rst | 3 +- plone/app/discussion/browser/conversation.py | 37 ++++++++++---------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index ec4efc4..1a0e008 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -22,6 +22,8 @@ Bug fixes: Bug fixes: +- Cleaned code from flake8 errors. [maurits] + - Reset the required setting of the author_email widget each time. Otherwise, the email field might get set to required when an anonymous user visits, and then remain required when an @@ -29,7 +31,6 @@ Bug fixes: user to fill in the form without validation error. Or when in the control panel the field is set as not required anymore, that change would have no effect until the instance was restarted. [maurits] -- Cleaned code from flake8 errors. [maurits] 2.4.14 (2016-06-06) diff --git a/plone/app/discussion/browser/conversation.py b/plone/app/discussion/browser/conversation.py index b198e6f..0017da4 100644 --- a/plone/app/discussion/browser/conversation.py +++ b/plone/app/discussion/browser/conversation.py @@ -19,6 +19,20 @@ except ImportError: DEXTERITY_INSTALLED = False +def traverse_parents(context): + # Run through the aq_chain of obj and check if discussion is + # enabled in a parent folder. + for obj in aq_chain(context): + if not IPloneSiteRoot.providedBy(obj): + obj_is_folderish = IFolderish.providedBy(obj) + obj_is_stuctural = not INonStructuralFolder.providedBy(obj) + if (obj_is_folderish and obj_is_stuctural): + flag = getattr(obj, 'allow_discussion', None) + if flag is not None: + return flag + return None + + class ConversationView(object): def enabled(self): @@ -31,14 +45,14 @@ class ConversationView(object): """ Returns True if discussion is enabled for this conversation. This method checks five different settings in order to figure out if - discussion is enable on a specific content object: + discussion is enabled on a specific content object: 1) Check if discussion is enabled globally in the plone.app.discussion registry/control panel. 2) If the current content object is a folder, always return False, since we don't allow comments on a folder. This - setting is used to allow/ disallow comments for all content + setting is used to allow / disallow comments for all content objects inside a folder, not for the folder itself. 3) Check if the allow_discussion boolean flag on the content object is @@ -63,22 +77,9 @@ class ConversationView(object): # Always return False if object is a folder context_is_folderish = IFolderish.providedBy(context) - context_is_structural = not INonStructuralFolder.providedBy(context) - if (context_is_folderish and context_is_structural): - return False - - def traverse_parents(context): - # Run through the aq_chain of obj and check if discussion is - # enabled in a parent folder. - for obj in aq_chain(context): - if not IPloneSiteRoot.providedBy(obj): - obj_is_folderish = IFolderish.providedBy(obj) - obj_is_stuctural = not INonStructuralFolder.providedBy(obj) - if (obj_is_folderish and obj_is_stuctural): - flag = getattr(obj, 'allow_discussion', None) - if flag is not None: - return flag - return None + if context_is_folderish: + if not INonStructuralFolder.providedBy(context): + return False # If discussion is disabled for the object, bail out obj_flag = getattr(aq_base(context), 'allow_discussion', None)