どせいたんさき。

ナスダヨー

python を 1 ミリも知らない自分が gm-notify の日本語対応を目指してがんばってみたログ(うまくいきました)

せっかくなので gm-notify v09 の日本語化を目指してみる

とりあえずライブログなので読みにくさ満点だと思います.ご了承くださいませ.

現況確認

前回インストールした gm-notify は日本語の題名が表示されないという現象が発生していたのでその点について確認してみる.自分から自分に「てすとてすと」という題名でメールを送信したところ, gm-notify のポップアップでは次のように表示された.

?UTF-8?B?44Gm44GZ44... という文字列が何のこっちゃ分からないけどもとりあえず現時点でのよそう.

  • ?UTF-8? とあたまについているので Gmail から返ってくる題名は UTF-8 なのだろう
  • 最後に書いてある ... は Onaneet さんのこめんとによれば長い題名を削除した名残り
  • 実は後ろの方にも ?UTF-8? みたいなタグがあってそれが切られてしまったとか?

どうやら Onaneet さんが怪しいと思っていた部分がビンゴなんじゃないかという気がしてくる.

v08 ではどうなのか

ウワサでは v08 では日本語表示に対応しているということだったのでダウンロード.表示をチェックする.

いける.これなら v08 をそのままつかっていればいいんじゃないか,という気もしてくるがとりあえず原因を探ってみる.

プログラム読む

プログラム 2 行目を確認.# -*- coding: utf-8 -*- とあるので utf-8 仕様にはきちんとなっている.あれ?でも 1 行目が何か違う.

#!/usr/bin/env python  # v08

#!/usr/bin/python      # v09

調べてみる.

Google 先生に聞いてみた詳細はこちら.特に関係なさそう.

今,プログラムはじめにある import の部分を見ているのだけど v08 と v09 でだいぶ違いがある.このあたりにエラーの原因があったらお手上げだなあ...そうでないことを祈ろう.

++ os, gtk2reactor(twisted.internet), reactor(twisted.internet), GMail(gmimap)
-- gtk, gmailatom

おそらく情報を取得するための関数が変わっているんじゃなかろうか.

初めから読んでいっても一発で理解できるわけじゃなさそうなので, Onaneet さんがヒントをくれた題名をカットするところを読んでみる. v08 はこちら.

# agregate the titles of the messages... cut the string if longer than 20 chars
titles = ""
newmail = self.filterNewMail()
for i in newmail:
  title = self.atom.getMsgTitle(i)

つづいて v09 はこちら.

# agregate the titles of the messages... cut the string if longer than 20 chars
titles = ""
for title in newmail:
  self.addIndicator(title)

どうやら題名を読み込むためのプロセスが異なっている様子.というかそもそも 20 文字でカットしない状態でどのように表示されるのか試していなかった.この時点でダメだった場合は...エンコードとかデコードとかが必要になってくると思うのだけど...というわけで 20 文字カットの部分をコメントにして再度チャレンジ.

( ゜д゜)ポカーン

わからなくなったら Google 先生.どうやら =?UTF-8?B? で始まるのは MIME-header というらしい.というわけで python でこれをデコードできる関数を探したいんだけど...探せど探せど perl ばっかり...

Google 先生との格闘の末

どうやら mail パッケージ(?)にある decode_header を使えば出来そう.

ちぃ覚えた

  • python には list と tuple というデータ構造があるらしい.ちぃ覚えた.
  • list も tuple も zero-origin のようだ.ちぃ覚えた.
  • シーケンス(スライス)は octave のそれに似ているかも(むしろ gnuplot ?).ちぃ覚えた.

とりあえず書いてみる.

from email.header import decode_header

for title in newmail:
  self.addIndicator(title)
  if title.find("=?UTF-8?B?")==0:
    title = decode_header(title).pop()[0]
    title = title.decode('utf-8')

動くかどうかチェック.何かエラーが出たので unicode にデコードしてある.

おおおおおおおおおおおおおお!うごいた!!!

まだエラーとか例外のチェックはしていないけど何とかなりそう.

最後は launchpad の掲示板に書き込む

書き込もうかとも思ったけどどうやら既に bug report がなされている模様.作者さまは trunk では既に修正した(次のバージョンでは修正される)ということを書き込んでいる模様.でもせっかくなので書き込んでみる.ヘブライ語のユーザーの方が困っているみたいだし.

書き込んだスレッドはこちら

しかし python コードに重要なインデントが崩壊してしまった...しかたないよね...

おしまい

というわけでおしまい.所要時間は v08 をダウンロードしてきてから 3 時間くらい. MIME-header のデコード方法を調べるのにかなり時間がかかった.あとは文字コードエラーとの地味な格闘...とりあえずバグがないといいなー(「・ω・)「

修正

Onaneet さんの指摘どおり,utf-8 ではない題名は変換できないことが判明しました.テストメールをすべて Gmail から送信していたためですね...敗因:テスト環境の不備.

decode_header() 関数はエンコードの形式も返してくれるのでそれを使って次のように訂正しました.

from email.header import decode_header

for title in newmail:
  self.addIndicator(title)
  if title.find("=?")==0 & title.find("?=") != -1:
    title_str = decode_header(title).pop()[0]  # title
    title_key = decode_header(title).pop()[1]  # encode
    title = title_str.decode(title_key)

これで大丈夫...かな? if 文の中身が気持ち悪いけど python正規表現をつかうためには re パッケージをインポートしなければならないみたいなのでとりあえず使わないで応急処置です.