メールのバッチ処理の一部として、メッセージをデコードしてクリーンアップする必要があります。そのプロセスの重要な部分の 1 つは、メッセージのメール本文とメールの添付ファイルを分離することです。最も難しい部分は、そのConent-Disposition: inline
部分がメッセージ本文の代替またはファイルと見なされる時期を判断することです。
これまでのところ、このコードはほとんどのケースを処理しているようです:
from email import message_from_string
def split_parts(raw):
msg = message_from_string(raw)
bodies = []
files = []
for sub in msg.walk():
if sub.is_multipart():
continue
cd = sub.get("Content-Disposition", "")
if cd.startswith("attachment") or (cd.startswith("inline") and
sub.get_filename()):
files.append(sub)
else:
bodies.append(sub)
return bodies, files
ヘッダーで指定されたファイル名を持つインライン パーツへの依存に注意してください。これは、Outlook がすべてのmultipart/related
メッセージに対して行っているようです。をヒントとして使用するContent-ID
こともできますが、RFC 2387によれば、そのようなインジケータではありません。
したがって、埋め込み画像が を持ちContent-Disposition: inline
、 を定義しContent-ID
、ファイル名を持たないメッセージ部分としてエンコードされている場合、上記のコードは誤ってそれをメッセージ本文の代替として分類する可能性があります。
私がRFCから読んだことから、簡単なチェックを見つけることはあまり期待できません(特に、RFCによるコーディングは現実の世界ではほとんど役に立たないため、誰もそれを行いません)。しかし、誤分類のケースに当たる可能性がどれほど大きいか疑問に思っていました.
根拠
multipart/*
それぞれのケースを処理し、それらを間接的に再帰させる一連の関数を持つことができます。ただし、忠実な表示についてはそれほど気にしません。実際のところ、すべての HTML メッセージをtidyでフィルタリングしています。代わりに、メッセージ本文の選択肢の 1 つを選択し、埋め込みを目的としている場合でも、できるだけ多くの添付ファイルを保存することに関心があります。
さらに、一部のユーザー エージェントは、multipart/alternative
インラインで表示することを意図していない添付ファイル (PDF ファイルなど) を含むメッセージを作成するときに、ユーザーが任意のファイルを作成ウィンドウにドラッグ アンド ドロップした結果、非常に奇妙な動作をします。