[Testbot] Plone 5.0 - Python 2.7 - Build # 1607 - Fixed! - 0 failure(s)

jenkins at plone.org jenkins at plone.org
Mon Feb 17 18:59:30 UTC 2014


-------------------------------------------------------------------------------
Plone 5.0 - Python 2.7 - Build # 1607 - Fixed!
-------------------------------------------------------------------------------

http://jenkins.plone.org/job/plone-5.0-python-2.7/1607/


-------------------------------------------------------------------------------
CHANGES
-------------------------------------------------------------------------------

Repository: Products.CMFPlone
Branch: refs/heads/master
Date: 2014-02-17T10:14:10-08:00
Author: Elizabeth Leddy (eleddy) <eleddy at umich.edu>
Commit: https://github.com/plone/Products.CMFPlone/commit/8db491bd8f57459cc601875fbd8d09dbe22e496c

Revert "Merge pull request #179 from plone/remove_sendto_cleanedup"

This reverts commit ae4a51caee497b62fb2e9f8c8534158ae26be51b, reversing
changes made to 1453b0c517615a576465efbaaae69ae06c5028ae.

Files changed:
A Products/CMFPlone/skins/plone_form_scripts/sendto.cpy
A Products/CMFPlone/skins/plone_form_scripts/sendto.cpy.metadata
A Products/CMFPlone/skins/plone_form_scripts/validate_sendto.vpy
A Products/CMFPlone/skins/plone_forms/sendto_form.cpt
A Products/CMFPlone/skins/plone_forms/sendto_form.cpt.metadata
A Products/CMFPlone/skins/plone_templates/sendto_template.pt
M Products/CMFPlone/PloneTool.py
M Products/CMFPlone/browser/configure.zcml
M Products/CMFPlone/browser/interfaces.py
M Products/CMFPlone/profiles/default/rolemap.xml
D Products/CMFPlone/browser/sendto.py
D Products/CMFPlone/browser/templates/sendto_template.pt

diff --git a/Products/CMFPlone/PloneTool.py b/Products/CMFPlone/PloneTool.py
index cc769f2..e9071dc 100644
--- a/Products/CMFPlone/PloneTool.py
+++ b/Products/CMFPlone/PloneTool.py
@@ -49,6 +49,9 @@
     import LinkIntegrityNotificationException
 
 
+AllowSendto = 'Allow sendto'
+permissions.setDefaultRoles(AllowSendto, ('Anonymous', 'Manager', ))
+
 _marker = utils._marker
 _icons = {}
 
@@ -160,6 +163,27 @@ def getMailHost(self):
         """
         return getattr(aq_parent(self), 'MailHost')
 
+    security.declareProtected(AllowSendto, 'sendto')
+    def sendto(self, send_to_address, send_from_address, comment,
+               subject='Plone', **kwargs):
+        # Sends a link of a page to someone.
+        host = self.getMailHost()
+        template = getattr(self, 'sendto_template')
+        portal = getToolByName(self, 'portal_url').getPortalObject()
+        encoding = portal.getProperty('email_charset')
+        if 'envelope_from' in kwargs:
+            envelope_from = kwargs['envelope_from']
+        else:
+            envelope_from = send_from_address
+        # Cook from template
+        message = template(self, send_to_address=send_to_address,
+                           send_from_address=send_from_address,
+                           comment=comment, subject=subject, **kwargs)
+        message = message.encode(encoding)
+        host.send(message, mto=send_to_address,
+                  mfrom=envelope_from, subject=subject,
+                  charset='utf-8')
+
     security.declarePublic('validateSingleNormalizedEmailAddress')
     def validateSingleNormalizedEmailAddress(self, address):
         """Lower-level function to validate a single normalized email address,
