web/views/massmailing.py
changeset 5556 9ab2b4c74baf
parent 5424 8ecbcbff9777
child 5658 7b9553a9db65
--- a/web/views/massmailing.py	Thu May 20 20:47:13 2010 +0200
+++ b/web/views/massmailing.py	Thu May 20 20:47:55 2010 +0200
@@ -15,18 +15,17 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
-"""Mass mailing form views
+"""Mass mailing handling: send mail to entities adaptable to IEmailable"""
 
-"""
 __docformat__ = "restructuredtext en"
 _ = unicode
 
 import operator
 
-from cubicweb.interfaces import IEmailable
-from cubicweb.selectors import implements, authenticated_user
+from cubicweb.selectors import (implements, authenticated_user,
+                                adaptable, match_form_params)
 from cubicweb.view import EntityView
-from cubicweb.web import stdmsgs, action, form, formfields as ff
+from cubicweb.web import stdmsgs, controller, action, form, formfields as ff
 from cubicweb.web.formwidgets import CheckBox, TextInput, AjaxWidget, ImgButton
 from cubicweb.web.views import forms, formrenderers
 
@@ -34,8 +33,9 @@
 class SendEmailAction(action.Action):
     __regid__ = 'sendemail'
     # XXX should check email is set as well
-    __select__ = (action.Action.__select__ & implements(IEmailable)
-                  & authenticated_user())
+    __select__ = (action.Action.__select__
+                  & authenticated_user()
+                  & adaptable('IEmailable'))
 
     title = _('send email')
     category = 'mainactions'
@@ -49,9 +49,11 @@
 
 
 def recipient_vocabulary(form, field):
-    vocab = [(entity.get_email(), entity.eid) for entity in form.cw_rset.entities()]
+    vocab = [(entity.cw_adapt_to('IEmailable').get_email(), entity.eid)
+             for entity in form.cw_rset.entities()]
     return [(label, value) for label, value in vocab if label]
 
+
 class MassMailingForm(forms.FieldsForm):
     __regid__ = 'massmailing'
 
@@ -62,10 +64,13 @@
 
     sender = ff.StringField(widget=TextInput({'disabled': 'disabled'}),
                             label=_('From:'),
-                            value=lambda f: '%s <%s>' % (f._cw.user.dc_title(), f._cw.user.get_email()))
+                            value=lambda f: '%s <%s>' % (
+                                f._cw.user.dc_title(),
+                                f._cw.user.cw_adapt_to('IEmailable').get_email()))
     recipient = ff.StringField(widget=CheckBox(), label=_('Recipients:'),
                                choices=recipient_vocabulary,
-                               value= lambda f: [entity.eid for entity in f.cw_rset.entities() if entity.get_email()])
+                               value= lambda f: [entity.eid for entity in f.cw_rset.entities()
+                                                 if entity.cw_adapt_to('IEmailable').get_email()])
     subject = ff.StringField(label=_('Subject:'), max_length=256)
     mailbody = ff.StringField(widget=AjaxWidget(wdgtype='TemplateTextField',
                                                 inputid='mailbody'))
@@ -84,8 +89,8 @@
     def get_allowed_substitutions(self):
         attrs = []
         for coltype in self.cw_rset.column_types(0):
-            eclass = self._cw.vreg['etypes'].etype_class(coltype)
-            attrs.append(eclass.allowed_massmail_keys())
+            entity = self._cw.vreg['etypes'].etype_class(coltype)(self._cw)
+            attrs.append(entity.cw_adapt_to('IEmailable').allowed_massmail_keys())
         return sorted(reduce(operator.and_, attrs))
 
     def build_substitutions_help(self):
@@ -135,9 +140,36 @@
 
 class MassMailingFormView(form.FormViewMixIn, EntityView):
     __regid__ = 'massmailing'
-    __select__ = implements(IEmailable) & authenticated_user()
+    __select__ = authenticated_user() & adaptable('IEmailable')
 
     def call(self):
         form = self._cw.vreg['forms'].select('massmailing', self._cw,
                                              rset=self.cw_rset)
         self.w(form.render())
+
+
+class SendMailController(controller.Controller):
+    __regid__ = 'sendmail'
+    __select__ = authenticated_user() & match_form_params('recipient', 'mailbody', 'subject')
+
+    def recipients(self):
+        """returns an iterator on email's recipients as entities"""
+        eids = self._cw.form['recipient']
+        # eids may be a string if only one recipient was specified
+        if isinstance(eids, basestring):
+            rset = self._cw.execute('Any X WHERE X eid %(x)s', {'x': eids})
+        else:
+            rset = self._cw.execute('Any X WHERE X eid in (%s)' % (','.join(eids)))
+        return rset.entities()
+
+    def publish(self, rset=None):
+        # XXX this allows users with access to an cubicweb instance to use it as
+        # a mail relay
+        body = self._cw.form['mailbody']
+        subject = self._cw.form['subject']
+        for recipient in self.recipients():
+            iemailable = recipient.cw_adapt_to('IEmailable')
+            text = body % iemailable.as_email_context()
+            self.sendmail(iemailable.get_email(), subject, text)
+        url = self._cw.build_url(__message=self._cw._('emails successfully sent'))
+        raise Redirect(url)