def sendMail(db, recipients, title, html_message, sender=None, cc=None, bcc=None, immediate=False): """Send an email """ host = getToolByName(db, 'MailHost') plone_tools = getToolByName(db, 'plone_utils') message = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n' message = message + "<html>" message = message + html_message message = message + "</html>" if sender is None: sender = db.getCurrentUser().getProperty("email") mail_message = message_from_string(asUnicode(message).encode('utf-8')) mail_message.set_charset('utf-8') mail_message.set_type("text/html") if cc: mail_message['CC']= Header(cc) if bcc: mail_message['BCC']= Header(bcc) if HAS_PLONE40: host.send(mail_message, recipients, sender, asUnicode(title).encode('utf-8'), msg_type='text/html', immediate=immediate) else: host.secureSend(message, recipients, sender, subject=title, subtype='html', charset='utf-8')
def _basic_message(self, from_address, to_addresses, subject): """Create the basic Message using the right Header info. This creates an email Message with no payload. :param from_address: The Unicode from address. :param to_addresses: A list of Unicode destination addresses. :param subject: A Unicode subject for the email. """ # It would be nice to use a single part if we only had one, but we # would have to know ahead of time how many parts we needed. # So instead, just default to multipart. msg = MIMEMultipart() # Header() does a good job of doing the proper encoding. However it # confuses my SMTP server because it doesn't decode the strings. So it # is better to send the addresses as: # =?utf-8?q?username?= <*****@*****.**> # Which is how Thunderbird does it from_user, from_email = self._split_address(from_address) msg['From'] = '%s <%s>' % (Header(unicode(from_user)), from_email) msg['User-Agent'] = 'bzr/%s' % _bzrlib_version to_emails = [] to_header = [] for addr in to_addresses: to_user, to_email = self._split_address(addr) to_emails.append(to_email) to_header.append('%s <%s>' % (Header(unicode(to_user)), to_email)) msg['To'] = ', '.join(to_header) msg['Subject'] = Header(subject) return msg, from_email, to_emails
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 __setitem__(self, name, val): "Forbids multi-line headers, to prevent header injection." if "\n" in val or "\r" in val: raise BadHeaderError, "Header values can't contain newlines (got %r for header %r)" % (val, name) if name == "Subject": val = Header(val.encode(settings.MAIL_CHARSET, "replace"), settings.MAIL_CHARSET) MIMEText.__setitem__(self, name, val)
def sendMail(env, fro, to, subject, text, files=[], bcc=None): assert type(to) == list toz = [] if fro.find("<") > 0: fro = str(Header(fro[:fro.find("<")], 'utf-8')) + fro[fro.find("<"):] for a in to: if a.find("<") > 0: a = str(Header(a[:a.find("<")], 'utf-8')) + a[a.find("<"):] toz.append(a) msg = MIMEMultipart() msgtext = MIMEText(text, "plain", "utf-8") msg.attach(msgtext) msg['From'] = fro if bcc != None: msg['Bcc'] = bcc msg['To'] = COMMASPACE.join(toz) msg['Date'] = formatdate(localtime=True) msg['Subject'] = Header(subject, 'utf-8') for file in files: part = MIMEBase('application', "octet-stream") part.set_payload(open(file, "rb").read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file)) msg.attach(part) p = os.popen( """%s -t -f"%s" """ % (env.conf.sendmail_location, env.conf.sendmail_from), "w") p.write(msg.as_string()) status = p.close()
def mail(smtp, fromaddr, toaddrs, replytoaddr, subject, body): from email.Header import Header from email.MIMEText import MIMEText msg = MIMEText(body, 'plain') from email.Utils import make_msgid msg['Message-Id'] = make_msgid() msg['Subject'] = Header(subject) msg['From'] = Header(fromaddr) from email.Utils import formatdate msg['Date'] = formatdate() if len(replytoaddr): msg['ReplyTo'] = Header(replytoaddr) if isinstance(toaddrs, basestring): toaddrs = [toaddrs] to = '' for t in toaddrs: if len(to): to += ', ' to += t msg['To'] = Header(to) try: r = smtp.sendmail(fromaddr, toaddrs, msg.as_string(False)) for (name, errormsg) in r.iteritems(): print name, ':', errormsg except smtplib.SMTPRecipientsRefused, obj: print 'ERROR: SMTPRecipientsRefused' for (addr, errormsg) in obj.recipients.iteritems(): print addr, ':', errormsg
def send_email(sender, recipient, subject, body): header_charset = 'ISO-8859-1' for body_charset in 'US-ASCII', 'ISO-8859-1', 'UTF-8': try: body.encode(body_charset) except UnicodeError: pass else: break sender_name, sender_addr = parseaddr(sender) recipient_name, recipient_addr = parseaddr(recipient) sender_name = str(Header(unicode(sender_name), header_charset)) recipient_name = str(Header(unicode(recipient_name), header_charset)) sender_addr = sender_addr.encode('ascii') recipient_addr = recipient_addr.encode('ascii') msg = MIMEText(body.encode(body_charset), 'plain', body_charset) msg['From'] = formataddr((sender_name, sender_addr)) msg['To'] = formataddr((recipient_name, recipient_addr)) msg['Subject'] = Header(unicode(subject), header_charset) smtp = SMTP("localhost") smtp.sendmail(sender, recipient, msg.as_string()) smtp.quit()
def sendmail(to, subject, body, sender=None, html=None, sender_name=None): sender_name = sender_name or SMTP.SENDER_NAME sender = sender or SMTP.SENDER # print to, '#!!!!!!!!!!!!!!!!!!' if html: text_subtype = 'html' msg = MIMEText(html, text_subtype, 'utf-8') else: text_subtype = 'plain' msg = MIMEText(body, text_subtype, 'utf-8') # print SMTP msg['Subject'] = Header(subject, 'utf-8') if sender_name is None: sender_name = sender.split('@', 1)[0] sender_name = str(Header(sender_name, 'utf-8')) msg['From'] = formataddr((sender_name, sender)) msg['To'] = to #msg['Bcc'] = MAIL_ARCHIVE smtp = smtplib.SMTP(SMTP.HOST) #smtp.set_debuglevel(True) print SMTP smtp.login(SMTP.USERNAME, SMTP.PASSWORD) smtp.sendmail(sender, to, msg.as_string())
def encode_addresses(addresses, header_name = None): """ Unicode address headers are automatically encoded by email.Header, but not correctly. The correct way is to put the textual name inside quotes and the address inside brackets: To: "=?utf-8?b?encoded" <recipient@domain> Each address in addrs may be a tuple of (name, address) or just an address. Returns a tuple of (header, addrlist) representing the encoded header text and the list of plain text addresses. """ header = [] addrs = [] for addr in addresses: if isinstance(addr, tuple): (name, addr) = addr try: name = name.encode('ascii') header.append('%s <%s>' % (name, addr)) except: h = Header(name, charset = "utf-8", header_name = header_name) header.append('"%s" <%s>' % (h.encode(), addr)) else: header.append(addr) addrs.append(addr) return (", ".join(header), addrs)
def sendmail(self, mailto, topic, content): if not mailto or not topic: return #print 'mailto',mailto,topic,content topic = topic.replace("\n", "<br>") content = content.replace("\n", "<br>") mail = MIMEText(content, 'html', 'utf-8') mail['Subject'] = Header("[Notify]:%s" % topic, 'utf-8') mail['From'] = Header( "%s <%s>" % (self.fromaddr[:self.fromaddr.find('@')], self.fromaddr), 'utf-8') mail['To'] = mailto mail["Accept-Language"] = "zh-CN" mail["Accept-Charset"] = "ISO-8859-1,utf-8" if '@toughradius.org' in self.fromaddr: mail['X-Mailgun-SFlag'] = 'yes' mail['X-Mailgun-SScore'] = 'yes' try: serv = smtplib.SMTP() # serv.set_debuglevel(True) serv.connect(self.server) if self.pwd and self.pwd not in ('no', 'none', 'anonymous'): serv.login(self.user, self.pwd) serv.sendmail(self.fromaddr, [mailto], mail.as_string()) serv.quit() print "Successfully sent email to %s" % mailto except Exception, e: print "Error: unable to send email %s" % str(e)
def sendEmail(server, port, login, password, sender, recipient, subject, body): """Send e-mail function with unicode support""" headerCharset = "ISO-8859-1" for bodyCharset in ("US-ASCII", "ISO-8859-1", "UTF-8"): try: body.encode(bodyCharset) except UnicodeError: pass else: break senderName, senderAddr = parseaddr(sender) recipientName, recipientAddr = parseaddr(recipient) senderName = str(Header(unicode(senderName), headerCharset)) recipientName = str(Header(unicode(recipientName), headerCharset)) senderAddr = senderAddr.encode("ascii") recipientAddr = recipientAddr.encode("ascii") msg = MIMEText(body.encode(bodyCharset), "html", bodyCharset) msg["From"] = formataddr((senderName, senderAddr)) msg["To"] = formataddr((recipientName, recipientAddr)) msg["Subject"] = Header(unicode(subject), headerCharset) server = smtplib.SMTP(server, port) server.login(login, password) server.sendmail(sender, recipient, msg.as_string()) server.quit()
def send_email(body, subject, recipient): import smtplib from smtplib import SMTP from email.MIMEText import MIMEText from email.Header import Header from email.Utils import parseaddr, formataddr """Send an email. All arguments should be Unicode strings (plain ASCII works as well). Only the real name part of sender and recipient addresses may contain non-ASCII characters. The email will be properly MIME encoded and delivered though SMTP to localhost port 25. This is easy to change if you want something different. The charset of the email will be the first one out of US-ASCII, ISO-8859-1 and UTF-8 that can represent all the characters occurring in the email. """ sender = '*****@*****.**' # Header class is smart enough to try US-ASCII, then the charset we # provide, then fall back to UTF-8. header_charset = 'ISO-8859-1' # We must choose the body charset manually for body_charset in 'US-ASCII', 'ISO-8859-1', 'UTF-8': try: body.encode(body_charset) except UnicodeError: pass else: break # Split real name (which is optional) and email address parts sender_name, sender_addr = parseaddr(sender) recipient_name, recipient_addr = parseaddr(recipient) # We must always pass Unicode strings to Header, otherwise it will # use RFC 2047 encoding even on plain ASCII strings. sender_name = str(Header(unicode(sender_name), header_charset)) recipient_name = str(Header(unicode(recipient_name), header_charset)) # Make sure email addresses do not contain non-ASCII characters sender_addr = sender_addr.encode('ascii') recipient_addr = recipient_addr.encode('ascii') # Create the message ('plain' stands for Content-Type: text/plain) msg = MIMEText(body.encode(body_charset), 'html', body_charset) msg['From'] = formataddr((sender_name, sender_addr)) msg['To'] = formataddr((recipient_name, recipient_addr)) msg['Subject'] = Header(unicode(subject), header_charset) # Create server object with SSL option server = smtplib.SMTP_SSL('smtp.{{service provider}}.com', 465) # Perform operations via server server.login(sender, '{pass}') server.sendmail(sender, [recipient], msg.as_string()) server.quit()
def secureSend(self, message, mto, mfrom, subject='[No Subject]', mcc=None, mbcc=None, subtype='plain', charset='us-ascii', debug=False, **kwargs): """Deprecated method attempting to maintain backwards compatibility for code depending on the SecureMailHost API.""" # Convert all our address list inputs mfrom = email_list_to_string(mfrom, charset) mto = email_list_to_string(mto, charset) mcc = email_list_to_string(mcc, charset) mbcc = email_list_to_string(mbcc, charset) # Convert to a message for adding headers. If it's already a # message, copy it to be safe. if not isinstance(message, Message): if isinstance(message, unicode): message.encode(charset) message = MIMEText(message, subtype, charset) else: message = deepcopy(message) # Add extra headers _addHeaders(message, Subject=Header(subject, charset), To=mto, Cc=mcc, From=mfrom, **dict((k, Header(v, charset)) for k, v in kwargs.iteritems())) all_recipients = [formataddr(pair) for pair in getaddresses((mto, mcc, mbcc))] # Convert message back to string for sending self._send(mfrom, all_recipients, message.as_string(), immediate=True)
def encodeMailHeaders(self, message, encoding): """Return ``message`` with correctly encoded headers. The following headers are encoded: ``From``, ``Reply-to``, ``Sender``, ``Cc`` and ``Subject``. """ mout = [] lines = message.split('\n') for line_i in range(0, len(lines)): line = lines[line_i] if not line: break ## End of headers block. header = line[:line.find(':')] if header.lower() in ('from', 'reply-to', 'sender', 'cc', 'subject'): value = line[len(header) + 1:].lstrip() if header.lower() in ('from', 'reply-to', 'sender', 'cc'): ## We must not encode e-mail addresses. addresses = EMAIL_ADDRESS_IN_HEADER_REGEXP.findall(value) if addresses: addresses = [(Header(s, encoding).encode(), addr) \ for s, addr in addresses] value = ', '.join(['%s <%s>' % (s, addr) \ for (s, addr) in addresses]) else: value = Header(value, encoding).encode() mout.append('%s: %s' % (header, value)) continue mout.append(line) mout.extend(lines[line_i:]) return '\n'.join(mout)
def send_mail(recipient, subject, body, body_html, file, encoding='utf-8'): session = None msg = MIMEMultipart() msg['Subject'] = Header(subject, encoding) msg['From'] = Header(u'"{0}" <{1}>'.format(SENDER_NAME, SENDER_EMAIL), encoding) msg['To'] = recipient msg['Date'] = formatdate() msg.attach(MIMEText(body, 'plain', encoding)) msg.attach(MIMEText(body_html, 'html', encoding)) if file != "": att = MIMEText(open(file, 'rb').read(), 'base64', 'utf-8') att["Content-Disposition"] = 'attachment; filename=' + file msg.attach(att) else: pass try: if SMTP_SSL_TYPE == 'SMTP_SSL': session = smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) else: session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT) if SMTP_SSL_TYPE == 'SMTP_TLS': session.ehlo() session.starttls() session.ehlo() session.login(SMTP_USERNAME, SMTP_PASSWORD) session.sendmail(SENDER_EMAIL, recipient, msg.as_string()) except Exception as e: raise e finally: if session: session.quit()
def forbid_multi_line_headers(name, val, encoding): """Forbids multi-line headers, to prevent header injection.""" encoding = encoding or settings.DEFAULT_CHARSET val = force_unicode(val) if '\n' in val or '\r' in val: raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name)) try: val = val.encode('ascii') except UnicodeEncodeError: if name.lower() in ('to', 'from', 'cc'): result = [] for nm, addr in getaddresses((val,)): nm = str(Header(nm.encode(encoding), encoding)) try: addr = addr.encode('ascii') except UnicodeEncodeError: # IDN addr = str(Header(addr.encode(encoding), encoding)) result.append(formataddr((nm, addr))) val = ', '.join(result) else: val = Header(val.encode(encoding), encoding) else: if name.lower() == 'subject': val = Header(val) return name, val
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 send(self, recipients=None, subject=None, body=None, sender_from=None, sender_from_name=None, encoding='ISO-2022-JP', with_normalize=False): if isinstance(body, list) or isinstance(body, tuple): body = ''.join(body) if with_normalize: body = normalize("NFKC", body) body = body.encode(encoding, errors='replace') msg = MIMEText(body, 'plain', encoding) if sender_from is None: sender_from = self.config['MAIL_SENDER_FROM'] if sender_from_name is not None: msg['From'] = str(Header('%s' % sender_from_name, encoding)) + ' <%s>' % sender_from else: msg['From'] = sender_from if isinstance(recipients, list) or isinstance(recipients, tuple): msg['To'] = ','.join(recipients) else: msg['To'] = recipients msg['Subject'] = Header(subject, encoding) msg['Date'] = formatdate() if self.config['MAIL_METHOD'] == 'smtp': return self.send_smtp(sender_from, recipients, msg) elif self.config['MAIL_METHOD'] == 'ses': return self.send_ses(sender_from, recipients, msg.as_string()) else: raise Exception('Unknown sendmail Method.')
def create_message(to_addr, subject, body, encoding='ISO-2022-JP'): body += u"\n\n※現在駒ぷりシステム試験中です。この投票は集計されません。" msg = MIMEText(body.encode(encoding, 'replace'), 'plain', encoding) msg['Subject'] = Header(subject, encoding) msg['From'] = '%s <%s>' % (str(Header(FROM_NAME, encoding)), FROM_ADDR) msg['To'] = to_addr msg['Date'] = formatdate(localtime=True) return msg
def query(): today = datetime.date.today() yesterday = today - datetime.timedelta(days=1) user_num_sql="SELECT count(*) FROM user_member where create_time<='" +str(today)+" 20:00:00';" phone_num_sql="SELECT count(*) FROM user_member WHERE USE_9I_PHONE=1 AND TYPE=0 AND create_time<='" +str(today)+" 20:00:00';" new_user_num_sql="SELECT count(*) FROM user_member WHERE create_time<='"+str(today)+" 20:00:00' AND create_time>='"+str(yesterday)+" 20:00:00';" new_phone_num_sql="SELECT count(*) FROM user_member WHERE USE_9I_PHONE=1 AND TYPE=0 AND create_time<='"+str(today)+" 20:00:00' AND create_time>='"+str(yesterday)+" 20:00:00';" #print user_num_sql #print phone_num_sql #print new_user_num_sql #print new_phone_num_sql conn=MySQLdb.connect(host="xxxxxxxxxxx.mysql.rds.aliyuncs.com",user='******',passwd='xxxxxxxxxx',db='xxxxxx',charset="utf8") cur = conn.cursor() cur.execute(user_num_sql) user_num_data = cur.fetchone() cur.execute(phone_num_sql) phone_num_data = cur.fetchone() cur.execute(new_user_num_sql) new_user_num_data = cur.fetchone() cur.execute(new_phone_num_sql) new_phone_num_data = cur.fetchone() conn.close() user_num=user_num_data[0] #print user_num phone_num=phone_num_data[0] new_user=new_user_num_data[0] new_phone=new_phone_num_data[0] mail_body='统计区间:'+str(yesterday)+'晚20:00-'+str(today)+"晚20:00 \n \ 总数: \n \ 九爱用户:"+str(user_num)+' 九爱手机用户:'+str(phone_num)+" \n \ 新增: \n \ 用户数:"+str(new_user)+' 九爱手机用户:'+str(new_phone) smtp = smtplib.SMTP_SSL(mail_server,mail_port) #smtp.set_debuglevel(1) smtp.login(mail_user, mail_passwd) subject = mail_subjet body = mail_body encoding = 'utf-8' msg = MIMEText(body.encode(encoding),'plain',encoding) msg['Subject'] = Header(subject,encoding) msg['From'] = Header('周盛强', 'utf-8') msg['To'] = Header('alen,稻荷', 'utf-8') smtp.sendmail(mail_user,mail_to,msg.as_string() ) smtp.quit()
def send_button_handler(self, action): """Create and Send the Email.""" data, errors = self.extractData() if len(errors) == 0: mh = getToolByName(self.context, 'MailHost') userid = self.context.portal_membership.getAuthenticatedMember() userid = userid.getId() intern_receiver = [] for receiver in data.get('intern_receiver', []): # cut away the username intern_receiver.append(receiver.split(':')[0]) extern_receiver = data.get('extern_receiver') or [] addresses = intern_receiver + extern_receiver # create the mail msg = self.create_mail( data.get('message'), data.get('documents'), only_links=data.get('documents_as_links')) msg['Subject'] = Header(data.get('subject'), CHARSET) user = ogds_service().fetch_user(userid) sender_address = user and user.email if not sender_address: portal = self.context.portal_url.getPortalObject() sender_address = portal.email_from_address msg['From'] = make_addr_header( user.label(), sender_address, CHARSET) header_to = Header(','.join(addresses), CHARSET) msg['To'] = header_to # send it mfrom = u'{} <{}>'.format( user.label(), sender_address).encode(CHARSET) mh.send(msg, mfrom=mfrom, mto=','.join(addresses)) # Store a copy of the sent mail in dossier if (data.get('file_copy_in_dossier', False) and self._allow_save_file_copy_in_context()): self.file_sent_mail_in_dossier(msg) # let the user know that the mail was sent info = _(u'info_mail_sent', 'E-mail has been sent.') notify(DocumentSent( self.context, userid, header_to, data.get('subject'), data.get('message'), data.get('documents'))) IStatusMessage(self.request).addStatusMessage(info, type='info') # and redirect to default view / tab return self.request.RESPONSE.redirect( get_containing_document_tab_url(data.get('documents')[0]))
def send_email(sender, recipient, subject, body, content_type='plain'): """Send an email. All arguments should be Unicode strings (plain ASCII works as well). Only the real name part of sender and recipient addresses may contain non-ASCII characters. The email will be properly MIME encoded and delivered though SMTP to localhost port 25. This is easy to change if you want something different. The charset of the email will be the first one out of US-ASCII, ISO-8859-1 and UTF-8 that can represent all the characters occurring in the email. """ # Header class is smart enough to try US-ASCII, then the charset we # provide, then fall back to UTF-8. header_charset = 'ISO-8859-1' # We must choose the body charset manually for body_charset in 'US-ASCII', 'ISO-8859-1', 'UTF-8': try: body.encode(body_charset) except UnicodeError: pass else: break # Split real name (which is optional) and email address parts sender_name, sender_addr = parseaddr(sender) recipient_name, recipient_addr = parseaddr(recipient) # We must always pass Unicode strings to Header, otherwise it will # use RFC 2047 encoding even on plain ASCII strings. sender_name = str(Header(unicode(sender_name), header_charset)) recipient_name = str(Header(unicode(recipient_name), header_charset)) # Make sure email addresses do not contain non-ASCII characters sender_addr = sender_addr.encode('ascii') recipient_addr = recipient_addr.encode('ascii') # Create the message ('plain' stands for Content-Type: text/plain) msg = MIMEText(body.encode(body_charset), content_type, body_charset) msg['From'] = formataddr((sender_name, sender_addr)) msg['To'] = formataddr((recipient_name, recipient_addr)) msg['Subject'] = Header(unicode(subject), header_charset) try: # Send the message via SMTP to localhost:25 smtp = SMTP("127.0.0.1") smtp.ehlo() smtp.sendmail(sender_addr, recipient, msg.as_string()) smtp.quit() except Exception as ex: pass
def buildmail(charset, fromaddr, toaddrs, subject, message): m_body = message.encode(charset, 'replace') m_subject = subject m_subject = Header(m_subject.encode(charset, 'replace'), charset) m_from = fromaddr m_to = ', '.join(toaddrs) message = MIMEText(m_body, 'plain', charset) message['Subject'] = m_subject message['From'] = m_from message['To'] = m_to return message
def discussion_notify(comment_on_object, variables = {}): portal = comment_on_object.portal_url.getPortalObject() send_from_address = portal.portal_properties.email_from_address send_from_name = portal.portal_properties.email_from_name host = portal.plone_utils.getMailHost() encoding = portal.plone_utils.getSiteEncoding() envelope_from = send_from_address mt = portal.portal_membership if IDiscussionResponse.providedBy(comment_on_object): owner = comment_on_object.Creator() if owner: member = mt.getMemberById(owner) if member: send_to_address = member.getProperty('email') if send_to_address: message_body = portal.discussion_reply_notify_template(portal, comment_on_object=comment_on_object, send_from_address=send_from_address, send_from_name=send_from_name, send_to_address=send_to_address, **variables) subject = "New comment on " + comment_on_object.title_or_id() message = message_from_string(message_body.encode(encoding)) message.set_charset(encoding) message['From'] = Header(envelope_from) if PLONE4: host.send(message, send_to_address, envelope_from, subject=subject, charset=encoding, msg_type='text/plain') else: host.secureSend(message_body, send_to_address, envelope_from, subject=subject, subtype='plain', charset=encoding, debug=False, From=envelope_from) parents = comment_on_object.parentsInThread() if not parents: return comment_on_object = parents[0] owner = comment_on_object.Creator() if owner: member = mt.getMemberById(owner) if member: send_to_address = member.getProperty('email') if send_to_address: message_body = portal.discussion_notify_template(portal, comment_on_object=comment_on_object, send_from_address=send_from_address, send_from_name=send_from_name, send_to_address=send_to_address, **variables) subject = "New comment on " + comment_on_object.title_or_id() message = message_from_string(message_body.encode(encoding)) message.set_charset(encoding) message['From'] = Header(envelope_from) if PLONE4: host.send(message, send_to_address, envelope_from, subject=subject, charset=encoding, msg_type='text/plain') else: host.secureSend(message_body, send_to_address, envelope_from, subject=subject, subtype='plain', charset=encoding, debug=False, From=envelope_from)
def encode_if_needed(text, charset, encoding='q'): needed = False if notascii.search(text): # Fall back on something vaguely sensible if there are high chars # and the encoding is us-ascii if charset == 'us-ascii': charset = 'iso-8859-15' return Header(text, charset) else: return Header(text, 'us-ascii')
def add_header(self,key,value,immediate=False): """adds a header to the message. by default, headers will added when re-injecting the message back to postfix if you set immediate=True the message source will be replaced immediately. Only set this to true if a header must be visible to later plugins (eg. for spamassassin rules), otherwise, leave as False which is faster. """ if immediate: val=unicode(value,errors='ignore') # is ignore the right thing to do here? hdr=Header(val, header_name=key, continuation_ws=' ') hdrline="%s: %s\n"%(key,hdr.encode()) src=hdrline+self.getSource() self.set_source(src) else: self.addheaders[key]=value
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 send_button_handler(self, action): """ create and Send the Email """ data, errors = self.extractData() if len(errors) == 0: mh = getToolByName(self.context, 'MailHost') contact_info = getUtility(IContactInformation) userid = self.context.portal_membership.getAuthenticatedMember() userid = userid.getId() intern_receiver = [] for receiver in data.get('intern_receiver', []): # cut away the username intern_receiver.append(receiver.split(':')[0]) extern_receiver = data.get('extern_receiver') or [] addresses = intern_receiver + extern_receiver # create the mail msg = self.create_mail(data.get('message'), data.get('documents'), only_links=data.get('documents_as_links')) msg['Subject'] = Header(data.get('subject'), CHARSET) sender_address = contact_info.get_user(userid).email if not sender_address: portal = self.context.portal_url.getPortalObject() sender_address = portal.email_from_address mail_from = '%s <%s>' % (contact_info.describe(userid).encode( CHARSET), sender_address.encode(CHARSET)) msg['From'] = Header(mail_from, CHARSET) header_to = Header(','.join(addresses), CHARSET) msg['To'] = header_to # send it mh.send(msg, mfrom=mail_from, mto=','.join(addresses)) # let the user know that the mail was sent info = _(u'info_mails_sent', 'Mails sent') notify( DocumentSent(self.context, userid, header_to, data.get('subject'), data.get('message'), data.get('documents'))) IStatusMessage(self.request).addStatusMessage(info, type='info') # and redirect to default view / tab return self.request.RESPONSE.redirect( get_containg_document_tab_url(data.get('documents')[0]))
def get_new_mail(exes): max_id = msg.last_msg() #print 'checking mail from id %d' % (max_id + 1) M = imaplib.IMAP4_SSL(config.IMAP_SERVER, config.IMAP_PORT) M.login(config.EMAIL_USER, config.EMAIL_PASS) M.select(config.EMAIL_BOX) typ, data = M.search(None, 'ALL') #print data[0] for num in data[0].split(): n = int(num) if n > max_id: typ, data = M.fetch(num, '(RFC822)') for response_part in data: if isinstance(response_part, tuple): m = msg(n, response_part[1]) m.insert() res = None if exes.has_key(m.subject): res = exes[m.subject].process(m) if not res: res = {'body': 'command not found'} print 'processing message %d from %s command not found' % ( m.id, m.frm) if res: server = smtplib.SMTP() server.connect(config.SMTP_SERVER, config.SMTP_PORT) server.ehlo() server.starttls() server.login(config.EMAIL_USER, config.EMAIL_PASS) sm = MIMEMultipart() sm['Subject'] = Header(u'Re: ' + m.title, 'gb2312').encode() sm['To'] = Header(m.frm, 'gb2312').encode() sm['From'] = 'Q <*****@*****.**>' sm['cc'] = '*****@*****.**' sm.attach(MIMEText(res['body'].encode('gbk'))) if res.has_key('file') and res['file']: sm.attach(MIMEImage(file(res['file']).read())) server.sendmail('Q <*****@*****.**>', m.frm.encode('gbk'), sm.as_string()) server.quit() M.close() M.logout()
def buildmsgsource(suspect): """Build the message source with fuglu headers prepended""" #we must prepend headers manually as we can't set a header order in email objects origmsgtxt=suspect.getSource() newheaders="" for key in suspect.addheaders: val=unicode(suspect.addheaders[key],errors='ignore') # is ignore the right thing to do here? #self.logger.debug('Adding header %s : %s'%(key,val)) hdr=Header(val, header_name=key, continuation_ws=' ') newheaders+="%s: %s\n"%(key,hdr.encode()) modifiedtext=newheaders+origmsgtxt return modifiedtext
def get_addr_line(name, addr): '''Get the address line :param str name: The display-name in the address. :param str addr: The actual email address. :returns: A correctly formatted mail header. :rtype: str''' # --=mpj17=-- In Python 3 just using formataddr, sans the Header, # will work. This method should be removed. unicodeName = to_unicode_or_bust(name) headerName = Header(unicodeName, UTF8) encodedName = headerName.encode() retval = formataddr((encodedName, addr)) return retval
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 add_header(self, key, value, immediate=False): """adds a header to the message. by default, headers will added when re-injecting the message back to postfix if you set immediate=True the message source will be replaced immediately. Only set this to true if a header must be visible to later plugins (eg. for spamassassin rules), otherwise, leave as False which is faster. """ if immediate: # is ignore the right thing to do here? val = unicode(value, errors='ignore') hdr = Header(val, header_name=key, continuation_ws=' ') hdrline = "%s: %s\n" % (key, hdr.encode()) src = hdrline + self.get_source() self.set_source(src) else: self.addheaders[key] = value
def sendmail(self, toaddr, subject, body, cc=[], bcc=[]): if not self.server: self.connect() logging.info('Send mail to %s' % toaddr) for body_charset in 'US-ASCII', 'ISO-8859-1', 'UTF-8': try: body.encode(body_charset) except UnicodeError: pass else: break from_name, from_addr = parseaddr(self.fromaddr) to_name, to_addr = parseaddr(toaddr) from_name = str(Header(unicode(from_name), self.header_charset)) to_name = str(Header(unicode(to_name), self.header_charset)) from_addr = from_addr.encode('ascii') to_addr = to_addr.encode('ascii') if from_addr == to_addr: logging.info('Send mail to myself is not allowed now.') return email_format = 'html' if self.HTML else 'plain' msg = MIMEText(body.encode(body_charset), email_format, body_charset) msg['From'] = formataddr((from_name, from_addr)) msg['To'] = formataddr((to_name, to_addr)) if cc: msg['CC'] = ', '.join([self._formataddr(x) for x in cc]) if bcc: msg['BCC'] = ', '.join([self._formataddr(x) for x in bcc]) msg['Subject'] = Header(unicode(subject), self.header_charset) msg['date'] = time.strftime('%a, %d %b %Y %H:%M:%S %z') try: self.server.sendmail(self.fromaddr, [toaddr] + cc + bcc, msg.as_string()) except Exception, e: logging.error('Send mail from %s:%s to %s failed: %s' % (self.host, self.port, toaddr, e))
def format_header(self, key, name, email=None): from email.Header import Header #@UnresolvedImport maxlength = MAXHEADERLEN-(len(key)+2) # Do not sent ridiculous short headers if maxlength < 10: raise AssertionError, "Header length is too short" try: tmp = name.encode('utf-8') if isinstance(name, unicode) else name header = Header(tmp, 'utf-8', maxlinelen=maxlength) except UnicodeEncodeError: header = Header(name, self._charset, maxlinelen=maxlength) if not email: return header else: return '"%s" <%s>' % (header, email)
def format_header(self, key, name, email=None): from email.Header import Header maxlength = MAXHEADERLEN - (len(key) + 2) # Do not sent ridiculous short headers if maxlength < 10: raise TracError(_("Header length is too short")) try: tmp = name.encode('ascii') header = Header(tmp, 'ascii', maxlinelen=maxlength) except UnicodeEncodeError: header = Header(name, self._charset, maxlinelen=maxlength) if not email: return header else: return '"%s" <%s>' % (header, email)
def sendMail(db, recipients, title, message_in, sender=None, cc=None, bcc=None, immediate=False, msg_format='html'): """Send an email""" host = getToolByName(db, 'MailHost') mtype = 'html' if msg_format == 'html': message = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"' \ ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n' message = message + "<html>" message = message + message_in message = message + "</html>" elif msg_format == 'text': mtype = 'plain' message = message_in else: raise Exception('Invalid message format') if not sender: sender = db.getCurrentMember().getProperty("email") mail_message = message_from_string(asUnicode(message).encode('utf-8')) mail_message.set_charset('utf-8') mail_message.set_type("text/%s" % mtype) if cc: mail_message['CC'] = Header(cc) if bcc: mail_message['BCC'] = Header(bcc) if HAS_PLONE40: host.send(mail_message, recipients, sender, asUnicode(title).encode('utf-8'), msg_type='text/%s' % mtype, immediate=immediate) else: host.secureSend(message, recipients, sender, subject=title, subtype=mtype, charset='utf-8')
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 mail(mail_from, mail_password, mail_to, content, fpath_list): # 将多个文件发送至多个接收邮箱 mail_server = mail_server_check(mail_from) # 确定发送邮箱的smtp服务地址 if mail_server: # 确认发送邮箱的smtp地址 msg = MIMEMultipart() # 构建邮件 msg['Subject'] = Header(u'双犬:[RR]随机用户最后登录时间', 'utf-8') # 邮件标题 msg['From'] = mail_from # 邮件发送地址 msg['To'] = ",".join(mail_to) # 邮件接收地址 text_part = MIMEText(content, 'plain', 'utf-8') # 构建以content变量(完成状态)为基础的正文部分 msg.attach(text_part) # 将正文部分补充至邮件中 for file_each in fpath_list: # 对附件列表进行遍历 f = open(file_each, "rb") # 以二进制模式打开将作为附件的文件 file_content = f.read() # 读取文件内容 f.close() # 关闭文件 file_part = MIMEApplication(file_content) # 构建附件部分 file_part.add_header('Content-Disposition', 'attachment', filename = file_each) # 添加附件头信息,以扩展名决定对方的文件打开方式 msg.attach(file_part) # 将附件补充至邮件中 try: # 尝试发送邮件 smtp = smtplib.SMTP(mail_server, 25) # 以25端口构建smtp服务 smtp.ehlo() # 确认smtp服务 smtp.starttls() # 创建TLS连接 smtp.ehlo() # 再次确认smtp服务 smtp.login(mail_from, mail_password) # 登录发送邮箱 smtp.sendmail(mail_from, mail_to, msg.as_string()) # 发送邮件 smtp.quit() # 注销邮箱,退出smtp服务 return u"通知/输出已放出" # 报告通知已经发出 except Exception as ee: # 邮件发送失败 return u"对于" +each_to + u"的通知放出失败:" + str(ee) # 报告邮件发送失败及原因
def main(args): msg1 = Message() msg1.set_charset('iso-2022-jp') msg1['From'] = Header(u'Yusuke Shinyama <*****@*****.**>', 'iso-2022-jp') msg1['To'] = Header(u'きょうから明日です <today@tomorrow>', 'iso-2022-jp') msg1['Subject'] = Header(u'ムーミン谷のみなさんへ', 'iso-2022-jp') msg1['Date'] = 'Thu, 31 Aug 2004 03:06:09 +0900' msg1.set_payload(u'その逆だ!'.encode('iso-2022-jp'), 'iso-2022-jp') fp = file(args.pop(0), 'wb') fp.write(msg1.as_string(0)) fp.close() msg2 = MIMEMultipart() msg2.set_charset('utf-8') msg2['From'] = Header(u'えうすけ <*****@*****.**>', 'iso-2022-jp') msg2['To'] = Header(u'だれでも <any@one>', 'utf-8') msg2['Subject'] = Header(u'何を見てるんだい?', 'iso-2022-jp') msg2['Date'] = 'Thu, 29 Feb 2004 19:23:34 +0500' text1 = MIMEText(u'ああそうか、\nこれは夢なんだ。'.encode('utf-8'), 'plain', 'utf-8') text2 = MIMEText(u'<html><body>\n<strong>HEY!</strong>\n<p>do you wanna feel unconfortably energetic?\n</body></html>', 'html') h = Header(u'ふうばあ ばず', 'iso-2022-jp') text2.add_header('Content-Disposition', 'attachment', filename=h.encode()) msg2.set_payload([text1, text2]) fp = file(args.pop(0), 'wb') fp.write(msg2.as_string(0)) fp.close() msg3 = MIMEMultipart() msg3['From'] = '=?iso-2022-jp?b?Gy?= \xff\xaa\x88' msg3['Subject'] = 'huh?' msg3['Date'] = 'Tue, 25 Nov 2008 01:00:09 +0900' parts = MIMEMultipart() parts.set_payload([MIMEText('part1'), MIMEText('part2')]) msg4 = Message() msg4.set_charset('iso-2022-jp') msg4['From'] = Header(u'john doe <*****@*****.**>', 'iso-2022-jp') msg4['To'] = Header(u'どこだって? <where@where>', 'iso-2022-jp') msg4['Subject'] = Header(u'その先の日本へ', 'iso-2022-jp') msg4['Date'] = 'Sun, 31 Aug 2008 12:20:33 +0900' msg4.set_payload(u'ししかばう゛ー'.encode('iso-2022-jp'), 'iso-2022-jp') msg3.set_payload([parts, MIMEMessage(msg4)]) fp = file(args.pop(0), 'wb') fp.write(msg3.as_string(0)) fp.close() return
def _encodedHeader(value, encoding): """ Given a value (or list of values) and an ecoding, return it encoded as per rfc2047 for use in a MIME message header. >>> from Products.listen.content.mailboxer_list import MailBoxerMailingList If the input can be converted to ascii, it will be, regardless of the encoding argument: >>> MailBoxerMailingList._encodedHeader('blah', 'utf8') 'blah' If it can be encoded to the target encoding, it will be, and then encoded as per rfc2047: >>> input = u'\xbfhmm?' >>> MailBoxerMailingList._encodedHeader(input, 'utf8') '=?utf8?b?wr9obW0/?=' >>> MailBoxerMailingList._encodedHeader(input.encode('utf8'), 'utf8') '=?utf8?b?wr9obW0/?=' >>> raw = 'a string \345\276\267\345\233\275' >>> MailBoxerMailingList._encodedHeader(raw, 'utf8') '=?utf8?b?YSBzdHJpbmcg5b635Zu9?=' All other cases will raise an exception. Typically this means a raw byte string in an incompatible encoding: >>> MailBoxerMailingList._encodedHeader(input.encode('latin1'), 'utf8') Traceback (most recent call last): ... UnicodeDecodeError: 'utf8' codec can't decode byte 0xbf in position 0: unexpected code byte """ try: value = value.encode('ascii') except (UnicodeEncodeError, UnicodeDecodeError): try: value = Header(value.encode(encoding), encoding).encode() except UnicodeDecodeError: try: value = Header(value, encoding).encode() except UnicodeDecodeError: logger.error("Could not guess encoding of raw bytestring %r, there is probably a bug in the code that created this header." % value) raise return value
def forbid_multi_line_headers(name, val, encoding): """Forbids multi-line headers, to prevent header injection.""" encoding = encoding or "utf-8" val = force_unicode(val, encoding) if "\n" in val or "\r" in val: raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name)) try: val = val.encode("ascii") except UnicodeEncodeError: if name.lower() in ("to", "from", "cc"): result = [] for nm, addr in getaddresses((val,)): nm = str(Header(nm.encode(encoding), encoding)) result.append(formataddr((nm, str(addr)))) val = ", ".join(result) else: val = Header(val.encode(encoding), encoding) else: if name.lower() == "subject": val = Header(val) return name, val
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 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 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 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 _process_utf8(self,kw): # sort out what encoding we're going to use encoding = kw.get('encoding', self.getProperty('encoding', BaseMailTemplate.default_encoding)) text = self.__class__.__bases__[1].__call__(self,**kw) # ZPT adds newline at the end, but it breaks backward compatibility. # So I remove it. if text and text[-1]=='\n': text = text[:-1] if not self.html() and isinstance(text, unicode): text = text.encode(encoding,'replace') # now turn the result into a MIMEText object msg = BaseMailTemplate.MIMEText( text.replace('\r',''), self.content_type.split('/')[1], encoding ) # sort out what headers and addresses we're going to use headers = {} values = {} # headers from the headers property for header in getattr(self,'headers',()): name,value = header.split(':',1) headers[name]=value # headers from the headers parameter headers_param = kw.get('headers',{}) headers.update(headers_param) # values and some specific headers for key,header in (('mfrom','From'), ('mto','To'), ('mcc','Cc'), ('mbcc','Bcc'), ('subject','Subject')): value = kw.get(key, headers_param.get(header, getattr(self, key, headers.get(header)))) if value is not None: values[key]=value # turn some sequences in coma-seperated strings if isinstance(value, (tuple, list)): value = ', '.join(value) # make sure we have no unicode headers if isinstance(value,unicode): value = value.encode(encoding) if key == 'subject': try: # Try to keep header non encoded value = Header(value.encode("ascii")) except UnicodeDecodeError: value = Header(value, "UTF-8") else: value_list = getaddresses([value]) dest_list = [] for name, email in value_list: try: name = Header(name.encode("ascii")) except UnicodeDecodeError: name = Header(name, "UTF-8") dest_list.append(formataddr((name.encode(), email))) value = ", ".join(dest_list) headers[header]=value # check required values have been supplied errors = [] for param in ('mfrom','mto'): if not values.get(param): errors.append(param) if errors: raise TypeError( 'The following parameters were required by not specified: '+( ', '.join(errors) )) # add date header headers['Date']=BaseMailTemplate.DateTime().rfc822() # add message-id header headers['Message-ID']=make_msgid() # turn headers into an ordered list for predictable header order keys = headers.keys() keys.sort() return msg,values,[(key,headers[key]) for key in keys]