`
wtx358
  • 浏览: 26105 次
  • 性别: Icon_minigender_1
  • 来自: 广西
社区版块
存档分类
最新评论

mailfile.py

阅读更多
功能:主要用来发送文件。

for Python 2.x
#!/usr/bin/env python
# -*- coding: utf-8 -*-

class ConfigFile:
    def __init__(self):
        from os.path import expanduser
        home = expanduser('~')
        self.rcfile = '%s/.mailfilerc' % home
        self.loadConfigFile()
    def initConfigFile(self):
        c = '''[mail]
from=xxx@@xxx.com
to=xxx@@xxx.com

[smtp]
host=smtp.xxx.com
port=25
user=xxx
passwd=xxx
'''
        f = open(self.rcfile, 'w')
        f.write(c)
        f.close()
    def loadConfigFile(self):
        import ConfigParser
        from os.path import exists
        if exists(self.rcfile):
            cf = ConfigParser.ConfigParser()
            cf.read(self.rcfile)
            self.host = cf.get('smtp', 'host')
            self.port = cf.getint('smtp', 'port')
            self.user = cf.get('smtp', 'user')
            self.passwd = cf.get('smtp', 'passwd')
            self.FROM = cf.get('mail','from')
            self.TO = cf.get('mail','to')
        else:
            self.initConfigFile()
            print ('** Please edit the config file %s !!!' % self.rcfile)

def sendmail(host, port, user, passwd, FILE):
    import email, smtplib, base64, sys
    from os.path import getsize
    from os import remove
    from decimal import Decimal as dec
    
    fp1=open(FILE)
    msg = email.message_from_file(fp1)
    fp1.close()
    FROM = email.utils.parseaddr(msg.get('from'))[1]
    TO = email.utils.parseaddr(msg.get('to'))[1]
    h = email.Header.Header(msg.get('subject'))
    SUBJECT = email.Header.decode_header(h)[0][0]
    print (('Connecting SMTP server %s ...') % host)

    smtp=smtplib.SMTP(host, port)
    #smtp.set_debuglevel(1)
    smtp.docmd('EHLO server')
    smtp.docmd('AUTH LOGIN')
    
    smtp.send(base64.b64encode(user)+'\r\n')
    smtp.getreply()
    smtp.send(base64.b64encode(passwd)+'\r\n')
    smtp.getreply()
    print('Logined')
    
    smtp.docmd('MAIL FROM:<%s>' % FROM)
    smtp.docmd('RCPT TO:<%s>' % TO)
    
    smtp.docmd('DATA')
    print('begin send data...')
    
    BUFSIZE=2048
    f=open(FILE,'rb')
    
    fileLen=getsize(FILE)
    curper=0
    bytes=f.read(BUFSIZE)
    while(bytes!=b'' and bytes!=''):
        curper+=len(bytes)
        sys.stdout.flush()
        sys.stdout.write('\r%6.2f %%' % (dec(100*curper)/dec(fileLen)))
        smtp.send(bytes.decode('utf-8'))
        bytes=f.read(BUFSIZE)
    f.close()
    
    smtp.send('\r\n.\r\n')
    smtp.getreply()
    
    smtp.quit()
    
    remove(FILE)

    print (('\nmail sended. ^_^'))

class Mail:
    def __init__(self, FROM, TO, SUBJECT = None, CHARSET = 'utf-8'):
        from email.mime.multipart import MIMEMultipart
        self.FROM = FROM
        self.TO = TO
        self.SUBJECT = SUBJECT
        self.CHARSET = CHARSET
        self.text = ''
        self.fileinfo = '\n----\n'
        self.files = []
        self.msg = MIMEMultipart()
        self.msg['From'] = '<%s>' % self.FROM
        self.msg['To'] = '<%s>' % self.TO
    def addtext(self, text = ''):
        self.text += text
    def addfile(self, FILE):
        import mimetypes
        from email.mime.image import MIMEImage
        from email.mime.text import MIMEText
        from email.mime.audio import MIMEAudio
        from email.mime.application import MIMEApplication
        from os.path import basename

        fileName = r'%s' % FILE
        baseName = basename(fileName)
        ctype, encoding = mimetypes.guess_type(fileName)
        if ctype is None or encoding is not None:
            ctype = 'application/octet-stream'
        maintype, subtype = ctype.split('/', 1)
        if maintype == 'text':
            att = MIMEText((lambda f: (f.read(), f.close()))(open(fileName, 'rb'))[0], \
                    _subtype = subtype, _charset = self.CHARSET)
            att.add_header('Content-Disposition', 'attachment', \
                       filename = self.header(baseName))
            att.set_charset(self.CHARSET)
            self.files.append(att)
        elif maintype == 'image':
            att = MIMEImage((lambda f: (f.read(), f.close()))(open(fileName, 'rb'))[0], \
                                                                   _subtype = subtype)
            att.add_header('Content-Disposition', 'attachment', \
                       filename = self.header(baseName))
            att.set_charset(self.CHARSET)
            self.files.append(att)
        elif maintype == 'audio':
            att = MIMEAudio((lambda f: (f.read(), f.close()))(open(fileName, 'rb'))[0], \
                                                                   _subtype = subtype)
            att.add_header('Content-Disposition', 'attachment', \
                       filename = self.header(baseName))
            att.set_charset(self.CHARSET)
            self.files.append(att)
        else:
            att = MIMEApplication((lambda f: (f.read(), f.close()))(open(fileName, 'rb'))[0], \
                                                                         _subtype = subtype)
            att.add_header('Content-Disposition', 'attachment', \
                       filename = self.header(baseName))
            att.set_charset(self.CHARSET)
            self.files.append(att)
        if not self.SUBJECT:
            self.SUBJECT = baseName
        self.fileinfo += '%s\t%s\n' % (self.md5sum(fileName), baseName)
    def makemail(self):
        from email.mime.text import MIMEText
        import uuid
        self.msg['Subject'] = self.header(self.SUBJECT)
        txt = MIMEText(self.utf8(self.text + self.fileinfo), \
                'plain', self.CHARSET)
        self.msg.attach(txt)
        for x in self.files:
            self.msg.attach(x)
        
        fName = 'MAIL_' + str(uuid.uuid4())
        fp = open(fName,'w')
        fp.write(self.msg.as_string())
        fp.close()
        return fName
    def utf8(self, data):
        try:
            return data.decode(self.CHARSET).encode(self.CHARSET)
        except:
            return data.decode('gb18030').encode(self.CHARSET)
    def header(self, data):
        '''encode into base64.'''
        from email.Header import Header
        return Header(data, self.CHARSET).encode()
    def md5sum(self, FILE):
        '''return a file's md5sum.'''
        from hashlib import md5
        BUFSIZE = 1024
        m = md5()
        file = open(FILE, 'r')
        bytes = file.read(BUFSIZE)
        while(bytes != b''):
            m.update(bytes)
            bytes = file.read(BUFSIZE)
        file.close()
        return m.hexdigest()

def main():
    import sys
    from optparse import OptionParser
    from os.path import exists
    
    parser = OptionParser(usage = 'Usage: %prog [options] <address>')
    parser.add_option('-a', dest = 'fileList', action = 'append', \
                      help = 'attach FILE', metavar = 'FILE')
    parser.add_option('-s', dest = 'subject', action = 'store', \
                      help = 'set SUBJECT', metavar = 'SUBJECT')
    parser.add_option('-v', dest = 'verbose', action = 'store_true', \
                      help = 'show only,not send')
    parser.add_option('-t', dest = 'isType', action = 'store_true', \
                      help = 'type text from stdin')
    parser.set_defaults(verbose = False)
    parser.set_defaults(isType = False)
    (opts, args) = parser.parse_args()
    if not opts.fileList and not opts.subject and not args:
        parser.print_help()
        sys.exit(1)
    cf = ConfigFile()
    From = cf.FROM
    if not args:
        mailTo = cf.TO
    else:
        mailTo = args[0]
    mymail = Mail(From, mailTo, opts.subject)
    if opts.isType:
        text = sys.stdin.read()
        mymail.addtext(text)
    if opts.fileList:
        for file in opts.fileList:
            if exists(file):
                mymail.addfile(file)
    fileName = mymail.makemail()

    if opts.verbose:
        print(mymail.msg.as_string())
    else:
        sendmail(cf.host, cf.port, cf.user, cf.passwd, fileName)

if __name__ == '__main__' :
    main()


for Python 3.x
#!/usr/bin/env python3

'''mailfile.py for python3'''

class ConfigFile:
    def __init__(self):
        from os.path import expanduser
        home = expanduser('~')
        self.rcfile = '%s/.mailfilerc' % home
        self.loadConfigFile()
    def initConfigFile(self):
        c = '''[mail]
from=xxx@@xxx.com
to=xxx@@xxx.com

[smtp]
host=smtp.xxx.com
port=25
user=xxx
passwd=xxx
'''
        f = open(self.rcfile, 'w')
        f.write(c)
        f.close()
    def loadConfigFile(self):
        import configparser
        from os.path import exists
        if exists(self.rcfile):
            cf = configparser.ConfigParser()
            cf.read(self.rcfile)
            self.host = cf.get('smtp', 'host')
            self.port = cf.getint('smtp', 'port')
            self.user = cf.get('smtp', 'user')
            self.passwd = cf.get('smtp', 'passwd')
            self.FROM = cf.get('mail','from')
            self.TO = cf.get('mail','to')
        else:
            self.initConfigFile()
            print ('** Please edit the config file %s !!!' % self.rcfile)

def sendmail(host, port, user, passwd, FILE):
    import email, smtplib, base64, sys
    from os.path import getsize
    from os import remove
    from decimal import Decimal as dec

    fp=open(FILE)
    msg = email.message_from_file(fp)
    fp.close()
    FROM = email.utils.parseaddr(msg.get('from'))[1]
    TO = email.utils.parseaddr(msg.get('to'))[1]
    h = msg.get('subject')
    SUBJECT = email.header.decode_header(h)[0][0]
    print(('Connecting SMTP server %s ...') % host)

    smtp = smtplib.SMTP(host, port)
    #smtp.set_debuglevel(1)
    smtp.docmd('EHLO server')
    smtp.docmd('AUTH LOGIN')
    
    smtp.send(base64.b64encode(user.encode('utf-8')).decode('utf-8')+'\r\n')
    smtp.getreply()
    smtp.send(base64.b64encode(passwd.encode('utf-8')).decode('utf-8')+'\r\n')
    smtp.getreply()
    print('Logined')
    
    smtp.docmd('MAIL FROM:<%s>' % FROM)
    smtp.docmd('RCPT TO:<%s>' % TO)
    
    smtp.docmd('DATA')
    print(('send mail %s to <%s> ...') % (SUBJECT.decode('utf-8'), TO))
    print('begin send data...')
    
    BUFSIZE = 2048
    f = open(FILE, 'rb')
    
    fileLen = getsize(FILE)
    curper = 0
    bytes = f.read(BUFSIZE)
    while(bytes != b'' and bytes != ''):
        curper += len(bytes)
        sys.stdout.write('\r%6.2f %%' % (dec(100)*dec(curper)/dec(fileLen)))
        smtp.send(bytes.decode('utf-8'))
        bytes = f.read(BUFSIZE)
    f.close()
    
    smtp.send('\r\n.\r\n')
    smtp.getreply()
    
    smtp.quit()
    
    remove(FILE)

    print('\nmail sended. ^_^')

class mail:
    def __init__(self, FROM, TO, SUBJECT = None, CHARSET = 'utf-8'):
        from email.mime.multipart import MIMEMultipart
        self.FROM = FROM
        self.TO = TO
        self.SUBJECT = SUBJECT
        self.CHARSET = CHARSET
        self.text = ''
        self.fileinfo = '\n----\n'
        self.files = []
        self.msg = MIMEMultipart()
        self.msg['From'] = self.FROM
        self.msg['To'] = self.TO
    def addtext(self, text = ''):
        self.text += text
    def addfile(self, FILE):
        import mimetypes
        from email.mime.image import MIMEImage
        from os.path import basename
        fileName = r'%s' % FILE
        baseName = basename(fileName)
        ctype, encoding = mimetypes.guess_type(fileName)
        if ctype is None or encoding is not None:
            ctype = 'application/octet-stream'
        maintype, subtype = ctype.split('/', 1)
        att = MIMEImage((lambda f: (f.read(), f.close())) \
                        (open(fileName, 'rb'))[0], _subtype = subtype)
        att.add_header('Content-Disposition', 'attachment', \
                       filename = self.header(baseName))
        att.set_charset(self.CHARSET)
        att.set_payload(att.get_payload().decode())
        self.files.append(att)
        if not self.SUBJECT:
            self.SUBJECT = baseName
        self.fileinfo += '%s\t%s\n' % (self.md5sum(fileName), baseName)
    def makemail(self):
        from email.mime.text import MIMEText
        import uuid
        
        self.msg['Subject'] = self.header(self.SUBJECT)
        txt = MIMEText(self.utf8(self.text + self.fileinfo), \
                'plain', self.CHARSET)
        self.msg.attach(txt)
        for x in self.files:
            self.msg.attach(x)

        fName = 'MAIL_' + str(uuid.uuid4())
        fp = open(fName,'w')
        fp.write(self.msg.as_string())
        fp.close()
        return fName

    def utf8(self, data):
        return data.encode(self.CHARSET)
    def header(self, data):
        '''encode into base64.'''
        from email.header import Header
        return Header(data, self.CHARSET).encode()
    def md5sum(self, FILE):
        '''return a file's md5sum.'''
        from hashlib import md5
        BUFSIZE = 1024
        m = md5()
        file = open(FILE, 'rb')
        bytes = file.read(BUFSIZE)
        while(bytes != b''):
            m.update(bytes)
            bytes = file.read(BUFSIZE)
        file.close()
        return m.hexdigest()

def main():
    import sys
    from optparse import OptionParser
    from os.path import exists
    
    parser = OptionParser(usage = 'Usage: %prog [options] <address>')
    parser.add_option('-a', dest = 'fileList', action = 'append', \
                      help = 'attach FILE', metavar = 'FILE')
    parser.add_option('-s', dest = 'subject', action = 'store', \
                      help = 'set SUBJECT', metavar = 'SUBJECT')
    parser.add_option('-v', dest = 'verbose', action = 'store_true', \
                      help = 'show only,not send')
    parser.set_defaults(verbose = False)
    (opts, args) = parser.parse_args()
    if not opts.fileList and not opts.subject and not args:
        parser.print_help()
        sys.exit(1)
    cf = ConfigFile()
    From = cf.FROM
    if not args:
        mailTo = cf.TO
    else:
        mailTo = args[0]
    mymail = mail(From, mailTo, opts.subject)
    if opts.fileList:
        for file in opts.fileList:
            if exists(file):
                mymail.addfile(file)

    fileName = mymail.makemail()
    
    if opts.verbose:
        print(mymail.msg.as_string())
    else:
        sendmail(cf.host, cf.port, cf.user, cf.passwd, fileName)

if __name__ == '__main__' :
    main()
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics