1. 程式人生 > >用Python實現在Linux環境傳送帶附件的郵件,支援文字/html格式

用Python實現在Linux環境傳送帶附件的郵件,支援文字/html格式

在Linux伺服器上定時執行shell指令碼,當發生錯誤時,需要傳送郵件知會開發組,但是我想把錯誤日誌當做附件傳送,結果原來的不支援附件。強迫症犯了,雖然不懂Python語言,只好硬著頭皮去寫,去測試。寫完了,本地測試木有任何問題,心中一陣竊喜。不料放在QA環境測試時,意向不到的事情發生了。傳送郵件時報錯:

Traceback (most recent call last):
  File "/data/news/tools/bin/smtp.py", line 12, in ?
    from email.mime.multipart import MIMEMultipart
ImportError: No module named mime.multipart

心理很是鬱悶,發現在引包時發生錯誤,查看了伺服器的Python版本,才發現版本是2.4.3,只好基於2.4.3又寫了一版本。詳見下文。

Python version 2.4.3

Python version 2.7.8及以上

Python version 2.4.3

#!/usr/bin/env python
#python version 2.4.3
#Send Email
#@author Haber
#@Date 2014/10/31

import os,sys
import smtplib
import socket
import traceback
import mimetypes
import email

from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase  
from email.MIMEText import MIMEText  
from email.MIMEAudio import MIMEAudio  
from email.MIMEImage import MIMEImage  
from email.Encoders import encode_base64

def sendMail(smtp_server, smtp_server_port, from_addr, mail_passwd, to_addr, subject, mail_type, content , *files_path):

    if to_addr.count(';') >=1:
        to_real_addr=to_addr.split(';')
    elif to_addr.count(',') >=1:
        to_real_addr=to_addr.split(',')
    else:
        to_real_addr=to_addr

    mailMsg = MIMEMultipart()
    mailMsg['From'] = from_addr
    mailMsg['To'] = to_addr
    mailMsg['Subject'] = subject
    mailMsg.attach(MIMEText(content,mail_type))
    
    for path in files_path:
        if os.path.isfile(path):
            attach = getAttachment(path)
            if attach :
                mailMsg.attach(attach)
        
    mailServer = smtplib.SMTP(smtp_server, smtp_server_port)
    
#     mailServer.set_debuglevel(1)
#     mailServer.login(from_addr, mail_passwd)
    mailServer.sendmail(from_addr, to_real_addr, mailMsg.as_string())
    mailServer.quit()
    print('Sent email to %s' % to_addr)

def getAttachment(file_path):
    
    if not os.path.isfile(file_path):
        return None
    
    if not os.path.exists(file_path):
        return None
		
    file_size=os.path.getsize(file_path)
    if file_size > 1024*1024*20 :
#         print("filesize maximum is 20M.")
        return None
		
    contentType, encoding = mimetypes.guess_type(file_path)
  
    if contentType is None or encoding is not None:  
        contentType = 'application/octet-stream'  
  
    mainType, subType = contentType.split('/', 1)  
    attach = open(file_path, 'rb')
  
    if mainType == 'text':
        attachment = MIMEText(attach.read())  
    elif mainType == 'message':  
        attachment = email.message_from_file(attach)  
    elif mainType == 'image':
        attachment = MIMEImage(attach.read(),_subType=subType)  
    elif mainType == 'audio':  
        attachment = MIMEAudio(attach.read(),_subType=subType)  
    else:  
        attachment = MIMEBase(mainType, subType)  
    attachment.set_payload(attach.read())
    attach.close()
    encode_base64(attachment)  

    attachment.add_header('Content-Disposition', 'attachment',  filename=os.path.basename(file_path))
    return attachment

### read file to  string
def readfile(fname):
    body=""
    if os.path.exists(fname):
        fobj=open(fname,'r')
        for eachLine in fobj:
            #eachLine.strip()
            #print eachLine.strip()
            body +=eachLine
        fobj.close()
    else:
        print("ERROR:'%s' not exists" % fname)
    return body

def getHostInfo():
    info=""
    info = info + "  path: %s/%s;\r\n" % (os.getcwd(),sys.argv[0])
    info = info + "  user: %s;\r\n" % os.getcwd()
    info = info + "  hostname: %s;\r\n" % socket.gethostname()
    
    return info

