email.generator: 生成 MIME 文檔?

源代碼: Lib/email/generator.py


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

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

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

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

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

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

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

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

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

3.2 新版功能.

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

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

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

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

如果 policy 選項 cte_type8bit (默認值),則會將未被修改的原始已解析消息中的任何標頭拷貝到輸出,其中會重新生成與原始數(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 字符集來編碼標頭中不符合 RFC 的非 ASCII 字節(jié)數(shù)據(jù),以使其符合 RFC。

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

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

clone(fp)?

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

write(s)?

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

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

因為字符串無法表示二進制數(shù)據(jù),Generator 類必須將任何消息中扁平化的任何二進制數(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_ 默認為 policymangle_from_ 設(shè)置值 (對于 compat32 策略為 True,對于所有其他策略則為 False)。 mangle_from_ 被設(shè)計為在當(dāng)消息以 unix mbox 格式存儲時使用 (參見 mailboxWHY THE CONTENT-LENGTH FORMAT IS BAD)。

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

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

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

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

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

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

如果 policy 選項 cte_type8bit,則視同選項被設(shè)為 7bit 來生成消息。 (這是必需的,因為字符串無法表示非 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 字符集來編碼標頭中不符合 RFC 的非 ASCII 字節(jié)數(shù)據(jù),以使其符合 RFC。

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

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

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

clone(fp)?

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

write(s)?

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

作為一個便捷工具,EmailMessage 提供了 as_string()str(aMessage) (即 __str__()) 等方法,它們簡單地生成一個消息對象的已格式化字符串表示形式。 更多細節(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,則使用下列默認 fmt:

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

可選的 _mangle_from_maxheaderlenGenerator 基類的相同。

備注

1

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