email.generator: 生成 MIME 文檔?

源代碼: Lib/email/generator.py


最普通的一種任務(wù)是生成由消息對象結(jié)構(gòu)體表示的電子郵件消息的扁平(序列化)版本。 如果你想通過 smtplib.SMTP.sendmail()nntplib 模塊來發(fā)送你的消息或是將消息打印到控制臺就將需要這樣做。 接受一個消息對象結(jié)構(gòu)體并生成其序列化表示就是這些生成器類的工作。

email.parser 模塊一樣,你并不會受限于已捆綁生成器的功能;你可以自己從頭寫一個。 不過,已捆綁生成器知道如何以符合標(biāo)準(zhǔn)的方式來生成大多數(shù)電子郵件,應(yīng)該能夠很好地處理 MIME 和非 MIME 電子郵件消息,并且被設(shè)計(jì)為面向字節(jié)的解析和生成操作是互逆的,它假定兩者都使用同樣的非轉(zhuǎn)換型 policy。 也就是說,通過 BytesParser 類來解析序列化字節(jié)流然后再使用 BytesGenerator 來重新生成序列化字節(jié)流應(yīng)當(dāng)?shù)玫脚c輸入相同的結(jié)果 1。 (而另一方面,在由程序所構(gòu)造的 EmailMessage 上使用生成器可能導(dǎo)致對默認(rèn)填入的 EmailMessage 對象的改變。。)

可以使用 Generator 類將消息扁平化為文本(而非二進(jìn)制數(shù)據(jù))的序列化表示形式,但是由于 Unicode 無法直接表示二進(jìn)制數(shù)據(jù),因此消息有必要被轉(zhuǎn)換為僅包含 ASCII 字符的數(shù)據(jù),這將使用標(biāo)準(zhǔn)電子郵件 RFC 內(nèi)容傳輸編碼格式技術(shù)來編碼電子郵件消息以便通過非 “8 比特位兼容”的信道來傳輸。

為了適應(yīng) SMIME 簽名消息的可重現(xiàn)處理過程,Generator 禁用了針對 multipart/signed 類型的消息部分及所有子部分的標(biāo)頭折疊。

class email.generator.BytesGenerator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)?

返回一個 BytesGenerator 對象,該對象將把提供給 flatten() 方法的任何消息或者提供給 write() 方法的任何經(jīng)過代理轉(zhuǎn)義編碼的文本寫入到 file-like object outfpoutfp 必須支持接受二進(jìn)制數(shù)據(jù)的 write 方法。

如果可選的 mangle_from_True,則會將一個 > 字符放到恰好以字符串 "From " 打頭,即開頭文本為 From 加一個空格的的行前面。 mangle_from_ 默認(rèn)為 policymangle_from_ 設(shè)置值 (對于 compat32 策略為 True,對于所有其他策略則為 False)。 mangle_from_ 被設(shè)計(jì)為在當(dāng)消息以 unix mbox 格式存儲時使用 (參見 mailboxWHY THE CONTENT-LENGTH FORMAT IS BAD)。

如果 maxheaderlen 不為 None,則重新折疊任何長于 maxheaderlen 的標(biāo)頭行,或者如果為 0,則不重新包裝任何標(biāo)頭。 如果 manheaderlenNone (默認(rèn)值),則根據(jù) policy 設(shè)置包裝標(biāo)頭和其他消息行。

如果指定了 policy,則使用該策略來控制消息的生成。 如果 policyNone (默認(rèn)值),則使用與傳遞給 flattenMessageEmailMessage 對象相關(guān)聯(lián)的策略來控制消息的生成。 請參閱 email.policy 了解有關(guān) policy 所控制內(nèi)容的詳情。

3.2 新版功能.

在 3.3 版更改: 添加了 policy 關(guān)鍵字。

在 3.6 版更改: mangle_from_maxheaderlen 形參的默認(rèn)行為是遵循策略。

flatten(msg, unixfrom=False, linesep=None)?

將將以 msg 為根的消息對象結(jié)構(gòu)體的文本表示形式打印到創(chuàng)建 BytesGenerator 實(shí)例時指定的輸出文件。

