mailbox — Манипулировать почтовыми ящиками в различных форматах

Источник: Lib/mailbox.py


Этот модуль определяет два класса, Mailbox и Message, для доступа и работы с почтовыми ящиками на диске и содержащимися в них сообщениями. Mailbox предлагает словарно-подобное отображение ключей на сообщения. Message расширяет класс email.message модуля 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 iterator выполняет итерацию по представлениям сообщений, а не по ключам, как итератор по умолчанию dictionary. Кроме того, модификация почтового ящика во время итерации безопасна и хорошо определена. Сообщения, добавленные в почтовый ящик после создания итератора, не будут видны итератору. Сообщения, удаленные из почтового ящика до того, как итератор их выдаст, будут молча пропущены, хотя использование ключа из итератора может привести к исключению 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 (например, если это экземпляр mboxMessage, а это экземпляр mbox), то используется его информация, специфичная для формата. В противном случае форматно-специфическая информация сообщения, которое в данный момент соответствует key, остается без изменений.

iterkeys()

Возвращает iterator по всем ключам

keys()

То же самое, что и iterkeys(), за исключением того, что возвращается list, а не iterator.

itervalues()
__iter__()

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

Примечание

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

values()

То же самое, что и itervalues(), за исключением того, что возвращается list, а не iterator.

iteritems()

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

items()

То же самое, что и iteritems(), за исключением того, что возвращается list пар, а не iterator пар.

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

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

get_message(key)

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

get_bytes(key)

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

Added in version 3.2.

get_string(key)

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

get_file(key)

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

Изменено в версии 3.2: Объект файла действительно является binary file; ранее он некорректно возвращался в текстовом режиме. Кроме того, file-like object теперь поддерживает протокол context manager: вы можете использовать оператор with для его автоматического закрытия.

Примечание

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

__contains__(key)

Возвращает True, если ключ соответствует сообщению, 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, почтовый ящик создается, если он не существует.

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

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

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

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

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

colon

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

import mailbox
mailbox.Maildir.colon = '!'

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

Изменено в версии 3.13: Maildir теперь игнорирует файлы с ведущей точкой.

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

list_folders()

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

get_folder(folder)

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

add_folder(folder)

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

remove_folder(folder)

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

clean()

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

get_flags(key)

Возвращает в виде строки флаги, установленные в сообщении, соответствующем key. Это то же самое, что и get_message(key).get_flags(), но гораздо быстрее, поскольку не открывает файл сообщения. Используйте этот метод при итерации по ключам, чтобы определить, какие сообщения интересно получить.

Если у вас есть объект MaildirMessage, используйте вместо него метод get_flags(), потому что изменения, сделанные методами set_flags(), add_flag() и remove_flag() сообщения, не отражаются здесь до вызова метода __setitem__() почтового ящика.

Added in version 3.13.

set_flags(key, flags)

В сообщении, соответствующем key, установите флаги, указанные в flags, и снимите все остальные. Вызов some_mailbox.set_flags(key, flags) аналогичен вызову

one_message = some_mailbox.get_message(key)
one_message.set_flags(flags)
some_mailbox[key] = one_message

но быстрее, поскольку не открывает файл сообщения.

Если у вас есть объект MaildirMessage, используйте вместо него его метод set_flags(), потому что изменения, сделанные с помощью этого метода почтового ящика, не будут видны методу объекта message, get_flags().

Added in version 3.13.

add_flag(key, flag)

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

Соображения по поводу использования этого метода в сравнении с методом add_flag() объекта сообщения аналогичны соображениям для set_flags(); см. обсуждение там.

Added in version 3.13.

remove_flag(key, flag)

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

Соображения по поводу использования этого метода в сравнении с методом remove_flag() объекта сообщения аналогичны соображениям для set_flags(); см. обсуждение там.

Added in version 3.13.

get_info(key)

Возвращает строку, содержащую информацию о сообщении, соответствующем key. Это то же самое, что и get_message(key).get_info(), но гораздо быстрее, поскольку не открывает файл сообщения. Используйте этот метод при итерации по ключам, чтобы определить, какие сообщения интересно получить.

Если у вас есть объект MaildirMessage, используйте вместо него метод get_info(), потому что изменения, сделанные методом set_info() сообщения, не отражаются здесь до вызова метода __setitem__() почтового ящика.

Added in version 3.13.

set_info(key, info)

Установите значение info для сообщения, соответствующего key. Вызов some_mailbox.set_info(key, flags) аналогичен вызову

one_message = some_mailbox.get_message(key)
one_message.set_info(info)
some_mailbox[key] = one_message

но быстрее, поскольку не открывает файл сообщения.

Если у вас есть объект MaildirMessage, используйте вместо него его метод set_info(), потому что изменения, сделанные с помощью этого метода почтового ящика, не будут видны методу объекта message, get_info().

Added in version 3.13.

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

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

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

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

flush()

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

lock()
unlock()

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

close()

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

get_file(key)

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

См.также

maildir man page from Courier

Спецификация формата. Описывает общее расширение для поддержки папок.

Using maildir format

Заметки о Maildir от его изобретателя. Включает обновленную схему создания имен и подробности о семантике «info».

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().

См.также

mbox man page from tin

Спецификация формата с подробным описанием блокировки.

Configuring Netscape Mail on Unix: Why The Content-Length Format is Bad

Аргумент в пользу использования оригинального формата mbox, а не его разновидности.

«mbox» is a family of several mutually incompatible mailbox formats

История вариаций mbox.

MH объектов

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

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

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

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

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

Изменено в версии 3.13: Поддерживаются папки, не содержащие файлов .mh_sequences.

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 - Message Handling System

