2010-05-09 36 views
6

Sử dụng Python 3.1.2 Tôi đang gặp sự cố khi gửi tệp đính kèm nhị phân (jpeg, pdf, v.v.) - Các tệp đính kèm MIMEText hoạt động tốt. Các mã trong câu hỏi là như sau ...Sự cố tệp đính kèm email nhị phân

for file in self.attachments: 
    part = MIMEBase('application', "octet-stream") 
    part.set_payload(open(file,"rb").read()) 
    encoders.encode_base64(part) 
    part.add_header('Content-Disposition', 'attachment; filename="%s"' % file) 
    msg.attach(part) # msg is an instance of MIMEMultipart() 

server = smtplib.SMTP(host, port) 
server.login(username, password) 
server.sendmail(from_addr, all_recipients, msg.as_string()) 

Tuy nhiên, con đường xuống trong sự kêu gọi-stack (xem traceback dưới đây), nó trông như thể msg.as_string() đã nhận được một tập tin đính kèm mà tạo ra một tải trọng của loại 'byte' thay vì chuỗi.

Có ai có ý tưởng gì có thể gây ra sự cố không? Bất kỳ trợ giúp sẽ được đánh giá cao.

Alan


builtins.TypeError: string payload expected: <class 'bytes'> 
File "c:\Dev\CommonPY\Scripts\email_send.py", line 147, in send 
    server.sendmail(self.from_addr, all_recipients, msg.as_string()) 
File "c:\Program Files\Python31\Lib\email\message.py", line 136, in as_string 
    g.flatten(self, unixfrom=unixfrom) 
File "c:\Program Files\Python31\Lib\email\generator.py", line 76, in flatten 
    self._write(msg) 
File "c:\Program Files\Python31\Lib\email\generator.py", line 101, in _write 
    self._dispatch(msg) 
File "c:\Program Files\Python31\Lib\email\generator.py", line 127, in _dispatch 
    meth(msg) 
File "c:\Program Files\Python31\Lib\email\generator.py", line 181, in _handle_multipart 
    g.flatten(part, unixfrom=False) 
File "c:\Program Files\Python31\Lib\email\generator.py", line 76, in flatten 
    self._write(msg) 
File "c:\Program Files\Python31\Lib\email\generator.py", line 101, in _write 
    self._dispatch(msg) 
File "c:\Program Files\Python31\Lib\email\generator.py", line 127, in _dispatch 
    meth(msg) 
File "c:\Program Files\Python31\Lib\email\generator.py", line 155, in _handle_text 
    raise TypeError('string payload expected: %s' % type(payload)) 
+0

Bằng cách của một workaround (tốt, một cách giải quyết có thể, Tôi thực sự không có ý tưởng nếu nó sẽ giúp), bạn có thể thử sử dụng 'MIMEApplication' thay vì' MIMEBase' –

+0

Hi David cảm ơn cho trả lời. Tôi đã thử MIMEApplication, nhưng không có kết quả (ví dụ: msg.get_payload() vẫn trả về các byte thay vì chuỗi). Tôi nghi ngờ đó là một cái gì đó để làm với mã hóa không chính xác chuyển đổi các tập tin nhị phân vào một chuỗi, nhưng tôi có thể sai. Tôi cũng lo ngại rằng tôi đã thử nhiều ví dụ tương tự từ các trang web khác nhau - tất cả đều thất bại đối với tôi, nhưng phải làm việc cho tác giả. Kính trọng –

Trả lời

3

Ok - sau nhiều lần thất vọng và web tìm kiếm, tôi đã phát hiện ra rằng vấn đề là một lỗi được biết áp dụng cho Python 3.x, encoders.py, chức năng encode_base64, mà nên đọc như sau ...

def encode_base64(msg): 
    """Encode the message's payload in Base64. 

    Also, add an appropriate Content-Transfer-Encoding header. 
    """ 
    orig = msg.get_payload() 
    encdata = _bencode(orig) 

    # new line inserted to ensure all bytes characters are converted to ASCII 
    encdata = str(encdata, "ASCII") 

    msg.set_payload(encdata) 
    msg['Content-Transfer-Encoding'] = 'base64' 

Các lỗi đã được nâng lên như vấn đề # 4768, và đã leo thang đến tình trạng nguy kịch trên 2010/05/10. Hy vọng rằng nó sẽ được cố định trong phiên bản tiếp theo (3.1.3?)

Kính trọng, Alan

+0

Tôi có thể sử dụng cách giải quyết khác không? –

3
for file in self.attachments: 
    fp = open(file,"rb")  
    part = MIMEApplication(fp.read())  
    fp.close()  
    encoders.encode_base64(part) 

    # the miracle 
    part.set_payload(part.get_payload().decode('ASCII')) 

    part.add_header('Content-Disposition', 'attachment; filename="%s"' % file)  
    msg.attach(part) 
+0

Điều đó có vẻ đầy hứa hẹn - Tôi sẽ thử - cảm ơn. –

+0

thêm "từ bộ mã hóa nhập email" – mastier

2

giải pháp từ this SO answer

from base64 import encodebytes 
for file in self.attachments: 
    fp = open(file, 'rb') 
    part = MIMEBase('application', "octet-stream") 
    part.set_payload(encodebytes(fp.read()).decode()) 
    fp.close() 
    part.add_header('Content-Transfer-Encoding', 'base64') 
    part.add_header('Content-Disposition', 'attachment; filename="%s"' % file) 
    msg.attach(part) # msg is an instance of MIMEMultipart() 

server = smtplib.SMTP(host, port) 
server.login(username, password) 
server.sendmail(from_addr, all_recipients, msg.as_string()) 
+0

@bstpierre, cảm ơn giải pháp này. Tôi sẽ lưu trữ nó đi trong trường hợp giải pháp hiện tại của tôi rơi xuống trong một phiên bản tương lai của Python. –

Các vấn đề liên quan