最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python基于smtplib實(shí)現(xiàn)異步發(fā)送郵件服務(wù)

 更新時(shí)間:2015年05月28日 12:11:09   投稿:hebedich  
這篇文章主要介紹了Python基于smtplib實(shí)現(xiàn)異步發(fā)送郵件服務(wù),需要的朋友可以參考下

基于smtplib包制作而成,但在實(shí)踐中發(fā)現(xiàn)一個(gè)不知道算不算是smtplib留的一個(gè)坑,在網(wǎng)絡(luò)斷開的情況下發(fā)送郵件時(shí)會(huì)拋出一個(gè)socket.gaierror的異常,但是smtplib中并沒有捕獲這個(gè)異常,導(dǎo)致程序會(huì)因這個(gè)異常終止,因此代碼中針對(duì)這部分的異常進(jìn)行處理,確保不會(huì)異常終止。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

__author__ = 'Zoa Chou'
# see http://www.mudoom.com/Article/show/id/29.html for detail

import logging
import smtplib
import mimetypes
import socket
from email import encoders
from email.header import Header
from email.mime.text import MIMEText, MIMENonMultipart
from email.mime.base import MIMEBase
from email.utils import parseaddr, formataddr


class Mailer(object):
  def __init__(self):
    pass

  def send_mail(self, smtp_server, from_address, to_address, subject, body, files=None):
    """
    發(fā)送郵件主程序
    :param smtp_server: dict 郵件服務(wù)器設(shè)置
      :keyword host: string smtp服務(wù)器地址
      :keyword port: int smtp服務(wù)器端口號(hào)
      :keyword user: string 用戶名
      :keyword passwd: string 密碼
      :keyword ssl: bool 是否啟用ssl,默認(rèn)False
      :keyword timeout: int 超時(shí)時(shí)間,默認(rèn)10s
    :param from_address: 發(fā)件人郵箱
    :param to_address: 收件人郵箱
    :param subject: 郵件標(biāo)題
    :param body: 郵件內(nèi)容
    :param files: 附件
    :raise: NetworkError/MailerException
    """
    # 格式化郵件內(nèi)容
    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')
    # 格式化郵件數(shù)據(jù)
    msg['From'] = self._format_address(from_address)
    msg['To'] = ', '.join(self._format_list(to_address))
    msg['subject'] = self._encode_utf8(subject)

    # 構(gòu)造附件數(shù)據(jù)
    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)

    # 沒有輸入端口則使用默認(rèn)端口
    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)
      # 開啟調(diào)試模式
      # server.set_debuglevel(1)

      # 如果存在用戶名密碼則嘗試登錄
      if user and passwd:
        server.login(user, passwd)

      # 發(fā)送郵件
      server.sendmail(from_address, to_address, msg.as_string())

      logging.debug('Mail sent success.')

      # 關(guān)閉stmp連接
      server.quit()

    except socket.gaierror, e:
      """ 網(wǎng)絡(luò)無(wú)法連接 """
      logging.exception(e)
      raise NetworkError(e)

    except smtplib.SMTPServerDisconnected, e:
      """ 網(wǎng)絡(luò)連接異常 """
      logging.exception(e)
      raise NetworkError(e)

    except smtplib.SMTPException, e:
      """ 郵件發(fā)送異常 """
      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的頭部數(shù)據(jù)
    :param s: string 待格式化數(shù)據(jù)
    :return: 格式化后的數(shù)據(jù)
    """
    return Header(s, 'utf-8').encode()

  def _encode_utf8(self, s):
    """
    格式化成utf-8編碼
    :param s: string 待格式化數(shù)據(jù)
    :return: string 格式化后的數(shù)據(jù)
    """
    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):
  """ 郵件發(fā)送異常類 """
  pass


class NetworkError(MailerException):
  """ 網(wǎng)絡(luò)異常類 """
  pass

# test for @qq.com
if __name__ == '__main__':
  import sys

  def prompt(prompt):
    """
    接收終端輸入的數(shù)據(jù)
    """
    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郵箱默認(rèn)設(shè)置
  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)

以上所述就是本文的全部?jī)?nèi)容了,希望大家能夠喜歡。

相關(guān)文章

  • 使用Python中tkinter庫(kù)簡(jiǎn)單gui界面制作及打包成exe的操作方法(二)

    使用Python中tkinter庫(kù)簡(jiǎn)單gui界面制作及打包成exe的操作方法(二)

    這篇文章主要介紹了使用Python中tkinter庫(kù)簡(jiǎn)單gui界面制作及打包成exe的操作方法(二),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • python中main函數(shù)(主函數(shù))相關(guān)應(yīng)用例子

    python中main函數(shù)(主函數(shù))相關(guān)應(yīng)用例子

    這篇文章主要介紹了python中main函數(shù)(主函數(shù))相關(guān)應(yīng)用,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • Python學(xué)習(xí)之while 循環(huán)語(yǔ)句

    Python學(xué)習(xí)之while 循環(huán)語(yǔ)句

    這篇文章主要給大家介紹了關(guān)于Python中while循環(huán)語(yǔ)句的相關(guān)資料,使用while循環(huán)語(yǔ)句可以解決程序中需要重復(fù)執(zhí)行的操作,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-10-10
  • Python Numpy中數(shù)據(jù)的常用保存與讀取方法

    Python Numpy中數(shù)據(jù)的常用保存與讀取方法

    這篇文章主要介紹了Python Numpy中數(shù)據(jù)的常用保存與讀取方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • LeetCode百錢買百雞python遞歸解法示例

    LeetCode百錢買百雞python遞歸解法示例

    這篇文章主要為大家介紹了LeetCode百錢買百雞題目python遞歸解法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • python獲取圖片顏色信息的方法

    python獲取圖片顏色信息的方法

    這篇文章主要介紹了python獲取圖片顏色信息的方法,涉及Python使用pil模操作圖片的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • Pytorch中的gather使用方法

    Pytorch中的gather使用方法

    這篇文章主要介紹了Pytorch中的gather使用方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • 使用python對(duì)多個(gè)txt文件中的數(shù)據(jù)進(jìn)行篩選的方法

    使用python對(duì)多個(gè)txt文件中的數(shù)據(jù)進(jìn)行篩選的方法

    今天小編就為大家分享一篇使用python對(duì)多個(gè)txt文件中的數(shù)據(jù)進(jìn)行篩選的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • python利用numpy存取文件案例教程

    python利用numpy存取文件案例教程

    這篇文章主要介紹了python利用numpy存取文件案例教程,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • python?pygame英雄循環(huán)飛行及作業(yè)示例

    python?pygame英雄循環(huán)飛行及作業(yè)示例

    這篇文章主要為大家介紹了python?pygame英雄循環(huán)飛行及作業(yè)實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08

最新評(píng)論

周口市| 舟山市| 乡城县| 清水县| 台北市| 大连市| 大英县| 疏勒县| 南京市| 荣昌县| 晴隆县| 军事| 通许县| 公主岭市| 惠安县| 贵溪市| 剑河县| 潜江市| 科尔| 江口县| 滁州市| 平陆县| 靖安县| 当涂县| 晴隆县| 绩溪县| 诸城市| 北海市| 洞头县| 长岭县| 安龙县| 湛江市| 龙口市| 慈溪市| 安溪县| 鄯善县| 探索| 高青县| 武定县| 上虞市| 庆元县|