mailbox — Работа с почтовыми ящиками различных форматов


Данный модуль определяет два класса: Mailbox и Message, для доступа и управления почтовыми ящиками на диске и содержащимися в них сообщениями. Mailbox предлагает подобное словарю сопоставление ключей с сообщениями. Message расширяет класс Message модуля email.message за счёт состояния и поведения, зависящих от формата. Поддерживаемые форматы почтовых ящиков: Maildir, mbox, MH, Babyl и MMDF.

См.также

Модуль email
Представляет сообщения и управляет ими.

Mailbox объекты

class mailbox.Mailbox

Почтовый ящик, который можно проверить и изменить.

Класс Mailbox определяет интерфейс и не предназначен для создания экземпляров. Вместо этого подклассы, зависящие от формата, должны наследоваться от Mailbox, а ваш код должен создавать конкретный подкласс.

Интерфейс Mailbox похож на словарь с маленькими ключами, соответствующими сообщениям. Ключи выдаются экземпляром Mailbox, с которым они будут использоваться, и имеют смысл только для этого экземпляра Mailbox. Ключ продолжает идентифицировать сообщение, даже если соответствующее сообщение изменено, например, путём замены его другим сообщением.

Сообщения могут быть добавлены в экземпляр Mailbox с помощью метода типа множества add() и удалены с помощью оператора del или методов типа множества remove() и discard().

Семантика интерфейса Mailbox отличается от семантики словаря некоторыми важными моментами. Каждый раз, когда запрашивается сообщение, создаётся новое представление (обычно экземпляр Message) на основе текущего состояния почтового ящика. Точно так же, когда сообщение добавляется в экземпляр Mailbox, содержимое предоставленного представления сообщения копируется. Ни в том, ни в другом случае экземпляр Mailbox не хранит ссылку на представление сообщения.

Итератор по умолчанию Mailbox перебирает представления сообщений, а не ключи, как это делает итератор словаря по умолчанию. Кроме того, модификация почтового ящика во время итерации безопасна и чётко определена. Сообщения, добавленные в почтовый ящик после создания итератора, не будут видны итератору. Сообщения, удалённые из почтового ящика до того, как итератор отдаст их, будут автоматически пропущены, хотя использование ключа из итератора может привести к исключению KeyError, если соответствующее сообщение впоследствии будет удалено.

Предупреждение

Будьте очень осторожны при изменении почтовых ящиков, которые могут быть одновременно изменены каким-либо другим процессом. Самый безопасный формат почтового ящика для таких задач — Maildir; старайтесь избегать использования однофайловых форматов, таких как mbox, для одновременной записи. Если вы изменяете почтовый ящик, вы должны блокировать его, вызывая методы lock() и unlock() перед чтением любых сообщений в файле или внося любые изменения, добавляя или удаляя сообщение. Если не заблокировать почтовый ящик, есть риск потери сообщений или повреждения всего почтового ящика.

Экземпляры Mailbox имеют следующие методы:

add(message)

Добавить message в почтовый ящик и вернуть ключ, который был ему назначен.

Параметр message может быть экземпляром Message, экземпляром email.message.Message, строкой, строкой байтов или файлоподобным объектом (который должен быть открыт в двоичном режиме). Если message является экземпляром соответствующего специфичного для формата подкласса Message (например, если это экземпляр mboxMessage, а это экземпляр mbox), используется его специфичная для формата информация. В противном случае используются разумные значения по умолчанию для информации, специфичной для формата.

Изменено в версии 3.2: Добавлена поддержка двоичного ввода.

remove(key)
__delitem__(key)
discard(key)

Удалить сообщение, соответствующее key, из почтового ящика.

Если такого сообщения не существует, возникает исключение KeyError, если метод был вызван как remove() или __delitem__(), но исключение не возникает, если метод был вызван как discard(). Поведение discard() может быть предпочтительным, если базовый формат почтового ящика поддерживает одновременное изменение другими процессами.

__setitem__(key, message)

Заменить сообщение, соответствующее key, на message. Вызывается исключение KeyError, если ни одно сообщение уже не соответствует key.

Как и в случае с add(), параметр message может быть экземпляром Message, экземпляром email.message.Message, строкой, строкой байтов или файлоподобным объектом (который должен быть открыт в двоичном режиме). Если message является экземпляром соответствующего специфичного для формата подкласса Message (например, если это экземпляр mboxMessage, а это экземпляр mbox), используется его специфичная для формата информация. В противном случае информация о формате сообщения, которая в настоящее время соответствует key, остаётся неизменной.

iterkeys()
keys()

Возвращает итератор по всем ключам, если вызывается как iterkeys(), или возвращает список ключей, если вызывается как keys().

itervalues()
__iter__()
values()

Возвращает итератор по представлениям всех сообщений, если вызывается как itervalues() или __iter__(), или возвращает список таких представлений, если вызывается как values(). Сообщения представлены как экземпляры соответствующего подкласса Message, зависящего от формата, если при инициализации экземпляра Mailbox не была указана фабрика пользовательских сообщений.

Примечание

Поведение __iter__() отличается от словарей, которые перебирают ключи.

iteritems()
items()

Возвращает итератор по парам (key, message), где key — ключ, а message — представление сообщения, если вызывается как iteritems(), или возвращает список таких пар, если вызывается как items(). Сообщения представлены как экземпляры соответствующего подкласса Message, зависящего от формата, если при инициализации экземпляра Mailbox не была указана фабрика пользовательских сообщений.

