Python2.7.xでIMAPのディレクトリ(修正UTF-7)をデコードしてみた

 最近、Pythonにはまっている。
 PHPとかに比べてフォーマットがインデントベースになっていて見通しが良い。 Rubyも同じだけど、Linux系だとほぼ標準で入っているからお名前.com VPSとかでもデフォルト状態ですぐ走らせられるし、Windows EXE化も簡単だったりしてポータビリティも良い。

 で、今回、Office365のメールのフルバックアップを取るスクリプトを書いてみた。
POP3でアクセスする場合、Office365では受信トレイしか取れない仕様らしい。
普段OutlookアプリやスマホのExchangeアクセスでフォルダ分けしたりしているから、POP3だとフルバックアップにはならないので、対応策としてIMAP4でアクセスする事になった。

 IMAP4のSSL使用アクセスは何の問題も無く簡単に実装できたが、ディレクトリ名がデコードできない。 軽く検索するとIMAPCLIENTと言うパッケージを使うとか言う解決策が示されている程度だった。
 で、Pythonの気に入っているポイントはポータビリティの良さなので、実行環境にパッケージを入れずに済ませたいので、仕様を調べて軽く実装してみた。

 IMAP4のディレクトリ名は、修正UTF-7形式。
 UTF-7のコーデックはPython2.7系に標準で入ってるけど、修正UTF-7は無い。
 修正UTF-7ではUTF-7とエンコード対象文字が一部異なる(ディレクトリに使われやすい記号がASCIIのまま。 B64エンコードの開始終了記号が&ではじまり-で終了する等)
 B64エンコードの中身は/が,になっている以外は同じみたいなので、元文字列からエンコードされている部分を切り出して、,を/に置換してUTF-7コーデックでデコードして、B64されていない部分と結合していくと言う実装をしてみた。

Decoding the modified UTF-7(i18n IMAP4 directory) to Unicode on the Python2.

 入力文字列を1文字ずつチェックしていくんでfor文かなと思うんだけど、Pythonでfor文中でカウンタを進める方法がわからなかったのでwhile文にした。 処理済みの文字列を随時消していくという処理で、入力文字列長が1未満になるまで回す。
 修正UTF-7のルールで、Printableな文字はそのまま通す、非Printableな文字は&で始めるから、先頭文字が&かチェック、ただしソースに&自体がある場合は&-になっているので次の文字が-かチェックしている。
&-じゃなければとりあえず1文字進める(&自体を消す)
-が来るまでB64部分保存用バッファに保存していくループ。 -が来たら1文字進めてループ終了。
修正B64ルールの,と/置換を逆置換してB64ルールにして、バッファ全体をB64として示すために+と-で挟む。
これでUTF-7のB64部分だけになっているはずなので、UTF-7コーデックでデコードしてリターン変数に突っ込む。
 あとは、ディレクトリ名を引数にこいつをコールしてやれば、Unicodeなディレクトリ名が戻る。

 とりあえず、自分が使ってるExchangeでは問題なくデコードできたけど、斜め読みした仕様をベースに作ってるんでほんとに正しいかは保証しないよ。

(1158)


カテゴリー: LAMP[Linux, Apache, MySQL, PHP]   パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です