email.header: Интернационализированные заголовки

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


Этот модуль является частью устаревшего (Compat32) почтового API. В текущем API кодирование и декодирование заголовков прозрачно обрабатывается словарным API класса EmailMessage. В дополнение к использованию в устаревшем коде, этот модуль может быть полезен в приложениях, которым необходимо полностью контролировать наборы символов, используемые при кодировании заголовков.

Оставшийся текст в этом разделе представляет собой оригинальную документацию по модулю.

RFC 2822 является базовым стандартом, описывающим формат сообщений электронной почты. Он основан на более старом стандарте RFC 822, который получил широкое распространение в то время, когда большая часть электронной почты состояла только из символов ASCII. RFC 2822 - это спецификация, написанная при условии, что электронное письмо содержит только 7-битные символы ASCII.

Конечно, по мере распространения электронной почты по всему миру она стала интернационализированной, так что теперь в сообщениях электронной почты можно использовать наборы символов, специфичные для конкретного языка. Базовый стандарт по-прежнему требует, чтобы сообщения электронной почты передавались с использованием только 7-разрядных символов ASCII, поэтому было написано множество рекомендаций, описывающих, как кодировать сообщения электронной почты, содержащие символы, отличные от ASCII, в формат, совместимый с RFC 2822. Эти предложения включают в себя RFC 2045, RFC 2046, RFC 2047, и RFC 2231. Пакет email поддерживает эти стандарты в своих модулях email.header и email.charset.

Если вы хотите включить символы, отличные от ASCII, в заголовки своих электронных писем, например, в поля Subject или To, вам следует использовать класс Header и назначить поле в объекте Message к экземпляру Header вместо использования строки в качестве значения заголовка. Импортируйте класс Header из модуля email.header. Например:

>>> from email.message import Message
>>> from email.header import Header
>>> msg = Message()
>>> h = Header('p\xf6stal', 'iso-8859-1')
>>> msg['Subject'] = h
>>> msg.as_string()
'Subject: =?iso-8859-1?q?p=F6stal?=\n\n'

Обратите внимание, почему мы хотели, чтобы поле Subject содержало символ, отличный от ASCII? Мы сделали это, создав экземпляр Header и передав набор символов, в котором была закодирована строка байтов. Когда следующий экземпляр Message был сглажен, поле Subject было должным образом закодировано в RFC 2047. Почтовые программы, поддерживающие MIME, отображали бы этот заголовок, используя встроенный символ ISO-8859-1.

Вот описание класса Header:

class email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')

Создайте заголовок, совместимый с MIME, который может содержать строки с разными наборами символов.

Необязательный символ s - это начальное значение заголовка. Если None (значение по умолчанию), начальное значение заголовка не задано. Позже вы можете добавить его к заголовку с помощью вызова метода append(). s может быть экземпляром bytes или str, но семантику смотрите в документации append().

Необязательный параметр charset служит двум целям: он имеет то же значение, что и аргумент charset для метода append(). Он также устанавливает набор символов по умолчанию для всех последующих вызовов append(), в которых отсутствует аргумент charset. Если charset не указан в конструкторе (по умолчанию), набор символов us-ascii используется как в качестве начальной кодировки s, так и по умолчанию для последующих вызовов append().

Максимальная длина строки может быть указана явно с помощью maxlinelen. Для разделения первой строки на более короткое значение (для учета заголовка поля, который не включен в s, например Subject) введите имя поля в header_name. Значение по умолчанию maxlinelen равно 76, а значение по умолчанию для header_name равно None, что означает, что оно не учитывается для первой строки длинного разделенного заголовка.

Необязательный символ continuation_ws должен соответствовать RFC 2822и обычно состоит либо из пробела, либо из символа табуляции. Этот символ будет добавляться перед строками продолжения. continuation_ws по умолчанию используется один символ пробела.

Необязательный параметр errors передается непосредственно в метод append().

append(s, charset=None, errors='strict')

Добавьте строку s в заголовок MIME.

