[gen] Pod field: send pod results by emails.
This commit is contained in:
parent
b565f38d97
commit
4947e2956c
|
@ -124,8 +124,15 @@ class Pod(Field):
|
|||
<x if="hasMailings" var2="sendLabel=_('email_send')">
|
||||
<tr for="mailing in mailings[fmt]" valign="top"
|
||||
var2="mailingName=field.getMailingName(obj, mailing)">
|
||||
<td width="85px"><span title=":sendLabel">:mailingName</span></td>
|
||||
<td width="15px"><img src=":url('email')"/></td>
|
||||
<td colspan="2">
|
||||
<a var="js='generatePod(%s,%s,%s,%s,%s,null,null,%s)' % \
|
||||
(q(uid), q(name), q(info.template), q(fmt), \
|
||||
q(ztool.getQueryInfo()), q(mailing))"
|
||||
onclick=":'askConfirm(%s,%s)' % (q('script'), q(js, False))"
|
||||
title=":sendLabel">
|
||||
<img src=":url('email')" align="left" style="margin-right: 2px"/>
|
||||
<x>:mailingName</x></a>
|
||||
</td>
|
||||
</tr>
|
||||
</x>
|
||||
</table>
|
||||
|
@ -404,7 +411,58 @@ class Pod(Field):
|
|||
# Deduce a nice name from p_mailing
|
||||
res = gutils.produceNiceMessage(mailing)
|
||||
return res
|
||||
|
||||
|
||||
def getMailingInfo(self, obj, template, mailing):
|
||||
'''Gets the necessary information for sending an email to
|
||||
p_mailing list.'''
|
||||
res = self.mailingInfo(obj, mailing)
|
||||
subject = res.subject
|
||||
if not subject:
|
||||
# Give a predefined subject
|
||||
mapping = {'site': obj.tool.o.getSiteUrl(),
|
||||
'title': obj.o.getShownValue('title'),
|
||||
'template': self.getTemplateName(obj, template)}
|
||||
subject = obj.translate('podmail_subject', mapping=mapping)
|
||||
body = res.body
|
||||
if not body:
|
||||
# Give a predefined body
|
||||
mapping = {'site': obj.tool.o.getSiteUrl()}
|
||||
body = obj.translate('podmail_body', mapping=mapping)
|
||||
return res.logins, subject, body
|
||||
|
||||
def sendMailing(self, obj, template, mailing, attachment):
|
||||
'''Sends the emails for m_mailing.'''
|
||||
logins, subject, body = self.getMailingInfo(obj, template, mailing)
|
||||
if not logins:
|
||||
obj.log('mailing %s contains no recipient.' % mailing)
|
||||
return 'action_ko'
|
||||
tool = obj.tool
|
||||
# Collect logins corresponding to inexistent users and recipients
|
||||
missing = []
|
||||
recipients = []
|
||||
for login in logins:
|
||||
user = tool.search1('User', noSecurity=True, login=login)
|
||||
if not user:
|
||||
missing.append(login)
|
||||
continue
|
||||
else:
|
||||
recipient = user.getMailRecipient()
|
||||
if not recipient:
|
||||
missing.append(login)
|
||||
else:
|
||||
recipients.append(recipient)
|
||||
if missing:
|
||||
obj.log('mailing %s: inexistent user or no email for %s.' % \
|
||||
(mailing, str(missing)))
|
||||
if not recipients:
|
||||
obj.log('mailing %s contains no recipient (after removing wrong ' \
|
||||
'entries, see above).' % mailing)
|
||||
msg = 'action_ko'
|
||||
else:
|
||||
tool.sendMail(recipients, subject, body, [attachment])
|
||||
msg = 'action_done'
|
||||
return msg
|
||||
|
||||
def getValue(self, obj, template=None, format=None, result=None,
|
||||
queryData=None, customContext=None, noSecurity=False):
|
||||
'''For a pod field, getting its value means computing a pod document or
|
||||
|
@ -669,8 +727,17 @@ class Pod(Field):
|
|||
obj.say(res)
|
||||
return tool.goto(rq.get('HTTP_REFERER'))
|
||||
# res contains a FileInfo instance.
|
||||
res.writeResponse(rq.RESPONSE)
|
||||
return
|
||||
# Must we return the res to the ui or send a mail with the res as
|
||||
# attachment?
|
||||
mailing = rq.get('mailing')
|
||||
if not mailing:
|
||||
res.writeResponse(rq.RESPONSE)
|
||||
return
|
||||
else:
|
||||
# Send the email(s).
|
||||
msg = self.sendMailing(obj, template, mailing, res)
|
||||
obj.say(obj.translate(msg))
|
||||
return tool.goto(rq.get('HTTP_REFERER'))
|
||||
# Performing any other action requires write access to p_obj.
|
||||
obj.o.mayEdit(self.writePermission, raiseError=True)
|
||||
msg = 'action_done'
|
||||
|
|
54
gen/mail.py
54
gen/mail.py
|
@ -9,8 +9,15 @@ from appy.shared.utils import sequenceTypes
|
|||
|
||||
# ------------------------------------------------------------------------------
|
||||
def sendMail(tool, to, subject, body, attachments=None):
|
||||
'''Sends a mail, via p_tool.mailHost, to p_to (a single email address or a
|
||||
list of email addresses).'''
|
||||
'''Sends a mail, via p_tool.mailHost, to p_to (a single email recipient or
|
||||
a list of recipients). Every (string) recipient can be an email address
|
||||
or a string of the form "[name] <[email]>".
|
||||
|
||||
p_attachment must be a list or tuple whose elements can have 2 forms:
|
||||
1. a tuple (fileName, fileContent): "fileName" is the name of the file
|
||||
as a string; "fileContent" is the file content, also as a string;
|
||||
2. a appy.fields.file.FileInfo instance.
|
||||
'''
|
||||
# Just log things if mail is disabled
|
||||
fromAddress = tool.mailFrom
|
||||
if not tool.mailEnabled or not tool.mailHost:
|
||||
|
@ -18,20 +25,20 @@ def sendMail(tool, to, subject, body, attachments=None):
|
|||
msg = ' (no mailhost defined)'
|
||||
else:
|
||||
msg = ''
|
||||
tool.log('Mail disabled%s: should send mail from %s to %s.' % \
|
||||
tool.log('mail disabled%s: should send mail from %s to %s.' % \
|
||||
(msg, fromAddress, str(to)))
|
||||
tool.log('Subject: %s' % subject)
|
||||
tool.log('Body: %s' % body)
|
||||
tool.log('subject: %s' % subject)
|
||||
tool.log('body: %s' % body)
|
||||
if attachments:
|
||||
tool.log('%d attachment(s).' % len(attachments))
|
||||
return
|
||||
tool.log('Sending mail from %s to %s (subject: %s).' % \
|
||||
tool.log('sending mail from %s to %s (subject: %s).' % \
|
||||
(fromAddress, str(to), subject))
|
||||
# Create the base MIME message
|
||||
body = MIMEText(body, 'plain', 'utf-8')
|
||||
if attachments:
|
||||
msg = MIMEMultipart()
|
||||
msg.attach( body )
|
||||
msg.attach(body)
|
||||
else:
|
||||
msg = body
|
||||
# Add the header values
|
||||
|
@ -48,23 +55,18 @@ def sendMail(tool, to, subject, body, attachments=None):
|
|||
to = fromAddress
|
||||
# Add attachments
|
||||
if attachments:
|
||||
for fileName, fileContent in attachments:
|
||||
part = MIMEBase('application', 'octet-stream')
|
||||
if fileContent.__class__.__name__ == 'FileWrapper':
|
||||
fileContent = fileContent._zopeFile
|
||||
if hasattr(fileContent, 'data'):
|
||||
# It is a File instance coming from the database
|
||||
data = fileContent.data
|
||||
if isinstance(data, basestring):
|
||||
payLoad = data
|
||||
else:
|
||||
payLoad = ''
|
||||
while data is not None:
|
||||
payLoad += data.data
|
||||
data = data.next
|
||||
for attachment in attachments:
|
||||
# 2 possible forms for an attachment
|
||||
if isinstance(attachment, tuple) or isinstance(attachment, list):
|
||||
fileName, fileContent = attachment
|
||||
else:
|
||||
payLoad = fileContent
|
||||
part.set_payload(payLoad)
|
||||
# a FileInfo instance
|
||||
fileName = attachment.uploadName
|
||||
f = file(attachment.fsPath, 'rb')
|
||||
fileContent = f.read()
|
||||
f.close()
|
||||
part = MIMEBase('application', 'octet-stream')
|
||||
part.set_payload(fileContent)
|
||||
Encoders.encode_base64(part)
|
||||
part.add_header('Content-Disposition',
|
||||
'attachment; filename="%s"' % fileName)
|
||||
|
@ -85,12 +87,12 @@ def sendMail(tool, to, subject, body, attachments=None):
|
|||
res = smtpServer.sendmail(fromAddress, [to], msg.as_string())
|
||||
smtpServer.quit()
|
||||
if res:
|
||||
tool.log('Could not send mail to some recipients. %s' % str(res),
|
||||
tool.log('could not send mail to some recipients. %s' % str(res),
|
||||
type='warning')
|
||||
except smtplib.SMTPException, e:
|
||||
tool.log('Mail sending failed: %s' % str(e), type='error')
|
||||
tool.log('mail sending failed: %s' % str(e), type='error')
|
||||
except socket.error, se:
|
||||
tool.log('Mail sending failed: %s' % str(se), type='error')
|
||||
tool.log('mail sending failed: %s' % str(se), type='error')
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def sendNotification(obj, transition, transitionName, workflow):
|
||||
|
|
|
@ -722,3 +722,11 @@ msgstr ""
|
|||
#. Default: "Send by email"
|
||||
msgid "email_send"
|
||||
msgstr ""
|
||||
|
||||
#. Default: "${site} - ${title} - ${template}"
|
||||
msgid "podmail_subject"
|
||||
msgstr ""
|
||||
|
||||
#. Default: "Hello, this email that was sent to you via ${site}. Please consult the attached file(s)."
|
||||
msgid "podmail_body"
|
||||
msgstr ""
|
||||
|
|
|
@ -722,3 +722,11 @@ msgstr ""
|
|||
#. Default: "Send by email"
|
||||
msgid "email_send"
|
||||
msgstr ""
|
||||
|
||||
#. Default: "${site} - ${title} - ${template}"
|
||||
msgid "podmail_subject"
|
||||
msgstr ""
|
||||
|
||||
#. Default: "Hello, this email that was sent to you via ${site}. Please consult the attached file(s)."
|
||||
msgid "podmail_body"
|
||||
msgstr ""
|
||||
|
|
|
@ -722,3 +722,11 @@ msgstr ""
|
|||
#. Default: "Send by email"
|
||||
msgid "email_send"
|
||||
msgstr ""
|
||||
|
||||
#. Default: "${site} - ${title} - ${template}"
|
||||
msgid "podmail_subject"
|
||||
msgstr ""
|
||||
|
||||
#. Default: "Hello, this email that was sent to you via ${site}. Please consult the attached file(s)."
|
||||
msgid "podmail_body"
|
||||
msgstr ""
|
||||
|
|
|
@ -723,3 +723,11 @@ msgstr "Microsoft Internet Explorer ${version} is not supported. Please upgrade
|
|||
#. Default: "Send by email"
|
||||
msgid "email_send"
|
||||
msgstr "Send by email"
|
||||
|
||||
#. Default: "${site} - ${title} - ${template}"
|
||||
msgid "podmail_subject"
|
||||
msgstr "${site} - ${title} - ${template}"
|
||||
|
||||
#. Default: "Hello, this email that was sent to you via ${site}. Please consult the attached file(s)."
|
||||
msgid "podmail_body"
|
||||
msgstr "Hello, this email that was sent to you via ${site}. Please consult the attached file(s)."
|
||||
|
|
|
@ -722,3 +722,11 @@ msgstr ""
|
|||
#. Default: "Send by email"
|
||||
msgid "email_send"
|
||||
msgstr ""
|
||||
|
||||
#. Default: "${site} - ${title} - ${template}"
|
||||
msgid "podmail_subject"
|
||||
msgstr ""
|
||||
|
||||
#. Default: "Hello, this email that was sent to you via ${site}. Please consult the attached file(s)."
|
||||
msgid "podmail_body"
|
||||
msgstr ""
|
||||
|
|
|
@ -723,3 +723,11 @@ msgstr "Microsoft Internet Explorer ${version} n'est pas supporté. Veuillez met
|
|||
#. Default: "Send by email"
|
||||
msgid "email_send"
|
||||
msgstr "Envoyer par email"
|
||||
|
||||
#. Default: "${site} - ${title} - ${template}"
|
||||
msgid "podmail_subject"
|
||||
msgstr "${site} - ${title} - ${template}"
|
||||
|
||||
#. Default: "Hello, this email that was sent to you via ${site}. Please consult the attached file(s)."
|
||||
msgid "podmail_body"
|
||||
msgstr "Bonjour, cet email vous est envoyé depuis ${site}. Veuillez consulter le(s) fichier(s) joint(s)."
|
||||
|
|
|
@ -722,3 +722,11 @@ msgstr ""
|
|||
#. Default: "Send by email"
|
||||
msgid "email_send"
|
||||
msgstr ""
|
||||
|
||||
#. Default: "${site} - ${title} - ${template}"
|
||||
msgid "podmail_subject"
|
||||
msgstr ""
|
||||
|
||||
#. Default: "Hello, this email that was sent to you via ${site}. Please consult the attached file(s)."
|
||||
msgid "podmail_body"
|
||||
msgstr ""
|
||||
|
|
|
@ -722,3 +722,11 @@ msgstr ""
|
|||
#. Default: "Send by email"
|
||||
msgid "email_send"
|
||||
msgstr ""
|
||||
|
||||
#. Default: "${site} - ${title} - ${template}"
|
||||
msgid "podmail_subject"
|
||||
msgstr ""
|
||||
|
||||
#. Default: "Hello, this email that was sent to you via ${site}. Please consult the attached file(s)."
|
||||
msgid "podmail_body"
|
||||
msgstr ""
|
||||
|
|
|
@ -686,7 +686,7 @@ function toggleCookie(cookieId) {
|
|||
|
||||
// Function that allows to generate a document from a pod template.
|
||||
function generatePod(uid, fieldName, template, podFormat, queryData,
|
||||
customParams, getChecked) {
|
||||
customParams, getChecked, mailing) {
|
||||
var f = document.getElementById('podForm');
|
||||
f.objectUid.value = uid;
|
||||
f.fieldName.value = fieldName;
|
||||
|
@ -695,6 +695,7 @@ function generatePod(uid, fieldName, template, podFormat, queryData,
|
|||
f.queryData.value = queryData;
|
||||
if (customParams) { f.customParams.value = customParams; }
|
||||
else { f.customParams.value = ''; }
|
||||
if (mailing) f.mailing.value = mailing;
|
||||
f.action.value = 'generate';
|
||||
f.checkedUids.value = '';
|
||||
f.checkedSem.value = '';
|
||||
|
|
|
@ -146,6 +146,7 @@ class ToolWrapper(AbstractWrapper):
|
|||
<input type="hidden" name="customParams"/>
|
||||
<input type="hidden" name="checkedUids"/>
|
||||
<input type="hidden" name="checkedSem"/>
|
||||
<input type="hidden" name="mailing"/>
|
||||
<input type="hidden" name="action" value="generate"/>
|
||||
</form>''')
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
from appy.fields.string import String
|
||||
from appy.gen import WorkflowOwner
|
||||
from appy.gen.layout import summaryPageLayouts
|
||||
from appy.gen.wrappers import AbstractWrapper
|
||||
|
@ -107,6 +108,14 @@ class UserWrapper(AbstractWrapper):
|
|||
from AccessControl.AuthEncoding import pw_validate
|
||||
return pw_validate(encryptedPassword, clearPassword)
|
||||
|
||||
def getMailRecipient(self):
|
||||
'''Returns, for this user, the "recipient string" (first name, name,
|
||||
email) as can be used for sending an email.'''
|
||||
res = self.email or self.login
|
||||
# Ensure this is really an email
|
||||
if not String.EMAIL.match(res): return
|
||||
return '%s <%s>' % (self.title, res)
|
||||
|
||||
def setLogin(self, oldLogin, newLogin):
|
||||
'''Changes the login of this user from p_oldLogin to p_newLogin.'''
|
||||
self.login = newLogin
|
||||
|
|
Loading…
Reference in a new issue