Steve Holden skrev:
I'm having some trouble getting attachments right for all recipients,
and it seems like Apple's mail.app is the pickiest client at the moment.
It doesn't handle attachments that both Thunderbird and Outlook find
perfectly acceptable.
Since the code I'm using is currently ugly and embedded, before I trim
it down for posting could anyone who's successfully generated emails
with attachments received by mail.app let me know if they had any
problems along the way? Google hasn't given me much on this, but I'm not
feeling very creative today.
This method is used in one of my Plone products, and there is also a bit
of imap in there. But it is probably simple enough to extract the
attachment relevant parts....
security.declareProtected(EDIT_CONTENTS_PERMISSION, 'sendMessage')
def sendMessage(self, to=None, cc=None, bcc=None, inReplyTo=None,
subject=None, body='', attachments=None, mode=None,
folderPath=None, uid=None, REQUEST=None):
"Sends a message"
site_encoding = self._site_encoding()
##################
# Create the message
msg = Message()
msg.set_payload(body, site_encoding)
#####################################
# if attachment, convert to multipart
# file fields are posted even if empty, so we need to remove
those :-s
if attachments is None:
attachments = []
attachments = [a for a in attachments if a]
if attachments or (mode == 'Forward'):
mimeMsg = MIMEMultipart()
mimeMsg.attach(msg)
# If mode is Forward we get original message as attachment
if mode == 'Forward' and folderPath and uid:
original = self.fetchMessageFromPath(folderPath, uid)
mimeMsg.attach(original)
for attachment in attachments:
# Add the attachment
tmp = email.message_from_string(str(attachment.headers))
filename = tmp.get_param('filename', 'Attachment',
'Content-Disposition')
# clean up IE paths
filename = filename[max(filename.rfind('/'),
filename.rfind('\\'),
filename.rfind(':')
)+1:]
contentType = tmp['Content-Type']
attach_part = Message()
attach_part.add_header('Content-Type', contentType,
name=filename)
attach_part.add_header('Content-Disposition',
'attachment', filename=filename)
attach_part.set_payload(attachment.read())
Encoders.encode_base64(attach_part)
mimeMsg.attach(attach_part)
msg = mimeMsg
########################
# set headers on message
from_ = self.getEmail()
msg['From'] = from_
msg['Reply-To'] = from_
if to: msg['To'] = to
if cc: msg['Cc'] = cc
if bcc: msg['Bcc'] = bcc
msg['Date'] = self.ZopeTime().rfc822() # needed by some servers
if inReplyTo:
msg['In-Reply-To'] = inReplyTo
msg['Subject'] = Header(subject, site_encoding)
##################
# Send the message
SMTPserver = self._mailhost()
outbox = smtplib.SMTP(SMTPserver)
try:
cleaner = lambda adresses: [adress.strip() for adress in
adresses.split(',') if adress.strip()]
all_receivers = cleaner(to) + cleaner(cc) + cleaner(bcc)
outbox.sendmail(from_, all_receivers, msg.as_string())
success = 1
except:
success = 0
######################################
# append the message to the 'Sent' box
if success:
Sent = self.getSentboxName()
connection = self.getConnection()
try:
connection.append(Sent, msg.as_string(), ('\\Seen',))
except:
# we don't want to not send messages just because the
sentbox isn't set correctly
pass
#################################
# returns a portal status message
if REQUEST:
if success:
message = 'Succes! The message was sent '
else:
message = 'Error! The message could not be sent'
REQUEST.RESPONSE.redirect(self.absolute_url() +
'/mxmImapClient_compose?portal_status_message=%s' % message)
--
hilsen/regards Max M, Denmark
http://www.mxm.dk/
IT's Mad Science