
:mod:`mailbox` --- 様々な形式のメールボックス操作
=================================================

.. module:: mailbox
   :synopsis: 様々な形式のメールボックス操作
.. moduleauthor:: Gregory K. Johnson <gkj@gregorykjohnson.com>
.. sectionauthor:: Gregory K. Johnson <gkj@gregorykjohnson.com>


このモジュールでは二つのクラス :class:`Mailbox` および :class:`Message`
をディスク上のメールボックスとそこに収められたメッセージへのアクセスと操作のために定義しています。
:class:`Mailbox` は辞書のようなキーからメッセージへの対応付けを提供しています。
:class:`Message` は :mod:`email.Message` モジュールの
:class:`Message` を拡張して形式ごとの状態と振る舞いを追加しています。
サポートされるメールボックスの形式は Maildir, mbox, MH, Babyl, MMDF です。


.. seealso::

   Module :mod:`email`
      メッセージの表現と操作


.. _mailbox-objects:

:class:`Mailbox` オブジェクト
-----------------------------


.. class:: Mailbox

   メールボックス。中を見られたり変更されたりします。

   :class:`Mailbox` 自体はインタフェースを定義し形式ごとのサブクラスに\
   継承されるように意図されたもので、インスタンス化されることは想定されていません。
   インスタンス化したいならばサブクラスを代わりに使うべきです。

   :class:`Mailbox` のインタフェースは辞書風で、小さなキーがメッセージに対応します。
   キーは対象となる :class:`Mailbox`
   インスタンスが発行するもので、そのインスタンスに対してのみ意味を持ちます。
   一つのキーは一つのメッセージにひも付けられ、その対応はメッセージが\
   他のメッセージで置き換えられるような更新をされたあとも続きます。

   メッセージを :class:`Mailbox` インスタンスに追加するには集合風のメソッド
   :meth:`add` を使います。
   また削除は ``del`` 文または集合風の :meth:`remove` や :meth:`discard`
   を使って行ないます。

   :class:`Mailbox` インタフェースのセマンティクスと辞書のそれとは\
   注意すべき違いがあります。
   メッセージは、要求されるたびに新しい表現(典型的には
   :class:`Message` インスタンス)が現在のメールボックスの状態に基づいて生成されます。
   同様に、メッセージが :class:`Mailbox`
   インスタンスに追加される時も、渡されたメッセージ表現の内容がコピーされます。
   どちらの場合も :class:`Makebox` インスタンスにメッセージ表現への参照は保たれません。

   デフォルトの :class:`Mailbox` イテレータはメッセージ表現ごとに繰り返すもので、
   辞書のイテレータのようにキーごとの繰り返しではありません。
   さらに、繰り返し中のメールボックスを変更することは安全であり整合的に定義されています。
   イテレータが作られた後にメールボックスに追加されたメッセージは\
   そのイテレータからは見えません。
   そのイテレータが yield するまえにメールボックスから削除されたメッセージは\
   黙ってスキップされますが、イテレータからのキーを使ったときにはそのキーに対応する\
   メッセージが削除されているならば :exc:`KeyError` を受け取ることになります。

   .. warning::

      十分な注意を、何か他のプロセスによっても同時に変更される可能性のある\
      メールボックスを更新する時は、払わなければなりません。
      そのようなタスクをこなすのに最も安全なメールボックス形式は Maildir で、
      mbox のような単一ファイルの形式を並行した書き込みに利用するのは避けるように\
      努力しましょう。
      メールボックスを更新する場面では、 *必ず* :meth:`lock` と :meth:`unlock`
      メソッドを、ファイル内のメッセージを読んだり書き込んだり削除したりといった操作をする
      *前* に、呼び出してロックします。
      メールボックスをロックし損なうと、\
      メッセージを失ったりメールボックス全体をぐちゃぐちゃにしたりする羽目に陥ります。

   :class:`Mailbox` インスタンスには次のメソッドがあります。


   .. method:: add(message)

      メールボックスに *message* を追加し、それに割り当てられたキーを返します。

      引数 *message* は :class:`Message` インスタンス、
      :class:`email.Message.Message` インスタンス、文字列、ファイル風オブジェクト
      (テキストモードで開かれていなければなりませんが)を使えます。
      *message* が適切な形式に特化した :class:`Message` サブクラスのインスタンス
      (例えばメールボックスが :class:`mbox` インスタンスのときの
      :class:`mboxMessage` インスタンス)であれば、形式ごとの情報が利用されます。
      そうでなければ、形式ごとに必要な情報は適当なデフォルトが使われます。


   .. method:: remove(key)
               __delitem__(key)
               discard(key)

      メールボックスから *key* に対応するメッセージを削除します。

      対応するメッセージが無い場合、メソッドが :meth:`remove` または
      :meth:`__delitem__` として呼び出されている時は
      :exc:`KeyError` 例外が送出されます。
      しかし、 :meth:`discard` として呼び出されている場合は例外は発生しません。
      基づいているメールボックス形式が別のプロセスからの平行した変更をサポートしている\
      ならば、この :meth:`discard` の振る舞いの方が好まれるかもしれません。


   .. method:: __setitem__(key, message)

      *key* に対応するメッセージを *message* で置き換えます。
      *key* に対応しているメッセージが既に無くなっている場合
      :exc:`KeyError` 例外が送出されます。

      :meth:`add` と同様に、引数の *message* には :class:`Message` インスタンス、
      :class:`email.Message.Message` インスタンス、文字列、ファイル風オブジェクト
      (テキストモードで開かれていなければなりませんが)を使えます。
      *message* が適切な形式に特化した :class:`Message` サブクラスのインスタンス
      (例えばメールボックスが :class:`mbox` インスタンスのときの :class:`mboxMessage`
      インスタンス)であれば、形式ごとの情報が利用されます。
      そうでなければ、現在 *key* に対応するメッセージの形式ごとの情報が\
      変更されずに残ります。


   .. method:: iterkeys()
               keys()

      :meth:`iterkeys` として呼び出されると全てのキーについてのイテレータを返しますが、
      :meth:`keys` として呼び出されるとキーのリストを返します。


   .. method:: itervalues()
               __iter__()
               values()

      :meth:`itervalues` または :meth:`__iter__`
      として呼び出されると全てのメッセージの表現についてのイテレータを返しますが、
      :meth:`values` として呼び出されるとその表現のリストを返します。
      メッセージは適切な形式ごとの :class:`Message`
      サブクラスのインスタンスとして表現されるのが普通ですが、
      :class:`Mailbox` インスタンスが初期化されるときに指定すればお好みの\
      メッセージファクトリを使うこともできます。

      .. note::

         :meth:`__iter__` は辞書のそれのようにキーについてのイテレータではありません。


   .. method:: iteritems()
               items()

      (*key*, *message*) ペア、ただし *key* はキーで *message* はメッセージ表現、
      のイテレータ(:meth:`iteritems` として呼び出された場合)、
      またはリスト(:meth:`items` として呼び出された場合)を返します。
      メッセージは適切な形式ごとの :class:`Message`
      サブクラスのインスタンスとして表現されるのが普通ですが、
      :class:`Mailbox` インスタンスが初期化されるときに指定すればお好みの\
      メッセージファクトリを使うこともできます。


   .. method:: get(key[, default=None])
               __getitem__(key)

      *key* に対応するメッセージの表現を返します。
      対応するメッセージが存在しない場合、 :meth:`get` として呼び出されたなら
      *default* を返しますが、 :meth:`__getitem__` として呼び出されたなら
      :exc:`KeyError` 例外が送出されます。
      メッセージは適切な形式ごとの :class:`Message`
      サブクラスのインスタンスとして表現されるのが普通ですが、
      :class:`Mailbox` インスタンスが初期化されるときに指定すればお好みの\
      メッセージファクトリを使うこともできます。


   .. method:: Mailbox.get_message(key)

      *key* に対応するメッセージの表現を形式ごとの :class:`Message`
      サブクラスのインスタンスとして返します。
      もし対応するメッセージが存在しなければ :exc:`KeyError` 例外が送出されます。


   .. method:: get_string(key)

      *key* に対応するメッセージの表現を文字列として返します。
      もし対応するメッセージが存在しなければ :exc:`KeyError` 例外が送出されます。


   .. method:: get_file(key)

      *key* に対応するメッセージの表現をファイル風表現として返します。
      もし対応するメッセージが存在しなければ :exc:`KeyError` 例外が送出されます。
      ファイル風オブジェクトはバイナリモードで開かれているように振る舞います。
      このファイルは必要がなくなったら閉じなければなりません。

      .. note::

         他の表現方法とは違い、ファイル風オブジェクトはそれを作り出した
         :class:`Mailbox` インスタンスやそれが基づいているメールボックスと\
         独立である必要がありません。
         より詳細な説明は各サブクラスごとにあります。


   .. method:: has_key(key)
               __contains__(key)

      *key* がメッセージに対応していれば ``True`` を、
      そうでなければ ``False`` を返します。


   .. method:: __len__()

      メールボックス中のメッセージ数を返します。


   .. method:: clear()

      メールボックスから全てのメッセージを削除します。


   .. method:: pop(key[, default])

      *key* に対応するメッセージの表現を返します。
      もし対応するメッセージが存在しなければ *default*
      が供給されていればその値を返し、そうでなければ
      :exc:`KeyError` 例外を送出します。
      メッセージは適切な形式ごとの :class:`Message`
      サブクラスのインスタンスとして表現されるのが普通ですが、
      :class:`Mailbox` インスタンスが初期化されるときに指定すればお好みの\
      メッセージファクトリを使うこともできます。


   .. method:: popitem()

      任意に選んだ (*key*, *message*) ペアを返します。
      ただしここで *key* はキーで *message* はメッセージ表現です。
      もしメールボックスが空ならば、 :exc:`KeyError` 例外を送出します。
      メッセージは適切な形式ごとの :class:`Message`
      サブクラスのインスタンスとして表現されるのが普通ですが、
      :class:`Mailbox` インスタンスが初期化されるときに指定すればお好みの\
      メッセージファクトリを使うこともできます。


   .. method:: update(arg)

      引数 *arg* は *key* から *message* へのマッピングまたは (*key*, *message*)
      ペアのイテレート可能オブジェクトでなければなりません。
      メールボックスは、各 *key* と *message* のペアについて
      :meth:`__setitem__` を使ったかのように *key* に対応するメッセージが
      *message* になるように更新されます。
      :meth:`__setitem__` と同様に、
      *key* は既存のメールボックス中のメッセージに対応しているものでなければならず、
      そうでなければ :exc:`KeyError` が送出されます。
      ですから、一般的には *arg* に :class:`Mailbox` インスタンスを渡すのは間違いです。

      .. note::

         辞書と違い、キーワード引数はサポートされていません。


   .. method:: flush()

      保留されている変更をファイルシステムに書き込みます。
      :class:`Mailbox` のサブクラスによっては変更はいつも直ちにファイルに書き込まれ
      :meth:`flush` は何もしないということもありますが、\
      それでもこのメソッドを呼ぶように習慣付けておきましょう。


   .. method:: lock()

      メールボックスの排他的アドバイザリロックを取得し、\
      他のプロセスが変更しないようにします。
      ロックが取得できない場合 :exc:`ExternalClashError` が送出されます。
      ロック機構はメールボックス形式によって変わります。
      メールボックスの内容に変更を加えるときは *いつも* ロックを掛けるべきです。


   .. method:: unlock()

      メールボックスのロックを、もしあれば、解放します。


   .. method:: close()

      メールボックスをフラッシュし、必要ならばアンロックし、開いているファイルを閉じます。
      :class:`Mailbox` サブクラスによっては何もしないこともあります。