Главная страница nmh, обновленной версии оригинального mh.

MH & nmh: Email for Users & Programmers

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

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 также имеет сопровождающий список labels, или коротких строк, которые записывают дополнительную информацию о сообщении, а список всех пользовательских меток, найденных в почтовом ящике, хранится в разделе опций Babyl.

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

get_labels()

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

Примечание

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

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

get_file(key)

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

lock()
unlock()

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

См.также

Format of Version 5 Babyl Files

Спецификация формата Babyl.

Reading Mail with 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 man page from tin

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

MMDF

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

Message объектов

class mailbox.Message(message=None)

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

Если message опущено, новый экземпляр создается в пустом состоянии по умолчанию. Если message является экземпляром email.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

Проект

Под составом

F

Отмеченные флажками

Отмечено как важное

P

Передано

Передано, отправлено повторно или отбито

R

Ответил

Ответил на

S

Видели

Читать

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()

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

set_info(info)

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

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

Результирующее состояние

Состояние mboxMessage или MMDFMessage

Подкаталог «cur»

Флаг

Флаг

Флаг

Флаг

Флаг

Флаг

Флаг

Флаг

Флаг D

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

Результирующее состояние

MHMessage государство

Подкаталог «cur»

«Невидимая» последовательность

Подкаталог «cur» и флаг S

нет «невидимой» последовательности

Флаг

последовательность «флажков»

Флаг

«Ответил» последовательность

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

Результирующее состояние

BabylMessage государство

Подкаталог «cur»

«Невидимая» этикетка

Подкаталог «cur» и флаг S

нет «невидимой» этикетки

Флаг

метка «переслано» или «отправлено»

Флаг

ярлык «ответил»

Флаг

метка «удалено»

mboxMessage объектов

class mailbox.mboxMessage(message=None)

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

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

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

Флаг

Значение

Пояснение

R

Читать

Читать

O

Старый

Ранее обнаруженные MUA

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 государство

Флаг

Флаг

Флаг

Подкаталог «cur»

Флаг D

Флаг

Флаг

Флаг

Флаг

Флаг

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

Результирующее состояние

MHMessage государство

Флаг R и флаг O

нет «невидимой» последовательности

Флаг

«Невидимая» последовательность

Флаг

последовательность «флажков»

Флаг

«Ответил» последовательность

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

Результирующее состояние

BabylMessage государство

Флаг R и флаг O

нет «невидимой» этикетки

Флаг

«Невидимая» этикетка

Флаг D

метка «удалено»

Флаг

ярлык «ответил»

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

Результирующее состояние

MMDFMessage государство

Флаг

Флаг

Флаг

Флаг

Флаг D

Флаг D

Флаг

Флаг

Флаг

Флаг

MHMessage объектов

class mailbox.MHMessage(message=None)

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

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

Последовательность

Пояснение

невидимый

Не прочитано, но ранее обнаружено MUA

ответил

Ответил на

отмечено

Отмечено как важное

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

get_sequences()

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

set_sequences(sequences)

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

add_sequence(sequence)

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

remove_sequence(sequence)

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

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

Результирующее состояние

MaildirMessage государство

«Невидимая» последовательность

нет флага S

«Ответил» последовательность

Флаг

последовательность «флажков»

Флаг

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

Результирующее состояние

Состояние mboxMessage или MMDFMessage

«Невидимая» последовательность

нет флага R

«Ответил» последовательность

Флаг

последовательность «флажков»

Флаг

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

Результирующее состояние

BabylMessage государство

«Невидимая» последовательность

«Невидимая» этикетка

«Ответил» последовательность

ярлык «ответил»

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 государство

«Невидимая» этикетка

нет флага S

метка «удалено»

Флаг

ярлык «ответил»

Флаг

метка «forwarded»

Флаг

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

Результирующее состояние

Состояние mboxMessage или MMDFMessage

«Невидимая» этикетка

нет флага R

метка «удалено»

Флаг D

ярлык «ответил»

Флаг

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

Результирующее состояние

MHMessage государство

«Невидимая» этикетка

«Невидимая» последовательность

ярлык «ответил»

«Ответил» последовательность

MMDFMessage объектов

class mailbox.MMDFMessage(message=None)

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

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

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

Флаг

Значение

Пояснение

R

Читать

Читать

O

Старый

Ранее обнаруженные MUA

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 государство

Флаг

Флаг

Флаг

Подкаталог «cur»

Флаг D

Флаг

Флаг

Флаг

Флаг

Флаг

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

Результирующее состояние

MHMessage государство

Флаг R и флаг O

нет «невидимой» последовательности

Флаг

«Невидимая» последовательность

Флаг

последовательность «флажков»

Флаг

«Ответил» последовательность

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

Результирующее состояние

BabylMessage государство

Флаг R и флаг O

нет «невидимой» этикетки

Флаг

«Невидимая» этикетка

Флаг D

метка «удалено»

Флаг

ярлык «ответил»

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

Результирующее состояние

mboxMessage государство

Флаг

Флаг

Флаг

Флаг

Флаг D

Флаг D

Флаг

Флаг

Флаг

Флаг

Исключения

В модуле 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']       # Could possibly be 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                # The message is malformed. Just leave it.

    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]

            # Write copy to disk before removing original.
            # If there's a crash, you might duplicate a message, but
            # that's better than losing a message completely.
            box.lock()
            box.add(message)
            box.flush()
            box.unlock()

            # Remove original message
            inbox.lock()
            inbox.discard(key)
            inbox.flush()
            inbox.unlock()
            break               # Found destination, so stop looking.

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