diff --git a/Products/CMFPlone/browser/configure.zcml b/Products/CMFPlone/browser/configure.zcml
index bf36f23..259e02f 100644
--- a/Products/CMFPlone/browser/configure.zcml
+++ b/Products/CMFPlone/browser/configure.zcml
@@ -12,17 +12,6 @@
       <allow interface="plone.app.layout.navigation.interfaces.INavigationQueryBuilder" />
   </class>
 
-  <permission
-    id="Products.CMFPlone.AllowSendto"
-    title="Allow sendto" />
-
-  <browser:page
-      for="*"
-      name="sendto_form"
-      class=".sendto.SendToForm"
-      permission="Products.CMFPlone.AllowSendto"
-      />
-
   <browser:page
       for="*"
       name="breadcrumbs_view"
diff --git a/Products/CMFPlone/browser/interfaces.py b/Products/CMFPlone/browser/interfaces.py
index 7b3442f..b003206 100644
--- a/Products/CMFPlone/browser/interfaces.py
+++ b/Products/CMFPlone/browser/interfaces.py
@@ -1,11 +1,7 @@
-from zope import schema
 from zope.interface import Interface
 
 import zope.deferredimport
 
-from Products.CMFPlone import PloneMessageFactory as _
-
-
 # This is used as a persistent marker interface, we need to provide an upgrade
 # step to update the class reference before removing it.
 zope.deferredimport.deprecated(
@@ -312,31 +308,3 @@ def bodyClass(template, view):
         """ returns template or view name to mark body tag with
             template-${template_id} CSS class
         """
-
-
-class ISendToForm(Interface):
-    """ Interface for describing the 'sendto' form """
-
-    send_to_address = schema.TextLine(
-        title=_(u'label_send_to_mail',
-                default=u'Send to'),
-        description=_(u'help_send_to_mail',
-                      default=u'The e-mail address to send this link to.'),
-        required=True
-    )
-
-    send_from_address = schema.TextLine(
-        title=_(u'label_send_from',
-                default=u'From'),
-        description=_(u'help_send_from',
-                      default=u'Your email address.'),
-        required=True
-    )
-
-    comment = schema.Text(
-        title=_(u'label_comment',
-                default=u'Comment'),
-        description=_(u'help_comment_to_link',
-                      default=u'A comment about this link.'),
-        required=False
-    )
diff --git a/Products/CMFPlone/browser/sendto.py b/Products/CMFPlone/browser/sendto.py
deleted file mode 100644
index aa97cf3..0000000
--- a/Products/CMFPlone/browser/sendto.py
+++ /dev/null
@@ -1,119 +0,0 @@
-from Products.CMFPlone import PloneMessageFactory as _
-from Products.CMFPlone.utils import pretty_title_or_id
-from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
-from Products.MailHost.interfaces import IMailHost
-from Products.statusmessages.interfaces import IStatusMessage
-
-from ZODB.POSException import ConflictError
-
-from plone.z3cform import layout
-
-from zope.component import getMultiAdapter
-from zope.component import getUtility
-
-from z3c.form import form
-from z3c.form import field
-from z3c.form import button
-
-from interfaces import ISendToForm
-
-import logging
-
-logger = logging.getLogger("Plone")
-
-
-class SendToForm(form.Form):
-    label = _(u'heading_send_page_to',
-              default=u'Send this page to someone')
-
-    description = _(u'description_send_page_url_to',
-                    default=u'Fill in the email address of your '
-                    u'friend, and we will send an email '
-                    u'that contains a link to this page.')
-
-    fields = field.Fields(ISendToForm)
-    ignoreContext = True
-
-    mail_template = ViewPageTemplateFile('templates/sendto_template.pt')
-
-    # XXX: Add validation, but the plan is the fields should be
-    # changed to the Email field that is to be provided by
-    # plone schema
-
-    @button.buttonAndHandler(_(u'label_send', default='Send'),
-                             name='send')
-    def handle_send(self, action):
-        data, errors = self.extractData()
-        if errors:
-            IStatusMessage(self.request).addStatusMessage(
-                self.formErrorsMessage,
-                type=u'error'
-            )
-            return
-
-        portal_state = getMultiAdapter(
-            (self.context, self.request),
-            name=u'plone_portal_state'
-        )
-        site = portal_state.portal()
-
-        context_state = getMultiAdapter(
-            (self.context, self.request),
-            name=u'plone_context_state'
-        )
-        url = context_state.view_url()
-
-        send_from_address = data.get('send_from_address')
-        send_to_address = data.get('send_to_address')
-        subject = pretty_title_or_id(self, self.context)
-        title = pretty_title_or_id(self, self.context)
-        description = self.context.Description()
-        comment = data.get('comment', None)
-        envelope_from = site.getProperty('email_from_address', None)
-
-        try:
-            # Sends a link of a page to someone.
-            host = getUtility(IMailHost)
-            encoding = site.getProperty('email_charset')
-
-            if not envelope_from:
-                envelope_from = send_from_address
-
-            # Cook from template
-            message = self.mail_template(
-                self,
-                send_to_address=send_to_address,
-                send_from_address=send_from_address,
-                comment=comment,
-                subject=subject,
-                title=title,
-                description=description
-            )
-
-            message = message.encode(encoding)
-
-            host.send(
-                message,
-                mto=send_to_address,
-                mfrom=envelope_from,
-                subject=subject,
-                charset='utf-8'
-            )
-
-        except ConflictError:
-            raise
-        except Exception as e:
-            # TODO To many things could possibly go wrong. So we catch all.
-            logger.info("Unable to send mail: " + str(e))
-            IStatusMessage(self.request).addStatusMessage(
-                _(u'Unable to send mail.'),
-                type=u'error'
-            )
-            return
-
-        IStatusMessage(self.request).addStatusMessage(
-            _(u'Mail sent.'),
-            type=u'info'
-        )
-
-send_to_form = layout.wrap_form(SendToForm)
diff --git a/Products/CMFPlone/browser/templates/sendto_template.pt b/Products/CMFPlone/browser/templates/sendto_template.pt
deleted file mode 100644
index a83e4d2..0000000
--- a/Products/CMFPlone/browser/templates/sendto_template.pt
+++ /dev/null
@@ -1,30 +0,0 @@
-<div xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
-     xmlns:tal="http://xml.zope.org/namespaces/tal"
-     xmlns:metal="http://xml.zope.org/namespaces/metal"
-     xmlns:i18n="http://xml.zope.org/namespaces/i18n"
-     i18n:domain="plone"
-     tal:omit-tag=""
-     tal:define="utool nocall:context/portal_url;
-                 charset context/email_charset|string:utf-8;
-                 dummy python:request.RESPONSE.setHeader('Content-Type', 'text/html;;charset=%s' % charset)"
-><div i18n:translate="sendto_mailtemplate_body" tal:omit-tag="">
-This link is sent to you from <span i18n:name="portal_url" tal:omit-tag="" tal:replace="structure utool" />
-
-You are receiving this mail because someone read a page at
-<span i18n:name="portal_title" tal:omit-tag="" tal:replace="structure utool/Title" />
-and thought it might interest you.
-
-It is sent by <span i18n:name="from_address" tal:omit-tag="" tal:replace="structure options/send_from_address"
-/> with the following comment:
-"<span i18n:name="comment" tal:omit-tag="" tal:replace="structure options/comment | nothing" />"
-
-<span i18n:name="document_title" tal:omit-tag="" tal:replace="structure options/title | context/Title" />
-
-<span i18n:name="document_description" tal:omit-tag="" tal:replace="structure options/description | context/Description" />
-
-<span i18n:name="document_url" tal:omit-tag="" tal:replace="structure options/url | context/absolute_url" />
-</div>
---
-<span tal:replace="structure context/email_from_name" />
-
-</div>
diff --git a/Products/CMFPlone/profiles/default/rolemap.xml b/Products/CMFPlone/profiles/default/rolemap.xml
index de9a084..ecde4b9 100644
--- a/Products/CMFPlone/profiles/default/rolemap.xml
+++ b/Products/CMFPlone/profiles/default/rolemap.xml
@@ -38,6 +38,7 @@
       <role name="Contributor"/>
     </permission>
     <permission name="Allow sendto" acquire="True">
+      <role name="Anonymous"/>
       <role name="Manager"/>
       <role name="Site Administrator"/>
       <role name="Member"/>
diff --git a/Products/CMFPlone/skins/plone_form_scripts/sendto.cpy b/Products/CMFPlone/skins/plone_form_scripts/sendto.cpy
new file mode 100644
index 0000000..7b8ae19
--- /dev/null
+++ b/Products/CMFPlone/skins/plone_form_scripts/sendto.cpy
@@ -0,0 +1,58 @@
+## Controller Python Script "sendto"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind state=state
+##bind subpath=traverse_subpath
+##parameters=
+##title=Send an URL to a friend
+
+REQUEST = context.REQUEST
+
+from Products.CMFPlone.utils import transaction_note
+from Products.CMFPlone.PloneTool import AllowSendto
+from Products.CMFCore.utils import getToolByName
+from Products.CMFPlone import PloneMessageFactory as _
+from ZODB.POSException import ConflictError
+
+plone_utils = getToolByName(context, 'plone_utils')
+mtool = getToolByName(context, 'portal_membership')
+site = getToolByName(context, 'portal_url').getPortalObject()
+pretty_title_or_id = plone_utils.pretty_title_or_id
+
+if not mtool.checkPermission(AllowSendto, context):
+    plone_utils.addPortalMessage(_(u'You are not allowed to send this link.'),
+                                 'error')
+    return state.set(status='failure')
+
+# Find the view action.
+context_state = context.restrictedTraverse("@@plone_context_state")
+url = context_state.view_url()
+
+variables = {'send_from_address' : REQUEST.send_from_address,
+             'send_to_address'   : REQUEST.send_to_address,
+             'subject'           : pretty_title_or_id(context),
+             'url'               : url,
+             'title'             : pretty_title_or_id(context),
+             'description'       : context.Description(),
+             'comment'           : REQUEST.get('comment', None),
+             'envelope_from'     : site.getProperty('email_from_address'),
+             }
+
+try:
+    plone_utils.sendto(**variables)
+except ConflictError:
+    raise
+except:  # TODO To many things could possibly go wrong. So we catch all.
+    exception = plone_utils.exceptionString()
+    message = _(u'Unable to send mail: ${exception}',
+                mapping={u'exception': exception})
+    plone_utils.addPortalMessage(message, 'error')
+    return state.set(status='failure')
+
+tmsg = 'Sent page %s to %s' % (url, REQUEST.send_to_address)
+transaction_note(tmsg)
+
+plone_utils.addPortalMessage(_(u'Mail sent.'))
+return state
diff --git a/Products/CMFPlone/skins/plone_form_scripts/sendto.cpy.metadata b/Products/CMFPlone/skins/plone_form_scripts/sendto.cpy.metadata
new file mode 100644
index 0000000..80bb542
--- /dev/null
+++ b/Products/CMFPlone/skins/plone_form_scripts/sendto.cpy.metadata
@@ -0,0 +1,6 @@
+[validators]
+validators=validate_sendto
+
+[actions]
+action.success = redirect_to_action:string:view
+action.failure = redirect_to_action:string:view
diff --git a/Products/CMFPlone/skins/plone_form_scripts/validate_sendto.vpy b/Products/CMFPlone/skins/plone_form_scripts/validate_sendto.vpy
new file mode 100644
index 0000000..f2f1fa0
--- /dev/null
+++ b/Products/CMFPlone/skins/plone_form_scripts/validate_sendto.vpy
@@ -0,0 +1,39 @@
+## Controller Script Python "validate_sendto"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind state=state
+##bind subpath=traverse_subpath
+##parameters=send_to_address='',send_from_address=''
+##title=validates the email adresses
+
+from Products.CMFPlone import PloneMessageFactory as _
+plone_utils=context.plone_utils
+
+if not send_to_address:
+    state.setError('send_to_address',
+                   _(u'Please submit an email address.'),
+                   'email_required')
+
+if not plone_utils.validateEmailAddresses(send_to_address):
+    state.setError('send_to_address',
+                   _(u'Please submit a valid email address.'),
+                   'email_required')
+
+if not send_from_address:
+    state.setError('send_from_address',
+                   _(u'Please submit an email address.'),
+                   'email_required')
+
+if not plone_utils.validateSingleEmailAddress(send_from_address):
+    state.setError('send_from_address',
+                   _(u'Please submit a valid email address.'),
+                   'email_required')
+
+if state.getErrors():
+    context.plone_utils.addPortalMessage(
+        _(u'Please correct the indicated errors.'), 'error')
+    return state.set(status='failure')
+else:
+    return state
diff --git a/Products/CMFPlone/skins/plone_forms/sendto_form.cpt b/Products/CMFPlone/skins/plone_forms/sendto_form.cpt
new file mode 100644
index 0000000..f4140eb
--- /dev/null
+++ b/Products/CMFPlone/skins/plone_forms/sendto_form.cpt
@@ -0,0 +1,126 @@
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
+      xmlns:tal="http://xml.zope.org/namespaces/tal"
+      xmlns:metal="http://xml.zope.org/namespaces/metal"
+      xmlns:i18n="http://xml.zope.org/namespaces/i18n"
+      metal:use-macro="context/main_template/macros/master"
+      i18n:domain="plone">
+
+<metal:block fill-slot="top_slot"
+             tal:define="dummy python:request.set('disable_border',1)" />
+
+  <metal:head fill-slot="head_slot">
+    <meta name="robots" content="noindex,follow" />
+  </metal:head>
+
+  <body>
+
+    <metal:main fill-slot="main"
+         tal:define="errors options/state/getErrors;">
+
+      <h1 class="documentFirstHeading"
+          i18n:translate="heading_send_page_to">Send this page to someone</h1>
+
+      <div class="documentDescription"
+         i18n:translate="description_send_page_url_to">
+        Fill in the email address of your friend, and we will send an email
+        that contains a link to this page.
+      </div>
+
+      <div id="content-core">
+          <form name="sendto_form"
+                class="enableAutoFocus"
+                action="sendto_form"
+                method="post"
+                enctype="multipart/form-data"
+                tal:attributes="action string:${context/@@plone_context_state/object_url}/${template/getId}">
+
+            <fieldset>
+
+              <legend i18n:translate="legend_address_info">Address info</legend>
+
+              <div class="field"
+                   tal:define="error errors/send_to_address|nothing;"
+                   tal:attributes="class python:test(error, 'field error', 'field')">
+
+                <label for="send_to_address" i18n:translate="label_send_to_mail">Send to</label>
+
+                <span class="fieldRequired" title="Required"
+                      i18n:attributes="title title_required;"
+                      i18n:translate="label_required">(Required)</span>
+
+                      <div class="formHelp" i18n:translate="help_send_to_mail">
+                        The e-mail address to send this link to.
+                      </div>
+
+                      <div tal:content="error">Validation error output</div>
+
+                      <input type="text"
+                             id="send_to_address"
+                             name="send_to_address"
+                             size="25"
+                             tal:attributes="value request/send_to_address | nothing;"
+                             />
+              </div>
+
+              <div class="field"
+                   tal:define="error errors/send_from_address|nothing;"
+                   tal:attributes="class python:test(error, 'field error', 'field')">
+
+                <label for="send_from_address" i18n:translate="label_send_from">From</label>
+
+                <span class="fieldRequired" title="Required"
+                      i18n:attributes="title title_required;"
+                      i18n:translate="label_required">(Required)</span>
+
+                      <div class="formHelp" i18n:translate="help_send_from">
+                        Your email address.
+                      </div>
+
+                      <div tal:content="error">Validation error output</div>
+
+                      <input type="text"
+                             id="send_from_address"
+                             name="send_from_address"
+                             size="25"
+                             tal:define="member context/@@plone_portal_state/member;"
+                             tal:attributes="value python: request.get('send_from_address', member.getProperty('email',''));"
+                             />
+              </div>
+
+              <div class="field">
+                <label for="comment" i18n:translate="label_comment">Comment</label>
+
+                <div class="formHelp" i18n:translate="help_comment_to_link">
+                  A comment about this link.
+                </div>
+
+                <textarea cols="80"
+                          rows="5"
+                          id="comment"
+                          name="comment"
+                          tal:content="request/comment | nothing"
+                          >
+                  Comment
+                </textarea>
+              </div>
+
+              <div class="formControls">
+                <input class="context"
+                       type="submit"
+                       name="form.button.Send"
+                       value="Send"
+                       i18n:attributes="value label_send;"
+                       />
+              </div>
+
+              <input type="hidden" name="form.submitted" value="1" />
+
+            </fieldset>
+
+          </form>
+      </div>
+
+    </metal:main>
+
+  </body>
+</html>
diff --git a/Products/CMFPlone/skins/plone_forms/sendto_form.cpt.metadata b/Products/CMFPlone/skins/plone_forms/sendto_form.cpt.metadata
new file mode 100644
index 0000000..96d0516
--- /dev/null
+++ b/Products/CMFPlone/skins/plone_forms/sendto_form.cpt.metadata
@@ -0,0 +1,9 @@
+[default]
+title=Send this page to somebody
+
+[validators]
+validators=validate_sendto
+
+[actions]
+action.success=traverse_to:string:sendto
+action.failure=traverse_to:string:sendto_form
diff --git a/Products/CMFPlone/skins/plone_templates/sendto_template.pt b/Products/CMFPlone/skins/plone_templates/sendto_template.pt
new file mode 100644
index 0000000..a83e4d2
--- /dev/null
+++ b/Products/CMFPlone/skins/plone_templates/sendto_template.pt
@@ -0,0 +1,30 @@
+<div xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
+     xmlns:tal="http://xml.zope.org/namespaces/tal"
+     xmlns:metal="http://xml.zope.org/namespaces/metal"
+     xmlns:i18n="http://xml.zope.org/namespaces/i18n"
+     i18n:domain="plone"
+     tal:omit-tag=""
+     tal:define="utool nocall:context/portal_url;
+                 charset context/email_charset|string:utf-8;
+                 dummy python:request.RESPONSE.setHeader('Content-Type', 'text/html;;charset=%s' % charset)"
+><div i18n:translate="sendto_mailtemplate_body" tal:omit-tag="">
+This link is sent to you from <span i18n:name="portal_url" tal:omit-tag="" tal:replace="structure utool" />
+
+You are receiving this mail because someone read a page at
+<span i18n:name="portal_title" tal:omit-tag="" tal:replace="structure utool/Title" />
+and thought it might interest you.
+
+It is sent by <span i18n:name="from_address" tal:omit-tag="" tal:replace="structure options/send_from_address"
+/> with the following comment:
+"<span i18n:name="comment" tal:omit-tag="" tal:replace="structure options/comment | nothing" />"
+
+<span i18n:name="document_title" tal:omit-tag="" tal:replace="structure options/title | context/Title" />
+
+<span i18n:name="document_description" tal:omit-tag="" tal:replace="structure options/description | context/Description" />
+
+<span i18n:name="document_url" tal:omit-tag="" tal:replace="structure options/url | context/absolute_url" />
+</div>
+--
+<span tal:replace="structure context/email_from_name" />
+
+</div>




-------------------------------------------------------------------------------


More information about the Testbot mailing list