2016-01-08 60 views
1

如何發送附加文件的電子郵件,其中的文件名包含unicode字符?用python電子郵件發送非ASCII文件名的附件

到目前爲止,文件將到達,但文件名爲「noname」

這是一個很完善的ASCII文件名的一部分:

import smtplib 
from email.mime.text import MIMEText 
from email.MIMEBase import MIMEBase 
from email.MIMEMultipart import MIMEMultipart 
from email.mime.application import MIMEApplication 
from email.Utils import formatdate 
from email import Encoders 
from email.Utils import encode_rfc2231 

msg = MIMEMultipart() 
msg['Subject'] = "New magazine delivery!" 
msg['From'] = sender_email 
msg['To'] = ', '.join(kindle_emails) 
msg['Date'] = formatdate(localtime=True) 
message = "see attachment" 
msg.attach(MIMEText(message)) 
part = MIMEApplication(open(f, 'rb').read(), _subtype='application/x-mobipocket-ebook') 

part.add_header('Content-Disposition', 'attachment', filename=os.path.basename(filename) 
msg.attach(part) 

首先嚐試

添加編碼,語言和編碼的字符串,而不僅是文件名的元組。

part.add_header('Content-Disposition', 'attachment', filename=('utf-8', 'fr', os.path.basename(f).encode('utf-8'))) 

第二個嘗試:

全局設置的字符集是這樣的:

from email import Charset 
Charset.add_charset('utf-8', Charset.QP, Charset.QP, 'utf-8') 

第三次嘗試

使用utils.encode_rfc2231

from email.Utils import encode_rfc2231 
utf8filename = encode_rfc2231(os.path.basename(f).encode('utf-8'), charset='utf-8') 
part.add_header('Content-Disposition', 'attachment', filename=('utf-8', 'fr', utf8filename)) 

第四次嘗試

使用urllib.quote()來urlencode文件名。這與第三種方法對文件名具有相同的效果。

utf8filename = urllib.quote(os.path.basename(f).encode('utf-8')) 
part.add_header('Content-Disposition', 'attachment', filename=('utf-8', 'fr', utf8filename)) 

任何想法?

我錯過了一些關於RFC2231文件名字符編碼的重要內容嗎?

我使用Gmail的SMTP服務器和Python 2.7。

回答

3

不是告訴它的UTF-8這樣的服務器:

filename=('utf-8', 'fr', os.path.basename(f).encode('utf-8'))) 

...它的作品時,我只是給UTF-8瞞着這樣:

filename=os.path.basename(f).encode('utf-8')) 

文件名將被正確顯示。

這似乎矛盾,其中列明瞭documentation

如果值中包含非ASCII字符,它必須被指定爲格式 三元組(字符集,語言,VALUE),其中CHARSET是 字符串命名字符集用於編碼的值,語言 通常可以設置爲無或空字符串(請參閱RFC 2231其他 的可能性),並且VALUE是字符串值包含非ASCII 代碼點。

這不起作用,但是python 3 documentation增加了:。

如果三元組不通過該值包含非ASCII字符 ,它會自動在RFC 2231格式使用UTF-8的 CHARSET和無的語言編碼。

只有這個工程,即使是Python 2.7,雖然它沒有在文檔中提到。