.. _mailbox-maildir:

:class:`Maildir`
^^^^^^^^^^^^^^^^


.. class:: Maildir(dirname[, factory=rfc822.Message[, create=True]])

   Maildir 形式のメールボックスのための :class:`Mailbox` のサブクラス。パラメータ *factory* は呼び出し可能オブジェクトで
   (バイナリモードで開かれているかのように振る舞う)ファイル風メッセージ表現を受け付けて好みの表現を返すものです。 *factory* が
   ``None`` ならば、 :class:`MaildirMessage` がデフォルトのメッセージ表現として使われます。 *create* が ``True``
   ならばメールボックスが存在しないときには作成します。

   *factory* のデフォルトが :class:`rfc822.Message` であったり、 *path* ではなく *dirname*
   という名前であったりというのは歴史的理由によるものです。 :class:`Maildir` インスタンスが他の :class:`Mailbox`
   サブクラスと同じように振る舞わせるためには、 *factory* に ``None`` をセットしてください。

   Maildir はディレクトリ型のメールボックス形式でメール転送エージェント qmail
   用に発明され、現在では多くの他のプログラムでもサポートされているものです。
   Maildir メールボックス中のメッセージは共通のディレクトリ構造の下で\
   個別のファイルに保存されます。
   このデザインにより、Maildir メールボックスは複数の無関係のプログラムから\
   データを失うことなくアクセスしたり変更したりできます。
   そのためロックは不要です。

   Maildir メールボックスには三つのサブディレクトリ
   :file:`tmp`, :file:`new`, :file:`cur` があります。
   メッセージはまず :file:`tmp` サブディレクトリに瞬間的に作られた後、
   :file:`new` サブディレクトリに移動されて配送を完了します。
   メールユーザエージェントが引き続いて :file:`cur` サブディレクトリにメッセージを移動し\
   メッセージの状態についての情報をファイル名に追加される特別な
   "info" セクションに保存することができます。

   Courier メール転送エージェントによって導入されたスタイルのフォルダもサポートされます。
   主たるメールボックスのサブディレクトリは ``'.'``
   がファイル名の先頭であればフォルダと見なされます。
   フォルダ名は :class:`Maildir` によって先頭の ``'.'``
   を除いて表現されます。
   各フォルダはまた Maildir メールボックスですがさらにフォルダを含むことはできません。
   その代わり、論理的包含関係は例えば
   "Archived.2005.07" のような ``'.'`` を使ったレベル分けで表わされます。

   .. note::

      本来の Maildir 仕様ではある種のメッセージのファイル名にコロン (``':'``)
      を使う必要があります。
      しかしながら、オペレーティングシステムによってはこの文字をファイル名に\
      含めることができないことがあります。
      そういった環境で Maildir のような形式を使いたい場合、\
      代わりに使われる文字を指定する必要があります。
      感嘆符 (``'!'``) を使うのが一般的な選択です。
      以下の例を見てください。
      ::

         import mailbox
         mailbox.Maildir.colon = '!'

      :attr:`colon` 属性はインスタンスごとにセットしても構いません。

   :class:`Maildir` インスタンスには :class:`Mailbox` の全てのメソッドに加え\
   以下のメソッドもあります。


   .. method:: list_folders()

      全てのフォルダ名のリストを返します。


   .. method:: get_folder(folder)

      名前が *folder* であるフォルダを表わす :class:`Maildir` インスタンスを返します。
      そのようなフォルダが存在しなければ
      :exc:`NoSuchMailboxError` 例外が送出されます。


   .. method:: Maildir.add_folder(folder)

      名前が *folder* であるフォルダを作り、それを表わす :class:`Maildir`
      インスタンスを返します。


   .. method:: remove_folder(folder)

      名前が *folder* であるフォルダを削除します。
      もしフォルダに一つでもメッセージが含まれていれば :exc:`NotEmptyError`
      例外が送出されフォルダは削除されません。


   .. method:: clean()

      過去36時間以内にアクセスされなかったメールボックス内の一時ファイルを削除します。
      Maildir 仕様はメールを読むプログラムはときどきこの作業をすべきだとしています。

   :class:`Maildir` で実装された :class:`Mailbox` のいくつかのメソッドには\
   特別な注意が必要です。


   .. method:: add(message)
               __setitem__(key, message)
               update(arg)

      .. warning::

         これらのメソッドは一意的なファイル名をプロセスIDに基づいて生成します。
         複数のスレッドを使う場合は、同じメールボックスを同時に操作しないように\
         スレッド間で調整しておかないと検知されない名前の衝突が起こり\
         メールボックスを壊すかもしれません。


   .. method:: flush()

      Maildir メールボックスへの変更は即時に適用されるので、このメソッドは何もしません。


   .. method:: lock()
               unlock()

      Maildir メールボックスはロックをサポート(または要求)しないので、\
      このメソッドは何もしません。


   .. method:: close()

      :class:`Maildir` インスタンスは開いたファイルを保持しませんし\
      メールボックスはロックをサポートしませんので、このメソッドは何もしません。


   .. method:: get_file(key)

      ホストのプラットフォームによっては、返されたファイルが開いている間、\
      元になったメッセージを変更したり削除したりできない場合があります。


