18.1.3. email.generator: Генерация MIME-документов¶email.generator: Generating MIME documents
Одна из самых распространённых задач – сгенерировать плоский текст 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)¶
Конструктор класса Generator принимает аргумент – файлоподобный объект с именем outfp. outfp должен поддерживать метод write() и быть пригодным для использования в качестве выходного файла для функции print().
Необязательный параметр mangle_from_ – это флаг, который при значении True добавляет символ > перед любой строкой в теле, которая начинается точно как From, то есть From, за которым следует пробел в начале строки. Это единственный гарантированно переносимый способ избежать того, чтобы такие строки были приняты за разделитель заголовка конверта в формате почтового ящика Unix (см. WHY THE CONTENT-LENGTH FORMAT IS BAD для подробностей). mangle_from_ по умолчанию равен True, но возможно, потребуется установить его в False, если вы не пишете файлы в формате почтового ящика Unix.
Необязательный параметр maxheaderlen задает максимальную длину для непродолженного заголовка. Если строка заголовка длиннее maxheaderlen (в символах, с табуляцией, развернутой в 8 пробелов), заголовок будет разбит, как определено в классе Header. Установите значение 0, чтобы отключить перенос заголовков. По умолчанию 78, как рекомендовано (но не требуется) RFC 2822.
Другие публичные методы Generator:
- flatten(msg, unixfrom=False, linesep='\n')¶
Выводит текстовое представление структуры объекта сообщения, начиная с msg, в выходной файл, заданный при создании экземпляра Generator. Вложенные части обходятся в глубину, и результирующий текст будет корректно закодирован в MIME.
Необязательный параметр unixfrom – это флаг, который принудительно выводит разделитель заголовка конверта перед первым заголовком RFC 2822 корневого объекта сообщения. Если у корневого объекта нет заголовка конверта, создается стандартный. По умолчанию установлено False, чтобы не выводить разделитель конверта.
Обратите внимание, что для вложенных частей заголовок конверта никогда не печатается.
Необязательный параметр linesep задаёт символ разделителя строк, используемый для завершения строк в выводе. По умолчанию используются \n, поскольку это наиболее подходящее значение для кода приложений на Python (другие пакеты библиотек ожидают строки, разделённые \n). linesep=\r\n можно использовать для создания вывода с разделителями строк, соответствующими RFC.
Сообщения, разобранные с помощью анализатора Bytes, имеющие Content-Transfer-Encoding со значением 8bit, будут преобразованы для использования 7bit Content-Transfer-Encoding. Не-ASCII байты в заголовках будут закодированы в соответствии с RFC 2047 с кодировкой unknown-8bit.
Изменено в версии 3.2: Добавлена поддержка перекодировки тел сообщений 8bit и аргумента linesep.
Для удобства см. методы Message: as_string() и str(aMessage), также известный как __str__(), которые упрощают создание форматированного строкового представления объекта сообщения. Подробнее см. email.message.
- class email.generator.BytesGenerator(outfp, mangle_from_=True, maxheaderlen=78)¶
Конструктор класса BytesGenerator принимает аргумент – двоичный файлоподобный объект с именем outfp. outfp должен поддерживать метод write(), который принимает двоичные данные.
Необязательный параметр mangle_from_ – это флаг, который при значении True добавляет символ > перед любой строкой в теле, которая начинается точно как From, то есть From, за которым следует пробел в начале строки. Это единственный гарантированно переносимый способ избежать того, чтобы такие строки были приняты за разделитель заголовка конверта в формате почтового ящика Unix (см. WHY THE CONTENT-LENGTH FORMAT IS BAD для подробностей). mangle_from_ по умолчанию равен True, но возможно, потребуется установить его в False, если вы не пишете файлы в формате почтового ящика Unix.
Необязательный параметр maxheaderlen задает максимальную длину для непродолженного заголовка. Если строка заголовка длиннее maxheaderlen (в символах, с табуляцией, развернутой в 8 пробелов), заголовок будет разбит, как определено в классе Header. Установите значение 0, чтобы отключить перенос заголовков. По умолчанию 78, как рекомендовано (но не требуется) RFC 2822.
Другие публичные методы BytesGenerator:
- flatten(msg, unixfrom=False, linesep='n')¶
Выводит текстовое представление структуры объекта сообщения, начиная с msg, в выходной файл, указанный при создании экземпляра BytesGenerator. Подчасти обходятся в глубину, и результирующий текст будет корректно закодирован в MIME. Если входные данные, из которых был создан msg, содержали байты с установленным старшим битом, и эти байты не были изменены, они будут скопированы в вывод без изменений, даже если это не строго соответствует RFC. (Для получения вывода, строго соответствующего RFC, используйте класс Generator.)
Сообщения, разобранные с помощью Bytes parser, которые имеют Content-Transfer-Encoding равный 8bit, будут восстановлены как 8bit, если они не были изменены.
Необязательный параметр unixfrom – это флаг, который принудительно выводит разделитель заголовка конверта перед первым заголовком RFC 2822 корневого объекта сообщения. Если у корневого объекта нет заголовка конверта, создается стандартный. По умолчанию установлено False, чтобы не выводить разделитель конверта.
Обратите внимание, что для вложенных частей заголовок конверта никогда не печатается.
Необязательный параметр linesep задаёт символ разделителя строк, используемый для завершения строк в выводе. По умолчанию используются \n, поскольку это наиболее подходящее значение для кода приложений на Python (другие пакеты библиотек ожидают строки, разделённые \n). linesep=\r\n можно использовать для создания вывода с разделителями строк, соответствующими RFC.
- clone(fp)¶
Возвращает независимую копию этого экземпляра BytesGenerator с теми же самыми параметрами.
- write(s)¶
Write the string s to the underlying file object. s is encoded using the ASCII codec and written to the write method of the outfp outfp passed to the BytesGenerator‘s constructor. This provides just enough file-like API for BytesGenerator instances to be used in the print() function.
Новое в версии 3.2.
The email.generator module also provides a derived class, called DecodedGenerator which is like the Generator base class, except that non-text parts are substituted with a format string representing the part.
- class email.generator.DecodedGenerator(outfp, mangle_from_=True, maxheaderlen=78, fmt=None)¶
Этот класс, производный от Generator, обходит все подчасти сообщения. Если подчасть имеет основной тип text, то выводится декодированное содержимое подчасти. Необязательные параметры _mangle_from_ и maxheaderlen работают так же, как в базовом классе Generator.
Если подчасть не является основным типом text, необязательный параметр fmt – это форматная строка, используемая вместо содержимого сообщения. fmt разворачивается с использованием следующих ключевых слов в формате %(keyword)s:
- type – Full MIME type of the non-text part
- maintype – Main MIME type of the non-text part
- subtype – Sub-MIME type of the non-text part
- filename – Filename of the non-text part
- description – Description associated with the non-text part
- encoding – Content transfer encoding of the non-text part
Значение по умолчанию для fmt – None, что означает
[Non-text (%(type)s) part of message omitted, filename %(filename)s]
Сноски
| [1] | Это утверждение предполагает, что используется подходящая настройка для аргумента unixfrom и что установлено maxheaderlen=0 (что сохранит исходные длины строк). Кроме того, это не совсем верно, поскольку во многих случаях последовательности пробелов в заголовках схлопываются в одиночные пробелы. Последнее является ошибкой, которая в конечном итоге будет исправлена. |