get(key, default=None)
__getitem__(key)

Возвращает представление сообщения, соответствующее key. Если такого сообщения не существует, возвращается default, если метод был вызван как get(), и возникает исключение KeyError, если метод был вызван как __getitem__(). Сообщение представляется как экземпляр соответствующего подкласса Message, зависящего от формата, если при инициализации экземпляра Mailbox не была указана фабрика пользовательских сообщений.

get_message(key)

Возвращает представление сообщения, соответствующего key, как экземпляр соответствующего подкласса Message, зависящего от формата, или создать исключение KeyError, если такого сообщения не существует.

get_bytes(key)

Возвращает байтовое представление сообщения, соответствующее key, или вызвать исключение KeyError, если такого сообщения не существует.

Добавлено в версии 3.2.

get_string(key)

Возвращает строковое представление сообщения, соответствующее key, или создать исключение KeyError, если такого сообщения не существует. Сообщение обрабатывается через email.message.Message, чтобы преобразовать его в 7-битное чистое представление.

get_file(key)

Возвращает файловое представление сообщения, соответствующее key, или создать исключение KeyError, если такого сообщения не существует. Файлоподобный объект ведёт себя так, как если бы он был открыт в двоичном режиме. Данный файл следует закрыть, как только он больше не нужен.

Изменено в версии 3.2: Файловый объект действительно является двоичным файлом; ранее он неправильно возвращался в текстовом режиме. Кроме того, файлоподобный объект теперь поддерживает протокол управления контекстом: вы можете использовать оператор with, чтобы автоматически закрыть его.

Примечание

В отличие от других представлений сообщений файловые представления не обязательно независимы от создавшего их экземпляра Mailbox или от базового почтового ящика. Более конкретная документация предоставляется каждым подклассом.

__contains__(key)

Возвращает True, если key соответствует сообщению, False в противном случае.

__len__()

Возвращает количество сообщений в почтовом ящике.

clear()

Удалить все сообщения из почтового ящика.

pop(key, default=None)

Возвращает представление сообщения, соответствующее key, и удалить сообщение. Если такого сообщения не существует, возвращает default. Сообщение представляется как экземпляр соответствующего подкласса Message, зависящего от формата, если при инициализации экземпляра Mailbox не была указана фабрика пользовательских сообщений.

popitem()

Возвращает произвольную пару (key, message), где key — ключ, а message — представление сообщения, и удалить соответствующее сообщение. Если почтовый ящик пуст, создать исключение KeyError. Сообщение представляется как экземпляр соответствующего подкласса Message, зависящего от формата, если при инициализации экземпляра Mailbox не была указана фабрика пользовательских сообщений.

update(arg)

Параметр arg должен быть сопоставлением key-to-message или итерацией пар (key, message). Обновляет почтовый ящик таким образом, что для каждого заданного key и message сообщение, соответствующее key, устанавливается на message, как если бы использовалось __setitem__(). Как и в случае с __setitem__(), каждый key уже должен соответствовать сообщению в почтовом ящике, иначе будет возбуждено исключение KeyError, поэтому в общем случае arg не может быть экземпляром Mailbox.

Примечание

В отличие от словарей ключевые аргументы не поддерживаются.

flush()

Записать любые ожидающие изменения в файловой системе. Для некоторых подклассов Mailbox изменения всегда записываются немедленно, а flush() ничего не делает, но вы все равно должны завести привычку вызывать данный метод.

lock()

Захватить эксклюзивную рекомендательную блокировку почтового ящика, чтобы другие процессы знали, что его нельзя изменять. Вызвается ExternalClashError, если блокировка недоступна. Конкретные используемые механизмы блокировки зависят от формата почтового ящика. Вы должны всегда блокировать почтовый ящик, прежде чем вносить какие-либо изменения в его содержимое.

unlock()

Снять блокировку с почтового ящика, если он есть.

close()

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

Maildir

class mailbox.Maildir(dirname, factory=None, create=True)

Подкласс Mailbox для почтовых ящиков в формате Maildir. Параметр factory — это вызываемый объект, который принимает файловое представление сообщения (которое ведёт себя так, как если бы оно было открыто в двоичном режиме) и возвращает пользовательское представление. Если factory имеет значение None, MaildirMessage используется в качестве представления сообщения по умолчанию. Если create равен True, почтовый ящик создаётся, если он не существует.

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

По историческим причинам dirname назван так, а не path.

Maildir — это формат почтового ящика на основе каталогов, разработанный для агента пересылки почты qmail и теперь широко поддерживаемый другими программами. Сообщения в почтовом ящике Maildir хранятся в отдельных файлах в общей структуре каталогов. Данный дизайн позволяет получать доступ к почтовым ящикам Maildir и изменять их несколькими несвязанными программами без повреждения данных, поэтому блокировка файлов не требуется.

Почтовые ящики Maildir содержат три подкаталога, а именно: tmp, new и cur. Сообщения мгновенно создаются в подкаталоге tmp, а затем перемещаются в подкаталог new для завершения доставки. Почтовый пользовательский агент может впоследствии переместить сообщение в подкаталог cur и сохранить информацию о состоянии сообщения в специальном разделе «info», добавленном к его имени файла.

Также поддерживаются папки в стиле агента пересылки почты Courier. Любой подкаталог основного почтового ящика считается папкой, если '.' является первым символом в его имени. Имена папок представлены Maildir без начального '.'. Каждая папка сама по себе является почтовым ящиком Maildir, но не должна содержать другие папки. Вместо этого логическая вложенность указывается с помощью '.' для разграничения уровней, например, «Архив.2005.07».