.. seealso::

   `qmail の maildir man  ページ <http://www.qmail.org/man/man5/maildir.html>`_
      Maildir 形式のオリジナルの仕様

   `Using maildir format <http://cr.yp.to/proto/maildir.html>`_
      Maildir 形式の発明者による注意書き。
      更新された名前生成規則と "info" の解釈についても含まれます。

   `Courier の maildir man ページ <http://www.courier-mta.org/maildir.html>`_
      Maildir 形式のもう一つの仕様。
      フォルダをサポートする一般的な拡張について記述されています。


.. _mailbox-mbox:

:class:`mbox`
^^^^^^^^^^^^^


.. class:: mbox(path[, factory=None[, create=True]])

   mbox 形式のメールボックスのための :class:`Mailbox` のサブクラス。パラメータ *factory* は呼び出し可能オブジェクトで
   (バイナリモードで開かれているかのように振る舞う)ファイル風メッセージ表現を受け付けて好みの表現を返すものです。 *factory* が
   ``None`` ならば、 :class:`mboxMessage` がデフォルトのメッセージ表現として使われます。 *create* が ``True``
   ならばメールボックスが存在しないときには作成します。

   mbox 形式は Unixシステム上でメールを保存する古くからある形式です。
   mbox メールボックスでは全てのメッセージが一つのファイルに保存されており\
   それぞれのメッセージは "From " という5文字で始まる行を先頭に付けられています。

   mbox 形式には幾つかのバリエーションがあり、それぞれオリジナルの形式にあった欠点を\
   克服すると主張しています。互換性のために、 :class:`mbox`
   はオリジナルの(時に :dfn:`mboxo` と呼ばれる) 形式を実装しています。
   すなわち、 :mailheader:`Content-Length`
   ヘッダはもしあっても無視され、メッセージのボディにある行頭の
   "From " はメッセージを保存する際に ">From " に変換されますが、この
   ">From " は読み出し時にも "From " に変換されません。

   :class:`mbox` で実装された :class:`Mailbox` のいくつかのメソッドには\
   特別な注意が必要です。


   .. method:: get_file(key)

      :class:`mbox` インスタンスに対し :meth:`flush` や :meth:`close` を呼び出した\
      後でファイルを使用すると予期しない結果を引き起こしたり例外が送出されたりすることが\
      あります。


   .. method:: lock()
               unlock()

      3種類のロック機構が使われます --- ドットロッキングと、もし使用可能ならば
      :cfunc:`flock` と :cfunc:`lockf` システムコールです。


.. seealso::

   `qmail の mbox man ページ <http://www.qmail.org/man/man5/mbox.html>`_
      mbox 形式の仕様および種々のバリエーション

   `tin の mbox man ページ <http://www.tin.org/bin/man.cgi?section=5&topic=mbox>`_
      もう一つの mbox 形式の仕様でロックについての詳細を含む

   `Configuring Netscape Mail on Unix: Why The Content-Length Format is Bad <http://www.jwz.org/doc/content-length.html>`_
      バリエーションの一つではなくオリジナルの mbox を使う理由

   `"mbox" is a family of several mutually incompatible mailbox formats <http://homepages.tesco.net./~J.deBoynePollard/FGA/mail-mbox-formats.html>`_
      mbox バリエーションの歴史


.. _mailbox-mh:

:class:`MH`
^^^^^^^^^^^


.. class:: MH(path[, factory=None[, create=True]])

   MH 形式のメールボックスのための :class:`Mailbox` のサブクラス。パラメータ *factory* は呼び出し可能オブジェクトで
   (バイナリモードで開かれているかのように振る舞う)ファイル風メッセージ表現を受け付けて好みの表現を返すものです。 *factory* が
   ``None`` ならば、 :class:`MHMessage` がデフォルトのメッセージ表現として使われます。 *create* が ``True``
   ならばメールボックスが存在しないときには作成します。

   MH はディレクトリに基づいたメールボックス形式で MH Message Handling System
   というメールユーザエージェントのために発明されました。
   MH メールボックス中のそれぞれのメッセージは一つのファイルとして収められています。
   MH メールボックスにはメッセージの他に別の MH メールボックス
   (:dfn:`フォルダ` と呼ばれます)を含んでもかまいません。
   フォルダは無限にネストできます。
   MH メールボックスにはもう一つ :dfn:`シーケンス` という名前付きのリストで\
   メッセージをサブフォルダに移動することなく論理的に分類するものがサポートされています。
   シーケンスは各フォルダの :file:`.mh_sequences` というファイルで定義されます。

   :class:`MH` クラスは MH メールボックスを操作しますが、
   :program:`mh` の動作の全てを模倣しようとはしていません。
   特に、 :program:`mh` が状態と設定を保存する :file:`context` や
   :file:`.mh_profile` といったファイルは書き換えませんし影響も受けません。

   :class:`MH` インスタンスには :class:`Mailbox` の全てのメソッドの他に\
   次のメソッドがあります。


   .. method:: list_folders()

      全てのフォルダの名前のリストを返します。


   .. method:: get_folder(folder)

      *folder* という名前のフォルダを表わす :class:`MH` インスタンスを返します。
      もしフォルダが存在しなければ
      :exc:`NoSuchMailboxError` 例外が送出されます。


   .. method:: add_folder(folder)

      *folder* という名前のフォルダを作成し、それを表わす :class:`MH`
      インスタンスを返します。


   .. method:: remove_folder(folder)

      *folder* という名前のフォルダを削除します。
      フォルダにメッセージが一つでも残っていれば、 :exc:`NotEmptyError`
      例外が送出されフォルダは削除されません。


   .. method:: get_sequences()

      シーケンス名をキーのリストに対応付ける辞書を返します。
      シーケンスが一つもなければ空の辞書を返します。


   .. method:: set_sequences(sequences)

      メールボックス中のシーケンスを :meth:`get_sequences`
      で返されるような名前とキーのリストを対応付ける辞書 *sequences*
      に基づいて再定義します。


   .. method:: pack()

      番号付けの間隔を詰める必要に応じてメールボックス中のメッセージの名前を付け替えます。
      シーケンスのリストのエントリもそれに応じて更新されます。

      .. note::

         既に発行されたキーはこの操作によって無効になるのでそれ以降使ってはなりません。

   :class:`MH` で実装された :class:`Mailbox` のいくつかのメソッドには\
   特別な注意が必要です。


   .. method:: remove(key)
               __delitem__(key)
               discard(key)

      これらのメソッドはメッセージを直ちに削除します。
      名前の前にコンマを付加してメッセージに削除の印を付けるという MH の規約は使いません。


   .. method:: lock()
               unlock()

      3種類のロック機構が使われます --- ドットロッキングと、もし使用可能ならば
      :cfunc:`flock` と :cfunc:`lockf` システムコールです。
      MH メールボックスに対するロックとは :file:`.mh_sequences` のロックと、
      それが影響を与える操作中だけの個々のメッセージファイルに対するロックを意味します。


   .. method:: get_file(key)

      ホストのプラットフォームによっては、返されたファイルが開いている間、\
      元になったメッセージを変更したり削除したりできない場合があります。


   .. method:: flush()

      MH メールボックスへの変更は即時に適用されますのでこのメソッドは何もしません。


   .. method:: close()

      :class:`MH` インスタンスは開いたファイルを保持しませんので\
      このメソッドは :meth:`unlock` と同じです。


.. seealso::

   `nmh - Message Handling System <http://www.nongnu.org/nmh/>`_
      :program:`mh` の改良版である :program:`nmh` のホームページ

   `MH & nmh:  Email for Users & Programmers <http://www.ics.uci.edu/~mh/book/>`_
      GPLライセンスの :program:`mh` および :program:`nmh` の本で、このメールボックス形式についての情報があります


.. _mailbox-babyl:

:class:`Babyl`
^^^^^^^^^^^^^^


