15 from cubicweb.web.action import Action |
15 from cubicweb.web.action import Action |
16 from cubicweb.web import stdmsgs |
16 from cubicweb.web import stdmsgs |
17 |
17 |
18 |
18 |
19 class SendEmailAction(Action): |
19 class SendEmailAction(Action): |
20 category = 'mainactions' |
20 id = 'sendemail' |
21 # XXX should check email is set as well |
21 # XXX should check email is set as well |
22 __select__ = implements(IEmailable) & match_user_groups('managers', 'users') |
22 __select__ = implements(IEmailable) & match_user_groups('managers', 'users') |
23 |
23 |
24 id = 'sendemail' |
|
25 title = _('send email') |
24 title = _('send email') |
|
25 category = 'mainactions' |
26 |
26 |
27 def url(self): |
27 def url(self): |
28 params = {'vid': 'massmailing', '__force_display': 1} |
28 params = {'vid': 'massmailing', '__force_display': 1} |
29 if self.req.form.has_key('rql'): |
29 if self.req.form.has_key('rql'): |
30 params['rql'] = self.req.form['rql'] |
30 params['rql'] = self.req.form['rql'] |
31 return self.build_url(self.req.relative_path(includeparams=False), |
31 return self.build_url(self.req.relative_path(includeparams=False), |
32 **params) |
32 **params) |
33 |
33 |
|
34 from cubicweb.web.form import FieldsForm, FormRenderer |
|
35 from cubicweb.web.form import StringField, CheckBox, TextInput, AjaxWidget |
|
36 |
|
37 class MassMailingForm(FieldsForm): |
|
38 id = 'massmailing' |
|
39 |
|
40 sender = StringField(widget=TextInput({'disabled': 'disabled'}), label=_('From:')) |
|
41 recipient = StringField(widget=CheckBox(), label=_('Recipients:')) |
|
42 subject = StringField(label=_('Subject:')) |
|
43 mailbody = StringField(widget=AjaxWidget(wdgtype='TemplateTextField', |
|
44 inputid='mailarea')) |
34 |
45 |
35 class MassMailingForm(EntityView): |
46 def form_field_vocabulary(self, field): |
|
47 if field.name == 'recipient': |
|
48 vocab = [(entity.get_email(), entity.eid) for entity in self.rset.entities()] |
|
49 return [(label, value) for label, value in vocab if label] |
|
50 return super(MassMailingForm, self).form_field_vocabulary(field) |
|
51 |
|
52 def form_field_value(self, field, values): |
|
53 if field.name == 'recipient': |
|
54 return [entity.eid for entity in self.rset.entities() if entity.get_email()] |
|
55 elif field.name == 'mailbody': |
|
56 field.widget.attrs['cubicweb:variables'] = self.get_allowed_substitutions() |
|
57 return super(MassMailingForm, self).form_field_value(field, values) |
|
58 |
|
59 def form_buttons(self): |
|
60 context = {'domid': self.domid, |
|
61 'cancel' : self.req._(stdmsgs.BUTTON_CANCEL), |
|
62 'cancelimgpath' : self.req.external_resource('CANCEL_EMAIL_ICON'), |
|
63 'send' : self.req._('send email'), |
|
64 'sendimgpath' : self.req.external_resource('SEND_EMAIL_ICON'), |
|
65 } |
|
66 return ['''<a id="sendbutton" href="javascript: $('%(domid)s').submit()"> |
|
67 <img src="%(sendimgpath)s" alt="%(send)s"/>%(send)s</a>''' % context, |
|
68 '''<a id="cancelbutton" href="javascript: history.back()"> |
|
69 <img src="%(cancelimgpath)s" alt="%(cancel)s"/>%(cancel)s</a>''' % context, |
|
70 ] |
|
71 |
|
72 def get_allowed_substitutions(self): |
|
73 attrs = [] |
|
74 for coltype in self.rset.column_types(0): |
|
75 eclass = self.vreg.etype_class(coltype) |
|
76 attrs.append(eclass.allowed_massmail_keys()) |
|
77 return sorted(reduce(operator.and_, attrs)) |
|
78 |
|
79 def build_substitutions_help(self): |
|
80 insertLink = u'<a href="javascript: insertText(\'%%(%s)s\', \'emailarea\');">%%(%s)s</a>' |
|
81 substs = (u'<div class="substitution">%s</div>' % (insertLink % (subst, subst)) |
|
82 for subst in self.get_allowed_substitutions()) |
|
83 helpmsg = self.req._('You can use any of the following substitutions in your text') |
|
84 return u'<div id="substitutions"><span>%s</span>%s</div>' % ( |
|
85 helpmsg, u'\n'.join(substs)) |
|
86 |
|
87 |
|
88 class MassMailingFormRenderer(FormRenderer): |
|
89 button_bar_class = u'toolbar' |
|
90 |
|
91 def _render_fields(self, fields, w, form, display_help): |
|
92 w(u'<table class="headersform">') |
|
93 for field in fields: |
|
94 if field.name == 'mailbody': |
|
95 w(u'</table>') |
|
96 w(u'<table>') |
|
97 w(u'<tr><td><div>') |
|
98 else: |
|
99 w(u'<tr>') |
|
100 w(u'<td class="hlabel">%s</td>' % self.render_label(form, field)) |
|
101 w(u'<td class="hvalue">') |
|
102 w(field.render(form, self)) |
|
103 if field.name == 'mailbody': |
|
104 w(u'</div></td>') |
|
105 w(u'<td>%s</td>' % form.build_substitutions_help()) |
|
106 w(u'</tr>') |
|
107 else: |
|
108 w(u'</td></tr>') |
|
109 w(u'</table>') |
|
110 |
|
111 |
|
112 class MassMailingFormView(EntityView): |
36 id = 'massmailing' |
113 id = 'massmailing' |
37 __select__ = implements(IEmailable) & match_user_groups('managers', 'users') |
114 __select__ = implements(IEmailable) & match_user_groups('managers', 'users') |
38 |
|
39 form_template = u""" |
|
40 <div id="compose"> |
|
41 <form id="sendemail" action="sendmail" method="post"> |
|
42 <table class="headersform"> |
|
43 <tr> |
|
44 <td class="hlabel">%(from_header)s</td> |
|
45 <td class="hvalue">%(from)s</td> |
|
46 </tr> |
|
47 <tr> |
|
48 <td class="hlabel">%(recipients_header)s</td> |
|
49 <td class="hvalue">%(recipients)s</td> |
|
50 </tr> |
|
51 <tr> |
|
52 <td class="hlabel">%(subject)s</td> |
|
53 <td class="hvalue"><input id="mailsubj" name="mailsubject" value="" /></td> |
|
54 </tr> |
|
55 </table> |
|
56 <div id="toolbar"> |
|
57 <ul> |
|
58 <li><a id="sendbutton" href="javascript: $('sendemail').submit()"> |
|
59 <img src="%(sendimgpath)s" alt="%(send)s"/>%(send)s</a></li> |
|
60 <li><a id="cancelbutton" href="javascript: history.back()"> |
|
61 <img src="%(cancelimgpath)s" alt="%(cancel)s"/>%(cancel)s</a></li> |
|
62 </ul> |
|
63 </div> |
|
64 <table> |
|
65 <tr> |
|
66 <td> |
|
67 <div> |
|
68 <div id="emailbody" class="widget" cubicweb:loadtype="auto" cubicweb:wdgtype="TemplateTextField" |
|
69 cubicweb:inputid="emailarea" cubicweb:inputname="mailbody" cubicweb:variables="%(variables)s"/> |
|
70 </div> |
|
71 </td> |
|
72 <td>%(substitutions)s</td> |
|
73 </tr> |
|
74 </table> |
|
75 </form> |
|
76 </div> |
|
77 """ |
|
78 |
115 |
79 def call(self): |
116 def call(self): |
80 req = self.req |
117 req = self.req |
81 req.add_js('cubicweb.widgets.js') |
118 req.add_js('cubicweb.widgets.js') |
82 req.add_css('cubicweb.mailform.css') |
119 req.add_css('cubicweb.mailform.css') |
83 from_addr = '%s <%s>' % (req.user.dc_title(), req.user.get_email()) |
120 from_addr = '%s <%s>' % (req.user.dc_title(), req.user.get_email()) |
84 ctx = { |
121 form = self.vreg.select_object('forms', 'massmailing', self.req, self.rset, |
85 'from_header' : req._('From: '), |
122 action='sendmail', domid='sendmail') |
86 'from' : html_escape(from_addr), |
123 self.w(form.form_render(sender=from_addr, renderer=MassMailingFormRenderer())) |
87 'substitutions' : self._build_substitutions_help(), |
|
88 'recipients_header' : req._('Recipients: '), |
|
89 'subject' : req._('Subject: '), |
|
90 'body' : req._('Email body: '), |
|
91 'variables' : ','.join(self._get_allowed_substitutions()), |
|
92 'recipients' : self._build_recipients_list(), |
|
93 'cancel' : req._(stdmsgs.BUTTON_CANCEL), |
|
94 'cancelimgpath' : req.external_resource('CANCEL_EMAIL_ICON'), |
|
95 'send' : req._('send email'), |
|
96 'sendimgpath' : req.external_resource('SEND_EMAIL_ICON'), |
|
97 } |
|
98 self.w(self.form_template % ctx) |
|
99 |
124 |
100 |
125 |
101 def _get_allowed_substitutions(self): |
|
102 coltypes = self.rset.column_types(0) |
|
103 attrs = [] |
|
104 for coltype in coltypes: |
|
105 eclass = self.vreg.etype_class(coltype) |
|
106 attrs.append(eclass.allowed_massmail_keys()) |
|
107 return sorted(reduce(operator.and_, attrs)) |
|
108 |
|
109 def _build_recipients_list(self): |
|
110 emails = ((entity.eid, entity.get_email()) for entity in self.rset.entities()) |
|
111 checkboxes = (u'<input name="recipient" type="checkbox" value="%s" checked="checked" />%s' |
|
112 % (eid, html_escape(email)) for eid, email in emails if email) |
|
113 boxes = (u'<div class="recipient">%s</div>' % cbox for cbox in checkboxes) |
|
114 return u'<div id="recipients">%s</div>' % u'\n'.join(boxes) |
|
115 |
|
116 |
|
117 def _build_substitutions_help(self): |
|
118 insertLink = u'<a href="javascript: insertText(\'%%(%s)s\', \'emailarea\');">%%(%s)s</a>' |
|
119 substs = (u'<div class="substitution">%s</div>' % (insertLink % (subst, subst)) |
|
120 for subst in self._get_allowed_substitutions()) |
|
121 helpmsg = self.req._('You can use any of the following substitutions in your text') |
|
122 return u'<div id="substitutions"><span>%s</span>%s</div>' % ( |
|
123 helpmsg, u'\n'.join(substs)) |
|
124 |
|
125 |
126 |