Примечание

Спецификация Maildir требует использования двоеточия (':') в некоторых именах файлов сообщений. Однако некоторые операционные системы не разрешают использовать данный символ в именах файлов. Если вы хотите использовать формат, подобный Maildir, в такой операционной системе, вы должны вместо этого указать другой символ. Восклицательный знак ('!') является популярным выбором. Например:

import mailbox
mailbox.Maildir.colon = '!'

Атрибут colon также может быть установлен для каждого экземпляра.

Экземпляры Maildir имеют все методы Mailbox в дополнение к следующим:

list_folders()

Возвращает список имён всех папок.

get_folder(folder)

Возвращает экземпляр Maildir, представляющий папку с именем folder. Вызывается исключение NoSuchMailboxError, если папка не существует.

add_folder(folder)

Создать папку с именем folder и возвращает экземпляр Maildir, представляющий её.

remove_folder(folder)

Удалить папку с именем folder. Если папка содержит какие-либо сообщения, будет поднято исключение NotEmptyError, и папка не будет удалена.

clean()

Удалить временные файлы из почтового ящика, к которым не обращались в течение последних 36 часов. Спецификация Maildir говорит, что программы чтения почты должны делать это время от времени.

Некоторые методы Mailbox, реализованные Maildir, заслуживают особого внимания:

add(message)
__setitem__(key, message)
update(arg)

Предупреждение

Данные методы генерируют уникальные имена файлов на основе текущего идентификатора процесса. При использовании нескольких потоков могут возникать необнаруженные конфликты имён и вызывать повреждение почтового ящика, если потоки не скоординированы, чтобы избежать использования данных методов для одновременного управления одним и тем же почтовым ящиком.

flush()

Все изменения в почтовых ящиках Maildir применяются немедленно, поэтому данный метод ничего не делает.

lock()
unlock()

Почтовые ящики Maildir не поддерживают (или не требуют) блокировки, поэтому данные методы ничего не делают.

close()

Экземпляры Maildir не хранят никаких открытых файлов, а базовые почтовые ящики не поддерживают блокировку, поэтому данный метод ничего не делает.

get_file(key)

В зависимости от платформы узла может оказаться невозможным изменить или удалить базовое сообщение, пока возвращаемый файл остаётся открытым.

См.также

man-страница maildir от Courier
Спецификация формата. Описывает общее расширение для поддержки папок.
Использование формата maildir
Заметки о Maildir его изобретателя. Включает обновленную схему создания имён и подробности о семантике «информации».

mbox

class mailbox.mbox(path, factory=None, create=True)

Подкласс Mailbox для почтовых ящиков в формате mbox. Параметр factory — это вызываемый объект, который принимает файловое представление сообщения (которое ведёт себя так, как если бы оно было открыто в двоичном режиме) и возвращает пользовательское представление. Если factory имеет значение None, mboxMessage используется в качестве представления сообщения по умолчанию. Если create равен True, почтовый ящик создаётся, если он не существует.

Формат mbox — это классический формат для хранения почты в системах Unix. Все сообщения в почтовом ящике mbox хранятся в одном файле, при этом начало каждого сообщения обозначается строкой, первые пять символов «From ».

Существует несколько вариантов формата mbox для устранения очевидных недостатков оригинала. В интересах совместимости mbox реализует исходный формат, который иногда называют mboxo. Это означает, что заголовок Content-Length, если он присутствует, игнорируется и что любые вхождения «From » в начале строки в теле сообщения преобразуются в «>From » при сохранении сообщения, хотя вхождения «>From » не преобразуется в «From » при чтении сообщения.

Некоторые методы Mailbox, реализованные mbox, заслуживают особого внимания:

get_file(key)

Использование файла после вызова flush() или close() в экземпляре mbox может привести к непредсказуемым результатам или вызвать исключение.

lock()
unlock()

Используются три механизма блокировки —точечная блокировка и, при наличии, системные вызовы flock() и lockf().

См.также

man-страница mbox от tin
Спецификация формата с подробной информацией о блокировке.
Настройка Netscape Mail в Unix: почему формат Content-Length — это плохо
Аргумент в пользу использования исходного формата mbox, а не его варианта.
«mbox» — это семейство нескольких взаимно несовместимых форматов почтовых ящиков
История вариаций mbox.

MH

class mailbox.MH(path, factory=None, create=True)

Подкласс Mailbox для почтовых ящиков в формате MH. Параметр factory — это вызываемый объект, который принимает файловое представление сообщения (которое ведёт себя так, как если бы оно было открыто в двоичном режиме) и возвращает пользовательское представление. Если factory — это None, MHMessage используется как представление сообщения по умолчанию. Если create равен True, почтовый ящик создаётся, если он не существует.

MH — это формат почтового ящика на основе каталога, разработанный для системы обработки сообщений MH, почтового агента пользователя. Каждое сообщение в почтовом ящике MH находится в отдельном файле. Почтовый ящик MH может содержать другие почтовые ящики MH (называемые каталоги) в дополнение к сообщениям. Папки могут быть вложены бесконечно. Почтовые ящики MH также поддерживают последовательности — именованные списки, используемые для логической группировки сообщений без их перемещения во вложенные папки. Последовательности определены в файле с именем .mh_sequences в каждой папке.