.. class:: Babyl(path[, factory=None[, create=True]])

   Babyl 形式のメールボックスのための :class:`Mailbox` のサブクラス。パラメータ *factory* は呼び出し可能オブジェクトで
   (バイナリモードで開かれているかのように振る舞う)ファイル風メッセージ表現を受け付けて好みの表現を返すものです。 *factory* が
   ``None`` ならば、 :class:`BabylMessage` がデフォルトのメッセージ表現として使われます。 *create* が ``True``
   ならばメールボックスが存在しないときには作成します。

   Babyl は単一ファイルのメールボックス形式で Emacs に付属している
   Rmail メールユーザエージェントで使われているものです。
   メッセージの開始は Control-Underscore (``'\\037'``) および
   Control-L (``'\\014'``) の二文字を含む行で示されます。
   メッセージの終了は次のメッセージの開始または最後のメッセージの場合には
   Control-Underscore を含む行で示されます。

   Babyl メールボックス中のメッセージには二つのヘッダのセット、
   オリジナルヘッダといわゆる可視ヘッダ、があります。
   可視ヘッダは典型的にはオリジナルヘッダの一部を分り易いように再整形したり\
   短くしたりしたものです。
   Babyl メールボックス中のそれぞれのメッセージには :dfn:`ラベル`
   というそのメッセージについての追加情報を記録する短い文字列のリストを伴い、
   メールボックス中に見出されるユーザが定義した全てのラベルのリストは Babyl
   オプションセクションに保持されます。

   :class:`Babyl` インスタンスには :class:`Mailbox` の全てのメソッドの他に\
   次のメソッドがあります。


   .. method:: get_labels()

      メールボックスで使われているユーザが定義した全てのラベルのリストを返します。

      .. note::

         メールボックスにどのようなラベルが存在するかを決めるのに、
         Babyl オプションセクションのリストを参考にせず、実際のメッセージを捜索しますが、
         Babyl セクションもメールボックスが変更されたときにはいつでも更新されます。

   :class:`Babyl` で実装された :class:`Mailbox` のいくつかのメソッドには\
   特別な注意が必要です。


   .. method:: get_file(key)

      Babyl メールボックスにおいて、メッセージのヘッダはボディと繋がって\
      格納されていません。
      ファイル風の表現を生成するために、ヘッダとボディが
      (:mod:`StringIO` モジュールの) ファイルと同じ API を持つ
      :class:`StringIO` インスタンスに一緒にコピーされます。
      その結果、ファイル風オブジェクトは本当に元にしているメールボックスとは\
      独立していますが、文字列表現と比べてメモリーを節約することにもなりません。


   .. method:: lock()
               unlock()

      3種類のロック機構が使われます --- ドットロッキングと、もし使用可能ならば
      :cfunc:`flock` と :cfunc:`lockf` システムコールです。


.. seealso::

   `Format of Version 5 Babyl Files <http://quimby.gnus.org/notes/BABYL>`_
      Babyl 形式の仕様

   `Reading Mail with Rmail <http://www.gnu.org/software/emacs/manual/html_node/emacs/Rmail.html>`_
      Rmail のマニュアルで Babyl のセマンティクスについての情報も少しある


.. _mailbox-mmdf:

:class:`MMDF`
^^^^^^^^^^^^^


.. class:: MMDF(path[, factory=None[, create=True]])

   MMDF 形式のメールボックスのための :class:`Mailbox` のサブクラス。パラメータ *factory* は呼び出し可能オブジェクトで
   (バイナリモードで開かれているかのように振る舞う)ファイル風メッセージ表現を受け付けて好みの表現を返すものです。 *factory* が
   ``None`` ならば、 :class:`BabylMessage` がデフォルトのメッセージ表現として使われます。 *create* が ``True``
   ならばメールボックスが存在しないときには作成します。

   MMDF は単一ファイルのメールボックス形式で
   Multichannel Memorandum Distribution Facility
   というメール転送エージェント用に発明されたものです。
   各メッセージは mbox と同様の形式で収められますが、前後を4つの Control-A
   (``'\\001'``) を含む行で挟んであります。
   mbox 形式と同じようにそれぞれのメッセージの開始は "From " の5文字を含む行で\
   示されますが、それ以外の場所での "From " は格納の際 ">From " には変えられません。
   それは追加されたメッセージ区切りによって新たなメッセージの開始と見間違うことが\
   避けられるからです。

   :class:`MMDF` で実装された :class:`Mailbox` のいくつかのメソッドには\
   特別な注意が必要です。


   .. method:: get_file(key)

      :class:`MMDF` インスタンスに対し :meth:`flush` や :meth:`close` を呼び出した\
      後でファイルを使用すると予期しない結果を引き起こしたり例外が送出されたりすることが\
      あります。


   .. method:: lock()
               unlock()

      3種類のロック機構が使われます --- ドットロッキングと、もし使用可能ならば
      :cfunc:`flock` と :cfunc:`lockf` システムコールです。


.. seealso::

   `tin の  mmdf man page <http://www.tin.org/bin/man.cgi?section=5&topic=mmdf>`_
      ニュースリーダ tin のドキュメント中の MMDF 形式仕様

   `MMDF <http://en.wikipedia.org/wiki/MMDF>`_
      Multichannel Memorandum Distribution Facility についてのウィキペディアの記事


.. _mailbox-message-objects:

:class:`Message` objects
------------------------


.. class:: Message([message])

   :mod:`email.Message` モジュールの :class:`Message` のサブクラス。 :class:`mailbox.Message`
   のサブクラスはメールボックス形式ごとの状態と動作を追加します。

   *message* が省略された場合、新しいインスタンスはデフォルトの空の状態で生成されます。 *message* が
   :class:`email.Message.Message` インスタンスならばその内容がコピーされます。さらに、 *message* が
   :class:`Message` インスタンスならば、形式固有の情報も可能な限り変換されます。 *message* が文字列または
   ファイルならば、読まれ解析されるべき :rfc:`2822` 準拠のメッセージを含んでいなければなりません

   サブクラスにより提供される形式ごとの状態と動作は様々ですが、一般に或るメールボックス\
   に固有のものでないプロパティだけがサポートされます(おそらくプロパティのセットは\
   メールボックス形式ごとに固有でしょうが)。例えば、単一ファイルメールボックス形式\
   におけるファイルオフセットやディレクトリ式メールボックス形式におけるファイル名は\
   保持されません、というのもそれらは元々のメールボックスにしか適用できないからです。
   しかし、メッセージがユーザに読まれたかどうかあるいは重要だとマークされたかどうか\
   という状態は保持されます、というのはそれらはメッセージ自体に適用されるからです。

   :class:`Mailbox` インスタンスを使って取得したメッセージを表現するのに
   :class:`Message` インスタンスが使われなければいけないとは要求していません。
   ある種の状況では :class:`Message` による表現を生成するのに必要な時間やメモリーが\
   受け入れられないこともあります。そういった状況では :class:`Mailbox` インスタンス\
   は文字列やファイル風オブジェクトの表現も提供できますし、 :class:`Mailbox`
   インスタンスを初期化する際にメッセージファクトリーを指定することもできます。


.. _mailbox-maildirmessage:

:class:`MaildirMessage`
^^^^^^^^^^^^^^^^^^^^^^^


