# HG changeset patch # User RĂ©mi Cardona # Date 1364897586 -7200 # Node ID 7da8339cd7682cf08902b5a3af61562f480508b4 # Parent 08bb2dd18fd291ba1b9b5b1c2fd54ada0be30e5f [web/views] Move massmailing to its own cube (closes #2788086) diff -r 08bb2dd18fd2 -r 7da8339cd768 doc/3.17.rst --- a/doc/3.17.rst Tue Apr 02 18:15:24 2013 +0200 +++ b/doc/3.17.rst Tue Apr 02 12:13:06 2013 +0200 @@ -14,13 +14,16 @@ API changes ----------- +* drop typed_eid() in favour of int() (see `#2742462 `_) + * The SIOC views and adapters have been removed from CubicWeb and moved to the `sioc` cube. * The web page embedding views and adapters have been removed from CubicWeb and moved to the `embed` cube. -* drop typed_eid() in favour of int() (see `#2742462 `_) +* The email sending views and controllers have been removed from CubicWeb and + moved to the `massmailing` cube. diff -r 08bb2dd18fd2 -r 7da8339cd768 web/data/cubicweb.mailform.css --- a/web/data/cubicweb.mailform.css Tue Apr 02 18:15:24 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* styles for the email form (views/massmailing.py) - * - * :organization: Logilab - * :copyright: 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. - * :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr - */ - -form#sendmail { - border: 1px solid #DBDCE3; - background-color: #E9F5F7; - font-family:Verdana,Tahoma,Arial,sans-serif; - padding: 1em 1ex; -} - -table.headersform { - width: 100%; -} - -form#sendmail td#buttonbar { - padding: 0.5ex 0ex; -} - -table.headersform td.hlabel { - padding-top: 0.5ex; - color: #444444; - text-align: right; -} - -table.headersform td.hvalue { - padding-top: 0.5ex; - padding-left: 0.5em; - width: 100%; -} - -table.headersform td.hvalue input#mailsubj { - width: 47em; -} - -form#sendmail div#toolbar { - margin: 0.5em 0em; - height: 29px; -} - -form#sendmail div#toolbar ul { - list-style-image: none; - list-style-position: outside; - list-style-type:none; - margin:0px; - padding:0px; - /* border: 1px solid #DBDCE3; */ -} - -form#sendmail div#toolbar li { - background: none; - padding-left: 1em; - float: left; -} - -form#sendmail div#toolbar li a { - font-family: Verdana,Tahoma,Arial,sans-serif; - color: #444444; -} - -div#substitutions { - padding-left: 1em; -} diff -r 08bb2dd18fd2 -r 7da8339cd768 web/test/unittest_form.py --- a/web/test/unittest_form.py Tue Apr 02 18:15:24 2013 +0200 +++ b/web/test/unittest_form.py Tue Apr 02 12:13:06 2013 +0200 @@ -122,14 +122,6 @@ data = form.render(row=0, rtype='content', formid='base', action='edit_rtype') self.assertTrue('content_format' in data) - # form view tests ######################################################### - - def test_massmailing_formview(self): - self.execute('INSERT EmailAddress X: X address L + "@cubicweb.org", ' - 'U use_email X WHERE U is CWUser, U login L') - rset = self.execute('CWUser X') - self.view('massmailing', rset, template=None) - # form tests ############################################################## diff -r 08bb2dd18fd2 -r 7da8339cd768 web/test/unittest_views_actions.py --- a/web/test/unittest_views_actions.py Tue Apr 02 18:15:24 2013 +0200 +++ b/web/test/unittest_views_actions.py Tue Apr 02 12:13:06 2013 +0200 @@ -30,16 +30,6 @@ vaction = [action for action in actions if action.__regid__ == 'view'][0] self.assertEqual(vaction.url(), 'http://testing.fr/cubicweb/view?rql=CWUser%20X') - def test_sendmail_action(self): - req = self.request() - rset = self.execute('Any X WHERE X login "admin"', req=req) - actions = self.vreg['actions'].poss_visible_objects(req, rset=rset) - self.assertTrue([action for action in actions if action.__regid__ == 'sendemail']) - self.login('anon') - req = self.request() - rset = self.execute('Any X WHERE X login "anon"', req=req) - actions = self.vreg['actions'].poss_visible_objects(req, rset=rset) - self.assertFalse([action for action in actions if action.__regid__ == 'sendemail']) if __name__ == '__main__': unittest_main() diff -r 08bb2dd18fd2 -r 7da8339cd768 web/test/unittest_views_basecontrollers.py --- a/web/test/unittest_views_basecontrollers.py Tue Apr 02 18:15:24 2013 +0200 +++ b/web/test/unittest_views_basecontrollers.py Tue Apr 02 12:13:06 2013 +0200 @@ -544,21 +544,6 @@ self.vreg['controllers'].select('reportbug', self.request(description='hop')) -class SendMailControllerTC(CubicWebTC): - - def test_not_usable_by_guest(self): - self.assertRaises(NoSelectableObject, - self.vreg['controllers'].select, 'sendmail', self.request()) - self.vreg['controllers'].select('sendmail', - self.request(subject='toto', - recipient='toto@logilab.fr', - mailbody='hop')) - self.login('anon') - self.assertRaises(NoSelectableObject, - self.vreg['controllers'].select, 'sendmail', self.request()) - - - class AjaxControllerTC(CubicWebTC): tested_controller = 'ajax' diff -r 08bb2dd18fd2 -r 7da8339cd768 web/views/basecontrollers.py --- a/web/views/basecontrollers.py Tue Apr 02 18:15:24 2013 +0200 +++ b/web/views/basecontrollers.py Tue Apr 02 12:13:06 2013 +0200 @@ -271,7 +271,6 @@ return ajax_controller.publish(rset) -# XXX move to massmailing class MailBugReportController(Controller): __regid__ = 'reportbug' __select__ = match_form_params('description') diff -r 08bb2dd18fd2 -r 7da8339cd768 web/views/massmailing.py --- a/web/views/massmailing.py Tue Apr 02 18:15:24 2013 +0200 +++ b/web/views/massmailing.py Tue Apr 02 12:13:06 2013 +0200 @@ -1,4 +1,4 @@ -# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -17,161 +17,24 @@ # with CubicWeb. If not, see . """Mass mailing handling: send mail to entities adaptable to IEmailable""" -__docformat__ = "restructuredtext en" -_ = unicode - -import operator -from functools import reduce - -from cubicweb.predicates import (is_instance, authenticated_user, - adaptable, match_form_params) -from cubicweb.view import EntityView -from cubicweb.web import (Redirect, stdmsgs, controller, action, - form, formfields as ff) -from cubicweb.web.formwidgets import CheckBox, TextInput, AjaxWidget, ImgButton -from cubicweb.web.views import forms, formrenderers - - -class SendEmailAction(action.Action): - __regid__ = 'sendemail' - # XXX should check email is set as well - __select__ = (action.Action.__select__ - & authenticated_user() - & adaptable('IEmailable')) - - title = _('send email') - category = 'mainactions' - - def url(self): - params = {'vid': 'massmailing', '__force_display': 1} - if 'rql' in self._cw.form: - params['rql'] = self._cw.form['rql'] - return self._cw.build_url(self._cw.relative_path(includeparams=False), - **params) - - -def recipient_vocabulary(form, field): - vocab = [(entity.cw_adapt_to('IEmailable').get_email(), unicode(entity.eid)) - for entity in form.cw_rset.entities()] - return [(label, value) for label, value in vocab if label] +try: + from cubes.massmailing.views import (SendEmailAction, + recipient_vocabulary, + MassMailingForm, + MassMailingFormRenderer, + MassMailingFormView, + SendMailController) -class MassMailingForm(forms.FieldsForm): - __regid__ = 'massmailing' - - needs_js = ('cubicweb.edition.js', 'cubicweb.widgets.js',) - needs_css = ('cubicweb.mailform.css') - domid = 'sendmail' - action = 'sendmail' - - sender = ff.StringField(widget=TextInput({'disabled': 'disabled'}), - label=_('From:'), - value=lambda form, field: '%s <%s>' % ( - form._cw.user.dc_title(), - form._cw.user.cw_adapt_to('IEmailable').get_email())) - recipient = ff.StringField(widget=CheckBox(), label=_('Recipients:'), - choices=recipient_vocabulary, - value= lambda form, field: [entity.eid for entity in form.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')) - - form_buttons = [ImgButton('sendbutton', "javascript: $('#sendmail').submit()", - _('send email'), 'SEND_EMAIL_ICON'), - ImgButton('cancelbutton', "javascript: history.back()", - _(stdmsgs.BUTTON_CANCEL[0]), stdmsgs.BUTTON_CANCEL[1])] - form_renderer_id = __regid__ - - def __init__(self, *args, **kwargs): - super(MassMailingForm, self).__init__(*args, **kwargs) - field = self.field_by_name('mailbody') - field.widget.attrs['cubicweb:variables'] = ','.join(self.get_allowed_substitutions()) - - def get_allowed_substitutions(self): - attrs = [] - for coltype in self.cw_rset.column_types(0): - 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): - insertLink = u'%%(%s)s' - substs = (u'
%s
' % (insertLink % (subst, subst)) - for subst in self.get_allowed_substitutions()) - helpmsg = self._cw._('You can use any of the following substitutions in your text') - return u'
%s%s
' % ( - helpmsg, u'\n'.join(substs)) - - -class MassMailingFormRenderer(formrenderers.FormRenderer): - __regid__ = 'massmailing' + from logilab.common.deprecation import class_moved, moved - def _render_fields(self, fields, w, form): - w(u'') - for field in fields: - if field.name == 'mailbody': - w(u'
') - self._render_toolbar(w, form) - w(u'') - w(u'') - w(u'' % self.render_label(form, field)) - w(u'') - w(u'' % form.build_substitutions_help()) - w(u'') - else: - w(u'') - w(u'
') - else: - w(u'
%s') - w(field.render(form, self)) - if field.name == 'mailbody': - w(u'%s
') - - def _render_toolbar(self, w, form): - w(u'
') - w(u'
    ') - for button in form.form_buttons: - w(u'
  • %s
  • ' % button.render(form)) - w(u'
') - w(u'
') - - def render_buttons(self, w, form): - pass - - -class MassMailingFormView(form.FormViewMixIn, EntityView): - __regid__ = 'massmailing' - __select__ = authenticated_user() & adaptable('IEmailable') - - def call(self): - form = self._cw.vreg['forms'].select('massmailing', self._cw, - rset=self.cw_rset) - form.render(w=self.w) - - -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) + msg = '[3.17] cubicweb.web.views.massmailing moved to cubes.massmailing.views' + SendEmailAction = class_moved(SendEmailAction, message=msg) + recipient_vocabulary = moved('cubes.massmailing.views', 'recipient_vocabulary') + MassMailingForm = class_moved(MassMailingForm, message=msg) + MassMailingFormRenderer = class_moved(MassMailingFormRenderer, message=msg) + MassMailingFormView = class_moved(MassMailingFormView, message=msg) + SendMailController = class_moved(SendMailController, message=msg) +except ImportError: + from cubicweb.web import LOGGER + LOGGER.warning('[3.17] massmailing extracted to cube massmailing that was not found. try installing it.')