Класс MH манипулирует почтовыми ящиками MH, но не пытается имитировать все функции mh. В частности, он не изменяется и не подвержен влиянию файлов context или .mh_profile, которые используются mh для хранения своего состояния и конфигурации.

Экземпляры MH имеют все методы Mailbox в дополнение к следующим:

list_folders()

Возвращает список имён всех папок.

get_folder(folder)

Возвращает экземпляр MH, представляющий папку с именем folder. Исключение NoSuchMailboxError возникает, если папка не существует.

add_folder(folder)

Создать папку с именем folder и возвращает экземпляр MH, представляющий её.

remove_folder(folder)

Удалить папку с именем folder. Если папка содержит какие-либо сообщения, будет вызвано исключение NotEmptyError, и папка не будет удалена.

get_sequences()

Возвращает словарь имён последовательностей, сопоставленных с ключевыми списками. Если последовательностей нет, возвращается пустой словарь.

set_sequences(sequences)

Переопределить последовательности, существующие в почтовом ящике, на основе sequences, словаря имён, сопоставленных с ключевыми списками, например, возвращаемого get_sequences().

pack()

При необходимости переименовывает сообщения в почтовом ящике, чтобы устранить пробелы в нумерации. Записи в списке последовательностей обновляются соответствующим образом.

Примечание

Эта операция делает уже выданные ключи недействительными, и их нельзя использовать в дальнейшем.

Некоторые методы Mailbox, реализованные MH, заслуживают особого внимания:

remove(key)
__delitem__(key)
discard(key)

Данные методы немедленно удаляют сообщение. Соглашение MH о пометке сообщения для удаления путём добавления запятой перед его именем не используется.

lock()
unlock()

Используются три механизма блокировки —точечная блокировка и, при наличии, системные вызовы flock() и lockf(). Для почтовых ящиков MH блокировка почтового ящика означает блокировку файла .mh_sequences и блокировку отдельных файлов сообщений только на время любых операций, влияющих на них.

get_file(key)

В зависимости от платформы хоста может быть невозможно удалить базовое сообщение, пока возвращённый файл остаётся открытым.

flush()

Все изменения в почтовых ящиках MH применяются немедленно, поэтому данный метод ничего не делает.

close()

Экземпляры MH не содержат открытых файлов, поэтому данный метод эквивалентен unlock().

См.также

nmh — система обработки сообщений
Домашняя страница nmh, обновленная версия оригинальной mh.
MH и nmh: электронная почта для пользователей и программистов
Книга по mh и nmh под лицензией GPL с некоторой информацией о формате почтового ящика.

Babyl

class mailbox.Babyl(path, factory=None, create=True)

Подкласс Mailbox для почтовых ящиков в формате Babyl. Параметр factory — это вызываемый объект, который принимает файловое представление сообщения (которое ведёт себя так, как если бы оно было открыто в двоичном режиме) и возвращает пользовательское представление. Если factory имеет значение None, BabylMessage используется в качестве представления сообщения по умолчанию. Если create равен True, почтовый ящик создаётся, если он не существует.

Babyl — это формат однофайлового почтового ящика, используемый почтовым агентом пользователя Rmail, включённым в Emacs. Начало сообщения обозначается строкой, содержащей два символа Control-Underscore ('\037') и Control-L ('\014'). Конец сообщения обозначается началом следующего сообщения или, в случае последнего сообщения, строкой, содержащей символ Control-Underscore ('\037').

Сообщения в почтовом ящике Babyl имеют два набора заголовков: исходные заголовки и так называемые видимые заголовки. Видимые заголовки обычно представляют собой подмножество исходных заголовков, которые были переформатированы или сокращены, чтобы сделать их более привлекательными. Каждое сообщение в почтовом ящике Babyl также имеет сопровождающий список меток или короткие строки, которые записывают дополнительную информацию о сообщении, а список всех пользовательских меток, найденных в почтовом ящике, хранится в разделе параметров Babyl.

Экземпляры Babyl имеют все методы Mailbox в дополнение к следующим:

get_labels()

Возвращает список имён всех пользовательских меток, используемых в почтовом ящике.

Примечание

Фактические сообщения проверяются, чтобы определить, какие метки существуют в почтовом ящике, а не сверяются со списком меток в разделе параметров Babyl, но раздел Babyl обновляется при каждом изменении почтового ящика.

Некоторые методы Mailbox, реализованные Babyl, заслуживают особого внимания:

get_file(key)

В почтовых ящиках Babyl заголовки сообщений не хранятся рядом с телом сообщения. Для создания файлового представления заголовки и тело копируются вместе в экземпляр io.BytesIO, API которого идентичен API-интерфейсу файла. В результате файлоподобный объект действительно независим от базового почтового ящика, но не экономит память по сравнению со строковым представлением.

lock()
unlock()

Используются три механизма блокировки —точечная блокировка и, при наличии, системные вызовы flock() и lockf().

См.также

Формат файлов Babyl версии 5
Спецификация формата Babyl.
Чтение почты с помощью Rmail
Руководство Rmail с некоторой информацией о семантике Babyl.

MMDF

class mailbox.MMDF(path, factory=None, create=True)

Подкласс Mailbox для почтовых ящиков в формате MMDF. Параметр factory — это вызываемый объект, который принимает файловое представление сообщения (которое ведёт себя так, как если бы оно было открыто в двоичном режиме) и возвращает пользовательское представление. Если factory имеет значение None, MMDFMessage используется в качестве представления сообщения по умолчанию. Если create равен True, почтовый ящик создаётся, если он не существует.

