Содержание страницы
19.4. mailbox – Работа с почтовыми ящиками в различных форматах¶mailbox – Manipulate mailboxes in various formats
Этот модуль определяет два класса: Mailbox и Message, для доступа к почтовым ящикам на диске и управления ими, а также для работы с содержащимися в них сообщениями. Mailbox предоставляет словареподобное отображение ключей на сообщения. Message расширяет класс email.message модуля Message, добавляя формат-специфичное состояние и поведение. Поддерживаемые форматы почтовых ящиков: Maildir, mbox, MH, Babyl и MMDF.
См. также
- Модуль email
- Представление сообщений и управление ими.
19.4.1. Mailbox объекты¶Mailbox objects
- class mailbox.Mailbox¶
Почтовый ящик, который можно просматривать и изменять.
Класс Mailbox определяет интерфейс и не предназначен для создания экземпляров. Вместо этого от Mailbox должны наследоваться подклассы, специфичные для формата, а код должен создавать экземпляры конкретного подкласса.
Интерфейс Mailbox напоминает словарь: небольшие ключи соответствуют сообщениям. Ключи выдаются экземпляром Mailbox, с которым они будут использоваться, и имеют смысл только для этого экземпляра Mailbox. Ключ продолжает идентифицировать сообщение, даже если соответствующее сообщение изменяется, например, заменяется другим сообщением.
Сообщения можно добавлять в экземпляр Mailbox с помощью метода, подобного set, add(), и удалять с помощью инструкции del или методов, подобных set, remove() и discard().
Семантика интерфейса Mailbox отличается от семантики словаря в некоторых важных аспектах. При каждом запросе сообщения создаётся новое представление (обычно экземпляр Message) на основе текущего состояния почтового ящика. Аналогично, при добавлении сообщения в экземпляр Mailbox содержимое переданного представления сообщения копируется. Ни в одном из случаев экземпляр Mailbox не хранит ссылку на представление сообщения.
Итератор по умолчанию Mailbox перебирает представления сообщений, а не ключи, как это делает итератор словаря по умолчанию. Более того, изменение почтового ящика во время итерации безопасно и имеет чётко определённое поведение. Сообщения, добавленные в почтовый ящик после создания итератора, не будут видны итератору. Сообщения, удалённые из почтового ящика до того, как итератор вернёт их, будут молча пропущены, хотя использование ключа от итератора может привести к исключению KeyError, если соответствующее сообщение будет впоследствии удалено.
Предупреждение
Следует соблюдать осторожность при изменении почтовых ящиков, которые могут одновременно изменяться другим процессом. Самый безопасный формат почтового ящика для таких задач – Maildir; следует избегать использования однофайловых форматов, таких как mbox, для одновременной записи. При изменении почтового ящика необходимо заблокировать его, вызвав методы lock() и unlock() перед чтением любых сообщений в файле или внесением любых изменений путём добавления или удаления сообщения. Неблокировка почтового ящика может привести к потере сообщений или повреждению всего почтового ящика.
Экземпляры Mailbox имеют следующие методы:
- add(message)¶
Добавляет сообщение в почтовый ящик и возвращает ключ, который был ему присвоен.
Параметр message может быть экземпляром Message, экземпляром email.message.Message, строкой, байтовой строкой или файлоподобным объектом (который должен быть открыт в бинарном режиме). Если message является экземпляром соответствующего формат-специфичного подкласса Message (например, если это экземпляр mboxMessage и данный экземпляр является mbox), используется его формат-специфичная информация. В противном случае используются разумные значения по умолчанию для формат-специфичной информации.
Изменено в версии 3.2: Добавлена поддержка двоичного ввода.
- remove(key)¶
- __delitem__(key)¶
- discard(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()¶
Возвращает итератор по парам (ключ, сообщение), где ключ – это ключ, а сообщение – представление сообщения, если метод вызван как iteritems(), или возвращает список таких пар, если вызван как items(). Сообщения представляются как экземпляры соответствующего подкласса Message, зависящего от формата, если только при инициализации экземпляра Mailbox не была указана пользовательская фабрика сообщений.
- get(key, default=None)¶
- __getitem__(key)¶
Возвращает представление сообщения, соответствующего ключу. Если такое сообщение отсутствует, возвращается значение по умолчанию, если метод был вызван как get(), и возбуждается исключение KeyError, если метод был вызван как __getitem__(). Сообщение представляется как экземпляр соответствующего подкласса Message, зависящего от формата, если только при инициализации экземпляра Mailbox не была указана пользовательская фабрика сообщений.
- get_message(key)¶
Возвращает представление сообщения, соответствующего ключу, в виде экземпляра соответствующего подкласса Message, зависящего от формата, или возбуждает исключение KeyError, если такое сообщение отсутствует.
- get_bytes(key)¶
Возвращает байтовое представление сообщения, соответствующего ключу, или возбуждает исключение KeyError, если такое сообщение отсутствует.
Новое в версии 3.2.
- get_string(key)¶
Возвращает строковое представление сообщения, соответствующего ключу, или возбуждает исключение KeyError, если такое сообщение отсутствует. Сообщение обрабатывается через email.message.Message для преобразования в 7-битное чистое представление.
- get_file(key)¶
Возвращает файлоподобное представление сообщения, соответствующего ключу, или возбуждает исключение KeyError, если такое сообщение отсутствует. Файлоподобный объект ведет себя как открытый в бинарном режиме. Этот файл следует закрыть, когда он больше не нужен.
Изменено в версии 3.2: файловый объект на самом деле является двоичным файлом; ранее он некорректно возвращался в текстовом режиме. Кроме того, теперь объект, подобный файлу, поддерживает протокол менеджера контекста: можно использовать оператор with для автоматического закрытия.
Примечание
В отличие от других представлений сообщений, файлоподобные представления не обязательно независимы от экземпляра Mailbox, который их создал, или от нижележащего почтового ящика. Более подробная документация предоставляется каждым подклассом.
- __contains__(key)¶
Возвращает True, если ключ соответствует сообщению, и False в противном случае.
- __len__()¶
Возвращает количество сообщений в почтовом ящике.
- clear()¶
Удаляет все сообщения из почтового ящика.
- pop(key, default=None)¶
Возвращает представление сообщения, соответствующего ключу, и удаляет сообщение. Если такое сообщение отсутствует, возвращает значение по умолчанию. Сообщение представляется как экземпляр соответствующего подкласса Message, зависящего от формата, если только при инициализации экземпляра Mailbox не была указана пользовательская фабрика сообщений.
- popitem()¶
Возвращает произвольную пару (ключ, сообщение), где ключ – это ключ, а сообщение – представление сообщения, и удаляет соответствующее сообщение. Если почтовый ящик пуст, возбуждает исключение KeyError. Сообщение представляется как экземпляр соответствующего подкласса Message, зависящего от формата, если только при инициализации экземпляра Mailbox не была указана пользовательская фабрика сообщений.
- update(arg)¶
Параметр arg должен быть отображением ключ → сообщение или итерируемым объектом из пар (ключ, сообщение). Обновляет почтовый ящик так, что для каждого заданного ключа и сообщения сообщение, соответствующее ключу, устанавливается в сообщение, как если бы это было сделано с помощью __setitem__(). Как и в случае с __setitem__(), каждый ключ уже должен соответствовать сообщению в почтовом ящике, иначе будет возбуждено исключение KeyError, поэтому в общем случае неверно, чтобы arg был экземпляром Mailbox.
Примечание
В отличие от словарей, именованные аргументы не поддерживаются.
- flush()¶
Записывает все ожидающие изменения в файловую систему. Для некоторых подклассов Mailbox изменения всегда записываются немедленно, и flush() ничего не делает, но всё равно стоит выработать привычку вызывать этот метод.
- lock()¶
Захватывает монопольную рекомендательную блокировку почтового ящика, чтобы другие процессы не изменяли его. Если блокировка недоступна, возбуждается исключение ExternalClashError. Конкретные механизмы блокировки зависят от формата почтового ящика. Следует всегда блокировать почтовый ящик перед внесением любых изменений в его содержимое.
- unlock()¶
Освобождает блокировку почтового ящика, если она установлена.
19.4.1.1. Maildir¶
- class mailbox.Maildir(dirname, factory=None, create=True)¶
Подкласс Mailbox для почтовых ящиков в формате Maildir. Параметр factory – это вызываемый объект, который принимает файлоподобное представление сообщения (ведущее себя как открытое в двоичном режиме) и возвращает пользовательское представление. Если factory равно None, то MaildirMessage используется как представление сообщения по умолчанию. Если create равно True, почтовый ящик создаётся, если он не существует.
По историческим причинам dirname назван так, а не path.
Maildir – это почтовый формат на основе каталогов, разработанный для агента передачи почты qmail и ныне широко поддерживаемый другими программами. Сообщения в почтовом ящике Maildir хранятся в отдельных файлах в общей структуре каталогов. Такая архитектура позволяет нескольким независимым программам получать доступ и изменять почтовые ящики Maildir без повреждения данных, поэтому файловая блокировка не требуется.
Почтовые ящики Maildir содержат три подкаталога: tmp, new и cur. Сообщения сперва создаются в подкаталоге tmp, а затем перемещаются в подкаталог new для завершения доставки. Почтовый клиент может затем переместить сообщение в подкаталог cur и сохранить информацию о состоянии сообщения в специальном разделе «info», добавляемом к его имени файла.
Также поддерживаются папки в стиле, введённом почтовым транспортным агентом Courier. Любой подкаталог основного почтового ящика считается папкой, если '.' является первым символом в его имени. Имена папок представляются объектами Maildir без ведущего '.'. Каждая папка сама является почтовым ящиком Maildir, но не должна содержать другие папки. Вместо этого логическая вложенность указывается с помощью '.' для разделения уровней, например «Archived.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)¶
В зависимости от платформы может быть невозможно изменить или удалить нижележащее сообщение, пока возвращенный файл остается открытым.
См. также
- Страница руководства maildir из qmail
- Оригинальная спецификация формата.
- Использование формата maildir
- Заметки о Maildir от его создателя. Включают обновлённую схему создания имён и детали семантики «info».
- man-страница maildir из Courier
- Другая спецификация формата. Описывает распространённое расширение для поддержки папок.
19.4.1.2. 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, заслуживают особых замечаний:
См. также
- Страница руководства mbox из qmail
- Спецификация формата и его разновидностей.
- Страница man mbox из tin
- Другая спецификация формата, с подробностями о блокировке.
- Настройка Netscape Mail в Unix: почему формат Content-Length плох
- Аргумент в пользу использования оригинального формата mbox, а не его вариации.
- «mbox» – это семейство нескольких взаимно несовместимых форматов почтовых ящиков
- История вариаций mbox.
19.4.1.3. 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 выбрасывается, если папка не существует.
- 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()¶
Используются три механизма блокировки – dot-блокировка и, если доступны, flock() и lockf() системные вызовы. Для почтовых ящиков MH блокировка почтового ящика означает блокировку файла .mh_sequences и, только на время любых операций, которые на них влияют, блокировку отдельных файлов сообщений.
- get_file(key)¶
В зависимости от платформы может быть невозможно удалить базовое сообщение, пока возвращённый файл остаётся открытым.
- flush()¶
Все изменения в почтовых ящиках MH применяются немедленно, поэтому этот метод ничего не делает.
См. также
- nmh – система обработки сообщений
- Домашняя страница nmh, обновлённой версии исходного mh.
- MH и nmh: электронная почта для пользователей и программистов
- Книга, лицензированная под GPL, о mh и nmh, с некоторой информацией о формате почтового ящика.
19.4.1.4. Babyl¶
- class mailbox.Babyl(path, factory=None, create=True)¶
Подкласс Mailbox для почтовых ящиков в формате Babyl. Параметр factory – это вызываемый объект, который принимает файлоподобное представление сообщения (которое ведет себя так, как если бы было открыто в бинарном режиме) и возвращает пользовательское представление. Если factory равно None, то в качестве представления сообщения по умолчанию используется BabylMessage. Если create равно True, почтовый ящик создается, если он не существует.
Babyl – это однофайловый формат почтового ящика, используемый почтовым клиентом Rmail, входящим в состав Emacs. Начало сообщения обозначается строкой, содержащей два символа: Control-Подчёркивание ('\037') и Control-L ('\014'). Конец сообщения обозначается началом следующего сообщения или, в случае последнего сообщения, строкой, содержащей символ Control-Подчёркивание ('\037').
Сообщения в почтовом ящике Babyl имеют два набора заголовков: исходные заголовки и так называемые видимые заголовки. Видимые заголовки обычно являются подмножеством исходных заголовков, которые были переформатированы или сокращены для большей привлекательности. Каждое сообщение в почтовом ящике Babyl также имеет сопутствующий список меток (коротких строк, которые записывают дополнительную информацию о сообщении), а список всех определённых пользователем меток, найденных в почтовом ящике, хранится в разделе параметров Babyl.
Экземпляры Babyl имеют все методы Mailbox, а также следующие:
- get_labels()¶
Возвращает список имён всех определённых пользователем меток, используемых в почтовом ящике.
Примечание
Фактические сообщения проверяются для определения того, какие метки существуют в почтовом ящике, вместо обращения к списку меток в разделе параметров Babyl, но раздел Babyl обновляется при каждом изменении почтового ящика.
Некоторые методы Mailbox, реализованные в Babyl, заслуживают отдельных замечаний:
- get_file(key)¶
В почтовых ящиках Babyl заголовки сообщения хранятся не подряд с телом сообщения. Чтобы создать представление, подобное файлу, заголовки и тело копируются вместе в экземпляр io.BytesIO, API которого идентичен API файла. В результате объект, подобный файлу, полностью независим от нижележащего почтового ящика, но не экономит память по сравнению со строковым представлением.
См. также
- Формат файлов Babyl версии 5
- Спецификация формата Babyl.
- Чтение почты с помощью Rmail
- Руководство по Rmail, содержащее некоторую информацию о семантике Babyl.
19.4.1.5. 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, заслуживают отдельных замечаний:
См. также
- страница руководства mmdf из tin
- Спецификация формата MMDF из документации tin, программы для чтения новостей.
- MMDF
- Статья в Википедии, описывающая Multichannel Memorandum Distribution Facility.
19.4.2. Message объекты¶Message objects
- class mailbox.Message(message=None)¶
Подкласс Message из модуля email.message. Подклассы mailbox.Message добавляют состояние и поведение, специфичные для формата почтового ящика.
Если параметр message опущен, новый экземпляр создается в состоянии по умолчанию, пустом. Если message является экземпляром email.message.Message, его содержимое копируется; кроме того, любая специфичная для формата информация преобразуется, насколько это возможно, если message является экземпляром Message. Если message является строкой, байтовой строкой или файлом, он должен содержать сообщение, совместимое с RFC 2822, которое считывается и разбирается. Файлы должны быть открыты в бинарном режиме, но текстовые файлы принимаются для обратной совместимости.
Формат-специфичные состояния и поведение, предоставляемые подклассами, различаются, но в целом поддерживаются только те свойства, которые не привязаны к конкретному почтовому ящику (хотя, предположительно, эти свойства специфичны для конкретного формата почтового ящика). Например, смещения в файлах для однофайловых форматов почтовых ящиков и имена файлов для форматов на основе каталогов не сохраняются, так как они применимы только к исходному почтовому ящику. Но такие состояния, как было ли сообщение прочитано пользователем или помечено как важное, сохраняются, поскольку они относятся к самому сообщению.
Нет требования, чтобы экземпляры Message использовались для представления сообщений, полученных с помощью экземпляров Mailbox. В некоторых ситуациях время и память, необходимые для создания представлений Message, могут быть неприемлемыми. Для таких ситуаций экземпляры Mailbox также предлагают строковые и файлоподобные представления, а пользовательская фабрика сообщений может быть указана при инициализации экземпляра Mailbox.
19.4.2.1. MaildirMessage¶
- class mailbox.MaildirMessage(message=None)¶
Сообщение с поведением, специфичным для Maildir. Параметр message имеет то же значение, что и в конструкторе Message.
Обычно почтовый клиент перемещает все сообщения из подкаталога new в подкаталог cur после первого открытия и закрытия почтового ящика пользователем, отмечая, что сообщения устарели, независимо от того, были ли они прочитаны. Каждое сообщение в cur имеет раздел «info», добавленный к его имени файла, для хранения информации о его состоянии. (Некоторые почтовые программы могут также добавлять раздел «info» к сообщениям в new.) Раздел «info» может принимать одну из двух форм: он может содержать «2,» с последующим списком стандартизированных флагов (например, «2,FR») или может содержать «1,» с последующей так называемой экспериментальной информацией. Стандартные флаги для сообщений Maildir следующие:
Флаг Значение Пояснение D Черновик В процессе составления F Помечено Помечено как важное P Передан Переслано, отправлено повторно или возвращено R Отвечено Получен ответ S Просмотрено Прочитано T Удалено Помечено для последующего удаления Экземпляры 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 или MMDFMessage состояние |
|---|---|
| Подкаталог «cur» | Флаг O |
| Флаг F | Флаг F |
| Флаг R | Флаг A |
| Флаг S | Флаг R |
| Флаг T | Флаг D |
Когда экземпляр MaildirMessage создается на основе экземпляра MHMessage, выполняются следующие преобразования:
| Результирующее состояние | MHMessage состояние |
|---|---|
| Подкаталог «cur» | последовательность «unseen» |
| подкаталог «cur» и флаг S | нет последовательности «unseen» |
| Флаг F | последовательность «flagged» |
| Флаг R | последовательность «replied» |
Когда экземпляр MaildirMessage создается на основе экземпляра BabylMessage, выполняются следующие преобразования:
| Результирующее состояние | BabylMessage состояние |
|---|---|
| Подкаталог «cur» | метка «unseen» |
| подкаталог «cur» и флаг S | нет метки «unseen» |
| Флаг P | метка «forwarded» или «resent» |
| Флаг R | метка «отвечено» |
| Флаг T | метка «удалено» |
19.4.2.2. mboxMessage¶
- class mailbox.mboxMessage(message=None)¶
Сообщение с поведением, специфичным для mbox. Параметр message имеет то же значение, что и в конструкторе Message.
Сообщения в почтовом ящике mbox хранятся вместе в одном файле. Адрес отправителя (envelope address) и время доставки обычно хранятся в строке, начинающейся с «From », которая используется для обозначения начала сообщения, хотя точный формат этих данных сильно различается в разных реализациях mbox. Флаги, указывающие на состояние сообщения, такие как прочитано или помечено как важное, обычно хранятся в заголовках Status и X-Status.
Обычные флаги для сообщений mbox:
Флаг Значение Пояснение R Прочитано Прочитано O Старое Ранее обнаружено почтовым клиентом D Удалено Помечено для последующего удаления F Помечено Помечено как важное A Отвечено Получен ответ Флаги «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 и флаг O | нет последовательности «unseen» |
| Флаг O | последовательность «unseen» |
| Флаг F | последовательность «flagged» |
| Флаг A | последовательность «replied» |
Когда экземпляр mboxMessage создаётся на основе экземпляра BabylMessage, выполняются следующие преобразования:
| Результирующее состояние | BabylMessage состояние |
|---|---|
| Флаг R и флаг O | нет метки «unseen» |
| Флаг O | метка «unseen» |
| Флаг D | метка «удалено» |
| Флаг A | метка «отвечено» |
Когда экземпляр Message создаётся на основе экземпляра MMDFMessage , строка «From » копируется, и все флаги напрямую соответствуют:
| Результирующее состояние | состояние MMDFMessage |
|---|---|
| Флаг R | Флаг R |
| Флаг O | Флаг O |
| Флаг D | Флаг D |
| Флаг F | Флаг F |
| Флаг A | Флаг A |
19.4.2.3. MHMessage¶
- class mailbox.MHMessage(message=None)¶
Сообщение с поведением, специфичным для MH. Параметр message имеет тот же смысл, что и в конструкторе Message.
Сообщения MH не поддерживают метки и флаги в традиционном понимании, но поддерживают последовательности – логические группировки произвольных сообщений. Некоторые почтовые программы (хотя не стандартные mh и nmh) используют последовательности примерно так же, как флаги используются в других форматах:
Последовательность Пояснение непрочитанное Не прочитано, но ранее обнаружено почтовым клиентом (MUA) отвечено Получен ответ помечено Помечено как важное Экземпляры 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» | метка «отвечено» |
19.4.2.4. BabylMessage¶
- class mailbox.BabylMessage(message=None)¶
Сообщение с поведением, специфичным для Babyl. Параметр message имеет тот же смысл, что и в конструкторе Message.
Некоторые метки сообщений, называемые attributes, по соглашению имеют специальное значение. Атрибуты следующие:
Метка Пояснение непрочитанное Не прочитано, но ранее обнаружено почтовым клиентом (MUA) удалено Помечено для последующего удаления архивировано Скопировано в другой файл или почтовый ящик отвечено Получен ответ переслано Переслано изменено Изменено пользователем переотправлено Отправлено повторно По умолчанию 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 |
| метка «удалено» | Флаг T |
| метка «отвечено» | Флаг R |
| Метка «forwarded» | Флаг P |
Когда экземпляр BabylMessage создаётся на основе экземпляра mboxMessage или MMDFMessage, заголовки Status и X-Status опускаются и выполняются следующие преобразования:
| Результирующее состояние | mboxMessage или MMDFMessage состояние |
|---|---|
| метка «unseen» | нет флага R |
| метка «удалено» | Флаг D |
| метка «отвечено» | Флаг A |
Когда экземпляр BabylMessage создаётся на основе экземпляра MHMessage, выполняются следующие преобразования:
| Результирующее состояние | MHMessage состояние |
|---|---|
| метка «unseen» | последовательность «unseen» |
| метка «отвечено» | последовательность «replied» |
19.4.2.5. MMDFMessage¶
- class mailbox.MMDFMessage(message=None)¶
Сообщение с поведением, специфичным для MMDF. Параметр message имеет то же значение, что и в конструкторе Message.
Как и сообщения в почтовом ящике mbox, сообщения MMDF хранятся с адресом отправителя и датой доставки в начальной строке, начинающейся с «From ». Аналогично, флаги, указывающие состояние сообщения, обычно хранятся в заголовках Status и X-Status.
Стандартные флаги для сообщений MMDF совпадают с флагами сообщений mbox и перечислены ниже:
Флаг Значение Пояснение R Прочитано Прочитано O Старое Ранее обнаружено почтовым клиентом D Удалено Помечено для последующего удаления F Помечено Помечено как важное A Отвечено Получен ответ Флаги «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 | метка «удалено» |
| Флаг A | метка «отвечено» |
Когда экземпляр MMDFMessage создаётся на основе экземпляра mboxMessage, строка «From » копируется и все флаги напрямую соответствуют:
| Результирующее состояние | mboxMessage состояние |
|---|---|
| Флаг R | Флаг R |
| Флаг O | Флаг O |
| Флаг D | Флаг D |
| Флаг F | Флаг F |
| Флаг A | Флаг A |
19.4.3. Исключения¶Exceptions
Следующие классы исключений определены в модуле mailbox:
- exception mailbox.Error¶
Базовый класс для всех остальных исключений, специфичных для модуля.
- exception mailbox.NoSuchMailboxError¶
Возникает, когда ожидается почтовый ящик, но он не найден, например, при создании экземпляра подкласса Mailbox с несуществующим путём (и с параметром create, установленным в False), или при открытии несуществующей папки.
- exception mailbox.NotEmptyError¶
Вызывается, когда почтовый ящик не пуст, но ожидается пустым, например, при удалении папки, содержащей сообщения.
- exception mailbox.ExternalClashError¶
Возникает, когда не зависящее от программы условие, связанное с почтовым ящиком, не позволяет продолжить работу, например, когда не удаётся получить блокировку, которая уже удерживается другой программой, или когда сгенерированное уникальное имя файла уже существует.
19.4.4. Примеры¶Examples
Простой пример вывода тем всех сообщений в почтовом ящике, которые кажутся интересными:
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:
# Получить почтовый ящик для использования.
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()