def errorInfo():
    info="Hi all, \r\n  Send Email Error. Please check Email tool.\r\n"
    info = info + "Host Info: \r\n%s" % getHostInfo()
    info = info + "Error Info: \r\n%s" % traceback.format_exc()
    return info

if __name__ == '__main__':
    
    import optparse
    usage = "usage: %prog [options] -t \"
[email protected]
;[email protected]\" -s hello -c 'hi man' " p = optparse.OptionParser(usage) p.add_option('--server',dest="smtp_server",default="internalmail.xxx.com") p.add_option('--port',type="int",dest="smtp_server_port",default=25) p.add_option('-f','--from',dest="from_addr",default="
[email protected]
") p.add_option('-t','--to',dest="to_addr") p.add_option('-s','--subject',dest="subject") p.add_option('--type',dest="email_type",type='string',default="plain",help="email type: plain or html") p.add_option('-c','--content',dest="content",help="string to send") p.add_option('-a','--attach',dest="attach",default="",help="attachment file path") p.add_option('--passwd',dest="mail_passwd",default="") try: (options, args) = p.parse_args() if not options.to_addr: p.error("options no mail receiver") elif not options.subject: p.error("options no subject") elif not options.content: p.error("options no mail content") if os.path.isfile(options.content): options.content = readfile(options.content) sendMail(options.smtp_server,options.smtp_server_port,options.from_addr,options.mail_passwd,options.to_addr,options.subject, options.email_type, options.content, options.attach) except Exception: print("Error:%s" % traceback.format_exc()) sendMail(options.smtp_server,options.smtp_server_port,options.from_addr,options.mail_passwd,options.to_addr,"Email Tools Error", options.email_type, errorInfo(), options.attach) else: print("I am being imported from another module")

Python version 2.7.8及以上

#!/usr/bin/env python
#python version 2.7.8
#Send Email
#@author Haber
#@Date 2014/10/31

import os,sys
import smtplib
import socket
import traceback

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.mime.application import MIMEApplication

def sendMail(smtp_server, smtp_server_port, from_addr, mail_passwd, to_addr, subject, mail_type, content , *files_path):

    if to_addr.count(';') >=1:
        to_real_addr=to_addr.split(';')
    elif to_addr.count(',') >=1:
        to_real_addr=to_addr.split(',')
    else:
        to_real_addr=to_addr

    mailMsg = MIMEMultipart()
    mailMsg['From'] = from_addr
    mailMsg['To'] = to_addr
    mailMsg['Subject'] = subject
    mailMsg.attach(MIMEText(content,mail_type))
    
    for path in files_path:
        if os.path.isfile(path):
            attach = getAttachment(path)
            if attach :
                mailMsg.attach(attach)
        
    mailServer = smtplib.SMTP(smtp_server, smtp_server_port)
    
#     mailServer.set_debuglevel(1)
#     mailServer.login(gmailUser, gmailPassword)
    mailServer.sendmail(from_addr, to_real_addr, mailMsg.as_string())
    mailServer.quit()
    print('Sent email to %s' % to_addr)

def getAttachment(file_path):
    
    if not os.path.isfile(file_path):
        return None
    
    if not os.path.exists(file_path):
        return None
        
    file_size=os.path.getsize(file_path)
    if file_size > 1024*1024*20 :
#         print("filesize maximum is 20M.")
        return None
    
    attach = open(file_path,'rb')
    attachment = MIMEApplication(attach.read())
    attach.close()

    attachment.add_header('Content-Disposition', 'attachment', filename=os.path.basename(file_path))
    return attachment

### read file to  string
def readfile(fname):
    body=""
    if os.path.exists(fname):
        fobj=open(fname,'r')
        for eachLine in fobj:
            #eachLine.strip()
            #print eachLine.strip()
            body +=eachLine
        fobj.close()
    else:
        print("ERROR:'%s' not exists" % fname)
    return body

def getHostInfo():
    info=""
    info = info + "  path: %s/%s;\r\n" % (os.getcwd(),sys.argv[0])
    info = info + "  user: %s;\r\n" % os.getcwd()
    info = info + "  hostname: %s;\r\n" % socket.gethostname()
    
    return info

def errorInfo():
    info="Hi all, \r\n  Send Email Error. Please check Email tool.\r\n"
    info = info + "Host Info: \r\n%s" % getHostInfo()
    info = info + "Error Info: \r\n%s" % traceback.format_exc()
    return info

if __name__ == '__main__':
    
    import optparse
    usage = "usage: %prog [options] -t \"[email protected];[email protected]\" -s hello -c 'hi man' "

    p = optparse.OptionParser(usage)
    p.add_option('--server',dest="smtp_server",default="internalmail.xxx.com")
    p.add_option('--port',type="int",dest="smtp_server_port",default=25)
    p.add_option('-f','--from',dest="from_addr",default="[email protected]")
    p.add_option('-t','--to',dest="to_addr")
    p.add_option('-s','--subject',dest="subject")
    p.add_option('--type',dest="email_type",type='string',default="plain",help="email type: plain or html")
    p.add_option('-c','--content',dest="content",help="string to send")
    p.add_option('-a','--attach',dest="attach",default="",help="attachment file path")
    p.add_option('--passwd',dest="mail_passwd",default="")

    try:
        (options, args) = p.parse_args()
    
        if not options.to_addr:
            p.error("options no mail receiver")
        elif not options.subject:
            p.error("options no subject")
        elif not options.content:
            p.error("options no mail content")

        if os.path.isfile(options.content):
            options.content = readfile(options.content)

        sendMail(options.smtp_server,options.smtp_server_port,options.from_addr,options.mail_passwd,options.to_addr,options.subject, options.email_type, options.content, options.attach)
    except Exception:
        print("Error:%s" % traceback.format_exc())
        sendMail(options.smtp_server,options.smtp_server_port,options.from_addr,options.mail_passwd,options.to_addr,"Email Tools Error", options.email_type, errorInfo(), options.attach)
else:
   print("I am being imported from another module")

參考資料:

相關推薦

Python實現在Linux環境傳送帶附件郵件支援文字/html格式

在Linux伺服器上定時執行shell指令碼,當發生錯誤時,需要傳送郵件知會開發組,但是我想把錯誤日誌當做附件傳送,結果原來的不支援附件。強迫症犯了,雖然不懂Python語言,只好硬著頭皮去寫,去測試。寫完了,本地測試木有任何問題,心中一陣竊喜。不料放在QA環境測試時,意向不

【Python3爬蟲】Python實現發送天氣預報郵件

int 字符串 開發者工具 height window 1.0 需要 targe 沒有 此次的目標是爬取指定城市的天氣預報信息,然後再用Python發送郵件到指定的郵箱。 一、爬取天氣預報 1、首先是爬取天氣預報的信息,用的網站是中國天氣網,網址是http://www.

類方法實現python實現一個簡單的單詞本添加/查找/刪除單詞。

end code div keys style 成功 move print utf 1.實現一個簡單的單詞本,功能: ①添加單詞,當所添加的單詞已存在時,讓用戶知道 ②查找單詞,當查找的單詞不存在時,讓用戶知道 ③刪除單詞,當刪除的單詞不存在時,讓用戶知道 以上

【人工智慧】Python實現一個簡單的人臉識別原來我和這個明星如此相似

近幾年來,興起了一股人工智慧熱潮,讓人們見到了AI的能力和強大,比如影象識別,語音識別,機器翻譯,無人駕駛等等。總體來說,AI的門檻還是比較高,不僅要學會使用框架實現,更重要的是,需要有一定的數學基礎,如線性代數,矩陣,微積分等。 幸慶的是,國內外許多大神都已經給我們造好“輪子”,我們可以直接來使用某些模型

【人工智能】Python實現一個簡單的人臉識別原來我和這個明星如此相似

數值 但是 智能 深度學習 lib python 數學 三方 python實現 近幾年來,興起了一股人工智能熱潮,讓人們見到了AI的能力和強大,比如圖像識別,語音識別,機器翻譯,無人駕駛等等。總體來說,AI的門檻還是比較高,不僅要學會使用框架實現,更重要的是,需要有一定的數

python實現的一個猜數字遊戲

使用者可以自定義猜的次數,如果在規定的次數內猜出來了,就輸出great,   from random import randint s=randint(0,300) go=int(input('請輸入猜字次數:')) def foo(t): i=0 while i 

【很有趣】Python實現一個簡單的人臉識別原來我和這個明星如此相似

近幾年來,興起了一股人工智慧熱潮,讓人們見到了AI的能力和強大,比如影象識別,語音識別,機器翻譯,無人駕駛等等。總體來說,AI的門檻還是比較高,不僅要學會使用框架實現,更重要的是,需要有一定的數學基礎,如線性代數,矩陣,微積分等。 幸慶的是,國內外許多大神都已經給我們造好“輪子”,我們可

【Unity】Shader實現圖片的區域遮罩支援半透明實現地圖動態上色功能

一個專案,做世界地圖時,希望未開啟的地塊是線稿,新地塊開啟時,做一個上色處理。 想到的方案就是:上了色的彩圖蓋線上稿上,然後用mask 控制彩圖的區域性顯隱。 網上找了一個,可以半透明遮罩的shader:https://www.jianshu.com/p/1d9d439c28fa 要控制不同區塊

【Python3爬蟲】Python實現傳送天氣預報郵件

此次的目標是爬取指定城市的天氣預報資訊,然後再用Python傳送郵件到指定的郵箱。   一、爬取天氣預報 1、首先是爬取天氣預報的資訊,用的網站是中國天氣網,網址是http://www.weather.com.cn/static/html/weather.shtml,任意選擇一個城市(比如武漢

學習記錄 C#.net 加 asp.net傳送帶附件郵件

必須using這兩個庫 using System.Net; using System.Net.Mail; 某個按鈕下的語句 protected void BtnSendAEmail_Click(object sender, EventArgs e)     {      

小練習:socket實現Linux和Windows之間的通信

ren argc 漏洞 markdown tex sockets acc sas -m 在日常生活中,絕大部分人使用的機器通常是windows系統,可是對於研發人員,開發、編譯等工作往往是建立在linux機器上。其實。在服務器方面,Linux、UNIX和

python實現LBP特征點計算

i+1 [0 code read cvt lena 實現 ims numpy 1 import cv2 2 import numpy as np 3 4 5 def olbp(src): 6 dst = np.zeros(src.shape,dty

21-城裏人套路深之python實現邏輯回歸算法

rom 成功 基礎知識 壓力 dvp ilb nbsp html 感覺 如果和一個人交流時,他的思想像彈幕一樣飄散在空中,將是怎樣的一種景象?我想大概會毫不猶豫的點關閉的。生活為啥不能簡單明了?因為太直白了令人乏味。保留一些不確定性反而撲朔迷離,引人入勝。我們學習了線性回歸

python實現歸並排序

想是 一個 pass 列合並 cnblogs plist post 思想 str def merge(lfrom, lto, low, mid, high): i, j, k = low, mid, low while i < mid and j &l

python實現一個命令行文本編輯器

screen alt 保存 模型 既然 ffffff 圖片 單行 pda “這看起來相當愚蠢”——題記   不過我整個人都很荒誕,何妨呢?貼一張目前的效果圖   看起來很舒服,不是麽?即使一切都是個幌子:光標只能在最後,按一下上下左右就會退出,一行超出75個字符

python實現銀行轉賬功能

賬號 pytho exec llb 賬戶 密碼 rollback money 輸入數據 #coding:utf-8 import MySQLdb #調用MySQL數據庫模塊 conn=MySQLdb.Connect( host='.........

Python 實現武科大教務處自動搶課

kit overflow 簡單的 pos request 直接 sts itl head 首先分析網頁,找到教務處登錄的驗證碼 然後用 Python 直接把驗證碼下載到本地(整個程序通過 requests 庫實現): def GetRandCode(): url

Python實現一個大數據搜索及源代碼

Python編程語言 Python案例講解 Python基礎精講 在日常生活中,大家了解搜索引擎如百度、360、搜狗、谷歌等,搜索是大數據領域裏常見的需求。Splunk和ELK分別是該領域在非開源和開源領域裏的領導者。本文利用很少的Python代碼實現了一個基本的數據搜索功能,試圖讓大家理解大數據

Python實現Excel的讀寫

github exc orm pytho sheet bin blog light int 一、讀excel文件的簡單示例 #!/usr/bin/env python # -*- coding:utf-8 -*- import xlrd from xlrd.bo

python實現發送文本郵件

rom file HA info sel login 簡單實現 ring AI 簡單實現了python發送文本郵件 1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 # @Time : 2018