如果 policy 選項(xiàng) cte_type8bit (默認(rèn)值),則會將未被修改的原始已解析消息中的任何標(biāo)頭拷貝到輸出,其中會重新生成與原始數(shù)據(jù)相同的高比特位組字節(jié)數(shù)據(jù),并保留具有它們的任何消息體部分的非 ASCII Content-Transfer-Encoding。 如果 cte_type7bit,則會根據(jù)需要使用兼容 ASCII 的 Content-Transfer-Encoding 來轉(zhuǎn)換高比特位組字節(jié)數(shù)據(jù)。 也就是說,將具有非 ASCII Content-Transfer-Encoding (Content-Transfer-Encoding: 8bit) 的部分轉(zhuǎn)換為兼容 ASCII 的 Content-Transfer-Encoding,并使用 MIME unknown-8bit 字符集來編碼標(biāo)頭中不符合 RFC 的非 ASCII 字節(jié)數(shù)據(jù),以使其符合 RFC。

如果 unixfromTrue,則會在根消息對象的第一個 RFC 5322 標(biāo)頭之前打印 Unix mailbox 格式 (參見 mailbox) 所使用的封包標(biāo)頭分隔符。 如果根對象沒有封包標(biāo)頭,則會創(chuàng)建一個標(biāo)準(zhǔn)標(biāo)頭。 默認(rèn)值為 False。 請注意對于子部分來說,不會打印任何封包標(biāo)頭。

如果 linesep 不為 None,則會將其用作扁平化消息的所有行之間的分隔符。 如果 linesepNone (默認(rèn)值),則使用在 policy 中指定的值。

clone(fp)?

返回此 BytesGenerator 實(shí)例的獨(dú)立克隆,具有完全相同的選項(xiàng)設(shè)置,而 fp 為新的 outfp。

write(s)?

使用 ASCII 編解碼器和 surrogateescape 錯誤處理程序編碼 s,并將其傳遞給傳入到 BytesGenerator 的構(gòu)造器的 outfpwrite 方法 。

作為一個便捷工具,EmailMessage 提供了 as_bytes()bytes(aMessage) (即 __bytes__()) 等方法,它們簡單地生成一個消息對象的序列化二進(jìn)制表示形式。 更多細(xì)節(jié)請參閱 email.message

因?yàn)樽址疅o法表示二進(jìn)制數(shù)據(jù),Generator 類必須將任何消息中扁平化的任何二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為兼容 ASCII 的格式,具體將其轉(zhuǎn)換為兼容 ASCII 的 Content-Transfer_Encoding。 使用電子郵件 RFC 的術(shù)語,你可以將其視作 Generator 序列化為不 "支持 8 比特" 的 I/O 流。 換句話說,大部分應(yīng)用程序?qū)⑿枰褂?BytesGenerator,而非 Generator

class email.generator.Generator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)?

返回一個 Generator,它將把提供給 flatten() 方法的任何消息,或者提供給 write() 方法的任何文本寫入到 file-like object outfp。 outfp 必須支持接受字符串?dāng)?shù)據(jù)的 write 方法。

如果可選的 mangle_from_True,則會將一個 > 字符放到恰好以字符串 "From " 打頭,即開頭文本為 From 加一個空格的的行前面。 mangle_from_ 默認(rèn)為 policymangle_from_ 設(shè)置值 (對于 compat32 策略為 True,對于所有其他策略則為 False)。 mangle_from_ 被設(shè)計(jì)為在當(dāng)消息以 unix mbox 格式存儲時使用 (參見 mailboxWHY THE CONTENT-LENGTH FORMAT IS BAD)。

如果 maxheaderlen 不為 None,則重新折疊任何長于 maxheaderlen 的標(biāo)頭行,或者如果為 0,則不重新包裝任何標(biāo)頭。 如果 manheaderlenNone (默認(rèn)值),則根據(jù) policy 設(shè)置包裝標(biāo)頭和其他消息行。

如果指定了 policy,則使用該策略來控制消息的生成。 如果 policyNone (默認(rèn)值),則使用與傳遞給 flattenMessageEmailMessage 對象相關(guān)聯(lián)的策略來控制消息的生成。 請參閱 email.policy 了解有關(guān) policy 所控制內(nèi)容的詳情。

在 3.3 版更改: 添加了 policy 關(guān)鍵字。

在 3.6 版更改: mangle_from_maxheaderlen 形參的默認(rèn)行為是遵循策略。

flatten(msg, unixfrom=False, linesep=None)?

