[Python-ml-jp 5041] Re: メールの日本語件名を記述通り復元するには?
Tokio Kikuchi
tkikuchi @ is.kochi-u.ac.jp
2010年 9月 26日 (日) 11:59:57 JST
菊地です。
(10/09/26 10:13), 十河 満 wrote:
> ソガワと申します。また教えて下さい。
>
> 日本ではメール送信時に、ISO-2022-JP+base64で文字エンコードして7-bit文字
> にするのが一般的ですが、逆にこれを戻す際に *white space* の問題で、記述
> 通り復元できるか疑問になって質問します。
>
> (1) 半角空白の扱い方はどうすれば良いのでしょうか?
> 私のメーラー(Thunderbird 3.1.4)では、"Python メーリングリスト Japan" は
> *SJ0* のように変換されるので、これを email.Header.decode_header(SJ0) す
> ると、結果は得られますが半角空白が失われます。
次のようにすると、(まともなメーラが作った MIME なら)幸せになれます。
>>> import email.header
>>> SJ0 = "Python
=?ISO-2022-JP?B?GyRCJWEhPCVqJXMlMCVqJTklSBsoQiBKYXBhbg==?="
>>> h = email.header.decode_header(SJ0)
>>> u = unicode(email.header.make_header(h))
>>> print u
Python メーリングリスト Japan
> 逆にThunderbird 3.1.4 では、*SJ0* 〜 *SJ4* をそのまま件名に記述すると
> 半角空白文字も有効となって正しく受信できます。
>
> (2) decode_header の終タグの判定は *white space* を含めてる?
> 次に、*SJ3*, *SJ4*のように、終タグ(?=)の直後に半角文字があると、
> email.Header.decode_header(SJx) はデコードしないようです。
> 無理やり終タグの後ろにタブ文字("\t")を埋め込んでますが・・・
Python の email.header では空白文字が必要です。RFC 2047 の解釈で
encoded_word とあるのを、そのまま英文における space separated
word であると解釈しています。SJ3,SJ4 がdecode できないのは、その
ためです。SJ2 が decode できるのは、手抜かりですね。(^^;)
>
> (3) 規定の解釈はどうなってるのでしょうか?
> RFC2822ではどのように規定してるのでしょうか? グレーでしょうか?
ま、グレーですね。なんつーか、上の解釈には私も関与してるのですが、
一応 thunderbird も MIME header 作るときには上の解釈に従ってやって
くれてるようです。decode のときに緩く対応するかどうかの違いです。
decode_header は、次の make_header で元のヘッダを再現すべきでは
ないか(とは、明確に言った覚えはないけど)というのが緩い解釈を
しない理由だと思います。多分、一発で unicode に緩く解釈するような
関数を別に用意してあげないといけないのだと思いますけど。
(このあたり、RFC822(5322) ヘッダには structured と unstructured
があるが、MIME decode は unstructured の部分に対してと、comment
部分に適用されるわけで、comment であれば先に comment 部分だけを
取り出して、その後に decode すればいいはず、という解釈です)
>
> (ソースコードのインデントには全角スペースを使用してます。)
> #!/usr/bin/python
> # -*- coding: utf-8 -*-
> import email
> SJ0 = "Python =?ISO-2022-JP?B?GyRCJWEhPCVqJXMlMCVqJTklSBsoQiBKYXBhbg==?="
> SJ1 = "Python =?ISO-2022-JP?B?GyRCJWEhPCVqJXMlMCVqJTklSBsoQg==?= Japan"
> SJ2 = "Python=?ISO-2022-JP?B?GyRCJWEhPCVqJXMlMCVqJTklSBsoQg==?= Japan"
> SJ3 = "Python =?ISO-2022-JP?B?GyRCJWEhPCVqJXMlMCVqJTklSBsoQg==?=Japan"
> SJ4 = "Python=?ISO-2022-JP?B?GyRCJWEhPCVqJXMlMCVqJTklSBsoQg==?=Japan"
> def test(subj):
> print "="+"0123456789"*4
> for txt, enc in email.Header.decode_header(subj):
> if enc:
> txt_sjis = unicode(txt, enc).encode("shift-jis")
> else:
> txt_sjis = txt
> print (">"+txt_sjis+"<").ljust(32), enc
> if __name__ == "__main__":
> print "* SJ1 *"; test(SJ1)
> print "* SJ2 *"; test(SJ2)
> print "* SJ3 *"; test(SJ3)
> print "* SJ4 *"; test(SJ4)
>
> c:\Users\SomethingCool\Dlib\Python\wince_v10\slmc2>python Test.py
> * SJ0 *
> =0123456789012345678901234567890123456789
>> Python< None
>> メーリングリスト Japan< iso-2022-jp
> * SJ1 *
> =0123456789012345678901234567890123456789
>> Python< None
>> メーリングリスト< iso-2022-jp
>> Japan< None
> * SJ2 *
> =0123456789012345678901234567890123456789
>> Python< None
>> メーリングリスト< iso-2022-jp
>> Japan< None
> * SJ3 *
> =0123456789012345678901234567890123456789
>> Python =?ISO-2022-JP?B?GyRCJWEhPCVqJXMlMCVqJTklSBsoQg==?=Japan< None
> * SJ4 *
> =0123456789012345678901234567890123456789
>> Python=?ISO-2022-JP?B?GyRCJWEhPCVqJXMlMCVqJTklSBsoQg==?=Japan< None
>
> c:\Users\SomethingCool\Dlib\Python\wince_v10\slmc2>
>
> 以上、宜しくお願い致します。
>
--
菊地時夫 tkikuchi @ is.kochi-u.ac.jp
http://weather.is.kochi-u.ac.jp/
〒780-8520 高知大学理学部情報科学教室
Python-ml-jp メーリングリストの案内