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

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

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


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

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

Вывод bytes можно сгенерировать с помощью класса BytesGenerator. Если структура объекта сообщения содержит не-ASCII байты, метод flatten() этого генератора выдаст исходные байты. Разбор двоичного сообщения и последующее преобразование в плоский текст с помощью BytesGenerator должно быть идемпотентным для сообщений, соответствующих стандартам.

Вот открытые методы класса Generator, импортируемые из модуля email.generator:

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

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

Необязательный флаг mangle_from_ – это флаг, который при значении True помещает символ > перед любой строкой в теле, которая начинается точно с From, т.е. From с последующим пробелом в начале строки. Это единственный гарантированно переносимый способ избежать ошибочного восприятия таких строк как разделителя заголовка конверта формата Unix mailbox (см. WHY THE CONTENT-LENGTH FORMAT IS BAD для подробностей). mangle_from_ по умолчанию равен True, но вы можете захотеть установить его в False, если не записываете файлы в формате Unix mailbox.

Необязательный параметр maxheaderlen задаёт максимальную длину для непродолжающегося заголовка. Если строка заголовка длиннее maxheaderlen (в символах, табуляция раскрывается до 8 пробелов), заголовок будет разбит, как определено в классе Header. Установите 0, чтобы отключить перенос заголовков. Значение по умолчанию – 78, как рекомендуется (но не требуется) в RFC 2822.

Ключевое слово policy задаёт объект policy, управляющий рядом аспектов работы генератора. Если policy не указан, то используется policy, прикреплённый к объекту сообщения, переданному в flatten.

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

Другие открытые методы Generator:

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

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

Необязательный флаг unixfrom принудительно выводит разделитель заголовка конверта перед первым заголовком RFC 2822 корневого объекта сообщения. Если у корневого объекта нет заголовка конверта, создаётся стандартный. По умолчанию установлено в False, чтобы подавить вывод разделителя конверта.

Обратите внимание, что для подчастей заголовок конверта никогда не выводится.

Необязательный параметр linesep задаёт символ разделителя строк, используемый для завершения строк в выводе. Если он указан, он переопределяет значение, заданное атрибутом policy объекта msg или объекта Generator.

Поскольку строки не могут представлять не-ASCII байты, если политика, применяемая при запуске flatten, имеет cte_type, установленный в 8bit, то Generator будет работать так, как если бы он был установлен в 7bit. Это означает, что сообщения, разобранные с помощью Bytes parser, которые имеют Content-Transfer-Encoding равное 8bit, будут преобразованы, чтобы использовать 7bit Content-Transfer-Encoding. Не-ASCII байты в заголовках будут RFC 2047 закодированы с кодировкой unknown-8bit.

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

clone(fp)

Возвращает независимую копию этого экземпляра Generator с теми же параметрами.

write(s)

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

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

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

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

Необязательный флаг mangle_from_ – это флаг, который при значении True помещает символ > перед любой строкой в теле, которая начинается точно с From, т.е. From с последующим пробелом в начале строки. Это единственный гарантированно переносимый способ избежать ошибочного восприятия таких строк как разделителя заголовка конверта формата Unix mailbox (см. WHY THE CONTENT-LENGTH FORMAT IS BAD для подробностей). mangle_from_ по умолчанию равен True, но вы можете захотеть установить его в False, если не записываете файлы в формате Unix mailbox.

Необязательный параметр maxheaderlen задаёт максимальную длину для непродолжающегося заголовка. Если строка заголовка длиннее maxheaderlen (в символах, табуляция раскрывается до 8 пробелов), заголовок будет разбит, как определено в классе Header. Установите 0, чтобы отключить перенос заголовков. Значение по умолчанию – 78, как рекомендуется (но не требуется) в RFC 2822.

Ключевое слово policy задаёт объект policy, управляющий рядом аспектов работы генератора. Если policy не указан, то используется policy, прикреплённый к объекту сообщения, переданному в flatten.

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

Другие открытые методы BytesGenerator:

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

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

Сообщения, разобранные с помощью Bytes parser, которые имеют Content-Transfer-Encoding равный 8bit, будут восстановлены как 8bit, если они не были изменены.

Необязательный флаг unixfrom принудительно выводит разделитель заголовка конверта перед первым заголовком RFC 2822 корневого объекта сообщения. Если у корневого объекта нет заголовка конверта, создаётся стандартный. По умолчанию установлено в False, чтобы подавить вывод разделителя конверта.

Обратите внимание, что для вложенных частей заголовок конверта никогда не печатается.

Необязательный linesep задаёт символ разделителя строк, используемый для завершения строк в выводе. Если он задан, он переопределяет значение, заданное Generator или msg's policy.

clone(fp)

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

write(s)

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

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

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

class email.generator.DecodedGenerator(outfp, mangle_from_=True, maxheaderlen=78, fmt=None)

Этот класс, производный от Generator, проходит по всем вложенным частям сообщения. Если вложенная часть имеет основной тип text, то выводится декодированная полезная нагрузка этой части. Необязательные параметры _mangle_from_ и maxheaderlen работают так же, как в базовом классе Generator.

Если вложенная часть не имеет основного типа text, необязательный fmt – это строка формата, используемая вместо полезной нагрузки сообщения. fmt разворачивается со следующими ключевыми словами в формате %(keyword)s:

  • type – полный MIME-тип части не-text
  • maintype – основной MIME-тип части не-text
  • subtype – подтип MIME части не-text
  • filename – имя файла части не-text
  • description – описание, связанное с частью не-text
  • encoding – кодировка передачи содержимого части не-text

Значение по умолчанию для fmtNone, то есть

[Non-text (%(type)s) part of message omitted, filename %(filename)s]

Сноски

[1]Это утверждение предполагает использование подходящей настройки для аргумента unixfrom и установку maxheaderlen=0 (что сохранит исходную длину строк). Кроме того, это не совсем верно, поскольку во многих случаях серии пробелов в заголовках сворачиваются в одиночные пробелы. Последнее является ошибкой, которая будет исправлена.