.. class:: MaildirMessage([message])

   Maildir 固有の動作をするメッセージ。
   引数 *message* は :class:`Message` のコンストラクタと同じ意味を持ちます。

   通常、メールユーザエージェントは :file:`new` サブディレクトリにある\
   全てのメッセージをユーザが最初にメールボックスを開くか閉じるかした後で
   :file:`cur` サブディレクトリに移動し、メッセージが実際に読まれたかどうかを記録します。
   :file:`cur` にある各メッセージには状態情報を保存するファイル名に付け加えられた
   "info" セクションがあります。(メールリーダの中には "info" セクションを
   :file:`new` にあるメッセージに付けることもあります。)
   "info" セクションには二つの形式があります。一つは "2,"
   の後に標準化されたフラグのリストを付けたもの (たとえば "2,FR")、もう一つは "1,"
   の後にいわゆる実験的情報を付け加えるものです。 Maildir
   の標準的なフラグは以下の通りです:

   +--------+---------------------+--------------------------+
   | フラグ | 意味                | 説明                     |
   +========+=====================+==========================+
   | D      | ドラフト(Draft)     | 作成中                   |
   +--------+---------------------+--------------------------+
   | F      | フラグ付き(Flagged) | 重要とされたもの         |
   +--------+---------------------+--------------------------+
   | P      | 通過(Passed)        | 転送、再送またはバウンス |
   +--------+---------------------+--------------------------+
   | R      | 返答済み(Replied)   | 返答されたもの           |
   +--------+---------------------+--------------------------+
   | S      | 既読(Seen)          | 読んだもの               |
   +--------+---------------------+--------------------------+
   | T      | ごみ(Trashed)       | 削除予定とされたもの     |
   +--------+---------------------+--------------------------+

   :class:`MaildirMessage` インスタンスは以下のメソッドを提供します。


   .. method:: get_subdir()

      "new" (メッセージが :file:`new` サブディレクトリに保存されるべき場合)
      または "cur" (メッセージが :file:`cur`
      サブディレクトリに保存されるべき場合)のどちらかを返します。

      .. note::

         メッセージは通常メールボックスがアクセスされた後、\
         メッセージが読まれたかどうかに関わらず :file:`new` から :file:`cur`
         に移動されます。
         メッセージ ``msg`` は ``"S" not in msg.get_flags()`` が ``True``
         ならば読まれています。


   .. method:: set_subdir(subdir)

      メッセージが保存されるべきサブディレクトリをセットします。
      パラメータ *subdir* は "new" または "cur" のいずれかでなければなりません。


   .. method:: get_flags()

      現在セットされているフラグを特定する文字列を返します。
      メッセージが標準 Maildir 形式に準拠しているならば、\
      結果はアルファベット順に並べられたゼロまたは1回の ``'D'`` 、
      ``'F'`` 、 ``'P'`` 、 ``'R'`` 、 ``'S'`` 、 ``'T'`` をつなげたものです。
      空文字列が返されるのはフラグが一つもない場合、または
      "info" が実験的セマンティクスを使っている場合です。


   .. method:: set_flags(flags)

      *flags* で指定されたフラグをセットし、他のフラグは下ろします。


   .. method:: add_flag(flag)

      *flags* で指定されたフラグをセットしますが他のフラグは変えません。
      一度に二つ以上のフラグをセットすることは、 *flag* に2文字以上の文字列を\
      指定すればできます。
      現在の "info" はフラグの代わりに実験的情報を使っていても上書きされます。


   .. method:: remove_flag(flag)

      *flags* で指定されたフラグを下ろしますが他のフラグは変えません。
      一度に二つ以上のフラグを取り除くことは、 *flag* に2文字以上の文字列を\
      指定すればできます。
      "info" がフラグの代わりに実験的情報を使っている場合は現在の
      "info" は書き換えられません。


   .. method:: get_date()

      メッセージの配送日時をエポックからの秒数を表わす浮動小数点数で返します。


   .. method:: set_date(date)

      メッセージの配送日時を *date* にセットします。
      *date* はエポックからの秒数を表わす浮動小数点数です。


   .. method:: get_info()

      メッセージの "info" を含む文字列を返します。
      このメソッドは実験的 (即ちフラグのリストでない) "info"
      にアクセスし、また変更するのに役立ちます。


   .. method:: set_info(info)

      "info" に文字列 *info* をセットします。

:class:`MaildirMessage` インスタンスが :class:`mboxMessage` や :class:`MMDFMessage`
のインスタンスに基づいて生成されるとき、 :mailheader:`Status` および :mailheader:`X-Status`
ヘッダは省かれ以下の変換が行われます:

+------------------------+--------------------------------------------------+
| 結果の状態             | :class:`mboxMessage` または :class:`MMDFMessage` |
|                        | の状態                                           |
+========================+==================================================+
| "cur" サブディレクトリ | O フラグ                                         |
+------------------------+--------------------------------------------------+
| F フラグ               | F フラグ                                         |
+------------------------+--------------------------------------------------+
| R フラグ               | A フラグ                                         |
+------------------------+--------------------------------------------------+
| S フラグ               | R フラグ                                         |
+------------------------+--------------------------------------------------+
| T フラグ               | D フラグ                                         |
+------------------------+--------------------------------------------------+

:class:`MaildirMessage` インスタンスが :class:`MHMessage` インスタンスに\
基づいて生成されるとき、以下の変換が行われます:

+---------------------------------------+---------------------------+
| 結果の状態                            | :class:`MHMessage` の状態 |
+=======================================+===========================+
| "cur" サブディレクトリ                | "unseen" シーケンス       |
+---------------------------------------+---------------------------+
| "cur" サブディレクトリおよび S フラグ | "unseen" シーケンス無し   |
+---------------------------------------+---------------------------+
| F フラグ                              | "flagged" シーケンス      |
+---------------------------------------+---------------------------+
| R フラグ                              | "replied" シーケンス      |
+---------------------------------------+---------------------------+

:class:`MaildirMessage` インスタンスが :class:`BabylMessage` インスタンスに\
基づいて生成されるとき、以下の変換が行われます:

+---------------------------------------+------------------------------------+
| 結果の状態                            | :class:`BabylMessage` の状態       |
+=======================================+====================================+
| "cur" サブディレクトリ                | "unseen" ラベル                    |
+---------------------------------------+------------------------------------+
| "cur" サブディレクトリおよび S フラグ | "unseen" ラベル無し                |
+---------------------------------------+------------------------------------+
| P フラグ                              | "forwarded" または "resent" ラベル |
+---------------------------------------+------------------------------------+
| R フラグ                              | "answered" ラベル                  |
+---------------------------------------+------------------------------------+
| T フラグ                              | "deleted" ラベル                   |
+---------------------------------------+------------------------------------+


.. _mailbox-mboxmessage:

:class:`mboxMessage`
^^^^^^^^^^^^^^^^^^^^


.. class:: mboxMessage([message])

   mbox 固有の動作をするメッセージ。引数 *message* は :class:`Message` のコンストラクタと同じ意味を持ちます。

   mbox メールボックス中のメッセージは単一ファイルにまとめて格納されています。
   送り主のエンベロープアドレスおよび配送日時は通常メッセージの開始を示す
   "From " から始まる行に記録されますが、正確なフォーマットに関しては mbox の実装ごとに\
   大きな違いがあります。メッセージの状態を示すフラグ、たとえば読んだかどうか\
   あるいは重要だとマークを付けられているかどうかといったようなもの、は典型的には
   :mailheader:`Status` および :mailheader:`X-Status` に収められます。

   規定されている mbox メッセージのフラグは以下の通りです:

   +--------+---------------------+-------------------------+
   | フラグ | 意味                | 説明                    |
   +========+=====================+=========================+
   | R      | 既読(Read)          | 読んだ                  |
   +--------+---------------------+-------------------------+
   | O      | 古い(Old)           | 以前に MUA に発見された |
   +--------+---------------------+-------------------------+
   | D      | 削除(Deleted)       | 削除予定                |
   +--------+---------------------+-------------------------+
   | F      | フラグ付き(Flagged) | 重要だとマークされた    |
   +--------+---------------------+-------------------------+
   | A      | 返答済み(Answered)  | 返答した                |
   +--------+---------------------+-------------------------+

   "R" および "O" フラグは :mailheader:`Status` ヘッダに記録され、
   "D"、"F"、"A" フラグは :mailheader:`X-Status` ヘッダに記録されます。
   フラグとヘッダは通常記述された順番に出現します。

   :class:`mboxMessage` インスタンスは以下のメソッドを提供します:


   .. method:: get_from()

      mbox メールボックスのメッセージの開始を示す "From " 行を表わす文字列を返します。
      先頭の "From " および末尾の改行は含まれません。


   .. method:: set_from(from_[, time_=None])

      "From " 行を *from_* にセットします。
      *from_* は先頭の "From " や末尾の改行を含まない形で指定しなければなりません。
      利便性のために、 *time_* を指定して適切に整形して *from_*
      に追加させることができます。
      *time_* を指定する場合、それは :class:`struct_time`
      インスタンス、 :meth:`time.strftime` に渡すのに適したタプル、または
      ``True`` (この場合 :meth:`time.gmtime` を使います)
      のいずれかでなければなりません。


   .. method:: get_flags()

      現在セットされているフラグを特定する文字列を返します。
      メッセージが規定された形式に準拠しているならば、結果は次の順に並べられた
      0回か1回の ``'R'`` 、 ``'O'`` 、 ``'D'`` 、 ``'F'`` 、 ``'A'`` です。


   .. method:: set_flags(flags)

      *flags* で指定されたフラグをセットして、他のフラグは下ろします。
      *flags* は並べられたゼロまたは1回の ``'R'`` 、
      ``'O'`` 、 ``'D'`` 、 ``'F'`` 、 ``'A'`` です。


   .. method:: add_flag(flag)

      *flags* で指定されたフラグをセットしますが他のフラグは変えません。
      一度に二つ以上のフラグをセットすることは、 *flag* に2文字以上の文字列を\
      指定すればできます。


   .. method:: remove_flag(flag)

      *flags* で指定されたフラグを下ろしますが他のフラグは変えません。
      一度に二つ以上のフラグを取り除くことは、 *flag* に2文字以上の文字列を\
      指定すればできます。

