find -name "*.py" -exec pyupgrade --py3-only --py37-plus {} +
This commit is contained in:
parent
34b758f2bd
commit
75c6a5dcc1
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# plone.app.discussion documentation build configuration file, created by
|
||||
# sphinx-quickstart on Thu Mar 18 10:17:15 2010.
|
||||
@ -47,8 +46,8 @@ source_suffix = ".txt"
|
||||
master_doc = "index"
|
||||
|
||||
# General information about the project.
|
||||
project = u"plone.app.discussion"
|
||||
copyright = u"2010, Timo Stollenwerk - Plone Foundation"
|
||||
project = "plone.app.discussion"
|
||||
copyright = "2010, Timo Stollenwerk - Plone Foundation"
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
@ -185,8 +184,8 @@ latex_documents = [
|
||||
(
|
||||
"index",
|
||||
"ploneappdiscussion.tex",
|
||||
u"plone.app.discussion Documentation",
|
||||
u"Timo Stollenwerk",
|
||||
"plone.app.discussion Documentation",
|
||||
"Timo Stollenwerk",
|
||||
"manual",
|
||||
),
|
||||
]
|
||||
|
@ -1,2 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
__import__("pkg_resources").declare_namespace(__name__)
|
||||
|
@ -1,2 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
__import__("pkg_resources").declare_namespace(__name__)
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from zope.i18nmessageid import MessageFactory
|
||||
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Captcha validator, see captcha.txt for design notes.
|
||||
from persistent import Persistent
|
||||
from plone.app.discussion.browser.comments import CommentForm
|
||||
@ -23,7 +22,7 @@ from zope.publisher.interfaces.browser import IDefaultBrowserLayer
|
||||
class Captcha(Persistent):
|
||||
"""Captcha input field."""
|
||||
|
||||
captcha = u""
|
||||
captcha = ""
|
||||
|
||||
|
||||
Captcha = factory(Captcha)
|
||||
|
@ -1,4 +1,3 @@
|
||||
# coding: utf-8
|
||||
from .comments import CommentForm
|
||||
from AccessControl import getSecurityManager
|
||||
from Acquisition import aq_inner
|
||||
@ -48,9 +47,9 @@ class View(BrowserView):
|
||||
will redirect right to the binary object, bypassing comments.
|
||||
"""
|
||||
if obj.portal_type in view_action_types:
|
||||
url = "{0}/view".format(url)
|
||||
url = f"{url}/view"
|
||||
|
||||
self.request.response.redirect("{0}#{1}".format(url, context.id))
|
||||
self.request.response.redirect(f"{url}#{context.id}")
|
||||
|
||||
|
||||
class EditCommentForm(CommentForm):
|
||||
@ -58,10 +57,10 @@ class EditCommentForm(CommentForm):
|
||||
|
||||
ignoreContext = True
|
||||
id = "edit-comment-form"
|
||||
label = _(u"edit_comment_form_title", default=u"Edit comment")
|
||||
label = _("edit_comment_form_title", default="Edit comment")
|
||||
|
||||
def updateWidgets(self):
|
||||
super(EditCommentForm, self).updateWidgets()
|
||||
super().updateWidgets()
|
||||
self.widgets["text"].value = self.context.text
|
||||
# We have to rename the id, otherwise TinyMCE can't initialize
|
||||
# because there are two textareas with the same id.
|
||||
@ -70,12 +69,12 @@ class EditCommentForm(CommentForm):
|
||||
def _redirect(self, target=""):
|
||||
if not target:
|
||||
portal_state = getMultiAdapter(
|
||||
(self.context, self.request), name=u"plone_portal_state"
|
||||
(self.context, self.request), name="plone_portal_state"
|
||||
)
|
||||
target = portal_state.portal_url()
|
||||
self.request.response.redirect(target)
|
||||
|
||||
@button.buttonAndHandler(_(u"label_save", default=u"Save"), name="comment")
|
||||
@button.buttonAndHandler(_("label_save", default="Save"), name="comment")
|
||||
def handleComment(self, action):
|
||||
|
||||
# Validate form
|
||||
@ -96,14 +95,14 @@ class EditCommentForm(CommentForm):
|
||||
|
||||
# Redirect to comment
|
||||
IStatusMessage(self.request).add(
|
||||
_(u"comment_edit_notification", default="Comment was edited"), type="info"
|
||||
_("comment_edit_notification", default="Comment was edited"), type="info"
|
||||
)
|
||||
return self._redirect(target=self.action.replace("@@edit-comment", "@@view"))
|
||||
|
||||
@button.buttonAndHandler(_(u"cancel_form_button", default=u"Cancel"), name="cancel")
|
||||
@button.buttonAndHandler(_("cancel_form_button", default="Cancel"), name="cancel")
|
||||
def handle_cancel(self, action):
|
||||
IStatusMessage(self.request).add(
|
||||
_(u"comment_edit_cancel_notification", default=u"Edit comment cancelled"),
|
||||
_("comment_edit_cancel_notification", default="Edit comment cancelled"),
|
||||
type="info",
|
||||
)
|
||||
return self._redirect(target=self.context.absolute_url())
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from AccessControl import getSecurityManager
|
||||
from AccessControl import Unauthorized
|
||||
from Acquisition import aq_inner
|
||||
@ -35,28 +34,28 @@ from zope.interface import alsoProvides
|
||||
|
||||
|
||||
COMMENT_DESCRIPTION_PLAIN_TEXT = _(
|
||||
u"comment_description_plain_text",
|
||||
default=u"You can add a comment by filling out the form below. "
|
||||
u"Plain text formatting.",
|
||||
"comment_description_plain_text",
|
||||
default="You can add a comment by filling out the form below. "
|
||||
"Plain text formatting.",
|
||||
)
|
||||
|
||||
COMMENT_DESCRIPTION_MARKDOWN = _(
|
||||
u"comment_description_markdown",
|
||||
default=u"You can add a comment by filling out the form below. "
|
||||
u"Plain text formatting. You can use the Markdown syntax for "
|
||||
u"links and images.",
|
||||
"comment_description_markdown",
|
||||
default="You can add a comment by filling out the form below. "
|
||||
"Plain text formatting. You can use the Markdown syntax for "
|
||||
"links and images.",
|
||||
)
|
||||
|
||||
COMMENT_DESCRIPTION_INTELLIGENT_TEXT = _(
|
||||
u"comment_description_intelligent_text",
|
||||
default=u"You can add a comment by filling out the form below. "
|
||||
u"Plain text formatting. Web and email addresses are "
|
||||
u"transformed into clickable links.",
|
||||
"comment_description_intelligent_text",
|
||||
default="You can add a comment by filling out the form below. "
|
||||
"Plain text formatting. Web and email addresses are "
|
||||
"transformed into clickable links.",
|
||||
)
|
||||
|
||||
COMMENT_DESCRIPTION_MODERATION_ENABLED = _(
|
||||
u"comment_description_moderation_enabled",
|
||||
default=u"Comments are moderated.",
|
||||
"comment_description_moderation_enabled",
|
||||
default="Comments are moderated.",
|
||||
)
|
||||
|
||||
|
||||
@ -64,7 +63,7 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
|
||||
|
||||
ignoreContext = True # don't use context to get widget data
|
||||
id = None
|
||||
label = _(u"Add a comment")
|
||||
label = _("Add a comment")
|
||||
fields = field.Fields(IComment).omit(
|
||||
"portal_type",
|
||||
"__parent__",
|
||||
@ -79,16 +78,16 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
|
||||
)
|
||||
|
||||
def updateFields(self):
|
||||
super(CommentForm, self).updateFields()
|
||||
super().updateFields()
|
||||
self.fields["user_notification"].widgetFactory = SingleCheckBoxFieldWidget
|
||||
|
||||
def updateWidgets(self):
|
||||
super(CommentForm, self).updateWidgets()
|
||||
super().updateWidgets()
|
||||
|
||||
# Widgets
|
||||
self.widgets["in_reply_to"].mode = interfaces.HIDDEN_MODE
|
||||
self.widgets["text"].addClass("autoresize")
|
||||
self.widgets["user_notification"].label = _(u"")
|
||||
self.widgets["user_notification"].label = _("")
|
||||
# Reset widget field settings to their defaults, which may be changed
|
||||
# further on. Otherwise, the email field might get set to required
|
||||
# when an anonymous user visits, and then remain required when an
|
||||
@ -140,7 +139,7 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
|
||||
self.widgets["user_notification"].mode = interfaces.HIDDEN_MODE
|
||||
|
||||
def updateActions(self):
|
||||
super(CommentForm, self).updateActions()
|
||||
super().updateActions()
|
||||
self.actions["cancel"].addClass("btn btn-secondary")
|
||||
self.actions["cancel"].addClass("hide")
|
||||
self.actions["comment"].addClass("btn btn-primary")
|
||||
@ -148,7 +147,7 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
|
||||
def get_author(self, data):
|
||||
context = aq_inner(self.context)
|
||||
# some attributes are not always set
|
||||
author_name = u""
|
||||
author_name = ""
|
||||
|
||||
# Make sure author_name/ author_email is properly encoded
|
||||
if "author_name" in data:
|
||||
@ -219,16 +218,14 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
|
||||
|
||||
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.",
|
||||
"Anonymous user tries to post a comment, but anonymous "
|
||||
"commenting is disabled. Or user does not have the "
|
||||
"'reply to item' permission.",
|
||||
)
|
||||
|
||||
return comment
|
||||
|
||||
@button.buttonAndHandler(
|
||||
_(u"add_comment_button", default=u"Comment"), name="comment"
|
||||
)
|
||||
@button.buttonAndHandler(_("add_comment_button", default="Comment"), name="comment")
|
||||
def handleComment(self, action):
|
||||
context = aq_inner(self.context)
|
||||
|
||||
@ -254,7 +251,7 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
|
||||
anon = portal_membership.isAnonymousUser()
|
||||
if captcha_enabled and anonymous_comments and anon:
|
||||
if "captcha" not in data:
|
||||
data["captcha"] = u""
|
||||
data["captcha"] = ""
|
||||
captcha = CaptchaValidator(
|
||||
self.context, self.request, None, ICaptcha["captcha"], None
|
||||
)
|
||||
@ -296,7 +293,7 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
|
||||
# Redirect to comment (inside a content object page)
|
||||
self.request.response.redirect(self.action + "#" + str(comment_id))
|
||||
|
||||
@button.buttonAndHandler(_(u"Cancel"))
|
||||
@button.buttonAndHandler(_("Cancel"))
|
||||
def handleCancel(self, action):
|
||||
# This method should never be called, it's only there to show
|
||||
# a cancel button that is handled by a jQuery method.
|
||||
@ -309,7 +306,7 @@ class CommentsViewlet(ViewletBase):
|
||||
index = ViewPageTemplateFile("comments.pt")
|
||||
|
||||
def update(self):
|
||||
super(CommentsViewlet, self).update()
|
||||
super().update()
|
||||
discussion_allowed = self.is_discussion_allowed()
|
||||
anonymous_allowed_or_can_reply = (
|
||||
self.is_anonymous()
|
||||
@ -483,7 +480,7 @@ class CommentsViewlet(ViewletBase):
|
||||
if username is None:
|
||||
return None
|
||||
else:
|
||||
return "{0}/author/{1}".format(self.context.portal_url(), username)
|
||||
return f"{self.context.portal_url()}/author/{username}"
|
||||
|
||||
def get_commenter_portrait(self, username=None):
|
||||
|
||||
@ -523,7 +520,7 @@ class CommentsViewlet(ViewletBase):
|
||||
return portal_membership.isAnonymousUser()
|
||||
|
||||
def login_action(self):
|
||||
return "{0}/login_form?came_from={1}".format(
|
||||
return "{}/login_form?came_from={}".format(
|
||||
self.navigation_root_url,
|
||||
quote(self.request.get("URL", "")),
|
||||
)
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from plone.app.discussion.interfaces import _
|
||||
from plone.app.discussion.interfaces import IDiscussionSettings
|
||||
from plone.app.discussion.upgrades import update_registry
|
||||
@ -32,22 +31,22 @@ class DiscussionSettingsEditForm(controlpanel.RegistryEditForm):
|
||||
|
||||
schema = IDiscussionSettings
|
||||
id = "DiscussionSettingsEditForm"
|
||||
label = _(u"Discussion settings")
|
||||
label = _("Discussion settings")
|
||||
description = _(
|
||||
u"help_discussion_settings_editform",
|
||||
default=u"Some discussion related settings are not "
|
||||
u"located in the Discussion Control Panel.\n"
|
||||
u"To enable comments for a specific content type, "
|
||||
u"go to the Types Control Panel of this type and "
|
||||
u'choose "Allow comments".\n'
|
||||
u"To enable the moderation workflow for comments, "
|
||||
u"go to the Types Control Panel, choose "
|
||||
u'"Comment" and set workflow to '
|
||||
u'"Comment Review Workflow".',
|
||||
"help_discussion_settings_editform",
|
||||
default="Some discussion related settings are not "
|
||||
"located in the Discussion Control Panel.\n"
|
||||
"To enable comments for a specific content type, "
|
||||
"go to the Types Control Panel of this type and "
|
||||
'choose "Allow comments".\n'
|
||||
"To enable the moderation workflow for comments, "
|
||||
"go to the Types Control Panel, choose "
|
||||
'"Comment" and set workflow to '
|
||||
'"Comment Review Workflow".',
|
||||
)
|
||||
|
||||
def updateFields(self):
|
||||
super(DiscussionSettingsEditForm, self).updateFields()
|
||||
super().updateFields()
|
||||
self.fields["globally_enabled"].widgetFactory = SingleCheckBoxFieldWidget
|
||||
self.fields["moderation_enabled"].widgetFactory = SingleCheckBoxFieldWidget
|
||||
self.fields["edit_comment_enabled"].widgetFactory = SingleCheckBoxFieldWidget
|
||||
@ -65,20 +64,20 @@ class DiscussionSettingsEditForm(controlpanel.RegistryEditForm):
|
||||
|
||||
def updateWidgets(self):
|
||||
try:
|
||||
super(DiscussionSettingsEditForm, self).updateWidgets()
|
||||
super().updateWidgets()
|
||||
except KeyError:
|
||||
# upgrade profile not visible in prefs_install_products_form
|
||||
# provide auto-upgrade
|
||||
update_registry(self.context)
|
||||
super(DiscussionSettingsEditForm, self).updateWidgets()
|
||||
self.widgets["globally_enabled"].label = _(u"Enable Comments")
|
||||
self.widgets["anonymous_comments"].label = _(u"Anonymous Comments")
|
||||
self.widgets["show_commenter_image"].label = _(u"Commenter Image")
|
||||
super().updateWidgets()
|
||||
self.widgets["globally_enabled"].label = _("Enable Comments")
|
||||
self.widgets["anonymous_comments"].label = _("Anonymous Comments")
|
||||
self.widgets["show_commenter_image"].label = _("Commenter Image")
|
||||
self.widgets["moderator_notification_enabled"].label = _(
|
||||
u"Moderator Email Notification",
|
||||
"Moderator Email Notification",
|
||||
)
|
||||
self.widgets["user_notification_enabled"].label = _(
|
||||
u"User Email Notification",
|
||||
"User Email Notification",
|
||||
)
|
||||
|
||||
@button.buttonAndHandler(_("Save"), name=None)
|
||||
@ -88,14 +87,14 @@ class DiscussionSettingsEditForm(controlpanel.RegistryEditForm):
|
||||
self.status = self.formErrorsMessage
|
||||
return
|
||||
self.applyChanges(data)
|
||||
IStatusMessage(self.request).addStatusMessage(_(u"Changes saved"), "info")
|
||||
IStatusMessage(self.request).addStatusMessage(_("Changes saved"), "info")
|
||||
self.context.REQUEST.RESPONSE.redirect("@@discussion-controlpanel")
|
||||
|
||||
@button.buttonAndHandler(_("Cancel"), name="cancel")
|
||||
def handleCancel(self, action):
|
||||
IStatusMessage(self.request).addStatusMessage(_(u"Edit cancelled"), "info")
|
||||
IStatusMessage(self.request).addStatusMessage(_("Edit cancelled"), "info")
|
||||
self.request.response.redirect(
|
||||
"{0}/{1}".format(
|
||||
"{}/{}".format(
|
||||
self.context.absolute_url(),
|
||||
self.control_panel_view,
|
||||
),
|
||||
@ -111,7 +110,7 @@ class DiscussionSettingsControlPanel(controlpanel.ControlPanelFormWrapper):
|
||||
def __call__(self):
|
||||
self.mailhost_warning()
|
||||
self.custom_comment_workflow_warning()
|
||||
return super(DiscussionSettingsControlPanel, self).__call__()
|
||||
return super().__call__()
|
||||
|
||||
@property
|
||||
def site_url(self):
|
||||
@ -180,8 +179,8 @@ class DiscussionSettingsControlPanel(controlpanel.ControlPanelFormWrapper):
|
||||
pass
|
||||
else:
|
||||
message = _(
|
||||
u"discussion_text_no_mailhost_configured",
|
||||
default=u"You have not configured a mail host or a site 'From' address, various features including contact forms, email notification and password reset will not work. Go to the E-Mail Settings to fix this.",
|
||||
"discussion_text_no_mailhost_configured",
|
||||
default="You have not configured a mail host or a site 'From' address, various features including contact forms, email notification and password reset will not work. Go to the E-Mail Settings to fix this.",
|
||||
) # noqa: E501
|
||||
IStatusMessage(self.request).addStatusMessage(message, "warning")
|
||||
|
||||
@ -195,8 +194,8 @@ class DiscussionSettingsControlPanel(controlpanel.ControlPanelFormWrapper):
|
||||
pass
|
||||
else:
|
||||
message = _(
|
||||
u"discussion_text_custom_comment_workflow",
|
||||
default=u"You have configured a custom workflow for the 'Discussion Item' content type. You can enable/disable the comment moderation in this control panel only if you use one of the default 'Discussion Item' workflows. Go to the Types control panel to choose a workflow for the 'Discussion Item' type.",
|
||||
"discussion_text_custom_comment_workflow",
|
||||
default="You have configured a custom workflow for the 'Discussion Item' content type. You can enable/disable the comment moderation in this control panel only if you use one of the default 'Discussion Item' workflows. Go to the Types control panel to choose a workflow for the 'Discussion Item' type.",
|
||||
) # noqa: E501
|
||||
IStatusMessage(self.request).addStatusMessage(message, "warning")
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from Acquisition import aq_base
|
||||
from Acquisition import aq_chain
|
||||
from Acquisition import aq_inner
|
||||
@ -34,7 +33,7 @@ def traverse_parents(context):
|
||||
return None
|
||||
|
||||
|
||||
class ConversationView(object):
|
||||
class ConversationView:
|
||||
def enabled(self):
|
||||
if DEXTERITY_INSTALLED and IDexterityContent.providedBy(self.context):
|
||||
return self._enabled_for_dexterity_types()
|
||||
|
@ -1,4 +1,3 @@
|
||||
# coding: utf-8
|
||||
from AccessControl import getSecurityManager
|
||||
from AccessControl import Unauthorized
|
||||
from Acquisition import aq_inner
|
||||
@ -51,7 +50,7 @@ class View(BrowserView):
|
||||
pass
|
||||
|
||||
def __init__(self, context, request):
|
||||
super(View, self).__init__(context, request)
|
||||
super().__init__(context, request)
|
||||
self.workflowTool = getToolByName(self.context, "portal_workflow")
|
||||
self.transitions = []
|
||||
|
||||
@ -229,7 +228,7 @@ class DeleteOwnComment(DeleteComment):
|
||||
|
||||
def __call__(self):
|
||||
if self.can_delete():
|
||||
super(DeleteOwnComment, self).__call__()
|
||||
super().__call__()
|
||||
else:
|
||||
raise Unauthorized("You're not allowed to delete this comment.")
|
||||
|
||||
@ -318,7 +317,7 @@ class BulkActionsView(BrowserView):
|
||||
"""
|
||||
|
||||
def __init__(self, context, request):
|
||||
super(BulkActionsView, self).__init__(context, request)
|
||||
super().__init__(context, request)
|
||||
self.workflowTool = getToolByName(context, "portal_workflow")
|
||||
|
||||
def __call__(self):
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Implement the ++comments++ traversal namespace. This should return the
|
||||
IDiscussion container for the context, from which traversal will continue
|
||||
into an actual comment object.
|
||||
@ -15,7 +14,7 @@ from zope.traversing.interfaces import TraversalError
|
||||
|
||||
@implementer(ITraversable)
|
||||
@adapter(Interface, IBrowserRequest)
|
||||
class ConversationNamespace(object):
|
||||
class ConversationNamespace:
|
||||
"""Allow traversal into a conversation via a ++conversation++name
|
||||
namespace. The name is the name of an adapter from context to
|
||||
IConversation. The special name 'default' will be taken as the default
|
||||
@ -30,7 +29,7 @@ class ConversationNamespace(object):
|
||||
def traverse(self, name, ignore):
|
||||
|
||||
if name == "default":
|
||||
name = u""
|
||||
name = ""
|
||||
|
||||
conversation = queryAdapter(self.context, IConversation, name=name)
|
||||
if conversation is None:
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Captcha validator, see captcha.txt for design notes.
|
||||
"""
|
||||
from Acquisition import aq_inner
|
||||
@ -39,7 +38,7 @@ class CaptchaValidator(validator.SimpleFieldValidator):
|
||||
# We adapt the CaptchaValidator class to all form fields (IField)
|
||||
|
||||
def validate(self, value):
|
||||
super(CaptchaValidator, self).validate(value)
|
||||
super().validate(value)
|
||||
|
||||
registry = queryUtility(IRegistry)
|
||||
settings = registry.forInterface(IDiscussionSettings, check=False)
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Catalog indexers, using plone.indexer. These will populate standard catalog
|
||||
indexes with values based on the IComment interface.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""The default comment class and factory.
|
||||
"""
|
||||
from AccessControl import ClassSecurityInfo
|
||||
@ -44,28 +43,28 @@ import six
|
||||
|
||||
|
||||
COMMENT_TITLE = _(
|
||||
u"comment_title",
|
||||
default=u"${author_name} on ${content}",
|
||||
"comment_title",
|
||||
default="${author_name} on ${content}",
|
||||
)
|
||||
|
||||
MAIL_NOTIFICATION_MESSAGE = _(
|
||||
u"mail_notification_message",
|
||||
default=u'A comment on "${title}" '
|
||||
u"has been posted here: ${link}\n\n"
|
||||
u"---\n"
|
||||
u"${text}\n"
|
||||
u"---\n",
|
||||
"mail_notification_message",
|
||||
default='A comment on "${title}" '
|
||||
"has been posted here: ${link}\n\n"
|
||||
"---\n"
|
||||
"${text}\n"
|
||||
"---\n",
|
||||
)
|
||||
|
||||
MAIL_NOTIFICATION_MESSAGE_MODERATOR = _(
|
||||
u"mail_notification_message_moderator2",
|
||||
default=u'A comment on "${title}" '
|
||||
u"has been posted by ${commentator}\n"
|
||||
u"here: ${link}\n\n"
|
||||
u"---\n\n"
|
||||
u"${text}\n\n"
|
||||
u"---\n\n"
|
||||
u"Log in to moderate.\n\n",
|
||||
"mail_notification_message_moderator2",
|
||||
default='A comment on "${title}" '
|
||||
"has been posted by ${commentator}\n"
|
||||
"here: ${link}\n\n"
|
||||
"---\n\n"
|
||||
"${text}\n\n"
|
||||
"---\n\n"
|
||||
"Log in to moderate.\n\n",
|
||||
)
|
||||
|
||||
logger = logging.getLogger("plone.app.discussion")
|
||||
@ -100,10 +99,10 @@ class Comment(
|
||||
comment_id = None # long
|
||||
in_reply_to = None # long
|
||||
|
||||
title = u""
|
||||
title = ""
|
||||
|
||||
mime_type = None
|
||||
text = u""
|
||||
text = ""
|
||||
|
||||
creator = None
|
||||
creation_date = None
|
||||
@ -137,7 +136,7 @@ class Comment(
|
||||
|
||||
@property
|
||||
def __name__(self):
|
||||
return self.comment_id and six.text_type(self.comment_id) or None
|
||||
return self.comment_id and str(self.comment_id) or None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
@ -162,7 +161,7 @@ class Comment(
|
||||
text = self.text
|
||||
if text is None:
|
||||
return ""
|
||||
if six.PY2 and isinstance(text, six.text_type):
|
||||
if six.PY2 and isinstance(text, str):
|
||||
text = text.encode("utf8")
|
||||
transform = transforms.convertTo(
|
||||
targetMimetype, text, context=self, mimetype=sourceMimetype
|
||||
@ -172,8 +171,8 @@ class Comment(
|
||||
else:
|
||||
logger = logging.getLogger("plone.app.discussion")
|
||||
msg = (
|
||||
u'Transform "{0}" => "{1}" not available. Failed to '
|
||||
u'transform comment "{2}".'
|
||||
'Transform "{0}" => "{1}" not available. Failed to '
|
||||
'transform comment "{2}".'
|
||||
)
|
||||
logger.error(
|
||||
msg.format(
|
||||
@ -194,8 +193,8 @@ class Comment(
|
||||
author_name = translate(
|
||||
Message(
|
||||
_(
|
||||
u"label_anonymous",
|
||||
default=u"Anonymous",
|
||||
"label_anonymous",
|
||||
default="Anonymous",
|
||||
),
|
||||
),
|
||||
)
|
||||
@ -373,7 +372,7 @@ def notify_user(obj, event):
|
||||
if not emails:
|
||||
return
|
||||
|
||||
subject = translate(_(u"A comment has been posted."), context=obj.REQUEST)
|
||||
subject = translate(_("A comment has been posted."), context=obj.REQUEST)
|
||||
message = translate(
|
||||
Message(
|
||||
MAIL_NOTIFICATION_MESSAGE,
|
||||
@ -441,7 +440,7 @@ def notify_moderator(obj, event):
|
||||
content_object = aq_parent(conversation)
|
||||
|
||||
# Compose email
|
||||
subject = translate(_(u"A comment has been posted."), context=obj.REQUEST)
|
||||
subject = translate(_("A comment has been posted."), context=obj.REQUEST)
|
||||
message = translate(
|
||||
Message(
|
||||
MAIL_NOTIFICATION_MESSAGE_MODERATOR,
|
||||
@ -453,8 +452,8 @@ def notify_moderator(obj, event):
|
||||
or translate(
|
||||
Message(
|
||||
_(
|
||||
u"label_anonymous",
|
||||
default=u"Anonymous",
|
||||
"label_anonymous",
|
||||
default="Anonymous",
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
""" Content rules handlers
|
||||
"""
|
||||
from plone.app.discussion import _
|
||||
@ -8,7 +7,7 @@ try:
|
||||
from plone.stringinterp.adapters import BaseSubstitution
|
||||
except ImportError:
|
||||
|
||||
class BaseSubstitution(object):
|
||||
class BaseSubstitution:
|
||||
"""Fallback class if plone.stringinterp is not available"""
|
||||
|
||||
def __init__(self, context, **kwargs):
|
||||
@ -32,7 +31,7 @@ class CommentSubstitution(BaseSubstitution):
|
||||
"""Comment string substitution"""
|
||||
|
||||
def __init__(self, context, **kwargs):
|
||||
super(CommentSubstitution, self).__init__(context, **kwargs)
|
||||
super().__init__(context, **kwargs)
|
||||
|
||||
@property
|
||||
def event(self):
|
||||
@ -48,53 +47,53 @@ class CommentSubstitution(BaseSubstitution):
|
||||
class Id(CommentSubstitution):
|
||||
"""Comment id string substitution"""
|
||||
|
||||
category = _(u"Comments")
|
||||
description = _(u"Comment id")
|
||||
category = _("Comments")
|
||||
description = _("Comment id")
|
||||
|
||||
def safe_call(self):
|
||||
"""Safe call"""
|
||||
return getattr(self.comment, "comment_id", u"")
|
||||
return getattr(self.comment, "comment_id", "")
|
||||
|
||||
|
||||
class Text(CommentSubstitution):
|
||||
"""Comment text"""
|
||||
|
||||
category = _(u"Comments")
|
||||
description = _(u"Comment text")
|
||||
category = _("Comments")
|
||||
description = _("Comment text")
|
||||
|
||||
def safe_call(self):
|
||||
"""Safe call"""
|
||||
return getattr(self.comment, "text", u"")
|
||||
return getattr(self.comment, "text", "")
|
||||
|
||||
|
||||
class AuthorUserName(CommentSubstitution):
|
||||
"""Comment author user name string substitution"""
|
||||
|
||||
category = _(u"Comments")
|
||||
description = _(u"Comment author user name")
|
||||
category = _("Comments")
|
||||
description = _("Comment author user name")
|
||||
|
||||
def safe_call(self):
|
||||
"""Safe call"""
|
||||
return getattr(self.comment, "author_username", u"")
|
||||
return getattr(self.comment, "author_username", "")
|
||||
|
||||
|
||||
class AuthorFullName(CommentSubstitution):
|
||||
"""Comment author full name string substitution"""
|
||||
|
||||
category = _(u"Comments")
|
||||
description = _(u"Comment author full name")
|
||||
category = _("Comments")
|
||||
description = _("Comment author full name")
|
||||
|
||||
def safe_call(self):
|
||||
"""Safe call"""
|
||||
return getattr(self.comment, "author_name", u"")
|
||||
return getattr(self.comment, "author_name", "")
|
||||
|
||||
|
||||
class AuthorEmail(CommentSubstitution):
|
||||
"""Comment author email string substitution"""
|
||||
|
||||
category = _(u"Comments")
|
||||
description = _(u"Comment author email")
|
||||
category = _("Comments")
|
||||
description = _("Comment author email")
|
||||
|
||||
def safe_call(self):
|
||||
"""Safe call"""
|
||||
return getattr(self.comment, "author_email", u"")
|
||||
return getattr(self.comment, "author_email", "")
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""The conversation and replies adapters
|
||||
|
||||
The conversation is responsible for storing all comments. It provides a
|
||||
@ -130,8 +129,7 @@ class Conversation(Traversable, Persistent, Explicit):
|
||||
children = self._children.get(comment_id, None)
|
||||
if children is not None:
|
||||
for child_id in children:
|
||||
for value in recurse(child_id, d + 1):
|
||||
yield value
|
||||
yield from recurse(child_id, d + 1)
|
||||
|
||||
# Find top level threads
|
||||
comments = self._children.get(root, None)
|
||||
@ -145,8 +143,7 @@ class Conversation(Traversable, Persistent, Explicit):
|
||||
return
|
||||
|
||||
# Let the closure recurse
|
||||
for value in recurse(comment_id):
|
||||
yield value
|
||||
yield from recurse(comment_id)
|
||||
|
||||
def addComment(self, comment):
|
||||
"""Add a new comment. The parent id should have been set already. The
|
||||
@ -276,14 +273,14 @@ class Conversation(Traversable, Persistent, Explicit):
|
||||
return [v.__of__(self) for v in self._comments.values()]
|
||||
|
||||
def iterkeys(self):
|
||||
return six.iterkeys(self._comments)
|
||||
return self._comments.keys()
|
||||
|
||||
def itervalues(self):
|
||||
for v in six.itervalues(self._comments):
|
||||
for v in self._comments.values():
|
||||
yield v.__of__(self)
|
||||
|
||||
def iteritems(self):
|
||||
for k, v in six.iteritems(self._comments):
|
||||
for k, v in self._comments.items():
|
||||
yield (
|
||||
k,
|
||||
v.__of__(self),
|
||||
@ -332,7 +329,7 @@ else:
|
||||
|
||||
@implementer(IReplies)
|
||||
@adapter(Conversation) # relies on implementation details
|
||||
class ConversationReplies(object):
|
||||
class ConversationReplies:
|
||||
"""An IReplies adapter for conversations.
|
||||
|
||||
This makes it easy to work with top-level comments.
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
""" Custom discussion events
|
||||
"""
|
||||
from plone.app.discussion.interfaces import ICommentAddedEvent
|
||||
@ -15,7 +14,7 @@ from zope.interface import implementer
|
||||
|
||||
|
||||
@implementer(IDiscussionEvent)
|
||||
class DiscussionEvent(object):
|
||||
class DiscussionEvent:
|
||||
"""Custom event"""
|
||||
|
||||
def __init__(self, context, comment, **kwargs):
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Interfaces for plone.app.discussion
|
||||
"""
|
||||
from plone.app.discussion import _
|
||||
@ -42,24 +41,24 @@ class IConversation(IIterableMapping):
|
||||
"""
|
||||
|
||||
total_comments = schema.Int(
|
||||
title=_(u"Total number of public comments on this item"),
|
||||
title=_("Total number of public comments on this item"),
|
||||
min=0,
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
last_comment_date = schema.Date(
|
||||
title=_(u"Date of the most recent public comment"),
|
||||
title=_("Date of the most recent public comment"),
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
commentators = schema.Set(
|
||||
title=_(u"The set of unique commentators (usernames)"),
|
||||
title=_("The set of unique commentators (usernames)"),
|
||||
readonly=True,
|
||||
)
|
||||
|
||||
public_commentators = schema.Set(
|
||||
title=_(
|
||||
u"The set of unique commentators (usernames) " u"of published_comments",
|
||||
"The set of unique commentators (usernames) " "of published_comments",
|
||||
),
|
||||
readonly=True,
|
||||
)
|
||||
@ -138,58 +137,58 @@ class IComment(Interface):
|
||||
"""
|
||||
|
||||
portal_type = schema.ASCIILine(
|
||||
title=_(u"Portal type"),
|
||||
title=_("Portal type"),
|
||||
default="Discussion Item",
|
||||
)
|
||||
|
||||
__parent__ = schema.Object(title=_(u"Conversation"), schema=Interface)
|
||||
__parent__ = schema.Object(title=_("Conversation"), schema=Interface)
|
||||
|
||||
__name__ = schema.TextLine(title=_(u"Name"))
|
||||
__name__ = schema.TextLine(title=_("Name"))
|
||||
|
||||
comment_id = schema.Int(title=_(u"A comment id unique to this conversation"))
|
||||
comment_id = schema.Int(title=_("A comment id unique to this conversation"))
|
||||
|
||||
in_reply_to = schema.Int(
|
||||
title=_(u"Id of comment this comment is in reply to"),
|
||||
title=_("Id of comment this comment is in reply to"),
|
||||
required=False,
|
||||
)
|
||||
|
||||
# for logged in comments - set to None for anonymous
|
||||
author_username = schema.TextLine(title=_(u"Name"), required=False)
|
||||
author_username = schema.TextLine(title=_("Name"), required=False)
|
||||
|
||||
# for anonymous comments only, set to None for logged in comments
|
||||
author_name = schema.TextLine(title=_(u"Name"), required=False)
|
||||
author_name = schema.TextLine(title=_("Name"), required=False)
|
||||
author_email = schema.TextLine(
|
||||
title=_(u"Email"),
|
||||
title=_("Email"),
|
||||
required=False,
|
||||
constraint=isEmail,
|
||||
)
|
||||
|
||||
title = schema.TextLine(title=_(u"label_subject", default=u"Subject"))
|
||||
title = schema.TextLine(title=_("label_subject", default="Subject"))
|
||||
|
||||
mime_type = schema.ASCIILine(title=_(u"MIME type"), default="text/plain")
|
||||
mime_type = schema.ASCIILine(title=_("MIME type"), default="text/plain")
|
||||
text = schema.Text(
|
||||
title=_(
|
||||
u"label_comment",
|
||||
default=u"Comment",
|
||||
"label_comment",
|
||||
default="Comment",
|
||||
),
|
||||
)
|
||||
|
||||
user_notification = schema.Bool(
|
||||
title=_(
|
||||
u"Notify me of new comments via email.",
|
||||
"Notify me of new comments via email.",
|
||||
),
|
||||
required=False,
|
||||
)
|
||||
|
||||
creator = schema.TextLine(title=_(u"Username of the commenter"))
|
||||
creation_date = schema.Date(title=_(u"Creation date"))
|
||||
modification_date = schema.Date(title=_(u"Modification date"))
|
||||
creator = schema.TextLine(title=_("Username of the commenter"))
|
||||
creation_date = schema.Date(title=_("Creation date"))
|
||||
modification_date = schema.Date(title=_("Modification date"))
|
||||
|
||||
|
||||
class ICaptcha(Interface):
|
||||
"""Captcha/ReCaptcha text field to extend the existing comment form."""
|
||||
|
||||
captcha = schema.TextLine(title=_(u"Captcha"), required=False)
|
||||
captcha = schema.TextLine(title=_("Captcha"), required=False)
|
||||
|
||||
|
||||
class IDiscussionSettings(Interface):
|
||||
@ -204,26 +203,26 @@ class IDiscussionSettings(Interface):
|
||||
# - Search control panel: Show comments in search results
|
||||
|
||||
globally_enabled = schema.Bool(
|
||||
title=_(u"label_globally_enabled", default=u"Globally enable comments"),
|
||||
title=_("label_globally_enabled", default="Globally enable comments"),
|
||||
description=_(
|
||||
u"help_globally_enabled",
|
||||
default=u"If selected, users are able to post comments on the "
|
||||
u"site. However, you will still need to enable comments "
|
||||
u"for specific content types, folders or content "
|
||||
u"objects before users will be able to post comments.",
|
||||
"help_globally_enabled",
|
||||
default="If selected, users are able to post comments on the "
|
||||
"site. However, you will still need to enable comments "
|
||||
"for specific content types, folders or content "
|
||||
"objects before users will be able to post comments.",
|
||||
),
|
||||
required=False,
|
||||
default=False,
|
||||
)
|
||||
|
||||
anonymous_comments = schema.Bool(
|
||||
title=_(u"label_anonymous_comments", default="Enable anonymous comments"),
|
||||
title=_("label_anonymous_comments", default="Enable anonymous comments"),
|
||||
description=_(
|
||||
u"help_anonymous_comments",
|
||||
default=u"If selected, anonymous users are able to post "
|
||||
u"comments without logging in. It is highly "
|
||||
u"recommended to use a captcha solution to prevent "
|
||||
u"spam if this setting is enabled.",
|
||||
"help_anonymous_comments",
|
||||
default="If selected, anonymous users are able to post "
|
||||
"comments without logging in. It is highly "
|
||||
"recommended to use a captcha solution to prevent "
|
||||
"spam if this setting is enabled.",
|
||||
),
|
||||
required=False,
|
||||
default=False,
|
||||
@ -231,11 +230,11 @@ class IDiscussionSettings(Interface):
|
||||
|
||||
anonymous_email_enabled = schema.Bool(
|
||||
title=_(
|
||||
u"label_anonymous_email_enabled", default=u"Enable anonymous email field"
|
||||
"label_anonymous_email_enabled", default="Enable anonymous email field"
|
||||
),
|
||||
description=_(
|
||||
u"help_anonymous_email_enabled",
|
||||
default=u"If selected, anonymous user will have to " u"give their email.",
|
||||
"help_anonymous_email_enabled",
|
||||
default="If selected, anonymous user will have to " "give their email.",
|
||||
),
|
||||
required=False,
|
||||
default=False,
|
||||
@ -243,28 +242,28 @@ class IDiscussionSettings(Interface):
|
||||
|
||||
moderation_enabled = schema.Bool(
|
||||
title=_(
|
||||
u"label_moderation_enabled",
|
||||
"label_moderation_enabled",
|
||||
default="Enable comment moderation",
|
||||
),
|
||||
description=_(
|
||||
u"help_moderation_enabled",
|
||||
default=u'If selected, comments will enter a "Pending" state '
|
||||
u"in which they are invisible to the public. A user "
|
||||
u'with the "Review comments" permission ("Reviewer" '
|
||||
u'or "Manager") can approve comments to make them '
|
||||
u"visible to the public. If you want to enable a "
|
||||
u"custom comment workflow, you have to go to the "
|
||||
u"types control panel.",
|
||||
"help_moderation_enabled",
|
||||
default='If selected, comments will enter a "Pending" state '
|
||||
"in which they are invisible to the public. A user "
|
||||
'with the "Review comments" permission ("Reviewer" '
|
||||
'or "Manager") can approve comments to make them '
|
||||
"visible to the public. If you want to enable a "
|
||||
"custom comment workflow, you have to go to the "
|
||||
"types control panel.",
|
||||
),
|
||||
required=False,
|
||||
default=False,
|
||||
)
|
||||
|
||||
edit_comment_enabled = schema.Bool(
|
||||
title=_(u"label_edit_comment_enabled", default="Enable editing of comments"),
|
||||
title=_("label_edit_comment_enabled", default="Enable editing of comments"),
|
||||
description=_(
|
||||
u"help_edit_comment_enabled",
|
||||
default=u"If selected, supports editing "
|
||||
"help_edit_comment_enabled",
|
||||
default="If selected, supports editing "
|
||||
'of comments for users with the "Edit comments" '
|
||||
"permission.",
|
||||
),
|
||||
@ -274,11 +273,11 @@ class IDiscussionSettings(Interface):
|
||||
|
||||
delete_own_comment_enabled = schema.Bool(
|
||||
title=_(
|
||||
u"label_delete_own_comment_enabled", default="Enable deleting own comments"
|
||||
"label_delete_own_comment_enabled", default="Enable deleting own comments"
|
||||
),
|
||||
description=_(
|
||||
u"help_delete_own_comment_enabled",
|
||||
default=u"If selected, supports deleting "
|
||||
"help_delete_own_comment_enabled",
|
||||
default="If selected, supports deleting "
|
||||
"of own comments for users with the "
|
||||
'"Delete own comments" permission.',
|
||||
),
|
||||
@ -287,16 +286,16 @@ class IDiscussionSettings(Interface):
|
||||
)
|
||||
|
||||
text_transform = schema.Choice(
|
||||
title=_(u"label_text_transform", default="Comment text transform"),
|
||||
title=_("label_text_transform", default="Comment text transform"),
|
||||
description=_(
|
||||
u"help_text_transform",
|
||||
default=u"Use this setting to choose if the comment text "
|
||||
u"should be transformed in any way. You can choose "
|
||||
u'between "Plain text" and "Intelligent text". '
|
||||
u'"Intelligent text" converts plain text into HTML '
|
||||
u"where line breaks and indentation is preserved, "
|
||||
u"and web and email addresses are made into "
|
||||
u"clickable links.",
|
||||
"help_text_transform",
|
||||
default="Use this setting to choose if the comment text "
|
||||
"should be transformed in any way. You can choose "
|
||||
'between "Plain text" and "Intelligent text". '
|
||||
'"Intelligent text" converts plain text into HTML '
|
||||
"where line breaks and indentation is preserved, "
|
||||
"and web and email addresses are made into "
|
||||
"clickable links.",
|
||||
),
|
||||
required=True,
|
||||
default="text/plain",
|
||||
@ -304,15 +303,15 @@ class IDiscussionSettings(Interface):
|
||||
)
|
||||
|
||||
captcha = schema.Choice(
|
||||
title=_(u"label_captcha", default="Captcha"),
|
||||
title=_("label_captcha", default="Captcha"),
|
||||
description=_(
|
||||
u"help_captcha",
|
||||
default=u"Use this setting to enable or disable Captcha "
|
||||
u"validation for comments. Install "
|
||||
u"plone.formwidget.captcha, "
|
||||
u"plone.formwidget.recaptcha, collective.akismet, or "
|
||||
u"collective.z3cform.norobots if there are no options "
|
||||
u"available.",
|
||||
"help_captcha",
|
||||
default="Use this setting to enable or disable Captcha "
|
||||
"validation for comments. Install "
|
||||
"plone.formwidget.captcha, "
|
||||
"plone.formwidget.recaptcha, collective.akismet, or "
|
||||
"collective.z3cform.norobots if there are no options "
|
||||
"available.",
|
||||
),
|
||||
required=True,
|
||||
default="disabled",
|
||||
@ -320,11 +319,11 @@ class IDiscussionSettings(Interface):
|
||||
)
|
||||
|
||||
show_commenter_image = schema.Bool(
|
||||
title=_(u"label_show_commenter_image", default=u"Show commenter image"),
|
||||
title=_("label_show_commenter_image", default="Show commenter image"),
|
||||
description=_(
|
||||
u"help_show_commenter_image",
|
||||
default=u"If selected, an image of the user is shown next to "
|
||||
u"the comment.",
|
||||
"help_show_commenter_image",
|
||||
default="If selected, an image of the user is shown next to "
|
||||
"the comment.",
|
||||
),
|
||||
required=False,
|
||||
default=True,
|
||||
@ -332,14 +331,14 @@ class IDiscussionSettings(Interface):
|
||||
|
||||
moderator_notification_enabled = schema.Bool(
|
||||
title=_(
|
||||
u"label_moderator_notification_enabled",
|
||||
default=u"Enable moderator email notification",
|
||||
"label_moderator_notification_enabled",
|
||||
default="Enable moderator email notification",
|
||||
),
|
||||
description=_(
|
||||
u"help_moderator_notification_enabled",
|
||||
default=u"If selected, the moderator is notified if a comment "
|
||||
u"needs attention. The moderator email address can "
|
||||
u"be set below.",
|
||||
"help_moderator_notification_enabled",
|
||||
default="If selected, the moderator is notified if a comment "
|
||||
"needs attention. The moderator email address can "
|
||||
"be set below.",
|
||||
),
|
||||
required=False,
|
||||
default=False,
|
||||
@ -347,25 +346,25 @@ class IDiscussionSettings(Interface):
|
||||
|
||||
moderator_email = schema.ASCIILine(
|
||||
title=_(
|
||||
u"label_moderator_email",
|
||||
default=u"Moderator Email Address",
|
||||
"label_moderator_email",
|
||||
default="Moderator Email Address",
|
||||
),
|
||||
description=_(
|
||||
u"help_moderator_email",
|
||||
default=u"Address to which moderator notifications " u"will be sent.",
|
||||
"help_moderator_email",
|
||||
default="Address to which moderator notifications " "will be sent.",
|
||||
),
|
||||
required=False,
|
||||
)
|
||||
|
||||
user_notification_enabled = schema.Bool(
|
||||
title=_(
|
||||
u"label_user_notification_enabled",
|
||||
default=u"Enable user email notification",
|
||||
"label_user_notification_enabled",
|
||||
default="Enable user email notification",
|
||||
),
|
||||
description=_(
|
||||
u"help_user_notification_enabled",
|
||||
default=u"If selected, users can choose to be notified "
|
||||
u"of new comments by email.",
|
||||
"help_user_notification_enabled",
|
||||
default="If selected, users can choose to be notified "
|
||||
"of new comments by email.",
|
||||
),
|
||||
required=False,
|
||||
default=False,
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from Products.CMFCore.utils import getToolByName
|
||||
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from plone.app.contenttypes.testing import PLONE_APP_CONTENTTYPES_FIXTURE
|
||||
from plone.app.discussion.interfaces import IDiscussionSettings
|
||||
from plone.app.robotframework.testing import REMOTE_LIBRARY_ROBOT_TESTING
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Test the plone.app.discussion catalog indexes
|
||||
"""
|
||||
from datetime import datetime
|
||||
@ -98,7 +97,7 @@ class ConversationCatalogTest(unittest.TestCase):
|
||||
new_comment2_id = self.conversation.addComment(comment2)
|
||||
|
||||
comment2 = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_comment2_id),
|
||||
f"++conversation++default/{new_comment2_id}",
|
||||
)
|
||||
comment2.reindexObject()
|
||||
brains = self.catalog.searchResults(
|
||||
@ -128,7 +127,7 @@ class ConversationCatalogTest(unittest.TestCase):
|
||||
new_comment2_id = self.conversation.addComment(comment2)
|
||||
|
||||
comment2 = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_comment2_id),
|
||||
f"++conversation++default/{new_comment2_id}",
|
||||
)
|
||||
comment2.reindexObject()
|
||||
brains = self.catalog.searchResults(
|
||||
@ -188,7 +187,7 @@ class ConversationCatalogTest(unittest.TestCase):
|
||||
new_comment2_id = self.conversation.addComment(comment2)
|
||||
|
||||
comment2 = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_comment2_id),
|
||||
f"++conversation++default/{new_comment2_id}",
|
||||
)
|
||||
comment2.reindexObject()
|
||||
|
||||
@ -283,7 +282,7 @@ class CommentCatalogTest(unittest.TestCase):
|
||||
|
||||
# Comment brain
|
||||
self.comment = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_comment1_id),
|
||||
f"++conversation++default/{new_comment1_id}",
|
||||
)
|
||||
brains = self.catalog.searchResults(
|
||||
dict(
|
||||
@ -304,7 +303,7 @@ class CommentCatalogTest(unittest.TestCase):
|
||||
|
||||
# Comment brain
|
||||
comment = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(cid),
|
||||
f"++conversation++default/{cid}",
|
||||
)
|
||||
brains = self.catalog.searchResults(
|
||||
dict(
|
||||
@ -503,7 +502,7 @@ class CommentCatalogTest(unittest.TestCase):
|
||||
brains = self.catalog.searchResults({"portal_type": "Discussion Item"})
|
||||
self.assertTrue(brains)
|
||||
comment_brain = brains[0]
|
||||
self.assertEqual(comment_brain.Title, u"Jim on Document 1")
|
||||
self.assertEqual(comment_brain.Title, "Jim on Document 1")
|
||||
self.assertEqual(
|
||||
comment_brain.getPath(),
|
||||
"/plone/doc1/++conversation++default/" + str(self.comment_id),
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from plone.app.discussion.browser.comment import View
|
||||
from plone.app.discussion.interfaces import IComment
|
||||
from plone.app.discussion.interfaces import IConversation
|
||||
@ -64,7 +63,7 @@ class CommentTest(unittest.TestCase):
|
||||
comment1.comment_id = 123
|
||||
self.assertEqual("123", comment1.id)
|
||||
self.assertEqual("123", comment1.getId())
|
||||
self.assertEqual(u"123", comment1.__name__)
|
||||
self.assertEqual("123", comment1.__name__)
|
||||
|
||||
def test_uid(self):
|
||||
conversation = IConversation(self.portal.doc1)
|
||||
@ -111,14 +110,14 @@ class CommentTest(unittest.TestCase):
|
||||
def test_title_special_characters(self):
|
||||
self.portal.invokeFactory(
|
||||
id="doc_sp_chars",
|
||||
title=u"Document äüö",
|
||||
title="Document äüö",
|
||||
type_name="Document",
|
||||
)
|
||||
conversation = IConversation(self.portal.doc_sp_chars)
|
||||
comment1 = createObject("plone.Comment")
|
||||
comment1.author_name = u"Tarek Ziadé"
|
||||
comment1.author_name = "Tarek Ziadé"
|
||||
conversation.addComment(comment1)
|
||||
self.assertEqual(u"Tarek Ziadé on Document äüö", comment1.Title())
|
||||
self.assertEqual("Tarek Ziadé on Document äüö", comment1.Title())
|
||||
|
||||
def test_title_special_characters_utf8(self):
|
||||
self.portal.invokeFactory(
|
||||
@ -130,7 +129,7 @@ class CommentTest(unittest.TestCase):
|
||||
comment1 = createObject("plone.Comment")
|
||||
comment1.author_name = "Hüüb Bôûmä"
|
||||
conversation.addComment(comment1)
|
||||
self.assertEqual(u"Hüüb Bôûmä on Document ëïû", comment1.Title())
|
||||
self.assertEqual("Hüüb Bôûmä on Document ëïû", comment1.Title())
|
||||
|
||||
def test_creator(self):
|
||||
comment1 = createObject("plone.Comment")
|
||||
@ -174,11 +173,8 @@ class CommentTest(unittest.TestCase):
|
||||
|
||||
def test_getText_with_non_ascii_characters(self):
|
||||
comment1 = createObject("plone.Comment")
|
||||
comment1.text = u"Umlaute sind ä, ö und ü."
|
||||
comment1.text = "Umlaute sind ä, ö und ü."
|
||||
out = b"<p>Umlaute sind \xc3\xa4, \xc3\xb6 und \xc3\xbc.</p>"
|
||||
if six.PY2:
|
||||
self.assertEqual(comment1.getText(), out)
|
||||
else:
|
||||
self.assertEqual(comment1.getText(), out.decode("utf8"))
|
||||
|
||||
def test_getText_doesnt_link(self):
|
||||
@ -233,7 +229,7 @@ class CommentTest(unittest.TestCase):
|
||||
new_comment1_id = conversation.addComment(comment1)
|
||||
|
||||
comment = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_comment1_id),
|
||||
f"++conversation++default/{new_comment1_id}",
|
||||
)
|
||||
self.assertTrue(IComment.providedBy(comment))
|
||||
|
||||
@ -268,7 +264,7 @@ class CommentTest(unittest.TestCase):
|
||||
comment1.text = "Comment text"
|
||||
new_comment1_id = conversation.addComment(comment1)
|
||||
comment = self.portal.image1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_comment1_id),
|
||||
f"++conversation++default/{new_comment1_id}",
|
||||
)
|
||||
|
||||
view = View(comment, self.request)
|
||||
@ -336,7 +332,7 @@ class CommentTest(unittest.TestCase):
|
||||
new_comment1_id = conversation.addComment(comment1)
|
||||
|
||||
comment = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_comment1_id),
|
||||
f"++conversation++default/{new_comment1_id}",
|
||||
)
|
||||
|
||||
# make sure the view is there
|
||||
@ -381,7 +377,7 @@ class RepliesTest(unittest.TestCase):
|
||||
comment.text = "Comment text"
|
||||
new_id = replies.addComment(comment)
|
||||
comment = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id),
|
||||
f"++conversation++default/{new_id}",
|
||||
)
|
||||
|
||||
# Add a reply to the CommentReplies adapter of the first comment
|
||||
@ -418,7 +414,7 @@ class RepliesTest(unittest.TestCase):
|
||||
comment.text = "Comment text"
|
||||
new_id = replies.addComment(comment)
|
||||
comment = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id),
|
||||
f"++conversation++default/{new_id}",
|
||||
)
|
||||
|
||||
# Add a reply to the CommentReplies adapter of the first comment
|
||||
@ -454,7 +450,7 @@ class RepliesTest(unittest.TestCase):
|
||||
comment.text = "Comment text"
|
||||
new_id = conversation.addComment(comment)
|
||||
comment = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id),
|
||||
f"++conversation++default/{new_id}",
|
||||
)
|
||||
|
||||
# Add a reply to the CommentReplies adapter of the first comment
|
||||
@ -463,7 +459,7 @@ class RepliesTest(unittest.TestCase):
|
||||
replies = IReplies(comment)
|
||||
new_re_id = replies.addComment(re_comment)
|
||||
re_comment = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_re_id),
|
||||
f"++conversation++default/{new_re_id}",
|
||||
)
|
||||
|
||||
# Add a reply to the reply
|
||||
@ -472,7 +468,7 @@ class RepliesTest(unittest.TestCase):
|
||||
replies = IReplies(re_comment)
|
||||
new_re_re_id = replies.addComment(re_re_comment)
|
||||
re_re_comment = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_re_re_id),
|
||||
f"++conversation++default/{new_re_re_id}",
|
||||
)
|
||||
|
||||
# Add a reply to the replies reply
|
||||
@ -481,7 +477,7 @@ class RepliesTest(unittest.TestCase):
|
||||
replies = IReplies(re_re_comment)
|
||||
new_re_re_re_id = replies.addComment(re_re_re_comment)
|
||||
re_re_re_comment = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_re_re_re_id),
|
||||
f"++conversation++default/{new_re_re_re_id}",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from AccessControl import Unauthorized
|
||||
from datetime import datetime
|
||||
from OFS.Image import Image
|
||||
@ -81,7 +80,7 @@ class TestCommentForm(unittest.TestCase):
|
||||
adapts=(Interface, IBrowserRequest),
|
||||
provides=Interface,
|
||||
factory=CommentForm,
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
|
||||
# The form should return an error if the comment text field is empty
|
||||
@ -89,7 +88,7 @@ class TestCommentForm(unittest.TestCase):
|
||||
|
||||
commentForm = getMultiAdapter(
|
||||
(self.context, request),
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
commentForm.update()
|
||||
data, errors = commentForm.extractData() # pylint: disable-msg=W0612
|
||||
@ -99,11 +98,11 @@ class TestCommentForm(unittest.TestCase):
|
||||
|
||||
# The form is submitted successfully, if the required text field is
|
||||
# filled out
|
||||
request = make_request(form={"form.widgets.text": u"bar"})
|
||||
request = make_request(form={"form.widgets.text": "bar"})
|
||||
|
||||
commentForm = getMultiAdapter(
|
||||
(self.context, request),
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
commentForm.update()
|
||||
data, errors = commentForm.extractData() # pylint: disable-msg=W0612
|
||||
@ -116,7 +115,7 @@ class TestCommentForm(unittest.TestCase):
|
||||
self.assertEqual(len(comments), 1)
|
||||
|
||||
for comment in comments:
|
||||
self.assertEqual(comment.text, u"bar")
|
||||
self.assertEqual(comment.text, "bar")
|
||||
self.assertEqual(comment.creator, "test_user_1_")
|
||||
self.assertEqual(comment.getOwner().getUserName(), "test-user")
|
||||
local_roles = comment.get_local_roles()
|
||||
@ -144,23 +143,23 @@ class TestCommentForm(unittest.TestCase):
|
||||
adapts=(Interface, IBrowserRequest),
|
||||
provides=Interface,
|
||||
factory=CommentForm,
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
|
||||
provideAdapter(
|
||||
adapts=(Interface, IBrowserRequest),
|
||||
provides=Interface,
|
||||
factory=EditCommentForm,
|
||||
name=u"edit-comment-form",
|
||||
name="edit-comment-form",
|
||||
)
|
||||
|
||||
# The form is submitted successfully, if the required text field is
|
||||
# filled out
|
||||
request = make_request(form={"form.widgets.text": u"bar"})
|
||||
request = make_request(form={"form.widgets.text": "bar"})
|
||||
|
||||
commentForm = getMultiAdapter(
|
||||
(self.context, request),
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
commentForm.update()
|
||||
data, errors = commentForm.extractData() # pylint: disable-msg=W0612
|
||||
@ -171,10 +170,10 @@ class TestCommentForm(unittest.TestCase):
|
||||
# Edit the last comment
|
||||
conversation = IConversation(self.context)
|
||||
comment = [x for x in conversation.getComments()][-1]
|
||||
request = make_request(form={"form.widgets.text": u"foobar"})
|
||||
request = make_request(form={"form.widgets.text": "foobar"})
|
||||
editForm = getMultiAdapter(
|
||||
(comment, request),
|
||||
name=u"edit-comment-form",
|
||||
name="edit-comment-form",
|
||||
)
|
||||
editForm.update()
|
||||
data, errors = editForm.extractData() # pylint: disable-msg=W0612
|
||||
@ -182,14 +181,14 @@ class TestCommentForm(unittest.TestCase):
|
||||
self.assertEqual(len(errors), 0)
|
||||
self.assertFalse(editForm.handleComment(editForm, "foo"))
|
||||
comment = [x for x in conversation.getComments()][-1]
|
||||
self.assertEqual(comment.text, u"foobar")
|
||||
self.assertEqual(comment.text, "foobar")
|
||||
|
||||
comments = IConversation(commentForm.context).getComments()
|
||||
comments = [c for c in comments] # consume iterator
|
||||
self.assertEqual(len(comments), 1)
|
||||
|
||||
for comment in comments:
|
||||
self.assertEqual(comment.text, u"foobar")
|
||||
self.assertEqual(comment.text, "foobar")
|
||||
self.assertEqual(comment.creator, "test_user_1_")
|
||||
|
||||
self.assertEqual(comment.getOwner().getUserName(), "test-user")
|
||||
@ -218,16 +217,16 @@ class TestCommentForm(unittest.TestCase):
|
||||
adapts=(Interface, IBrowserRequest),
|
||||
provides=Interface,
|
||||
factory=CommentForm,
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
|
||||
# The form is submitted successfully, if the required text field is
|
||||
# filled out
|
||||
form_request = make_request(form={"form.widgets.text": u"bar"})
|
||||
form_request = make_request(form={"form.widgets.text": "bar"})
|
||||
|
||||
commentForm = getMultiAdapter(
|
||||
(self.context, form_request),
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
|
||||
commentForm.update()
|
||||
@ -240,7 +239,7 @@ class TestCommentForm(unittest.TestCase):
|
||||
comment = [x for x in conversation.getComments()][-1]
|
||||
deleteView = getMultiAdapter(
|
||||
(comment, self.request),
|
||||
name=u"moderate-delete-comment",
|
||||
name="moderate-delete-comment",
|
||||
)
|
||||
# try to delete last comment without 'Delete comments' permission
|
||||
setRoles(self.portal, TEST_USER_ID, ["Member"])
|
||||
@ -275,16 +274,16 @@ class TestCommentForm(unittest.TestCase):
|
||||
adapts=(Interface, IBrowserRequest),
|
||||
provides=Interface,
|
||||
factory=CommentForm,
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
|
||||
# The form is submitted successfully, if the required text field is
|
||||
# filled out
|
||||
form_request = make_request(form={"form.widgets.text": u"bar"})
|
||||
form_request = make_request(form={"form.widgets.text": "bar"})
|
||||
|
||||
commentForm = getMultiAdapter(
|
||||
(self.context, form_request),
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
|
||||
commentForm.update()
|
||||
@ -297,7 +296,7 @@ class TestCommentForm(unittest.TestCase):
|
||||
comment = [x for x in conversation.getComments()][-1]
|
||||
deleteView = getMultiAdapter(
|
||||
(comment, self.request),
|
||||
name=u"delete-own-comment",
|
||||
name="delete-own-comment",
|
||||
)
|
||||
# try to delete last comment with johndoe
|
||||
setRoles(self.portal, "johndoe", ["Member"])
|
||||
@ -337,20 +336,20 @@ class TestCommentForm(unittest.TestCase):
|
||||
adapts=(Interface, IBrowserRequest),
|
||||
provides=Interface,
|
||||
factory=CommentForm,
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
|
||||
# Post an anonymous comment and provide a name
|
||||
request = make_request(
|
||||
form={
|
||||
"form.widgets.name": u"john doe",
|
||||
"form.widgets.text": u"bar",
|
||||
"form.widgets.name": "john doe",
|
||||
"form.widgets.text": "bar",
|
||||
}
|
||||
)
|
||||
|
||||
commentForm = getMultiAdapter(
|
||||
(self.context, request),
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
commentForm.update()
|
||||
data, errors = commentForm.extractData() # pylint: disable-msg=W0612
|
||||
@ -363,7 +362,7 @@ class TestCommentForm(unittest.TestCase):
|
||||
self.assertEqual(len(comments), 1)
|
||||
|
||||
for comment in IConversation(commentForm.context).getComments():
|
||||
self.assertEqual(comment.text, u"bar")
|
||||
self.assertEqual(comment.text, "bar")
|
||||
self.assertIsNone(comment.creator)
|
||||
roles = comment.get_local_roles()
|
||||
self.assertEqual(len(roles), 0)
|
||||
@ -387,14 +386,14 @@ class TestCommentForm(unittest.TestCase):
|
||||
adapts=(Interface, IBrowserRequest),
|
||||
provides=Interface,
|
||||
factory=CommentForm,
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
|
||||
request = make_request(form={"form.widgets.text": u"bar"})
|
||||
request = make_request(form={"form.widgets.text": "bar"})
|
||||
|
||||
commentForm = getMultiAdapter(
|
||||
(self.context, request),
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
commentForm.update()
|
||||
data, errors = commentForm.extractData() # pylint: disable-msg=W0612
|
||||
@ -425,12 +424,12 @@ class TestCommentForm(unittest.TestCase):
|
||||
adapts=(Interface, IBrowserRequest),
|
||||
provides=Interface,
|
||||
factory=CommentForm,
|
||||
name=u"comment-form",
|
||||
name="comment-form",
|
||||
)
|
||||
|
||||
request = make_request(form={"form.widgets.text": u"bar"})
|
||||
request = make_request(form={"form.widgets.text": "bar"})
|
||||
|
||||
commentForm = getMultiAdapter((self.context, request), name=u"comment-form")
|
||||
commentForm = getMultiAdapter((self.context, request), name="comment-form")
|
||||
commentForm.update()
|
||||
data, errors = commentForm.extractData() # pylint: disable-msg=W0612
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from plone.app.discussion.interfaces import ICommentAddedEvent
|
||||
from plone.app.discussion.interfaces import ICommentRemovedEvent
|
||||
from plone.app.discussion.interfaces import IConversation
|
||||
@ -56,32 +55,32 @@ class CommentContentRulesTest(unittest.TestCase):
|
||||
self.assertTrue(IRuleEventType.providedBy(IReplyRemovedEvent))
|
||||
|
||||
def testCommentIdStringSubstitution(self):
|
||||
comment_id = getAdapter(self.document, IStringSubstitution, name=u"comment_id")
|
||||
comment_id = getAdapter(self.document, IStringSubstitution, name="comment_id")
|
||||
self.assertIsInstance(comment_id(), int)
|
||||
|
||||
def testCommentTextStringSubstitution(self):
|
||||
comment_text = getAdapter(
|
||||
self.document, IStringSubstitution, name=u"comment_text"
|
||||
self.document, IStringSubstitution, name="comment_text"
|
||||
)
|
||||
self.assertEqual(comment_text(), u"This is a comment")
|
||||
self.assertEqual(comment_text(), "This is a comment")
|
||||
|
||||
def testCommentUserIdStringSubstitution(self):
|
||||
comment_user_id = getAdapter(
|
||||
self.document, IStringSubstitution, name=u"comment_user_id"
|
||||
self.document, IStringSubstitution, name="comment_user_id"
|
||||
)
|
||||
self.assertEqual(comment_user_id(), u"jim")
|
||||
self.assertEqual(comment_user_id(), "jim")
|
||||
|
||||
def testCommentUserFullNameStringSubstitution(self):
|
||||
comment_user_fullname = getAdapter(
|
||||
self.document, IStringSubstitution, name=u"comment_user_fullname"
|
||||
self.document, IStringSubstitution, name="comment_user_fullname"
|
||||
)
|
||||
self.assertEqual(comment_user_fullname(), u"Jim")
|
||||
self.assertEqual(comment_user_fullname(), "Jim")
|
||||
|
||||
def testCommentUserEmailStringSubstitution(self):
|
||||
comment_user_email = getAdapter(
|
||||
self.document, IStringSubstitution, name=u"comment_user_email"
|
||||
self.document, IStringSubstitution, name="comment_user_email"
|
||||
)
|
||||
self.assertEqual(comment_user_email(), u"jim@example.com")
|
||||
self.assertEqual(comment_user_email(), "jim@example.com")
|
||||
|
||||
|
||||
class ReplyContentRulesTest(unittest.TestCase):
|
||||
@ -103,7 +102,7 @@ class ReplyContentRulesTest(unittest.TestCase):
|
||||
comment.text = "This is a comment"
|
||||
new_id = replies.addComment(comment)
|
||||
comment = self.document.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id),
|
||||
f"++conversation++default/{new_id}",
|
||||
)
|
||||
|
||||
re_comment = createObject("plone.Comment")
|
||||
@ -119,7 +118,7 @@ class ReplyContentRulesTest(unittest.TestCase):
|
||||
reply_id = getAdapter(
|
||||
self.document,
|
||||
IStringSubstitution,
|
||||
name=u"comment_id",
|
||||
name="comment_id",
|
||||
)
|
||||
self.assertIsInstance(reply_id(), int)
|
||||
|
||||
@ -127,30 +126,30 @@ class ReplyContentRulesTest(unittest.TestCase):
|
||||
reply_text = getAdapter(
|
||||
self.document,
|
||||
IStringSubstitution,
|
||||
name=u"comment_text",
|
||||
name="comment_text",
|
||||
)
|
||||
self.assertEqual(reply_text(), u"This is a reply")
|
||||
self.assertEqual(reply_text(), "This is a reply")
|
||||
|
||||
def testReplyUserIdStringSubstitution(self):
|
||||
reply_user_id = getAdapter(
|
||||
self.document,
|
||||
IStringSubstitution,
|
||||
name=u"comment_user_id",
|
||||
name="comment_user_id",
|
||||
)
|
||||
self.assertEqual(reply_user_id(), u"julia")
|
||||
self.assertEqual(reply_user_id(), "julia")
|
||||
|
||||
def testReplyUserFullNameStringSubstitution(self):
|
||||
reply_user_fullname = getAdapter(
|
||||
self.document,
|
||||
IStringSubstitution,
|
||||
name=u"comment_user_fullname",
|
||||
name="comment_user_fullname",
|
||||
)
|
||||
self.assertEqual(reply_user_fullname(), u"Juliana")
|
||||
self.assertEqual(reply_user_fullname(), "Juliana")
|
||||
|
||||
def testReplyUserEmailStringSubstitution(self):
|
||||
reply_user_email = getAdapter(
|
||||
self.document,
|
||||
IStringSubstitution,
|
||||
name=u"comment_user_email",
|
||||
name="comment_user_email",
|
||||
)
|
||||
self.assertEqual(reply_user_email(), u"julia@example.com")
|
||||
self.assertEqual(reply_user_email(), "julia@example.com")
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from plone.app.discussion.interfaces import IDiscussionSettings
|
||||
from plone.app.discussion.testing import ( # noqa
|
||||
PLONE_APP_DISCUSSION_INTEGRATION_TESTING,
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from Acquisition import aq_base
|
||||
from Acquisition import aq_parent
|
||||
from datetime import datetime
|
||||
@ -387,17 +386,17 @@ class ConversationTest(unittest.TestCase):
|
||||
self.assertTrue(comment2 in conversation.values())
|
||||
|
||||
# check if comment ids are in iterkeys
|
||||
self.assertTrue(new_id1 in six.iterkeys(conversation))
|
||||
self.assertTrue(new_id2 in six.iterkeys(conversation))
|
||||
self.assertFalse(123 in six.iterkeys(conversation))
|
||||
self.assertTrue(new_id1 in conversation.keys())
|
||||
self.assertTrue(new_id2 in conversation.keys())
|
||||
self.assertFalse(123 in conversation.keys())
|
||||
|
||||
# check if comment objects are in itervalues
|
||||
self.assertTrue(comment1 in six.itervalues(conversation))
|
||||
self.assertTrue(comment2 in six.itervalues(conversation))
|
||||
self.assertTrue(comment1 in conversation.values())
|
||||
self.assertTrue(comment2 in conversation.values())
|
||||
|
||||
# check if iteritems returns (key, comment object) pairs
|
||||
self.assertTrue((new_id1, comment1) in six.iteritems(conversation))
|
||||
self.assertTrue((new_id2, comment2) in six.iteritems(conversation))
|
||||
self.assertTrue((new_id1, comment1) in conversation.items())
|
||||
self.assertTrue((new_id2, comment2) in conversation.items())
|
||||
|
||||
# TODO test acquisition wrapping # noqa T000
|
||||
# self.assertTrue(aq_base(aq_parent(comment1)) is conversation)
|
||||
@ -852,18 +851,18 @@ class RepliesTest(unittest.TestCase):
|
||||
# Create the nested comment structure
|
||||
new_id_1 = replies.addComment(comment1)
|
||||
comment1 = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id_1),
|
||||
f"++conversation++default/{new_id_1}",
|
||||
)
|
||||
replies_to_comment1 = IReplies(comment1)
|
||||
new_id_2 = replies.addComment(comment2)
|
||||
comment2 = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id_2),
|
||||
f"++conversation++default/{new_id_2}",
|
||||
)
|
||||
replies_to_comment2 = IReplies(comment2)
|
||||
|
||||
new_id_1_1 = replies_to_comment1.addComment(comment1_1)
|
||||
comment1_1 = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id_1_1),
|
||||
f"++conversation++default/{new_id_1_1}",
|
||||
)
|
||||
replies_to_comment1_1 = IReplies(comment1_1)
|
||||
replies_to_comment1_1.addComment(comment1_1_1)
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from plone.app.discussion.interfaces import IConversation
|
||||
from plone.app.discussion.interfaces import IReplies
|
||||
from plone.app.discussion.testing import ( # noqa
|
||||
@ -20,7 +19,7 @@ import unittest
|
||||
#
|
||||
|
||||
|
||||
class EventsRegistry(object):
|
||||
class EventsRegistry:
|
||||
"""Fake registry to be used while testing discussion events"""
|
||||
|
||||
commentAdded = False
|
||||
@ -123,7 +122,7 @@ class CommentEventsTest(unittest.TestCase):
|
||||
conversation = IConversation(self.document)
|
||||
new_id = conversation.addComment(comment)
|
||||
comment = self.document.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id),
|
||||
f"++conversation++default/{new_id}",
|
||||
)
|
||||
comment.text = "foo"
|
||||
notify(ObjectModifiedEvent(comment))
|
||||
@ -191,7 +190,7 @@ class RepliesEventsTest(unittest.TestCase):
|
||||
comment.text = "Comment text"
|
||||
new_id = replies.addComment(comment)
|
||||
comment = self.document.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id),
|
||||
f"++conversation++default/{new_id}",
|
||||
)
|
||||
|
||||
re_comment = createObject("plone.Comment")
|
||||
@ -211,7 +210,7 @@ class RepliesEventsTest(unittest.TestCase):
|
||||
comment.text = "Comment text"
|
||||
comment_id = replies.addComment(comment)
|
||||
comment = self.document.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(comment_id),
|
||||
f"++conversation++default/{comment_id}",
|
||||
)
|
||||
re_comment = createObject("plone.Comment")
|
||||
re_comment.text = "Comment text"
|
||||
@ -232,7 +231,7 @@ class RepliesEventsTest(unittest.TestCase):
|
||||
comment.text = "Comment text"
|
||||
new_id = replies.addComment(comment)
|
||||
comment = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id),
|
||||
f"++conversation++default/{new_id}",
|
||||
)
|
||||
|
||||
re_comment = createObject("plone.Comment")
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Functional Doctests for plone.app.discussion.
|
||||
|
||||
These test are only triggered when Plone 4 (and plone.testing) is installed.
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Test for the plone.app.discussion indexers
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from plone.app.discussion.browser.moderation import BulkActionsView
|
||||
from plone.app.discussion.browser.moderation import CommentTransition
|
||||
from plone.app.discussion.browser.moderation import DeleteComment
|
||||
@ -42,7 +41,7 @@ class ModerationBulkActionsViewTest(unittest.TestCase):
|
||||
comment1.Creator = "Jim"
|
||||
new_id_1 = conversation.addComment(comment1)
|
||||
self.comment1 = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id_1),
|
||||
f"++conversation++default/{new_id_1}",
|
||||
)
|
||||
comment2 = createObject("plone.Comment")
|
||||
comment2.title = "Comment 2"
|
||||
@ -50,7 +49,7 @@ class ModerationBulkActionsViewTest(unittest.TestCase):
|
||||
comment2.Creator = "Joe"
|
||||
new_id_2 = conversation.addComment(comment2)
|
||||
self.comment2 = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id_2),
|
||||
f"++conversation++default/{new_id_2}",
|
||||
)
|
||||
comment3 = createObject("plone.Comment")
|
||||
comment3.title = "Comment 3"
|
||||
@ -58,7 +57,7 @@ class ModerationBulkActionsViewTest(unittest.TestCase):
|
||||
comment3.Creator = "Emma"
|
||||
new_id_3 = conversation.addComment(comment3)
|
||||
self.comment3 = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id_3),
|
||||
f"++conversation++default/{new_id_3}",
|
||||
)
|
||||
self.conversation = conversation
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from plone.app.discussion.browser.moderation import BulkActionsView
|
||||
from plone.app.discussion.browser.moderation import CommentTransition
|
||||
from plone.app.discussion.browser.moderation import DeleteComment
|
||||
@ -81,7 +80,7 @@ class ModerationBulkActionsViewTest(unittest.TestCase):
|
||||
comment1.Creator = "Jim"
|
||||
new_id_1 = conversation.addComment(comment1)
|
||||
self.comment1 = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id_1),
|
||||
f"++conversation++default/{new_id_1}",
|
||||
)
|
||||
comment2 = createObject("plone.Comment")
|
||||
comment2.title = "Comment 2"
|
||||
@ -89,7 +88,7 @@ class ModerationBulkActionsViewTest(unittest.TestCase):
|
||||
comment2.Creator = "Joe"
|
||||
new_id_2 = conversation.addComment(comment2)
|
||||
self.comment2 = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id_2),
|
||||
f"++conversation++default/{new_id_2}",
|
||||
)
|
||||
comment3 = createObject("plone.Comment")
|
||||
comment3.title = "Comment 3"
|
||||
@ -97,7 +96,7 @@ class ModerationBulkActionsViewTest(unittest.TestCase):
|
||||
comment3.Creator = "Emma"
|
||||
new_id_3 = conversation.addComment(comment3)
|
||||
self.comment3 = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(new_id_3),
|
||||
f"++conversation++default/{new_id_3}",
|
||||
)
|
||||
self.conversation = conversation
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from Acquisition import aq_base
|
||||
from plone.app.discussion.interfaces import IConversation
|
||||
from plone.app.discussion.testing import ( # noqa
|
||||
@ -80,7 +79,7 @@ class TestUserNotificationUnit(unittest.TestCase):
|
||||
# you may get lines separated by '\n' or '\r\n' in here.
|
||||
msg = msg.replace("\r\n", "\n")
|
||||
self.assertIn('A comment on "K=C3=B6lle Alaaf" has been posted here:', msg)
|
||||
self.assertIn("http://nohost/plone/d=\noc1/view#{0}".format(comment_id), msg)
|
||||
self.assertIn(f"http://nohost/plone/d=\noc1/view#{comment_id}", msg)
|
||||
self.assertIn("Comment text", msg)
|
||||
self.assertNotIn("Approve comment", msg)
|
||||
self.assertNotIn("Delete comment", msg)
|
||||
@ -215,7 +214,7 @@ class TestModeratorNotificationUnit(unittest.TestCase):
|
||||
# The output should be encoded in a reasonable manner
|
||||
# (in this case quoted-printable):
|
||||
self.assertTrue('A comment on "K=C3=B6lle Alaaf" has been posted' in msg)
|
||||
self.assertIn("http://nohost/plone/doc1/view#{0}".format(comment_id), msg)
|
||||
self.assertIn(f"http://nohost/plone/doc1/view#{comment_id}", msg)
|
||||
self.assertIn(comment.author_email, msg)
|
||||
self.assertIn(comment.text, msg)
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from plone.app.discussion.testing import PLONE_APP_DISCUSSION_ROBOT_TESTING
|
||||
from plone.app.testing import ROBOT_TEST_LEVEL
|
||||
from plone.testing import layered
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Test plone.app.discussion workflow and permissions.
|
||||
"""
|
||||
from AccessControl import Unauthorized
|
||||
@ -128,7 +127,7 @@ class CommentOneStateWorkflowTest(unittest.TestCase):
|
||||
cid = conversation.addComment(comment)
|
||||
|
||||
self.comment = self.folder.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(cid),
|
||||
f"++conversation++default/{cid}",
|
||||
)
|
||||
|
||||
self.portal.acl_users._doAddUser("member", "secret", ["Member"], [])
|
||||
@ -223,7 +222,7 @@ class CommentReviewWorkflowTest(unittest.TestCase):
|
||||
comment.text = "Comment text"
|
||||
comment_id = conversation.addComment(comment)
|
||||
comment = self.portal.doc1.restrictedTraverse(
|
||||
"++conversation++default/{0}".format(comment_id),
|
||||
f"++conversation++default/{comment_id}",
|
||||
)
|
||||
|
||||
self.conversation = conversation
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""The portal_discussion tool, usually accessed via
|
||||
queryUtility(ICommentingTool). The default implementation delegates to the
|
||||
standard portal_catalog for indexing comments.
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from plone.app.discussion.interfaces import IDiscussionSettings
|
||||
from plone.registry.interfaces import IRegistry
|
||||
from Products.CMFCore.utils import getToolByName
|
||||
@ -63,7 +62,7 @@ def upgrade_comment_workflows_apply_rolemapping(context):
|
||||
wf.updateRoleMappingsFor(comment)
|
||||
comment.reindexObjectSecurity()
|
||||
except (AttributeError, KeyError):
|
||||
logger.info("Could not reindex comment {0}".format(brain.getURL()))
|
||||
logger.info(f"Could not reindex comment {brain.getURL()}")
|
||||
|
||||
|
||||
def upgrade_comment_workflows(context):
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from plone.app.discussion.interfaces import _
|
||||
from zope.schema.vocabulary import SimpleTerm
|
||||
from zope.schema.vocabulary import SimpleVocabulary
|
||||
@ -40,7 +39,7 @@ except ImportError:
|
||||
def captcha_vocabulary(context):
|
||||
"""Vocabulary with all available captcha implementations."""
|
||||
terms = []
|
||||
terms.append(SimpleTerm(value="disabled", token="disabled", title=_(u"Disabled")))
|
||||
terms.append(SimpleTerm(value="disabled", token="disabled", title=_("Disabled")))
|
||||
|
||||
if HAS_CAPTCHA: # pragma: no cover
|
||||
terms.append(SimpleTerm(value="captcha", token="captcha", title="Captcha"))
|
||||
|
Loading…
Reference in New Issue
Block a user