MMDF — это формат однофайлового почтового ящика, разработанный для Multichannel Memorandum Distribution Facility, агента по пересылке почты. Каждое сообщение имеет ту же форму, что и сообщение mbox, но заключено в квадратные скобки до и после строк, содержащих четыре символа Control-A ('\001'). Как и в формате mbox, начало каждого сообщения обозначается строкой, первые пять символов которой — «From », но дополнительные вхождения «From » не преобразуются в «>From » при сохранении сообщений, поскольку лишние строки-разделители сообщений предотвращают ошибочно принимая такие события за начало последующих сообщений.

Некоторые методы Mailbox, реализованные MMDF, заслуживают особого внимания:

get_file(key)

Использование файла после вызова flush() или close() в экземпляре MMDF может привести к непредсказуемым результатам или вызвать исключение.

lock()
unlock()

Используются три механизма блокировки: точечная блокировка и, при наличии, системные вызовы flock() и lockf().

См.также

mmdf справочная страница из tin
Спецификация формата MMDF из документации программы чтения новостей tin.
MMDF
Статья в Википедии, описывающая Многоканальный механизм распространения меморандумов.

Message объектов

class mailbox.Message(message=None)

Подкласс email.message модуля Message. Подклассы mailbox.Message добавляют состояние и поведение, зависящее от формата почтового ящика.

Если message пропущен, новый экземпляр создаётся в пустом состоянии по умолчанию. Если message является экземпляром email.message.Message, его содержимое копируется; кроме того, любая информация, относящаяся к формату, преобразуется, насколько это возможно, если message является экземпляром Message. Если message является строкой, строкой байтов или файлом, он должен содержать сообщение, совместимое с RFC 2822, которое считывается и анализируется. Файлы должны быть открыты в двоичном режиме, но файлы текстового режима принимаются для обратной совместимости.

Специфическое для формата состояние и поведение, предлагаемые подклассами, различаются, но в целом поддерживаются только свойства, не относящиеся к конкретному почтовому ящику (хотя, предположительно, свойства относятся к определённому формату почтового ящика). Например, смещения файлов для форматов почтовых ящиков с одним файлом и имена файлов для форматов почтовых ящиков на основе каталогов не сохраняются, поскольку они применимы только к исходному почтовому ящику. Но состояние, например, было ли сообщение прочитано пользователем или помечено как важное, сохраняется, поскольку оно относится к самому сообщению.

Не требуется, чтобы экземпляры Message использовались для представления сообщений, полученных с использованием экземпляров Mailbox. В некоторых ситуациях время и память, необходимые для создания представлений Message, могут оказаться неприемлемыми. Для таких ситуаций экземпляры Mailbox также предлагают строковые и файловые представления, и при инициализации экземпляра Mailbox может быть указана фабрика пользовательских сообщений.

MaildirMessage

class mailbox.MaildirMessage(message=None)

Сообщение с поведением, специфичным для Maildir. Параметр message имеет то же значение, что и конструктор Message.

Как правило, почтовое приложение агента пользователя перемещает все сообщения из подкаталога new в подкаталог cur после того, как пользователь впервые открывает и закрывает почтовый ящик, записывая, что сообщения устарели независимо от того, были ли они действительно прочитаны. Каждое сообщение в cur имеет раздел «info», добавленный к его имени файла для хранения информации о его состоянии. (Некоторые почтовые программы могут также добавлять раздел «info» к сообщениям в new.) Раздел «info» может иметь одну из двух форм: он может содержать «2», за которым следует список стандартных флагов (например, «2, FR») или может содержать «1», за которой следует так называемая экспериментальная информация. Стандартные флаги для сообщений Maildir следующие:

Флаг Значение Объяснение
D Draft Под композицией
F Flagged Помечено как важное
P Passed Переадресовано, повторно отправлено или отклонено
R Replied Ответил на
S Seen Читать
T Trashed Помечено для последующего удаления

Экземпляры MaildirMessage предлагают следующие методы:

get_subdir()

Возвращает либо «new» (если сообщение должно быть сохранено в подкаталоге new), либо «cur» (если сообщение должно быть сохранено в подкаталоге cur).

Примечание

Сообщение обычно перемещается из new в cur после доступа к его почтовому ящику, независимо от того, было ли сообщение прочитано. Сообщение msg прочитано, если "S" in msg.get_flags() равно True.

set_subdir(subdir)

Указать подкаталог, в котором должно храниться сообщение. Параметр subdir должен быть либо «new», либо «cur».

get_flags()

Возвращает строку, указывающую установленные в данный момент флаги. Если сообщение соответствует стандартному формату Maildir, результатом будет объединение в алфавитном порядке нуля или одного вхождения каждого из 'D', 'F', 'P', 'R', 'S' и 'T'. Пустая строка возвращается, если флаги не установлены или «info» содержит экспериментальную семантику.

set_flags(flags)

Устанавливает флаги, указанные в flags, и снять все остальные.

add_flag(flag)

Устанавливает флаг(и), указанные в flag, без изменения других флагов. Чтобы добавить более одного флага за раз, flag может быть строкой из более чем одного символа. Текущая «info» перезаписывается независимо от того, содержит ли она экспериментальную информацию, а не флаги.

remove_flag(flag)

Снять флаги, указанные в flag, без изменения других флагов. Чтобы удалить более одного флага за раз, flag может быть строкой из более чем одного символа. Если «info» содержит экспериментальную информацию, а не флаги, текущая «info» не изменяется.