:class:`mboxMessage` インスタンスが :class:`MaildirMessage` インスタンスに
基づいて生成されるとき、 :class:`MaildirMessage` インスタンスの配送日時に基づいて "From " 行が作り出され、次の変換が行われます:

+------------+--------------------------------+
| 結果の状態 | :class:`MaildirMessage` の状態 |
+============+================================+
| R フラグ   | S フラグ                       |
+------------+--------------------------------+
| O フラグ   | "cur" サブディレクトリ         |
+------------+--------------------------------+
| D フラグ   | T フラグ                       |
+------------+--------------------------------+
| F フラグ   | F フラグ                       |
+------------+--------------------------------+
| A フラグ   | R フラグ                       |
+------------+--------------------------------+

:class:`mboxMessage` インスタンスが :class:`MHMessage` インスタンスに基づいて生成されるとき、以下の変換が行われます。

+--------------------------+-------------------------+
| 結果の状態               | :class:`MHMessage` 状態 |
+==========================+=========================+
| R フラグおよび O フラグ  | "unseen" シーケンス無し |
+--------------------------+-------------------------+
| O フラグ                 | "unseen" シーケンス     |
+--------------------------+-------------------------+
| F フラグ                 | "flagged" シーケンス    |
+--------------------------+-------------------------+
| A フラグ                 | "replied" シーケンス    |
+--------------------------+-------------------------+

:class:`mboxMessage` インスタンスが :class:`BabylMessage` インスタンスに\
基づいて生成されるとき、以下の変換が行われます:

+--------------------------+------------------------------+
| 結果の状態               | :class:`BabylMessage` の状態 |
+==========================+==============================+
| R フラグおよび O フラグ  | "unseen" ラベル無し          |
+--------------------------+------------------------------+
| O フラグ                 | "unseen" ラベル              |
+--------------------------+------------------------------+
| D フラグ                 | "deleted" ラベル             |
+--------------------------+------------------------------+
| A フラグ                 | "answered" ラベル            |
+--------------------------+------------------------------+

:class:`mboxMessage` インスタンスが :class:`MMDFMessage` インスタンスに基づいて生成されるとき、"From "
行はコピーされ全てのフラグは直接対応します:

+------------+-----------------------------+
| 結果の状態 | :class:`MMDFMessage` の状態 |
+============+=============================+
| R フラグ   | R フラグ                    |
+------------+-----------------------------+
| O フラグ   | O フラグ                    |
+------------+-----------------------------+
| D フラグ   | D フラグ                    |
+------------+-----------------------------+
| F フラグ   | F フラグ                    |
+------------+-----------------------------+
| A フラグ   | A フラグ                    |
+------------+-----------------------------+


.. _mailbox-mhmessage:

:class:`MHMessage`
^^^^^^^^^^^^^^^^^^


.. class:: MHMessage([message])

   MH 固有の動作をするメッセージ。引数 *message* は :class:`Message` のコンストラクタと同じ意味を持ちます。

   MH メッセージは伝統的な意味あいにおいてマークやフラグをサポートしません。
   しかし、MH メッセージにはシーケンスがあり任意のメッセージを論理的に\
   グループ分けできます。いくつかのメールソフト(標準の :program:`mh` や
   :program:`nmh` はそうではありませんが) は他の形式におけるフラグとほぼ\
   同じようにシーケンスを使います。

   +------------+-------------------------------------------+
   | シーケンス | 説明                                      |
   +============+===========================================+
   | unseen     | 読んではいないが既にMUAに見つけられている |
   +------------+-------------------------------------------+
   | replied    | 返答した                                  |
   +------------+-------------------------------------------+
   | flagged    | 重要だとマークされた                      |
   +------------+-------------------------------------------+

   :class:`MHMessage` インスタンスは以下のメソッドを提供します:


   .. method:: get_sequences()

      このメッセージを含むシーケンスの名前のリストを返す。


   .. method:: set_sequences(sequences)

      このメッセージを含むシーケンスのリストをセットする。


   .. method:: add_sequence(sequence)

      *sequence* をこのメッセージを含むシーケンスのリストに追加する。


   .. method:: remove_sequence(sequence)

      *sequence* をこのメッセージを含むシーケンスのリストから除く。

:class:`MHMessage` インスタンスが :class:`MaildirMessage` インスタンスに\
基づいて生成されるとき、以下の変換が行われます:

+----------------------+--------------------------------+
| 結果の状態           | :class:`MaildirMessage` の状態 |
+======================+================================+
| "unseen" シーケンス  | S フラグ無し                   |
+----------------------+--------------------------------+
| "replied" シーケンス | R フラグ                       |
+----------------------+--------------------------------+
| "flagged" シーケンス | F フラグ                       |
+----------------------+--------------------------------+

:class:`MHMessage` インスタンスが :class:`mboxMessage` や :class:`MMDFMessage`
のインスタンスに基づいて生成されるとき、 :mailheader:`Status` および :mailheader:`X-Status`
ヘッダは省かれ以下の変換が行われます:

+----------------------+--------------------------------------------------+
| 結果の状態           | :class:`mboxMessage` または :class:`MMDFMessage` |
|                      | の状態                                           |
+======================+==================================================+
| "unseen" シーケンス  | R フラグ無し                                     |
+----------------------+--------------------------------------------------+
| "replied" シーケンス | A フラグ                                         |
+----------------------+--------------------------------------------------+
| "flagged" シーケンス | F フラグ                                         |
+----------------------+--------------------------------------------------+

:class:`MHMessage` インスタンスが :class:`BabylMessage` インスタンスに
基づいて生成されるとき、以下の変換が行われます:

+----------------------+------------------------------+
| 結果の状態           | :class:`BabylMessage` の状態 |
+======================+==============================+
| "unseen" シーケンス  | "unseen" ラベル              |
+----------------------+------------------------------+
| "replied" シーケンス | "answered" ラベル            |
+----------------------+------------------------------+


.. _mailbox-babylmessage:

:class:`BabylMessage`
^^^^^^^^^^^^^^^^^^^^^


.. class:: BabylMessage([message])

   Babyl 固有の動作をするメッセージ。引数 *message* は :class:`Message` のコンストラクタと同じ意味を持ちます。

   ある種のメッセージラベルは :dfn:`アトリビュート` と呼ばれ、規約により特別な意味が与えられています。アトリビュートは以下の通りです:

   +-----------+------------------------------------------------+
   | ラベル    | 説明                                           |
   +===========+================================================+
   | unseen    | 読んでいないが既に MUA に見つかっている        |
   +-----------+------------------------------------------------+
   | deleted   | 削除予定                                       |
   +-----------+------------------------------------------------+
   | filed     | 他のファイルまたはメールボックスにコピーされた |
   +-----------+------------------------------------------------+
   | answered  | 返答済み                                       |
   +-----------+------------------------------------------------+
   | forwarded | 転送された                                     |
   +-----------+------------------------------------------------+
   | edited    | ユーザによって変更された                       |
   +-----------+------------------------------------------------+
   | resent    | 再送された                                     |
   +-----------+------------------------------------------------+

   デフォルトでは Rmail は可視ヘッダのみ表示します。
   :class:`BabylMessage` クラスはしかし、
   オリジナルヘッダをより完全だという理由で使います。
   可視ヘッダは望むならそのように指示してアクセスすることができます。

   :class:`BabylMessage` インスタンスは以下のメソッドを提供します:


   .. method:: get_labels()

      メッセージに付いているラベルのリストを返します。


   .. method:: set_labels(labels)

      メッセージに付いているラベルのリストを *labels* にセットします。


   .. method:: add_label(label)

      メッセージに付いているラベルのリストに *label* を追加します。


   .. method:: remove_label(label)

      メッセージに付いているラベルのリストから *label* を削除します。


   .. method:: get_visible()

      ヘッダがメッセージの可視ヘッダでありボディが空であるような
      :class:`Message` インスタンスを返します。


   .. method:: set_visible(visible)

      メッセージの可視ヘッダを *visible* のヘッダと同じにセットします。
      引数 *visible* は :class:`Message` インスタンスまたは
      :class:`email.Message.Message` インスタンス、文字列、\
      ファイル風オブジェクト(テキストモードで開かれてなければなりません)のいずれかです。


   .. method:: update_visible()

      :class:`BabylMessage` インスタンスのオリジナルヘッダが変更されたとき、\
      可視ヘッダは自動的に対応して変更されるわけではありません。
      このメソッドは可視ヘッダを以下のように更新します。
      対応するオリジナルヘッダのある可視ヘッダはオリジナルヘッダの値がセットされます。
      対応するオリジナルヘッダの無い可視ヘッダは除去されます。
      そして、オリジナルヘッダにあって可視ヘッダに無い :mailheader:`Date` 、
      :mailheader:`From` 、 :mailheader:`Reply-To` 、 :mailheader:`To` 、
      :mailheader:`CC` 、 :mailheader:`Subject` は可視ヘッダに追加されます。

