您的位置:首页 > 运维架构 > Linux

用Python实现在Linux环境发送带附件的邮件,支持文本/html格式

2014-10-31 18:54 1206 查看
在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

下载地址:http://download.csdn.net/download/haber001/8106081

Python version 2.7.8及以上


下载地址:http://download.csdn.net/download/haber001/8106087

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 \"one@gmail.com;two@gmail.com\" -s hello -c 'hi man' "

p = optparse.OptionParser(usage)
p.add_option('--server',dest="smtp_server",default="internalmail.morningstar.com")
p.add_option('--port',type="int",dest="smtp_server_port",default=25)
p.add_option('-f','--from',dest="from_addr",default="back-end-daily@morningstar.com")
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及以上


下载地址:http://download.csdn.net/download/haber001/8106087

#!/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 \"one@gmail.com;two@gmail.com\" -s hello -c 'hi man' "

p = optparse.OptionParser(usage)
p.add_option('--server',dest="smtp_server",default="internalmail.morningstar.com")
p.add_option('--port',type="int",dest="smtp_server_port",default=25)
p.add_option('-f','--from',dest="from_addr",default="back-end-daily@morningstar.com")
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")


参考资料:

http://justcoding.iteye.com/blog/918933
http://my.oschina.net/leejun2005/blog/74416
http://www.cnblogs.com/xiaowuyi/archive/2012/03/17/2404015.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Python 邮件 附件
相关文章推荐