diff -r a64f48dd5fe4 -r 9ab2b4c74baf web/views/massmailing.py --- 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 . -"""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)