:class:`BabylMessage` インスタンスが :class:`MaildirMessage` インスタンスに\
基づいて生成されるとき、以下の変換が行われます:

+--------------------+--------------------------------+
| 結果の状態         | :class:`MaildirMessage` の状態 |
+====================+================================+
| "unseen" ラベル    | S フラグ無し                   |
+--------------------+--------------------------------+
| "deleted" ラベル   | T フラグ                       |
+--------------------+--------------------------------+
| "answered" ラベル  | R フラグ                       |
+--------------------+--------------------------------+
| "forwarded" ラベル | P フラグ                       |
+--------------------+--------------------------------+

:class:`BabylMessage` インスタンスが :class:`mboxMessage` や :class:`MMDFMessage`
のインスタンスに基づいて生成されるとき、 :mailheader:`Status` および :mailheader:`X-Status`
ヘッダは省かれ以下の変換が行われます:

+-------------------+--------------------------------------------------+
| 結果の状態        | :class:`mboxMessage` または :class:`MMDFMessage` |
|                   | の状態                                           |
+===================+==================================================+
| "unseen" ラベル   | R フラグ無し                                     |
+-------------------+--------------------------------------------------+
| "deleted" ラベル  | D フラグ                                         |
+-------------------+--------------------------------------------------+
| "answered" ラベル | A フラグ                                         |
+-------------------+--------------------------------------------------+

:class:`BabylMessage` インスタンスが :class:`MHMessage` インスタンスに
基づいて生成されるとき、以下の変換が行われます:

+-------------------+---------------------------+
| 結果の状態        | :class:`MHMessage` の状態 |
+===================+===========================+
| "unseen" ラベル   | "unseen" シーケンス       |
+-------------------+---------------------------+
| "answered" ラベル | "replied" シーケンス      |
+-------------------+---------------------------+


.. _mailbox-mmdfmessage:

:class:`MMDFMessage`
^^^^^^^^^^^^^^^^^^^^


.. class:: MMDFMessage([message])

   MMDF 固有の動作をするメッセージ。引数 *message* は :class:`Message` のコンストラクタと同じ意味を持ちます。

   mbox メールボックスのメッセージと同様に、MMDF メッセージは送り主のアドレスと\
   配送日時が最初の "From " で始まる行に記録されています。
   同様に、メッセージの状態を示すフラグは通常 :mailheader:`Status` および
   :mailheader:`X-Status` ヘッダに収められています。

よく使われる MMDF メッセージのフラグは mbox メッセージのものと同一で以下の通りです:

   +--------+---------------------+-------------------------+
   | フラグ | 意味                | 説明                    |
   +========+=====================+=========================+
   | R      | 既読(Read)          | 読んだ                  |
   +--------+---------------------+-------------------------+
   | O      | 古い(Old)           | 以前に MUA に発見された |
   +--------+---------------------+-------------------------+
   | D      | 削除(Deleted)       | 削除予定                |
   +--------+---------------------+-------------------------+
   | F      | フラグ付き(Flagged) | 重要だとマークされた    |
   +--------+---------------------+-------------------------+
   | A      | 返答済み(Answered)  | 返答した                |
   +--------+---------------------+-------------------------+

   "R" および "O" フラグは :mailheader:`Status` ヘッダに記録され、
   "D"、"F"、"A" フラグは
   :mailheader:`X-Status` ヘッダに記録されます。
   フラグとヘッダは通常記述された順番に出現します。

   :class:`MMDFMessage` インスタンスは :class:`mboxMessage`
   インスタンスと同一の以下のメソッドを提供します:


   .. method:: get_from()

      MMDF メールボックスのメッセージの開始を示す "From " 行を表わす文字列を返します。
      先頭の "From " および末尾の改行は含まれません。


   .. method:: set_from(from_[, time_=None])

      "From " 行を *from_* にセットします。 *from_* は先頭の "From " や\
      末尾の改行を含まない形で指定しなければなりません。
      利便性のために、 *time_* を指定して適切に整形して *from_*
      に追加させることができます。
      *time_* を指定する場合、それは :class:`struct_time` インスタンス、
      :meth:`time.strftime` に渡すのに適したタプル、または ``True``
      (この場合 :meth:`time.gmtime` を使います) のいずれかでなければなりません。


   .. method:: get_flags()

      現在セットされているフラグを特定する文字列を返します。
      メッセージが規定された形式に準拠しているならば、結果は次の順に並べられた\
      ゼロまたは1回の ``'R'`` 、 ``'O'`` 、 ``'D'`` 、 ``'F'`` 、 ``'A'`` です。


   .. method:: set_flags(flags)

      *flags* で指定されたフラグをセットして、他のフラグは下ろします。
      *flags* は並べられたゼロまたは1回の ``'R'`` 、
      ``'O'`` 、 ``'D'`` 、 ``'F'`` 、 ``'A'`` です。


   .. method:: add_flag(flag)

      *flags* で指定されたフラグをセットしますが他のフラグは変えません。
      一度に二つ以上のフラグをセットすることは、 *flag* に2文字以上の文字列を\
      指定すればできます。


   .. method:: remove_flag(flag)

      *flags* で指定されたフラグを下ろしますが他のフラグは変えません。
      一度に二つ以上のフラグを取り除くことは、 *flag* に2文字以上の文字列を\
      指定すればできます。

:class:`MMDFMessage` インスタンスが :class:`MaildirMessage` インスタンスに\
基づいて生成されるとき、 :class:`MaildirMessage` インスタンスの配送日時に基づいて
"From " 行が作り出され、次の変換が行われます:

+------------+--------------------------------+
| 結果の状態 | :class:`MaildirMessage` の状態 |
+============+================================+
| R フラグ   | S フラグ                       |
+------------+--------------------------------+
| O フラグ   | "cur" サブディレクトリ         |
+------------+--------------------------------+
| D フラグ   | T フラグ                       |
+------------+--------------------------------+
| F フラグ   | F フラグ                       |
+------------+--------------------------------+
| A フラグ   | R フラグ                       |
+------------+--------------------------------+

:class:`MMDFMessage` インスタンスが :class:`MHMessage` インスタンスに基づいて生成されるとき、以下の変換が行われます。

+--------------------------+-------------------------+
| 結果の状態               | :class:`MHMessage` 状態 |
+==========================+=========================+
| R フラグおよび O フラグ  | "unseen" シーケンス無し |
+--------------------------+-------------------------+
| O フラグ                 | "unseen" シーケンス     |
+--------------------------+-------------------------+
| F フラグ                 | "flagged" シーケンス    |
+--------------------------+-------------------------+
| A フラグ                 | "replied" シーケンス    |
+--------------------------+-------------------------+

:class:`MMDFMessage` インスタンスが :class:`BabylMessage` インスタンスに\
基づいて生成されるとき、以下の変換が行われます:

+--------------------------+------------------------------+
| 結果の状態               | :class:`BabylMessage` の状態 |
+==========================+==============================+
| R フラグおよび O フラグ  | "unseen" ラベル無し          |
+--------------------------+------------------------------+
| O フラグ                 | "unseen" ラベル              |
+--------------------------+------------------------------+
| D フラグ                 | "deleted" ラベル             |
+--------------------------+------------------------------+
| A フラグ                 | "answered" ラベル            |
+--------------------------+------------------------------+