將以 msg 為根的消息對象結(jié)構(gòu)體的文本表示形式打印到當(dāng) Generator 實(shí)例被創(chuàng)建時所指定的輸出文件。

如果 policy 選項(xiàng) cte_type8bit,則視同選項(xiàng)被設(shè)為 7bit 來生成消息。 (這是必需的,因?yàn)樽址疅o法表示非 ASCII 字節(jié)數(shù)據(jù)。) 將使用兼容 ASCII 的 Content-Transfer-Encoding 按需轉(zhuǎn)換任何具有高比特位組的字節(jié)數(shù)據(jù)。 也就是說,將具有非 ASCII Content-Transfer-Encoding (Content-Transfer-Encoding: 8bit) 的部分轉(zhuǎn)換為兼容 ASCII 的 Content-Transfer-Encoding,并使用 MIME unknown-8bit 字符集來編碼標(biāo)頭中不符合 RFC 的非 ASCII 字節(jié)數(shù)據(jù),以使其符合 RFC。

如果 unixfromTrue,則會在根消息對象的第一個 RFC 5322 標(biāo)頭之前打印 Unix mailbox 格式 (參見 mailbox) 所使用的封包標(biāo)頭分隔符。 如果根對象沒有封包標(biāo)頭,則會創(chuàng)建一個標(biāo)準(zhǔn)標(biāo)頭。 默認(rèn)值為 False。 請注意對于子部分來說,不會打印任何封包標(biāo)頭。

如果 linesep 不為 None,則會將其用作扁平化消息的所有行之間的分隔符。 如果 linesepNone (默認(rèn)值),則使用在 policy 中指定的值。

在 3.2 版更改: 添加了對重編碼 8bit 消息體的支持,以及 linesep 參數(shù)。

clone(fp)?

返回此 Generator 實(shí)例的獨(dú)立克隆,具有完全相同的選項(xiàng)設(shè)置,而 fp 為新的 outfp

write(s)?

s 寫入到傳給 Generator 的構(gòu)造器的 outfpwrite 方法。 這足夠?yàn)?Generator 實(shí)際提供可用于 print() 函數(shù)的文件類 API。

作為一個便捷工具,EmailMessage 提供了 as_string()str(aMessage) (即 __str__()) 等方法,它們簡單地生成一個消息對象的已格式化字符串表示形式。 更多細(xì)節(jié)請參閱 email.message。

email.generator 模塊還提供了一個派生類 DecodedGenerator,它類似于 Generator 基類,不同之處在于非 text 部分不會被序列化,而是被表示為 基于模板并填寫了有關(guān)該部分的信息的字符串輸出流的形式。

class email.generator.DecodedGenerator(outfp, mangle_from_=None, maxheaderlen=None, fmt=None, *, policy=None)?

行為類似于 Generator,不同之處在于對傳給 Generator.flatten() 的消息的任何子部分,如果該子部分的主類型為 text,則打印該子部分的已解碼載荷,而如果其主類型不為 text,則不直接打印它而是使用來自該部分的信息填入字符串 fmt 并將填寫完成的字符串打印出來。

要填入 fmt,則執(zhí)行 fmt % part_info,其中 part_info 是由下列鍵和值組成的字典:

  • type -- 非 text 部分的完整 MIME 類型

  • maintype -- 非 text 部分的主 MIME 類型

  • subtype -- 非 text 部分的子 MIME 類型

  • filename -- 非 text 部分的文件名

  • description -- 與非 text 部分相關(guān)聯(lián)的描述

  • encoding -- 非 text 部分的內(nèi)容轉(zhuǎn)換編碼格式

如果 fmtNone,則使用下列默認(rèn) fmt:

"[忽略消息的非文本 (%(type)s) 部分,文件名 %(filename)s]"

可選的 _mangle_from_maxheaderlenGenerator 基類的相同。

備注

1

此語句假定你使用了正確的 unixfrom 設(shè)置,并且沒有用于自動調(diào)整的 policy 設(shè)置調(diào)用(例如 refold_source 必須為 none,這 不是 默認(rèn)值)。 這也不是 100% 為真,因?yàn)槿绻⒉蛔裱?RFC 標(biāo)準(zhǔn)則有時實(shí)際原始文本的信息會在解析錯誤恢復(fù)時丟失。 它的目標(biāo)是在可能的情況下修復(fù)這些后續(xù)邊緣情況。