Содержание страницы
18.11. rfc822 – Разбор заголовков почты RFC 2822¶rfc822 – Parse RFC 2822 mail headers
Устарело с версии 2.3: Пакет email следует использовать вместо модуля rfc822. Этот модуль существует только для поддержки обратной совместимости и удалён в Python 3.
Этот модуль определяет класс Message, который представляет «сообщение электронной почты», как определено в интернет-стандарте RFC 2822. 1 Такие сообщения состоят из набора заголовков и тела сообщения. В этом модуле также определён вспомогательный класс AddressList для разбора адресов RFC 2822. Обратитесь к RFC за информацией о конкретном синтаксисе сообщений RFC 2822.
Модуль mailbox предоставляет классы для чтения почтовых ящиков, созданных различными пользовательскими почтовыми программами.
-
class
rfc822.Message(file[, seekable])¶ Экземпляр
Messageсоздаётся с входным объектом в качестве параметра. Message полагается только на то, что входной объект имеет методreadline(); в частности, подходят обычные файловые объекты. При создании экземпляра заголовки читаются из входного объекта до строки-разделителя (обычно пустой строки) и сохраняются в экземпляре. Тело сообщения, следующее за заголовками, не потребляется.Этот класс может работать с любым входным объектом, поддерживающим метод
readline(). Если входной объект имеет возможность seek и tell, будет работать методrewindbody(); кроме того, некорректные строки будут возвращены обратно во входной поток. Если входной объект не имеет seek, но имеет методunread(), который может вернуть строку обратно,Messageбудет использовать его для возврата некорректных строк. Таким образом, этот класс можно использовать для разбора сообщений, поступающих из буферизованного потока.Необязательный аргумент seekable предоставляется как обходной путь для некоторых библиотек stdio, в которых
tell()сбрасывает буферизованные данные, прежде чем обнаружить, что системный вызовlseek()не работает. Для максимальной переносимости следует установить аргумент seekable в ноль, чтобы предотвратить этот начальныйtell()при передаче непозиционируемого объекта, например файлового объекта, созданного из объекта сокета.Входные строки, читаемые из файла, могут заканчиваться либо CR-LF, либо одиночным переводом строки; завершающий CR-LF заменяется на одиночный перевод строки перед сохранением строки.
Все сравнения заголовков выполняются без учёта регистра; например,
m['From'],m['from']иm['FROM']дают одинаковый результат.
-
class
rfc822.AddressList(field)¶ Можно создать экземпляр вспомогательного класса
AddressList, используя один строковый параметр – список адресов RFC 2822, разделённых запятыми, для разбора. (ПараметрNoneдаёт пустой список.)
-
rfc822.quote(str)¶ Возвращает новую строку, в которой обратная косая черта в str заменена на две обратные косые черты, а двойные кавычки – на обратную косую черту и двойную кавычку.
-
rfc822.unquote(str)¶ Возвращает новую строку, которая является расквотированной версией str. Если str начинается и заканчивается двойными кавычками, они удаляются. Аналогично, если str начинается и заканчивается угловыми скобками, они удаляются.
-
rfc822.parseaddr(address)¶ Разбирает address, который должен быть значением какого-либо поля, содержащего адрес, например To или Cc, на составные части – «имя» и «адрес электронной почты». Возвращает кортеж с этой информацией, если только разбор не завершается ошибкой; в этом случае возвращается кортеж из двух элементов
(None, None).
-
rfc822.dump_address_pair(pair)¶ Обратная функция к
parseaddr(), она принимает кортеж из двух элементов вида(realname, email_address)и возвращает строковое значение, подходящее для заголовка To или Cc. Если первый элемент pair равен false, то второй элемент возвращается без изменений.
-
rfc822.parsedate(date)¶ Пытается разобрать дату в соответствии с правилами RFC 2822. Однако некоторые почтовые программы не следуют этому формату, поэтому
parsedate()пытается правильно угадать дату в таких случаях. date – это строка, содержащая дату в формате RFC 2822, например,'Mon, 20 Nov 1995 19:12:08 -0500'. Если разбор даты успешен,parsedate()возвращает кортеж из 9 элементов, который можно напрямую передать вtime.mktime(); в противном случае возвращаетсяNone. Обратите внимание, что индексы 6, 7 и 8 кортежа результата не пригодны для использования.
-
rfc822.parsedate_tz(date)¶ Выполняет ту же функцию, что и
parsedate(), но возвращает либоNone, либо кортеж из 10 элементов; первые 9 элементов образуют кортеж, который можно напрямую передать вtime.mktime(), а десятый – смещение часового пояса даты относительно UTC (официальный термин для среднего времени по Гринвичу). (Обратите внимание, что знак смещения часового пояса противоположен знаку переменнойtime.timezoneдля того же часового пояса; последняя переменная соответствует стандарту POSIX, тогда как этот модуль следует RFC 2822.) Если входная строка не содержит часового пояса, последним элементом возвращаемого кортежа являетсяNone. Обратите внимание, что индексы 6, 7 и 8 результирующего кортежа не могут быть использованы.
-
rfc822.mktime_tz(tuple)¶ Преобразует кортеж из 10 элементов, возвращаемый функцией
parsedate_tz(), во временную метку UTC. Если элемент часового пояса в кортеже равенNone, предполагается местное время. Небольшой недостаток: сначала первые 8 элементов интерпретируются как местное время, а затем применяется поправка на разницу часовых поясов; это может привести к небольшой ошибке в даты перехода на летнее время. Но для обычного использования это несущественно.
См. также
- Модуль
email Комплексный пакет для обработки электронной почты; заменяет модуль
rfc822.- Модуль
mailbox Классы для чтения различных форматов почтовых ящиков, созданных пользовательскими почтовыми программами.
- Модуль
mimetools Подкласс
rfc822.Message, обрабатывающий сообщения в кодировке MIME.
18.11.1. Объекты сообщений¶Message Objects
Экземпляр Message имеет следующие методы:
-
Message.rewindbody()¶ Перейти к началу тела сообщения. Работает только если файловый объект поддерживает позиционирование.
-
Message.isheader(line)¶ Возвращает канонизированное имя поля строки (ключ словаря, который будет использоваться для индексации), если строка является допустимым заголовком RFC 2822; в противном случае возвращает
None(что означает, что разбор должен остановиться, а строка должна быть возвращена во входной поток). Иногда бывает полезно переопределить этот метод в подклассе.
-
Message.islast(line)¶ Возвращает истину, если данная строка является разделителем, на котором Message должен остановиться. Строка-разделитель потребляется, а позиция чтения файлового объекта устанавливается сразу после неё. По умолчанию этот метод просто проверяет, что строка пуста, но его можно переопределить в подклассе.
-
Message.iscomment(line)¶ Возвращает
True, если данную строку следует полностью игнорировать, просто пропустить. По умолчанию это заглушка, которая всегда возвращаетFalse, но вы можете переопределить её в подклассе.
-
Message.getallmatchingheaders(name)¶ Возвращает список строк, содержащий все заголовки, соответствующие name, если они есть. Каждая физическая строка (строка продолжения или нет) является отдельным элементом списка. Возвращает пустой список, если ни один заголовок не соответствует name.
-
Message.getfirstmatchingheader(name)¶ Возвращает список строк, включающий первый заголовок, соответствующий name, и его строки продолжения (если они есть). Возвращает
None, если нет заголовка, соответствующего name.
-
Message.getrawheader(name)¶ Возвращает одну строку, содержащую текст после двоеточия в первом заголовке, соответствующем name. Включает начальные пробелы, завершающий символ новой строки, а также внутренние переводы строк и пробелы, если были строки продолжения. Возвращает
None, если нет заголовка, соответствующего name.
-
Message.getheader(name[, default])¶ Возвращает одну строку, состоящую из последнего заголовка, соответствующего name, но с удалением начальных и конечных пробелов. Внутренние пробелы не удаляются. Необязательный аргумент default можно использовать для указания другого значения, возвращаемого при отсутствии заголовка, соответствующего name; по умолчанию он равен
None. Это предпочтительный способ получения разобранных заголовков.
-
Message.get(name[, default])¶ Псевдоним для
getheader(), чтобы сделать интерфейс более совместимым с обычными словарями.
-
Message.getaddr(name)¶ Возвращает пару
(full name, email address), разобранную из строки, возвращаемойgetheader(name). Если заголовок, соответствующий name, отсутствует, возвращает(None, None); в противном случае и полное имя, и адрес являются (возможно, пустыми) строками.Пример: если первый заголовок From объекта m содержит строку
'jack@cwi.nl (Jack Jansen)', тоm.getaddr('From')вернёт пару('Jack Jansen', 'jack@cwi.nl'). Если бы заголовок содержал'Jack Jansen <jack@cwi.nl>', результат был бы точно таким же.
-
Message.getaddrlist(name)¶ Это похоже на
getaddr(list), но разбирает заголовок, содержащий список адресов электронной почты (например, заголовок To), и возвращает список пар(full name, email address)(даже если в заголовке был только один адрес). Если заголовок, соответствующий name, отсутствует, возвращает пустой список.Если существует несколько заголовков, соответствующих указанному имени (например, несколько заголовков Cc), все они разбираются на адреса. Также разбираются все строки продолжения, содержащиеся в этих заголовках.
-
Message.getdate(name)¶ Извлекает заголовок с помощью
getheader()и разбирает его в 9-кортеж, совместимый сtime.mktime(); обратите внимание, что поля 6, 7 и 8 непригодны. Если заголовок, соответствующий name, отсутствует или не поддаётся разбору, возвращаетNone.Разбор даты – это, похоже, чёрная магия, и не все почтовые программы следуют стандарту. Хотя функция была протестирована и признана корректной на большой коллекции писем из многих источников, всё же возможно, что иногда она будет выдавать неверный результат.
-
Message.getdate_tz(name)¶ Извлекает заголовок с помощью
getheader()и разбирает его в 10-кортеж; первые 9 элементов образуют кортеж, совместимый сtime.mktime(), а 10-й – число, указывающее смещение часового пояса даты от UTC. Обратите внимание, что поля 6, 7 и 8 непригодны. Как и вgetdate(), если заголовок, соответствующий name, отсутствует или не поддаётся разбору, возвращаетNone.
Экземпляры Message также поддерживают ограниченный интерфейс отображения. В частности: m[name] работает как m.getheader(name), но вызывает KeyError, если нет соответствующего заголовка; а len(m), m.get(name[, default]), name in m, m.keys(), m.values() m.items() и m.setdefault(name[, default]) ведут себя как ожидается, с одной разницей: setdefault() использует пустую строку в качестве значения по умолчанию. Экземпляры Message также поддерживают интерфейс записи отображения m[name]
= value и del m[name]. Объекты Message не поддерживают методы clear(), copy(), popitem() или update() интерфейса отображения. (Поддержка get() и setdefault() была добавлена только в Python 2.2.)
Наконец, экземпляры Message имеют несколько открытых переменных экземпляра:
-
Message.headers¶ Список, содержащий весь набор строк заголовков в порядке их чтения (за исключением того, что вызовы setitem могут нарушить этот порядок). Каждая строка содержит завершающий символ новой строки. Пустая строка, завершающая заголовки, в список не включается.
-
Message.fp¶ Файл или файлоподобный объект, переданный при создании экземпляра. Может использоваться для чтения содержимого сообщения.
-
Message.unixfrom¶ Строка Unix
From, если она присутствует в сообщении, или пустая строка. Это необходимо для регенерации сообщения в некоторых контекстах, например, в почтовом файле стиляmbox.
18.11.2. Объекты AddressList¶AddressList Objects
Экземпляр AddressList имеет следующие методы:
-
AddressList.__len__()¶ Возвращает количество адресов в списке адресов.
-
AddressList.__str__()¶ Возвращает каноническое строковое представление списка адресов. Адреса отображаются в форме «имя» <host@domain>, разделённые запятыми.
-
AddressList.__add__(alist)¶ Возвращает новый экземпляр
AddressList, содержащий все адреса из обоих операндовAddressList, с удалением дубликатов (объединение множеств).
-
AddressList.__iadd__(alist)¶ Версия
__add__(), изменяющая объект на месте; превращает данный экземплярAddressListв объединение самого себя и правого экземпляра alist.
-
AddressList.__sub__(alist)¶ Возвращает новый экземпляр
AddressList, содержащий все адреса из левого операндаAddressList, которые отсутствуют в правом операнде (разность множеств).
-
AddressList.__isub__(alist)¶ Версия
__sub__(), изменяющая объект на месте; удаляет из этого списка адреса, которые также присутствуют в alist.
Наконец, экземпляры AddressList имеют одну открытую переменную экземпляра:
-
AddressList.addresslist¶ Список кортежей из двух строк, по одному на каждый адрес. В каждом элементе первый – каноническая часть имени, второй – фактический маршрутный адрес (пара «имя пользователя»-«хост.домен», разделённая
'@').
Сноски