:class:`MMDFMessage` インスタンスが :class:`mboxMessage` インスタンスに基づいて生成されるとき、"From "
行はコピーされ全てのフラグは直接対応します:

+------------+-----------------------------+
| 結果の状態 | :class:`mboxMessage` の状態 |
+============+=============================+
| R フラグ   | R フラグ                    |
+------------+-----------------------------+
| O フラグ   | O フラグ                    |
+------------+-----------------------------+
| D フラグ   | D フラグ                    |
+------------+-----------------------------+
| F フラグ   | F フラグ                    |
+------------+-----------------------------+
| A フラグ   | A フラグ                    |
+------------+-----------------------------+


例外
----

:mod:`mailbox` モジュールでは以下の例外クラスが定義されています:


.. exception:: Error()

   他の全てのモジュール固有の例外の基底クラス。


.. exception:: NoSuchMailboxError()

   メールボックスがあると思っていたが見つからなかった場合に送出されます。これはたとえば :class:`Mailbox`
   のサブクラスを存在しないパスでインスタンス化しようとしたとき(かつ *create* パラメータは ``False`` であった場合)、
   あるいは存在しないフォルダを開こうとした時などに発生します。


.. exception:: NotEmptyError()

   メールボックスが空であることを期待されているときに空でない場合、たとえばメッセージの残っているフォルダを削除しようとした時などに送出されます。


.. exception:: ExternalClashError()

   メールボックスに関係したある条件がプログラムの制御を外れてそれ以上作業を
   続けられなくなった場合、たとえば他のプログラムが既に保持しているロックを取得しようとして
   失敗したとき、あるいは一意的に生成されたファイル名が既に存在していた場合などに送出されます。


.. exception:: FormatError()

   ファイル中のデータが解析できない場合、たとえば :class:`MH` インスタンスが壊れた :file:`.mh_sequences`
   ファイルを読もうと試みた場合などに送出されます。


.. _mailbox-deprecated:

撤廃されたクラスとメソッド
--------------------------

.. deprecated:: 2.6

古いバージョンの :mod:`mailbox` モジュールはメッセージの追加や削除といった
メールボックスの変更をサポートしていませんでした。また形式ごとのメッセージプロパティ
を表現するクラスも提供していませんでした。後方互換性のために、古いメールボックスクラスもまだ使うことができますが、できるだけ新しいクラスを使うべきです。
古いクラスは Python 3.0 で削除されます。

古いメールボックスオブジェクトは繰り返しと一つの公開メソッドだけを提供していました:


.. method:: oldmailbox.next()

   メールボックスオブジェクトのコンストラクタに渡された、オプションの *factory* 引数を使って、メールボックス中の次のメッセージを
   生成して返します。標準の設定では、 *factory* は :class:`rfc822.Message` オブジェクトです (:mod:`rfc822`
   モジュールを参照してください)。メールボックスの実装により、このオブジェクトの *fp* 属性は真のファイルオブジェクトかもしれないし、
   複数のメールメッセージが単一のファイルに収められているなどの場合に、メッセージ間の境界を注意深く扱うためにファイルオブジェクトをシミュレート
   するクラスのインスタンスであるかもしれません。次のメッセージがない場合、このメソッドは ``None`` を返します。

ほとんどの古いメールボックスクラスは現在のメールボックスクラスと違う名前ですが、 :class:`Maildir` だけは例外です。そのため、新しい方の
:class:`Maildir` クラスには :meth:`next` メソッドが定義され、コンストラクタも他の新しいメールボックスクラスとは少し異なります。

古いメールボックスのクラスで名前が新しい対応物と同じでないものは以下の通りです:


.. class:: UnixMailbox(fp[, factory])

   全てのメッセージが単一のファイルに収められ、 ``From``  (``From_`` として知られています) 行によって分割されているような、旧来の
   Unix形式のメールボックスにアクセスします。ファイルオブジェクト *fp* はメールボックスファイルを指します。オプションの *factory*
   パラメタは新たなメッセージオブジェクトを生成するような呼び出し可能オブジェクトです。 *factory* は、メールボックスオブジェクトに対して
   :meth:`next` メソッドを実行した際に、単一の引数、 *fp* を伴って呼び出されます。この引数の標準の値は
   :class:`rfc822.Message` クラスです (:mod:`rfc822` モジュール -- および以下 -- を参照してください)。

   .. note::

      このモジュールの実装上の理由により、 *fp* オブジェクトはバイナリモードで開くようにしてください。特にWindows上では注意が必要です。

   可搬性を最大限にするために、Unix形式のメールボックス内にあるメッセージは、正確に ``'From '`` (末尾の空白に注意してください)
   で始まる文字列が、直前の正しく二つの改行の後にくるような行で分割されます。現実的には広範なバリエーションがあるため、それ以外の ``From_``
   行について考慮すべきではないのですが、現在の実装では先頭の二つの改行をチェックしていません。これはほとんどのアプリケーションでうまく動作します。

   :class:`UnixMailbox` クラスでは、ほぼ正確に ``From_``
   デリミタにマッチするような正規表現を用いることで、より厳密に ``From_``
   行のチェックを行うバージョンを実装しています。
   :class:`UnixMailbox` ではデリミタ行が ``From name time``
   の行に分割されるものと考えます。
   可搬性を最大限にするためには、代わりに :class:`PortableUnixMailbox`
   クラスを使ってください。
   このクラスは :class:`UnixMailbox` と同じですが、個々のメッセージは ``From``
   行だけで分割されるものとみなします。


.. class:: PortableUnixMailbox(fp[, factory])

   厳密性の低い :class:`UnixMailbox` のバージョンで、メッセージを分割する行は ``From``
   のみであると見なします。実際に見られるメールボックスのバリエーションに対応するため、 From 行における "*name* *time*"
   部分は無視されます。メール処理ソフトウェアはメッセージ中の ``'From '`` で始まる行をクオートするため、この分割はうまく動作します。


.. class:: MmdfMailbox(fp[, factory])

   全てのメッセージが単一のファイルに収められ、4 つの control-A 文字によって分割されているような、MMDF 形式のメールボックスにアクセスします。
   ファイルオブジェクト *fp* はメールボックスファイルをさします。オプションの *factory* は :class:`UnixMailbox`
   クラスにおけるのと同様です。


.. class:: MHMailbox(dirname[, factory])

   数字で名前のつけられた別々のファイルに個々のメッセージを収めたディレクトリである、MH メールボックスにアクセスします。メールボックスディレクトリの名前は
   *dirname* で渡します。 *factory* は :class:`UnixMailbox` クラスにおけるのと同様です。


.. class:: BabylMailbox(fp[, factory])

   MMDF メールボックスと似ている、Babyl メールボックスにアクセスします。
   Babyl 形式では、各メッセージは二つのヘッダからなるセット、
   *original* ヘッダおよび *visible* ヘッダを持っています。
   original ヘッダは ``'*** EOOH ***'`` (End-Of-Original-Headers)
   だけを含む行の前にあり、visible ヘッダは ``EOOH`` 行の後にあります。Babyl
   互換のメールリーダは visible ヘッダのみを表示し、
   :class:`BabylMailbox` オブジェクトは visible
   ヘッダのみを含むようなメッセージを返します。
   メールメッセージは EOOH 行で始まり、 ``'\037\014'`` だけを含む行で終わります。
   *factory* は :class:`UnixMailbox` クラスにおけるのと同様です。

古いメールボックスクラスを撤廃された :mod:`rfc822` モジュールではなく、 :mod:`email`
モジュールと使いたいならば、以下のようにできます::

   import email
   import email.Errors
   import mailbox

   def msgfactory(fp):
       try:
           return email.message_from_file(fp)
       except email.Errors.MessageParseError:
           # Don't return None since that will
           # stop the mailbox iterator
           return ''

   mbox = mailbox.UnixMailbox(fp, msgfactory)

一方、メールボックス内には正しい形式の MIME メッセージしか入っていないと分かっているのなら、単に以下のようにします::

   import email
   import mailbox

   mbox = mailbox.UnixMailbox(fp, email.message_from_file)


.. _mailbox-examples:

例
--

メールボックス中の面白そうなメッセージのサブジェクトを全て印字する簡単な例::

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

