def send_email(success): import smtplib from email.mime.text import MIMEText from email import charset if len(config["smtp"]["host"]) == 0: logging.error("Failed to send email because smtp host is not set") return # use quoted-printable instead of the default base64 charset.add_charset("utf-8", charset.SHORTEST, charset.QP) if success: body = "SnapRAID job completed successfully:\n\n\n" else: body = "Error during SnapRAID job:\n\n\n" body += email_log.getvalue() msg = MIMEText(body, "plain", "utf-8") msg["Subject"] = config["email"]["subject"] + \ (" SUCCESS" if success else " ERROR") msg["From"] = config["email"]["from"] msg["To"] = config["email"]["to"] smtp = {"host": config["smtp"]["host"]} if config["smtp"]["port"]: smtp["port"] = config["smtp"]["port"] if config["smtp"]["ssl"]: server = smtplib.SMTP_SSL(**smtp) else: server = smtplib.SMTP(**smtp) if config["smtp"]["user"]: server.login(config["smtp"]["user"], config["smtp"]["password"]) server.sendmail( config["email"]["from"], [config["email"]["to"]], msg.as_string()) server.quit()
def send(email_receivers, stories): charset.add_charset("utf-8", charset.QP, charset.QP) sender = "salvitobot" for story in stories: for recipient in email_receivers: multipart = MIMEMultipart("alternative") multipart["Subject"] = Header(story["title"].encode("utf-8"), "UTF-8").encode() multipart["To"] = Header(recipient.encode("utf-8"), "UTF-8").encode() multipart["From"] = Header(sender.encode("utf-8"), "UTF-8").encode() textpart = MIMEText(story["body"], "plain", "UTF-8") multipart.attach(textpart) mystream = io.StringIO() g = Generator(mystream, False) g.flatten(multipart) message = mystream.getvalue() try: smtpObj = smtplib.SMTP("localhost") smtpObj.sendmail(sender, recipient, message) message_to_user = ( "\nSuccessfully sent email.\n" "Probably it went to your SPAM folder.\n" "If you are using Gmail you might need to create a filter\n" "to avoid sending emails from <*****@*****.**> to \n" "your SPAM folder. More info here https://support.google.com/mail/answer/6579\n" ) print(message_to_user) except smtplib.SMTPException: print("Error: unable to send email")
def __init__(self, m, to, sender, subject=None, cc=None, bcc=None): super().__init__() self.m = check_m(m) to = to_list(to) cc = to_list(cc) bcc = to_list(bcc) if not subject: subject = '%s mailer' % (IDENT) subject = '%s - %s' % (subject, get_timestamp()) self.__sender = sender self.__recipients = list(_chain(to, cc, bcc)) _charset.add_charset('utf-8', _charset.QP, _charset.QP, 'UTF-8') self.__message = _MIMEMultipart() self.__message.add_header('To', ', '.join(to)) if cc: self.__message.add_header('CC', ', '.join(cc)) self.__message.add_header('From', sender) self.__message.add_header('Subject', subject) self.__message.add_header('Date', _formatdate()) self.__message.add_header('X-Mailer', '%s mailer' % (IDENT)) self.m( 'mail tool startup done', more=dict(to=to, cc=cc, bcc=bcc, sender=sender, subject=subject), verbose=False )
def confirmation_mail(reg): fields = dict() fields.update(reg) fields["confirmation_url"] = CONFIRMATION_URL_BASE % reg["id"] fields["nick_name"] = reg["nick_name"] or "-" fields["university_alt"] = reg["university_alt"] or "-" fields["food"] = essen_dict[reg["food"]] fields["arbeitskreise"] = reg["arbeitskreise"] or "-" fields["notes"] = reg["notes"] or " -\n" text = open("MAIL_TEXT.tpl").read().format(**fields) # Create a text/plain message add_charset("utf-8", QP, QP, "utf-8") msg = MIMEText(text, _charset="utf-8") msg["Subject"] = "Anmeldung zur ZaPF im SoSe 2013" msg["From"] = formataddr((str(Header(ME_NAME, "utf-8")), ME_EMAIL)) msg["To"] = formataddr((str(Header(reg["first_name"] + " " + reg["last_name"], "utf-8")), reg["email"])) msg.add_header("Reply-To", ME_REPLY_TO) server = smtplib.SMTP(ME_MAILSERVER) server.set_debuglevel(1) server.send_message(msg) server.quit()
def dispatch(self,noise=None): charset.add_charset('utf-8', charset.SHORTEST) if self.args.encrypted and self.args.encrypted.lower() not in ['false','no','0']: msg = MIMEText(fake_pgp_msg(), _charset='utf-8') else: msg = MIMEText(noise if noise else self.args.body, _charset='utf-8') msg['Subject'] = self.args.subject msg['From'] = self.args.sender if ',' in self.args.to: random.seed() msg['To'] = random.choice(self.args.to.split(', ')) else: msg['To'] = self.args.to if self.args.proxy: # Let's use a Tor SOCKS proxy, if available. Obviously, start Tor before running this program socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS4, 'localhost', self.args.proxy) s = socks.socksocket() s.connect(('example.com', 80)) s.close() socks.wrapmodule(smtplib) # Use STARTTLS for added security smtpserver = smtplib.SMTP(self.args.server) smtpserver.starttls() smtpserver.set_debuglevel(True) smtpserver.login(self.args.sender,self.args.passwd) try: smtpserver.sendmail(self.args.sender, [self.args.to], msg.as_string()) finally: smtpserver.close() return "Successfully sent mail"
def __init__(self, sender='', recipients=(), subject='', alternative=0, reply_to=None, cc=(), bcc=(), email_account=None, expose_recipients=None): from email import charset as Charset Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8') if isinstance(recipients, string_types): recipients = recipients.replace(';', ',').replace('\n', '') recipients = split_emails(recipients) # remove null recipients = filter(None, (strip(r) for r in recipients)) self.sender = sender self.reply_to = reply_to or sender self.recipients = recipients self.subject = subject self.expose_recipients = expose_recipients self.msg_root = MIMEMultipart('mixed') self.msg_alternative = MIMEMultipart('alternative') self.msg_root.attach(self.msg_alternative) self.cc = cc or [] self.bcc = bcc or [] self.html_set = False self.email_account = email_account or get_outgoing_email_account(sender=sender)
def send_owner_notification(resource, owner, itip_event, success=True): """ Send a reservation notification to the resource owner """ import smtplib from pykolab import utils from email.MIMEText import MIMEText from email.Utils import formatdate # encode unicode strings with quoted-printable from email import charset charset.add_charset('utf-8', charset.SHORTEST, charset.QP) notify = False status = itip_event['xml'].get_attendee_by_email(resource['mail']).get_participant_status(True) invitationpolicy = get_resource_invitationpolicy(resource) if invitationpolicy is not None: for policy in invitationpolicy: # TODO: distingish ACCEPTED / DECLINED status notifications? if policy & COND_NOTIFY and owner['mail']: notify = True break if notify or not success: log.debug( _("Sending booking notification for event %r to %r from %r") % ( itip_event['uid'], owner['mail'], resource['cn'] ), level=8 ) # change gettext language to the preferredlanguage setting of the resource owner if owner.has_key('preferredlanguage'): pykolab.translate.setUserLanguage(owner['preferredlanguage']) message_text = owner_notification_text(resource, owner, itip_event['xml'], success) msg = MIMEText(utils.stripped_message(message_text), _charset='utf-8') msg['To'] = owner['mail'] msg['From'] = resource['mail'] msg['Date'] = formatdate(localtime=True) msg['Subject'] = utils.str2unicode(_('Booking for %s has been %s') % ( resource['cn'], participant_status_label(status) if success else _('failed') )) smtp = smtplib.SMTP("localhost", 10027) if conf.debuglevel > 8: smtp.set_debuglevel(True) try: smtp.sendmail(resource['mail'], owner['mail'], msg.as_string()) except Exception, e: log.error(_("SMTP sendmail error: %r") % (e)) smtp.quit()
def send_cancel_notification(object, receiving_user): """ Send a notification about event/task cancellation """ import smtplib from email.MIMEText import MIMEText from email.Utils import formatdate # encode unicode strings with quoted-printable from email import charset charset.add_charset('utf-8', charset.SHORTEST, charset.QP) log.debug(_("Send cancellation notification for %s %r to user %r") % ( object.type, object.uid, receiving_user['mail'] ), level=8) organizer = object.get_organizer() orgemail = organizer.email() orgname = organizer.name() # compose different notification texts for events/tasks if object.type == 'task': message_text = """ The assignment for '%(summary)s' has been cancelled by %(organizer)s. The copy in your tasklist as been marked as cancelled accordingly. """ % { 'summary': object.get_summary(), 'organizer': orgname if orgname else orgemail } else: message_text = """ The event '%(summary)s' at %(start)s has been cancelled by %(organizer)s. The copy in your calendar as been marked as cancelled accordingly. """ % { 'summary': object.get_summary(), 'start': xmlutils.property_to_string('start', object.get_start()), 'organizer': orgname if orgname else orgemail } message_text += "\n" + _("*** This is an automated message. Please do not reply. ***") # compose mime message msg = MIMEText(utils.stripped_message(message_text), _charset='utf-8') msg['To'] = receiving_user['mail'] msg['Date'] = formatdate(localtime=True) msg['Subject'] = utils.str2unicode(_('"%s" has been cancelled') % (object.get_summary())) msg['From'] = utils.str2unicode('"%s" <%s>' % (orgname, orgemail) if orgname else orgemail) smtp = smtplib.SMTP("localhost", 10027) if conf.debuglevel > 8: smtp.set_debuglevel(True) try: smtp.sendmail(orgemail, receiving_user['mail'], msg.as_string()) except Exception, e: log.error(_("SMTP sendmail error: %r") % (e))
def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--subject', required=True) parser.add_argument('--from', required=True) parser.add_argument('--to', required=True) parser.add_argument('--configfile', type=argparse.FileType('r'), required=True, help='The .ini file with the mailserver credentials') parser.add_argument('--configsection', default='DEFAULT', help='The mail server section to choose in the configfile.') parser.add_argument('mailbody', metavar='MAILBODY', type=argparse.FileType('r'), help='A text file containing the mail body itself') parser.add_argument('attachments', metavar='ATTACHMENT', type=argparse.FileType('rb'), nargs='*', help='Optional files to attach') args = parser.parse_args() config = configparser.ConfigParser() config.sections() config.read_file(args.configfile) try: args.configsection config.items(args.configsection) except configparser.NoSectionError: print("Section {} not found in configfile {}.".format(args.configsection, args.configfile.name)) add_charset('utf-8', QP, QP, 'utf-8') if len(args.attachments): msg = MIMEMultipart() msg.preamble = 'You will not see this in a MIME-aware mail reader.\n' mime_parts = [] msg.attach(MIMEText(args.mailbody.read(), _charset='utf-8')) args.mailbody.close() for attachment in args.attachments: ctype, encoding = mimetypes.guess_type(attachment.name) if ctype is None or encoding is not None: ctype = 'application/octet-stream' maintype, subtype = ctype.split('/', 1) if maintype == 'image': mime_part = MIMEImage(attachment.read(), _subtype=subtype) else: mime_part = MIMEBase(maintype, subtype) mime_part.set_payload(attachment.read()) encoders.encode_base64(mime_part) attachment.close() mime_part.add_header('Content-Disposition', 'attachment', filename=os.path.basename(attachment.name)) msg.attach(mime_part) else: msg = MIMEText(args.mailbody.read(), _charset='utf-8') args.mailbody.close() msg['Subject'] = args.subject msg['From'] = getattr(args, 'from') msg['To'] = args.to server = smtplib.SMTP(config.get(args.configsection, 'server'), config.get(args.configsection, 'port')) server.ehlo() server.starttls() server.ehlo() server.login(config.get(args.configsection, 'username'), config.get(args.configsection, 'password')) server.send_message(msg) server.quit()
def __connect(self): charset.add_charset("utf-8", charset.SHORTEST, charset.QP) if self.tls: server = smtplib.SMTP_SSL(self.hostname, self.port, timeout = 3) else: server = smtplib.SMTP(self.hostname, self.port, timeout = 3) if self.username and self.password: server.login(self.username, self.password) return server
def init_mailer(): if CHARSETS: for canonical, charset_dict in CHARSETS.iteritems(): add_charset(canonical, **charset_dict) if ALIASES: for alias, canonical in ALIASES.iteritems(): add_alias(alias, canonical) if CODECS: for canonical, codec_name in CODECS.iteritems(): add_codec(canonical, codec_name)
def __init__( self, host, port, use_ssl=True, disclose_recipients=True, hidden_recipients_address=None, sender=None, local_hostname=None, ): """Initialize an instance of ``pooldlib.api.communication.Email. :param host: Addressable name of SMTP server to send email through. :type host: string :param port: Port on which to connect to SMTP server. :type port: int :param use_ssl: If true, connect to SMTP server via SSL connection. Default: True :type use_ssl: boolean :param disclose_recipients: If true, make recipients visible to all recipients via 'To' header. Default: True :type disclose_recipients: boolean :param hidden_recipients_address: Email address to use in 'To' header when hiding recipients. Defaults to sender address. :type disclose_recipients: string :param sender: Email address string to use as sender of generated email(s). Should be of the form 'Sender Name <*****@*****.**>' :type sender: string :param local_hostname: The FQDN of the host sending the email. See smtplib.SMTP. :type local_hostname: string """ self._recipients = list() if sender is None: sender = "Poold Inc. <*****@*****.**>" self.sender = sender self.subject = None self.disclose_recipients = disclose_recipients self._recipient_address = hidden_recipients_address self._recipients = list() self._cc_recipients = list() self._bcc_recipients = list() self.msg_root = None self._host = host self._port = port self._local_hostname = local_hostname self._use_ssl = use_ssl self._connected = False self._logged_in = False charset.add_charset("utf-8", charset.QP, charset.QP) self.server = smtplib.SMTP(host=None, port=None, local_hostname=self._local_hostname)
def build(self): """build message string""" # There can be only ONE ENCODING TO RULE THEM ALL!! MUWAHAHAHA subject, body = map( lambda x: UnicodeDammit(x).unicode_markup, [self._subject, self._body] ) if self._embedded_images: msg = MIMEMultipart('related') #msg = MIMEMultipart('mixed') else: msg = MIMEMultipart() msg['From'] = self._sender msg['To'] = COMMASPACE.join(self._recipients) msg['Date'] = formatdate(localtime=True) msg['Subject'] = Header(subject, 'utf-8') msg['Cc'] = COMMASPACE.join(self._carbon_copy) # NOTE: Bcc headers are not added to the message # The BCC'd recipients are added to the smtplib recipient # list when the mail is actually sent. # TODO: Send individual messages for each recipient on the BCC list # (and use the BCC header). This way the BCC'd recip's KNOW that they we're BCC'd. # Set character encoding so that viewing the source # of an HTML email is still readable to humans. charset.add_charset('utf-8', charset.SHORTEST) # add body of email msg.attach(MIMEText( body, _subtype=self._format, _charset='utf-8', )) # add attachments for f in self._attachments: msg.attach(_build_attachment(f)) for content_id, image_filename in self._embedded_images: fp = open(image_filename, 'rb') msgImage = MIMEImage(fp.read()) fp.close() # Define the image's ID as referenced above msgImage.add_header('Content-ID', '<{0}>'.format(content_id)) msg.attach(msgImage) return msg.as_string()
def send_email(success): import smtplib from email.mime.text import MIMEText from email import charset if len(config["smtp"]["host"]) == 0: logging.error("Failed to send email because smtp host is not set") return # use quoted-printable instead of the default base64 charset.add_charset("utf-8", charset.SHORTEST, charset.QP) if success: body = "SnapRAID job completed successfully:\n\n\n" else: body = "Error during SnapRAID job:\n\n\n" log = email_log.getvalue() maxsize = config['email'].get('maxsize', 500) * 1024 if maxsize and len(log) > maxsize: cut_lines = log.count("\n", maxsize//2, -maxsize//2) log = ( "NOTE: Log was too big for email and was shortened\n\n" + log[:maxsize//2] + "[...]\n\n\n --- LOG WAS TOO BIG - {} LINES REMOVED --\n\n\n[...]".format( cut_lines) + log[-maxsize//2:]) body += log msg = MIMEText(body, "plain", "utf-8") msg["Subject"] = config["email"]["subject"] + \ (" SUCCESS" if success else " ERROR") msg["From"] = config["email"]["from"] msg["To"] = config["email"]["to"] smtp = {"host": config["smtp"]["host"]} if config["smtp"]["port"]: smtp["port"] = config["smtp"]["port"] if config["smtp"]["ssl"]: server = smtplib.SMTP_SSL(**smtp) else: server = smtplib.SMTP(**smtp) if config["smtp"]["tls"]: server.starttls() if config["smtp"]["user"]: server.login(config["smtp"]["user"], config["smtp"]["password"]) server.sendmail( config["email"]["from"], [config["email"]["to"]], msg.as_string()) server.quit()
def send_email_multi_alternatives_with_template( from_email, to_list, subject, text_template, context, html_template=None, headers=None): # revert the changes of a Django patch # https://code.djangoproject.com/attachment/ticket/11212/0001-Ticket-11212-default-to-7bit-email.patch from email import charset charset.add_charset('utf-8', charset.SHORTEST, charset.QP, 'utf-8') text_content = template_loader.render_to_string( text_template, context) mail = EmailMultiAlternatives(subject, text_content, from_email, list(to_list), headers=headers) if html_template: html_content = template_loader.render_to_string( html_template, context) mail.attach_alternative(html_content, 'text/html') mail.send()
def make_msg(self, args): message = args.message.read().decode('utf-8') charset.add_charset(__class__.CHARSET, charset.SHORTEST, None, __class__.CHARSET) msg = None; if isinstance(args.attachments, list): msg = MIMEMultipart() msg.preamble = 'You will not see this in a MIME-aware mail reader.\n' msg.attach(MIMEText(message, args.type, __class__.CHARSET)) for stream in args.attachments: filename = os.path.basename(stream.name) ctype, encoding = mimetypes.guess_type(stream.name) if ctype is None or encoding is not None: ctype = 'application/octet-stream' maintype, subtype = ctype.split('/', 1) if maintype == 'text': msg_attach = MIMEText(stream.read().decode(__class__.CHARSET), _subtype=subtype) elif maintype == 'image': msg_attach = MIMEImage(stream.read(), _subtype=subtype) elif maintype == 'audio': msg_attach = MIMEAudio(stream.read(), _subtype=subtype) else: msg_attach = MIMEBase(maintype, subtype) msg_attach.set_payload(stream.read()) encoders.encode_base64(msg_attach) msg_attach.add_header('Content-Disposition', 'attachment', filename=filename) msg.attach(msg_attach) else: msg = MIMEText(message, args.type, __class__.CHARSET) msg['Subject'] = Header(args.subject, __class__.CHARSET) msg['X-Mailer'] = args.mailer msg['From'] = args.from_address msg['To'] = ", ".join(args.to_addresses) if isinstance(args.cc, list): msg['Cc'] = ", ".join(args.cc) if isinstance(args.bcc, list): msg['Bcc'] = ", ".join(args.bcc) if args.verbose: print(msg.as_string(), file=sys.stderr) return msg
def make_header(to, sender, cc, subject=None, subjecttag=None, subjectdate=None): # prevent python to encode utf-8 text in base64. using quoted printables instead charset.add_charset('utf-8', charset.QP, charset.QP, 'UTF-8') result = MIMEMultipart() # result.preamble = 'whatever' result.add_header('To', ', '.join(to)) cc and result.add_header('CC', ', '.join(cc)) result.add_header('From', sender) if not subject: subject = getconf('email_subject') if not subject: subject = '☃' subject = '[' + subjecttag + '] ' + subject if subjecttag else subject subject = subject + ' ' + formatdate(localtime=True) if subjectdate else subject result.add_header('Subject', subject) result.add_header('Date', formatdate()) result.add_header('X-Mailer', 'Postbote Willy') return result
def __init__(self, mail): charset.add_charset('utf-8', charset.SHORTEST, None, "utf-8") self.envelope = MIMEMultipart("plain", "utf-8") self.envelope["Date"] = datetime.datetime.now().strftime("%a, %d %b %Y %X %Z") #Sat, 04 Oct 2014 11:03:31 +0200 self.envelope["X-Mailer"] = "Python mailler" # self.envelope["User-Agent"] = "Python mailler" self.list_to = [] self.list_cc = [] self.list_bcc = [] # self.envelope["Resent-Date"] = "Test mail python" # self.envelope["Resent-From"] = "Test mail python" # self.envelope["Resent-Sender"] = "Test mail python" self.envelope.attach(MIMEText(mail, "plain", "utf-8"))
def send_email(success): import smtplib from email.mime.text import MIMEText from email import charset if len(config["smtp"]["host"]) == 0: logging.error("Failed to send email because smtp host is not set") return # use quoted-printable instead of the default base64 charset.add_charset("utf-8", charset.SHORTEST, charset.QP) if success: body = "SnapRAID job completed successfully:\n\n\n" else: body = "Error during SnapRAID job:\n\n\n" log = email_log.getvalue() maxsize = config['email'].get('maxsize', 500) * 1024 if maxsize and len(log) > maxsize: cut_lines = log.count("\n", maxsize // 2, -maxsize // 2) log = ( "NOTE: Log was too big for email and was shortened\n\n" + log[:maxsize // 2] + "[...]\n\n\n --- LOG WAS TOO BIG - {} LINES REMOVED --\n\n\n[...]". format(cut_lines) + log[-maxsize // 2:]) body += log msg = MIMEText(body, "plain", "utf-8") msg["Subject"] = config["email"]["subject"] + \ (" SUCCESS" if success else " ERROR") msg["From"] = config["email"]["from"] msg["To"] = config["email"]["to"] smtp = {"host": config["smtp"]["host"]} if config["smtp"]["port"]: smtp["port"] = config["smtp"]["port"] if config["smtp"]["ssl"]: server = smtplib.SMTP_SSL(**smtp) else: server = smtplib.SMTP(**smtp) if config["smtp"]["user"]: server.login(config["smtp"]["user"], config["smtp"]["password"]) server.sendmail(config["email"]["from"], [config["email"]["to"]], msg.as_string()) server.quit()
def build_html_email(self, from_email, to_email, subject, text, html, images, output_email_file): logger.info("Creating an html email file. ") # couldn't figure out how to get the email to display so that it wasn't base64 encoded # this post on the interweb pointed out this line # http://bugs.python.org/issue12552 charset.add_charset('utf-8', charset.SHORTEST, charset.QP) # Create message container - the correct MIME type is multipart/alternative. msg_root = MIMEMultipart('alternative') msg_root['Subject'] = subject msg_root['From'] = from_email msg_root['To'] = to_email # Record the MIME types of both parts - text/plain and text/html. plain_text = MIMEText(text, 'plain') html_text = MIMEText(html, 'html') logger.info("Added headers. ") # Attach parts into message container. # According to RFC 2046, the last part of a multipart message, in this case # the HTML message, is best and preferred. msg_root.attach(plain_text) msg_root.attach(html_text) logger.info("Added body. ") for image_id in images: logger.info("Added image: {} ".format(image_id)) # This example assumes the image is in the current directory image_path = images[image_id] try: fp = open(image_path, 'rb') msg_image = MIMEImage(fp.read()) fp.close() except: logger.error("Could not attach image file {}".format(image_path)) logger.error(traceback.format_exc()) # Define the image's ID as referenced above msg_image.add_header('Content-ID', '<{}>'.format(image_id)) msg_root.attach(msg_image) self.fs.write_raw_text_to_file(output_email_file, msg_root.as_string())
def _send(self, newsletter, emails, test=False): """ Send combined HTML and plain text email. """ data = newsletter.render(self.get_mailer_context(), store=False) from_email = '%s <%s>' % (newsletter.from_name, newsletter.from_email) subject = data['subject'] if test: subject = 'TEST - ' + subject # Mon Oct 14 16:11:03 CEST 2013 - Mathias Andre # Django 1.4 changed the default encoding from quoted-printable to 8bit # This can cause problem with HTML content where lines > 998 characters # end up cut arbitrarily by the mail server. # To fix this we force back quoted-printable Charset.add_charset('utf-8', Charset.SHORTEST, Charset.QP, 'utf-8') msg = EmailMultiAlternatives(subject, data['text'], from_email, emails) msg.attach_alternative(data['html'], "text/html") msg.send()
def send_email_multi_alternatives_with_template(from_email, to_list, subject, text_template, context, html_template=None, headers=None): # revert the changes of a Django patch # https://code.djangoproject.com/attachment/ticket/11212/0001-Ticket-11212-default-to-7bit-email.patch from email import charset charset.add_charset('utf-8', charset.SHORTEST, charset.QP, 'utf-8') text_content = template_loader.render_to_string(text_template, context) mail = EmailMultiAlternatives(subject, text_content, from_email, list(to_list), headers=headers) if html_template: html_content = template_loader.render_to_string(html_template, context) mail.attach_alternative(html_content, 'text/html') mail.send()
def __init__(self, sender='', recipients=(), subject='', alternative=0, reply_to=None, cc=(), bcc=(), email_account=None, expose_recipients=None): from email import charset as Charset Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8') if isinstance(recipients, string_types): recipients = recipients.replace(';', ',').replace('\n', '') recipients = split_emails(recipients) # remove null recipients = filter(None, (strip(r) for r in recipients)) self.sender = sender self.reply_to = reply_to or sender self.recipients = recipients self.subject = subject self.expose_recipients = expose_recipients if PY3: self.msg_root = MIMEMultipart('mixed', policy=policy.SMTPUTF8) self.msg_alternative = MIMEMultipart('alternative', policy=policy.SMTPUTF8) else: self.msg_root = MIMEMultipart('mixed') self.msg_alternative = MIMEMultipart('alternative') self.msg_root.attach(self.msg_alternative) self.cc = cc or [] self.bcc = bcc or [] self.html_set = False self.email_account = email_account or get_outgoing_email_account( sender=sender)
def send_email(success): import smtplib from email.mime.text import MIMEText from email import charset if len(config["smtp"]["host"]) == 0: logging.error("Failed to send email because smtp host is not set") return # use quoted-printable instead of the default base64 charset.add_charset("utf-8", charset.SHORTEST, charset.QP) if success: body = "SnapRAID job completed successfully:\n\n\n" else: body = "Error during SnapRAID job:\n\n\n" maxsize = config["email"].get("maxsize", 500) * 1024 log = get_log(maxsize) body += log msg = MIMEText(body, "plain", "utf-8") msg["Subject"] = config["email"]["subject"] + \ (" SUCCESS" if success else " ERROR") msg["From"] = config["email"]["from"] msg["To"] = config["email"]["to"] smtp = {"host": config["smtp"]["host"]} if config["smtp"]["port"]: smtp["port"] = config["smtp"]["port"] if config["smtp"]["ssl"]: server = smtplib.SMTP_SSL(**smtp) else: server = smtplib.SMTP(**smtp) if config["smtp"]["tls"]: server.starttls() if config["smtp"]["user"]: server.login(config["smtp"]["user"], config["smtp"]["password"]) server.sendmail(config["email"]["from"], [config["email"]["to"]], msg.as_string()) server.quit()
def __init__( self, sender="", recipients=(), subject="", alternative=0, reply_to=None, cc=(), bcc=(), email_account=None, expose_recipients=None, ): from email import charset as Charset Charset.add_charset("utf-8", Charset.QP, Charset.QP, "utf-8") if isinstance(recipients, string_types): recipients = recipients.replace(";", ",").replace("\n", "") recipients = split_emails(recipients) # remove null recipients = filter(None, (strip(r) for r in recipients)) self.sender = sender self.reply_to = reply_to or sender self.recipients = recipients self.subject = subject self.expose_recipients = expose_recipients self.msg_root = MIMEMultipart("mixed", policy=policy.SMTPUTF8) self.msg_alternative = MIMEMultipart("alternative", policy=policy.SMTPUTF8) self.msg_root.attach(self.msg_alternative) self.cc = cc or [] self.bcc = bcc or [] self.html_set = False self.email_account = email_account or get_outgoing_email_account( sender=sender)
def send(): keyvalue = { 'key': request.forms.get('key_field').decode('utf-8'), 'value': request.forms.get('value_field').decode('utf-8') } email_body = """ キー: {key} 値: {value} """.strip().decode('utf-8').format(**keyvalue) try: msg = MIMEText(email_body, 'plain', 'utf-8') msg['Subject'] = Header(u'メールテスト', 'utf-8') msg['From'] = SENDER_ADDRESS msg['To'] = ','.join(RECIEVER_ADDRESSES) charset.add_charset('utf-8', charset.SHORTEST, None, 'utf-8') # Sendmail version p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE) p.communicate(msg.as_string()) # SMTP Auth(login) version smtp_auth_client = smtplib.SMTP(SENDER_DOMAIN, 587) smtp_auth_client.login(SENDER_LOGIN_ID, SENDER_PASSWORD) smtp_auth_client.sendmail(SENDER_ADDRESS, RECIEVER_ADDRESSES, msg.as_string()) smtp_auth_client.quit() # Error version smtp_client = smtplib.SMTP(SENDER_DOMAIN, 587) smtp_client.sendmail(SENDER_ADDRESS, RECIEVER_ADDRESSES, msg.as_string()) smtp_client.quit() except Exception, err: return map(str, err)
def send_telegram(success): from email import charset import requests if len(config["telegram"]["token"]) == 0: logging.error("Failed to send telegram because token is not set.") return if len(config["telegram"]["chat_id"]) == 0: logging.error("Failed to send telegram because chat_id is not set.") return # use quoted-printable instead of the default base64 charset.add_charset("utf-8", charset.SHORTEST, charset.QP) body = get_success_message(success) maxsize = 4096 log = get_log(maxsize) body += log url = "https://api.telegram.org/bot{}/sendMessage".format( config["telegram"]["token"]) data = {"chat_id": config["telegram"]["chat_id"], "text": body} requests.post(url, data)
def send_smtp(to="", subject="", plaintext="", html=""): """ Send an email. """ # Create message container - the correct MIME type is multipart/alternative. msg = MIMEMultipart("alternative") ch = charset.add_charset("utf-8", charset.QP) msg.set_charset(ch) msg["Subject"] = subject msg["From"] = application.config["MAIL_DEFAULT_SENDER"] msg["To"] = to # Record the MIME types of both parts - text/plain and text/html. part1 = MIMEText(plaintext, "plain", "utf-8") # part2 = MIMEText(html, "html", "utf-8") # Attach parts into message container. # According to RFC 2046, the last part of a multipart message, in this case # the HTML message, is best and preferred. msg.attach(part1) # msg.attach(part2) try: s = smtplib.SMTP(application.config["MAIL_SERVER"]) if application.config["MAIL_USERNAME"] is not None: s.login( application.config["MAIL_USERNAME"], application.config["MAIL_PASSWORD"], ) except Exception: logger.exception("send_smtp raised:") else: s.sendmail( application.config["MAIL_DEFAULT_SENDER"], msg["To"], msg.as_bytes().decode(encoding="UTF-8"), ) s.quit()
# Copyright (C) 2011-2012 Patrick Totzke <*****@*****.**> # This file is released under the GNU GPL, version 3 or a later revision. # For further details see the COPYING file import os import email import re import glob import email.charset as charset charset.add_charset('utf-8', charset.QP, charset.QP, 'utf-8') from email.encoders import encode_7or8bit from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.application import MIMEApplication from alot import __version__ import logging import alot.helper as helper import alot.crypto as crypto import gpgme from alot.settings import settings from alot.errors import GPGProblem from attachment import Attachment from utils import encode_header class Envelope(object): """a message that is not yet sent and still editable. It holds references to unencoded! body text and mail headers among other things. Envelope implements the python container API for easy access of header values. So `e['To']`, `e['To'] = '*****@*****.**'` and
from resource_views import LoginView from skins import skin_registry from utils import get_base_path_query from root_views import PoweredBy, ContactForm from root_views import NotFoundView, ForbiddenView, NotAllowedView from root_views import UploadStatsView, UpdateDocs, UnavailableView from update import UpdateInstanceView # itools source and target languages config = get_abspath('setup.conf') config = ConfigFile(config) itools_source_language = config.get_value('source_language') itools_target_languages = config.get_value('target_languages') # Force email to send UTF-8 mails in plain text add_charset('utf-8', QP, None, 'utf-8') add_codec('utf-8', 'utf_8') class CtrlView(BaseView): access = True def GET(self, resource, context): context.content_type = 'text/plain' database = context.database return dumps({ 'packages': resource.get_version_of_packages(context), 'read-only': not isinstance(database, RWDatabase) })
from buildbot import config from buildbot import interfaces from buildbot import util from buildbot.process.properties import Properties from buildbot.reporters.notifier import ENCODING from buildbot.reporters.notifier import NotifierBase from buildbot.util import ssl from buildbot.util import unicode2bytes from .utils import merge_reports_prop from .utils import merge_reports_prop_take_first # this incantation teaches email to output utf-8 using 7- or 8-bit encoding, # although it has no effect before python-2.7. # needs to match notifier.ENCODING charset.add_charset(ENCODING, charset.SHORTEST, None, ENCODING) try: from twisted.mail.smtp import ESMTPSenderFactory [ESMTPSenderFactory] # for pyflakes except ImportError: ESMTPSenderFactory = None # Email parsing can be complex. We try to take a very liberal # approach. The local part of an email address matches ANY non # whitespace character. Rather allow a malformed email address than # croaking on a valid (the matching of domains should be correct # though; requiring the domain to not be a top level domain). With # these regular expressions, we can match the following: # # [email protected]
#coding:utf-8 from email import charset from threading import Thread from flask import current_app, render_template from flask_mail import Message, Mail from . import mail #添加utf-8编码 charset.add_charset('utf-8', charset.SHORTEST, charset.BASE64, 'utf-8') def send_async_email(app, msg): with app.app_context(): #创建程序上下文 mail.send(msg) print('发送成功') #参数为:收件人地址、主题、渲染邮件正文的模板、关键字参数 def send_email(to, subject, template, **kwargs): app = current_app._get_current_object() #实例化(暂时不知道为何这样实例化) print(app.config['MAIL_USERNAME'], "发送给", to, app.config['MAIL_PASSWORD']) msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + subject, sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to], charset='utf-8') #utf-8编码 msg.body = render_template(template + '.txt', **kwargs) msg.html = render_template(template + '.html', **kwargs) thr = Thread(target=send_async_email, args=[app, msg]) #后台线程 thr.start() return thr
import smtplib from email import charset from email.mime.application import MIMEApplication from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.utils import formatdate from flask import g from indico.core.config import config from indico.core.logger import Logger from indico.util.string import to_unicode # Prevent base64 encoding of utf-8 e-mails charset.add_charset('utf-8', charset.SHORTEST) class GenericMailer: @classmethod def send(cls, notification, skipQueue=False): if isinstance(notification, dict): # Wrap a raw dictionary in a notification class from indico.legacy.webinterface.mail import GenericNotification notification = GenericNotification(notification) # enqueue emails if we have a rh and do not skip queuing, otherwise send immediately rh = g.get('rh') mailData = cls._prepare(notification) if mailData: if skipQueue or not rh:
# Copyright (C) 2020 by the Linux Foundation # __author__ = 'Konstantin Ryabitsev <*****@*****.**>' import os import sys import b4 import re import mailbox import json from datetime import timedelta from tempfile import mkstemp from email import utils, charset charset.add_charset('utf-8', None) logger = b4.logger PULL_BODY_SINCE_ID_RE = [ re.compile(r'changes since commit ([0-9a-f]{5,40}):', re.M | re.I) ] # I like these PULL_BODY_WITH_COMMIT_ID_RE = [ re.compile(r'fetch changes up to ([0-9a-f]{5,40}):', re.M | re.I), ] # I don't like these PULL_BODY_REMOTE_REF_RE = [ re.compile(r'^\s*([\w+-]+(?:://|@)[\w/.@:~-]+)[\s\\]+([\w/._-]+)\s*$', re.M | re.I),
from skins import skin_registry from root_views import PoweredBy, ContactForm from root_views import NotFoundView, ForbiddenView, NotAllowedView from root_views import UploadStatsView, UpdateDocs, UnavailableView from update import UpdateInstanceView # itools source and target languages config = get_abspath('setup.conf') config = ro_database.get_handler(config, ConfigFile) itools_source_language = config.get_value('source_language') itools_target_languages = config.get_value('target_languages') # Force email to send UTF-8 mails in plain text add_charset('utf-8', QP, None, 'utf-8') add_codec('utf-8', 'utf_8') class CtrlView(BaseView): access = True def GET(self, resource, context): context.content_type = 'text/plain' database = context.database return dumps( {'packages': resource.get_version_of_packages(context), 'read-only': not isinstance(database, RWDatabase)})
from zope.interface import implementer from buildbot import config from buildbot import interfaces from buildbot import util from buildbot.process.properties import Properties from buildbot.process.results import Results from buildbot.reporters.notifier import ENCODING from buildbot.reporters.notifier import NotifierBase from buildbot.util import ssl from buildbot.util import unicode2bytes # this incantation teaches email to output utf-8 using 7- or 8-bit encoding, # although it has no effect before python-2.7. # needs to match notifier.ENCODING charset.add_charset(ENCODING, charset.SHORTEST, None, ENCODING) try: from twisted.mail.smtp import ESMTPSenderFactory ESMTPSenderFactory = ESMTPSenderFactory # for pyflakes except ImportError: ESMTPSenderFactory = None # Email parsing can be complex. We try to take a very liberal # approach. The local part of an email address matches ANY non # whitespace character. Rather allow a malformed email address than # croaking on a valid (the matching of domains should be correct # though; requiring the domain to not be a top level domain). With # these regular expressions, we can match the following: # # [email protected]
def main(): """Main function.""" ################# # Parse arguments ################# parser = argparse.ArgumentParser( description='Emails notable events in the journal') parser.add_argument('--config', '-c', action='store', default='journalwatch.json', help='json config file (default: %(default)s)') # parser.add_argument('--show-config', action='store_true', # help="Display parsed configuration file") parser.add_argument('--no-send', action='store_true', help="Don't send email, just print it") parser.add_argument('--version', action='version', version='%(prog)s version {}'.format(__version__)) args = parser.parse_args() # Load config file with open(args.config) as f: config = json.load(f) ################# # Define patterns to ignore ################# # Those are for matching dynamically named units: user_session = re.compile("user@\d+.service") session = re.compile("session-[a-z]?\d+.scope") ssh_unit = re.compile("sshd@[0-9a-f.:]*") # Those will match the logged message itself: btsync_deverr = re.compile("UPnP: Device error.*") journal_restart = re.compile("Journal (started|stopped)") login_buttons = re.compile("Watching system buttons .*") attic_backup = re.compile("Archive fingerprint: .*") packages_found = re.compile("Packages \((\d+)\).*") # sshSocketStart = re.compile("(Starting|Stopping) OpenSSH Per-Connection Daemon.*") # ssh_pubkey = re.compile("Accepted publickey for (earl|git).*") # sshReceivedDisconnect = re.compile("Received disconnect from.*") # logindNewSession = re.compile("New session [a-z]?\d+ of user (bob|alice).*") # sshdSessionClosed = re.compile(".*session closed for user (bob|alice).*") # sessionOpenedRoot = re.compile(".*session opened for user root.*") # suSessionClosedGit = re.compile(".*session opened for user git.*") # anacronNormalExit = re.compile("Normal exit (\d+ jobs run).*") # postfixStatistics = re.compile("statistics:.*") # postfixHostnameDoesNotResolve = re.compile("warning: hostname .* does not resolve to address .*: Name or service not known") ################# # Ready the journal ################# j = journal.Reader() j.log_level(journal.LOG_INFO) # TODO: Find when the last time this was run instead yesterday = datetime.now() - timedelta(days=1, minutes=10) j.seek_realtime(yesterday) mail_content = [] service_entries = {key: [] for key in ('attic', 'pacupdate', 'mail', 'timesyncd', 'sshd')} attic_count = 0 package_count = None ################# # Scan through the journal, filter out anything notable ################# for entry in j: # A log doesn't have a message...? weird if 'MESSAGE' not in entry: line = '{} {}[{}]: empty' line = line.format(datetime.ctime(entry['__REALTIME_TIMESTAMP']), entry['PRIORITY'], entry['SYSLOG_IDENTIFIER']) mail_content.append(line) # With systemd unit name elif '_SYSTEMD_UNIT' in entry: if entry['_SYSTEMD_UNIT'] in ("udisks.service", "polkit.service", "avahi-daemon.service", "bluetooth.service", "accounts-daemon.service", "rtkit-daemon.service", "dbus.service", "lightdm.service", "systemd-udevd.service", "*****@*****.**", "mkinitcpio-generate-shutdown-ramfs.service"): pass elif user_session.match(entry['_SYSTEMD_UNIT']): pass elif "btsync" in entry['_SYSTEMD_UNIT']: if btsync_deverr.match(entry['MESSAGE']): pass elif entry['_SYSTEMD_UNIT'] == 'systemd-journald.service': if journal_restart.match(entry['MESSAGE']): pass elif entry['_SYSTEMD_UNIT'] == 'systemd-logind.service': if login_buttons.match(entry['MESSAGE']): pass elif session.match(entry['_SYSTEMD_UNIT']): pass # elif sshUnit.match(entry['_SYSTEMD_UNIT']): # if sshAcceptPublicKey.match(entry['MESSAGE']): # pass # elif sshReceivedDisconnect.match(entry['MESSAGE']): # pass # elif entry['_SYSTEMD_UNIT'] == "systemd-logind.service": # if logindNewSession.match(entry['MESSAGE']): # pass # elif entry['_SYSTEMD_UNIT'] == "postfix.service": # if postfixHostnameDoesNotResolve.match(entry['MESSAGE']): # pass # Attic elif "attic" in entry['_SYSTEMD_UNIT']: if attic_backup.match(entry['MESSAGE']): attic_count += 1 service_entries['attic'].append('U %s %s %s %s[%s]: %s' % ( entry['__REALTIME_TIMESTAMP'].strftime("%a %b %d %I:%m:%S %p"), entry['PRIORITY'], entry['_SYSTEMD_UNIT'], entry.get('SYSLOG_IDENTIFIER', 'UNKNOWN'), entry['_PID'], entry['MESSAGE'] )) # Count packages elif entry['_SYSTEMD_UNIT'] == 'pacupdate.service': match = packages_found.match(entry['MESSAGE']) if match: package_count = match.group(1) service_entries['pacupdate'].append('U %s %s %s %s[%s]: %s' % ( entry['__REALTIME_TIMESTAMP'].strftime("%a %b %d %I:%m:%S %p"), entry['PRIORITY'], entry['_SYSTEMD_UNIT'], entry.get('SYSLOG_IDENTIFIER', 'UNKNOWN'), entry['_PID'], entry['MESSAGE'] )) # timesyncd elif entry['_SYSTEMD_UNIT'] == 'systemd-timesyncd.service': service_entries['timesyncd'].append('U %s %s %s %s[%s]: %s' % ( entry['__REALTIME_TIMESTAMP'].strftime("%a %b %d %I:%m:%S %p"), entry['PRIORITY'], entry['_SYSTEMD_UNIT'], entry.get('SYSLOG_IDENTIFIER', 'UNKNOWN'), entry['_PID'], entry['MESSAGE'] )) # sshd elif ssh_unit.match(entry['_SYSTEMD_UNIT']): service_entries['sshd'].append('U %s %s %s %s[%s]: %s' % ( entry['__REALTIME_TIMESTAMP'].strftime("%a %b %d %I:%m:%S %p"), entry['PRIORITY'], entry['_SYSTEMD_UNIT'], entry.get('SYSLOG_IDENTIFIER', 'UNKNOWN'), entry['_PID'], entry['MESSAGE'] )) # dovecot elif entry['_SYSTEMD_UNIT'] == 'dovecot.service': service_entries['mail'].append('U %s %s %s %s[%s]: %s' % ( entry['__REALTIME_TIMESTAMP'].strftime("%a %b %d %I:%m:%S %p"), entry['PRIORITY'], entry['_SYSTEMD_UNIT'], entry.get('SYSLOG_IDENTIFIER', 'UNKNOWN'), entry['_PID'], entry['MESSAGE'] )) # postfix elif entry['_SYSTEMD_UNIT'] == 'postfix.service': service_entries['mail'].append('U %s %s %s %s[%s]: %s' % ( entry['__REALTIME_TIMESTAMP'].strftime("%a %b %d %I:%m:%S %p"), entry['PRIORITY'], entry['_SYSTEMD_UNIT'], entry.get('SYSLOG_IDENTIFIER', 'UNKNOWN'), entry['_PID'], entry['MESSAGE'] )) # other mail types elif entry['_SYSTEMD_UNIT'] in ('opendkim.service', 'spamassassin.service'): service_entries['mail'].append('U %s %s %s %s[%s]: %s' % ( entry['__REALTIME_TIMESTAMP'].strftime("%a %b %d %I:%m:%S %p"), entry['PRIORITY'], entry['_SYSTEMD_UNIT'], entry.get('SYSLOG_IDENTIFIER', 'UNKNOWN'), entry['_PID'], entry['MESSAGE'] )) else: mail_content.append('U %s %s %s %s[%s]: %s' % ( entry['__REALTIME_TIMESTAMP'].strftime("%a %b %d %I:%m:%S %p"), entry['PRIORITY'], entry['_SYSTEMD_UNIT'], entry.get('SYSLOG_IDENTIFIER', 'UNKNOWN'), entry['_PID'], entry['MESSAGE'] )) # With syslog identifier only elif entry['SYSLOG_IDENTIFIER'] in ("systemd", "kernel", "bluetoothd", "systemd-sysctl", "systemd-journald", "systemd-udevd", "ntpd", "mtp-probe"): pass # if sshSocketStart.match(entry['MESSAGE']): # pass # # elif firewalldStart.match(entry['MESSAGE']): # # pass # elif entry['SYSLOG_IDENTIFIER'] == "sshd": # if sshdSessionClosed.match(entry['MESSAGE']): # pass # elif entry['SYSLOG_IDENTIFIER'] == "sudo": # if sessionOpenedRoot.match(entry['MESSAGE']): # pass # elif entry['SYSLOG_IDENTIFIER'] == "postfix/anvil": # if postfixStatistics.match(entry['MESSAGE']): # pass # elif entry['SYSLOG_IDENTIFIER'] == "su": # if suSessionClosedGit.match(entry['MESSAGE']): # pass else: mail_content.append('S %s %s %s: %s' % ( entry['__REALTIME_TIMESTAMP'].strftime("%a %b %d %I:%m:%S %p"), entry['PRIORITY'], entry.get('SYSLOG_IDENTIFIER', 'UNKNOWN'), entry['MESSAGE'] )) # Create summary message mail_summary = "Daily journalwatch\n\n" if attic_count: mail_summary += "attic backed up {} times".format(attic_count) if package_count: mail_summary += "pacupdate found {} packages to update\n".format(package_count) for service in ('attic', 'pacupdate', 'sshd', 'mail', 'timesyncd'): mail_summary += '\n=====================\n' mail_summary += '{} logs:\n'.format(service) mail_summary += '\n'.join(service_entries[service]) mail_summary += '\n' mail_summary += '\n=====================\n' mail_summary += "Remaining filtered log from {} to now follows:\n".format(yesterday) # TODO: Also count ssh, nginx, dovecot, postfix info (logins passed and failed, etc) ################# # Send email ################# # Make sure UTF-8 is quoted-printable, not base64 # http://stackoverflow.com/questions/9403265/how-do-i-use-python-3-2-email-module-to-send-unicode-messages-encoded-in-utf-8-w/9509718#9509718 charset.add_charset('utf-8', charset.QP, charset.QP) mail = MIMEText(mail_summary + '\n'.join(mail_content)) mail['Subject'] = config['subject'] mail['To'] = config['to'] mail['From'] = config['from'] mail['Date'] = email.utils.formatdate(localtime=True) mail['Message-ID'] = email.utils.make_msgid() mail['User-Agent'] = __file__ if args.no_send: print(mail.as_string()) else: tls_context = ssl.create_default_context() tls_context.check_hostname = True with SMTP(config['smtp_host'], config['smtp_port']) as smtp: # smtp.set_debuglevel(True) smtp.starttls(context=tls_context) smtp.login(config['smtp_user'], config['smtp_pass']) smtp.send_message(mail) return
from twisted.internet import reactor from twisted.python import log as twlog from zope.interface import implements try: from twisted.mail.smtp import ESMTPSenderFactory ESMTPSenderFactory = ESMTPSenderFactory # for pyflakes except ImportError: ESMTPSenderFactory = None # this incantation teaches email to output utf-8 using 7- or 8-bit encoding, # although it has no effect before python-2.7. from email import charset charset.add_charset("utf-8", charset.SHORTEST, None, "utf-8") from buildbot import config from buildbot import interfaces from buildbot import util from buildbot.process.properties import Properties from buildbot.reporters import utils from buildbot.reporters.message import MessageFormatter as DefaultMessageFormatter from buildbot.status.results import CANCELLED from buildbot.status.results import EXCEPTION from buildbot.status.results import FAILURE from buildbot.status.results import Results from buildbot.status.results import SUCCESS from buildbot.status.results import WARNINGS from buildbot.util import service
def perform(self, req, summary): if summary is None: return False config = self.env.config encoding = 'utf-8' subject = self.subject if not config.getbool('notification', 'smtp_enabled'): return False from_email = config['notification'].get('smtp_from') from_name = config['notification'].get('smtp_from_name') replyto_email = config['notification'].get('smtp_replyto') from_email = from_email or replyto_email if not from_email: return False # Authentication info (optional) user_name = config['notification'].get('smtp_user') password = config['notification'].get('smtp_password') # Thanks to the author of this recipe: # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/473810 add_charset('utf-8', SHORTEST, None, None) projname = config.get('project', 'name') # Create the root message and fill in from, to, and subject headers msg_root = MIMEMultipart('alternative') msg_root['To'] = str(', ').join(self.emails) msg_root['X-Mailer'] = 'ClientsPlugin for Trac' msg_root['X-Trac-Version'] = __version__ msg_root['X-Trac-Project'] = projname msg_root['Precedence'] = 'bulk' msg_root['Auto-Submitted'] = 'auto-generated' msg_root['Subject'] = subject msg_root['From'] = '%s <%s>' % (from_name or projname, from_email) msg_root['Reply-To'] = replyto_email msg_root.preamble = 'This is a multi-part message in MIME format.' view = 'plain' arg = "'%s'" % view result = self.transform(summary, view=arg) msg_text = MIMEText(str(result), view, encoding) msg_root.attach(msg_text) msg_related = MIMEMultipart('related') msg_root.attach(msg_related) view = 'html' arg = "'%s'" % view result = self.transform(summary, view=arg) # file = open('/tmp/send-client-email.html', 'w') # file.write(str(result)) # file.close() msg_text = MIMEText(str(result), view, encoding) msg_related.attach(msg_text) # Handle image embedding... view = 'images' arg = "'%s'" % view result = self.transform(summary, view=arg) if result: images = result.getroot() if images is not None: for img in images: if 'img' != img.tag: continue if not img.get('id') or not img.get('src'): continue with open(img.get('src'), 'rb') as fp: if not fp: continue msg_img = MIMEImage(fp.read()) msg_img.add_header('Content-ID', '<%s>' % img.get('id')) msg_related.attach(msg_img) # Send the email import smtplib smtp = smtplib.SMTP() # smtp_server, smtp_port) if False and user_name: smtp.login(user_name, password) smtp.connect() smtp.sendmail(from_email, self.emails, msg_root.as_string()) smtp.quit() return True
import mimetypes from email import utils from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email import encoders, charset from email.mime.audio import MIMEAudio from email.mime.base import MIMEBase from email.mime.image import MIMEImage from email.header import Header from email import base64mime from sendgrid import exceptions # Overwrite how utf-8 bodies are handled, instead of base64encoding use # quote-printable charset.add_charset('utf-8', charset.QP, charset.QP, 'utf-8') class Smtp(object): """ Transport to send emails using smtp """ HOSTPORT = ('smtp.sendgrid.net', 587) def __init__(self, username, password, **opts): """ Construct smtp transport object Args: username: Sendgrid uaername password: Sendgrid password
"""Send notification emails.""" from typing import Optional, Dict, Any, Union, Iterable import aiosmtplib import jinja2 from email import charset charset.add_charset('utf-8', charset.SHORTEST, charset.QP) # type: ignore # noinspection PyPep8 from email.mime.text import MIMEText import asyncio # noinspection PyPep8 from irisett import ( log, ) async def send_email(loop: asyncio.AbstractEventLoop, mail_from: str, mail_to: Union[Iterable, str], subject: str, body: str, server: str = 'localhost') -> None: """Send an email to one or more recipients. Only supports plain text emails with a single message body. No attachments etc. """ if type(mail_to) == str: mail_to = [mail_to] smtp = aiosmtplib.SMTP(hostname=server, port=25, loop=loop) try:
} db = SQLAlchemy(metadata=MetaData(naming_convention=naming_convention)) def include_object(object, name, type_, reflected, compare_to): if (type_, name, reflected) == ("table", "spatial_ref_sys", True): return False return True # Force Quoted-Printable encoding for emails. # The flask-mail package sets the header encoding to "SHORTEST" and the body encoding # to None. Somehow this, combined with Postmark, results in the email body being wrapped # twice, which results in ugly plaintext emails. charset.add_charset("utf-8", charset.QP, charset.QP, "utf-8") cache = Cache() csrf = CSRFProtect() migrate = Migrate(include_object=include_object) manager = VersioningManager(options={"strategy": "subquery"}) make_versioned(manager=manager, plugins=[FlaskPlugin()]) mail = Mail() login_manager = LoginManager() static_digest = FlaskStaticDigest() toolbar = DebugToolbarExtension() gocardless_client = None volunteer_admin = None def create_app(dev_server=False, config_override=None):
from email.mime.text import MIMEText from email.header import Header from email.utils import formatdate, formataddr, make_msgid, parseaddr from functools import wraps from .._compat import PY2, string_types, to_bytes, to_unicode from ..libs.contenttype import contenttype from ..extensions import Extension from ..utils import cachedprop if PY2: message_policy = None else: from email import policy message_policy = policy.SMTP _charsetreg.add_charset('utf-8', _charsetreg.SHORTEST, None, 'utf-8') def _has_newline(line): if line and ('\r' in line or '\n' in line): return True return False def sanitize_subject(subject, encoding='utf-8'): try: subject.encode('ascii') except UnicodeEncodeError: subject = Header(subject, encoding).encode() return subject
def send_email(success, runtime): """send email notification Arguments: success {bool} -- processing was successful runtime {sting} -- script runtime """ try: import smtplib from email.mime.text import MIMEText from email import charset except ImportError as e: raise ImportError(f"Cannot import {e}") if not config['email.smtp']['host']: raise ValueError("Failed to send eMail because smtp Host is not set") if not config['email']['from']: raise ValueError("Failed to send eMail because 'from' is not set") if not config['email']['to']: raise ValueError("Failed to send eMail because 'to' is not set") # use quoted-printable instead of the default base64 charset.add_charset("utf-8", charset.SHORTEST, charset.QP) body = f"snapraid_runner finished in {runtime}.\n\n" if success: body += "SnapRAID job completed successfully:\n\n\n" else: body += "Error during SnapRAID job:\n\n\n" if mail_log: log = mail_log.getvalue() maxsize = config['email']['maxsize'] * 1024 if maxsize and len(log) > maxsize: log = ("NOTE: Log was too big for email and was shortened\n\n" "{START}[...]\n\n\n" "--- LOG WAS TOO BIG - ~{LINES} LINES REMOVED --\n\n\n" "[...]{END}".format( START=log[:maxsize // 2], LINES=(log.count("\n", maxsize // 2, -maxsize // 2) + 1), END=log[(-maxsize // 2):])) body += log msg = MIMEText(body, "plain", "utf-8") msg['subject'] = (config['email']['subject'].replace( "{STATE}", "SUCCESS" if success else "ERROR").replace("{RUNTIME}", runtime)) msg['From'] = config['email']['from'] msg['To'] = config['email']['to'] smtp = {'host': config['email.smtp']['host']} if config['email.smtp']['port']: smtp['port'] = config['email.smtp']['port'] server = None try: if config["email.smtp"]["ssl"]: server = smtplib.SMTP_SSL(**smtp) else: server = smtplib.SMTP(**smtp) if config['email.smtp']['tls']: server.starttls() if config['email.smtp']['user']: server.login(user=config['email.smtp']['user'], password=config['email.smtp']['password']) server.sendmail(from_addr=config['email']['from'], to_addrs=[config['email']['to']], msg=msg.as_string()) except Exception as e: raise Exception(e) finally: if server: server.quit()
def sendmail(self, account, recipients, subject, body, attachments, smtp_host, smtp_port, html): """ :param account: Account or nothing for anon. :param recipients: str("*****@*****.**"), Account list of (Account or string). :param subject: str("My Subject"). :param body: str("My Body"). :param attachments: file or list of file. :param smtp_host: str("localhost"). :param smtp_port: int(25). :param html: allow html into mail body (booleen). """ charset.add_charset('utf-8', charset.SHORTEST, charset.QP) # Verify account account_firstname = account.firstname account_lastname = account.lastname account_mail = account.mail if not account_mail: self.logger.info( 'No mail adress for this user (Fill the mail account field)') account_mail = '{0}@{1}'.format(account.user, socket.gethostname()) if isinstance(account_mail, (list, tuple)): account_mail = account_mail[0] if not account_lastname and not account_firstname: account_full_mail = '"{0}" <{1}>'.format( account_mail.split('@')[0].title(), account_mail) else: account_full_mail = account.get_full_mail() if not re.match("^[a-zA-Z0-9._%-]+@[a-zA-Z0-9._%-]+.([a-zA-Z]{2,6})?$", str(account_mail)): return ( 2, 'Invalid Email format for sender: {0}'.format(account_mail)) # Verify recipients if not recipients: return (2, 'No recipients configured') if not isinstance(recipients, list): recipients = [recipients] dests = [] for dest in recipients: if isinstance(dest, basestring): if re.match( "^[a-zA-Z0-9._%-]+@[a-zA-Z0-9._%-]+.([a-zA-Z]{2,6})?$", dest): dest_mail = dest dest_full_mail = '"{0}" <{1}>'.format( dest_mail.split('@')[0].title(), dest_mail) dests.append(dest_full_mail) else: self.logger.error( 'Ignoring invalid recipient: {0}'.format(dest)) dests_str = ', '.join(dests) # Verify attachments if attachments: storage = Storage(account=account, namespace='object') if not isinstance(attachments, list): attachments = [attachments] # Send msg = MIMEMultipart() msg["From"] = account_full_mail msg["To"] = dests_str msg["Subject"] = subject if html: msg.attach(MIMEText(body, 'html', _charset='utf-8')) else: msg.attach(MIMEText(body, 'plain', _charset='utf-8')) msg['Date'] = formatdate(localtime=True) if attachments: for _file in attachments: part = MIMEBase('application', "octet-stream") #meta_file = _file.get(storage) content_file = _file.get(storage) part.set_payload(content_file) Encoders.encode_base64(part) part.add_header( 'Content-Disposition', 'attachment; filename="%s"' % _file.data['file_name']) part.add_header('Content-Type', _file.data['content_type']) msg.attach(part) sock = socket.socket() try: sock.connect((smtp_host, smtp_port)) except Exception as err: return (2, 'Connection to SMTP <{0}:{1}> failed: {2}'.format( smtp_host, smtp_port, err)) try: server = smtplib.SMTP(smtp_host, smtp_port) server.sendmail(account_full_mail, dests, msg.as_string()) server.quit() except Exception as err: return (2, "Impossible to send mail: {0}".format(err)) return (0, "Mail sent successfully")
assignments = parse_assigment_columns(args.assignment_columns.split(','), email_column, sheet.ncols) assignments = list(flatten(assignments)) if args.verbose: print('Will send grades for: ', assignments) subject = course_prefix.upper() + '-' + str(args.course_id) + ' Βαθμολογίες ( ' # add info about which assignments' grades are sent for col in assignments: subject = subject + str(sheet.cell(header_row, col).value) + ' ' subject = subject + ')' charset.add_charset('utf-8', charset.BASE64, charset.BASE64) if args.verbose: print('Subject: ', subject) # for all rows bellow the header for row in range(header_row + 1, sheet.nrows): to = sheet.cell(row, email_column).value if args.verbose: print('Sending to: ', to) if not is_valid_email(to): raise Exception('\"' + to + '\" is not a valid e-mail address') text = 'Καλησπέρα,\n\n'
from django.db.models import Q from django.template import loader, Context from django.utils.translation import get_language, ugettext as _ from django.utils import translation from livesettings import config_value from custom_comments.models import CommentExmo from .celery_tasks import send_email, send_org_email from .models import UserProfile, Organization, MONITORING_INTERACTION, MONITORING_FINALIZING # TRAC BUG 2299 # Django BUG https://code.djangoproject.com/ticket/22561 # Revert django/core/mail/message.py hack. Use BASE64 to encode UTF-8 messages. from email import charset as Charset Charset.add_charset('utf-8', Charset.SHORTEST, Charset.BASE64, 'utf-8') class ExmoEmail(EmailMultiAlternatives): def __init__(self, *args, **kwargs): template_basename = kwargs.pop('template_basename') context = Context(dict(kwargs.pop('context'), subject=kwargs['subject'])) body_txt = loader.get_template(template_basename + '.txt').render(context) body_html = loader.get_template(template_basename + '.html').render(context) kwargs.update( body=body_txt, alternatives=[(body_html, "text/html")], from_email=kwargs.get('from_email', config_value('EmailServer', 'DEFAULT_FROM_EMAIL')))
from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email.mime.text import MIMEText from email.header import Header from email.generator import Generator import email.charset as Charset import email.encoders as Encoders # DEFINE SENDMAIL CONFIG sendmail = 0 sendmail_file = open("/etc/setoolkit/set.config", "r").readlines() from src.core.setcore import * Charset.add_charset('utf-8', Charset.BASE64, Charset.BASE64, 'utf-8') # Specify if its plain or html message_flag = "plain" for line in sendmail_file: # strip carriage returns line = line.rstrip() match = re.search("SENDMAIL=", line) if match: # if match and if line is flipped on continue on if line == ("SENDMAIL=ON"): print_info( "Sendmail is a Linux based SMTP Server, this can be used to spoof email addresses." ) print_info("Sendmail can take up to three minutes to start FYI.")
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.application import MIMEApplication from email.mime.text import MIMEText from email import charset from indico.core.config import Config from indico.util.string import to_unicode from MaKaC.errors import MaKaCError from MaKaC.i18n import _ from indico.core.logger import Logger from MaKaC.common.contextManager import ContextManager # Prevent base64 encoding of utf-8 e-mails charset.add_charset('utf-8', charset.SHORTEST) class GenericMailer: @classmethod def send(cls, notification, skipQueue=False): if isinstance(notification, dict): # Wrap a raw dictionary in a notification class from MaKaC.webinterface.mail import GenericNotification notification = GenericNotification(notification) # enqueue emails if we have a rh and do not skip queuing, otherwise send immediately rh = ContextManager.get('currentRH', None) mailData = cls._prepare(notification) if mailData:
from buildbot import util from buildbot.process.properties import Properties from buildbot.process.results import CANCELLED from buildbot.process.results import EXCEPTION from buildbot.process.results import FAILURE from buildbot.process.results import SUCCESS from buildbot.process.results import WARNINGS from buildbot.process.results import Results from buildbot.reporters import utils from buildbot.reporters.message import MessageFormatter as DefaultMessageFormatter from buildbot.reporters.message import MessageFormatterMissingWorker from buildbot.util import service from buildbot.util import ssl from buildbot.util import unicode2bytes charset.add_charset('utf-8', charset.SHORTEST, None, 'utf-8') try: from twisted.mail.smtp import ESMTPSenderFactory ESMTPSenderFactory = ESMTPSenderFactory # for pyflakes except ImportError: ESMTPSenderFactory = None # Email parsing can be complex. We try to take a very liberal # approach. The local part of an email address matches ANY non # whitespace character. Rather allow a malformed email address than # croaking on a valid (the matching of domains should be correct # though; requiring the domain to not be a top level domain). With # these regular expressions, we can match the following: # # [email protected]
from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email.mime.text import MIMEText from email.header import Header from email.generator import Generator import email.charset as Charset import email.encoders as Encoders # DEFINE SENDMAIL CONFIG sendmail = 0 sendmail_file = open("/etc/setoolkit/set.config", "r").readlines() from src.core.setcore import * Charset.add_charset('utf-8', Charset.BASE64, Charset.BASE64, 'utf-8') # Specify if its plain or html message_flag = "plain" for line in sendmail_file: # strip carriage returns line = line.rstrip() match = re.search("SENDMAIL=", line) if match: # if match and if line is flipped on continue on if line == ("SENDMAIL=ON"): print_info( "Sendmail is a Linux based SMTP Server, this can be used to spoof email addresses.") print_info("Sendmail can take up to three minutes to start FYI.") print_status("Sendmail is set to ON")
from email.utils import formatdate, parseaddr, formataddr from html2text import html2text from markdown2 import markdown from blazeutils.helpers import tolist import six from blazeweb.globals import settings from blazeweb.exceptions import SettingsError from blazeweb.utils.encoding import smart_str, force_unicode log = logging.getLogger(__name__) # Don't BASE64-encode UTF-8 messages so that we avoid unwanted attention from # some spam filters. charset.add_charset('utf-8', charset.SHORTEST, charset.QP, 'utf-8') # Default MIME type to use on attachments (if it is not explicitly given # and cannot be guessed). DEFAULT_ATTACHMENT_MIME_TYPE = 'application/octet-stream' # Cache the hostname, but do it lazily: socket.getfqdn() can take a couple of # seconds, which slows down the restart of the server. class CachedDnsName(object): def __str__(self): return self.get_fqdn() def get_fqdn(self): if not hasattr(self, '_fqdn'): self._fqdn = socket.getfqdn()
# BBB Python 2 vs 3 compat try: unicode except NameError: # pragma: no cover basestring = (bytes, str) else: basestring = (str, unicode) from email.mime.multipart import MIMEMultipart from email.mime.nonmultipart import MIMENonMultipart from email import charset charset.add_charset('utf-8', charset.SHORTEST, charset.QP, 'utf-8') charset.add_charset('utf8', charset.SHORTEST, charset.QP, 'utf8') from pyramid_mailer.response import encode_string, MailResponse from pyramid_mailer.exceptions import BadHeaders from pyramid_mailer.exceptions import InvalidMessage def attachment_to_message(attachment): mtype, stype = attachment.content_type.split('/') if attachment.filename: msg = MIMENonMultipart(mtype, stype, name=attachment.filename) else: msg = MIMENonMultipart(mtype, stype) if attachment.disposition: if attachment.filename: msg.add_header('Content-Dispsition', attachment.disposition, filename=attachment.filename)
def send_message( self, sender: str, recipients: str, subject: str = "", body: str = "", attachments: str = None, html: bool = False, images: str = None, ) -> bool: """Send SMTP email :param sender: who is sending, ie. 'from' :param recipients: who is receiving, ie. 'to' :param subject: mail subject field :param body: mail body content :param attachments: list of filepaths to attach, defaults to [] :param html: if message content is in HTML, default `False` :param images: list of filepaths for inline use, defaults to [] Valid sender values: - First Lastname <address@domain> - address@domain Example: .. code-block:: robotframework Send Message [email protected] [email protected] ... subject=Greetings Software Robot Developer ... body=${email_body} ... attachments=${CURDIR}${/}report.pdf """ add_charset("utf-8", QP, QP, "utf-8") recipients, attachments, images = self._handle_message_parameters( recipients, attachments, images) msg = MIMEMultipart() self._add_attachments_to_msg(attachments, msg) msg["From"] = sender msg["To"] = ",".join(recipients) msg["Subject"] = Header(subject, "utf-8") if html: for im in images: im = im.strip() imname = Path(im).name body = body.replace(str(imname), f"cid:{imname}") with open(im, "rb") as f: img = MIMEImage(f.read()) img.add_header("Content-ID", f"<{imname}>") msg.attach(img) htmlpart = MIMEText(body, "html", "UTF-8") msg.attach(htmlpart) else: textpart = MIMEText(body, "plain", "UTF-8") msg.attach(textpart) for im in images: im = im.strip() imname = Path(im).name with open(im, "rb") as f: img = MIMEImage(f.read()) msg.add_header( "Content-Disposition", f"inline; filename= {imname}", ) msg.attach(img) # Create a generator and flatten message object to 'file’ str_io = StringIO() g = Generator(str_io, False) g.flatten(msg) try: self.smtp_conn.sendmail(sender, recipients, str_io.getvalue()) except Exception as err: raise ValueError(f"Send Message failed: {err}") from err return True
# -*- coding: utf-8 -*- from threading import Thread from flask import current_app from flask.ext.mail import Message from . import mail from email import charset charset.add_charset('utf-8', charset.SHORTEST, charset.BASE64, 'utf-8') #解决邮件不能使用中文问题 def send_async_email(app, msg): with app.app_context(): mail.send(msg) def send_email(recipients, body, html): app = current_app._get_current_object() #msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + ' ' + subject, # sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to]) msg = Message( '[理工]' + '通知信件', recipients=[recipients], charset='utf-8') #Message(主题,发件人,收件人,charset='utf-8'(解决邮件不能使用中文问题 )) #msg.body = render_template(template + '.txt', **kwargs) #msg.html = render_template(template + '.html', **kwargs) msg.body = body msg.html = html #mail.send(msg) thr = Thread(target=send_async_email, args=[app, msg]) #print(body) #print(html) thr.start()
def send_mailout(subject, body): """ Sends email with supplied subject/body to all members who have an email address, and who have mailout==True and mailout_failed=False. Requires subject and body to be unicode. Also sends an email to settings.MAILOUT_DELIVERY_REPORT_TO when done. returns a tuple: (error, sent_count, error_message) where error is True if an error occurred. """ # Configure to 'intelligently' use shortest encoding for subject, but just # send body of email as 8 bit plain. (This was the default behaviour in # Django 1.5.x - retain it so as not to rock the boat for mail delivery) charset.add_charset('utf-8', charset.SHORTEST, None, 'utf-8') header_template = u"Dear {0},\n\n" signature_template = ( u"\n" + u"\n" + u"If you wish to be removed from our mailing list please use this link:\n" + u"http://{0}{{0}}?k={{2}}\n" + u"To edit details of your membership, please use this link:\n" + u"http://{0}{{1}}?k={{2}}\n" ).format(settings.EMAIL_UNSUBSCRIBE_HOST) recipients = Member.objects.mailout_recipients() count = recipients.count() sent = 0 one_percent = count // 100 or 1 if count == 0: logger.error("No recipients found") return (True, 0, 'No recipients found') logger.info("Sending mailout to {0} recipients".format(count)) # Open connection to SMTP server: try: smtp_conn = smtplib.SMTP(settings.EMAIL_HOST, settings.EMAIL_PORT) except Exception as exc: msg = "Failed to connect to SMTP server: {0}".format(exc) logger.error(msg) return (True, 0, msg) # Cache if body is 7 bit clean (will need to check each sender name, but # save a bit of time by not scanning everything) body_is_ascii = string_is_ascii(body) and string_is_ascii(signature_template) err_list = [] # XXX XXX XXX # Uncomment the following line if you want to disable mailout for testing # return (True, 0, 'DISABLED UNTIL READY') try: for recipient in recipients: # Nb; this is not the email header, it's just the "Dear XYZ" # bit at the top of the mail: header = header_template.format( recipient.name ) # Build per-recipient signature, with customised unsubscribe links: signature = signature_template.format( reverse("unsubscribe-member", args=(recipient.pk,)), reverse("edit-member", args=(recipient.pk,)), recipient.mailout_key, ) # Build final email, still in unicode: mail_body = header + body + signature mail_is_ascii = body_is_ascii and string_is_ascii(header) error = _send_email(smtp_conn, recipient.email, subject, mail_body, mail_is_ascii) if error: err_list.append(error) sent += 1 if sent % one_percent == 0: progress = int((100.0 * sent) / count) + 1 current_task.update_state(state='PROGRESS{0:03}'.format(progress), meta={'sent': sent, 'total': count}) # All done? Send report: report = "{0} copies of the following were sent out on cube members list\n".format(sent) if len(err_list) > 0: # Only send a max of 100 error messages! report += "{0} errors:\n{1}".format(len(err_list), "\n".join(err_list[:100])) if len(err_list) > 100: report += "(Error list truncated at 100 entries)\n" report += "\n" report += body _send_email(smtp_conn, unicode(settings.MAILOUT_DELIVERY_REPORT_TO), subject, report, body_is_ascii) except Exception as exc: logger.exception("Mailout job failed, {0}".format(exc)) return (True, sent, "Mailout job died: {0}".format(exc)) finally: try: smtp_conn.quit() except smtplib.SMTPException as smtpe: logger.error("SMTP Quit failed: {0}".format(smtpe)) return (False, sent, 'Ok')
import time import unicodedata from inspect import Parameter from email import charset, policy from email.encoders import encode_base64 from email.mime.base import MIMEBase from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.header import Header from email.utils import formatdate, formataddr, make_msgid, parseaddr from molten import Settings from .exceptions import MailUnicodeDecodeError, BadHeaderError charset.add_charset("utf-8", charset.SHORTEST, None, "utf-8") def force_text(s, encoding="utf-8", errors="strict"): if isinstance(s, str): return s try: if not isinstance(s, str): if isinstance(s, bytes): s = s.decode(encoding, errors) else: s = str(s) except UnicodeDecodeError as e: try:
""" Helpers & Utils """ from email import charset from email.header import Header from email.utils import formataddr # Add charset to the global registry, since we're only using unicode here # NOTE: global effect! charset.add_charset('utf-8', charset.SHORTEST, None, 'utf-8') def unicode_header(*args, **kwargs): """ Shortcut to create a unicode Header() string. :rtype: str """ return str(Header(*args, charset='utf-8', **kwargs)) class Address(object): """ E-Mail address :param arg: e-mail address, or a 2-tuple (email, name) :type arg: basestring|tuple[basestring] """ def __init__(self, arg): if isinstance(arg, basestring): self.email = arg self.name = None
if six.PY3: from email import charset as Charset from email.header import Header from email.encoders import encode_base64 from email.utils import formatdate, parseaddr, formataddr else: from email import Charset from email.Header import Header from email.Encoders import encode_base64 from email.Utils import formatdate, parseaddr, formataddr logger = logging.getLogger(__name__) # Don't BASE64-encode UTF-8 messages so that we avoid unwanted attention from # some spam filters. Charset.add_charset('utf-8', Charset.SHORTEST, Charset.QP, 'utf-8') # Default MIME type to use on attachments (if it is not explicitly given # and cannot be guessed). DEFAULT_ATTACHMENT_MIME_TYPE = 'application/octet-stream' # Default charset DEFAULT_CHARSET = 'utf-8' # Cache the hostname, but do it lazily: socket.getfqdn() can take a couple of # seconds, which slows down the restart of the server. class CachedDnsName(object): def __str__(self): return self.get_fqdn()