Документация Python неофициальный перевод

19.1.3. email.generator: Генерация MIME-документовemail.generator: Generating MIME documents

Исходный код: Lib/email/generator.py


Одна из самых распространённых задач – создание плоской (сериализованной) версии email-сообщения, представленного структурой объекта сообщения. Это понадобится, если нужно отправить сообщение через smtplib.SMTP.sendmail() или модуль nntplib, или вывести сообщение на консоль. За создание сериализованного представления из структуры объекта сообщения отвечают классы генераторов.

Как и в случае с модулем email.parser, функциональность не ограничена встроенным генератором; можно написать свой с нуля. Однако встроенный генератор умеет создавать большинство писем в соответствии со стандартами, корректно обрабатывает как MIME-, так и не-MIME-сообщения и спроектирован так, что байт-ориентированные операции разбора и генерации являются обратными друг другу при условии использования одного и того же нетрансформирующего policy для обеих. То есть, разбор сериализованного байтового потока через класс BytesParser и последующая генерация сериализованного байтового потока с помощью BytesGenerator должны давать вывод, идентичный входному 1. (С другой стороны, использование генератора на объекте EmailMessage, созданном программно, может привести к изменениям объекта EmailMessage, так как заполняются значения по умолчанию.)

Класс Generator можно использовать для преобразования сообщения в текстовое (в отличие от двоичного) сериализованное представление, но поскольку Unicode не может напрямую представлять двоичные данные, сообщение неизбежно преобразуется в нечто, содержащее только символы ASCII, с использованием стандартных методов кодирования пересылки содержимого согласно RFC электронной почты для передачи по каналам, которые не являются «8-битно чистыми».

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

Возвращает объект BytesGenerator, который будет записывать любое сообщение, переданное методу flatten(), или любой текст, закодированный с surrogateescape, переданный методу write(), в объект, подобный файлу outfp. outfp должен поддерживать метод write, принимающий двоичные данные.

Если необязательный параметр mangle_from_ равен True, перед каждой строкой тела сообщения, которая начинается с точной строки "From " (то есть с From и следующего за ним пробела) ставится символ >. Параметр mangle_from_ по умолчанию принимает значение настройки mangle_from_ из policy (True для политики compat32 и False для всех остальных). Параметр mangle_from_ предназначен для случая, когда сообщения хранятся в формате unix mbox (см. mailbox и раздел «ПОЧЕМУ ФОРМАТ CONTENT-LENGTH ПЛОХ»).

Если maxheaderlen не равен None, переформатировать любые строки заголовков, длиннее maxheaderlen, а если 0, не переносить заголовки. Если manheaderlen равен None (по умолчанию), переносить заголовки и другие строки сообщения в соответствии с настройками policy.

Если указан policy, использовать эту политику для управления генерацией сообщений. Если policy равен None (по умолчанию), использовать политику, связанную с объектом Message или EmailMessage, переданным в flatten, для управления генерацией сообщений. Подробнее о том, что контролирует policy, см. в email.policy.

Новое в версии 3.2.

Изменено в версии 3.3: Добавлен параметр policy.

Изменено в версии 3.6: Поведение по умолчанию параметров mangle_from_ и maxheaderlen теперь следует политике.

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

Выводит текстовое представление структуры объекта сообщения, корнем которой является msg, в выходной файл, указанный при создании экземпляра BytesGenerator.

Если опция policy cte_type равна 8bit (по умолчанию), копировать все заголовки в исходном разобранном сообщении, которые не были изменены, в вывод, воспроизводя любые байты с установленным старшим битом как в оригинале, и сохранять не-ASCII Content-Transfer-Encoding любых частей тела, имеющих его. Если cte_type равен 7bit, преобразовывать байты с установленным старшим битом по мере необходимости, используя совместимый с ASCII Content-Transfer-Encoding. То есть, преобразовывать части с не-ASCII Content-Transfer-Encoding (Content-Transfer-Encoding: 8bit) в совместимый с ASCII Content-Transfer-Encoding, и кодировать недопустимые по RFC не-ASCII байты в заголовках, используя набор символов MIME unknown-8bit, делая их таким образом соответствующими RFC.

Если unixfrom равно True, печатать разделитель заголовка конверта, используемый форматом почтовых ящиков Unix (см. mailbox), перед первым из заголовков RFC 5322 корневого объекта сообщения. Если корневой объект не имеет заголовка конверта, сформировать стандартный. По умолчанию False. Обратите внимание, что для подчастей заголовок конверта никогда не печатается.

Если linesep не равно None, использовать его как символ-разделитель между всеми строками сериализованного сообщения. Если linesep равно None (по умолчанию), использовать значение, указанное в policy.

clone(fp)

Возвращает независимую копию этого экземпляра BytesGenerator с точно такими же настройками параметров и fp в качестве нового outfp.

write(s)

Кодирует s, используя кодек ASCII и обработчик ошибок surrogateescape, и передаёт его методу write объекта outfp, переданного конструктору BytesGenerator.

Для удобства EmailMessage предоставляет методы as_bytes() и bytes(aMessage) (также известный как __bytes__()), которые упрощают генерацию сериализованного двоичного представления объекта сообщения. Подробнее см. email.message.