get_date()

Возвращает дату доставки сообщения в виде числа с плавающей запятой, представляющего секунды с начала эпохи.

set_date(date)

Устанавливает дату доставки сообщения на date, число с плавающей запятой, представляющее секунды с начала эпохи.

get_info()

Возвращает строку, содержащую «info» для сообщения. Это полезно для доступа и изменения «info», которая является экспериментальной (т. е. не списком флагов).

set_info(info)

Устанавливает для «info» значение info, которое должно быть строкой.

Когда экземпляр MaildirMessage создаётся на основе экземпляра mboxMessage или MMDFMessage, заголовки Status и X-Status пропускаются и выполняются следующие преобразования:

Результирующее состояние mboxMessage or MMDFMessage состояние
«cur» подкаталог O флаг
F флаг F флаг
R флаг A флаг
S флаг R флаг
T флаг D флаг

Когда экземпляр MaildirMessage создаётся на основе экземпляра MHMessage, выполняются следующие преобразования:

Результирующее состояние MHMessage состояние
«cur» подкаталог «unseen» последовательность
«cur» подкаталог and S флаг не «unseen» последовательность
F флаг «flagged» последовательность
R флаг «replied» последовательность

Когда экземпляр MaildirMessage создаётся на основе экземпляра BabylMessage, выполняются следующие преобразования:

Результирующее состояние BabylMessage состояние
«cur» подкаталог «unseen» метка
«cur» подкаталог и S флаг не «unseen» метка
P флаг «forwarded» или «resent» метка
R флаг «answered» метка
T флаг «deleted» метка

mboxMessage

class mailbox.mboxMessage(message=None)

Сообщение с поведением, характерным для mbox. Параметр message имеет то же значение, что и конструктор Message.

Сообщения в почтовом ящике mbox хранятся вместе в одном файле. Адрес конверта отправителя и время доставки обычно хранятся в строке, начинающейся с «From », которая используется для обозначения начала сообщения, хотя точный формат данных данных в разных реализациях mbox сильно различается. Флаги, указывающие на состояние сообщения, например, было ли оно прочитано или помечено как важное, обычно хранятся в заголовках Status и X-Status.

Обычные флаги для сообщений mbox следующие:

Флаг Значение Объяснение
R Read Читать
O Old Ранее обнаружен MUA
D Deleted Помечено для последующего удаления
F Flagged Помечено как важное
A Answered Ответил на

Флаги «R» и «O» хранятся в заголовке Status, а флаги «D», «F» и «A» — в заголовке X-Status. Флаги и заголовки обычно появляются в указанном порядке.

Экземпляры mboxMessage предлагают следующие методы:

get_from()

Возвращает строку, представляющую строку «From », которая отмечает начало сообщения в почтовом ящике mbox. Начальный «From » и завершающий символ новой строки исключаются.

set_from(from_, time_=None)

Устанавливает для строки «From » значение from_, которое должно быть указано без начального «From » или завершающей новой строки. Для удобства можно указать time_, который будет отформатирован соответствующим образом и добавлен к from_. Если указан time_, это должен быть экземпляр time.struct_time, кортеж, подходящий для передачи в time.strftime() или True (для использования time.gmtime()).

get_flags()

Возвращает строку, указывающую установленные в данный момент флаги. Если сообщение соответствует обычному формату, результатом является объединение в следующем порядке от нуля до одного вхождения каждого из 'R', 'O', 'D', 'F' и 'A'.

set_flags(flags)

Устанавливает флаги, указанные в flags, и снять все остальные. Параметр flags должен представлять собой объединение в любом порядке нуля или более вхождений каждого из 'R', 'O', 'D', 'F' и 'A'.

add_flag(flag)

Устанавливает флаг(и), указанные в flag, без изменения других флагов. Чтобы добавить более одного флага за раз, flag может быть строкой из более чем одного символа.

remove_flag(flag)

Снять флаги, указанные в flag, без изменения других флагов. Чтобы удалить более одного флага за раз, flag может быть строкой из более чем одного символа.

Когда экземпляр mboxMessage создаётся на основе экземпляра MaildirMessage, строка «From » создаётся на основе даты доставки экземпляра MaildirMessage, и выполняются следующие преобразования:

Результирующее состояние MaildirMessage состояние
R флаг S флаг
O флаг «cur» подкаталог
D флаг T флаг
F флаг F флаг
A флаг R флаг

Когда экземпляр mboxMessage создаётся на основе экземпляра MHMessage, выполняются следующие преобразования:

Результирующее состояние MHMessage состояние
R флаг and O флаг не «unseen» последовательность
O флаг «unseen» последовательность
F флаг «flagged» последовательность
A флаг «replied» последовательность

Когда экземпляр mboxMessage создаётся на основе экземпляра BabylMessage, выполняются следующие преобразования:

Результирующее состояние BabylMessage состояние
R флаг и O флаг не «unseen» метка
O флаг «unseen» метка
D флаг «deleted» метка
A флаг «answered» метка

Когда экземпляр Message создаётся на основе экземпляра MMDFMessage, строка «From » копируется, и все флаги напрямую соответствуют:

Результирующее состояние MMDFMessage состояние
R флаг R флаг
O флаг O флаг
D флаг D флаг
F флаг F флаг
A флаг A флаг

MHMessage

class mailbox.MHMessage(message=None)

