Python не может отправлять файлы вложений по электронной почте - PullRequest
6 голосов
/ 10 декабря 2011

У меня есть следующий код, который отлично работает, но он не отправляет файлы вложений.

import smtplib
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.MIMEBase import MIMEBase
from email import Encoders

msg=MIMEMultipart()

def mymail(address,body,format,mylist=None):

    msg['To']=address
    msg['From']='ggous1@gmail.com'
    if format=='txt':
        text_msg=MIMEText(body,'plain')
    elif format=='html':
        text_msg=MIMEText(body,'html')
    msg.attach(text_msg)
    if mylist is not None:
        mylist=[]
        fn=[]
        for f in range(len(mylist)):
            direct=os.getcwd()
            os.chdir(direct)
            part=MIMEBase('application','octet-stream')
            part.set_payload(open(mylist[f],'rb').read())
            Encoders.encode_base64(part)
            part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(mylist[f])) 
            fn.append(part)
            msg.attach(fn)

    srv=smtplib.SMTP('smtp.gmail.com')
    srv.set_debuglevel(1)
    srv.ehlo()
    srv.starttls()
    srv.ehlo()
    srv.login('username','pass')
    srv.sendmail(msg['From'],msg['To'],msg.as_string())
    srv.quit()

if __name__=="__main__":
    address=raw_input('Enter an address to send email in the form "name@host.com" ')
    body=raw_input('Enter the contents of the email')
    format=raw_input('The format is txt or html?')
    question=raw_input('Do you have any files to attach?Yes or No?')
    mylist=[]
    if question=='Yes' or question=='yes':
        fn=raw_input('Enter filename')
        mylist.append(fn)

    mymail(address,body,format,mylist)

Правильно ли я не использую MIMEBase или у меня ошибка в моем коде?

UPDATE ------------------------

 if mylist is not None:
        mylist=[]
        fn=[]
        for f in range(len(mylist)):
            direct=os.getcwd()
            os.chdir(direct)
            fn[f]=open(mylist[f],'r')             
            part=msg.attach(MIMEApplication(fn[f]))
            mylist.append(part)

1 Ответ

15 голосов
/ 10 декабря 2011

Я бы рекомендовал использовать MIMEApplication вместо вложения.Вам также не нужно выполнять всю кодировку полезной нагрузки вручную, поскольку это уже выполняется автоматически.Этот пример работает для меня:

from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.utils import formataddr
from email.utils import make_msgid
from email.utils import formatdate

email = MIMEMultipart()
email['From'] = formataddr(('Jane Doe', 'jane@example.com'))
email['Subject'] = u'Test email'
email['Message-Id'] = make_msgid()
email['Date'] = formatdate(localtime=True)
email.attach(MIMEText(u'This is your email contents.'))
email.attach(MIMEApplication('your binary data'))
print email.as_string()

Обратите внимание, что я также стараюсь установить правильный заголовок Date и Message-Id здесь.

Применение этого к вашему коду (и выполнениенесколько небольших очисток) я получаю следующий рабочий код:

import smtplib
import os
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.text import MIMEText
from email.utils import make_msgid
from email.utils import formatdate


def make_mail(address,body,format,mylist=[]):
    msg = MIMEMultipart()
    msg['To'] = address
    msg['From'] = 'ggous1@gmail.com'
    msg['Message-Id'] = make_msgid()
    msg['Date'] = formatdate(localtime=True)
    msg.attach(MIMEText(body, 'plain' if format == 'txt' else 'html'))
    for filename in mylist:
        part = MIMEApplication(open(filename).read())
        part.add_header('Content-Disposition',
                'attachment; filename="%s"' % os.path.basename(filename))
        msg.attach(part)
    return msg    

def send_mail(msg):
    srv = smtplib.SMTP('smtp.gmail.com')
    srv.set_debuglevel(1)
    srv.ehlo()
    srv.starttls()
    srv.ehlo()
    srv.login('username','pass')
    srv.sendmail(msg['From'], msg['To'], msg.as_string())
    srv.quit()

if __name__=="__main__":
    address=raw_input('Enter an address to send email in the form "name@host.com" ')
    body=raw_input('Enter the contents of the email')
    format=raw_input('The format is txt or html?')
    question=raw_input('Do you have any files to attach?Yes or No?')
    mylist=[]
    if question=='Yes' or question=='yes':
        fn=raw_input('Enter filename')
        mylist.append(fn)

    msg = make_mail(address,body,format,mylist)
    send_mail(msg)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...