Поскольку строки не могут представлять двоичные данные, класс Generator должен преобразовывать любые двоичные данные в любом сообщении, которое он формирует, в формат, совместимый с ASCII, преобразуя их в совместимое с ASCII Content-Transfer-Encoding. Используя терминологию RFC электронной почты, это можно рассматривать как сериализацию Generator в поток I/O, который не является «8-битно чистым». Другими словами, большинству приложений следует использовать BytesGenerator, а не Generator.

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

Возвращает объект Generator, который будет записывать любое сообщение, переданное методу flatten(), или любой текст, переданный методу write(), в объект, подобный файлу outfp. outfp должен поддерживать метод write, принимающий строковые данные.

Если необязательный параметр mangle_from_ равен True, перед каждой строкой тела сообщения, которая начинается с точной строки "From " (то есть с From и следующего за ним пробела) ставится символ >. Параметр mangle_from_ по умолчанию принимает значение настройки mangle_from_ из policy (True для политики compat32 и False для всех остальных). Параметр mangle_from_ предназначен для случая, когда сообщения хранятся в формате unix mbox (см. mailbox и раздел «ПОЧЕМУ ФОРМАТ CONTENT-LENGTH ПЛОХ»).

Если maxheaderlen не равен None, переформатировать любые строки заголовков, длиннее maxheaderlen, а если 0, не переносить заголовки. Если manheaderlen равен None (по умолчанию), переносить заголовки и другие строки сообщения в соответствии с настройками policy.

Если указан policy, использовать эту политику для управления генерацией сообщений. Если policy равен None (по умолчанию), использовать политику, связанную с объектом Message или EmailMessage, переданным в flatten, для управления генерацией сообщений. Подробнее о том, что контролирует policy, см. в email.policy.

Изменено в версии 3.3: Добавлен параметр policy.

Изменено в версии 3.6: Поведение по умолчанию параметров mangle_from_ и maxheaderlen теперь следует политике.

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

Выводит текстовое представление структуры объекта сообщения, корнем которой является msg, в выходной файл, указанный при создании экземпляра Generator.

Если параметр policy cte_type равен 8bit, сообщение генерируется так, как если бы этот параметр был установлен в 7bit. (Это требуется, потому что строки не могут представлять не-ASCII байты.) Преобразуйте все байты с установленным старшим битом, используя совместимую с ASCII Content-Transfer-Encoding. То есть преобразуйте части с не-ASCII Cotnent-Transfer-Encoding (Content-Transfer-Encoding: 8bit) в совместимую с ASCII Content-Transfer-Encoding, и закодируйте невалидные по RFC не-ASCII байты в заголовках, используя набор символов MIME unknown-8bit, тем самым делая их соответствующими RFC.

Если unixfrom равно True, печатать разделитель заголовка конверта, используемый форматом почтовых ящиков Unix (см. mailbox), перед первым из заголовков RFC 5322 корневого объекта сообщения. Если корневой объект не имеет заголовка конверта, сформировать стандартный. По умолчанию False. Обратите внимание, что для подчастей заголовок конверта никогда не печатается.

Если linesep не равно None, использовать его как символ-разделитель между всеми строками сериализованного сообщения. Если linesep равно None (по умолчанию), использовать значение, указанное в policy.

Изменено в версии 3.2: Добавлена поддержка перекодировки тел сообщений 8bit и аргумента linesep.

clone(fp)

Возвращает независимый клон экземпляра Generator с теми же параметрами и fp в качестве нового outfp.

write(s)

Записывает s в метод write объекта outfp, переданного в конструктор Generator. Этого достаточно для использования экземпляров Generator в функции print() в качестве файлоподобного API.

Для удобства EmailMessage предоставляет методы as_string() и str(aMessage) (также известный как __str__()), которые упрощают создание форматированного строкового представления объекта сообщения. Подробнее см. email.message.

Модуль email.generator также предоставляет производный класс DecodedGenerator, который похож на базовый класс Generator, за исключением того, что части не типа text не сериализуются, а вместо этого представляются в выходном потоке строкой, полученной из шаблона, заполненного информацией о части.

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

Работает как Generator, за исключением того, что для любой подчасти сообщения, переданной в Generator.flatten(), если подчасть имеет основной тип text, выводится декодированное содержимое подчасти, а если основной тип не text, то вместо вывода заполняется строка fmt с использованием информации из части и выводится полученная заполненная строка.

Чтобы заполнить fmt, выполните fmt % part_info, где part_info – это словарь, состоящий из следующих ключей и значений:

  • type – полный MIME-тип части не-text

  • maintype – основной MIME-тип части не-text

  • subtype – подтип MIME части не-text

  • filename – имя файла части не-text

  • description – описание, связанное с частью не-text

  • encoding – кодировка передачи содержимого части не-text

Если fmt равно None, используйте следующий fmt по умолчанию:

“[Часть сообщения не текстового типа (%(type)s) пропущена, имя файла %(filename)s]”

Необязательные _mangle_from_ и maxheaderlen такие же, как в базовом классе Generator.

Сноски

1

Данное утверждение предполагает, что используются соответствующие настройки для unixfrom и что нет настроек policy, требующих автоматической корректировки (например, refold_source должно быть none, что не является значением по умолчанию). Это также не совсем верно, поскольку если сообщение не соответствует стандартам RFC, иногда информация о точном исходном тексте теряется при восстановлении после ошибок синтаксического разбора. Цель – исправить эти последние крайние случаи, когда это возможно.