Сообщение с поведением, характерным для MH. Параметр message имеет то же значение, что и конструктор Message.

Сообщения MH не поддерживают метки или флаги в традиционном смысле, но они поддерживают последовательности, которые представляют собой логические группы произвольных сообщений. Некоторые программы чтения почты (хотя и не стандартные mh и nmh) используют последовательности почти так же, как флаги используются с другими форматами, как показано ниже:

Последовательность Объяснение
unseen Не прочитано, но ранее обнаружено MUA
replied Ответил на
flagged Помечено как важное

Экземпляры MHMessage предлагают следующие методы:

get_sequences()

Возвращает список имён последовательностей, которые включают это сообщение.

set_sequences(sequences)

Устанавливает список последовательностей, которые включают это сообщение.

add_sequence(sequence)

Добавить sequence в список последовательностей, содержащих это сообщение.

remove_sequence(sequence)

Удалить sequence из списка последовательностей, содержащих это сообщение.

Когда экземпляр MHMessage создаётся на основе экземпляра MaildirMessage, выполняются следующие преобразования:

Результирующее состояние MaildirMessage состояние
«unseen» последовательность не S флаг
«replied» последовательность R флаг
«flagged» последовательность F флаг

Когда экземпляр MHMessage создаётся на основе экземпляра mboxMessage или MMDFMessage, заголовки Status и X-Status пропускаются и выполняются следующие преобразования:

Результирующее состояние mboxMessage или MMDFMessage состояние
«unseen» последовательность не R флаг
«replied» последовательность A флаг
«flagged» последовательность F флаг

Когда экземпляр MHMessage создаётся на основе экземпляра BabylMessage, выполняются следующие преобразования:

Результирующее состояние BabylMessage состояние
«unseen» последовательность «unseen» метка
«replied» последовательность «answered» метка

BabylMessage

class mailbox.BabylMessage(message=None)

Сообщение с поведением, характерным для Babyl. Параметр message имеет то же значение, что и конструктор Message.

Определённые метки сообщений, называемые атрибутами, по соглашению имеют особое значение. Атрибуты следующие:

Метка Объяснение
unseen Не прочитано, но ранее обнаружено MUA
deleted Помечено для последующего удаления
filed Копируется в другой файл или почтовый ящик
answered Ответил на
forwarded Пересылается
edited Изменено пользователем
resent Недавний

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

Экземпляры BabylMessage предлагают следующие методы:

get_labels()

Возвращает список меток в сообщении.

set_labels(labels)

Задаёт для списка меток сообщения значение labels.

add_label(label)

Добавить label в список меток сообщения.

remove_label(label)

Удалить label из списка меток в сообщении.

get_visible()

Возвращает экземпляр Message, заголовки которого являются видимыми заголовками сообщения, а тело пусто.

set_visible(visible)

Устанавливает видимые заголовки сообщения такими же, как заголовки в message. Параметр visible должен быть экземпляром Message, экземпляром email.message.Message, строкой или файлоподобным объектом (который должен быть открыт в текстовом режиме).

update_visible()

При изменении исходных заголовков экземпляра BabylMessage видимые заголовки не изменяются автоматически для соответствия. Данный метод обновляет видимые заголовки следующим образом: каждому видимому заголовку с соответствующим исходным заголовком присваивается значение исходного заголовка, каждый видимый заголовок без соответствующего исходного заголовка удаляется, и любой из Date, From, Reply-To, To, CC и Subject, присутствующие в исходных заголовках, но не видимые заголовки, добавляются к видимым заголовкам.

Когда экземпляр BabylMessage создаётся на основе экземпляра MaildirMessage, выполняются следующие преобразования:

Результирующее состояние MaildirMessage состояние
«unseen» метка не S флаг
«deleted» метка T флаг
«answered» метка R флаг
«forwarded» метка P флаг

Когда экземпляр BabylMessage создаётся на основе экземпляра mboxMessage или MMDFMessage, заголовки Status и X-Status опускаются и выполняются следующие преобразования:

Результирующее состояние mboxMessage или MMDFMessage состояние
«unseen» метка не R флаг
«deleted» метка D флаг
«answered» метка A флаг

Когда экземпляр BabylMessage создаётся на основе экземпляра MHMessage, выполняются следующие преобразования:

Результирующее состояние MHMessage состояние
«unseen» метка «unseen» последовательность
«answered» метка «replied» последовательность

MMDFMessage

class mailbox.MMDFMessage(message=None)

Сообщение с поведением, характерным для MMDF. Параметр message имеет то же значение, что и конструктор Message.

Как и сообщения в почтовом ящике mbox, сообщения MMDF хранятся с адресом отправителя и датой доставки в начальной строке, начинающейся с «From ». Аналогично, флаги, указывающие на состояние сообщения, обычно хранятся в заголовках Status и X-Status.

Обычные флаги для сообщений MMDF идентичны флагам сообщения mbox и заключаются в следующем:

Флаг Значение Объяснение
R Read Читать
O Old Ранее обнаружен MUA
D Deleted Помечено для последующего удаления
F Flagged Помечено как важное
A Answered Ответил на

Флаги «R» и «O» хранятся в заголовке Status, а флаги «D», «F» и «A» — в заголовке X-Status. Флаги и заголовки обычно появляются в указанном порядке.

Экземпляры MMDFMessage предлагают следующие методы, которые идентичны методам, предлагаемым mboxMessage:

get_from()

Возвращает строку, представляющую строку «From », которая отмечает начало сообщения в почтовом ящике mbox. Начальный «From » и завершающий символ новой строки исключаются.

