
:mod:`rfc822` --- RFC 2822 準拠のメールヘッダ読み出し
=====================================================

.. module:: rfc822
   :synopsis: RFC 2822 形式のメールメッセージを解釈します。
   :deprecated:


.. deprecated:: 2.3
   :mod:`rfc822` モジュールを使うよりも  :mod:`email` パッケージを使うべきです。
   このモジュールは以前のバージョンとの互換性のために保守されているにすぎません。
   Python 3.0 ではこのモジュールは削除されました。

このモジュールでは、インターネット標準 :rfc:`2822` [#]_ で定義されている
"電子メールメッセージ" を表現するクラス、 :class:`Message` を定義しています。
このメッセージはメッセージヘッダ群とメッセージボディの集まりからなります。
このモジュールではまた、ヘルパークラス  :rfc:`2822` アドレス群を解釈するための
:class:`AddressList` クラスを定義しています。
:rfc:`2822` メッセージ固有の構文に関する情報は RFC を参照してください。

.. index:: module: mailbox

:mod:`mailbox` モジュールでは、多くのエンドユーザメールプログラムによって生成されるメールボックスを読み出すためのクラスを提供しています。


.. class:: Message(file[, seekable])

   :class:`Message` インスタンスは入力オブジェクトをパラメタに与えてインスタンス化します。入力オブジェクトのメソッドのうち、Message が
   依存するのは :meth:`readline` だけです; 通常のファイルオブジェクトは適格です。インスタンス化を行うと、入力オブジェクトからデリミタ行
   (通常は空行 1 行) に到達するまでヘッダを読み出し、それらをインスタンス中に保持します。ヘッダの後のメッセージ本体は読み出しません。

   このクラスは :meth:`readline` メソッドをサポートする任意の入力オブジェクトを扱うことができます。入力オブジェクトが seek および
   tell できる場合、 :meth:`rewindbody` メソッドが動作します。また、不正な行データを入力ストリームにプッシュバックできます。
   入力オブジェクトが seek できない一方で、入力行をプッシュバックする :meth:`unread`
   メソッドを持っている場合、 :class:`Message` は不正な行データにこのプッシュバックを使います。こうして、
   このクラスはバッファされているストリームから来るメッセージを解釈するのに使うことができます。

   オプションの *seekable* 引数は、 :cfunc:`lseek` システムコールが動作しないと分かるまでは :cfunc:`tell`
   がバッファされたデータを無視するような、ある種の stdio ライブラリで回避手段として提供されています。可搬性を最大にするために、socket
   オブジェクトによって生成されたファイルのような、seek できないオブジェクトを渡す際には、最初に :meth:`tell` が呼び出されないようにするために
   seekable 引数をゼロに設定すべきです。

   ファイルとして読み出された入力行データは CR-LF と単一の改行 (line feed) のどちらで終端されていてもかまいません;
   行データを記憶する前に、終端の CR-LF は単一の改行と置き換えられます。

   ヘッダに対するマッチは全て大小文字に依存しません。例えば、 ``m['From']`` 、 ``m['from']`` 、および ``m['FROM']``
   は全て同じ結果になります。


.. class:: AddressList(field)

   :rfc:`2833` アドレスをカンマで区切ったものとして解釈される単一の文字列パラメタを使って、 :class:`AddressList` ヘルパークラスを
   インスタンス化することができます。 (パラメタ ``None`` は空のリストを表します。)


.. function:: quote(str)

   *str* 中のバックスラッシュが 2 つのバックスラッシュに置き換えられ、二重引用符がバックスラッシュ付きの二重引用符に置き換えられた、
   新たな文字列を返します。


.. function:: unquote(str)

   *str* の *逆クオートされた* 新たな文字列を返します。 *str* が二重引用符で囲われていた場合、二重引用符を剥ぎ取ります。同様に、 *str*
   が三角括弧で囲われていた場合にも剥ぎ取ります。


.. function:: parseaddr(address)

   :mailheader:`To` や :mailheader:`Cc` といった、アドレスが入っているフィールドの値 *address*
   を解析し、含まれている "実名 (realname)" 部分および "電子メールアドレス" 部分に分けます。それらの情報からなる
   タプルを返します。解析が失敗した場合には 2 要素のタプル  ``(None, None)`` を返します。


.. function:: dump_address_pair(pair)

   :meth:`parseaddr` の逆で、 ``(realname, email_address)``  形式の 2
   要素のタプルをとり、 :mailheader:`To` や :mailheader:`Cc` ヘッダに適した文字列値を返します。 *pair*
   の最初の要素が真値をとらない場合、二つ目の要素をそのまま返します。


.. function:: parsedate(date)

   :rfc:`2822` の規則に従っている日付を解析しようと試みます。しかしながら、メイラによっては :rfc:`2822` で指定されている
   ような書式に従わないため、そのような場合には :func:`parsedata`  は正しい日付を推測しようと試みます。 *date* は ``'Mon, 20
   Nov 1995 19:12:08 -0500'`` のような :rfc:`2822` 様式の日付を収めた文字列です。日付の解析に成功した場合、
   :func:`parsedate` は :func:`time.mktime` にそのまま渡すことができるような 9 要素のタプルを返します;
   そうでない場合には ``None`` を返します。
   結果のインデックス 6、7、および 8 は有用な情報ではありません。


.. function:: parsedate_tz(date)

   :func:`parsedate` と同じ機能を実現しますが、 ``None`` または 10 要素のタプルを返します; 最初の 9 要素は
   :func:`time.mktime` に直接渡すことができるようなタプルで、 10 番目の要素はその日のタイムゾーンにおける UTC
   (グリニッチ標準時の公式名称) からのオフセットです。(タイムゾーンオフセットの符号は、同じタイムゾーンにおける ``time.timezone``
   変数の符号と反転しています; 後者の変数が POSIX 標準に従っている一方、このモジュールは :rfc:`2822` に従っているからです。) 入力文字列
   がタイムゾーン情報を持たない場合、タプルの最後の要素は ``None`` になります。
   結果のインデックス 6、7、および 8 は有用な情報ではありません。


.. function:: mktime_tz(tuple)

   :func:`parsedata_tz` が返す 10 要素のタプルを UTC タイムスタンプに変換します。タプル内のタイムゾーン要素が ``None``
   の場合、地域の時刻を表しているものと家庭します。些細な欠陥: この関数はまず最初の 8 要素を地域における時刻として変換し、次にタイムゾーンの違いに対する
   補償を行います; これにより、夏時間の切り替え日前後でちょっとしたエラーが生じるかもしれません。通常の利用に関しては心配ありません。


.. seealso::

   Module :mod:`email`
      網羅的な電子メール処理パッケージです; :mod:`rfc822` モジュールを代替します。

   Module :mod:`mailbox`
      エンドユーザのメールプログラムによって生成される、様々な mailbox 形式を読み出すためのクラス群。

   Module :mod:`mimetools`
      MIME エンコードされたメッセージを処理する :class:`rfc822.Message` のサブクラス。


.. _message-objects:

Message オブジェクト
--------------------

:class:`Message` インスタンスは以下のメソッドを持っています:


.. method:: Message.rewindbody()

   メッセージ本体の先頭を seek します。このメソッドはファイルオブジェクトが seek 可能である場合にのみ動作します。


.. method:: Message.isheader(line)

   ある行が正しい :rfc:`2822` ヘッダである場合、その行の正規化されたフィールド名 (インデクス指定の際に使われる辞書キー) を返します;
   そうでない場合 ``None`` を返します (解析をここで一度中断し、行データを入力ストリームに押し戻すことを意味します)。
   このメソッドをサブクラスで上書きすると便利なことがあります。


.. method:: Message.islast(line)

   与えられた line が Message の区切りとなるデリミタであった場合に真を返します。このデリミタ行は消費され、ファイルオブジェクトの読み位置は
   その直後になります。標準ではこのメソッドは単にその行が空行かどうかをチェックしますが、サブクラスで上書きすることもできます。


.. method:: Message.iscomment(line)

   与えられた行全体を無視し、単に読み飛ばすときに真を返します。標準では、これは控えメソッド (stub) であり、常に ``False`` を返し
   ますが、サブクラスで上書きすることもできます。


.. method:: Message.getallmatchingheaders(name)

   *name* に一致するヘッダからなる行のリストがあれば、それらを全て返します。各物理行は連続した行内容であるか否かに関わらず
   別々のリスト要素になります。 *name* に一致するヘッダがない場合、空のリストを返します。


.. method:: Message.getfirstmatchingheader(name)

   *name* に一致する最初のヘッダと、その行に連続する (複数) 行からなる行データのリストを返します。 *name* に一致するヘッダがない場合
   ``None`` を返します。


.. method:: Message.getrawheader(name)

   *name* に一致する最初のヘッダにおけるコロン以降のテキストが入った単一の文字列を返します。このテキストには、先頭の空白、末尾の改行、
   また後続の行がある場合には途中の改行と空白が含まれます。 *name* に一致するヘッダが存在しない場合には ``None``  を返します。


.. method:: Message.getheader(name[, default])

   *name* に一致する最後のヘッダから先頭および末尾の空白を剥ぎ取った単一の文字列を返します。
   途中にある空白は剥ぎ取られません。オプションの
   *default* 引数は、 *name* に一致するヘッダが存在しない場合に、別のデフォルト値を返すように指定するために使われます。
   デフォルトは ``None`` です。
   パースされたヘッダを得る方法としてはこれが好ましいでしょう。


.. method:: Message.get(name[, default])

   正規の辞書との互換性をより高めるための :meth:`getheader` の別名 (alias) です。


.. method:: Message.getaddr(name)

   ``getheader(name)`` が返した文字列を解析して、 ``(full name, email address)`` からなるペアを返します。
   *name* に一致するヘッダが無い場合、 ``(None, None)`` が返されます; そうでない場合、 *full name* および *address*
   は (空文字列をとりうる) 文字列になります。

   例: *m* に最初の :mailheader:`From` ヘッダに文字列 ``'jack@cwi.nl (Jack Jansen)'`` が入っている場合、
   ``m.getaddr('From')`` はペア ``('Jack Jansen', 'jack@cwi.nl')`` になります。また、
   ``'Jack Jansen <jack@cwi.nl>'`` であっても、全く同じ結果になります。


.. method:: Message.getaddrlist(name)

   ``getaddr(list)`` に似ていますが、複数のメールアドレスからなるリストが入ったヘッダ (例えば :mailheader:`To` ヘッダ) を
   解析し、 ``(full name, email address)`` のペアからなるリストを (たとえヘッダには一つしかアドレスが入っていなかった
   としても) 返します。 *name* に一致するヘッダが無かった場合、空のリストを返します。

   指定された名前に一致する複数のヘッダが存在する場合 (例えば、複数の :mailheader:`Cc` ヘッダが存在する場合)、全てのアドレスを
   解析します。指定されたヘッダが連続する行に収められている場合も解析されます。


.. method:: Message.getdate(name)

   :meth:`getheader` を使ってヘッダを取得して解析し、 :func:`time.mktime` と互換な 9 要素のタプルにします;  フィールド
   6、7、および 8 は有用な値ではないので注意して下さい。 *name* に一致するヘッダが存在しなかったり、ヘッダが解析不能であった場合、 ``None``
   を返します。

   日付の解析は妖術のようなものであり、全てのヘッダが標準に従っているとは限りません。このメソッドは多くの発信源から集められた
   膨大な数の電子メールでテストされており、正しく動作することが分かっていますが、間違った結果を出力してしまう可能性はまだあります。


.. method:: Message.getdate_tz(name)

   :meth:`getheader` を使ってヘッダを取得して解析し、10 要素のタプルにします; 最初の 9 要素は :func:`time.mktime`
   と互換性のあるタプルを形成し、10 番目の要素はその日におけるタイムゾーンの UTC からのオフセットを与える数字になります。 :meth:`getdate`
   と同様に、 *name* に一致するヘッダがなかったり、解析不能であった場合、 ``None`` を返します。

:class:`Message` インスタンスはまた、限定的なマップ型のインタフェースを持っています。すなわち: ``m[name]`` は
``m.getheader(name)`` に似ていますが、一致するヘッダがない場合 :exc:`KeyError` を送出します; ``len(m)`` 、
``m.get(name[, default])`` 、 ``name in m``, ``m.keys()`` 、 ``m.values()``
``m.items()`` 、および ``m.setdefault(name[, default])`` は期待通りに動作します。
ただし :meth:`setdefault` は標準の設定値として空文字列をとります。 :class:`Message` インスタンスはまた、
マップ型への書き込みを行えるインタフェース ``m[name] = value`` および ``del m[name]`` をサポートしています。
:class:`Message` オブジェクトでは、 :meth:`clear` 、 :meth:`copy` 、 :meth:`popitem` 、あるいは
:meth:`update` といったマップ型インタフェースのメソッドはサポートしていません。 (:meth:`get` および
:meth:`setdefault` のサポートは Python 2.2 でしか追加されていません。)

最後に、 :class:`Message` インスタンスはいくつかの public なインスタンス変数を持っています:


.. attribute:: Message.headers

   ヘッダ行のセット全体が、(setitem を呼び出して変更されない限り)  読み出された順番に入れられたリストです。各行は末尾の改行を
   含んでいます。ヘッダを終端する空行はリストに含まれません。


.. attribute:: Message.fp

   インスタンス化の際に渡されたファイルまたはファイル類似オブジェクトです。この値はメッセージ本体を読み出すために使うことができます。


.. attribute:: Message.unixfrom

   メッセージに Unix ``From`` 行がある場合はその行、そうでなければ空文字列になります。この値は例えば ``mbox`` 形式のメールボックス
   ファイルのような、あるコンテキスト中のメッセージを再生成するために必要です。


.. _addresslist-objects:

AddressList オブジェクト
------------------------

:class:`AddressList` インスタンスは以下のメソッドを持ちます:


.. method:: AddressList.__len__()

   アドレスリスト中のアドレスの数を返します。


.. method:: AddressList.__str__()

   アドレスリストの正規化 (canonicalize) された文字列表現を返します。アドレスはカンマで分割された "name" <host@domain>
   形式になります。


.. method:: AddressList.__add__(alist)

   二つの :class:`AddressList` 被演算子中の双方に含まれるアドレスについて、重複を除いた (集合和の) 全てのアドレスを含む新たな
   :class:`AddressList` インスタンスを返します。


.. method:: AddressList.__iadd__(alist)

   :meth:`__add__` のインプレース演算版です; :class:`AddressList`  インスタンスと右側値 *alist*
   との集合和をとり、その結果をインスタンス自体と置き換えます。


.. method:: AddressList.__sub__(alist)

   左側値の :class:`AddressList` インスタンスのアドレスのうち、右側値中に含まれていないもの全てを含む (集合差分の) 新たな
   :class:`AddressList` インスタンスを返します。


.. method:: AddressList.__isub__(alist)

   :meth:`__sub__` のインプレース演算版で、 *alist* にも含まれているアドレスを削除します。

最後に、 :class:`AddressList` インスタンスは public なインスタンス変数を一つ持ちます:


.. attribute:: AddressList.addresslist

   アドレスあたり一つの文字列ペアで構成されるタプルからなるリストです。各メンバ中では、最初の要素は正規化された名前部分で、二つ目は実際の配送アドレス
   (``'@'`` で分割されたユーザ名と  ホスト.ドメインからなるペア) です。

.. rubric:: Footnotes

.. [#] このモジュールはもともと :rfc:`822` に適合していたので、そういう名前になっています。その後、 :rfc:`2822` が :rfc:`822`
   に対する更新としてリリースされました。このモジュールは :rfc:`2822` 適合であり、特に :rfc:`822`
   からの構文や意味付けに対する変更がなされています。