Необязательный набор символов, если он указан, должен быть экземпляром Charset (см. email.charset) или именем набора символов, который будет преобразован в экземпляр Charset. Значение None (по умолчанию) означает, что используется кодировка, указанная в конструкторе.

s может быть экземпляром bytes или str. Если это экземпляр bytes, то charset является кодировкой этой байтовой строки, и UnicodeError будет поднят, если строка не может быть декодирована с помощью этого набора символов.

Если s является экземпляром str, то charset - это подсказка, указывающая набор символов в строке.

В любом случае, при создании заголовка, совместимого с RFC 2822, с использованием правил RFC 2047, строка будет закодирована с использованием выходного кодека кодировки. Если строка не может быть закодирована с помощью выходного кодека, будет выдана ошибка Unicode.

Необязательный параметр errors передается в качестве аргумента errors для вызова decode, если s является байтовой строкой.

encode(splitchars=';, \t', maxlinelen=None, linesep='\n')

Закодируйте заголовок сообщения в формат, совместимый с RFC, возможно, обернув длинные строки и инкапсулируя части, отличные от ASCII, в кодировках base64 или в кодировках, доступных для печати в кавычках.

Необязательный splitchars - это строка, содержащая символы, которым алгоритм разделения должен придать дополнительный вес при обычном переносе заголовка. Это очень приблизительная поддержка «синтаксических разрывов более высокого уровня» RFC 2822: при разделении строки предпочтительны разделительные точки, которым предшествует символ разделения, причем символы предпочтительны в том порядке, в котором они появляются в строке. Пробел и табуляция могут быть включены в строку, чтобы указать, следует ли отдавать предпочтение одному из них перед другим в качестве разделительной точки, когда другие разделительные символы не отображаются в разделяемой строке. Splitchars не влияет на RFC 2047 закодированные строки.

maxlinelen, если указано, переопределяет значение экземпляра для максимальной длины строки.

linesep указывает символы, используемые для разделения строк в сложенном заголовке. По умолчанию это наиболее полезное значение для кода приложения на Python (\n), но \r\n может быть указано для создания заголовков с разделителями строк, совместимыми с RFC.

Изменено в версии 3.2: Добавлен аргумент linesep.

Класс Header также предоставляет ряд методов для поддержки стандартных операторов и встроенных функций.

__str__()

Возвращает приблизительное значение Header в виде строки, используя неограниченную длину строки. Все фрагменты преобразуются в юникод с использованием указанной кодировки и соответствующим образом объединяются. Любые фрагменты с кодировкой 'unknown-8bit' декодируются как ASCII с помощью обработчика ошибок 'replace'.

Изменено в версии 3.2: Добавлена обработка для кодировки 'unknown-8bit'.

__eq__(other)

Этот метод позволяет вам сравнить два экземпляра Header на предмет равенства.

__ne__(other)

Этот метод позволяет вам сравнить два экземпляра Header на предмет неравенства.

Модуль email.header также предоставляет следующие удобные функции.

email.header.decode_header(header)

Расшифруйте значение заголовка сообщения без преобразования набора символов. Значение заголовка находится в header.

Эта функция возвращает список пар (decoded_string, charset), содержащих каждую из декодированных частей заголовка. кодировка - это None для некодированных частей заголовка, в противном случае строка в нижнем регистре, содержащая название набора символов, указанного в закодированной строке.

Вот пример:

>>> from email.header import decode_header
>>> decode_header('=?iso-8859-1?q?p=F6stal?=')
[(b'p\xf6stal', 'iso-8859-1')]
email.header.make_header(decoded_seq, maxlinelen=None, header_name=None, continuation_ws=' ')

Создайте экземпляр Header из последовательности пар, возвращаемой decode_header().

decode_header() принимает строку значений заголовка и возвращает последовательность пар в формате (decoded_string, charset), где charset - это название набора символов.

Эта функция принимает одну из этих последовательностей пар и возвращает экземпляр Header. Необязательные значения maxlinelen, header_name и continuation_ws такие же, как в конструкторе Header.

Вернуться на верх