# `email.generator`: Generating MIME documents

Вихідний код: Lib/email/generator.py

One of the most common tasks is to generate the flat (serialized) version of the email message represented by a message object structure. You will need to do this if you want to send your message via `smtplib.SMTP.sendmail()` or the `nntplib` module, or print the message on the console. Taking a message object structure and producing a serialized representation is the job of the generator classes.

Як і у випадку з модулем `email.parser`, ви не обмежені функціональністю вбудованого генератора; ви можете написати його з нуля самостійно. Однак укомплектований генератор знає, як генерувати більшість електронних листів відповідно до стандартів, має добре обробляти повідомлення електронної пошти MIME та не MIME та розроблено таким чином, щоб операції синтаксичного аналізу та генерування, орієнтовані на байти, були зворотними, припускаючи однакові не-MIME transforming `policy` використовується для обох. Тобто розбір серіалізованого потоку байтів за допомогою класу `BytesParser`, а потім регенерація серіалізованого потоку байтів за допомогою `BytesGenerator` має давати вихідні дані, ідентичні вхідним [1]. (З іншого боку, використання генератора для `EmailMessage`, створеного програмою, може призвести до змін в об’єкті `EmailMessage`, оскільки стандартні значення заповнені.)

Клас `Generator` можна використовувати для зведення повідомлення в текстове (на відміну від двійкового) серіалізоване представлення, але оскільки Юнікод не може представляти двійкові дані напряму, повідомлення обов’язково перетворюється на щось, що містить лише символи ASCII, використання стандартних методів кодування електронної пошти RFC Content Transfer для кодування повідомлень електронної пошти для передачі через канали, які не є «8-бітними чистими».

Для забезпечення відтворюваної обробки повідомлень, підписаних SMIME, `Generator` вимикає згортання заголовків для частин повідомлення типу `multipart/signed` та всіх підчастин.

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

  Повертає об’єкт `BytesGenerator`, який записуватиме будь-яке повідомлення, надане методу `flatten()`, або будь-який текст у кодуванні surrogateescape, наданий методу `write()`, у file-like object outfp. outfp повинен підтримувати метод `write`, який приймає двійкові дані.

  If optional mangle_from_ is `True`, put a `>` character in front of any line in the body that starts with the exact string `"From "`, that is `From` followed by a space at the beginning of a line. mangle_from_ defaults to the value of the `mangle_from_` setting of the policy (which is `True` for the `compat32` policy and `False` for all others). mangle_from_ is intended for use when messages are stored in Unix mbox format (see `mailbox` and WHY THE CONTENT-LENGTH FORMAT IS BAD).

  Якщо maxheaderlen не є `None`, перепакуйте будь-які рядки заголовків, які довші за maxheaderlen, або якщо `0`, не перегортайте жодних заголовків. Якщо manheaderlen має значення `None` (за замовчуванням), оберніть заголовки та інші рядки повідомлень відповідно до налаштувань policy.

  Якщо вказано політику, використовуйте цю політику для керування створенням повідомлень. Якщо policy має значення `None` (за замовчуванням), використовуйте політику, пов’язану з об’єктом `Message` або `EmailMessage`, переданим у `flatten` для керування генерацією повідомлень. Перегляньте `email.policy`, щоб дізнатися більше про те, що контролює policy.

  Нове в версії 3.2.

  Змінено в версії 3.3: Додано ключове слово політика.

  Змінено в версії 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`, що серіалізується на потік вводу/виводу, який не є «8-бітним чистим». Іншими словами, більшість програм захочуть використовувати `BytesGenerator`, а не `Generator`.

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

  Повертає об’єкт `Generator`, який записуватиме будь-яке повідомлення, надане методу `flatten()`, або будь-який текст, наданий методу `write()`, у file-like object outfp. outfp повинен підтримувати метод `write`, який приймає рядкові дані.

  If optional mangle_from_ is `True`, put a `>` character in front of any line in the body that starts with the exact string `"From "`, that is `From` followed by a space at the beginning of a line. mangle_from_ defaults to the value of the `mangle_from_` setting of the policy (which is `True` for the `compat32` policy and `False` for all others). mangle_from_ is intended for use when messages are stored in Unix mbox format (see `mailbox` and WHY THE CONTENT-LENGTH FORMAT IS BAD).

  Якщо maxheaderlen не є `None`, перепакуйте будь-які рядки заголовків, які довші за maxheaderlen, або якщо `0`, не перегортайте жодних заголовків. Якщо manheaderlen має значення `None` (за замовчуванням), оберніть заголовки та інші рядки повідомлень відповідно до налаштувань policy.

  Якщо вказано політику, використовуйте цю політику для керування створенням повідомлень. Якщо policy має значення `None` (за замовчуванням), використовуйте політику, пов’язану з об’єктом `Message` або `EmailMessage`, переданим у `flatten` для керування генерацією повідомлень. Перегляньте `email.policy`, щоб дізнатися більше про те, що контролює policy.

  Змінено в версії 3.3: Додано ключове слово політика.

  Змінено в версії 3.6: Поведінка за замовчуванням параметрів mangle_from_ і maxheaderlen полягає в дотриманні політики.

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

    Надрукуйте текстове представлення структури об’єкта повідомлення з коренем msg у вихідний файл, указаний під час створення екземпляра `Generator`.

    Якщо параметр `policy` `cte_type` має значення `8bit`, згенеруйте повідомлення так, ніби для параметра встановлено значення `7bit`. (Це потрібно, оскільки рядки не можуть представляти байти, відмінні від ASCII.) Перетворюйте будь-які байти зі старшим бітом, якщо потрібно, за допомогою 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.

    Змінено в версії 3.2: Додано підтримку перекодування тіл повідомлень `8bit` і аргументу linesep.

  clone(fp)

    Повернути незалежний клон цього екземпляра `Generator` з такими самими параметрами та fp, що й новий outfp.

  write(s)

    Запишіть s у метод write outfp, переданого конструктору `Generator`. Це забезпечує достатньо файлоподібного API для екземплярів `Generator` для використання у функції `print()`.

Для зручності `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` – Sub-MIME-тип неtext частини

  - `filename` – ім’я файлу неtext частини

  - `description` – Опис, пов’язаний з неtext частиною

  - `encoding` – кодування передачі вмісту неtext частини

  Якщо fmt має значення `None`, використовуйте такий fmt за замовчуванням:

  > «[Нетекстова (%(type)s) частина повідомлення пропущена, ім’я файлу %(filename)s]»

  Необов’язкові _mangle_from_ і maxheaderlen такі ж, як у базового класу `Generator`.

Виноски

[1]

This statement assumes that you use the appropriate setting for `unixfrom`, and that there are no `email.policy` settings calling for automatic adjustments (for example, `refold_source` must be `none`, which is not the default). It is also not 100% true, since if the message does not conform to the RFC standards occasionally information about the exact original text is lost during parsing error recovery. It is a goal to fix these latter edge cases when possible.