メール通知日本語化計画

会社で導入できないっていうのに、懲りずにtracネタを。

けど、何で最近tracだったりABAPUnit(xUnit)にこんなに構成管理ツールに惹かれるのでしょう…?


今日やろうとしたことは、メール通知のカスタマイズ。

tracには、チケットが更新されたときに関係者にメールを送るという機能があります。で、これですがデフォルトだと項目名が英語の状態で表示されます。こんな風に。

--------------------+-------------------------------------------------------
 Reporter:  guest  |            Owner:  guest
     Type:  タスク    |           Status:  new
 Priority:  普通     |        Milestone:
 Component:  その他    |          Version:
 Keywords:         |   Estimatedhours:  0
Due_assign:         |            Hours:  0
 Due_close:         |       Totalhours:  0
 Billable:  1      |         Complete:
--------------------+-------------------------------------------------------
Condition:


--------------------+-------------------------------------------------------
テストコメント

↑でも意味は分かるのですが、もしこの先プロジェクトにtrac導入を検討しようとなったときに、英語表記だとそれだけで敬遠される可能性があります。こういうところでマイナスされたくないので、少しでもとっつきやすいように日本語表記にできないかと、ここ2週間ぐらい仕事から帰ってPython&tracと格闘してました。


とは言っても、Pythonなんて初めてなので、初歩的な文法すら分からない状態。さすがに素のテキストエディタでは厳しいので、@nifty:@homepage:エラーとか入れてみました。

とりあえず、403 Forbiddenを見てどのクラスのどのメソッドらへんでやっているかは理解しました。あとは、愚直にトライアンドエラー。適当にソースファイルを修正した後にチケットを更新してメールを飛ばす。そのメールの中身を見て望み通りになっていないなら、もう一度最初から。せめてデバッグ手法でも知っておけば、少しは効率よくできたかもしれませんが…。

で、いろいろごちゃごちゃしたあげく、format_props()の↓の部分が怪しいかもとあたりをつける。

...

for f in [f for f in fields if f['name'] != 'description']: 
  fname = f['name'] 

...

if f['type'] == 'textarea' or '\n' in unicode(fval):
  big.append((fname.capitalize(), CRLF.join(fval.splitlines()))) 
else:

...

「fname」って変数が英語表記の項目名っぽいな。ここを日本語表記にすればいいんだ。そういや、どっかで「label」って変数を見たな。試してみよう!

...

for f in [f for f in fields if f['name'] != 'description']: 
  fname = f['name'] 
  flabel = f['label'] # この行追加

...

if f['type'] == 'textarea' or '\n' in unicode(fval):
  big.append((flabel.capitalize(), CRLF.join(fval.splitlines())))  # この行修正
else:

...

結果は、以下のように。日本語化ができました!!

------------------------+---------------------------------------------------
    報告者:  guest  |    担当者:  guest
       分類:  タスク    |   ステータス:  assigned
    優先度:  普通     |   マイルストーン:
コンポーネント:  その他    |   バージョン:
 解決方法:         |   キーワード:
         見積時間:  0      |        着手予定日:
      今日の作業時間:  0      |        終了予定日:
        総作業時間:  0      |        集計対象?:  1
       進捗率(%):         |
------------------------+---------------------------------------------------
進捗状況:


------------------------+---------------------------------------------------
コメント (by guest):

 項目名を日本語化


ただ、これだとあまりよろしくないのですよね。というのは、文面がきれいにフォーマットされていない。

どうやらマルチバイト文字をフォーマット書式で出すときに、文字数のカウントがうまくいっていないためにバラバラに出力されるみたい。メール通知の文字コードUTF-8だからまずいのかなと思って、OZACC.blog: trac 0.10.4とかWhiteDog@Blog: 2007/06も試したのですが、結局無理でした…orz

なので、二段組は諦めて一行一項目作戦に。完璧に逃げですw。上と同じく、format_propsの一部分を↓のように変更してみました。

...

#  txt += format[i % 2] % (fname.capitalize(), fval)       # この行削除
   txt += '%s : %s%s' % (flabel.capitalize(), fval, CRLF)  # この行追加

...

結果は、こんな感じ。

------------------------+---------------------------------------------------
報告者 : guest
担当者 : guest
分類 : タスク
ステータス : assigned
優先度 : 普通
マイルストーン :
コンポーネント : その他
バージョン :
解決方法 :
キーワード :
見積時間 : 0
着手予定日 :
今日の作業時間 : 0
終了予定日 :
総作業時間 : 0
集計対象? : 1
進捗率(%) :
------------------------+---------------------------------------------------
進捗状況:


------------------------+---------------------------------------------------
コメント (by guest):

 一段組み出力


途中長くなったけど、結局やった修正はこんな感じ。

--- TracLight/python/Lib/site-packages/trac/ticket/notification.py (リビジョン 49)
+++ TracLight/python/Lib/site-packages/trac/ticket/notification.py (リビジョン 51)
@@ -152,16 +152,14 @@
         i = 0
         for f in [f for f in fields if f['name'] != 'description']:
             fname = f['name']
+            flabel = f['label']
             if not tkt.values.has_key(fname):
                 continue
             fval = tkt[fname]
             if f['type'] == 'textarea' or '\n' in unicode(fval):
-                big.append((fname.capitalize(), CRLF.join(fval.splitlines())))
+                big.append((flabel.capitalize(), CRLF.join(fval.splitlines())))
             else:
-                txt += format[i % 2] % (fname.capitalize(), fval)
-                i += 1
-        if i % 2:
-            txt += CRLF
+                txt += '%s : %s%s' % (flabel.capitalize(), fval, CRLF)
         if big:
             txt += sep
             for name, value in big:

あー、疲れた。けど、日本語で出力するっていう要望ありそうなのに、ネット調べても見つからなかったのですよね。それともあまりに簡単過ぎて、敢えて誰も取り上げないだけ…?