def test_japanese_codecs(self): eq = self.ndiffAssertEqual j = Charset("euc-jp") g = Charset("iso-8859-1") h = Header("Hello World!") jhello = '\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc\xa5\xeb\xa5\xc9\xa1\xaa' ghello = 'Gr\xfc\xdf Gott!' h.append(jhello, j) h.append(ghello, g) # BAW: This used to -- and maybe should -- fold the two iso-8859-1 # chunks into a single encoded word. However it doesn't violate the # standard to have them as two encoded chunks and maybe it's # reasonable <wink> for each .append() call to result in a separate # encoded word. eq(h.encode(), """\ Hello World! =?iso-2022-jp?b?GyRCJU8lbSE8JW8hPCVrJUkhKhsoQg==?= =?iso-8859-1?q?Gr=FC=DF?= =?iso-8859-1?q?_Gott!?=""") eq(decode_header(h.encode()), [('Hello World!', None), ('\x1b$B%O%m!<%o!<%k%I!*\x1b(B', 'iso-2022-jp'), ('Gr\xfc\xdf Gott!', 'iso-8859-1')]) long = 'test-ja \xa4\xd8\xc5\xea\xb9\xc6\xa4\xb5\xa4\xec\xa4\xbf\xa5\xe1\xa1\xbc\xa5\xeb\xa4\xcf\xbb\xca\xb2\xf1\xbc\xd4\xa4\xce\xbe\xb5\xc7\xa7\xa4\xf2\xc2\xd4\xa4\xc3\xa4\xc6\xa4\xa4\xa4\xde\xa4\xb9' h = Header(long, j, header_name="Subject") # test a very long header enc = h.encode() # TK: splitting point may differ by codec design and/or Header encoding eq(enc , """\ =?iso-2022-jp?b?dGVzdC1qYSAbJEIkWEVqOUYkNSRsJD8lYSE8JWskTztKGyhC?= =?iso-2022-jp?b?GyRCMnE8VCROPjVHJyRyQlQkQyRGJCQkXiQ5GyhC?=""") # TK: full decode comparison eq(h.__unicode__().encode('euc-jp'), long)
def test_japanese_codecs(self): eq = self.ndiffAssertEqual j = Charset("euc-jp") g = Charset("iso-8859-1") h = Header("Hello World!") jhello = '\xa5\xcf\xa5\xed\xa1\xbc\xa5\xef\xa1\xbc\xa5\xeb\xa5\xc9\xa1\xaa' ghello = 'Gr\xfc\xdf Gott!' h.append(jhello, j) h.append(ghello, g) # BAW: This used to -- and maybe should -- fold the two iso-8859-1 # chunks into a single encoded word. However it doesn't violate the # standard to have them as two encoded chunks and maybe it's # reasonable <wink> for each .append() call to result in a separate # encoded word. eq( h.encode(), """\ Hello World! =?iso-2022-jp?b?GyRCJU8lbSE8JW8hPCVrJUkhKhsoQg==?= =?iso-8859-1?q?Gr=FC=DF?= =?iso-8859-1?q?_Gott!?=""") eq(decode_header(h.encode()), [('Hello World!', None), ('\x1b$B%O%m!<%o!<%k%I!*\x1b(B', 'iso-2022-jp'), ('Gr\xfc\xdf Gott!', 'iso-8859-1')]) long = 'test-ja \xa4\xd8\xc5\xea\xb9\xc6\xa4\xb5\xa4\xec\xa4\xbf\xa5\xe1\xa1\xbc\xa5\xeb\xa4\xcf\xbb\xca\xb2\xf1\xbc\xd4\xa4\xce\xbe\xb5\xc7\xa7\xa4\xf2\xc2\xd4\xa4\xc3\xa4\xc6\xa4\xa4\xa4\xde\xa4\xb9' h = Header(long, j, header_name="Subject") # test a very long header enc = h.encode() # TK: splitting point may differ by codec design and/or Header encoding eq( enc, """\ =?iso-2022-jp?b?dGVzdC1qYSAbJEIkWEVqOUYkNSRsJD8lYSE8JWskTztKGyhC?= =?iso-2022-jp?b?GyRCMnE8VCROPjVHJyRyQlQkQyRGJCQkXiQ5GyhC?=""") # TK: full decode comparison eq(h.__unicode__().encode('euc-jp'), long)
def send_email(self): """Sends the email """ properties = getUtility(IPropertiesTool) mh = getToolByName(self.context, 'MailHost') from_addr = properties.email_from_address # prepare from address for header header_from = Header(properties.email_from_name.decode('utf-8'), 'iso-8859-1') header_from.append(u'<%s>' % from_addr.decode('utf-8'), 'iso-8859-1') # Subject subject = self.context.translate(self.get_subject()) header_subject = Header(unicode(subject), 'iso-8859-1') html_body = self.render_template().encode('utf-8') msg = MIMEText(html_body, 'html', 'utf-8') msg['From'] = header_from msg['Subject'] = header_subject for rcpt in self.config.get_receivers(): msg['To'] = rcpt mh.secureSend(msg, mto=rcpt, mfrom=from_addr, subject=subject)
def _encode_address_string(text, charset): """Split the email into parts and use header encoding on the name part if needed. We do this because the actual addresses need to be ASCII with no encoding for most SMTP servers, but the non-address parts should be encoded appropriately.""" header = Header() name, addr = parseaddr(text) try: name.decode('us-ascii') except UnicodeDecodeError: if charset: charset = Charset(charset) name = charset.header_encode(name) # We again replace rather than raise an error or pass an 8bit string header.append(formataddr((name, addr)), errors='replace') return header
def sendDeleteNotifications(con, lang, project, category, relativeID, userID): """ Send a notification in case of delete """ cursor = con.cursor() # creating the list of recipients query = """ SELECT mail FROM Client WHERE subscription = True AND allowed = True AND project = %s""" cursor.execute(query, (projectID(con, project), )) recipients = [] for row in cursor.fetchall() : recipients.append(row[0]) # get message content query = """ SELECT name, lastMessageID FROM Entry WHERE relativeID = %s AND category = %s""" categoryCode = {'bug' : 1, 'feature' : 2} cursor.execute(query, (relativeID, categoryCode[category])) row = cursor.fetchone() title = row[0] inReplyTo = row[1] # user caracteristics (the one who deleted the entry) query = """SELECT login, mail FROM Client WHERE id=%s""" cursor.execute(query, (userID, )) row = cursor.fetchone() author = row[0] authorMail = row[1] # load template mytemplate = Template(filename='templates/'+lang+'/mails/delete.mail', output_encoding='utf-8', default_filters=['decode.utf8'], input_encoding='utf-8') text = mytemplate.render(creator = author) category = category[0].upper()+category[1:].lower() h = Header() h.append(u'Re:', 'utf-8') h.append(category, 'utf-8') h.append(u'#'+str(relativeID)+u':', 'utf-8') h.append(title, 'utf-8') # make messageID # no need to save it to the database : the entry will be deleted messageID = make_msgid() mail = {'From' : author + ' <' + authorMail + '>', 'To' : recipients, 'Subject' : h, 'Reply-To' : project + '@projects.naphtaline.net', 'Message-ID' : messageID, 'In-Reply-To' : inReplyTo, 'text' : text, 'files' : []} send_mail(mail)
def sendMailMessage(self, xMailMessage): COMMASPACE = ', ' if dbg: print >> sys.stderr, "PyMailSMPTService sendMailMessage" recipients = xMailMessage.getRecipients() sendermail = xMailMessage.SenderAddress sendername = xMailMessage.SenderName subject = xMailMessage.Subject ccrecipients = xMailMessage.getCcRecipients() bccrecipients = xMailMessage.getBccRecipients() if dbg: print >> sys.stderr, "PyMailSMPTService subject", subject print >> sys.stderr, "PyMailSMPTService from", sendername.encode('utf-8') print >> sys.stderr, "PyMailSMTPService from", sendermail print >> sys.stderr, "PyMailSMPTService send to", recipients attachments = xMailMessage.getAttachments() textmsg = Message() content = xMailMessage.Body flavors = content.getTransferDataFlavors() if dbg: print >> sys.stderr, "PyMailSMPTService flavors len", len(flavors) #Use first flavor that's sane for an email body for flavor in flavors: if flavor.MimeType.find('text/html') != -1 or flavor.MimeType.find('text/plain') != -1: if dbg: print >> sys.stderr, "PyMailSMPTService mimetype is", flavor.MimeType textbody = content.getTransferData(flavor) try: textbody = textbody.value except: pass textbody = textbody.encode('utf-8') if len(textbody): mimeEncoding = re.sub("charset=.*", "charset=UTF-8", flavor.MimeType) if mimeEncoding.find('charset=UTF-8') == -1: mimeEncoding = mimeEncoding + "; charset=UTF-8" textmsg['Content-Type'] = mimeEncoding textmsg['MIME-Version'] = '1.0' textmsg.set_payload(textbody) break if (len(attachments)): msg = MIMEMultipart() msg.epilogue = '' msg.attach(textmsg) else: msg = textmsg hdr = Header(sendername, 'utf-8') hdr.append('<'+sendermail+'>','us-ascii') msg['Subject'] = subject msg['From'] = hdr msg['To'] = COMMASPACE.join(recipients) if len(ccrecipients): msg['Cc'] = COMMASPACE.join(ccrecipients) if xMailMessage.ReplyToAddress != '': msg['Reply-To'] = xMailMessage.ReplyToAddress mailerstring = "OpenOffice.org 2.0 via Caolan's mailmerge component" try: ctx = uno.getComponentContext() aConfigProvider = ctx.ServiceManager.createInstance("com.sun.star.configuration.ConfigurationProvider") prop = uno.createUnoStruct('com.sun.star.beans.PropertyValue') prop.Name = "nodepath" prop.Value = "/org.openoffice.Setup/Product" aSettings = aConfigProvider.createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", (prop,)) mailerstring = aSettings.getByName("ooName") + " " + \ aSettings.getByName("ooSetupVersion") + " via Caolan's mailmerge component" except: pass msg['X-Mailer'] = mailerstring msg['Date'] = formatdate(localtime=True) for attachment in attachments: content = attachment.Data flavors = content.getTransferDataFlavors() flavor = flavors[0] ctype = flavor.MimeType maintype, subtype = ctype.split('/', 1) msgattachment = MIMEBase(maintype, subtype) data = content.getTransferData(flavor) msgattachment.set_payload(data) Encoders.encode_base64(msgattachment) fname = attachment.ReadableName try: fname.encode('ascii') except: fname = ('utf-8','',fname.encode('utf-8')) msgattachment.add_header('Content-Disposition', 'attachment', \ filename=fname) msg.attach(msgattachment) uniquer = {} for key in recipients: uniquer[key] = True if len(ccrecipients): for key in ccrecipients: uniquer[key] = True if len(bccrecipients): for key in bccrecipients: uniquer[key] = True truerecipients = uniquer.keys() if dbg: print >> sys.stderr, "PyMailSMPTService recipients are", truerecipients self.server.sendmail(sendermail, truerecipients, msg.as_string())
def send(self, recipients=[]): """Sends the newsletter. An optional list of dicts (keys=fullname|mail) can be passed in for sending a newsletter out addresses != subscribers. """ # preparations request = self.REQUEST test = hasattr(request, 'test') current_state = api.content.get_state(obj=self) # check for workflow if not (test or recipients) and current_state != 'sending': raise ValueError('Executed send in wrong review state!') # get hold of the parent Newsletter object# enl = self.getNewsletter() # get sender name sender_name = request.get('sender_name') if not sender_name: sender_name = enl.getSenderName() # don't use Header() with a str and a charset arg, even if # it is correct this would generate a encoded header and mail # server may not support utf-8 encoded header from_header = Header(safe_unicode(sender_name)) # get sender e-mail sender_email = request.get('sender_email') if not sender_email: sender_email = enl.getSenderEmail() from_header.append(u'<%s>' % safe_unicode(sender_email)) # determine MailHost first (build-in vs. external) deliveryServiceName = enl.getDeliveryService() if deliveryServiceName == 'mailhost': mail_host = getToolByName(enl, 'MailHost') else: mail_host = getUtility(IMailHost, name=deliveryServiceName) log.info('Using mail delivery service "%r"' % mail_host) send_counter = 0 send_error_counter = 0 charset = get_email_charset() if not recipients: receivers = self._send_recipients() issue_data_fetcher = IIssueDataFetcher(self) for receiver in receivers: # get complete issue data issue_data = issue_data_fetcher(receiver) # create multipart mail outer = MIMEMultipart('alternative') outer['To'] = Header(u'<%s>' % safe_unicode(receiver['email'])) outer['From'] = from_header outer['Subject'] = issue_data['subject_header'] outer.epilogue = '' # Attach text part text_part = MIMEText(issue_data['body_plain'], 'plain', charset) # Attach html part with images html_part = MIMEMultipart('related') html_text = MIMEText(issue_data['body_html'], 'html', charset) html_part.attach(html_text) # Add images to the message for image in issue_data['images_to_attach']: html_part.attach(image) outer.attach(text_part) outer.attach(html_part) try: mail_host.send(outer.as_string()) log.info('Send newsletter to "%s"' % receiver['email']) send_counter += 1 except Exception, e: # noqa log.exception( 'Sending newsletter to "%s" failed, with error "%s"!' % (receiver['email'], e)) send_error_counter += 1
def sendMailMessage(self, xMailMessage): COMMASPACE = ", " if dbg: print >>sys.stderr, "PyMailSMPTService sendMailMessage" recipients = xMailMessage.getRecipients() sendermail = xMailMessage.SenderAddress sendername = xMailMessage.SenderName subject = xMailMessage.Subject ccrecipients = xMailMessage.getCcRecipients() bccrecipients = xMailMessage.getBccRecipients() if dbg: print >>sys.stderr, "PyMailSMPTService subject", subject print >>sys.stderr, "PyMailSMPTService from", sendername.encode("utf-8") print >>sys.stderr, "PyMailSMTPService from", sendermail print >>sys.stderr, "PyMailSMPTService send to", recipients attachments = xMailMessage.getAttachments() content = xMailMessage.Body flavors = content.getTransferDataFlavors() flavor = flavors[0] if dbg: print >>sys.stderr, "PyMailSMPTService mimetype is", flavor.MimeType textbody = content.getTransferData(flavor) textmsg = Message() mimeEncoding = re.sub("charset=.*", "charset=UTF-8", flavor.MimeType) textmsg["Content-Type"] = mimeEncoding textmsg["MIME-Version"] = "1.0" textmsg.set_payload(textbody.encode("utf-8")) if len(attachments): msg = MIMEMultipart() msg.epilogue = "" msg.attach(textmsg) else: msg = textmsg hdr = Header(sendername, "utf-8") hdr.append("<" + sendermail + ">", "us-ascii") msg["Subject"] = subject msg["From"] = hdr msg["To"] = COMMASPACE.join(recipients) if len(ccrecipients): msg["Cc"] = COMMASPACE.join(ccrecipients) if xMailMessage.ReplyToAddress != "": msg["Reply-To"] = xMailMessage.ReplyToAddress msg["X-Mailer"] = "OpenOffice.org 2.0 via Caolan's mailmerge component" msg["Date"] = formatdate(localtime=True) for attachment in attachments: content = attachment.Data flavors = content.getTransferDataFlavors() flavor = flavors[0] ctype = flavor.MimeType maintype, subtype = ctype.split("/", 1) msgattachment = MIMEBase(maintype, subtype) data = content.getTransferData(flavor) msgattachment.set_payload(data) Encoders.encode_base64(msgattachment) msgattachment.add_header("Content-Disposition", "attachment", filename=attachment.ReadableName) msg.attach(msgattachment) uniquer = {} for key in recipients: uniquer[key] = True if len(ccrecipients): for key in ccrecipients: uniquer[key] = True if len(bccrecipients): for key in bccrecipients: uniquer[key] = True truerecipients = uniquer.keys() if dbg: print >>sys.stderr, "PyMailSMPTService recipients are", truerecipients self.server.sendmail(sendermail, truerecipients, msg.as_string())
#!/usr/bin/env python from email.MIMEText import MIMEText from email.Header import Header from email import Utils message = """Hello, This is a test message from Rock, I hope you enjoy it! --Anonymous""" msg = MIMEText(message) msg['To'] = '*****@*****.**' fromhdr = Header("Michael M\xfcller", 'iso-8859-1') fromhdr.append('<*****@*****.**>', 'ascii') msg['From'] = fromhdr msg['Subject'] = Header('Test Message, Rock') msg['Date'] = Utils.formatdate(localtime = 1) msg['Message-ID'] = Utils.make_msgid() print msg.as_string()
def send(self, recipients=[]): """Sends the newsletter. An optional list of dicts (keys=fullname|mail) can be passed in for sending a newsletter out addresses != subscribers. """ # preparations request = self.REQUEST # get hold of the parent Newsletter object# enl = self.getNewsletter() # get sender name sender_name = request.get("sender_name", "") if sender_name == "": sender_name = enl.getSenderName() # don't use Header() with a str and a charset arg, even if it is correct # this would generate a encoded header and mail server may not support utf-8 encoded header from_header = Header(safe_unicode(sender_name)) # get sender e-mail sender_email = request.get("sender_email", "") if sender_email == "": sender_email = enl.getSenderEmail() from_header.append('<%s>' % safe_unicode(sender_email)) # get subject subject = request.get("subject", "") if subject == "": subject = self.Title() subject_header = Header(safe_unicode(subject)) # Create from-header #from_header = enl.getSenderName() and '"%s" <%s>' % (sender_name, sender_email) or sender_email #from_header = safe_unicode(from_header) # determine MailHost first (build-in vs. external) deliveryServiceName = enl.getDeliveryService() if deliveryServiceName == 'mailhost': MailHost = getToolByName(enl, 'MailHost') else: MailHost = getUtility(IMailHost, name=deliveryServiceName) log.info('Using mail delivery service "%r"' % MailHost) send_counter = 0 send_error_counter = 0 receivers = self._send_recipients(recipients) output_html = self._render_output_html() rendered_newsletter = self._exchange_relative_urls(output_html) text = rendered_newsletter['html'] text_plain = rendered_newsletter['plain'] image_urls = rendered_newsletter['images'] props = getToolByName(self, "portal_properties").site_properties charset = props.getProperty("default_charset") for receiver in receivers: # create multipart mail outer = MIMEMultipart('alternative') if hasattr(request, "test"): outer['To'] = Header('<%s>' % safe_unicode(receiver['email'])) fullname = receiver['fullname'] salutation = receiver['salutation'] personal_text = text.replace("[[SUBSCRIBER_SALUTATION]]", "") personal_text_plain = text_plain.replace("[[SUBSCRIBER_SALUTATION]]", "") personal_text = text.replace("[[UNSUBSCRIBE]]", "") personal_text_plain = text_plain.replace("[[UNSUBSCRIBE]]", "") else: if 'uid' in receiver: try: unsubscribe_text = enl.getUnsubscribe_string() except AttributeError: unsubscribe_text = "Click here to unsubscribe" unsubscribe_link = enl.absolute_url() + "/unsubscribe?subscriber=" + receiver['uid'] personal_text = text.replace("[[UNSUBSCRIBE]]", """<a href="%s">%s.</a>""" % (unsubscribe_link, unsubscribe_text)) personal_text_plain = text_plain.replace("[[UNSUBSCRIBE]]", """\n%s: %s""" % (unsubscribe_text, unsubscribe_link)) else: personal_text = text.replace("[[UNSUBSCRIBE]]", "") personal_text_plain = text_plain.replace("[[UNSUBSCRIBE]]", "") if 'salutation' in receiver: salutation = receiver["salutation"] else: salutation = '' fullname = receiver['fullname'] if not fullname: try: fullname = enl.getFullname_fallback() except AttributeError: fullname = "Sir or Madam" outer['To'] = Header('<%s>' % safe_unicode(receiver['email'])) subscriber_salutation = safe_portal_encoding(salutation) + ' ' + safe_portal_encoding(fullname) personal_text = personal_text.replace("[[SUBSCRIBER_SALUTATION]]", str(subscriber_salutation)) personal_text_plain = personal_text_plain.replace("[[SUBSCRIBER_SALUTATION]]", str(subscriber_salutation)) outer['From'] = from_header outer['Subject'] = subject_header outer.epilogue = '' # Attach text part #text_part = MIMEText(personal_text_plain, "plain", charset) # Attach html part with images #html_part = MIMEText(personal_text, "html", charset) # Attach text part text_part = MIMEMultipart("related") text_part.attach(MIMEText(personal_text_plain, "plain", charset)) # Attach html part with images html_part = MIMEMultipart("related") html_text = MIMEText(personal_text, "html", charset) html_part.attach(html_text) # Add images to the message image_number = 0 reference_tool = getToolByName(self, 'reference_catalog') for image_url in image_urls: #XXX: we need to provide zope3 resource image too! try: image_url = urlparse(image_url)[2] if 'resolveuid' in image_url: urlparts = image_url.split('/')[1:] uuid = urlparts.pop(0) o = reference_tool.lookupObject(uuid) if o and urlparts: # get thumb o = o.restrictedTraverse(urlparts[0]) else: o = self.restrictedTraverse(urllib.unquote(image_url)) except Exception, e: log.error("Could not resolve the image \"%s\": %s" % (image_url, e)) else: if hasattr(o, "_data"): # file-based image = MIMEImage(o._data) elif hasattr(o, "data"): image = MIMEImage(o.data) # zodb-based else: image = MIMEImage(o.GET()) # z3 resource image image["Content-ID"] = "<image_%s>" % image_number image_number += 1 # attach images only to html parts html_part.attach(image) outer.attach(text_part) outer.attach(html_part) try: #MailHost.send(msg) MailHost.send(outer.as_string()) log.info("Send newsletter to \"%s\"" % receiver['email']) send_counter += 1 except AttributeError: # Plone3.3.x MailHost.send(msg.as_string()) log.info("Send newsletter to \"%s\"" % receiver['email']) send_counter += 1 except Exception, e: log.info("Sending newsletter to \"%s\" failed, with error \"%s\"!" % (receiver['email'], e)) send_error_counter += 1
def sendMailMessage(self, xMailMessage): COMMASPACE = ', ' if dbg: print >> sys.stderr, "PyMailSMPTService sendMailMessage" recipients = xMailMessage.getRecipients() sendermail = xMailMessage.SenderAddress sendername = xMailMessage.SenderName subject = xMailMessage.Subject ccrecipients = xMailMessage.getCcRecipients() bccrecipients = xMailMessage.getBccRecipients() if dbg: print >> sys.stderr, "PyMailSMPTService subject", subject print >> sys.stderr, "PyMailSMPTService from", sendername.encode( 'utf-8') print >> sys.stderr, "PyMailSMTPService from", sendermail print >> sys.stderr, "PyMailSMPTService send to", recipients attachments = xMailMessage.getAttachments() textmsg = Message() content = xMailMessage.Body flavors = content.getTransferDataFlavors() if dbg: print >> sys.stderr, "PyMailSMPTService flavors len", len(flavors) #Use first flavor that's sane for an email body for flavor in flavors: if flavor.MimeType.find('text/html') != -1 or flavor.MimeType.find( 'text/plain') != -1: if dbg: print >> sys.stderr, "PyMailSMPTService mimetype is", flavor.MimeType textbody = content.getTransferData(flavor) try: textbody = textbody.value except: pass textbody = textbody.encode('utf-8') if len(textbody): mimeEncoding = re.sub("charset=.*", "charset=UTF-8", flavor.MimeType) if mimeEncoding.find('charset=UTF-8') == -1: mimeEncoding = mimeEncoding + "; charset=UTF-8" textmsg['Content-Type'] = mimeEncoding textmsg['MIME-Version'] = '1.0' textmsg.set_payload(textbody) break if (len(attachments)): msg = MIMEMultipart() msg.epilogue = '' msg.attach(textmsg) else: msg = textmsg hdr = Header(sendername, 'utf-8') hdr.append('<' + sendermail + '>', 'us-ascii') msg['Subject'] = subject msg['From'] = hdr msg['To'] = COMMASPACE.join(recipients) if len(ccrecipients): msg['Cc'] = COMMASPACE.join(ccrecipients) if xMailMessage.ReplyToAddress != '': msg['Reply-To'] = xMailMessage.ReplyToAddress mailerstring = "OpenOffice.org 2.0 via Caolan's mailmerge component" try: ctx = uno.getComponentContext() aConfigProvider = ctx.ServiceManager.createInstance( "com.sun.star.configuration.ConfigurationProvider") prop = uno.createUnoStruct('com.sun.star.beans.PropertyValue') prop.Name = "nodepath" prop.Value = "/org.openoffice.Setup/Product" aSettings = aConfigProvider.createInstanceWithArguments( "com.sun.star.configuration.ConfigurationAccess", (prop, )) mailerstring = aSettings.getByName("ooName") + " " + \ aSettings.getByName("ooSetupVersion") + " via Caolan's mailmerge component" except: pass msg['X-Mailer'] = mailerstring msg['Date'] = formatdate(localtime=True) for attachment in attachments: content = attachment.Data flavors = content.getTransferDataFlavors() flavor = flavors[0] ctype = flavor.MimeType maintype, subtype = ctype.split('/', 1) msgattachment = MIMEBase(maintype, subtype) data = content.getTransferData(flavor) msgattachment.set_payload(data) Encoders.encode_base64(msgattachment) fname = attachment.ReadableName try: fname.encode('ascii') except: fname = ('utf-8', '', fname.encode('utf-8')) msgattachment.add_header('Content-Disposition', 'attachment', \ filename=fname) msg.attach(msgattachment) uniquer = {} for key in recipients: uniquer[key] = True if len(ccrecipients): for key in ccrecipients: uniquer[key] = True if len(bccrecipients): for key in bccrecipients: uniquer[key] = True truerecipients = uniquer.keys() if dbg: print >> sys.stderr, "PyMailSMPTService recipients are", truerecipients self.server.sendmail(sendermail, truerecipients, msg.as_string())
def send(self, recipients=[]): """Sends the newsletter. An optional list of dicts (keys=fullname|mail) can be passed in for sending a newsletter out addresses != subscribers. """ # preparations request = self.REQUEST # get hold of the parent Newsletter object# enl = self.getNewsletter() # get sender name sender_name = request.get("sender_name", "") if sender_name == "": sender_name = enl.getSenderName() # don't use Header() with a str and a charset arg, even if it is correct # this would generate a encoded header and mail server may not support utf-8 encoded header from_header = Header(safe_unicode(sender_name)) # get sender e-mail sender_email = request.get("sender_email", "") if sender_email == "": sender_email = enl.getSenderEmail() from_header.append('<%s>' % safe_unicode(sender_email)) # get subject subject = request.get("subject", "") if subject == "": subject = self.Title() subject_header = Header(safe_unicode(subject)) # determine MailHost first (build-in vs. external) deliveryServiceName = enl.getDeliveryService() if deliveryServiceName == 'mailhost': MailHost = getToolByName(enl, 'MailHost') else: MailHost = getUtility(IMailHost, name=deliveryServiceName) log.info('Using mail delivery service "%r"' % MailHost) send_counter = 0 send_error_counter = 0 receivers = self._send_recipients(recipients) output_html = self._render_output_html() rendered_newsletter = self._exchange_relative_urls(output_html) text = rendered_newsletter['html'] text_plain = rendered_newsletter['plain'] image_urls = rendered_newsletter['images'] props = getToolByName(self, "portal_properties").site_properties charset = props.getProperty("default_charset") portal = getSite() for receiver in receivers: # create multipart mail outer = MIMEMultipart('alternative') if hasattr(request, "test"): outer['To'] = Header('<%s>' % safe_unicode(receiver['email'])) fullname = receiver['fullname'] salutation = receiver['salutation'] personal_text = text.replace("[[SUBSCRIBER_SALUTATION]]", "") personal_text_plain = text_plain.replace( "[[SUBSCRIBER_SALUTATION]]", "") personal_text = text.replace("[[UNSUBSCRIBE]]", "") personal_text_plain = text_plain.replace("[[UNSUBSCRIBE]]", "") else: if 'uid' in receiver: try: unsubscribe_text = enl.getUnsubscribe_string() except AttributeError: unsubscribe_text = "Click here to unsubscribe" unsubscribe_link = enl.absolute_url( ) + "/unsubscribe?subscriber=" + receiver['uid'] personal_text = text.replace( "[[UNSUBSCRIBE]]", """<a href="%s">%s.</a>""" % (unsubscribe_link, unsubscribe_text)) personal_text_plain = text_plain.replace( "[[UNSUBSCRIBE]]", """\n%s: %s""" % (unsubscribe_text, unsubscribe_link)) else: personal_text = text.replace("[[UNSUBSCRIBE]]", "") personal_text_plain = text_plain.replace( "[[UNSUBSCRIBE]]", "") if 'salutation' in receiver: salutation = receiver["salutation"] else: salutation = '' fullname = receiver['fullname'] if not fullname: try: fullname = enl.getFullname_fallback() except AttributeError: fullname = "Sir or Madam" outer['To'] = Header('<%s>' % safe_unicode(receiver['email'])) subscriber_salutation = safe_portal_encoding( salutation) + ' ' + safe_portal_encoding(fullname) personal_text = personal_text.replace("[[SUBSCRIBER_SALUTATION]]", str(subscriber_salutation)) personal_text_plain = personal_text_plain.replace( "[[SUBSCRIBER_SALUTATION]]", str(subscriber_salutation)) outer['From'] = from_header outer['Subject'] = subject_header outer.epilogue = '' # Attach text part text_part = MIMEText(personal_text_plain, "plain", charset) # Attach html part with images html_part = MIMEMultipart("related") html_text = MIMEText(personal_text, "html", charset) html_part.attach(html_text) # Add images to the message image_number = 0 reference_tool = getToolByName(self, 'reference_catalog') for image_url in image_urls: try: image_url = urlparse(image_url)[2] if 'resolveuid' in image_url: urlparts = image_url.split('/')[1:] uuid = urlparts.pop(0) o = reference_tool.lookupObject(uuid) if o and urlparts: # get thumb o = o.restrictedTraverse(urlparts[0]) elif "@@images" in image_url: image_url_base, image_scale_params = image_url.split( "@@images") image_scale = image_scale_params.split("/")[-1] scales = self.restrictedTraverse( urllib.unquote( image_url_base.strip('/') + '/@@images')) o = scales.scale('image', scale=image_scale) else: o = self.restrictedTraverse(urllib.unquote(image_url)) except Exception, e: log.error("Could not resolve the image \"%s\": %s" % (image_url, e)) else: if hasattr(o, "_data"): # file-based image = MIMEImage(o._data) elif hasattr(o, "data"): image = MIMEImage(o.data) # zodb-based elif hasattr(o, "GET"): image = MIMEImage(o.GET()) # z3 resource image else: log.error( "Could not get the image data from image object!") image["Content-ID"] = "<image_%s>" % image_number image_number += 1 # attach images only to html parts html_part.attach(image) outer.attach(text_part) outer.attach(html_part) try: #MailHost.send(msg) MailHost.send(outer.as_string()) log.info("Send newsletter to \"%s\"" % receiver['email']) send_counter += 1 except AttributeError: # Plone3.3.x MailHost.send(msg.as_string()) log.info("Send newsletter to \"%s\"" % receiver['email']) send_counter += 1 except Exception, e: log.info( "Sending newsletter to \"%s\" failed, with error \"%s\"!" % (receiver['email'], e)) send_error_counter += 1
def sendNewEntryNotifications(con, lang, project, category, id, files) : cursor = con.cursor() # list of recipients query = """ SELECT mail FROM Client WHERE subscription = True AND allowed = True AND project = %s """ cursor.execute(query, (projectID(con, project), )) recipients = [] for row in cursor.fetchall() : recipients.append(row[0]) # content of the message query = """ SELECT Entry.relativeID, Entry.name, Entry.description, Entry.status, Entry.severity, Client.login, Client.mail, extract( day FROM Entry.creationDate), extract( month FROM Entry.creationDate), extract( year FROM Entry.creationDate) FROM Entry INNER JOIN Client ON Entry.creator = Client.id WHERE Entry.id = %s""" cursor.execute(query, (id, )) row = cursor.fetchone() relativeID = int(row[0]) title = row[1] description = unFormatText(row[2]) status = int(row[3]) severity = int(row[4]) creator = row[5] creatorMail = row[6] day = row[7] month = row[8] year = row[9] # creating Message-ID for this entry, and therefore the entry-point for the thread messageID = make_msgid() query = """ UPDATE Entry SET lastMessageID = %s WHERE id = %s""" cursor.execute(query, (messageID,id)) con.commit() mytemplate = Template(filename='templates/'+lang+'/mails/newEntry.mail', output_encoding='utf-8', default_filters=['decode.utf8'], input_encoding='utf-8') text = mytemplate.render( creator = creator, title = title, description = description, files = files, status = status, severity = severity ) category = category[0].upper()+category[1:].lower() h = Header() h.append(category, 'utf-8') h.append(u'#'+str(relativeID)+u':', 'utf-8') h.append(title, 'utf-8') mail = { 'From' : creator + ' <' + creatorMail + '>', 'To' : recipients, 'Subject' : h, 'Reply-To' : project + '@projects.naphtaline.net', 'Message-ID' : messageID, 'In-Reply-To' : '', 'text' : text, 'files' : files, } send_mail(mail)
def sendNewCommentNotifications(con, lang, project, category, id, content, files) : cursor = con.cursor() # creating the list of recipients query = """ SELECT mail FROM Client WHERE subscription = True AND allowed = True AND project = %s """ cursor.execute(query, (projectID(con, project), )) recipients = [] for row in cursor.fetchall() : recipients.append(row[0]) # creating the message query = """ SELECT Client.login, Client.mail, Comment.entry, extract( day FROM Comment.creationDate), extract( month FROM Comment.creationDate), extract( year FROM Comment.creationDate), Entry.name, Entry.relativeID, Entry.lastMessageID FROM Comment INNER JOIN Entry ON Comment.entry = Entry.id INNER JOIN Client ON Comment.author = Client.id WHERE Comment.id = %s""" cursor.execute(query, (id, )) row = cursor.fetchone() author = row[0] authorMail = row[1] idEntry = int(row[2]) day = int(row[3]) month = int(row[4]) year = int(row[5]) title = row[6] relativeID = int(row[7]) inReplyTo = row[8] # updating Message-ID messageID = make_msgid() query = """ UPDATE Entry SET lastMessageID = %s WHERE id = %s""" cursor.execute(query, (messageID,id)) con.commit() mytemplate = Template(filename='templates/'+lang+'/mails/newcomment.mail', output_encoding='utf-8', default_filters=['decode.utf8'], input_encoding='utf-8') text = mytemplate.render( author = author, comment = content, files = files ) category = category[0].upper()+category[1:].lower() h = Header() h.append(u'Re:', 'utf-8') h.append(category, 'utf-8') h.append(u'#'+str(relativeID)+u':', 'utf-8') h.append(title, 'utf-8') mail = { 'From' : author + ' <' + authorMail + '>', 'To' : recipients, 'Subject' : h, 'Reply-To' : project + '@projects.naphtaline.net', 'Message-ID' : messageID, 'In-Reply-To' : inReplyTo, 'text' : text, 'files' : files, } send_mail(mail)
def sendMailMessage(self, xMailMessage): COMMASPACE = ', ' if dbg: print >> sys.stderr, "PyMailSMPTService sendMailMessage" recipients = xMailMessage.getRecipients() sendermail = xMailMessage.SenderAddress sendername = xMailMessage.SenderName subject = xMailMessage.Subject ccrecipients = xMailMessage.getCcRecipients() bccrecipients = xMailMessage.getBccRecipients() if dbg: print >> sys.stderr, "PyMailSMPTService subject", subject print >> sys.stderr, "PyMailSMPTService from", sendername.encode( 'utf-8') print >> sys.stderr, "PyMailSMTPService from", sendermail print >> sys.stderr, "PyMailSMPTService send to", recipients attachments = xMailMessage.getAttachments() content = xMailMessage.Body flavors = content.getTransferDataFlavors() flavor = flavors[0] if dbg: print >> sys.stderr, "PyMailSMPTService mimetype is", flavor.MimeType textbody = content.getTransferData(flavor) textmsg = Message() mimeEncoding = re.sub("charset=.*", "charset=UTF-8", flavor.MimeType) textmsg['Content-Type'] = mimeEncoding textmsg['MIME-Version'] = '1.0' textmsg.set_payload(textbody.encode('utf-8')) if (len(attachments)): msg = MIMEMultipart() msg.epilogue = '' msg.attach(textmsg) else: msg = textmsg hdr = Header(sendername, 'utf-8') hdr.append('<' + sendermail + '>', 'us-ascii') msg['Subject'] = subject msg['From'] = hdr msg['To'] = COMMASPACE.join(recipients) if len(ccrecipients): msg['Cc'] = COMMASPACE.join(ccrecipients) if xMailMessage.ReplyToAddress != '': msg['Reply-To'] = xMailMessage.ReplyToAddress msg['X-Mailer'] = "OpenOffice.org 2.0 via Caolan's mailmerge component" msg['Date'] = formatdate(localtime=True) for attachment in attachments: content = attachment.Data flavors = content.getTransferDataFlavors() flavor = flavors[0] ctype = flavor.MimeType maintype, subtype = ctype.split('/', 1) msgattachment = MIMEBase(maintype, subtype) data = content.getTransferData(flavor) msgattachment.set_payload(data) Encoders.encode_base64(msgattachment) msgattachment.add_header('Content-Disposition', 'attachment', \ filename=attachment.ReadableName) msg.attach(msgattachment) uniquer = {} for key in recipients: uniquer[key] = True if len(ccrecipients): for key in ccrecipients: uniquer[key] = True if len(bccrecipients): for key in bccrecipients: uniquer[key] = True truerecipients = uniquer.keys() if dbg: print >> sys.stderr, "PyMailSMPTService recipients are", truerecipients self.server.sendmail(sendermail, truerecipients, msg.as_string())