set_from(from_, time_=None)

Устанавливает для строки «From » значение from_, которое должно быть указано без начального «From » или завершающей новой строки. Для удобства можно указать time_, который будет отформатирован соответствующим образом и добавлен к from_. Если указан time_, это должен быть экземпляр time.struct_time, кортеж, подходящий для передачи в time.strftime() или True (для использования time.gmtime()).

get_flags()

Возвращает строку, указывающую установленные в данный момент флаги. Если сообщение соответствует обычному формату, результатом является объединение в следующем порядке от нуля до одного вхождения каждого из 'R', 'O', 'D', 'F' и 'A'.

set_flags(flags)

Устанавливает флаги, указанные в flags, и снять все остальные. Параметр flags должен представлять собой объединение в любом порядке нуля или более вхождений каждого из 'R', 'O', 'D', 'F' и 'A'.

add_flag(flag)

Устанавливает флаг(и), указанные в flag, без изменения других флагов. Чтобы добавить более одного флага за раз, flag может быть строкой из более чем одного символа.

remove_flag(flag)

Снять флаги, указанные в flag, без изменения других флагов. Чтобы удалить более одного флага за раз, flag может быть строкой из более чем одного символа.

Когда экземпляр MMDFMessage создаётся на основе экземпляра MaildirMessage, строка «From » создаётся на основе даты доставки экземпляра MaildirMessage, и выполняются следующие преобразования:

Результирующее состояние MaildirMessage состояние
R флаг S флаг
O флаг «cur» подкаталог
D флаг T флаг
F флаг F флаг
A флаг R флаг

Когда экземпляр MMDFMessage создаётся на основе экземпляра MHMessage, выполняются следующие преобразования:

Результирующее состояние MHMessage состояние
R флаг и O флаг не «unseen» последовательность
O флаг «unseen» последовательность
F флаг «flagged» последовательность
A флаг «replied» последовательность

Когда экземпляр MMDFMessage создаётся на основе экземпляра BabylMessage, выполняются следующие преобразования:

Результирующее состояние BabylMessage состояние
R флаг и O флаг не «unseen» метка
O флаг «unseen» метка
D флаг «deleted» метка
A флаг «answered» метка

Когда экземпляр MMDFMessage создаётся на основе экземпляра mboxMessage, строка «From » копируется, и все флаги напрямую соответствуют:

Результирующее состояние mboxMessage состояние
R флаг R флаг
O флаг O флаг
D флаг D флаг
F флаг F флаг
A флаг A флаг

Исключения

Следующие классы исключений определены в модуле mailbox:

exception mailbox.Error

Базовый класс для всех других исключений, связанных с модулем.

exception mailbox.NoSuchMailboxError

Возникает, когда почтовый ящик ожидается, но не найден, например, при создании экземпляра подкласса Mailbox с несуществующим путём (и с параметром create, установленным на False) или при открытии несуществующей папки.

exception mailbox.NotEmptyError

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

exception mailbox.ExternalClashError

Возникает, когда какое-либо состояние, связанное с почтовым ящиком, не зависящее от программы, приводит к тому, что она не может продолжить работу, например, когда не удается получить блокировку, которую уже удерживает другая программа, или когда уникально сгенерированное имя файла уже существует.

exception mailbox.FormatError

Возникает, когда данные в файле не могут быть проанализированы, например, когда экземпляр MH пытается прочитать поврежденный файл .mh_sequences.

Примеры

Простой пример печати тем всех сообщений в почтовом ящике, которые кажутся интересными:

import mailbox
for message in mailbox.mbox('~/mbox'):
    subject = message['subject']       # Возможно, это None.
    if subject and 'python' in subject.lower():
        print(subject)

Чтобы скопировать всю почту из почтового ящика Babyl в почтовый ящик MH, преобразовав всю информацию, относящуюся к формату, которую можно преобразовать:

import mailbox
destination = mailbox.MH('~/Mail')
destination.lock()
for message in mailbox.Babyl('~/RMAIL'):
    destination.add(mailbox.MHMessage(message))
destination.flush()
destination.unlock()

В этом примере почта из нескольких списков рассылки сортируется по разным почтовым ящикам с осторожностью, чтобы избежать повреждения почты из-за одновременного изменения другими программами, потери почты из-за прерывания программы или преждевременного завершения из-за искаженных сообщений в почтовом ящике:

import mailbox
import email.errors

list_names = ('python-list', 'python-dev', 'python-bugs')

boxes = {name: mailbox.mbox('~/email/%s' % name) for name in list_names}
inbox = mailbox.Maildir('~/Maildir', factory=None)

for key in inbox.iterkeys():
    try:
        message = inbox[key]
    except email.errors.MessageParseError:
        continue                # Сообщение неправильно сформировано. Просто оставить.

    for name in list_names:
        list_id = message['list-id']
        if list_id and name in list_id:
            # Get mailbox to use
            box = boxes[name]

            # Перед удалением оригинала необходимо записать копию на диск. Если происходит
            # сбой, вы можете дублировать сообщение, но это лучше, чем полностью потерять
            # сообщение.
            box.lock()
            box.add(message)
            box.flush()
            box.unlock()

            # Удалить исходное сообщение
            inbox.lock()
            inbox.discard(key)
            inbox.flush()
            inbox.unlock()
            break               # Найдено место назначения, так что перестань искать.

for box in boxes.itervalues():
    box.close()