国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python基于smtplib實現異步發送郵件服務

2020-02-23 01:27:06
字體:
來源:轉載
供稿:網友

基于smtplib包制作而成,但在實踐中發現一個不知道算不算是smtplib留的一個坑,在網絡斷開的情況下發送郵件時會拋出一個socket.gaierror的異常,但是smtplib中并沒有捕獲這個異常,導致程序會因這個異常終止,因此代碼中針對這部分的異常進行處理,確保不會異常終止。

#!/usr/bin/env python# -*- coding: utf-8 -*-__author__ = 'Zoa Chou'# see http://www.mudoom.com/Article/show/id/29.html for detailimport loggingimport smtplibimport mimetypesimport socketfrom email import encodersfrom email.header import Headerfrom email.mime.text import MIMEText, MIMENonMultipartfrom email.mime.base import MIMEBasefrom email.utils import parseaddr, formataddrclass Mailer(object):  def __init__(self):    pass  def send_mail(self, smtp_server, from_address, to_address, subject, body, files=None):    """    發送郵件主程序    :param smtp_server: dict 郵件服務器設置      :keyword host: string smtp服務器地址      :keyword port: int smtp服務器端口號      :keyword user: string 用戶名      :keyword passwd: string 密碼      :keyword ssl: bool 是否啟用ssl,默認False      :keyword timeout: int 超時時間,默認10s    :param from_address: 發件人郵箱    :param to_address: 收件人郵箱    :param subject: 郵件標題    :param body: 郵件內容    :param files: 附件    :raise: NetworkError/MailerException    """    # 格式化郵件內容    body = self._encode_utf8(body)    # 郵件類型    content_type = 'html' if body.startswith('<html>') else 'plain'    msg = MIMENonMultipart() if files else MIMEText(body, content_type, 'utf-8')    # 格式化郵件數據    msg['From'] = self._format_address(from_address)    msg['To'] = ', '.join(self._format_list(to_address))    msg['subject'] = self._encode_utf8(subject)    # 構造附件數據    if files:      msg.attach(MIMEText(body, content_type, 'utf-8'))      cid = 0      for file_name, payload in files:        file_name = self._encode_utf8(file_name)        main_type, sub_type = self._get_file_type(file_name)        if hasattr(payload, 'read'):          payload = payload.read()        f_name = self._encode_header(file_name)        mime = MIMEBase(main_type, sub_type, filename=f_name)        mime.add_header('Content-Disposition', 'attachment', filename=f_name)        mime.add_header('Content-ID', '<%s>' % cid)        mime.add_header('X-Attachment-Id', '%s' % cid)        mime.set_payload(payload)        encoders.encode_base64(mime)        msg.attach(mime)        cid += 1    host = smtp_server.get('host')    port = smtp_server.get('port')    user = smtp_server.get('user')    passwd = smtp_server.get('passwd')    ssl = smtp_server.get('ssl', False)    time_out = smtp_server.get('timeout', 10)    # 沒有輸入端口則使用默認端口    if port is None or port == 0:      if ssl:        port = 465      else:        port = 25    logging.debug('Send mail form %s to %s' % (msg['From'], msg['To']))    try:      if ssl:        # 開啟ssl連接模式        server = smtplib.SMTP_SSL('%s:%d' % (host, port), timeout=time_out)      else:        server = smtplib.SMTP('%s:%d' % (host, port), timeout=time_out)      # 開啟調試模式      # server.set_debuglevel(1)      # 如果存在用戶名密碼則嘗試登錄      if user and passwd:        server.login(user, passwd)      # 發送郵件      server.sendmail(from_address, to_address, msg.as_string())      logging.debug('Mail sent success.')      # 關閉stmp連接      server.quit()    except socket.gaierror, e:      """ 網絡無法連接 """      logging.exception(e)      raise NetworkError(e)    except smtplib.SMTPServerDisconnected, e:      """ 網絡連接異常 """      logging.exception(e)      raise NetworkError(e)    except smtplib.SMTPException, e:      """ 郵件發送異常 """      logging.exception(e)      raise MailerException(e)  def _format_address(self, s):    """    格式化郵件地址    :param s:string 郵件地址    :return: string 格式化后的郵件地址    """    name, address = parseaddr(s)    return formataddr((self._encode_header(name), self._encode_utf8(address)))  def _encode_header(self, s):    """    格式化符合MIME的頭部數據    :param s: string 待格式化數據    :return: 格式化后的數據    """    return Header(s, 'utf-8').encode()  def _encode_utf8(self, s):    """    格式化成utf-8編碼    :param s: string 待格式化數據    :return: string 格式化后的數據    """    if isinstance(s, unicode):      return s.encode('utf-8')    else:      return s  def _get_file_type(self, file_name):    """    獲取附件類型    :param file_name: 附件文件名    :return: dict 附件MIME    """    s = file_name.lower()    pos = s.rfind('.')    if pos == -1:      return 'application', 'octet-stream'    ext = s[pos:]    mime = mimetypes.types_map.get(ext, 'application/octet-stream')    pos = mime.find('/')    if pos == (-1):      return mime, ''    return mime[:pos], mime[pos+1:]  def _format_list(self, address):    """    將收件人地址格式化成list    :param address: string/list 收件人郵箱    :return: list 收件人郵箱list    """    l = address    if isinstance(l, basestring):      l = [l]    return [self._format_address(s) for s in l]class MailerException(Exception):  """ 郵件發送異常類 """  passclass NetworkError(MailerException):  """ 網絡異常類 """  pass# test for @qq.comif __name__ == '__main__':  import sys  def prompt(prompt):    """    接收終端輸入的數據    """    sys.stdout.write(prompt + ": ")    return sys.stdin.readline().strip()  from_address = prompt("From(Only @qq.com)")  passwd = prompt("Password")  to_address = prompt("To").split(',')  subject = prompt("Subject")  print "Enter message, end with ^D:"  msg = ''  while 1:    line = sys.stdin.readline()    if not line:      break    msg = msg + line  print "Message length is %d" % len(msg)  # QQ郵箱默認設置  smtp_server = {'host': 'smtp.qq.com', 'port': None, 'user': from_address, 'passwd': passwd, 'ssl': True}  mailer = Mailer()  try:    mailer.send_mail(smtp_server, from_address, to_address, subject, msg)  except MailerException, e:    print(e)            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 芮城县| 南和县| 公安县| 铜川市| 上思县| 正蓝旗| 昌图县| 琼结县| 湖北省| 自贡市| 图木舒克市| 永和县| 利辛县| 海盐县| 安乡县| 南丰县| 平原县| 长泰县| 霞浦县| 望奎县| 达日县| 聂拉木县| 嘉义县| 永康市| 六盘水市| 宁化县| 临泉县| 基隆市| 高台县| 沂源县| 襄垣县| 乌兰察布市| 共和县| 固原市| 灵山县| 本溪| 隆林| 浙江省| 郯城县| 平果县| 洛川县|