OSDN Git Service

updates
authorshy <shy>
Tue, 9 Aug 2005 00:41:52 +0000 (00:41 +0000)
committershy <shy>
Tue, 9 Aug 2005 00:41:52 +0000 (00:41 +0000)
46 files changed:
ChangeLog
NEWS [new file with mode: 0644]
README
lib/ninix-install.py
lib/ninix-update.py
lib/ninix/alias.py
lib/ninix/balloon.py
lib/ninix/communicate.py
lib/ninix/config.py
lib/ninix/dll.py
lib/ninix/dll/aya.py
lib/ninix/dll/aya5.py
lib/ninix/dll/bln.py
lib/ninix/dll/hanayu.py
lib/ninix/dll/kawari.py
lib/ninix/dll/kawari8.py
lib/ninix/dll/lettuce.py
lib/ninix/dll/mciaudio.py
lib/ninix/dll/mciaudior.py
lib/ninix/dll/misaka.py
lib/ninix/dll/niseshiori.py
lib/ninix/dll/saori_cpuid.py
lib/ninix/dll/satori.py
lib/ninix/dll/ssu.py
lib/ninix/dll/textcopy.py
lib/ninix/dll/wmove.py
lib/ninix/entry_db.py
lib/ninix/ghost.py
lib/ninix/home.py
lib/ninix/keymap.py
lib/ninix/kinoko.py
lib/ninix/main.py
lib/ninix/makoto.py
lib/ninix/menu.py
lib/ninix/nekodorif.py
lib/ninix/ngm.py
lib/ninix/pix.py
lib/ninix/prefs.py
lib/ninix/sakura.py
lib/ninix/script.py
lib/ninix/seriko.py
lib/ninix/sstp.py
lib/ninix/surface.py
lib/ninix/update.py
lib/ninix/version.py
lib/sstplib.py

index 352662c..a24e37d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+Tue August 9 2005   Shyouzou Sugitani <shy@users.sourceforge.jp>
+       * バージョン3.5.9リリース.
+
+Mon August 8 2005   Shyouzou Sugitani <shy@users.sourceforge.jp>
+       * READMEファイルをREADMEとNEWSに分割.
+       * READMEの「必要なもの」にNumerical Pythonの記述を追加.
+       * READMEの「必要なもの」の日本語コーデックに関する記述を修正.
+       (Thanks to jadoさん)
+
+Mon August 8 2005   Shun-ichi TAHARA <jado@flowernet.gr.jp>
+       * バルーンフォントの変更が保存されていなかったのを修正.
+
+Thu August 4 2005   Shyouzou Sugitani <shy@users.sourceforge.jp>
+       * PYTHON: コーディングスタイルを調整.
+
+Wed August 3 2005   Shyouzou Sugitani <shy@users.sourceforge.jp>
+       * PYTHON: プレフィックスやサフィックスを調べるときに, 文字列の
+       スライスを使うのを避け, 代わりにstartswith()とendswith()を使うよう修正.
+
+Tue August 2 2005   Shyouzou Sugitani <shy@users.sourceforge.jp>
+       * PYTHON: オブジェクト型の比較には常にisinstance()を使い
+       型を直接比較しないよう修正.
+
+Mon August 1 2005   Shyouzou Sugitani <shy@users.sourceforge.jp>
+       * PYTHON: 文字列連結に+, +=ではなく''.join()を使うよう修正.
+       * PYTHON: stringモジュールではなく文字列メソッドを使うよう修正.
+
 Fri July 29 2005   Shyouzou Sugitani <shy@users.sourceforge.jp>
        * PYTHON: Noneとの比較に==, !=を使っている個所をis, is notを使うよう修正.
 
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e7288ff
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,203 @@
+Ver.3.4の変更点
+---------------
+- GTK+2.4 APIに移行しました。
+- 「華和梨8」でのマルチゴーストに対応しました。
+  (_kawari8.soも対応したものが必要になります。従来のものは動作しません。)
+- スクリプトエラーからの復帰処理を追加しました。
+- 単体のシェルを使用すると落ちる問題を修正しました。
+- 「文」のバージョン判定を修正しました。
+-  \![change,ghost]による自分自身への交代が正しく処理されるよう修正しました。
+- メニューのサイドバーとフォントカラー変更の実装を修正しました。
+- サーフェスのリセットで自由配置が無効になるバグを修正しました。
+- サーフェスのリセットの際に必要以上にオーバーレイ等を消去してしまうのを修正
+  しました。
+- PNAファイルによるサーフェスとバルーンのアルファチャンネル設定に対応しました。
+  (オーバーレイ等についても対応しています。本体の透過処理にはXサーバが
+    Composition拡張機能を持ち、適切に設定されていることが必要です。)
+- 本体設定でPNAファイルを使用するかどうかを設定できるようにしました。
+- openngmをベースに「何かゴーストマネージャ」のクローンを実装しました。
+  (未完成のため検索とネットワーク更新機能のみです。)
+
+Ver.3.2の変更点
+---------------
+- 「きのこ」互換機能を追加しました。スキンファイルはninix-installでインストール
+  することができます。
+- 「猫どりふ」互換機能を追加しました。スキンおよび落下物ファイルはninix-installで
+  インストールすることができます。
+   (未完成のため落下物を落としてSHIORIイベントを発生させることしかできません。)
+- サーフェスの当たり判定領域の表示/非表示を本体設定から変更できるようにしました。
+- ホームディレクトリが同じninix-ayaの多重起動を禁止しました。
+- アニメーションのバグを修正しました。
+- 「里々」互換モジュールを改良/修正しました。
+- 3.0で'\-'タグが機能しなくなっていたのを修正しました。
+- SSTPのEXECUTE/1.0にCheckQueueコマンドを追加しました。
+- 「文」のバージョン判定を修正しました。
+
+Ver.3.0の変更点
+---------------
+- 「文5」モジュールインタフェース。
+- ポップアップメニューからゴーストを複数起動できるようにしました。
+- SSTP Bottleクライアント向けにGetNamesコマンドを追加しました。
+- SSTP SEND/1.4の処理でIfGhost指定されたゴーストが起動していない場合には
+  一時的にそのゴーストを呼び出してスクリプトを再生するようにしました。
+  (指定ゴーストがインストールされていない場合に他のゴーストでスクリプトを
+    再生するかどうかは本体設定の「色々」->「SSTP 設定」で変更できます。)
+- アニメーションの処理を改良しました。(SERIKO/2.0にも対応。)
+- フォントの設定ファイルpango_fontrcをpreferencesに統合しました。
+  設定は従来通り本体設定から行なうようになっています。
+- これまではポップアップメニューから他のゴーストの専用バルーンも含めた全バルーンが
+  選択できたのをそのゴーストの専用バルーンと汎用バルーンに制限しました。
+  (デフォルトバルーンは汎用バルーンからのみ選択可能です。)
+  これは複数ゴースト起動が可能になったための変更で、消滅したゴーストの専用バルーン
+  を使用しているゴーストがいるという状況が発生しないようにするための措置です。
+- サーフェス倍率と表示ウエイトのデフォルト設定は本体設定で行なうようになりました。
+  ポップアップメニューからの変更は対象となるゴーストの設定を一時的に変更するだけに
+  なります。他のゴーストや次回起動時の設定には影響しません。
+- -Rオプションを削除しました。
+- Pythonのトレースバック出力専用ダイアログを追加しました。
+- オーナードローメニュー用画像をポップアップメニューで利用するようにしました。
+
+Ver.2.6の変更点
+---------------
+- 「里々」互換モジュールを大幅に更新しました。
+- 「里々」互換モジュールで SAORI 互換モジュール呼び出しに対応しました。
+- saori_cpuid.dll 互換モジュールを追加しました。
+- ssu.dll 互換モジュールを追加しました。
+- 「花柚」互換モジュールで radar 形式のグラフに対応しました。
+- メニューアイテムにアクセラレータを設定しました。
+- デフォルトバルーンの設定に「常にこのバルーンを使う」チェックボックスを
+  追加しました。
+- OnChoiceEnter イベントのサポートを追加しました。
+- 「文」互換モジュールを Ver. 4.97fix0 仕様に更新しました。
+- 明示的にサーフェス指定が来ない限りサーフェスを出さないように変更しました。
+- cjkcodecs(要1.0.2)にも対応しました。
+- 「華和梨」、「偽栞」互換モジュールのメタ文字列の展開を改良しました。
+- サーフェスの当り判定の ID を0〜255に拡張しました。
+- バルーン切り替えの際にゴーストを再起動しないように変更しました。
+- 表示する文字が含まれていないスクリプト(改行のみなど)の場合にはバルーンを
+  出さないようにしました。
+- バルーンのフォントサイズの設定が実際の表示に反映されるよう修正しました。
+- バルーンフォント設定の変更が即反映されるように修正しました。
+- %username の展開で最初に SHIORI で設定されている値を問い合わせるように
+  しました。
+- 「ポータル」、「おすすめ」の中の項目を選択した際に
+  OnRecommandedSiteChoice イベントを発生させるようにしました。
+- バルーンの配置を改良しました。
+
+Ver.2.4の変更点
+---------------
+- サーフェス倍率の最小値を10%から40%に変更しました。
+- サーフェスに合わせてバルーンも縮小できるようにしました。
+- 本体設定にデフォルトバルーンの設定を追加しました。
+  それに合わせてポップアップメニューのバルーンの項目は起動中のゴーストの
+  バルーンを一時的に変更するのみにしました。
+- 起動時点でサーフェス全てを読み込んでいたのを必要になってから読み込むように
+  変更しました。起動時間の短縮、メモリ使用量の削減などの効果があります。
+  ただし一部アニメーション等で動作が遅くなることがあります。
+- passivemode 中に SSTP を受信した場合には passivemode を抜けるまで再生を
+  始めないよう修正しました。
+- サーフェス移動中にゴーストの動作を停止させないよう変更しました。
+- wmove.dll 互換モジュールを追加しました。
+- UNIX ドメインソケット版の SSTP サーバを追加した際に入ったバグを修正しました。
+- ポップアップメニューに「ポータル」、「おすすめ」を実装しました。
+- Shell の descript.txt の seriko.alignmenttodesktop に対応しました。
+- 全てのデスクトップに居座るようにする設定をポップアップメニューに追加
+  しました。ウインドウマネージャによっては正しく機能しないことがあります。
+- 起動後に本体設定で画面下端からの距離を調整できるようにしました。
+  (従来通り -R オプションも使用可能ですが、このオプションは将来削除される
+   可能性があります。オプションを指定した場合はそれが優先されます。)
+  また画面上部に移動するゴースト向けに画面上端からの距離も指定できるように
+  しました。
+  easyballoon 互換モジュールもこれらの設定の影響を受けます。
+- Python2.3 で動作するようにしました。
+- easyballoon 互換モジュールを1.0仕様に対応させました。
+
+Ver.2.2の変更点
+---------------
+- ゴーストが最小化されている時はしゃべらなくなりました。(時間経過イベントは
+  発生しています。) SSTP リクエストに対しては "512 Invisible" を返します。
+- Python栞のサポートを削除しました。
+- 本体のターミナル出力を UTF-8 に変更しました。互換栞等はそれぞれが内部で
+  使用している文字コードでの出力のままです。
+- install.txt で指定されるインストールディレクトリの文字コードを UTF-8 に
+  変換するよう変更しました。
+- ファイル名に関して文字コード変換を行なわないよう変更しました。
+  アーカイブ内にマルチバイト文字を使用したファイル名があるものについては
+  ゴースト・シェル等の種類を問わずサポート対象外です。
+- メニュー等を L10N (gettext化)しました。メッセージカタログは日本語(ja.po)と
+  中国語(zh_TW.po)が用意されています。(zh_TW.poはChieh-Nan Wangさんが作成。)
+- バルーンに使用しているウインドウの種類がダイアログに変わりました。
+- コミュニケートウインドウ, 花柚ウインドウの移動の処理が変更になりました。
+  よりスムーズに移動できるようになっています。
+- サーフェス・バルーン・コミュニケートウインドウがサイズ変更を拒否するよう
+  にしました。
+- 本体・SSTP サーバ・互換 SAORI 内部で使用する文字コードを Unicode に変更
+  しました。
+- 華和梨7で日本語以外の文字コードを使用したゴーストにも対応しました。
+- サーフェスが最小化された場合と復帰した場合にイベントが発生します。
+- ninix-install で pnaファイルもインストールするようにしました。
+  ネットワーク更新の対象としても認識されるようになっています。
+- ninix 用プラグインの定義ファイル plugin.txt で EUC-JP 以外の文字コードを
+  使用可能にしました。
+  (デフォルトは EUC-JP なので既存のプラグインの変更は不要です。)
+- ゴースト起動時に OnDisplayChange を送信するようにしました。
+- ~/.ninix/gtkrc をインストールしないようにしました.
+  ファイルは doc/examples に移動しています。
+- ゴーストのアイコンをサーフェスウインドウのアイコンとして使うようにしました。
+  ポップアップメニューでも使っています。
+- misaka.py を「フサギコ漫談」対応のため変更しました。
+- サーフェス画像として暗号化 PNG を使えるようにしました。
+- 着せ替えメニューをポップアップメニューから分離して画面上に置いておける
+  ようにしました。
+
+Ver.2.0の変更点
+---------------
+- GTK+1.2 から GTK+2.0 API に移行しました。
+  Python 2.0, GTK+2.0, PyGTK 1.99 以降が必要です。
+  (Python 2.2, GTK+ 2.2.1, PyGTK 1.99.14 以降推奨。)
+- libpng を使用していた _image.so モジュールは削除されました。
+  ビルドに libpng のヘッダは不要です。
+- サーフェス縮小機能を搭載しました。
+  ポップアップメニューの「サーフェス倍率」から選択して下さい。
+- 画像ファイルの xpm 形式への変換および変換してインストールされたファイルの
+  サポートが削除されました。
+  変換を使用していた場合はゴーストを再インストールする必要があります。
+- ゴーストインストーラ(ninix-install)の動作が変更になりました。
+  ゴーストのインストール先となるディレクトリの決定方法が従来と異なり
+  ゴーストアーカイブ内の install.txt に従うようになっています。
+  既にインストールされているゴーストはそのままで動作しますので
+  再インストールの必要はありません。
+- ゴースト起動時間と消滅回数の記録先が ~/.ninix/history, ~/.ninix/vanished
+  からゴーストのインストール先の HISTORY ファイルに変更になりました。
+  以前のファイルの記録は引き継がれません。
+  また、これまでのサーフェス毎の起動時間ではなくそのディレクトリにある
+  サーフェス全てについての起動時間の合計のみが記録されるようになっています。
+- バルーンフォントの指定がPango形式に変更になっています。指定は従来通り
+  ポップアップメニューの「設定」から行なえます。
+  設定ファイルは ~/.ninix/pango_fontrc になります。
+- CROW 同梱ゴーストのインストール機能は削除されました。
+- マウスカーソルがサーフェスの当り判定領域に入るとカーソル形状が変わります。
+  撫で/触り判定はボタンを押していない状態でマウスを動かすと発生するように
+  変更されています。
+- バルーンのスクロールボタンがマウスホイールで操作できるようになりました。
+- -p オプションは廃止されました。ウインドウマネージャで強制しない限り
+  ウインドウの枠などは付きません。また、ウインドウの配置も可能な範囲で
+  ウインドウマネージャの制御を受けないようになっています。
+- 着せ替え対応。
+
+Ver.1.0の変更点
+---------------
+- 「文」互換 SHIORI モジュール aya.py。
+- SAORI API 互換フレームワークおよび各種 SAORI 互換モジュール。
+  (各モジュールの詳細は doc/saori.txt を参照して下さい。)
+- 「華和梨8」モジュールインタフェース。
+  (「華和梨8」モジュールの詳細は doc/kawari.txt を参照して下さい。)
+- ゴースト間コミュニケーション対応。
+- アニメーション機能強化。
+- ネットワーク更新の途中キャンセル対応。
+- SakuraScript 対応強化。
+- 画面の上端や自由配置といった位置指定に対応。
+
+aya.py は、umeici 氏が開発公開されている「文(あや)」Ver. 3.x〜4.xの
+仕様に準拠した互換モジュールです。基本的な構造は「偽林檎」を参考に
+させていただきました。
diff --git a/README b/README
index 3b5f2ef..1405994 100644 (file)
--- a/README
+++ b/README
@@ -9,210 +9,6 @@ UNIX 対応デスクトップアクセサリninixに拡張機能を追加した
 現在は、以下の追加機能を搭載しています。 また、オリジナルninixに収録されて
 いない小規模な改良、バグフィックスも合わせて収録しています。
 
-Ver.1.0の変更点
----------------
-- 「文」互換 SHIORI モジュール aya.py。
-- SAORI API 互換フレームワークおよび各種 SAORI 互換モジュール。
-  (各モジュールの詳細は doc/saori.txt を参照して下さい。)
-- 「華和梨8」モジュールインタフェース。
-  (「華和梨8」モジュールの詳細は doc/kawari.txt を参照して下さい。)
-- ゴースト間コミュニケーション対応。
-- アニメーション機能強化。
-- ネットワーク更新の途中キャンセル対応。
-- SakuraScript 対応強化。
-- 画面の上端や自由配置といった位置指定に対応。
-
-aya.py は、umeici 氏が開発公開されている「文(あや)」Ver. 3.x〜4.xの
-仕様に準拠した互換モジュールです。基本的な構造は「偽林檎」を参考に
-させていただきました。
-
-Ver.2.0の変更点
----------------
-- GTK+1.2 から GTK+2.0 API に移行しました。
-  Python 2.0, GTK+2.0, PyGTK 1.99 以降が必要です。
-  (Python 2.2, GTK+ 2.2.1, PyGTK 1.99.14 以降推奨。)
-- libpng を使用していた _image.so モジュールは削除されました。
-  ビルドに libpng のヘッダは不要です。
-- サーフェス縮小機能を搭載しました。
-  ポップアップメニューの「サーフェス倍率」から選択して下さい。
-- 画像ファイルの xpm 形式への変換および変換してインストールされたファイルの
-  サポートが削除されました。
-  変換を使用していた場合はゴーストを再インストールする必要があります。
-- ゴーストインストーラ(ninix-install)の動作が変更になりました。
-  ゴーストのインストール先となるディレクトリの決定方法が従来と異なり
-  ゴーストアーカイブ内の install.txt に従うようになっています。
-  既にインストールされているゴーストはそのままで動作しますので
-  再インストールの必要はありません。
-- ゴースト起動時間と消滅回数の記録先が ~/.ninix/history, ~/.ninix/vanished
-  からゴーストのインストール先の HISTORY ファイルに変更になりました。
-  以前のファイルの記録は引き継がれません。
-  また、これまでのサーフェス毎の起動時間ではなくそのディレクトリにある
-  サーフェス全てについての起動時間の合計のみが記録されるようになっています。
-- バルーンフォントの指定がPango形式に変更になっています。指定は従来通り
-  ポップアップメニューの「設定」から行なえます。
-  設定ファイルは ~/.ninix/pango_fontrc になります。
-- CROW 同梱ゴーストのインストール機能は削除されました。
-- マウスカーソルがサーフェスの当り判定領域に入るとカーソル形状が変わります。
-  撫で/触り判定はボタンを押していない状態でマウスを動かすと発生するように
-  変更されています。
-- バルーンのスクロールボタンがマウスホイールで操作できるようになりました。
-- -p オプションは廃止されました。ウインドウマネージャで強制しない限り
-  ウインドウの枠などは付きません。また、ウインドウの配置も可能な範囲で
-  ウインドウマネージャの制御を受けないようになっています。
-- 着せ替え対応。
-
-Ver.2.2の変更点
----------------
-- ゴーストが最小化されている時はしゃべらなくなりました。(時間経過イベントは
-  発生しています。) SSTP リクエストに対しては "512 Invisible" を返します。
-- Python栞のサポートを削除しました。
-- 本体のターミナル出力を UTF-8 に変更しました。互換栞等はそれぞれが内部で
-  使用している文字コードでの出力のままです。
-- install.txt で指定されるインストールディレクトリの文字コードを UTF-8 に
-  変換するよう変更しました。
-- ファイル名に関して文字コード変換を行なわないよう変更しました。
-  アーカイブ内にマルチバイト文字を使用したファイル名があるものについては
-  ゴースト・シェル等の種類を問わずサポート対象外です。
-- メニュー等を L10N (gettext化)しました。メッセージカタログは日本語(ja.po)と
-  中国語(zh_TW.po)が用意されています。(zh_TW.poはChieh-Nan Wangさんが作成。)
-- バルーンに使用しているウインドウの種類がダイアログに変わりました。
-- コミュニケートウインドウ, 花柚ウインドウの移動の処理が変更になりました。
-  よりスムーズに移動できるようになっています。
-- サーフェス・バルーン・コミュニケートウインドウがサイズ変更を拒否するよう
-  にしました。
-- 本体・SSTP サーバ・互換 SAORI 内部で使用する文字コードを Unicode に変更
-  しました。
-- 華和梨7で日本語以外の文字コードを使用したゴーストにも対応しました。
-- サーフェスが最小化された場合と復帰した場合にイベントが発生します。
-- ninix-install で pnaファイルもインストールするようにしました。
-  ネットワーク更新の対象としても認識されるようになっています。
-- ninix 用プラグインの定義ファイル plugin.txt で EUC-JP 以外の文字コードを
-  使用可能にしました。
-  (デフォルトは EUC-JP なので既存のプラグインの変更は不要です。)
-- ゴースト起動時に OnDisplayChange を送信するようにしました。
-- ~/.ninix/gtkrc をインストールしないようにしました.
-  ファイルは doc/examples に移動しています。
-- ゴーストのアイコンをサーフェスウインドウのアイコンとして使うようにしました。
-  ポップアップメニューでも使っています。
-- misaka.py を「フサギコ漫談」対応のため変更しました。
-- サーフェス画像として暗号化 PNG を使えるようにしました。
-- 着せ替えメニューをポップアップメニューから分離して画面上に置いておける
-  ようにしました。
-
-Ver.2.4の変更点
----------------
-- サーフェス倍率の最小値を10%から40%に変更しました。
-- サーフェスに合わせてバルーンも縮小できるようにしました。
-- 本体設定にデフォルトバルーンの設定を追加しました。
-  それに合わせてポップアップメニューのバルーンの項目は起動中のゴーストの
-  バルーンを一時的に変更するのみにしました。
-- 起動時点でサーフェス全てを読み込んでいたのを必要になってから読み込むように
-  変更しました。起動時間の短縮、メモリ使用量の削減などの効果があります。
-  ただし一部アニメーション等で動作が遅くなることがあります。
-- passivemode 中に SSTP を受信した場合には passivemode を抜けるまで再生を
-  始めないよう修正しました。
-- サーフェス移動中にゴーストの動作を停止させないよう変更しました。
-- wmove.dll 互換モジュールを追加しました。
-- UNIX ドメインソケット版の SSTP サーバを追加した際に入ったバグを修正しました。
-- ポップアップメニューに「ポータル」、「おすすめ」を実装しました。
-- Shell の descript.txt の seriko.alignmenttodesktop に対応しました。
-- 全てのデスクトップに居座るようにする設定をポップアップメニューに追加
-  しました。ウインドウマネージャによっては正しく機能しないことがあります。
-- 起動後に本体設定で画面下端からの距離を調整できるようにしました。
-  (従来通り -R オプションも使用可能ですが、このオプションは将来削除される
-   可能性があります。オプションを指定した場合はそれが優先されます。)
-  また画面上部に移動するゴースト向けに画面上端からの距離も指定できるように
-  しました。
-  easyballoon 互換モジュールもこれらの設定の影響を受けます。
-- Python2.3 で動作するようにしました。
-- easyballoon 互換モジュールを1.0仕様に対応させました。
-
-Ver.2.6の変更点
----------------
-- 「里々」互換モジュールを大幅に更新しました。
-- 「里々」互換モジュールで SAORI 互換モジュール呼び出しに対応しました。
-- saori_cpuid.dll 互換モジュールを追加しました。
-- ssu.dll 互換モジュールを追加しました。
-- 「花柚」互換モジュールで radar 形式のグラフに対応しました。
-- メニューアイテムにアクセラレータを設定しました。
-- デフォルトバルーンの設定に「常にこのバルーンを使う」チェックボックスを
-  追加しました。
-- OnChoiceEnter イベントのサポートを追加しました。
-- 「文」互換モジュールを Ver. 4.97fix0 仕様に更新しました。
-- 明示的にサーフェス指定が来ない限りサーフェスを出さないように変更しました。
-- cjkcodecs(要1.0.2)にも対応しました。
-- 「華和梨」、「偽栞」互換モジュールのメタ文字列の展開を改良しました。
-- サーフェスの当り判定の ID を0〜255に拡張しました。
-- バルーン切り替えの際にゴーストを再起動しないように変更しました。
-- 表示する文字が含まれていないスクリプト(改行のみなど)の場合にはバルーンを
-  出さないようにしました。
-- バルーンのフォントサイズの設定が実際の表示に反映されるよう修正しました。
-- バルーンフォント設定の変更が即反映されるように修正しました。
-- %username の展開で最初に SHIORI で設定されている値を問い合わせるように
-  しました。
-- 「ポータル」、「おすすめ」の中の項目を選択した際に
-  OnRecommandedSiteChoice イベントを発生させるようにしました。
-- バルーンの配置を改良しました。
-
-Ver.3.0の変更点
----------------
-- 「文5」モジュールインタフェース。
-- ポップアップメニューからゴーストを複数起動できるようにしました。
-- SSTP Bottleクライアント向けにGetNamesコマンドを追加しました。
-- SSTP SEND/1.4の処理でIfGhost指定されたゴーストが起動していない場合には
-  一時的にそのゴーストを呼び出してスクリプトを再生するようにしました。
-  (指定ゴーストがインストールされていない場合に他のゴーストでスクリプトを
-    再生するかどうかは本体設定の「色々」->「SSTP 設定」で変更できます。)
-- アニメーションの処理を改良しました。(SERIKO/2.0にも対応。)
-- フォントの設定ファイルpango_fontrcをpreferencesに統合しました。
-  設定は従来通り本体設定から行なうようになっています。
-- これまではポップアップメニューから他のゴーストの専用バルーンも含めた全バルーンが
-  選択できたのをそのゴーストの専用バルーンと汎用バルーンに制限しました。
-  (デフォルトバルーンは汎用バルーンからのみ選択可能です。)
-  これは複数ゴースト起動が可能になったための変更で、消滅したゴーストの専用バルーン
-  を使用しているゴーストがいるという状況が発生しないようにするための措置です。
-- サーフェス倍率と表示ウエイトのデフォルト設定は本体設定で行なうようになりました。
-  ポップアップメニューからの変更は対象となるゴーストの設定を一時的に変更するだけに
-  なります。他のゴーストや次回起動時の設定には影響しません。
-- -Rオプションを削除しました。
-- Pythonのトレースバック出力専用ダイアログを追加しました。
-- オーナードローメニュー用画像をポップアップメニューで利用するようにしました。
-
-Ver.3.2の変更点
----------------
-- 「きのこ」互換機能を追加しました。スキンファイルはninix-installでインストール
-  することができます。
-- 「猫どりふ」互換機能を追加しました。スキンおよび落下物ファイルはninix-installで
-  インストールすることができます。
-   (未完成のため落下物を落としてSHIORIイベントを発生させることしかできません。)
-- サーフェスの当たり判定領域の表示/非表示を本体設定から変更できるようにしました。
-- ホームディレクトリが同じninix-ayaの多重起動を禁止しました。
-- アニメーションのバグを修正しました。
-- 「里々」互換モジュールを改良/修正しました。
-- 3.0で'\-'タグが機能しなくなっていたのを修正しました。
-- SSTPのEXECUTE/1.0にCheckQueueコマンドを追加しました。
-- 「文」のバージョン判定を修正しました。
-
-Ver.3.4の変更点
----------------
-- GTK+2.4 APIに移行しました。
-- 「華和梨8」でのマルチゴーストに対応しました。
-  (_kawari8.soも対応したものが必要になります。従来のものは動作しません。)
-- スクリプトエラーからの復帰処理を追加しました。
-- 単体のシェルを使用すると落ちる問題を修正しました。
-- 「文」のバージョン判定を修正しました。
--  \![change,ghost]による自分自身への交代が正しく処理されるよう修正しました。
-- メニューのサイドバーとフォントカラー変更の実装を修正しました。
-- サーフェスのリセットで自由配置が無効になるバグを修正しました。
-- サーフェスのリセットの際に必要以上にオーバーレイ等を消去してしまうのを修正
-  しました。
-- PNAファイルによるサーフェスとバルーンのアルファチャンネル設定に対応しました。
-  (オーバーレイ等についても対応しています。本体の透過処理にはXサーバが
-    Composition拡張機能を持ち、適切に設定されていることが必要です。)
-- 本体設定でPNAファイルを使用するかどうかを設定できるようにしました。
-- openngmをベースに「何かゴーストマネージャ」のクローンを実装しました。
-  (未完成のため検索とネットワーク更新機能のみです。)
-
 必要なもの
 ----------
 
@@ -225,17 +21,25 @@ Ver.3.4の変更点
 - GTK+ (http://www.gtk.org/)
   X Window System 用の GUI ライブラリです。バージョン 2.4.2 での
   動作を確認しています。バージョン 2.4 の API を使用していますので
-  それ以前のバージョンでは動作しません.
+  それ以前のバージョンでは動作しません。
+
+- Numerical Python(http://numeric.scipy.org/)
+  PyGTKのpixels_arrayを使用しているため必要になります。
+  バージョン 23.8での動作を確認しています。
 
 - PyGTK (http://www.daa.com.au/~james/pygtk/)
   Python から GTK+ を利用するためのライブラリです。バージョン 
   2.4.1 での動作を確認しています。Numeric support が必須です。
+  Numerical Pythonをインストールした上でPyGTKがビルドされている必要が
+  あります。
 
 - JapaneseCodecs (http://www.python.jp/Zope/download/JapaneseCodecs)
   Python で日本語の文字エンコーディングを利用できるようにするための
-  コーデック集です。バージョン 1.4.9 での動作を確認しています。
+  コーデック集です。Python 2.4 以降であれば不要です。
+  バージョン 1.4.9 での動作を確認しています。
   中国語ゴーストを使う場合には CJK Codecs (http://cjkpython.berlios.de)
-  が必要です。CJK Codecs を入れた場合にはこちらで日本語も扱えますので
+  が必要です。こちらも Python 2.4 以降であれば不要です。
+  CJK Codecs を入れた場合にはこちらで日本語も扱えますので
   JapaneseCodecs は不要です。バージョン 1.0.2 での動作を確認しています。
 
 - UnZip (Info-ZIP)
@@ -283,7 +87,7 @@ Copyright (C) 2001, 2002 by Tamito KAJIYAMA <kajiyama3@geocities.co.jp>
 Copyright (C) 2002-2005 by MATSUMURA Namihiko <nie@counterghost.net>
 Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 Copyright (C) 2002, 2003 by ABE Hideaki <abe-xx@eos.dricas.com>
-Copyright (C) 2003, 2004 by Shun-ichi TAHARA <jado@flowernet.gr.jp>
+Copyright (C) 2003-2005 by Shun-ichi TAHARA <jado@flowernet.gr.jp>
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License (version 2) as
index fa64d59..17925a4 100755 (executable)
@@ -14,7 +14,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-#  $Id: ninix-install.py,v 1.34 2005/02/07 01:20:26 shy Exp $
+#  $Id: ninix-install.py,v 1.35 2005/08/09 00:41:52 shy Exp $
 #
 
 # env.var: NINIX_HOME, NINIX_USER, NINIX_ARCHIVE, TMPDIR
@@ -32,8 +32,8 @@ import urllib
 import gettext
 gettext.install('ninix')
 
-if os.environ.has_key("DISPLAY"):
-    del os.environ["DISPLAY"]
+if os.environ.has_key('DISPLAY'):
+    del os.environ['DISPLAY']
 
 import ninix.alias
 import ninix.config
@@ -42,7 +42,7 @@ import ninix.version
 
 PROGRAM_NAME = os.path.basename(sys.argv[0])
 
-USAGE = """\
+USAGE = '''\
 Usage: %s [options] [file ...]
 Options:
   -g, --ghost            assume that all files are ghosts
@@ -63,15 +63,17 @@ Options:
   -p, --port NUM         port number for SSTP connection (default: 9801)
   -L, --lower            lower file names with upper case letters
   -h, --help             show this message
-"""
+'''
 
 def usage():
     sys.stderr.write(USAGE % PROGRAM_NAME)
     sys.exit(1)
 
+
 class InstallError(Exception):
     pass
 
+
 def fatal(error):
     raise InstallError, error
 
@@ -83,63 +85,63 @@ def main():
     global mode, arcdir
     try:
         options, files = getopt.getopt(
-            sys.argv[1:], "gsbS:PKNDRridxH:U:A:T:rp:q:Lh",
-            ["ghost", "shell", "balloon", "supplement=", "plugin",
-             "kinoko", "nekoninni", "katochan",
-             "homedir=", "userdir=", "arcdir=", "tempdir=",
-             "interactive", "download", "reload", "port=",
-             "lower", "help"])
+            sys.argv[1:], 'gsbS:PKNDRridxH:U:A:T:rp:q:Lh',
+            ['ghost', 'shell', 'balloon', 'supplement=', 'plugin',
+             'kinoko', 'nekoninni', 'katochan',
+             'homedir=', 'userdir=', 'arcdir=', 'tempdir=',
+             'interactive', 'download', 'reload', 'port=',
+             'lower', 'help'])
     except getopt.error, e:
-        sys.stderr.write("Error: %s\n" % str(e))
+        sys.stderr.write('Error: %s\n' % str(e))
         usage()
-    homedir = os.environ.get("NINIX_HOME")
-    userdir = os.environ.get("NINIX_USER")
-    arcdir = os.environ.get("NINIX_ARCHIVE", "~/.ninix/archive")
+    homedir = os.environ.get('NINIX_HOME')
+    userdir = os.environ.get('NINIX_USER')
+    arcdir = os.environ.get('NINIX_ARCHIVE', '~/.ninix/archive')
     tempdir = None
     filetype = None
     target = None
     mode = 0
     to_lower = 0
     to_reload = 0
-    host = ""
+    host = ''
     port = 9801
     for opt, val in options:
-        if opt in ["-h", "--help"]:
+        if opt in ['-h', '--help']:
             usage()
-        elif opt in ["-g", "--ghost"]:
-            filetype = "ghost"
-        elif opt in ["-s", "--shell"]:
-            filetype = "shell"
-        elif opt in ["-b", "--balloon"]:
-            filetype = "balloon"
-        elif opt in ["-P", "--plugin"]:
-            filetype = "plugin"
-        elif opt in ["-K", "--kinoko"]:
-            filetype = "kinoko"
-        elif opt in ["-N", "--nekoninni"]:
-            filetype = "nekoninni"
-        elif opt in ["-D", "--katochan"]:
-            filetype = "katochan"
-        elif opt in ["-S", "--supplement"]:
-            filetype = "supplement"
+        elif opt in ['-g', '--ghost']:
+            filetype = 'ghost'
+        elif opt in ['-s', '--shell']:
+            filetype = 'shell'
+        elif opt in ['-b', '--balloon']:
+            filetype = 'balloon'
+        elif opt in ['-P', '--plugin']:
+            filetype = 'plugin'
+        elif opt in ['-K', '--kinoko']:
+            filetype = 'kinoko'
+        elif opt in ['-N', '--nekoninni']:
+            filetype = 'nekoninni'
+        elif opt in ['-D', '--katochan']:
+            filetype = 'katochan'
+        elif opt in ['-S', '--supplement']:
+            filetype = 'supplement'
             target = val
-        elif opt in ["-H", "--homedir"]:
+        elif opt in ['-H', '--homedir']:
             homedir = val
-        elif opt in ["-U", "--userdir"]:
+        elif opt in ['-U', '--userdir']:
             userdir = val
-        elif opt in ["-A", "--arcdir"]:
+        elif opt in ['-A', '--arcdir']:
             arcdir = val
-        elif opt in ["-T", "--tempdir"]:
+        elif opt in ['-T', '--tempdir']:
             tempdir = val
-        elif opt in ["-i", "--interactive"]:
+        elif opt in ['-i', '--interactive']:
             mode = mode | INTERACTIVE
-        elif opt in ["-d", "--download"]:
+        elif opt in ['-d', '--download']:
             mode = mode | DOWNLOAD
-        elif opt in ["-r", "--reload"]:
+        elif opt in ['-r', '--reload']:
             to_reload = 1
-        elif opt in ["-p", "--port"]:
+        elif opt in ['-p', '--port']:
             port = int(val)
-        elif opt in ["-L", "--lower"]:
+        elif opt in ['-L', '--lower']:
             to_lower = 1
     if homedir:
         ninix.home.NINIX_HOME = homedir
@@ -151,7 +153,7 @@ def main():
     if to_lower:
         n = 0
         homedir = ninix.home.get_ninix_home()
-        for data in ["ghost", "balloon"]:
+        for data in ['ghost', 'balloon']:
             try:
                 buffer = os.listdir(os.path.join(homedir, data))
             except OSError:
@@ -161,17 +163,17 @@ def main():
                 if os.path.isdir(path):
                     n += lower_files(path)
         if n > 0:
-            print n, "files renamed"
+            print n, 'files renamed'
     buffer = []
     for filename in files:
-        if filename[:1] == "@":
+        if filename.startswith('@'):
             try:
                 lines = open(filename[1:]).readlines()
             except IOError, e:
                 sys.stderr.write("cannot read '%s' (skipped)\n" % filename[1:])
             else:
                 for line in [line.strip() for line in lines]:
-                    if line and line[0] != "#":
+                    if line and not line.startswith('#'):
                         buffer.append(line)
         else:
             buffer.append(filename)
@@ -179,137 +181,142 @@ def main():
         try:
             install(filename, filetype, target, ninix.home.get_ninix_home())
         except InstallError, error:
-            sys.stderr.write("%s: %s (skipped)\n" % (filename, error))
+            sys.stderr.write('%s: %s (skipped)\n' % (filename, error))
     if to_reload:
         reload(host, port)
 
 def escape(s):
     for c in ['"', '`']:
-        s = s.replace(c, '\\' + c)
-    return '"' + s + '"'
+        s = s.replace(c, ''.join(('\\', c)))
+    return ''.join(('"', s, '"'))
 
 def install(filename, filetype, target, homedir):
     # check archive format
-    suffix = filename[-4:].lower()
-    if suffix in [".nar", ".zip"]:
-        archiver = "unzip -o %(f)s -d %(d)s"
-    elif suffix == ".lzh":
-        archiver = "lha xfw=%(d)s %(f)s"
+    if filename.lower().endswith('.nar') or \
+       filename.lower().endswith('.zip'):
+        archiver = 'unzip -o %(f)s -d %(d)s'
+    elif filename.lower().endswith('.lzh'):
+        archiver = 'lha xfw=%(d)s %(f)s'
     else:
-        fatal("unknown archive format")
+        fatal('unknown archive format')
     # extract files from the archive
-    tmpdir = tempfile.mktemp("ninix")
-    if not run("mkdir -p %s" % escape(tmpdir)):
-        fatal("cannot make temporary directory")
+    tmpdir = tempfile.mktemp('ninix')
+    if not run('mkdir -p %s' % escape(tmpdir)):
+        fatal('cannot make temporary directory')
     url = None
-    if filename[:5] == "http:" or filename[:4] == "ftp:":
+    if filename.startswith('http:') or filename.startswith('ftp:'):
         url = filename
         filename = download(filename, tmpdir)
         if filename is None:
-            os.system("rm -rf %s" % escape(tmpdir))
-            fatal("cannot download the archive file")
-    if not run(archiver % {"f": escape(filename), "d": escape(tmpdir)}):
-        os.system("rm -rf %s" % escape(tmpdir))
-        fatal("cannot extract files from the archive")
+            os.system('rm -rf %s' % escape(tmpdir))
+            fatal('cannot download the archive file')
+    if not run(archiver % {'f': escape(filename), 'd': escape(tmpdir)}):
+        os.system('rm -rf %s' % escape(tmpdir))
+        fatal('cannot extract files from the archive')
     if url and not mode & DOWNLOAD:
-        run("rm %s" % escape(filename))
-    os.system("find %s -type d -exec chmod u+rwx {} \\;" % escape(tmpdir))
-    os.system("find %s -type f -exec chmod u+rw  {} \\;" % escape(tmpdir))
+        run('rm %s' % escape(filename))
+    os.system('find %s -type d -exec chmod u+rwx {} \\;' % escape(tmpdir))
+    os.system('find %s -type f -exec chmod u+rw  {} \\;' % escape(tmpdir))
     rename_files(tmpdir)
     # check the file type (ghost, shell, balloon or supplement)
     error = None
     inst = ninix.home.read_install_txt(tmpdir)
     if inst:
-        guess = inst.get("type")
-        if guess == "ghost":
-            if os.path.exists(os.path.join(tmpdir, "ghost", "master")):
-                guess = "ghost.redo"
+        guess = inst.get('type')
+        if guess == 'ghost':
+            if os.path.exists(os.path.join(tmpdir, 'ghost', 'master')):
+                guess = 'ghost.redo'
             else:
-                guess = "ghost.inverse"
-        elif guess == "ghost with balloon":
-            guess = "ghost.inverse"
-        elif guess in ["shell", "shell with balloon"]:
-            if inst.has_key("accept"):
-                guess = "supplement"
+                guess = 'ghost.inverse'
+        elif guess == 'ghost with balloon':
+            guess = 'ghost.inverse'
+        elif guess in ['shell', 'shell with balloon']:
+            if inst.has_key('accept'):
+                guess = 'supplement'
             else:
-                guess = "shell.inverse"
-        elif guess == "skin":
-            guess = "nekoninni"
-        elif guess == "katochan":
-            guess = "katochan"
+                guess = 'shell.inverse'
+        elif guess == 'skin':
+            guess = 'nekoninni'
+        elif guess == 'katochan':
+            guess = 'katochan'
     else:
         guess = None
-        for f, t in [("ghost/master/", "ghost.redo"),
-                     ("shell/",        "shell.redo"),
-                     ("kawari.ini",    "ghost.inverse"),
-                     ("ai.txt",        "ghost.inverse"),
-                     ("ai.dtx",        "ghost.inverse"),
-                     ("surface/",      "shell.inverse"),
-                     ("balloons0.png", "balloon"),
-                     ("balloons0.jpg", "balloon"),
-                     ("plugin.txt",    "plugin"),
-                     ("kinoko.ini",    "kinoko")]:
+        for f, t in [('ghost/master/', 'ghost.redo'),
+                     ('shell/',        'shell.redo'),
+                     ('kawari.ini',    'ghost.inverse'),
+                     ('ai.txt',        'ghost.inverse'),
+                     ('ai.dtx',        'ghost.inverse'),
+                     ('surface/',      'shell.inverse'),
+                     ('balloons0.png', 'balloon'),
+                     ('balloons0.jpg', 'balloon'),
+                     ('plugin.txt',    'plugin'),
+                     ('kinoko.ini',    'kinoko')]:
             if os.path.exists(os.path.join(tmpdir, f)):
                 guess = t
                 break
     if filetype is None and guess is None:
-        error = "cannot guess the file type; use option -g, -s, -b, -P or -S"
+        error = 'cannot guess the file type; use option -g, -s, -b, -P or -S'
     elif filetype is None:
         filetype = guess
-    elif filetype == "ghost" and guess in ["ghost.redo", "ghost.inverse"]:
+    elif filetype == 'ghost' and guess in ['ghost.redo', 'ghost.inverse']:
         filetype = guess
-    elif filetype == "shell" and guess in ["ghost.redo", "shell.redo", "supplement"]:
-        filetype = "shell.redo"
-    elif filetype == "shell" and guess == "ghost.inverse":
-        filetype = "shell.inverse"
+    elif filetype == 'shell' and guess in ['ghost.redo', 'shell.redo',
+                                           'supplement']:
+        filetype = 'shell.redo'
+    elif filetype == 'shell' and guess == 'ghost.inverse':
+        filetype = 'shell.inverse'
     elif guess is not None and filetype != guess:
-        error = "wrong file type option; correct file type is " + guess
+        error = ''.join(('wrong file type option; correct file type is ',
+                         guess))
     try:
         if error is not None:
             fatal(error)
-        elif filetype == "ghost.redo":
+        elif filetype == 'ghost.redo':
             install_redo_ghost(filename, tmpdir, homedir)
-        elif filetype == "shell.redo":
+        elif filetype == 'shell.redo':
             install_redo_shell(filename, tmpdir, homedir)
-        elif filetype == "supplement":
+        elif filetype == 'supplement':
             install_redo_supplement(filename, tmpdir, homedir, target)
-        elif filetype == "ghost.inverse":
+        elif filetype == 'ghost.inverse':
             install_inverse_ghost(filename, tmpdir, homedir)
-        elif filetype == "shell.inverse":
+        elif filetype == 'shell.inverse':
             install_inverse_shell(filename, tmpdir, homedir)
-        elif filetype == "balloon":
+        elif filetype == 'balloon':
             install_balloon(filename, tmpdir, homedir)
-        elif filetype == "plugin":
+        elif filetype == 'plugin':
             install_plugin(filename, tmpdir, homedir)
-        elif filetype == "kinoko":
+        elif filetype == 'kinoko':
             install_kinoko(filename, tmpdir, homedir)
-        elif filetype == "nekoninni":
+        elif filetype == 'nekoninni':
             install_nekoninni(filename, tmpdir, homedir)
-        elif filetype == "katochan":
+        elif filetype == 'katochan':
             install_katochan(filename, tmpdir, homedir)
     finally:
-        run("rm -rf %s" % escape(tmpdir))
+        run('rm -rf %s' % escape(tmpdir))
+
 
 class URLopener(urllib.FancyURLopener):
-    version = "ninix/%s" % ninix.version.VERSION
+    version = 'ninix/%s' % ninix.version.VERSION
+
+
 urllib._urlopener = URLopener()
 
 def download(url, dir):
-    print "downloading", url
+    print 'downloading', url
     try:
         ifile = urllib.urlopen(url)
     except IOError:
         return None
     headers = ifile.info()
-    if headers.has_key("content-length"):
-        print "(size = %s bytes)" % headers.get("content-length")
+    if headers.has_key('content-length'):
+        print '(size = %s bytes)' % headers.get('content-length')
     if mode & DOWNLOAD:
         if not os.path.exists(arcdir):
-            run("mkdir -p %s" % escape(arcdir))
+            run('mkdir -p %s' % escape(arcdir))
         dir = arcdir
     filename = os.path.join(dir, os.path.basename(url))
     try:
-        ofile = open(filename, "w")
+        ofile = open(filename, 'w')
     except IOError:
         return None
     while 1:
@@ -320,14 +327,14 @@ def download(url, dir):
     ifile.close()
     ofile.close()
     # check the format of the downloaded file
-    suffix = filename[-4:].lower()
-    if suffix in [".nar", ".zip"]:
-        archiver = "unzip -t"
-    elif suffix == ".lzh":
-        archiver = "lha t"
+    if filename.lower().endswith('.nar') or \
+       filename.lower().endswith('.zip'):
+        archiver = 'unzip -t'
+    elif filename.lower().endswith('.lzh'):
+        archiver = 'lha t'
     else:
-        fatal("unknown archive format")
-    if os.system("%s %s >/dev/null 2>&1" % (archiver, escape(filename))):
+        fatal('unknown archive format')
+    if os.system('%s %s >/dev/null 2>&1' % (archiver, escape(filename))):
         return None
     return filename
 
@@ -361,7 +368,7 @@ def remove_files_and_dirs(mask, dir):
         if os.path.isdir(current_path):
             head, tail = os.path.split(current_path)
             if not tail in mask and not os.listdir(current_path):
-                run("rm -rf %s" % escape(current_path))
+                run('rm -rf %s' % escape(current_path))
 
 def remove_files(mask, dir, list):
     for name in list:
@@ -369,7 +376,7 @@ def remove_files(mask, dir, list):
         if os.path.isdir(path) or name in mask:
             pass
         else:
-            run("rm -f %s" % escape(path))
+            run('rm -f %s' % escape(path))
 
 def lower_files(dir):
     n = 0
@@ -378,7 +385,7 @@ def lower_files(dir):
         path = os.path.join(dir, filename2)
         if filename != filename2:
             os.rename(os.path.join(dir, filename), path)
-            print "renamed", os.path.join(dir, filename)
+            print 'renamed', os.path.join(dir, filename)
             n += 1
         if os.path.isdir(path):
             n += lower_files(path)
@@ -387,7 +394,7 @@ def lower_files(dir):
 def confirm_overwrite(path):
     if not mode & INTERACTIVE:
         return 1
-    print PROGRAM_NAME + ': overwrite "%s"? (yes/no)' % path
+    print ''.join((PROGRAM_NAME, ': overwrite "%s"? (yes/no)' % path))
     try:
         answer = raw_input()
     except EOFError:
@@ -396,12 +403,12 @@ def confirm_overwrite(path):
         sys.exit(1)
     if not answer:
         return 0
-    return answer[0].lower() == "y"
+    return answer.lower().startswith('y')
 
 def confirm_removal(path):
     if not mode & INTERACTIVE:
         return 1
-    print PROGRAM_NAME + ': remove "%s"? (yes/no)' % path
+    print ''.join((PROGRAM_NAME, ': remove "%s"? (yes/no)' % path))
     try:
         answer = raw_input()
     except EOFError:
@@ -410,93 +417,93 @@ def confirm_removal(path):
         sys.exit(1)
     if not answer:
         return 0
-    return answer[0].lower() == "y"
+    return answer.lower().startswith('y')
 
 def uninstall_plugin(homedir, name):
     try:
-        dirlist = os.listdir(os.path.join(homedir, "plugin"))
+        dirlist = os.listdir(os.path.join(homedir, 'plugin'))
     except OSError:
         return
     for subdir in dirlist:
-        path = os.path.join(homedir, "plugin", subdir)
+        path = os.path.join(homedir, 'plugin', subdir)
         plugin = ninix.home.read_plugin_txt(path)
         if plugin is None:
             continue
         plugin_name, plugin_dir, startup, menu_items = plugin
         if plugin_name == name:
-            plugin_dir = os.path.join(homedir, "plugin", subdir)
+            plugin_dir = os.path.join(homedir, 'plugin', subdir)
             if confirm_removal(plugin_dir):
-                run("rm -rf %s" % escape(plugin_dir))
+                run('rm -rf %s' % escape(plugin_dir))
 
 def install_redo_ghost(archive, tmpdir, homedir):
     global mode
     # find install.txt
     inst = ninix.home.read_install_txt(tmpdir)
     if inst is None:
-        fatal("install.txt not found")
-    dir = inst.get("directory")
+        fatal('install.txt not found')
+    dir = inst.get('directory')
     if dir is None:
-        fatal("\"directory\" not found in install.txt")
+        fatal('"directory" not found in install.txt')
     dir = dir.encode('utf-8')
-    prefix = os.path.join(homedir, "ghost", dir)
-    ghost_src = os.path.join(tmpdir, "ghost", "master")
-    shell_src = os.path.join(tmpdir, "shell")
-    ghost_dst = os.path.join(prefix, "ghost", "master")
-    shell_dst = os.path.join(prefix, "shell")
+    prefix = os.path.join(homedir, 'ghost', dir)
+    ghost_src = os.path.join(tmpdir, 'ghost', 'master')
+    shell_src = os.path.join(tmpdir, 'shell')
+    ghost_dst = os.path.join(prefix, 'ghost', 'master')
+    shell_dst = os.path.join(prefix, 'shell')
     filelist = []
-    filelist.append((os.path.join(tmpdir, "install.txt"),
-                     os.path.join(prefix, "install.txt")))
+    filelist.append((os.path.join(tmpdir, 'install.txt'),
+                     os.path.join(prefix, 'install.txt')))
     # find ghost/master/descript.txt
     desc = ninix.home.read_descript_txt(ghost_src)
     if desc:
-        filelist.append((os.path.join(ghost_src, "descript.txt"),
-                         os.path.join(ghost_dst, "descript.txt")))
+        filelist.append((os.path.join(ghost_src, 'descript.txt'),
+                         os.path.join(ghost_dst, 'descript.txt')))
     # find ghost/master/alias.txt
-    path = os.path.join(ghost_src, "alias.txt")
+    path = os.path.join(ghost_src, 'alias.txt')
     if os.path.exists(path):
-        filelist.append((path, os.path.join(ghost_dst, "alias.txt")))
+        filelist.append((path, os.path.join(ghost_dst, 'alias.txt')))
         aliases = ninix.alias.open(path)
     else:
         aliases = {}
     # find pseudo AI
     pseudo_ai = find_pseudo_ai(ghost_src, ghost_dst)
     if pseudo_ai is None:
-        fatal("pseudo AI not found - cannot be used as a ghost")
+        fatal('pseudo AI not found - cannot be used as a ghost')
     filelist.extend(pseudo_ai)
     # XXX: ad hoc work around for Mayura v3.10
-    path = os.path.join(ghost_src, "makotob.dll")
+    path = os.path.join(ghost_src, 'makotob.dll')
     if os.path.exists(path):
-        os.system("mv %s %s" % (escape(path),
-                                escape(os.path.join(ghost_src, "makoto.dll"))))
+        os.system('mv %s %s' % (escape(path),
+                                escape(os.path.join(ghost_src, 'makoto.dll'))))
     # find makoto.dll
-    for filename in aliases.get("makoto", ["makoto.dll"]):
+    for filename in aliases.get('makoto', ['makoto.dll']):
         path = os.path.join(ghost_src, filename)
         try:
             data = open(path).read()
         except IOError:
             continue
-        if data.find("Makoto Basic with Select and Repeat") > 0:
-            os.system("rm -f %s" % escape(path))
-            os.system("touch %s" % escape(path))
+        if data.find('Makoto Basic with Select and Repeat') > 0:
+            os.system('rm -f %s' % escape(path))
+            os.system('touch %s' % escape(path))
             filelist.append((path, os.path.join(ghost_dst, filename)))
     # find shell
     shell = find_redo_shell(shell_src, shell_dst)
     if shell:
         filelist.extend(shell)
     # find balloon
-    balloon_dir = inst and inst.get("balloon.directory")
+    balloon_dir = inst and inst.get('balloon.directory')
     if balloon_dir:
         balloon_dir = balloon_dir.encode('utf-8').lower()
         filelist.extend(find_balloon(os.path.join(tmpdir,    balloon_dir),
                                      os.path.join(ghost_dst, balloon_dir)))
     if os.path.exists(prefix):
         inst_dst = ninix.home.read_install_txt(prefix)
-        if not inst_dst or inst_dst.get("name") != inst.get("name"):
+        if not inst_dst or inst_dst.get('name') != inst.get('name'):
             mode |= INTERACTIVE
-        if inst.getint("refresh", 0):
+        if inst.getint('refresh', 0):
             # uninstall older versions of the ghost
             if confirm_removal(prefix):
-                mask = inst.get("refreshundeletemask", "").lower().split(':')
+                mask = inst.get('refreshundeletemask', '').lower().split(':')
                 mask.append('HISTORY')
                 remove_files_and_dirs(mask, prefix)
             else:
@@ -505,7 +512,7 @@ def install_redo_ghost(archive, tmpdir, homedir):
             if not confirm_overwrite(prefix):
                 return
     # install files
-    print "installing", archive, "(ghost)"
+    print 'installing', archive, '(ghost)'
     install_files(filelist)
 
 def install_redo_shell(archive, tmpdir, homedir):
@@ -513,42 +520,42 @@ def install_redo_shell(archive, tmpdir, homedir):
     # find install.txt
     inst = ninix.home.read_install_txt(tmpdir)
     if inst is None:
-        fatal("install.txt not found")
-    dir = inst.get("directory")
+        fatal('install.txt not found')
+    dir = inst.get('directory')
     if dir is None:
-        fatal("\"directory\" not found in install.txt")
+        fatal('"directory" not found in install.txt')
     dir = dir.encode('utf-8')
-    prefix = os.path.join(homedir, "ghost", dir)
-    ghost_src = os.path.join(tmpdir, "ghost", "master")
-    shell_src = os.path.join(tmpdir, "shell")
-    ghost_dst = os.path.join(prefix, "ghost", "master")
-    shell_dst = os.path.join(prefix, "shell")
+    prefix = os.path.join(homedir, 'ghost', dir)
+    ghost_src = os.path.join(tmpdir, 'ghost', 'master')
+    shell_src = os.path.join(tmpdir, 'shell')
+    ghost_dst = os.path.join(prefix, 'ghost', 'master')
+    shell_dst = os.path.join(prefix, 'shell')
     filelist = []
-    filelist.append((os.path.join(tmpdir, "install.txt"),
-                     os.path.join(prefix, "install.txt")))
+    filelist.append((os.path.join(tmpdir, 'install.txt'),
+                     os.path.join(prefix, 'install.txt')))
     # find ghost/master/descript.txt
     desc = ninix.home.read_descript_txt(ghost_src)
     if desc:
-        filelist.append((os.path.join(ghost_src, "descript.txt"),
-                         os.path.join(ghost_dst, "descript.txt")))
+        filelist.append((os.path.join(ghost_src, 'descript.txt'),
+                         os.path.join(ghost_dst, 'descript.txt')))
     # find shell
     shell = find_redo_shell(shell_src, shell_dst)
     if shell:
         filelist.extend(shell)
     # find balloon
-    balloon_dir = inst and inst.get("balloon.directory")
+    balloon_dir = inst and inst.get('balloon.directory')
     if balloon_dir:
         balloon_dir = balloon_dir.encode('utf-8').lower()
         filelist.extend(find_balloon(os.path.join(tmpdir,    balloon_dir),
                                      os.path.join(ghost_dst, balloon_dir)))
     if os.path.exists(prefix):
         inst_dst = ninix.home.read_install_txt(prefix)
-        if not inst_dst or inst_dst.get("name") != inst.get("name"):
+        if not inst_dst or inst_dst.get('name') != inst.get('name'):
             mode |= INTERACTIVE
-        if inst.getint("refresh", 0):
+        if inst.getint('refresh', 0):
             # uninstall older versions of the ghost
             if confirm_removal(prefix):
-                mask = inst.get("refreshundeletemask", "").lower().split(':')
+                mask = inst.get('refreshundeletemask', '').lower().split(':')
                 mask.append('HISTORY')
                 remove_files_and_dirs(mask, prefix)
             else:
@@ -557,56 +564,56 @@ def install_redo_shell(archive, tmpdir, homedir):
             if not confirm_overwrite(prefix):
                 return
     # install files
-    print "installing", archive, "(shell)"
+    print 'installing', archive, '(shell)'
     install_files(filelist)
 
 def install_redo_supplement(archive, tmpdir, homedir, target):
     inst = ninix.home.read_install_txt(tmpdir)
-    if inst and inst.has_key("accept"):
-        print "searching supplement target ...",
+    if inst and inst.has_key('accept'):
+        print 'searching supplement target ...',
         candidates = []
         try:
-            dirlist = os.listdir(os.path.join(homedir, "ghost"))
+            dirlist = os.listdir(os.path.join(homedir, 'ghost'))
         except OSError:
             dirlist = []
         for dirname in dirlist:
-            path = os.path.join(homedir, "ghost", dirname)
-            if os.path.exists(os.path.join(path, "shell", "surface.txt")):
+            path = os.path.join(homedir, 'ghost', dirname)
+            if os.path.exists(os.path.join(path, 'shell', 'surface.txt')):
                 continue
             desc = ninix.home.read_descript_txt(
-                os.path.join(path, "ghost", "master"))
-            if desc and desc.get("sakura.name") == inst.get("accept"):
+                os.path.join(path, 'ghost', 'master'))
+            if desc and desc.get('sakura.name') == inst.get('accept'):
                 candidates.append(dirname)
         if not candidates:
-            print "not found"
+            print 'not found'
         elif target and target not in candidates:
-            print '"%s" not found' % target
+            print "'%s' not found" % target
             return
         elif len(candidates) == 1 or target in candidates:
             if target:
-                path = os.path.join(homedir, "ghost", target)
+                path = os.path.join(homedir, 'ghost', target)
             else:
-                path = os.path.join(homedir, "ghost", candidates[0])
-            if inst.has_key("directory"):
-                if inst.get("type") == "shell":
-                    path = os.path.join(path, "shell", inst["directory"])
+                path = os.path.join(homedir, 'ghost', candidates[0])
+            if inst.has_key('directory'):
+                if inst.get('type') == 'shell':
+                    path = os.path.join(path, 'shell', inst['directory'])
                 else:
-                    if not inst.has_key("type"):
-                        print "supplement type not specified"
+                    if not inst.has_key('type'):
+                        print 'supplement type not specified'
                     else:
-                        print "unsupported supplement type:", inst["type"]
+                        print 'unsupported supplement type:', inst['type']
                     return
-            print "found"
+            print 'found'
             if not os.path.exists(path):
-                run("mkdir -p %s" % escape(path))
-            run("rm -f %s" % escape(os.path.join(tmpdir, "install.txt")))
-            run("cp -r %s/* %s" % (escape(tmpdir), escape(path)))
+                run('mkdir -p %s' % escape(path))
+            run('rm -f %s' % escape(os.path.join(tmpdir, 'install.txt')))
+            run('cp -r %s/* %s' % (escape(tmpdir), escape(path)))
             return
         else:
-            print "multiple candidates found"
+            print 'multiple candidates found'
             for candidate in candidates:
-                print "   ", candidate
-            fatal("try -S option with a target ghost name")
+                print '   ', candidate
+            fatal('try -S option with a target ghost name')
     # install supplement as a stand alone shell
     install_redo_shell(archive, tmpdir, homedir)
 
@@ -619,28 +626,32 @@ def find_redo_shell(srcdir, dstdir):
         shell_dst = os.path.join(dstdir, dirname)
         if not os.path.isdir(shell_src):
             continue
-        path = os.path.join(shell_src, "surfaces.txt")
+        path = os.path.join(shell_src, 'surfaces.txt')
         if os.path.exists(path):
-            filelist.append((path, os.path.join(shell_dst, "surfaces.txt")))
+            filelist.append((path, os.path.join(shell_dst, 'surfaces.txt')))
             for key, config in ninix.home.read_surfaces_txt(shell_src):
-                if key[:7] == "surface":
-                    for e in find_surface_elements(shell_src, shell_dst, config):
+                if key.startswith('surface'):
+                    for e in find_surface_elements(shell_src, shell_dst,
+                                                   config):
                         if e not in filelist:
                             filelist.append(e)
         desc = ninix.home.read_descript_txt(shell_src)
         if desc:
-            filelist.append((os.path.join(shell_src, "descript.txt"),
-                             os.path.join(shell_dst, "descript.txt")))
-            for name, default in [("readme", "readme.txt"),
-                                  ("menu.sidebar.bitmap.filename", "menu_sidebar.png"),
-                                  ("menu.background.bitmap.filename", "menu_background.png"),
-                                  ("menu.foreground.bitmap.filename", "menu_foreground.png")]:
+            filelist.append((os.path.join(shell_src, 'descript.txt'),
+                             os.path.join(shell_dst, 'descript.txt')))
+            for name, default in [('readme', 'readme.txt'),
+                                  ('menu.sidebar.bitmap.filename',
+                                   'menu_sidebar.png'),
+                                  ('menu.background.bitmap.filename',
+                                   'menu_background.png'),
+                                  ('menu.foreground.bitmap.filename',
+                                   'menu_foreground.png')]:
                 name = desc.get(name, default).replace('\\', '/')
                 name = name.encode('utf-8')
                 path = os.path.join(shell_src, name)
                 if os.path.exists(path):
                     filelist.append((path, os.path.join(shell_dst, name)))
-        for name in ["alias.txt", "thumbnail.png"]:
+        for name in ['alias.txt', 'thumbnail.png']:
             path = os.path.join(shell_src, name)
             if os.path.exists(path):
                 filelist.append((path, os.path.join(shell_dst, name)))
@@ -649,22 +660,23 @@ def find_redo_shell(srcdir, dstdir):
 
 def find_surface_elements(shell_src, shell_dst, config):
     filelist = []
-    for key, method, filename, x, y in ninix.home.list_surface_elements(config):
+    for key, method, filename, x, y in \
+            ninix.home.list_surface_elements(config):
         filename = filename.lower()
         path = os.path.join(shell_src, filename)
         basename, suffix = os.path.splitext(filename)
         if not os.path.exists(path):
-            path = os.path.join(shell_src, basename + '.dgp')
+            path = os.path.join(shell_src, ''.join((basename, '.dgp')))
             if os.path.exists(path):
-                filename = basename + '.dgp'
+                filename = ''.join((basename, '.dgp'))
             else:
-                print "%s file not found: %s" % (key, filename)
+                print '%s file not found: %s' % (key, filename)
                 continue
-        if suffix != ".png":
-            print "unsupported image format for %s: %s" % (key, filename)
+        if suffix != '.png':
+            print 'unsupported image format for %s: %s' % (key, filename)
             continue
         filelist.append((path, os.path.join(shell_dst, filename)))
-        filename = basename + '.pna'
+        filename = ''.join((basename, '.pna'))
         path = os.path.join(shell_src, filename)
         if os.path.exists(path):
             filelist.append((path, os.path.join(shell_dst, filename)))
@@ -675,56 +687,56 @@ def install_inverse_ghost(archive, tmpdir, homedir):
     # find install.txt
     inst = ninix.home.read_install_txt(tmpdir)
     if inst is None:
-        fatal("install.txt not found")
-    dir = inst.get("directory")
+        fatal('install.txt not found')
+    dir = inst.get('directory')
     if dir is None:
-        fatal("\"directory\" not found in install.txt")
+        fatal('"directory" not found in install.txt')
     dir = dir.encode('utf-8')
-    prefix = os.path.join(homedir, "ghost", dir)
-    ghost_dst = os.path.join(prefix, "ghost", "master")
-    shell_dst = os.path.join(prefix, "shell")
+    prefix = os.path.join(homedir, 'ghost', dir)
+    ghost_dst = os.path.join(prefix, 'ghost', 'master')
+    shell_dst = os.path.join(prefix, 'shell')
     filelist = []
-    filelist.append((os.path.join(tmpdir, "install.txt"),
-                     os.path.join(prefix, "install.txt")))
+    filelist.append((os.path.join(tmpdir, 'install.txt'),
+                     os.path.join(prefix, 'install.txt')))
     # find descript.txt
     desc = ninix.home.read_descript_txt(tmpdir)
     if desc:
-        filelist.append((os.path.join(tmpdir,    "descript.txt"),
-                         os.path.join(ghost_dst, "descript.txt")))
+        filelist.append((os.path.join(tmpdir,    'descript.txt'),
+                         os.path.join(ghost_dst, 'descript.txt')))
     # find pseudo AI dictionaries
     pseudo_ai = find_pseudo_ai(tmpdir, ghost_dst)
     if pseudo_ai is None:
-        fatal("pseudo AI not found - cannot be used as a ghost")
+        fatal('pseudo AI not found - cannot be used as a ghost')
     filelist.extend(pseudo_ai)
     # find makoto.dll
-    path = os.path.join(tmpdir, "makoto.dll")
+    path = os.path.join(tmpdir, 'makoto.dll')
     try:
         data = open(path).read()
     except IOError:
         pass
     else:
-        if data.find("Makoto Basic with Select and Repeat") > 0:
-            os.system("rm -f %s" % escape(path))
-            os.system("touch %s" % escape(path))
-            filelist.append((path, os.path.join(ghost_dst, "makoto.dll")))
+        if data.find('Makoto Basic with Select and Repeat') > 0:
+            os.system('rm -f %s' % escape(path))
+            os.system('touch %s' % escape(path))
+            filelist.append((path, os.path.join(ghost_dst, 'makoto.dll')))
     # find shell
     shell = find_inverse_shell(tmpdir, shell_dst)
     if shell:
         filelist.extend(shell)
     # find balloon
-    balloon_dir = inst and inst.get("balloon.directory")
+    balloon_dir = inst and inst.get('balloon.directory')
     if balloon_dir:
         balloon_dir = balloon_dir.encode('utf-8').lower()
         filelist.extend(find_balloon(os.path.join(tmpdir,    balloon_dir),
                                      os.path.join(ghost_dst, balloon_dir)))
     if os.path.exists(prefix):
         inst_dst = ninix.home.read_install_txt(prefix)
-        if not inst_dst or inst_dst.get("name") != inst.get("name"):
+        if not inst_dst or inst_dst.get('name') != inst.get('name'):
             mode |= INTERACTIVE
-        if inst.getint("refresh", 0):
+        if inst.getint('refresh', 0):
             # uninstall older versions of the ghost
             if confirm_removal(prefix):
-                mask = inst.get("refreshundeletemask", "").lower().split(':')
+                mask = inst.get('refreshundeletemask', '').lower().split(':')
                 mask.append('HISTORY')
                 remove_files_and_dirs(mask, prefix)
             else:
@@ -733,7 +745,7 @@ def install_inverse_ghost(archive, tmpdir, homedir):
             if not confirm_overwrite(prefix):
                 return
     # install files
-    print "installing", archive, "(ghost)"
+    print 'installing', archive, '(ghost)'
     install_files(filelist)
 
 def install_inverse_shell(archive, tmpdir, homedir):
@@ -741,40 +753,40 @@ def install_inverse_shell(archive, tmpdir, homedir):
     # find install.txt
     inst = ninix.home.read_install_txt(tmpdir)
     if inst is None:
-        fatal("install.txt not found")
-    dir = inst.get("directory")
+        fatal('install.txt not found')
+    dir = inst.get('directory')
     if dir is None:
-        fatal("\"directory\" not found in install.txt")
+        fatal('"directory" not found in install.txt')
     dir = dir.encode('utf-8')
-    prefix = os.path.join(homedir, "ghost", dir)
-    ghost_dst = os.path.join(prefix, "ghost", "master")
-    shell_dst = os.path.join(prefix, "shell")
+    prefix = os.path.join(homedir, 'ghost', dir)
+    ghost_dst = os.path.join(prefix, 'ghost', 'master')
+    shell_dst = os.path.join(prefix, 'shell')
     filelist = []
-    filelist.append((os.path.join(tmpdir, "install.txt"),
-                     os.path.join(prefix, "install.txt")))
+    filelist.append((os.path.join(tmpdir, 'install.txt'),
+                     os.path.join(prefix, 'install.txt')))
     # find descript.txt
     desc = ninix.home.read_descript_txt(tmpdir)
     if desc:
-        filelist.append((os.path.join(tmpdir,    "descript.txt"),
-                         os.path.join(ghost_dst, "descript.txt")))
+        filelist.append((os.path.join(tmpdir,    'descript.txt'),
+                         os.path.join(ghost_dst, 'descript.txt')))
     # find shell
     shell = find_inverse_shell(tmpdir, shell_dst)
     if shell:
         filelist.extend(shell)
     # find balloon
-    balloon_dir = inst and inst.get("balloon.directory")
+    balloon_dir = inst and inst.get('balloon.directory')
     if balloon_dir:
         balloon_dir = balloon_dir.encode('utf-8').lower()
         filelist.extend(find_balloon(os.path.join(tmpdir,    balloon_dir),
                                      os.path.join(ghost_dst, balloon_dir)))
     if os.path.exists(prefix):
         inst_dst = ninix.home.read_install_txt(prefix)
-        if not inst_dst or inst_dst.get("name") != inst.get("name"):
+        if not inst_dst or inst_dst.get('name') != inst.get('name'):
             mode |= INTERACTIVE
-        if inst.getint("refresh", 0):
+        if inst.getint('refresh', 0):
             # uninstall older versions of the shell
             if confirm_removal(prefix):
-                mask = inst.get("refreshundeletemask", "").lower().split(':')
+                mask = inst.get('refreshundeletemask', '').lower().split(':')
                 mask.append('HISTORY')
                 remove_files_and_dirs(mask, prefix)
             else:
@@ -783,33 +795,33 @@ def install_inverse_shell(archive, tmpdir, homedir):
             if not confirm_overwrite(prefix):
                 return
     # install files
-    print "installing", archive, "(shell)"
+    print 'installing', archive, '(shell)'
     install_files(filelist)
 
 def find_inverse_shell(srcdir, dstdir):
     filelist = []
     # find descript.txt
-    path = os.path.join(srcdir, "descript.txt")    
+    path = os.path.join(srcdir, 'descript.txt')    
     if os.path.exists(path):
         descript_txt = path
     else:
         descript_txt = None
     # find alias.txt
-    path = os.path.join(srcdir, "alias.txt")
+    path = os.path.join(srcdir, 'alias.txt')
     if os.path.exists(path):
         alias_txt = path
     else:
         alias_txt = None
     # find surface sets
     dirlist = []
-    path = os.path.join(srcdir, "surface.txt")
+    path = os.path.join(srcdir, 'surface.txt')
     if os.path.exists(path):
-        filelist.append((path, os.path.join(dstdir, "surface.txt")))
+        filelist.append((path, os.path.join(dstdir, 'surface.txt')))
         config = ninix.config.open(path)
         for name, subdir in config.itemlist:
             dirlist.append((name, subdir.lower()))
     else:
-        dirlist.append((None, "surface"))
+        dirlist.append((None, 'surface'))
     for name, subdir in dirlist:
         shell_src = os.path.join(srcdir, subdir)
         shell_dst = os.path.join(dstdir, subdir)
@@ -818,11 +830,11 @@ def find_inverse_shell(srcdir, dstdir):
         if descript_txt:
             # make a copy
             filelist.append((descript_txt,
-                             os.path.join(shell_dst, "descript.txt")))
+                             os.path.join(shell_dst, 'descript.txt')))
         if alias_txt:
             # make a copy
             filelist.append((alias_txt,
-                             os.path.join(shell_dst, "alias.txt")))
+                             os.path.join(shell_dst, 'alias.txt')))
         filelist.extend(find_surface_set(shell_src, shell_dst))
     return filelist
 
@@ -832,28 +844,28 @@ def install_balloon(archive, srcdir, homedir):
     # find install.txt
     inst = ninix.home.read_install_txt(srcdir)
     if inst is None:
-        fatal("install.txt not found")
-    #dstdir = os.path.join(homedir, "balloon", os.path.basename(archive)[:-4])
-    dir = inst.get("directory")
+        fatal('install.txt not found')
+    #dstdir = os.path.join(homedir, 'balloon', os.path.basename(archive)[:-4])
+    dir = inst.get('directory')
     if dir is None:
-        fatal("\"directory\" not found in install.txt")
+        fatal('"directory" not found in install.txt')
     dir = dir.encode('utf-8')
-    dstdir = os.path.join(homedir, "balloon", dir)
+    dstdir = os.path.join(homedir, 'balloon', dir)
     # find balloon
     balloon = find_balloon(srcdir, dstdir)
     if not balloon:
-        fatal("balloon not found")
+        fatal('balloon not found')
     filelist.extend(balloon)
-    filelist.append((os.path.join(srcdir, "install.txt"),
-                     os.path.join(dstdir, "install.txt")))
+    filelist.append((os.path.join(srcdir, 'install.txt'),
+                     os.path.join(dstdir, 'install.txt')))
     if os.path.exists(dstdir):
         inst_dst = ninix.home.read_install_txt(dstdir)
-        if not inst_dst or inst_dst.get("name") != inst.get("name"):
+        if not inst_dst or inst_dst.get('name') != inst.get('name'):
             mode |= INTERACTIVE
-        if inst.getint("refresh", 0):
+        if inst.getint('refresh', 0):
             # uninstall older versions of the balloon
             if confirm_removal(dstdir):
-                mask = inst.get("refreshundeletemask", "").lower().split(':')
+                mask = inst.get('refreshundeletemask', '').lower().split(':')
                 remove_files_and_dirs(mask, dstdir)
             else:
                 return
@@ -861,16 +873,16 @@ def install_balloon(archive, srcdir, homedir):
             if not confirm_overwrite(dstdir):
                 return
     # install files
-    print "installing", archive, "(balloon)"
+    print 'installing', archive, '(balloon)'
     install_files(filelist)
 
 def install_plugin(archive, srcdir, homedir):
     filelist = []
-    dstdir = os.path.join(homedir, "plugin", os.path.basename(archive)[:-4])
+    dstdir = os.path.join(homedir, 'plugin', os.path.basename(archive)[:-4])
     # find plugin.txt
     plugin = ninix.home.read_plugin_txt(srcdir)
     if plugin is None:
-        fatal("failed to read plugin.txt")
+        fatal('failed to read plugin.txt')
     plugin_name, plugin_dir, startup, menu_items = plugin
     # find files
     for filename in os.listdir(srcdir):
@@ -880,36 +892,38 @@ def install_plugin(archive, srcdir, homedir):
     # uninstall older versions of the plugin
     uninstall_plugin(homedir, plugin_name)
     # install files
-    print "installing", archive, "(plugin)"
+    print 'installing', archive, '(plugin)'
     install_files(filelist)
 
 def uninstall_kinoko(homedir, name):
     try:
-        dirlist = os.listdir(os.path.join(homedir, "kinoko"))
+        dirlist = os.listdir(os.path.join(homedir, 'kinoko'))
     except OSError:
         return
     for subdir in dirlist:
-        path = os.path.join(homedir, "kinoko", subdir)
+        path = os.path.join(homedir, 'kinoko', subdir)
         kinoko = ninix.home.read_kinoko_ini(path)
         if kinoko is None:
             continue
         kinoko_name = kinoko['title']
         if kinoko_name == name:
-            kinoko_dir = os.path.join(homedir, "kinoko", subdir)
+            kinoko_dir = os.path.join(homedir, 'kinoko', subdir)
             if confirm_removal(kinoko_dir):
-                run("rm -rf %s" % escape(kinoko_dir))
+                run('rm -rf %s' % escape(kinoko_dir))
 
 def install_kinoko(archive, srcdir, homedir):
     filelist = []
     # find kinoko.ini
     kinoko = ninix.home.read_kinoko_ini(srcdir)
     if kinoko is None:
-        fatal("failed to read kinoko.ini")
+        fatal('failed to read kinoko.ini')
     kinoko_name = kinoko['title']
     if kinoko['extractpath'] is not None:
-        dstdir = os.path.join(homedir, "kinoko", kinoko['extractpath'].encode('utf-8', 'ignore'))
+        dstdir = os.path.join(
+            homedir, 'kinoko', kinoko['extractpath'].encode('utf-8', 'ignore'))
     else:
-        dstdir = os.path.join(homedir, "kinoko", os.path.basename(archive)[:-4])
+        dstdir = os.path.join(
+            homedir, 'kinoko', os.path.basename(archive)[:-4])
     # find files
     for filename in os.listdir(srcdir):
         path = os.path.join(srcdir, filename)
@@ -918,15 +932,15 @@ def install_kinoko(archive, srcdir, homedir):
     # uninstall older versions of the kinoko
     uninstall_kinoko(homedir, kinoko_name)
     # install files
-    print "installing", archive, "(kinoko)"
+    print 'installing', archive, '(kinoko)'
     install_files(filelist)
 
 def uninstall_nekoninni(homedir, dir):
-    nekoninni_dir = os.path.join(homedir, "nekodorif", "skin", dir)
+    nekoninni_dir = os.path.join(homedir, 'nekodorif', 'skin', dir)
     if not os.path.exists(nekoninni_dir):
         return
     if confirm_removal(nekoninni_dir):
-        run("rm -rf %s" % escape(nekoninni_dir))
+        run('rm -rf %s' % escape(nekoninni_dir))
 
 def install_nekoninni(archive, srcdir, homedir):
     global mode
@@ -934,12 +948,12 @@ def install_nekoninni(archive, srcdir, homedir):
     # find install.txt
     inst = ninix.home.read_install_txt(srcdir)
     if inst is None:
-        fatal("install.txt not found")
-    dir = inst.get("directory")
+        fatal('install.txt not found')
+    dir = inst.get('directory')
     if dir is None:
-        fatal("\"directory\" not found in install.txt")
+        fatal('"directory" not found in install.txt')
     dir = dir.encode('utf-8')
-    dstdir = os.path.join(homedir, "nekodorif", "skin", dir)
+    dstdir = os.path.join(homedir, 'nekodorif', 'skin', dir)
     # find files
     for filename in os.listdir(srcdir):
         path = os.path.join(srcdir, filename)
@@ -948,15 +962,15 @@ def install_nekoninni(archive, srcdir, homedir):
     # uninstall older versions of the skin
     uninstall_nekoninni(homedir, dir)
     # install files
-    print "installing", archive, "(nekodorif skin)"
+    print 'installing', archive, '(nekodorif skin)'
     install_files(filelist)
 
 def uninstall_katochan(homedir, dir):
-    katochan_dir = os.path.join(homedir, "nekodorif", "katochan", dir)
+    katochan_dir = os.path.join(homedir, 'nekodorif', 'katochan', dir)
     if not os.path.exists(katochan_dir):
         return
     if confirm_removal(katochan_dir):
-        run("rm -rf %s" % escape(katochan_dir))
+        run('rm -rf %s' % escape(katochan_dir))
 
 def install_katochan(archive, srcdir, homedir):
     global mode
@@ -964,12 +978,12 @@ def install_katochan(archive, srcdir, homedir):
     # find install.txt
     inst = ninix.home.read_install_txt(srcdir)
     if inst is None:
-        fatal("install.txt not found")
-    dir = inst.get("directory")
+        fatal('install.txt not found')
+    dir = inst.get('directory')
     if dir is None:
-        fatal("\"directory\" not found in install.txt")
+        fatal('"directory" not found in install.txt')
     dir = dir.encode('utf-8')
-    dstdir = os.path.join(homedir, "nekodorif", "katochan", dir)
+    dstdir = os.path.join(homedir, 'nekodorif', 'katochan', dir)
     # find files
     for filename in os.listdir(srcdir):
         path = os.path.join(srcdir, filename)
@@ -978,7 +992,7 @@ def install_katochan(archive, srcdir, homedir):
     # uninstall older versions of the skin
     uninstall_katochan(homedir, dir)
     # install files
-    print "installing", archive, "(nekodorif katochan)"
+    print 'installing', archive, '(nekodorif katochan)'
     install_files(filelist)
 
 def list_all_files(top, dir):
@@ -998,16 +1012,16 @@ def find_pseudo_ai(srcdir, dstdir): # redo, inverse
                          os.path.join(dstdir, path)))
     return filelist
 
-re_surface_img = re.compile(r"surface[0-9]+\.(png|dgp|pna)")
-re_surface_txt = re.compile(r"surface[0-9]+[sa]\.txt")
+re_surface_img = re.compile(r'surface[0-9]+\.(png|dgp|pna)')
+re_surface_txt = re.compile(r'surface[0-9]+[sa]\.txt')
 
 def find_surface_set(srcdir, dstdir):
     filename_alias = {}
-    path = os.path.join(srcdir, "alias.txt")
+    path = os.path.join(srcdir, 'alias.txt')
     if os.path.exists(path):
         dict = ninix.alias.open(path)
         for basename, alias in dict.items():
-            if basename[:7] == "surface":
+            if basename.startswith('surface'):
                 filename_alias[alias] = basename
     filelist = []
     for filename in os.listdir(srcdir):
@@ -1020,33 +1034,34 @@ def find_surface_set(srcdir, dstdir):
                              os.path.join(dstdir, filename)))
             continue
         basename, suffix = os.path.splitext(filename)
-        if not (filename_alias.has_key(basename) and suffix in [".png", ".dgp", ".pna"]):
+        if not (filename_alias.has_key(basename) and suffix in \
+                ['.png', '.dgp', '.pna']):
             continue
         filelist.append((os.path.join(srcdir, filename),
                          os.path.join(dstdir, filename)))
-        for suffix in ["s.txt", "a.txt"]:
-            filename = basename + suffix
+        for suffix in ['s.txt', 'a.txt']:
+            filename = ''.join((basename, suffix))
             if os.path.exists(os.path.join(srcdir, filename)):
                 filelist.append((os.path.join(srcdir, filename),
                                  os.path.join(dstdir, filename)))
     return filelist
 
-re_balloon_img = re.compile(r"(balloon[skc][0-9]+|arrow[01]|sstp|online[0-9]+)\.(png|pna)")
-re_balloon_txt = re.compile(r"balloon[sk][0-9]+s\.txt")
+re_balloon_img = re.compile(r'(balloon[skc][0-9]+|arrow[01]|sstp|online[0-9]+)\.(png|pna)')
+re_balloon_txt = re.compile(r'balloon[sk][0-9]+s\.txt')
 
 def find_balloon(srcdir, dstdir): # redo, inverse
     filelist = []
     if not os.path.exists(srcdir):
         return filelist
-    path = os.path.join(srcdir, "descript.txt")
+    path = os.path.join(srcdir, 'descript.txt')
     if os.path.exists(path):
-        filelist.append((path, os.path.join(dstdir, "descript.txt")))
+        filelist.append((path, os.path.join(dstdir, 'descript.txt')))
     for filename in os.listdir(srcdir):
         if re_balloon_img.match(filename):
             basename, suffix = os.path.splitext(filename)
             filelist.append((
                 os.path.join(srcdir, filename),
-                os.path.join(dstdir, basename + suffix)))
+                os.path.join(dstdir, ''.join((basename, suffix)))))
         elif re_balloon_txt.match(filename):
             filelist.append((
                 os.path.join(srcdir, filename),
@@ -1057,8 +1072,8 @@ def install_files(filelist):
     for from_path, to_path in filelist:
         dirname, filename = os.path.split(to_path)
         if not os.path.exists(dirname):
-            run("mkdir -p %s" % escape(dirname))
-        run("cp %s %s" % (escape(from_path), escape(to_path)))
+            run('mkdir -p %s' % escape(dirname))
+        run('cp %s %s' % (escape(from_path), escape(to_path)))
 
 def reload(host, port):
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
@@ -1066,17 +1081,17 @@ def reload(host, port):
         s.connect((host, port))
     except socket.error:
         return
-    s.send("EXECUTE SSTP/1.5\r\n"
-           "Command: Reload\r\n"
-           "Sender: ninix-aya/%s\r\n"
-           "\r\n" % ninix.version.VERSION)
+    s.send('EXECUTE SSTP/1.5\r\n'
+           'Command: Reload\r\n'
+           'Sender: ninix-aya/%s\r\n'
+           '\r\n' % ninix.version.VERSION)
     s.recv(1024)
     s.close()
 
 def run(command):
     print command
     if os.system(command):
-        print "***FAILED***"
+        print '***FAILED***'
         return 0
     return 1
 
@@ -1087,5 +1102,5 @@ def readable(path):
         return 0
     return 1
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     main()
index 471e27a..b60e561 100755 (executable)
@@ -4,7 +4,7 @@
 #  ninix-update.py - a command-line network update utility for ninix
 #  Copyright (C) 2001, 2002 by Tamito KAJIYAMA
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
-#  Copyright (C) 2002-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
@@ -13,7 +13,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-#  $Id: ninix-update.py,v 1.13 2004/11/24 02:36:37 shy Exp $
+#  $Id: ninix-update.py,v 1.14 2005/08/09 00:41:52 shy Exp $
 #
 
 import getopt
@@ -26,16 +26,16 @@ import codecs
 import locale
 locale.setlocale(locale.LC_ALL, '')
 
-if os.environ.has_key("DISPLAY"):
-    del os.environ["DISPLAY"]
+if os.environ.has_key('DISPLAY'):
+    del os.environ['DISPLAY']
 
 import ninix.home
 import ninix.update
 import ninix.dll
 
-PROGRAM_NAME = os.environ.get("NINIX_UPDATE", sys.argv[0])
+PROGRAM_NAME = os.environ.get('NINIX_UPDATE', sys.argv[0])
 
-USAGE = """\
+USAGE = '''\
 Usage: %s [options] [URL] [directory]
 Options:
   -l, --list          show a list of ghosts
@@ -44,7 +44,7 @@ Options:
   -T, --tempdir DIR   temporary directory (default: /usr/tmp)
   -q, --quiet         suppress most messages
   -h, --help          show this message
-"""
+'''
 
 def usage():
     sys.stderr.write(USAGE % os.path.basename(PROGRAM_NAME))
@@ -52,25 +52,25 @@ def usage():
 
 def main():
     try:
-        options, argv = getopt.getopt(sys.argv[1:], "lsH:T:qh",
-            ["list", "script", "homedir=", "tempdir=", "quiet", "help"])
+        options, argv = getopt.getopt(sys.argv[1:], 'lsH:T:qh',
+            ['list', 'script', 'homedir=', 'tempdir=', 'quiet', 'help'])
     except getopt.error, e:
-        sys.stderr.write("Error: %s\n" % str(e))
+        sys.stderr.write('Error: %s\n' % str(e))
         usage()
     list = script = 0
-    homedir = os.environ.get("NINIX_HOME")
+    homedir = os.environ.get('NINIX_HOME')
     tempdir = None
     quiet = 0
     for opt, val in options:
-        if opt in ["-l", "--list"]:
+        if opt in ['-l', '--list']:
             list = 1
-        elif opt in ["-s", "--script"]:
+        elif opt in ['-s', '--script']:
             list = script = 1
-        elif opt in ["-H", "--homedir"]:
+        elif opt in ['-H', '--homedir']:
             homedir = val
-        elif opt in ["-T", "--tempdir"]:
+        elif opt in ['-T', '--tempdir']:
             tempdir = val
-        elif opt in ["-q", "--quiet"]:
+        elif opt in ['-q', '--quiet']:
             quiet = 1
         else:
             usage()
@@ -86,23 +86,24 @@ def main():
         usage()
         
 def list_ghosts(script):
-    sys.stderr.write("Searching ghosts...\n")
+    sys.stderr.write('Searching ghosts...\n')
     config = ninix.home.load_config()
     if config is None:
-        sys.stderr.write("Error: ninix home not found\n")
+        sys.stderr.write('Error: ninix home not found\n')
         sys.exit(1)
     ghosts, shells, balloons, plugins, nekoninni, katochan, kinoko = config
     found = 0
     default_path = os.path.join(sys.path[0], 'ninix', 'dll')
     saori_lib = ninix.dll.Library('saori', default_path, ghost=None)
     dll = ninix.dll.Library('shiori', default_path, saori_lib=saori_lib)
-    for desc, shiori_dir, use_makoto, surface_set, balloon, prefix, shiori_dll, shiori_name in ghosts:
+    for desc, shiori_dir, use_makoto, surface_set, \
+        balloon, prefix, shiori_dll, shiori_name in ghosts:
         name = (shiori_dll, shiori_name)
         homeurl = ''
         shiori = dll.request(name)
         if shiori and shiori.load(shiori_dir):
             if getattr(shiori, 'is_oldtype', None):
-                homeurl = shiori.getstring("homeurl")
+                homeurl = shiori.getstring('homeurl')
                 shiori.finalize()
             else:
                 response = shiori.request('GET SHIORI/3.0\n' \
@@ -116,21 +117,24 @@ def list_ghosts(script):
             continue
         if script:
             if not found:
-                print "#!/bin/sh"
-            print "echo " + "-" * 60
-            print "echo 'Ghost: %s'" % desc.get("name", "").encode('utf-8', 'ignore')
+                print '#!/bin/sh'
+            print ''.join(('echo ', '-' * 60))
+            print "echo 'Ghost: %s'" % \
+                  desc.get('name', '').encode('utf-8', 'ignore')
             print "echo 'Home URL: %s'" % homeurl
             print "echo 'Directory: %s'" % prefix
             print PROGRAM_NAME, homeurl, prefix
         else:
-            print "-" * 60
-            print "Ghost:", desc.get("name", "").encode('utf-8', 'ignore')
-            print "(%s,%s)" % (desc.get("sakura.name", "").encode('utf-8', 'ignore'), desc.get("kero.name", "").encode('utf-8', 'ignore'))
-            print "Home URL:", homeurl
-            print "Directory:", prefix
+            print '-' * 60
+            print 'Ghost:', desc.get('name', '').encode('utf-8', 'ignore')
+            print '(%s,%s)' % \
+                  (desc.get('sakura.name', '').encode('utf-8', 'ignore'),
+                   desc.get('kero.name', '').encode('utf-8', 'ignore'))
+            print 'Home URL:', homeurl
+            print 'Directory:', prefix
         found = 1
     if not found:
-        sys.stderr.write("No ghost found\n")
+        sys.stderr.write('No ghost found\n')
 
 def get_value(response):
     header = StringIO.StringIO(response)
@@ -139,7 +143,7 @@ def get_value(response):
         line = header.readline()
         if not line:
             break # EOF
-        if line[-1] == '\n':
+        if line.endswith('\n'):
             line = line[:-1]
         line = line.strip()
         if not line:
@@ -147,7 +151,7 @@ def get_value(response):
         colon = line.find(':')
         if colon >= 0:
             key = line[:colon].strip()
-            result[key] = line[colon+1:].strip()
+            result[key] = line[colon + 1:].strip()
         else:
             continue
     if result.has_key('Charset'):
@@ -155,7 +159,7 @@ def get_value(response):
         try:
             codecs.lookup(charset)
         except:
-            sys.stderr.write("Unsupported charset %s" % repr(charset))
+            sys.stderr.write('Unsupported charset %s' % repr(charset))
         else:
             for key in result.keys():
                 result[key] = unicode(result[key], charset, 'ignore')
@@ -166,7 +170,7 @@ def get_value(response):
 
 def update_ghost(homeurl, ghostdir, quiet):
     if not os.path.exists(os.path.expanduser(ghostdir)):
-        sys.stderr.write("Error: %s not found\n" % ghostdir)
+        sys.stderr.write('Error: %s not found\n' % ghostdir)
         sys.exit(1)
     updateman = ninix.update.NetworkUpdate(None)
     updateman.start(homeurl, ghostdir, timeout=60)
@@ -178,22 +182,22 @@ def update_ghost(homeurl, ghostdir, quiet):
                 break
             if quiet:
                 continue
-            elif event[0] in ["OnUpdateBegin",
-                              "OnUpdate.OnMD5CompareComplete",
-                              "OnUpdate.OnMD5CompareFailure"]:
+            elif event[0] in ['OnUpdateBegin',
+                              'OnUpdate.OnMD5CompareComplete',
+                              'OnUpdate.OnMD5CompareFailure']:
                 print event[0]
-            elif event[0] in ["OnUpdateReady",
-                              "OnUpdateComplete",
-                              "OnUpdateFailure",
-                              "OnUpdate.OnDownloadBegin"]:
-                print "%s (%s)" % event[:2]
+            elif event[0] in ['OnUpdateReady',
+                              'OnUpdateComplete',
+                              'OnUpdateFailure',
+                              'OnUpdate.OnDownloadBegin']:
+                print '%s (%s)' % event[:2]
         if code == 0:
             break
         if updateman.state == 5 and updateman.schedule:
-            print "File(s) to be updated:"
+            print 'File(s) to be updated:'
             for filename, checksum in updateman.schedule:
-                print "   ", filename
+                print '   ', filename
     updateman.stop()
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     main()
index 6eb7c92..2129643 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: ascii -*-
 #
 #  Copyright (C) 2001, 2002 by Tamito KAJIYAMA
-#  Copyright (C) 2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2004, 2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
@@ -10,7 +10,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: alias.py,v 1.6 2004/04/13 05:21:59 shy Exp $
+# $Id: alias.py,v 1.7 2005/08/09 00:41:52 shy Exp $
 #
 
 import sys
@@ -20,10 +20,10 @@ import ninix.config
 builtin_open = open
 
 def print_error(message):
-    sys.stderr.write(message + "\n")
+    sys.stderr.write(''.join((message, '\n')))
 
 def fatal(error):
-    print_error("alias.py: %s" % str(error))
+    print_error('alias.py: %s' % str(error))
     return ninix.config.null_config()
 
 def open(path):
@@ -42,7 +42,7 @@ def new_alias(buffer):
     while i < j:
         line = buffer[i]
         i += 1
-        if line in ["sakura.surface.alias", "kero.surface.alias"]:
+        if line in ['sakura.surface.alias', 'kero.surface.alias']:
             name = line
             table = {}
             try:
@@ -51,30 +51,31 @@ def new_alias(buffer):
                         line = buffer[i]
                         i += 1
                     else:
-                        raise ValueError, "unexpedted end of file"
-                    line = line.replace("\x81\x40", "").strip()
+                        raise ValueError, 'unexpedted end of file'
+                    line = line.replace('\x81\x40', '').strip()
                     if not line:
                         continue
-                    elif line == "{":
+                    elif line == '{':
                         break
-                    raise ValueError, "open brace not found"
+                    raise ValueError, 'open brace not found'
                 while 1:
                     if i < j:
                         line = buffer[i]
                         i += 1
                     else:
-                        raise ValueError, "unexpected end of file"
-                    line = line.replace("\x81\x40", "").strip()
+                        raise ValueError, 'unexpected end of file'
+                    line = line.replace('\x81\x40', '').strip()
                     if not line:
                         continue
-                    elif line == "}":
+                    elif line == '}':
                         break
                     line = line.split(',', 1)
                     if len(line) == 2:
                         key, values = [s.strip() for s in line]
                     else:
-                        raise ValueError, "malformed line found"
-                    if values and values[0] == "[" and values[-1] == "]":
+                        raise ValueError, 'malformed line found'
+                    if values and \
+                       values.startswith('[') and values.endswith(']'):
                         table[key] = []
                         for value in values[1:-1].split(','):
                             try:
@@ -83,7 +84,7 @@ def new_alias(buffer):
                                 pass
                             table[key].append(value)
                     else:
-                        raise ValueError, "malformed line found"
+                        raise ValueError, 'malformed line found'
             except ValueError, error:
                 return fatal(error)
             dict[name] = table
@@ -92,9 +93,10 @@ def new_alias(buffer):
             if len(line) == 2:
                 key, value = [s.strip() for s in line]
             else:
-                return fatal("malformed line found")
-            if key == "makoto":
-                if value and value[0] == "[" and value[-1] == "]":
+                return fatal('malformed line found')
+            if key == 'makoto':
+                if value and \
+                   value.startswith('[') and value.endswith(']'):
                     value = value[1:-1].split(',')
                 else:
                     value = [value]
@@ -102,6 +104,6 @@ def new_alias(buffer):
     return dict
 
 # test
-if __name__ == "__main__":
+if __name__ == '__main__':
     import sys
     print open(sys.argv[1])
index 7a8ccf2..65ba7a5 100644 (file)
@@ -16,7 +16,7 @@
 import os
 import sys
 
-if os.environ.has_key("DISPLAY"):
+if os.environ.has_key('DISPLAY'):
     import gtk
     import gobject
     import pango
@@ -25,6 +25,7 @@ import ninix.home
 
 import pix
 
+
 class Balloon:
 
     def __init__(self, sakura, debug=0):
@@ -101,7 +102,7 @@ class Balloon:
         window.set_skip_pager_hint(False)
         window.set_skip_taskbar_hint(False)
         window.font_name = self.font_name
-        window.connect("delete_event", self.delete)
+        window.connect('delete_event', self.delete)
         window.realize()
         return window
 
@@ -126,31 +127,31 @@ class Balloon:
         communicate2 = None
         communicate3 = None
         for key, value in balloon.items():
-            if key in ["arrow0", "arrow1"]:
+            if key in ['arrow0', 'arrow1']:
                 balloon0[key] = value
                 balloon1[key] = value
-            elif key == "sstp":
+            elif key == 'sstp':
                 balloon0[key] = value  # sstp marker
-            elif key[0] == "s":
+            elif key.startswith('s'):
                 balloon0[key] = value  # Sakura
-            elif key[0] == "k":
+            elif key.startswith('k'):
                 balloon1[key] = value  # Unyuu
-            elif key == "c0":
+            elif key == 'c0':
                 communicate0 = value # send box
-            elif key == "c1":
+            elif key == 'c1':
                 communicate1 = value # communicate box
-            elif key == "c2":
+            elif key == 'c2':
                 communicate2 = value # teach box
-            elif key == "c3":
+            elif key == 'c3':
                 communicate3 = value # input box
         self.balloon1 = balloon1 ## FIXME
         # create balloon windows
         for balloon_window in self.window:
             balloon_window.destroy()
         self.window = []
-        for name, side, id_format, balloon in [("sakura", 0, "s%d", balloon0),
-                                               ("kero", 1, "k%d", balloon1)]:
-            gtk_window = self.create_gtk_window('balloon.' + name)
+        for name, side, id_format, balloon in [('sakura', 0, 's%d', balloon0),
+                                               ('kero', 1, 'k%d', balloon1)]:
+            gtk_window = self.create_gtk_window(''.join(('balloon.', name)))
             balloon_window = BalloonWindow(
                 gtk_window, side, self.sakura, desc, balloon,
                 id_format, self.__use_pna, self.__alpha_channel, self.debug)
@@ -167,7 +168,7 @@ class Balloon:
     def add_window(self, side):
         assert side >= 2 and len(self.window) == side ## FIXME
         gtk_window = self.create_gtk_window('balloon.char%d' % side)
-        id_format = "k%d"
+        id_format = 'k%d'
         balloon = self.balloon1 ## FIXME
         balloon_window = BalloonWindow(
             gtk_window, side, self.sakura, self.desc, balloon,
@@ -189,7 +190,7 @@ class Balloon:
             window.redraw()
 
     def get_balloon_name(self):
-        return self.desc.get("name", "")
+        return self.desc.get('name', '')
 
     def get_balloon_size(self, side):
         if len(self.window) > side:
@@ -293,7 +294,8 @@ class Balloon:
         if self.synchronized:
             for side in self.synchronized:
                 if len(self.window) > side:
-                    self.window[side].append_link(label, value, newline_required)
+                    self.window[side].append_link(label, value,
+                                                  newline_required)
         else:
             if len(self.window) > side:
                 self.window[side].append_link(label, value, newline_required)
@@ -350,7 +352,8 @@ class BalloonWindow:
                 pixbuf = pix.create_pixbuf_from_file(path)
             except:
                 continue
-            self.pixbuf[key] = (pixbuf, (pixbuf.get_width(), pixbuf.get_height()))
+            self.pixbuf[key] = (pixbuf,
+                                (pixbuf.get_width(), pixbuf.get_height()))
         # create drawing area
         self.darea = gtk.DrawingArea()
         self.darea.show()
@@ -360,27 +363,27 @@ class BalloonWindow:
                               gtk.gdk.POINTER_MOTION_HINT_MASK|
                               gtk.gdk.SCROLL_MASK)
         self.callbacks = []
-        for signal, func in [("expose_event",        self.redraw),
-                             ("button_press_event",  self.button_press),
-                             ("motion_notify_event", self.motion_notify),
-                             ("scroll_event",        self.scroll)]:
+        for signal, func in [('expose_event',        self.redraw),
+                             ('button_press_event',  self.button_press),
+                             ('motion_notify_event', self.motion_notify),
+                             ('scroll_event',        self.scroll)]:
             self.callbacks.append(self.darea.connect(signal, func))
         self.window.add(self.darea)
         self.darea.realize()
         self.darea.window.set_back_pixmap(None, False)
-        mask_r = desc.getint("maskcolor.r", 128)
-        mask_g = desc.getint("maskcolor.g", 128)
-        mask_b = desc.getint("maskcolor.b", 128)
-        self.cursor_color = "#%02x%02x%02x" % (mask_r, mask_g, mask_b)
-        text_r = desc.getint(["font.color.r", "fontcolor.r"], 0)
-        text_g = desc.getint(["font.color.g", "fontcolor.g"], 0)
-        text_b = desc.getint(["font.color.b", "fontcolor.b"], 0)
-        self.text_normal_color = "#%02x%02x%02x" % (text_r, text_g, text_b)
-        if desc.getint("maskmethod") == 1:
+        mask_r = desc.getint('maskcolor.r', 128)
+        mask_g = desc.getint('maskcolor.g', 128)
+        mask_b = desc.getint('maskcolor.b', 128)
+        self.cursor_color = '#%02x%02x%02x' % (mask_r, mask_g, mask_b)
+        text_r = desc.getint(['font.color.r', 'fontcolor.r'], 0)
+        text_g = desc.getint(['font.color.g', 'fontcolor.g'], 0)
+        text_b = desc.getint(['font.color.b', 'fontcolor.b'], 0)
+        self.text_normal_color = '#%02x%02x%02x' % (text_r, text_g, text_b)
+        if desc.getint('maskmethod') == 1:
             text_r = 255 - text_r
             text_g = 255 - text_g
             text_b = 255 - text_b
-        self.text_active_color = "#%02x%02x%02x" % (text_r, text_g, text_b)
+        self.text_active_color = '#%02x%02x%02x' % (text_r, text_g, text_b)
         # initialize
         self.direction = min(side, 1) ## kluge: multi chractor
         self.set_position(0, 0)
@@ -391,10 +394,12 @@ class BalloonWindow:
         for key in self.balloon.keys():
             path, config = self.balloon[key]
             try:
-                pixbuf = pix.create_pixbuf_from_file(path, use_pna=self.__use_pna)
+                pixbuf = pix.create_pixbuf_from_file(path,
+                                                     use_pna=self.__use_pna)
             except:
                 continue
-            self.pixbuf[key] = (pixbuf, (pixbuf.get_width(), pixbuf.get_height()))
+            self.pixbuf[key] = (pixbuf,
+                                (pixbuf.get_width(), pixbuf.get_height()))
 
     def set_use_pna(self, flag):
         if flag:
@@ -438,49 +443,52 @@ class BalloonWindow:
         # arrow positions
         self.arrow = []
         w, h = self.pixbuf[self.balloon_id][1]
-        x = self.config_adjust("arrow0.x", w, -10)
-        y = self.config_adjust("arrow0.y", h,  10)
+        x = self.config_adjust('arrow0.x', w, -10)
+        y = self.config_adjust('arrow0.y', h,  10)
         self.arrow.append((x, y))
-        x = self.config_adjust("arrow1.x", w, -10)
-        y = self.config_adjust("arrow1.y", h, -20)
+        x = self.config_adjust('arrow1.x', w, -10)
+        y = self.config_adjust('arrow1.y', h, -20)
         self.arrow.append((x, y))
         # sstp marker position
         if self.side == 0:
             self.sstp = []
-            x = self.config_adjust("sstpmarker.x", w,  30)
-            y = self.config_adjust("sstpmarker.y", h, -20)
+            x = self.config_adjust('sstpmarker.x', w,  30)
+            y = self.config_adjust('sstpmarker.y', h, -20)
             self.sstp.append((x, y)) # sstp marker
-            x = self.config_adjust("sstpmessage.x", w,  50)
-            y = self.config_adjust("sstpmessage.y", h, -20)
+            x = self.config_adjust('sstpmessage.x', w,  50)
+            y = self.config_adjust('sstpmessage.y', h, -20)
             self.sstp.append((x, y)) # sstp message
         # arrow pixmaps and masks
         x, y = self.arrow[0]
-        pixbuf = self.pixbuf["arrow0"][0]
+        pixbuf = self.pixbuf['arrow0'][0]
         scale = self.get_scale()
         w = int(pixbuf.get_width() * scale / 100)
         h = int(pixbuf.get_height() * scale / 100)
-        pixmap, mask = pixbuf.scale_simple(w, h, gtk.gdk.INTERP_BILINEAR).render_pixmap_and_mask(255)
+        pixmap, mask = pixbuf.scale_simple(
+            w, h, gtk.gdk.INTERP_BILINEAR).render_pixmap_and_mask(255)
         self.arrow0_pixmap = pixmap, mask, (w, h)
         self.arrow0_gc = self.new_mask_gc(mask, x, y)
         x, y = self.arrow[1]
-        pixbuf = self.pixbuf["arrow1"][0]
+        pixbuf = self.pixbuf['arrow1'][0]
         w = int(pixbuf.get_width() * scale / 100)
         h = int(pixbuf.get_height() * scale / 100)
-        pixmap, mask = pixbuf.scale_simple(w, h, gtk.gdk.INTERP_BILINEAR).render_pixmap_and_mask(255)
+        pixmap, mask = pixbuf.scale_simple(
+            w, h, gtk.gdk.INTERP_BILINEAR).render_pixmap_and_mask(255)
         self.arrow1_pixmap = pixmap, mask, (w, h)
         self.arrow1_gc = self.new_mask_gc(mask, x, y)
         # sstp marker pixmap and mask
-        if self.side == 0 and self.pixbuf.has_key("sstp"):
+        if self.side == 0 and self.pixbuf.has_key('sstp'):
             x, y = self.sstp[0]
-            pixbuf = self.pixbuf["sstp"][0]
+            pixbuf = self.pixbuf['sstp'][0]
             w = int(pixbuf.get_width() * scale / 100)
             h = int(pixbuf.get_height() * scale / 100)
-            pixmap, mask = pixbuf.scale_simple(w, h, gtk.gdk.INTERP_BILINEAR).render_pixmap_and_mask(255)
+            pixmap, mask = pixbuf.scale_simple(
+                w, h, gtk.gdk.INTERP_BILINEAR).render_pixmap_and_mask(255)
             self.sstp_pixmap = pixmap, mask, (w, h)
             self.sstp_gc = self.new_mask_gc(mask, x, y)
         # font
         default_size = 12
-        size = self.desc.getint(["font.height", "font.size"], default_size)
+        size = self.desc.getint(['font.height', 'font.size'], default_size)
         self.layout = pango.Layout(self.darea.get_pango_context())
         self.font_desc = pango.FontDescription(self.window.font_name)
         size = size * self.font_desc.get_size() * 3 / 4 / default_size
@@ -494,7 +502,7 @@ class BalloonWindow:
         # font for sstp message
         if self.side == 0:
             default_size = 10
-            size = self.desc.getint("sstpmessage.font.height", default_size)
+            size = self.desc.getint('sstpmessage.font.height', default_size)
             self.sstp_layout = pango.Layout(self.darea.get_pango_context())
             self.sstp_font_desc = pango.FontDescription(self.window.font_name)
             size = size * self.sstp_font_desc.get_size() * 3 / 4 / default_size
@@ -507,23 +515,23 @@ class BalloonWindow:
             sstp_font_height = 0
         # font metrics
         origin_x = self.config_getint(
-            "origin.x",
-            self.config_getint("zeropoint.x",
-                               self.config_getint("validrect.left", 14)))
+            'origin.x',
+            self.config_getint('zeropoint.x',
+                               self.config_getint('validrect.left', 14)))
         origin_y = self.config_getint(
-            "origin.y",
-            self.config_getint("zeropoint.y",
-                               self.config_getint("validrect.top", 14)))
+            'origin.y',
+            self.config_getint('zeropoint.y',
+                               self.config_getint('validrect.top', 14)))
         wpx = self.config_getint(
-            "wordwrappoint.x",
-            self.config_getint("validrect.right", -14))
+            'wordwrappoint.x',
+            self.config_getint('validrect.right', -14))
         if wpx > 0:
             line_width = wpx - origin_x
         elif wpx < 0:
             line_width = self.width - origin_x + wpx
         else:
             line_width = self.width - origin_x * 2
-        wpy = self.config_getint("validrect.bottom", -14)
+        wpy = self.config_getint('validrect.bottom', -14)
         if wpy > 0:
             text_height = min(wpy, self.height) - origin_y
         elif wpy < 0:
@@ -547,10 +555,10 @@ class BalloonWindow:
 
     def update_line_regions(self, offset, new_y):
         origin_y = self.config_getint(
-            "origin.y",
-            self.config_getint("zeropoint.y",
-                               self.config_getint("validrect.top", 14)))
-        wpy = self.config_getint("validrect.bottom", -14)
+            'origin.y',
+            self.config_getint('zeropoint.y',
+                               self.config_getint('validrect.top', 14)))
+        wpy = self.config_getint('validrect.bottom', -14)
         if wpy > 0:
             text_height = min(wpy, self.height) - origin_y
         elif wpy < 0:
@@ -564,7 +572,7 @@ class BalloonWindow:
         for i in range(offset, len(self.line_regions)):
             self.line_regions[i] = (origin_x, y, line_width, line_height)
             y += line_height
-        for i in range(len(self.line_regions), self.lines+1):
+        for i in range(len(self.line_regions), self.lines + 1):
             self.line_regions.append((origin_x, y, line_width, line_height))
             y += line_height
 
@@ -593,7 +601,8 @@ class BalloonWindow:
         self.width  = int(w * scale / 100)
         self.height = int(h * scale / 100)
         self.darea.set_size_request(self.width, self.height)
-        self.balloon_pixbuf = pixbuf.scale_simple(self.width, self.height, gtk.gdk.INTERP_BILINEAR)
+        self.balloon_pixbuf = pixbuf.scale_simple(
+            self.width, self.height, gtk.gdk.INTERP_BILINEAR)
         pixmap, mask = self.balloon_pixbuf.render_pixmap_and_mask(255)
         self.window.shape_combine_mask(mask, 0, 0)
         if self.__shown:
@@ -678,18 +687,19 @@ class BalloonWindow:
     def show_sstp_message(self, message, sender):
         if self.sstp_region is None:
             self.show()
-        self.sstp_message = "%s (%s)" % (message, sender)
+        self.sstp_message = '%s (%s)' % (message, sender)
         x, y, w, h = self.sstp_region
         self.sstp_layout.set_text(self.sstp_message)
         message_width, message_height = self.sstp_layout.get_pixel_size()
         if message_width > w:
-            self.sstp_message = u"... (%s)" % sender
+            self.sstp_message = u'... (%s)' % sender
             i = 0
             while 1:
                 i += 1
-                s = "%s... (%s)" % (message[:i], sender)
+                s = '%s... (%s)' % (message[:i], sender)
                 self.sstp_layout.set_text(s)
-                message_width, message_height = self.sstp_layout.get_pixel_size()
+                message_width, message_height = \
+                               self.sstp_layout.get_pixel_size()
                 if message_width > w:
                     break
                 self.sstp_message = s
@@ -703,12 +713,13 @@ class BalloonWindow:
         if not self.__shown:
             return
         # draw/erase sstp marker
-        if self.pixbuf.has_key("sstp"):
+        if self.pixbuf.has_key('sstp'):
             x, y = self.sstp[0]
             w, h = self.sstp_pixmap[2]
             if self.sstp_message:
                 pixmap = self.sstp_pixmap[0]
-                self.darea.window.draw_drawable(self.sstp_gc, pixmap, 0, 0, x, y, w, h)
+                self.darea.window.draw_drawable(
+                    self.sstp_gc, pixmap, 0, 0, x, y, w, h)
             else:
                 self.redraw_area(x, y, w, h)
         # draw/erase sstp message
@@ -724,7 +735,8 @@ class BalloonWindow:
         x, y = self.arrow[0]
         pixmap, mask, (w, h) = self.arrow0_pixmap
         if self.lineno > 0:
-            self.darea.window.draw_drawable(self.arrow0_gc, pixmap, 0, 0, x, y, w, h)
+            self.darea.window.draw_drawable(
+                self.arrow0_gc, pixmap, 0, 0, x, y, w, h)
         elif clear:
             self.redraw_area(x, y, w, h)
 
@@ -733,7 +745,8 @@ class BalloonWindow:
         pixmap, mask, (w, h) = self.arrow1_pixmap
         if self.lineno + self.lines < len(self.text_buffer) or \
            self.sakura.script_mode == self.sakura.PAUSE_MODE:
-            self.darea.window.draw_drawable(self.arrow1_gc, pixmap, 0, 0, x, y, w, h)
+            self.darea.window.draw_drawable(
+                self.arrow1_gc, pixmap, 0, 0, x, y, w, h)
         elif clear:
             self.redraw_area(x, y, w, h)
 
@@ -743,7 +756,8 @@ class BalloonWindow:
             pix.modify_pixbuf_alpha(pixbuf, self.__alpha_channel)
             self.darea.window.draw_pixbuf(None, pixbuf, x, y, x, y, w, h)
         else:
-            self.darea.window.draw_pixbuf(None, self.balloon_pixbuf, x, y, x, y, w, h)
+            self.darea.window.draw_pixbuf(
+                None, self.balloon_pixbuf, x, y, x, y, w, h)
 
     def redraw(self, darea=None, event=None):
         if not self.__shown:
@@ -757,7 +771,8 @@ class BalloonWindow:
             pix.modify_pixbuf_alpha(pixbuf, self.__alpha_channel)
             self.darea.window.draw_pixbuf(None, pixbuf, 0, 0, 0, 0, -1, -1)
         else:
-            darea.window.draw_pixbuf(None, self.balloon_pixbuf, 0, 0, 0, 0, -1, -1)
+            darea.window.draw_pixbuf(
+                None, self.balloon_pixbuf, 0, 0, 0, 0, -1, -1)
         # draw foreground pixmap
         for i in range(len(self.images)):
             pixbuf, (w, h), (x, y) = self.images[i]
@@ -780,7 +795,8 @@ class BalloonWindow:
                     y = int(y)
                 except:
                     continue
-            pixmap, mask = pixbuf.scale_simple(w, h, gtk.gdk.INTERP_BILINEAR).render_pixmap_and_mask(255)
+            pixmap, mask = pixbuf.scale_simple(
+                w, h, gtk.gdk.INTERP_BILINEAR).render_pixmap_and_mask(255)
             gc = pixmap.new_gc()
             gc.set_clip_mask(mask)
             gc.set_clip_origin(x, y)
@@ -793,7 +809,7 @@ class BalloonWindow:
             if i >= j:
                 break
             x, y, w, h = self.line_regions[line]
-            if self.text_buffer[i][-7:] == "\n[half]":
+            if self.text_buffer[i].endswith('\n[half]'):
                 new_y = int(y + (self.font_height + self.line_space) / 2)
                 self.update_line_regions(line + 1, new_y)
                 self.layout.set_text(self.text_buffer[i][:-7])
@@ -812,7 +828,8 @@ class BalloonWindow:
                     my = y + (self.font_height + self.line_space) / 2
                     my = my - mh / 2
                     gc = self.new_mask_gc(mask, mx, my)
-                    self.darea.window.draw_drawable(gc, pixmap, 0, 0, mx, my, mw, mh)
+                    self.darea.window.draw_drawable(
+                        gc, pixmap, 0, 0, mx, my, mw, mh)
             i += 1
             line += 1
         if self.side == 0 and self.sstp_message:
@@ -825,10 +842,10 @@ class BalloonWindow:
     def update_link_region(self, darea, index, clear=0):
         sl = self.link_buffer[index][0]
         el = self.link_buffer[index][2]
-        if sl >= self.lineno and sl <= self.lineno + self.lines:
+        if self.lineno <= sl <= self.lineno + self.lines:
             sn = self.link_buffer[index][1]
             en = self.link_buffer[index][3]
-            for n in range(sl, el+1):
+            for n in range(sl, el + 1):
                 if n - self.lineno >= len(self.line_regions):
                     break
                 x, y, w, h = self.line_regions[n - self.lineno]
@@ -878,10 +895,10 @@ class BalloonWindow:
         for i in range(len(self.link_buffer)):
             sl = self.link_buffer[i][0]
             el = self.link_buffer[i][2]
-            if sl >= self.lineno and sl <= self.lineno + self.lines:
+            if self.lineno <= sl <= self.lineno + self.lines:
                 sn = self.link_buffer[i][1]
                 en = self.link_buffer[i][3]
-                for n in range(sl,el+1):
+                for n in range(sl,el + 1):
                     if n - self.lineno >= len(self.line_regions):
                         break
                     x, y, w, h = self.line_regions[n - self.lineno]
@@ -902,11 +919,13 @@ class BalloonWindow:
                         break
         if new_selection is not None:
             if self.selection != new_selection:
-                sl, sn, el, en, id, raw_text, text = self.link_buffer[new_selection]
-                self.sakura.notify_event("OnChoiceEnter", raw_text, id, self.selection)
+                sl, sn, el, en, id, raw_text, text = \
+                    self.link_buffer[new_selection]
+                self.sakura.notify_event(
+                    'OnChoiceEnter', raw_text, id, self.selection)
         else:
             if self.selection is not None:
-                self.sakura.notify_event("OnChoiceEnter")
+                self.sakura.notify_event('OnChoiceEnter')
         if new_selection == self.selection:
             return 0
         else:
@@ -976,7 +995,8 @@ class BalloonWindow:
             return True
         # links
         if self.selection is not None:
-            sl, sn, el, en, id, raw_text, text = self.link_buffer[self.selection]
+            sl, sn, el, en, id, raw_text, text = \
+                self.link_buffer[self.selection]
             self.sakura.notify_link_selection(id, raw_text, self.selection)
             return True
         # balloon's background
@@ -1001,14 +1021,14 @@ class BalloonWindow:
 
     def append_text(self, text):
         if not self.text_buffer or self.newline_required:
-            s = ""
+            s = ''
             column = 0
             self.newline_required = 0
         else:
             s = self.text_buffer.pop(-1)
             column = len(s)
         i = len(s)
-        text = s + text
+        text = ''.join((s, text))
         j = len(text)
         self.text_count += j
         p = 0
@@ -1017,9 +1037,9 @@ class BalloonWindow:
                 self.text_buffer.append(text[p:i])
                 self.draw_last_line(column)
                 break
-            if text[i] == "\n":
-                if j >= i+7 and text[i:i+7] == "\n[half]":
-                    self.text_buffer.append(text[p:i] + "\n[half]")
+            if text[i] == '\n':
+                if j >= i + 7 and text[i:i + 7] == '\n[half]':
+                    self.text_buffer.append(''.join((text[p:i], '\n[half]')))
                     p = i = i + 7
                 else:
                     self.text_buffer.append(text[p:i])
@@ -1040,7 +1060,7 @@ class BalloonWindow:
             i = n
 
     def append_sstp_marker(self):
-        if not self.pixbuf.has_key("sstp"):
+        if not self.pixbuf.has_key('sstp'):
             return
         if not self.text_buffer:
             line = 0
@@ -1052,7 +1072,7 @@ class BalloonWindow:
             line = line + 1
             offset = 0
         self.sstp_marker.append((line, offset))
-        w, h = self.pixbuf["sstp"][1]
+        w, h = self.pixbuf['sstp'][1]
         i = 1
         while 1:
             space = u'\u3000' * i ## FIXME
@@ -1082,11 +1102,13 @@ class BalloonWindow:
         line_number = 0
         while 1:
             n = i + 1
-            self.layout.set_text(offset+text[start:n])
+            self.layout.set_text(''.join((offset, text[start:n])))
             text_w, text_h = self.layout.get_pixel_size()
             if text_w > self.line_width:
-                if line_number == 0 and not newline_required and self.text_buffer:
-                    self.text_buffer[-1] = self.text_buffer[-1] + text[start:i]
+                if line_number == 0 and \
+                   not newline_required and self.text_buffer:
+                    self.text_buffer[-1] = ''.join(
+                        (self.text_buffer[-1], text[start:i]))
                     self.draw_last_line()
                 else:
                     self.text_buffer.append(text[start:i])
@@ -1095,8 +1117,10 @@ class BalloonWindow:
                 offset = ''
             i = n
             if i >= len(text):
-                if line_number == 0 and not newline_required and self.text_buffer:
-                    self.text_buffer[-1] = self.text_buffer[-1] + text[start:i]
+                if line_number == 0 and \
+                   not newline_required and self.text_buffer:
+                    self.text_buffer[-1] = ''.join(
+                        (self.text_buffer[-1], text[start:i]))
                 else:
                     self.text_buffer.append(text[start:i])
                 break
@@ -1123,7 +1147,7 @@ class BalloonWindow:
         line = len(self.text_buffer) - 1
         if self.lineno <= line < self.lineno + self.lines:
             x, y, w, h = self.line_regions[line - self.lineno]
-            if self.text_buffer[line][-7:] == "\n[half]":
+            if self.text_buffer[line].endswith('\n[half]'):
                 offset = line - self.lineno + 1
                 new_y = int(y + (self.font_height + self.line_space) / 2)
                 self.update_line_regions(offset, new_y)
@@ -1138,7 +1162,8 @@ class BalloonWindow:
                     my = y + (self.font_height + self.line_space) / 2
                     my = my - mh / 2
                     gc = self.new_mask_gc(mask, mx, my)
-                    self.darea.window.draw_drawable(gc, pixmap, 0, 0, mx, my, mw, mh)
+                    self.darea.window.draw_drawable(
+                        gc, pixmap, 0, 0, mx, my, mw, mh)
         else:
             self.redraw()
             while line >= self.lineno + self.lines:
@@ -1146,8 +1171,9 @@ class BalloonWindow:
                 self.redraw()
 
 class CommunicateWindow:
-    NAME = ""
-    ENTRY = ""
+
+    NAME = ''
+    ENTRY = ''
 
     def __init__(self, sakura, debug):
         self.sakura = sakura
@@ -1162,17 +1188,17 @@ class CommunicateWindow:
         self.window.set_title('communicate')
         self.window.set_decorated(False)
         self.window.set_resizable(False)
-        self.window.connect("delete_event",         self.delete)
-        self.window.connect("key_press_event",      self.key_press)
-        self.window.connect("button_press_event",   self.button_press)
+        self.window.connect('delete_event',         self.delete)
+        self.window.connect('key_press_event',      self.key_press)
+        self.window.connect('button_press_event',   self.button_press)
         self.window.set_events(gtk.gdk.BUTTON_PRESS_MASK)
         self.window.set_modal(True)
         self.window.set_position(gtk.WIN_POS_CENTER)
         self.window.realize()
-        w = desc.getint("communicatebox.width", 250)
-        h = desc.getint("communicatebox.height", -1)
+        w = desc.getint('communicatebox.width', 250)
+        h = desc.getint('communicatebox.height', -1)
         self.entry = gtk.Entry()
-        self.entry.connect("activate", self.activate)
+        self.entry.connect('activate', self.activate)
         self.entry.set_size_request(w, h)
         self.entry.show()
         image, mask = None, None
@@ -1189,8 +1215,8 @@ class CommunicateWindow:
             gtk_image.set_padding(0, 0)
             gtk_image.set_from_pixmap(image, mask)
             gtk_image.show()
-            x = desc.getint("communicatebox.x", 10)
-            y = desc.getint("communicatebox.y", 20)
+            x = desc.getint('communicatebox.x', 10)
+            y = desc.getint('communicatebox.y', 20)
             fixed = gtk.Fixed()
             fixed.put(gtk_image, 0, 0)
             fixed.put(self.entry, x, y)
@@ -1227,7 +1253,9 @@ class CommunicateWindow:
 
     def button_press(self, widget, event):
         if event.button in [1, 2]:
-            self.window.begin_move_drag(event.button, int(event.x_root), int(event.y_root), gtk.get_current_event_time())
+            self.window.begin_move_drag(
+                event.button, int(event.x_root), int(event.y_root),
+                gtk.get_current_event_time())
         return True
 
     def activate(self, widget):
@@ -1235,7 +1263,7 @@ class CommunicateWindow:
         self.enter()
         return True
 
-    def show(self, default=""):
+    def show(self, default=''):
         self.entry.set_text(default)
         self.window.show()
 
@@ -1246,8 +1274,9 @@ class CommunicateWindow:
         pass
 
 class CommunicateBox(CommunicateWindow):
-    NAME = "communicatebox"
-    ENTRY = "Communicate"
+
+    NAME = 'communicatebox'
+    ENTRY = 'Communicate'
 
     def new(self, desc, balloon):
         CommunicateWindow.new(self, desc, balloon)
@@ -1284,8 +1313,9 @@ class CommunicateBox(CommunicateWindow):
         self.sakura.notify_user_communicate(data)
 
 class TeachBox(CommunicateWindow):
-    NAME = "teachbox"
-    ENTRY = "Teach"
+
+    NAME = 'teachbox'
+    ENTRY = 'Teach'
 
     def enter(self):
         self.send(self.entry.get_text())
@@ -1299,8 +1329,9 @@ class TeachBox(CommunicateWindow):
         self.sakura.notify_user_teach(data)
 
 class InputBox(CommunicateWindow):
-    NAME = "inputbox"
-    ENTRY = "Input"
+
+    NAME = 'inputbox'
+    ENTRY = 'Input'
 
     def show(self, symbol, limittime, default):
         self.symbol = symbol
@@ -1308,9 +1339,9 @@ class InputBox(CommunicateWindow):
             try:
                 text = unicode(default).encode('utf-8')
             except:
-                text = ""
+                text = ''
         else:
-            text = ""
+            text = ''
         try:
             limittime = int(limittime)
         except ValueError:
@@ -1323,7 +1354,7 @@ class InputBox(CommunicateWindow):
 
     def timeout(self):
         self.window.hide()
-        self.send("timeout")
+        self.send('timeout')
 
     def enter(self):
         self.send(self.entry.get_text())
@@ -1338,8 +1369,9 @@ class InputBox(CommunicateWindow):
             data = unicode(data, 'utf-8')
         self.sakura.notify_user_input(self.symbol, data)
 
+
 def test():
     pass
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     test()
index 32facc3..e3c0b1b 100644 (file)
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-#  $Id: communicate.py,v 1.10 2005/07/29 08:25:59 shy Exp $
+#  $Id: communicate.py,v 1.11 2005/08/09 00:41:52 shy Exp $
 #
 
 import os
 import socket
-import string
 import fcntl
 
 import ninix.home
 
+
 class Communicate:
 
     def __init__(self):
@@ -38,7 +38,7 @@ class Communicate:
         otherghostname = []
         for key in self.__ghosts.keys():
             if self.__ghosts[key][0] != name:
-                otherghostname.append(string.join(self.__ghosts[key], chr(1)))
+                otherghostname.append(''.join((self.__ghosts[key], chr(1))))
         return otherghostname
 
     def send_message(self, ghostname, sender, sentence):
index 01a3686..c369aef 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: ascii -*-
 #
 #  Copyright (C) 2001, 2002 by Tamito KAJIYAMA
-#  Copyright (C) 2003, 2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2003-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: config.py,v 1.11 2004/04/13 05:21:59 shy Exp $
+# $Id: config.py,v 1.12 2005/08/09 00:41:52 shy Exp $
 #
 
-import string
 import UserDict
 import codecs
 
 builtin_open = open
 
+
 class Config(UserDict.UserDict):
+
     def __init__(self):
         UserDict.UserDict.__init__(self)
         self.itemlist = []
+
     def __setitem__(self, key, value):
         UserDict.UserDict.__setitem__(self, key, value)
         self.itemlist.append((key, value))
+
     def get(self, name, default=None):
-        if type(name) == type([]):
+        if isinstance(name, list):
             keylist = name
         else:
             keylist = [name]
@@ -35,6 +38,7 @@ class Config(UserDict.UserDict):
             if self.data.has_key(key):
                 return self.data[key]
         return default
+
     def getint(self, name, default=None):
         value = self.get(name)
         if value:
@@ -43,6 +47,7 @@ class Config(UserDict.UserDict):
             except ValueError:
                 pass
         return default
+
     def getfloat(self, name, default=None):
         value = self.get(name)
         if value:
@@ -51,11 +56,12 @@ class Config(UserDict.UserDict):
             except ValueError:
                 pass
         return default
+
     def adjust(self, name, base, default=None):
         value = self.get(name)
         if value:
             try:
-                if value[:2] == "--":
+                if value.startswith('--'):
                     return int(value[1:])
                 value = int(value)
             except (TypeError, ValueError):
@@ -63,11 +69,13 @@ class Config(UserDict.UserDict):
         if value is not None and value < 0:
             value = base + value
         return value
+
     def __str__(self):
         buffer = []
         for item in self.data.items():
             buffer.append('%s,%s\n' % item)
-        return string.join(buffer, '')
+        return ''.join(buffer)
+
 
 def open(path):
     file = builtin_open(path)
@@ -90,7 +98,7 @@ def new_config(buffer):
             try:
                 codecs.lookup(charset)
             except:
-                print "Unsupported charset %s" % value.strip()
+                print 'Unsupported charset %s' % value.strip()
             else:
                 charset = value.strip()
         elif key.strip() in ['refreshundeletemask', 'icon', 'cursor',
index 317ab02..078a4f1 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: ascii -*-
 #
 #  dll.py - a pseudo DLL (SHIORI/SAORI API support) module for ninix
-#  Copyright (C) 2002-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
 #
 #  This program is free software; you can redistribute it and/or modify it
@@ -11,7 +11,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-#  $Id: dll.py,v 1.8 2005/07/29 08:25:59 shy Exp $
+#  $Id: dll.py,v 1.9 2005/08/09 00:41:52 shy Exp $
 #
 
 import sys
@@ -20,11 +20,15 @@ import os
 import StringIO
 import codecs
 
+
 class SAORI:
+
     def __init__(self):
         self.loaded = 0
+
     def check_import(self):
         return 1
+
     def load(self, dir=os.curdir):
         self.dir = dir
         result = 0
@@ -37,16 +41,20 @@ class SAORI:
                 self.loaded = 1
                 result = 1
         return result
+
     def setup(self):
         return 1
+
     def unload(self):
         if self.loaded == 0:
             return 0
         else:
             self.loaded = 0
             return self.finalize()
+
     def finalize(self):
         return 1
+
     def request(self, req):
         type, argument = self.evaluate_request(req)
         if not type:
@@ -59,8 +67,10 @@ class SAORI:
                 return 'SAORI/1.0 204 No Content\r\n\r\n'
             else:
                 return result
+
     def execute(self, args):
         return None
+
     def evaluate_request(self, req):
         type = None
         argument = []
@@ -72,22 +82,23 @@ class SAORI:
                 continue
             if type is None:
                 for request in ['EXECUTE', 'GET Version']: ## FIXME
-                    if line[:len(request)] == request:
+                    if line.startswith(request):
                         type = request
                 continue
             colon = line.find(':')
             if colon >= 0:
                 key = line[:colon].strip()
-                value = line[colon+1:].strip()
+                value = line[colon + 1:].strip()
                 if key == 'Charset':
                     charset = value
                     try:
                         codecs.lookup(charset)
                     except:
-                        sys.stderr.write("Unsupported charset %s" % repr(charset))
+                        sys.stderr.write(
+                            'Unsupported charset %s' % repr(charset))
                     else:
                         self.charset = charset
-                if key[:8] == 'Argument': ## FIXME
+                if key.startswith('Argument'): ## FIXME
                     argument.append(value)
                 else:
                     continue
@@ -96,12 +107,14 @@ class SAORI:
         return type, argument
 
 class Library:
+
     def __init__(self, type, dir, ghost=None, saori_lib=None):
         self.__type = type
         self.__dir_list = []
         self.__dir_list.append(dir)
         self.__ghost = ghost
         self.__saori_lib = saori_lib
+
     def request(self, name):
         if self.__type == 'shiori':
             dll_name, name = name
@@ -111,7 +124,7 @@ class Library:
         head, tail = os.path.split(name)
         name = tail
         if name:
-            if name[-4:] == '.dll':
+            if name.endswith('.dll'):
                 name = name[:-4]
         else:
             return None
@@ -140,6 +153,7 @@ class Library:
                 del module
                 del sys.modules[name]
             return instance
+
     def __import_module(self, name):
         fp = None
         try:
index 757c7db..adf1b84 100644 (file)
@@ -1,6 +1,6 @@
 # -*- coding: EUC-JP -*-
 #
-#  aya.py - an "" aya.dll compatible Shiori module for ninix
+#  aya.py - an aya.dll compatible Shiori module for ninix
 #  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
 #
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-#  $Id: aya.py,v 1.41 2005/07/29 08:25:59 shy Exp $
+#  $Id: aya.py,v 1.42 2005/08/09 00:41:52 shy Exp $
 #
 
 import os
-import string
 import sys
 import random
 import time
-from types import *
 import math
 from stat import *
 import shutil
@@ -27,9 +25,11 @@ import StringIO
 import fcntl
 import re
 
+
 class AyaError(ValueError):
     pass
 
+
 def encrypt_char(char):
     c = ord(char)
     j = 0
@@ -65,21 +65,21 @@ def decrypt_readline(file):
         c = file.read(1)
         if c == '':
             break
-        line = string.join((line, decrypt_char(c)), '')
-        if line[-1:] == chr(10) or \
-           line[-2:] == string.join((chr(13), chr(10)), ''):
+        line = ''.join((line, decrypt_char(c)))
+        if line.endswith(chr(10)) or \
+           line.endswith(''.join((chr(13), chr(10)))):
             break
     return line
 
 def line_strip(line):
     line = line.strip()
-    while len(line) > 0:
-        if line[:2] == '¡¡': ## FIXME
+    while line:
+        if line.startswith('¡¡'): ## FIXME
             line = line[2:].strip()
         else:
             break
-    while len(line) > 0:
-        if line[-2:] == '¡¡': ## FIXME
+    while line:
+        if line.endswith('¡¡'): ## FIXME
             line = line[:-2].strip()
         else:
             break
@@ -94,9 +94,9 @@ def find_not_quoted(line, token):
         elif pos_new == 0:
             break
         position = line.find('"', position)
-        if position >= 0 and position < pos_new:
+        if 0 <= position < pos_new:
             position += 1
-            while position < len(line)-1:
+            while position < len(line) - 1:
                 if line[position] == '"':
                     position += 1
                     break
@@ -108,13 +108,13 @@ def find_not_quoted(line, token):
     return pos_new
 
 def find_comment(line):
-    if line[:2] == '//':
+    if line.startswith('//'):
         return 0, len(line)
-    start = len(line) # not len(line)-1
+    start = len(line) # not len(line) - 1
     end = -1
     for token in [' //', '\t//', '¡¡//', '/*']: ## FIXME
         pos_new = find_not_quoted(line, token)
-        if pos_new >= 0 and pos_new < start:
+        if 0 <= pos_new < start:
             start = pos_new
             if token == '/*':
                 end = find_not_quoted(line, '*/')
@@ -131,11 +131,12 @@ def get_aya_version(list):
         return 0
     dic_files = list
     for filename in dic_files:
-        if filename[-12:] == '_shiori3.dic':
+        if filename.endswith('_shiori3.dic'):
             file = open(filename)
             for line in file:
                 try: ## FIXME
-                    line = unicode(line, 'Shift_JIS').encode('EUC-JP', 'ignore')
+                    line = unicode(line, 'Shift_JIS').encode('EUC-JP',
+                                                             'ignore')
                     if line.find('for ʸ version 4') > 0:
                         return 4
                     elif line.find('for AYA5') > 0:
@@ -155,7 +156,7 @@ def find_dict(aya_dir, file):
             if end < 0:
                 continue
             else:
-                line = line[end+2:]
+                line = line[end + 2:]
                 comment = 0
         while 1:
             start, end = find_comment(line)
@@ -165,14 +166,14 @@ def find_dict(aya_dir, file):
                 comment = 1
                 line = line[:start]
                 break
-            line = string.join((line[:start], line[end:]))
+            line = ' '.join((line[:start], line[end:]))
         line = line_strip(line)
         if not line:
             continue
         comma = line.find(',')
         if comma >= 0:
             key = line_strip(line[:comma])
-            value = line_strip(line[comma+1:])
+            value = line_strip(line[comma + 1:])
         else:
             continue
         if key == 'dic':
@@ -185,8 +186,9 @@ def check_version(dir, dll_name):
     filename = None
     if os.path.isfile(os.path.join(dir, 'aya.txt')):
         filename = os.path.join(dir, 'aya.txt')
-    elif dll_name is not None and os.path.isfile(os.path.join(dir, dll_name[:-3]+'txt')):
-        filename = os.path.join(dir, dll_name[:-3]+'txt')
+    elif dll_name is not None and \
+         os.path.isfile(os.path.join(dir, ''.join((dll_name[:-3], 'txt')))):
+        filename = os.path.join(dir, ''.join((dll_name[:-3], 'txt')))
     if filename is not None:
         file = open(filename)                    
         version = get_aya_version(find_dict(dir, file))
@@ -195,15 +197,17 @@ def check_version(dir, dll_name):
         version = 0
     return version
 
+
 class Shiori:
+
     __AYA_TXT = 'aya.txt'
     __DBNAME = 'aya_variable.cfg'
 
     def __init__(self, dll_name):
         self.dll_name = dll_name
         if dll_name is not None:
-            self.__AYA_TXT = dll_name[:-3] + 'txt'
-            self.__DBNAME = dll_name[:-4] + '_variable.cfg'
+            self.__AYA_TXT = ''.join((dll_name[:-3], 'txt'))
+            self.__DBNAME = ''.join((dll_name[:-4], '_variable.cfg'))
         self.saori = None
         self.debug = 1
         self.dic_files = []
@@ -221,9 +225,10 @@ class Shiori:
         return result
 
     def show_description(self):
-        sys.stdout.write('Shiori: AYA compatible module for ninix\n'
-                         '        Copyright (C) 2002-2004 by Shyouzou Sugitani\n'
-                         '        Copyright (C) 2002, 2003 by MATSUMURA Namihiko\n')
+        sys.stdout.write(
+            'Shiori: AYA compatible module for ninix\n'
+            '        Copyright (C) 2002-2005 by Shyouzou Sugitani\n'
+            '        Copyright (C) 2002, 2003 by MATSUMURA Namihiko\n')
 
     def reset(self):
         self.boot_time = time.time()
@@ -276,7 +281,7 @@ class Shiori:
                 if self.debug & 4:
                     print 'cannnot read %s' % path
                 continue
-            if path[-4:] == '.ayc':
+            if path.endswith('.ayc'):
                 encrypted = 1
             else:
                 encrypted = 0
@@ -291,19 +296,22 @@ class Shiori:
                      'ID: OnLoad\r\n' \
                      'Sender: AYA\r\n' \
                      'SecurityLevel: local\r\n' \
-                     'Path: %s\r\n\r\n' % unicode(self.aya_dir.replace('/', '\\'), 'EUC-JP', 'ignore').encode('Shift_JIS', 'ignore')) ## FIXME: UTF-8(path) -> Shift_JIS
+                     'Path: %s\r\n\r\n' % \
+                     unicode(self.aya_dir.replace('/', '\\'), 'EUC-JP',
+                             'ignore').encode('Shift_JIS', 'ignore')) ## FIXME: UTF-8(path) -> Shift_JIS
         return 1
 
     def load_aya_txt(self, file):
         comment = 0
         for line in file:
-            line = unicode(line, 'Shift_JIS', 'ignore').encode('EUC-JP', 'ignore') ## FIXME
+            line = unicode(line, 'Shift_JIS', 'ignore').encode('EUC-JP',
+                                                               'ignore') ## FIXME
             if comment:
                 end = find_not_quoted(line, '*/')
                 if end < 0:
                     continue
                 else:
-                    line = line[end+2:]
+                    line = line[end + 2:]
                     comment = 0
             while 1:
                 start, end = find_comment(line)
@@ -313,14 +321,14 @@ class Shiori:
                     comment = 1
                     line = line[:start]
                     break
-                line = string.join((line[:start], line[end:]))
+                line = ' '.join((line[:start], line[end:]))
             line = line_strip(line)
             if not line:
                 continue
             comma = line.find(',')
             if comma >= 0:
                 key = line_strip(line[:comma])
-                value = line_strip(line[comma+1:])
+                value = line_strip(line[comma + 1:])
             else:
                 continue
             self.evaluate_config(key, value)
@@ -407,7 +415,7 @@ class Shiori:
                 colon = line.find(':')
                 if colon >= 0:
                     key = line_strip(line[:colon])
-                    value = line_strip(line[colon+1:])
+                    value = line_strip(line[colon + 1:])
                     try:
                         value = int(value)
                     except:
@@ -417,13 +425,16 @@ class Shiori:
                 else:
                     continue
             for key in self.req_header.keys():
-                if type(self.req_header[key]) is StringType:
-                    self.req_header[key] = unicode(self.req_header[key], 'Shift_JIS', 'ignore').encode('EUC-JP', 'ignore') ## FIXME
+                if isinstance(self.req_header[key], str):
+                    self.req_header[key] = unicode(
+                        self.req_header[key],
+                        'Shift_JIS', 'ignore').encode('EUC-JP', 'ignore') ## FIXME
         if self.first_boot:
-            if self.req_header['ID'] in ['OnBoot', 'OnVanished', 'OnGhostChanged']:
+            if self.req_header['ID'] in ['OnBoot', 'OnVanished',
+                                         'OnGhostChanged']:
                 self.first_boot = 0
                 if self.debug & 4:
-                    print "We lost the %s. Initializing...." % self.__DBNAME
+                    print 'We lost the %s. Initializing....' % self.__DBNAME
                 self.request('NOTIFY SHIORI/3.0\r\n'
                              'ID: OnFirstBoot\r\n'
                              'Sender: ninix\r\n'
@@ -435,17 +446,18 @@ class Shiori:
         func = self.dic.get_function('OnRequest')
         if not func and self.req_header.has_key('ID'): # Ver.3
             for i in range(9):
-                self.global_namespace.remove(string.join(('reference', str(i)), ''))
+                self.global_namespace.remove(''.join(('reference', str(i))))
             for i in range(9):
-                key = string.join(('Reference', str(i)), '')
+                key = ''.join(('Reference', str(i)))
                 if self.req_header.has_key(key):
-                    self.global_namespace.put(string.join(('reference', str(i)), ''),
+                    self.global_namespace.put(''.join(('reference', str(i))),
                                               self.req_header[key])
-            if self.req_header['ID'][:2] != 'On':
+            if not self.req_header['ID'].startswith('On'):
                 prefix = 'On_'
             else:
                 prefix = ''
-            func = self.dic.get_function(string.join((prefix, self.req_header['ID']), ''))
+            func = self.dic.get_function(
+                ''.join((prefix, self.req_header['ID'])))
         if func:
             result = func.call()
         if self.ver_3 and self.req_header.has_key('ID') and \
@@ -465,12 +477,16 @@ class Shiori:
         if self.ver_3: # Ver.3
             result = 'SHIORI/3.0 200 OK\r\n' \
                      'Sender: AYA\r\n' \
-                     'Value: %s\r\n\r\n' % unicode(result, 'EUC-JP', 'ignore').encode('Shift_JIS', 'ignore') ## FIXME
+                     'Value: %s\r\n\r\n' % \
+                     unicode(result, 'EUC-JP', 'ignore').encode('Shift_JIS',
+                                                                'ignore') ## FIXME
             return result
         else:
-            return unicode(result, 'EUC-JP','ignore').encode('Shift_JIS', 'ignore') ## FIXME
+            return unicode(result, 'EUC-JP','ignore').encode('Shift_JIS',
+                                                             'ignore') ## FIXME
 
 class AyaSecurity:
+
     __DENY = 0
     __ACCEPT = 1
     __CONFIG = 'aya_security.cfg'
@@ -528,31 +544,31 @@ class AyaSecurity:
                     name = self.expand_path(name)
                     if name == '*':
                         break
-                    if self.__aya_dir[:len(name)] == name:
+                    if self.__aya_dir.startswith(name):
                         break
                 data = {}
                 end = line.find(']')
                 if end < 0:
                     end = len(line)
-                name = line[start+1:end]
+                name = line[start + 1:end]
             else:
                 comma = line.find(',')
                 if comma >= 0:
                     key = line[:comma].strip()
-                    value = line[comma+1:].strip()
-                    if key[:5] == 'deny.':
+                    value = line[comma + 1:].strip()
+                    if key.startswith('deny.'):
                         key = key[5:]
                         list = data.get(key, [])
                         list.append([self.__DENY, value])
                         data[key] = list
-                    elif key[:7] == 'accept.':
+                    elif key.startswith('accept.'):
                         key = key[7:]
                         list = data.get(key, [])
                         list.append([self.__ACCEPT, value])
                         data[key] = list
                     elif key == 'log':
                         head, tail = os.path.split(self.__cfg)
-                        value = string.join(('./', value), '')
+                        value = ''.join(('./', value))
                         value = os.path.join(head, value)
                         value = os.path.abspath(value)
                         data[key] = value
@@ -561,7 +577,8 @@ class AyaSecurity:
             line = self.readline(file)
         else:
             if not name:
-                print '*WARNING : aya_security.cfg - no entry found for %s.' % os.path.join(self.__aya_dir, 'aya.dll')
+                print '*WARNING : aya_security.cfg - no entry found for %s.' \
+                      % os.path.join(self.__aya_dir, 'aya.dll')
                 return
         self.__fwrite.extend(data.get('fwrite', []))
         for i in range(len(self.__fwrite)):
@@ -581,8 +598,8 @@ class AyaSecurity:
             return head
         meta = path.rfind('%CFGDIR')
         if meta >= 0:
-            path = path[meta+7:].replace('\\', '/').lower()
-            path = string.join(('./', path), '')
+            path = path[meta + 7:].replace('\\', '/').lower()
+            path = ''.join(('./', path))
             path = os.path.join(head, path)
         else:
             path = path.replace('\\', '/').lower()
@@ -591,7 +608,8 @@ class AyaSecurity:
 
     def readline(self, file):
         while 1:
-            line = unicode(file.readline(), 'Shift_JIS', 'ignore').encode('EUC-JP', 'ignore') ## FIXME
+            line = unicode(file.readline(),
+                           'Shift_JIS', 'ignore').encode('EUC-JP', 'ignore') ## FIXME
             if not line:
                 break # EOF
             if self.comment:
@@ -599,7 +617,7 @@ class AyaSecurity:
                 if end < 0:
                     continue
                 else:
-                    line = line[end+2:]
+                    line = line[end + 2:]
                     self.comment = 0
             while 1:
                 start, end = find_comment(line)
@@ -609,7 +627,7 @@ class AyaSecurity:
                     self.comment = 1
                     line = line[:start]
                     break
-                line = string.join((line[:start] + ' ' + line[end:]), '')
+                line = ''.join((line[:start], ' ', line[end:]))
             line = line_strip(line)
             if not line:
                 continue
@@ -620,7 +638,7 @@ class AyaSecurity:
         result = 0
         abspath = os.path.abspath(path)
         head, tail = os.path.split(abspath)
-        if tail != "aya_security.cfg":
+        if tail != 'aya_security.cfg':
             if flag in ['w', 'w+', 'r+', 'a', 'a+']:
                 for perm, name in self.__fwrite:
                     if name == '*' or abspath[:len(name)] == name:
@@ -644,9 +662,13 @@ class AyaSecurity:
                         break
         if self.__logfile and result == 0:
             if flag == 'r':
-                self.logging('µö²Ä¤µ¤ì¤Æ¤¤¤Ê¤¤¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï¥Ç¥£¥ì¥¯¥È¥ê³¬ÁؤÎÆɤ߼è¤ê¤ò¥Ö¥í¥Ã¥¯¤·¤Þ¤·¤¿.', 'file', abspath)
+                self.logging('µö²Ä¤µ¤ì¤Æ¤¤¤Ê¤¤¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï'
+                             '¥Ç¥£¥ì¥¯¥È¥ê³¬ÁؤÎÆɤ߼è¤ê¤ò¥Ö¥í¥Ã¥¯¤·¤Þ¤·¤¿.',
+                             'file', abspath)
             else:
-                self.logging('µö²Ä¤µ¤ì¤Æ¤¤¤Ê¤¤¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï¥Ç¥£¥ì¥¯¥È¥ê³¬Áؤؤνñ¤­¹þ¤ß¤ò¥Ö¥í¥Ã¥¯¤·¤Þ¤·¤¿.', 'file', abspath)
+                self.logging('µö²Ä¤µ¤ì¤Æ¤¤¤Ê¤¤¥Õ¥¡¥¤¥ë¤Þ¤¿¤Ï'
+                             '¥Ç¥£¥ì¥¯¥È¥ê³¬Áؤؤνñ¤­¹þ¤ß¤ò¥Ö¥í¥Ã¥¯¤·¤Þ¤·¤¿.',
+                             'file', abspath)
         return result
 
     def check_lib(self, dll):
@@ -660,7 +682,8 @@ class AyaSecurity:
                 elif perm == self.__DENY:
                     result = 0
         if self.__logfile and result == 0:
-            self.logging('µö²Ä¤µ¤ì¤Æ¤¤¤Ê¤¤ DLL ¤Î¥í¡¼¥É¤ò¥Ö¥í¥Ã¥¯¤·¤Þ¤·¤¿.', 'dll ', dll_name)
+            self.logging('µö²Ä¤µ¤ì¤Æ¤¤¤Ê¤¤ DLL ¤Î¥í¡¼¥É¤ò¥Ö¥í¥Ã¥¯¤·¤Þ¤·¤¿.',
+                         'dll ', dll_name)
         return result
 
     def logging(self, message, target_type, target): ## FIXME
@@ -675,10 +698,11 @@ class AyaSecurity:
                 return None
         fcntl.lockf(file.fileno(), fcntl.LOCK_EX)
         aya_dll = os.path.join(self.__aya_dir, 'aya.dll')
-        line = string.join(('*WARNING : ', str(message), '\n'), '')
-        line = string.join((line, 'AYA  : ', aya_dll, '\n'), '')
-        line = string.join((line, 'date : ', time.strftime('%Y/%m/%d(%a) %H:%M:%S'), '\n'), '')
-        line = string.join((line, str(target_type), ' : ', str(target), '\n'), '')
+        line = ''.join(('*WARNING : ', str(message), '\n'))
+        line = ''.join((line, 'AYA  : ', aya_dll, '\n'))
+        line = ''.join((line, 'date : ',
+                        time.strftime('%Y/%m/%d(%a) %H:%M:%S'), '\n'))
+        line = ''.join((line, str(target_type), ' : ', str(target), '\n'))
         file.write(line)
         file.write('\n')
         fcntl.lockf(file.fileno(), fcntl.LOCK_UN)
@@ -706,7 +730,8 @@ class AyaDictionary:
                 line = decrypt_readline(file)
             else:
                 line = file.readline()
-            line = unicode(line, 'Shift_JIS', 'ignore').encode('EUC-JP', 'ignore') ## FIXME
+            line = unicode(line, 'Shift_JIS', 'ignore').encode('EUC-JP',
+                                                               'ignore') ## FIXME
             if not line:
                 break # EOF
             if comment:
@@ -714,7 +739,7 @@ class AyaDictionary:
                 if end < 0:
                     continue
                 else:
-                    line = line[end+2:]
+                    line = line[end + 2:]
                     comment = 0
             while 1:
                 start, end = find_comment(line)
@@ -724,26 +749,26 @@ class AyaDictionary:
                     comment = 1
                     line = line[:start]
                     break
-                line = string.join((line[:start] + ' ' + line[end:]), '')
+                line = ''.join((line[:start], ' ', line[end:]))
             line = line_strip(line)
             if not line:
                 continue
-            if line[-1:] == '/':
-                logical_line += line[:-1]
+            if line.endswith('/'):
+                logical_line = ''.join((logical_line, line[:-1]))
             else:
-                logical_line += line
+                logical_line = ''.join((logical_line, line))
                 buffer = line
                 # preprosess
-                if buffer[0] == '#':
+                if buffer.startswith('#'):
                     buffer = line_strip(buffer[1:])
                     for (tag, target) in [('define', local_macro),
                                           ('globaldefine', self.global_macro)]:
-                        if buffer[:len(tag)] == tag:
+                        if buffer.startswith(tag):
                             buffer = line_strip(buffer[len(tag):])
                             i = 0
                             while i < len(buffer):
                                 if buffer[i] == ' ' or buffer[i] == '\t' or \
-                                   buffer[i:i+2] == '¡¡':
+                                   buffer[i:i + 2] == '¡¡':
                                     key = line_strip(buffer[:i])
                                     target[key] = line_strip(buffer[i:])
                                     break
@@ -755,14 +780,14 @@ class AyaDictionary:
                     logical_line = self.preprosess(macro, logical_line)
                 # multi statement
                 list_lines = self.split_line(line_strip(logical_line))
-                if len(list_lines) > 0:
+                if list_lines:
                     all_lines.extend(list_lines)
                 logical_line = '' # reset
         for line in all_lines:
             while 1:
                 pos = find_not_quoted(line, '¡¡')
                 if pos >= 0:
-                    line = string.join((line[:pos], ' ', line[pos+2:]), '')
+                    line = ''.join((line[:pos], ' ', line[pos + 2:]))
                 else:
                     break
         self.evaluate_lines(all_lines, os.path.split(file.name)[1])
@@ -772,15 +797,15 @@ class AyaDictionary:
         while 1:
             if not line:
                 break
-            pos = len(line) # not len(line)-1
+            pos = len(line) # not len(line) - 1
             token = ''
             for x in ['{', '}']:
                 pos_new = find_not_quoted(line, x)
-                if pos_new >= 0 and pos_new < pos:
+                if 0 <= pos_new < pos:
                     pos = pos_new
                     token = x
             new = line_strip(line[:pos])
-            line = line_strip(line[pos+len(token):])
+            line = line_strip(line[pos + len(token):])
             if new:
                 lines.append(new)
             if token != '':
@@ -792,7 +817,9 @@ class AyaDictionary:
             line = line.replace(key, macro[key])
         return line
 
-    __SPECIAL_CHARS = [r']', r'(', r')', r'[', r'+', r'-', r'*', r'/', r'=', r':', r';', r'!', r'{', r'}', r'%', r'&', r'#', r'"', r'<', r'>', r',', r'?']
+    __SPECIAL_CHARS = [r']', r'(', r')', r'[', r'+', r'-', r'*', r'/', r'=',
+                       r':', r';', r'!', r'{', r'}', r'%', r'&', r'#', r'"',
+                       r'<', r'>', r',', r'?']
 
     def evaluate_lines(self, lines, file_name):
         prev = None
@@ -810,18 +837,22 @@ class AyaDictionary:
                 else:
                     if prev is None:
                         if self.debug & 4:
-                            print 'syntax error in %s: unbalanced "{" at the top of file' % file_name
+                            print 'syntax error in %s: unbalanced "{" at ' \
+                                  'the top of file' % file_name
                     else:
                         if self.debug & 4:
-                            print 'syntax error in %s: unbalanced "{" at the bottom of function "%s"' % (file_name, prev)
+                            print 'syntax error in %s: unbalanced "{" at ' \
+                                  'the bottom of function "%s"' % \
+                                  (file_name, prev)
             elif line == '}':
                 if name is not None:
                     block_nest -= 1
                     if block_nest > 0:
                         function.append(line)
                     elif block_nest == 0:
-                        self.functions[name] = AyaFunction(self, name, function,
-                                                           option, debug=self.debug)
+                        self.functions[name] = AyaFunction(self, name,
+                                                           function, option,
+                                                           debug=self.debug)
                         # reset
                         prev = name
                         name = None
@@ -830,22 +861,26 @@ class AyaDictionary:
                 else:
                     if prev is None:
                         if self.debug & 4:
-                            print 'syntax error in %s: unbalanced "}" at the top of file' % file_name                    
+                            print 'syntax error in %s: unbalanced "}" at ' \
+                                  'the top of file' % file_name
                     else:
                         if self.debug & 4:
-                            print 'syntax error in %s: unbalanced "}" at the bottom of function "%s"' % (file_name, prev)
+                            print 'syntax error in %s: unbalanced "}" at ' \
+                                  'the bottom of function "%s"' % \
+                                  (file_name, prev)
                     block_nest = 0
             elif name is None:
                 colon = line.find(':')
                 if colon > 0:
-                    option = line[colon+1:].strip()
+                    option = line[colon + 1:].strip()
                     name = line[:colon].strip()
                 else:
                     name = line
                 for char in self.__SPECIAL_CHARS:
                     if name.find(char) >= 0:
                         if self.debug & 4:
-                            print 'illegal function name "%s" in %s' % (name, file_name)
+                            print 'illegal function name "%s" in %s' % \
+                                  (name, file_name)
                 function = []
             else:
                 if name is not None and block_nest > 0:
@@ -855,6 +890,7 @@ class AyaDictionary:
                         print 'syntax error in %s: %s' % (file_name, line)
 
 class AyaFunction:
+
     __TYPE_INT = 10
     __TYPE_FLOAT = 11
     __TYPE_DECISION = 12
@@ -897,7 +933,9 @@ class AyaFunction:
     __re_switch = re.compile('switch\s')
     __re_case = re.compile('case\s')
     __re_when = re.compile('when\s')
-    __SPECIAL_CHARS = [r']', r'(', r')', r'[', r'+', r'-', r'*', r'/', r'=', r':', r';', r'!', r'{', r'}', r'%', r'&', r'#', r'"', r'<', r'>', r',', r'?']
+    __SPECIAL_CHARS = [r']', r'(', r')', r'[', r'+', r'-', r'*', r'/', r'=',
+                       r':', r';', r'!', r'{', r'}', r'%', r'&', r'#', r'"',
+                       r'<', r'>', r',', r'?']
 
     def __init__(self, dic, name, lines, option, debug=0):
         self.dic = dic
@@ -937,15 +975,17 @@ class AyaFunction:
                 while 1:
                     current_line = lines[i]
                     if self.__re_if.match(current_line):
-                        condition_tokens = AyaStatement(current_line[2:].strip()).tokens
+                        condition_tokens = AyaStatement(
+                            current_line[2:].strip()).tokens
                         condition = self.parse_condition(condition_tokens)
                     elif self.__re_elseif.match(current_line):
-                        condition_tokens = AyaStatement(current_line[6:].strip()).tokens
+                        condition_tokens = AyaStatement(
+                            current_line[6:].strip()).tokens
                         condition = self.parse_condition(condition_tokens)
                     else:
                         condition = [self.__TYPE_CONDITION, None]
                     inner_block = []
-                    i, inner_block = self.get_block(lines, i+1)
+                    i, inner_block = self.get_block(lines, i + 1)
                     if condition is None:
                         inner_blocks = []
                         break
@@ -953,9 +993,9 @@ class AyaFunction:
                     entry.append(condition)
                     entry.append(self.parse(inner_block))
                     inner_blocks.append(entry)
-                    if i+1 >= len(lines):
+                    if i + 1 >= len(lines):
                         break
-                    next_line = lines[i+1]
+                    next_line = lines[i + 1]
                     if not self.__re_elseif.match(next_line) and \
                        next_line != 'else':
                         break
@@ -966,38 +1006,45 @@ class AyaFunction:
                 condition_tokens = AyaStatement(line[5:].strip()).tokens
                 condition = self.parse_condition(condition_tokens)
                 inner_block = []
-                i, inner_block = self.get_block(lines, i+1)
-                result.append([self.__TYPE_WHILE, [condition, self.parse(inner_block)]])
+                i, inner_block = self.get_block(lines, i + 1)
+                result.append([self.__TYPE_WHILE,
+                               [condition, self.parse(inner_block)]])
             elif self.__re_for.match(line):
                 inner_block = []
-                i, inner_block = self.get_block(lines, i+1)
+                i, inner_block = self.get_block(lines, i + 1)
                 end = find_not_quoted(line, ';')
                 if end < 0:
                     if self.debug & 4:
-                        print 'syntax error in function "%s": illegal for statement "%s"' % (self.name, line)
+                        print 'syntax error in function "%s": ' \
+                              'illegal for statement "%s"' % (self.name, line)
                 else:
                     init = self.parse([line[3:end].strip()])
-                    condition = line[end+1:].strip()
+                    condition = line[end + 1:].strip()
                     end = find_not_quoted(condition, ';')
                     if end < 0:
                         if self.debug & 4:
-                            print 'syntax error in function "%s": illegal for statement "%s"' % (self.name, line)
+                            print 'syntax error in function "%s": ' \
+                                  'illegal for statement "%s"' % (self.name, line)
                     else:
-                        reset = self.parse([condition[end+1:].strip()])
-                        condition_tokens = AyaStatement(condition[:end].strip()).tokens
+                        reset = self.parse([condition[end + 1:].strip()])
+                        condition_tokens = AyaStatement(
+                            condition[:end].strip()).tokens
                         condition = self.parse_condition(condition_tokens)
                         if condition is not None:
-                            result.append([self.__TYPE_FOR, [[init, condition, reset], self.parse(inner_block)]])
+                            result.append([self.__TYPE_FOR,
+                                           [[init, condition, reset],
+                                            self.parse(inner_block)]])
             elif self.__re_switch.match(line):
                 index = self.parse_token(line[6:].strip())
                 ##assert index[0] in [] # FIXME
                 inner_block = []
-                i, inner_block = self.get_block(lines, i+1)
-                result.append([self.__TYPE_SWITCH, [index, self.parse(inner_block)]])
+                i, inner_block = self.get_block(lines, i + 1)
+                result.append([self.__TYPE_SWITCH,
+                               [index, self.parse(inner_block)]])
             elif self.__re_case.match(line):
                 left = self.parse_token(line[4:].strip())
                 ## assert left[0] in [] # FIXME
-                i, block = self.get_block(lines, i+1)
+                i, block = self.get_block(lines, i + 1)
                 inner_blocks = []
                 j = 0
                 while 1:
@@ -1007,7 +1054,7 @@ class AyaFunction:
                     else: # 'others'
                         right = None
                     inner_block = []
-                    j, inner_block = self.get_block(block, j+1)
+                    j, inner_block = self.get_block(block, j + 1)
                     if right is not None:
                         argument = AyaArgument(right)
                         while argument.has_more_tokens():
@@ -1015,21 +1062,27 @@ class AyaFunction:
                             right = argument.next_token()
                             tokens = AyaStatement(right).tokens
                             if tokens[0] in ['-', '+']:
-                                min = self.parse_statement([tokens.pop(0), tokens.pop(0)])
+                                min = self.parse_statement([tokens.pop(0),
+                                                            tokens.pop(0)])
                             else:
                                 min = self.parse_statement([tokens.pop(0)])
                             max = min
                             if tokens:
                                 if tokens[0] != '-':
                                     if self.debug & 4:
-                                        print 'syntax error in function "%s": when %s' % (self.name, right)
+                                        print 'syntax error in function ' \
+                                              '"%s": when %s' % \
+                                              (self.name, right)
                                     continue
                                 else:
                                     tokens.pop(0)
                                 if len(tokens) > 2 or \
-                                   (len(tokens) == 2 and not tokens[0] in ['-', '+']):
+                                   (len(tokens) == 2 and \
+                                    not tokens[0] in ['-', '+']):
                                     if self.debug & 4:
-                                        print 'syntax error in function "%s": when %s' % (self.name, right)
+                                        print 'syntax error in function ' \
+                                              '"%s": when %s' % \
+                                              (self.name, right)
                                     continue
                                 else:
                                     max = self.parse_statement(tokens)
@@ -1041,9 +1094,9 @@ class AyaFunction:
                         entry.append(right)
                         entry.append(self.parse(inner_block))
                         inner_blocks.append(entry)
-                    if j+1 == len(block):
+                    if j + 1 == len(block):
                         break
-                    next_line = block[j+1]
+                    next_line = block[j + 1]
                     if not self.__re_when.match(next_line) and \
                        next_line != 'others':
                         break
@@ -1051,14 +1104,14 @@ class AyaFunction:
                 result.append([self.__TYPE_CASE, [left, inner_blocks]])
             elif find_not_quoted(line, ';') >= 0:
                 end = find_not_quoted(line, ';')
-                new_line = line[end+1:].strip()
+                new_line = line[end + 1:].strip()
                 line = line[:end].strip()
                 new_lines = lines[:i]
                 if line:
                     new_lines.append(line)
                 if new_line:
                     new_lines.append(new_line)
-                new_lines.extend(lines[i+1:])
+                new_lines.extend(lines[i + 1:])
                 lines = new_lines
                 continue
             elif self.is_substitution(line):
@@ -1068,14 +1121,16 @@ class AyaFunction:
                                    self.__TYPE_VARIABLE,
                                    self.__TYPE_TOKEN]:
                     if self.debug & 4:
-                        print 'syntax error in function "%s": illegall substitution "%s"' % (self.name, line)
+                        print 'syntax error in function "%s": ' \
+                              'illegall substitution "%s"' % (self.name, line)
                 else:
                     if left[0] == self.__TYPE_TOKEN: # this cannot be FUNCTION
                         left[0] = self.__TYPE_VARIABLE
                         left[1] = [left[1], None]
                     ope = [self.__TYPE_OPERATOR, tokens[1]]
                     right = self.parse_statement(tokens[2:])
-                    result.append([self.__TYPE_SUBSTITUTION, [left, ope, right]])
+                    result.append([self.__TYPE_SUBSTITUTION,
+                                   [left, ope, right]])
             elif self.is_inc_or_dec(line): # ++/--
                 ope = line[-2:]
                 var = self.parse_token(line[:-2])
@@ -1083,7 +1138,9 @@ class AyaFunction:
                                   self.__TYPE_VARIABLE,
                                   self.__TYPE_TOKEN]:
                     if self.debug & 4:
-                        print 'syntax error in function "%s": illegall increment/decrement "%s"' % (self.name, line)
+                        print 'syntax error in function "%s": ' \
+                              'illegall increment/decrement "%s"' % \
+                              (self.name, line)
                 else:
                     if var[0] == self.__TYPE_TOKEN:
                         var[0] = self.__TYPE_VARIABLE
@@ -1098,11 +1155,13 @@ class AyaFunction:
                 tokens = AyaStatement(line).tokens
                 if tokens[-1] == '"': # This is kluge.
                     if self.debug & 4:
-                        print 'syntax error in function "%s": unbalanced \'"\' or \'"\' in string %s' % (self.name, string.join(tokens, ''))
-                    token = string.join(tokens[:-1], '')
-                    if len(token) > 0 and token[0] == '"':
+                        print 'syntax error in function "%s": ' \
+                              'unbalanced \'"\' or \'"\' in string %s' % \
+                              (self.name, ''.join(tokens))
+                    token = ''.join(tokens[:-1])
+                    if token and token[0] == '"':
                         token = token[1:]
-                    if len(token) > 0:
+                    if token:
                         if token.find('%') < 0:
                             result.append([self.__TYPE_STRING_LITERAL, token])
                         else:
@@ -1119,7 +1178,8 @@ class AyaFunction:
         n_tokens = len(statement_tokens)
         statement = []
         if n_tokens == 1:
-            statement = [self.__TYPE_STATEMENT, self.parse_token(statement_tokens[0])]
+            statement = [self.__TYPE_STATEMENT,
+                         self.parse_token(statement_tokens[0])]
         elif statement_tokens[0] in ['+', '-']:
             tokens = ['0']
             tokens.extend(statement_tokens)
@@ -1143,36 +1203,44 @@ class AyaFunction:
                         ope_index = -1 - ope_index
                 finally:
                     statement_tokens.reverse()
-            if ope_index in [None, -1, 0, n_tokens-1]:
-                if statement_tokens[0][0] == '"' and \
-                   statement_tokens[0][-1] == '"' and \
-                   statement_tokens[-1][0] == '"' and \
-                   statement_tokens[-1][-1] == '"':
+            if ope_index in [None, -1, 0, n_tokens - 1]:
+                if statement_tokens[0].startswith('"') and \
+                   statement_tokens[0].endswith('"') and \
+                   statement_tokens[-1].startswith('"') and \
+                   statement_tokens[-1].endswith('"'):
                     if self.debug & 4:
-                        print 'syntax error in function "%s": \'"\' in string %s' % (self.name, string.join(statement_tokens))
-                    return self.parse_token(string.join(statement_tokens))
+                        print 'syntax error in function "%s": ' \
+                              '\'"\' in string %s' % \
+                              (self.name, ' '.join(statement_tokens))
+                    return self.parse_token(' '.join(statement_tokens))
                 else:
                     if self.debug & 4:
-                        print 'syntax error in function "%s": illegal statement "%s"' % (self.name, string.join(statement_tokens))
+                        print 'syntax error in function "%s": ' \
+                              'illegal statement "%s"' % \
+                              (self.name, ' '.join(statement_tokens))
                     return []
             else:
                 ope = [self.__TYPE_OPERATOR, statement_tokens[ope_index]]
                 if len(statement_tokens[:ope_index]) == 1:
-                    if statement_tokens[0][0] == '(':
+                    if statement_tokens[0].startswith('('):
                         tokens = AyaStatement(statement_tokens[0][1:-1]).tokens
                         left = self.parse_statement(tokens)
                     else:
-                        left = self.parse_token(statement_tokens[:ope_index][0])
+                        left = self.parse_token(
+                            statement_tokens[:ope_index][0])
                 else:
                     left = self.parse_statement(statement_tokens[:ope_index])
-                if len(statement_tokens[ope_index+1:]) == 1:
-                    if statement_tokens[-1][0] == '(':
-                        tokens = AyaStatement(statement_tokens[ope_index+1][1:-1]).tokens
+                if len(statement_tokens[ope_index + 1:]) == 1:
+                    if statement_tokens[-1].startswith('('):
+                        tokens = AyaStatement(
+                            statement_tokens[ope_index + 1][1:-1]).tokens
                         right = self.parse_statement(tokens)
                     else:
-                        right = self.parse_token(statement_tokens[ope_index+1:][0])
+                        right = self.parse_token(
+                            statement_tokens[ope_index + 1:][0])
                 else:
-                    right = self.parse_statement(statement_tokens[ope_index+1:])
+                    right = self.parse_statement(
+                        statement_tokens[ope_index + 1:])
                 statement = [self.__TYPE_STATEMENT, left, ope, right]
         return statement
 
@@ -1197,24 +1265,26 @@ class AyaFunction:
                     new_index = condition_tokens.index(ope)
                     if ope_index is None or new_index < ope_index:
                         ope_index = new_index
-            if ope_index in [None, -1, 0, n_tokens-1]:
+            if ope_index in [None, -1, 0, n_tokens - 1]:
                 if self.debug & 4:
-                    print 'syntax error in function "%s": illegal condition "%s"' % (self.name, string.join(condition_tokens))
+                    print 'syntax error in function "%s": ' \
+                          'illegal condition "%s"' % \
+                          (self.name, ' '.join(condition_tokens))
                 return None
             ope = [self.__TYPE_OPERATOR, condition_tokens[ope_index]]
             if len(condition_tokens[:ope_index]) == 1:
                 left = self.parse_token(condition_tokens[:ope_index][0])
             else:
                 left = self.parse_statement(condition_tokens[:ope_index])
-            if len(condition_tokens[ope_index+1:]) == 1:
-                right = self.parse_token(condition_tokens[ope_index+1:][0])
+            if len(condition_tokens[ope_index + 1:]) == 1:
+                right = self.parse_token(condition_tokens[ope_index + 1:][0])
             else:
-                right = self.parse_statement(condition_tokens[ope_index+1:])
+                right = self.parse_statement(condition_tokens[ope_index + 1:])
             condition = [self.__TYPE_CONDITION, [left, ope, right]]
         else:
             ope = [self.__TYPE_OPERATOR, condition_tokens[ope_index]]
             left = self.parse_condition(condition_tokens[:ope_index])
-            right = self.parse_condition(condition_tokens[ope_index+1:])
+            right = self.parse_condition(condition_tokens[ope_index + 1:])
             if left is not None and right is not None:
                 condition = [self.__TYPE_CONDITION, [left, ope, right]]
         return condition
@@ -1224,21 +1294,25 @@ class AyaFunction:
         arguments = []
         while argument.has_more_tokens():
             token = argument.next_token()
-            if token[0] == '&':
+            if token.startswith('&'):
                 result = self.parse_token(token[1:])
                 if result[0] == self.__TYPE_ARRAY:
                     arguments.append([self.__TYPE_ARRAY_POINTER, result[1]])
                 elif result[0] == self.__TYPE_VARIABLE:
                     arguments.append([self.__TYPE_VARIABLE_POINTER, result[1]])
                 elif result[0] == self.__TYPE_TOKEN:
-                    arguments.append([self.__TYPE_VARIABLE_POINTER, [result[1], None]])
+                    arguments.append([self.__TYPE_VARIABLE_POINTER,
+                                      [result[1], None]])
                 else:
                     if self.debug & 4:
-                        print 'syntax error in function "%s": illegal argument "%s"' % (self.name, token)
-            elif token[0] == '(':
-                if token[-1] != ')':
+                        print 'syntax error in function "%s": ' \
+                              'illegal argument "%s"' % (self.name, token)
+            elif token.startswith('('):
+                if not token.endswith(')'):
                     if self.debug & 4:
-                        print 'syntax error in function "%s": unbalanced "(" in the string(%s)' % (self.name, line)
+                        print 'syntax error in function "%s": ' \
+                              'unbalanced "(" in the string(%s)' % \
+                              (self.name, line)
                     return None
                 else:
                     statement = AyaStatement(token[1:-1])
@@ -1253,13 +1327,14 @@ class AyaFunction:
             result = [self.__TYPE_FLOAT, token]
         elif self.__re_d.match(token):
             result = [self.__TYPE_INT, token]
-        elif token[0] == '"':
+        elif token.startswith('"'):
             text = token[1:]
-            if text[-1] == '"':
+            if text.endswith('"'):
                 text = text[:-1]
             if text.count('"') > 0:
                 if self.debug & 4:
-                    print 'syntax error in function "%s": \'"\' in string "%s"' % (self.name, text)
+                    print 'syntax error in function "%s": ' \
+                          '\'"\' in string "%s"' % (self.name, text)
             if text.find('%') < 0:
                 result = [self.__TYPE_STRING_LITERAL, text]
             else:
@@ -1270,36 +1345,45 @@ class AyaFunction:
             if pos_parenthesis_open != -1 and \
                (pos_block_open == -1 or \
                 pos_parenthesis_open < pos_block_open): # function
-                if token[-1] != ')':
+                if not token.endswith(')'):
                     if self.debug & 4:
                         print 'syntax error: unbalnced "(" in "%s"' % token
                 else:
                     func_name = token[:pos_parenthesis_open]
-                    arguments = self.parse_argument(token[pos_parenthesis_open+1:-1])
+                    arguments = self.parse_argument(
+                        token[pos_parenthesis_open + 1:-1])
                     for char in self.__SPECIAL_CHARS:
                         if func_name.find(char) >=0:
                             if self.debug & 4:
-                                print 'illegal character "%s" in the name of function "%s"' % (char, token)
+                                print 'illegal character "%s" in ' \
+                                      'the name of function "%s"' % \
+                                      (char, token)
                             break
                     else:
-                        if self.dic.aya.get_system_functions().exists(func_name):
+                        if self.dic.aya.get_system_functions().exists(
+                            func_name):
                             if func_name == 'LOGGING':
-                                result = [self.__TYPE_SYSTEM_FUNCTION, [func_name, arguments, token[pos_parenthesis_open+1:-1]]]
+                                result = [self.__TYPE_SYSTEM_FUNCTION,
+                                          [func_name, arguments,
+                                           token[pos_parenthesis_open + 1:-1]]]
                             else:
-                                result = [self.__TYPE_SYSTEM_FUNCTION, [func_name, arguments]]
+                                result = [self.__TYPE_SYSTEM_FUNCTION,
+                                          [func_name, arguments]]
                         else:
-                            result = [self.__TYPE_FUNCTION, [func_name, arguments]]
+                            result = [self.__TYPE_FUNCTION,
+                                      [func_name, arguments]]
             elif pos_block_open != -1: # array
-                if token[-1] != ']':
+                if not token.endswith(']'):
                     if self.debug & 4:
                         print 'syntax error: unbalnced "[" in "%s"' % token
                 else:
                     array_name = token[:pos_block_open]
-                    index = self.parse_token(token[pos_block_open+1:-1])
+                    index = self.parse_token(token[pos_block_open + 1:-1])
                     for char in self.__SPECIAL_CHARS:
                         if array_name.find(char) >=0:
                             if self.debug & 4:
-                                print 'illegal character "%s" in the name of array "%s"' % (char, token)
+                                print 'illegal character "%s" in ' \
+                                      'the name of array "%s"' % (char, token)
                             break
                     else:
                         result = [self.__TYPE_ARRAY, [array_name, index]]
@@ -1307,7 +1391,10 @@ class AyaFunction:
                 for char in self.__SPECIAL_CHARS:
                     if token.find(char) >=0:
                         if self.debug & 4:
-                            print 'syntax error in function "%s": illegal character "%s" in the name of function/variable "%s"' % (self.name, char, token)
+                            print 'syntax error in function "%s": ' \
+                                  'illegal character "%s" in the name of ' \
+                                  'function/variable "%s"' % \
+                                  (self.name, char, token)
                         break
                 else:
                     result = [self.__TYPE_TOKEN, token]
@@ -1321,7 +1408,7 @@ class AyaFunction:
         else:
             namespace.put('_argc', len(argv))
             for i in range(len(argv)):
-                if type(argv[i]) is DictType:
+                if isinstance(argv[i], dict):
                     _argv.append(argv[i]['value'])
                 else:
                     _argv.append(argv[i])
@@ -1332,7 +1419,7 @@ class AyaFunction:
             result = ''
         if argv:
             for i in range(len(argv)):
-                if type(argv[i]) is DictType:
+                if isinstance(argv[i], dict):
                     value = _argv[i]
                     name = argv[i]['name']
                     namespace = argv[i]['namespace']
@@ -1347,16 +1434,18 @@ class AyaFunction:
         i = 0
         while i < n_lines:
             line = lines[i]
-            if len(line) < 1:
+            if not line:
                 i += 1
                 continue
-            if line[0] in [self.__TYPE_DECISION, self.__TYPE_RETURN, self.__TYPE_BREAK, self.__TYPE_CONTINUE] or \
-               self.status in [self.__CODE_RETURN, self.__CODE_BREAK, self.__CODE_CONTINUE]:
-                if len(alternatives) > 0:
+            if line[0] in [self.__TYPE_DECISION, self.__TYPE_RETURN,
+                           self.__TYPE_BREAK, self.__TYPE_CONTINUE] or \
+               self.status in [self.__CODE_RETURN, self.__CODE_BREAK,
+                               self.__CODE_CONTINUE]:
+                if alternatives:
                     if is_inner_block:
                         if index_to_return < 0:
                             result.append(random.choice(alternatives))
-                        elif index_to_return <= len(alternatives)-1:
+                        elif index_to_return <= len(alternatives) - 1:
                             result.append(alternatives[index_to_return])
                         else: # out of range
                             result.append('')
@@ -1377,7 +1466,8 @@ class AyaFunction:
                     break
             elif line[0] == self.__TYPE_BLOCK:
                 inner_func = line[1]
-                local_namespace = AyaNamespace(self.dic.aya, namespace, debug=self.debug)
+                local_namespace = AyaNamespace(self.dic.aya, namespace,
+                                               debug=self.debug)
                 result_of_inner_func = self.evaluate(local_namespace,
                                                      inner_func, -1, 1)
                 if result_of_inner_func:
@@ -1392,10 +1482,12 @@ class AyaFunction:
                 else:
                     type_float = 0
                 ##assert right[0] == self.__TYPE_STATEMENT
-                right_result = self.evaluate_statement(namespace, right, type_float)
+                right_result = self.evaluate_statement(namespace, right,
+                                                       type_float)
                 if ope != '=' and ope != ':=':
                     left_result = self.evaluate_token(namespace, left) 
-                    right_result = self.operation(left_result, ope[0], right_result, type_float)
+                    right_result = self.operation(left_result, ope[0],
+                                                  right_result, type_float)
                     ope = ope[1:]
                 self.substitute(namespace, left, ope, right_result)
             elif line[0] == self.__TYPE_INC or \
@@ -1409,7 +1501,7 @@ class AyaFunction:
                 var = line[1]
                 ## assert var[0] in [self.__TYPE_ARRAY, self.__TYPE_VARIABLE]
                 var_name = var[1][0]
-                if var_name[0] == '_':
+                if var_name.startswith('_'):
                     target_namespace = namespace
                 else:
                     target_namespace = self.dic.aya.get_global_namespace()
@@ -1420,15 +1512,16 @@ class AyaFunction:
                         index = int(index)
                     except:
                         if self.debug & 4:
-                            print 'index of array has to be integer: %s[%s]' % (var_name, var[1][1][0])
+                            print 'index of array has to be integer: ' \
+                                  '%s[%s]' % (var_name, var[1][1][0])
                         return None
                 else:
                     index = None
-                if type(value) in [IntType, FloatType]:
+                if isinstance(value, int) or isinstance(value, float):
                     if ope == '++':
-                        target_namespace.put(var_name, int(value)+1, index)
+                        target_namespace.put(var_name, int(value) + 1, index)
                     elif ope == '--':
-                        target_namespace.put(var_name, int(value)-1, index)
+                        target_namespace.put(var_name, int(value) - 1, index)
                     else:
                         return None # should not reach here
                 else:
@@ -1445,9 +1538,11 @@ class AyaFunction:
                     assert condition[0] == self.__TYPE_CONDITION
                     if condition is None or \
                        self.evaluate_condition(namespace, condition) == 1:
-                        local_namespace = AyaNamespace(self.dic.aya, namespace, debug=self.debug)
+                        local_namespace = AyaNamespace(self.dic.aya, namespace,
+                                                       debug=self.debug)
                         result_of_inner_block = self.evaluate(local_namespace,
-                                                              inner_block, -1, 1)
+                                                              inner_block,
+                                                              -1, 1)
                         if result_of_inner_block:
                             alternatives.append(result_of_inner_block)
                         break
@@ -1456,7 +1551,8 @@ class AyaFunction:
                 inner_block = line[1][1]
                 assert condition[0] == self.__TYPE_CONDITION
                 while self.evaluate_condition(namespace, condition):
-                    local_namespace = AyaNamespace(self.dic.aya, namespace, debug=self.debug)
+                    local_namespace = AyaNamespace(self.dic.aya, namespace,
+                                                   debug=self.debug)
                     result_of_inner_block = self.evaluate(local_namespace,
                                                           inner_block, -1, 1)
                     if result_of_inner_block is not None:
@@ -1476,7 +1572,8 @@ class AyaFunction:
                 self.evaluate(namespace, init, -1, 1)
                 assert condition[0] == self.__TYPE_CONDITION
                 while self.evaluate_condition(namespace, condition):
-                    local_namespace = AyaNamespace(self.dic.aya, namespace, debug=self.debug)
+                    local_namespace = AyaNamespace(self.dic.aya, namespace,
+                                                   debug=self.debug)
                     result_of_inner_block = self.evaluate(local_namespace,
                                                           inner_block, -1, 1)
                     if result_of_inner_block is not None:
@@ -1496,7 +1593,8 @@ class AyaFunction:
                     index = int(index)
                 except ValueError:
                     index = 0
-                local_namespace = AyaNamespace(self.dic.aya, namespace, debug=self.debug)
+                local_namespace = AyaNamespace(self.dic.aya, namespace,
+                                               debug=self.debug)
                 result_of_inner_block = self.evaluate(local_namespace,
                                                       inner_block, index, 1)
                 if result_of_inner_block:
@@ -1509,14 +1607,15 @@ class AyaFunction:
                 for j in range(n_blocks):
                     entry = inner_blocks[j]
                     inner_block = entry[1]
-                    local_namespace = AyaNamespace(self.dic.aya, namespace, debug=self.debug)
+                    local_namespace = AyaNamespace(self.dic.aya, namespace,
+                                                   debug=self.debug)
                     if entry[0] is not None:
                         min, max = entry[0]
                         min = self.evaluate_statement(namespace, min, 1)
                         max = self.evaluate_statement(namespace, max, 1)
-                        if left >= min and left <= max:
-                            result_of_inner_block = self.evaluate(local_namespace,
-                                                                  inner_block, -1, 1)
+                        if min <= left <= max:
+                            result_of_inner_block = self.evaluate(
+                                local_namespace, inner_block, -1, 1)
                             if result_of_inner_block:
                                 alternatives.append(result_of_inner_block)
                                 break
@@ -1546,7 +1645,7 @@ class AyaFunction:
                 else:
                     for index in range(len(result)):
                         current = self.sequential[1][index]
-                        if current < len(result[index])-1:
+                        if current < len(result[index]) - 1:
                             self.sequential[1][index] = current + 1
                             break
                         else:
@@ -1558,13 +1657,13 @@ class AyaFunction:
                 if self.nonoverlap[0] != list:
                     self.nonoverlap[0] = list
                     self.nonoverlap[2] = []
-                if len(self.nonoverlap[2]) == 0:
+                if not self.nonoverlap[2]:
                     self.nonoverlap[2].append([0] * len(result))
                     while 1:
                         new = []
                         new.extend(self.nonoverlap[2][-1])
                         for index in range(len(result)):
-                            if new[index] < len(result[index])-1:
+                            if new[index] < len(result[index]) - 1:
                                 new[index] += 1
                                 self.nonoverlap[2].append(new)
                                 break
@@ -1582,16 +1681,16 @@ class AyaFunction:
                     result[index] = result[index][self.nonoverlap[1][index]]
                 else:
                     result[index] = random.choice(result[index])
-        if len(result) == 0:
+        if not result:
             return None
         elif len(result) == 1:
             return result[0]
         else:
-            return string.join([str(s) for s in result], '')
+            return ''.join([str(s) for s in result])
 
     def substitute(self, namespace, left, ope, right):
         var_name = left[1][0]
-        if var_name[0] == '_':
+        if var_name.startswith('_'):
             target_namespace = namespace
         else:
             target_namespace = self.dic.aya.get_global_namespace()
@@ -1608,7 +1707,7 @@ class AyaFunction:
                 if ope == '=':
                     elem = right
                 elif ope == ':=':
-                    if type(right) is IntType:
+                    if isinstance(right, int):
                         elem = float(right)
                     else:
                         elem = right
@@ -1631,10 +1730,10 @@ class AyaFunction:
                     result = func.call()
                 elif system_functions.exists(token[1]):
                     result = system_functions.call(namespace, token[1], [])
-                elif token[1][:6] == 'random': # ver.3
+                elif token[1].startswith('random'): # ver.3
                     result = int(random.randrange(0, 100, 1))
                 else:
-                    if token[1][0] == '_':
+                    if token[1].startswith('_'):
                         target_namespace = namespace
                     else:
                         target_namespace = self.dic.aya.get_global_namespace()
@@ -1652,8 +1751,9 @@ class AyaFunction:
             system_functions = self.dic.aya.get_system_functions()
             func_name = token[1][0]
             ##assert system_functions.exists(func_name)
-            ##raise Exception(string.join(('function ', func_name, ' not found.'), ''))
-            arguments = self.evaluate_argument(namespace, func_name, token[1][1], 1)
+            ##raise Exception(''.join(('function ', func_name, ' not found.')))
+            arguments = self.evaluate_argument(namespace, func_name,
+                                               token[1][1], 1)
             if func_name == 'CALLBYNAME':
                 func = self.dic.get_function(arguments[0])
                 system_functions = self.dic.aya.get_system_functions()
@@ -1672,12 +1772,13 @@ class AyaFunction:
             func_name = token[1][0]
             func = self.dic.get_function(func_name)
             ##assert func is not None:
-            ##raise Exception(string.join(('function ', func_name, ' not found.'), ''))
-            arguments = self.evaluate_argument(namespace, func_name, token[1][1], 0)
+            ##raise Exception(''.join(('function ', func_name, ' not found.')))
+            arguments = self.evaluate_argument(namespace, func_name,
+                                               token[1][1], 0)
             result = func.call(arguments)
         elif token[0] == self.__TYPE_ARRAY:
             var_name = token[1][0]
-            if var_name[0] == '_':
+            if var_name.startswith('_'):
                 target_namespace = namespace
             else:
                 target_namespace = self.dic.aya.get_global_namespace()
@@ -1686,12 +1787,13 @@ class AyaFunction:
                 index = int(index)
             except:
                 if self.debug & 4:
-                    print 'index of array has to be integer: %s[%s]' % (var_name, token[1][1])
+                    print 'index of array has to be integer: %s[%s]' % \
+                          (var_name, token[1][1])
             else:
                 if var_name == 'random': # Ver.3
                     result = int(random.randrange(0, index, 1))
                 elif var_name == 'ascii': # Ver.3
-                    if index >= 0 and index < 0x80: ## FIXME
+                    if 0 <= index < 0x80: ## FIXME
                         result = chr(index)
                     else:
                         result = ' '
@@ -1699,7 +1801,7 @@ class AyaFunction:
                     result = target_namespace.get(var_name, index)
         elif token[0] == self.__TYPE_VARIABLE:
             var_name = token[1][0]
-            if var_name[0] == '_':
+            if var_name.startswith('_'):
                 target_namespace = namespace
             else:
                 target_namespace = self.dic.aya.get_global_namespace()
@@ -1707,7 +1809,7 @@ class AyaFunction:
                 result = target_namespace.get(var_name)
         elif token[0] == self.__TYPE_ARRAY_POINTER:
             var_name = token[1][0]
-            if var_name[0] == '_':
+            if var_name.startswith('_'):
                 target_namespace = namespace
             else:
                 target_namespace = self.dic.aya.get_global_namespace()
@@ -1716,12 +1818,13 @@ class AyaFunction:
                 index = int(index)
             except:
                 if self.debug & 4:
-                    print 'index of array has to be integer: %s[%s]' % (var_name, token[1][1])
+                    print 'index of array has to be integer: %s[%s]' % \
+                          (var_name, token[1][1])
             else:
                 if var_name == 'random': # Ver.3
                     result = int(random.randrange(0, index, 1))
                 elif var_name == 'ascii': # Ver.3
-                    if index >= 0 and index < 0x80: ## FIXME
+                    if 0 <= index < 0x80: ## FIXME
                         result = chr(index)
                     else:
                         result = ' '
@@ -1733,7 +1836,7 @@ class AyaFunction:
                               'value': value}
         elif token[0] == self.__TYPE_VARIABLE_POINTER:
             var_name = token[1][0]
-            if var_name[0] == '_':
+            if var_name.startswith('_'):
                 target_namespace = namespace
             else:
                 target_namespace = self.dic.aya.get_global_namespace()
@@ -1772,12 +1875,12 @@ class AyaFunction:
         elif ope[1] == '!=':
             result = (left_result != right_result)
         elif ope[1] == '_in_':
-            if type(right_result) is StringType and type(left_result) is StringType:
+            if isinstance(right_result, str) and isinstance(left_result, str):
                 result = (right_result.find(left_result) >= 0)
             else:
                 result = 0
         elif ope[1] == '!_in_':
-            if type(right_result) is StringType and type(left_result) is StringType:
+            if isinstance(right_result, str) and isinstance(left_result, str):
                 result = (right_result.find(left_result) == -1)
             else:
                 result = 0
@@ -1809,7 +1912,7 @@ class AyaFunction:
             left = self.evaluate_token(namespace, statement)
         ##else:
         ##    if self.debug & 4:
-        ##        print 'illegal statement: %s' % string.join(statement[1])
+        ##        print 'illegal statement: %s' % ' '.join(statement[1])
         ##    return ''
         if num == 3:
             ##assert statement[2][0] == self.__TYPE_OPERATOR
@@ -1828,12 +1931,15 @@ class AyaFunction:
                 else:
                     right = int(float(token))
             elif type == self.__TYPE_STATEMENT:
-                right = self.evaluate_statement(namespace, statement[3], type_float)
+                right = self.evaluate_statement(namespace, statement[3],
+                                                type_float)
             else:
                 right = self.evaluate_token(namespace, statement[3])
             ##else:
             ##    if self.debug & 4:
-            ##        print 'illegal statement: %s' % string.join(statement[0][1], statement[1][1], statement[2][1])
+            ##        print 'illegal statement: %s' % \
+            ##              ' '.join((statement[0][1], statement[1][1],
+            ##                        statement[2][1]))
             ##    return ''            
             result = self.operation(left, ope, right, type_float)
         else:
@@ -1845,8 +1951,8 @@ class AyaFunction:
             if type_float:
                 left = float(left)
                 right = float(right)
-            elif ope != '+' or (type(left) is not StringType and \
-                                type(right) is not StringType):
+            elif ope != '+' or \
+                 (not isinstance(left, str) and not isinstance(right, str)):
                 left = int(left)
                 right = int(right)
             else:
@@ -1871,7 +1977,8 @@ class AyaFunction:
                 return left % right
         except:
             if self.debug & 4:
-                print 'illegal operation: %s' % string.join([str(left), str(ope), str(right)])
+                print 'illegal operation: %s' % \
+                      ' '.join((str(left), str(ope), str(right)))
             return ''
 
     def get_block(self, parent, startpoint):
@@ -1902,24 +2009,25 @@ class AyaFunction:
         while startpoint < len(line):
             pos = line.find('%', startpoint)
             if pos < 0:
-                buffer = string.join((buffer, line[startpoint:]), '')
+                buffer = ''.join((buffer, line[startpoint:]))
                 startpoint = len(line)
                 continue
             else:
-                buffer = string.join((buffer, line[startpoint:pos]), '')
+                buffer = ''.join((buffer, line[startpoint:pos]))
                 startpoint = pos
             endpoint = len(line)
             for char in self.__SPECIAL_CHARS:
-                pos = line.find(char, startpoint+2, endpoint)
-                if pos > 0 and pos < endpoint:
+                pos = line.find(char, startpoint + 2, endpoint)
+                if 0 < pos < endpoint:
                     endpoint = pos
-            if  line[startpoint+1] == '[': # history
+            if  line[startpoint + 1] == '[': # history
                 if line[endpoint] != ']':
                     if self.debug & 4:
-                        print 'unbalanced "%[" or illegal index in the string(%s)' % line
+                        print 'unbalanced "%[" or illegal index in ' \
+                              'the string(%s)' % line
                     buffer = ''
                     break
-                index_token = self.parse_token(line[startpoint+2:endpoint])
+                index_token = self.parse_token(line[startpoint + 2:endpoint])
                 index = self.evaluate_token(namespace, index_token)
                 try:
                     index = int(index)
@@ -1927,32 +2035,32 @@ class AyaFunction:
                     if self.debug & 4:
                         print 'illegal history index in the string(%s)' % line
                 else:
-                    if index >= 0 and index < len(history):
-                        buffer = string.join((buffer,
-                                              self.format(history[index])), '')
+                    if 0 <= index < len(history):
+                        buffer = ''.join((buffer, self.format(history[index])))
                 startpoint = endpoint + 1
                 continue
             replaced = 0
-            while endpoint > startpoint+1:
-                token = line[startpoint+1:endpoint]
+            while endpoint > startpoint + 1:
+                token = line[startpoint + 1:endpoint]
                 if token == 'random' or token == 'ascii': # Ver.3
                     if endpoint < len(line) and \
                        line[endpoint] == '[':
-                        end_of_block = line.find(']', endpoint+1)
+                        end_of_block = line.find(']', endpoint + 1)
                         if end_of_block < 0:
                             if self.debug & 4:
-                                print 'unbalanced "[" or illegal index in the string(%s)' % line
+                                print 'unbalanced "[" or illegal index in ' \
+                                      'the string(%s)' % line
                             startpoint = len(line)
                             buffer = ''
                             break
-                        index = self.parse_token(line[endpoint+1:end_of_block])
-                        content_of_var = self.evaluate_token(namespace, [self.__TYPE_ARRAY, [token, index]])
+                        index = self.parse_token(line[endpoint + 1:end_of_block])
+                        content_of_var = self.evaluate_token(
+                            namespace, [self.__TYPE_ARRAY, [token, index]])
                         if content_of_var is None:
                             content_of_var = ''
                         history.append(content_of_var)
-                        buffer = string.join((buffer,
-                                              self.format(content_of_var)), '')
-                        startpoint = end_of_block+1
+                        buffer = ''.join((buffer, self.format(content_of_var)))
+                        startpoint = end_of_block + 1
                         replaced = 1
                         break
                 func = self.dic.get_function(token)
@@ -1960,7 +2068,7 @@ class AyaFunction:
                 if func is not None or is_system_func:
                     if endpoint < len(line) and \
                        line[endpoint] == '(':
-                        end_of_parenthesis = line.find(')', endpoint+1)
+                        end_of_parenthesis = line.find(')', endpoint + 1)
                         if end_of_parenthesis < 0:
                             if self.debug & 4:
                                 print 'unbalanced "(" in the string(%s)' % line
@@ -1968,52 +2076,56 @@ class AyaFunction:
                             buffer = ''
                             break
                         func_name = token
-                        arguments = self.parse_argument(line[endpoint+1:end_of_parenthesis])
-                        arguments = self.evaluate_argument(namespace, func_name, arguments, is_system_func)
+                        arguments = self.parse_argument(
+                            line[endpoint + 1:end_of_parenthesis])
+                        arguments = self.evaluate_argument(
+                            namespace, func_name, arguments, is_system_func)
                         if is_system_func:
                             if func_name == 'CALLBYNAME':
                                 func = self.dic.get_function(arguments[0])
                                 if func:
                                     result_of_func = func.call()
                                 elif system_functions.exists(arguments[0]):
-                                    result_of_func = system_functions.call(namespace, arguments[0], [])
+                                    result_of_func = system_functions.call(
+                                        namespace, arguments[0], [])
                             elif func_name == 'LOGGING':
-                                arguments.insert(0, line[endpoint+1:end_of_parenthesis])
+                                arguments.insert(
+                                    0, line[endpoint + 1:end_of_parenthesis])
                                 arguments.insert(0, self.name)
                                 arguments.insert(0, self.dic.aya.logfile)
-                                result_of_func = system_functions.call(namespace, func_name, arguments)
+                                result_of_func = system_functions.call(
+                                    namespace, func_name, arguments)
                             else:
-                                result_of_func = system_functions.call(namespace, func_name, arguments)
+                                result_of_func = system_functions.call(
+                                    namespace, func_name, arguments)
                         else:
                             result_of_func = func.call(arguments)
                         if result_of_func is None:
                             result_of_func = ''
                         history.append(result_of_func)
-                        buffer = string.join((buffer,
-                                              self.format(result_of_func)), '')
-                        startpoint = end_of_parenthesis+1
+                        buffer = ''.join((buffer, self.format(result_of_func)))
+                        startpoint = end_of_parenthesis + 1
                         replaced = 1
                         break
                     elif func is not None:
                         result_of_func = func.call()
                         history.append(result_of_func)
-                        buffer = string.join((buffer,
-                                              self.format(result_of_func)), '')
+                        buffer = ''.join((buffer, self.format(result_of_func)))
                         startpoint = endpoint
                         replaced = 1
                         break
                     else:
-                        result_of_func = system_functions.call(namespace, token, [])
+                        result_of_func = system_functions.call(
+                            namespace, token, [])
                         if result_of_func is None:
                             result_of_func = ''
                         history.append(result_of_func)
-                        buffer = string.join((buffer,
-                                              self.format(result_of_func)), '')
+                        buffer = ''.join((buffer, self.format(result_of_func)))
                         startpoint = endpoint
                         replaced = 1
                         break
                 else:
-                    if token[0] == '_':
+                    if token.startswith('_'):
                         target_namespace = namespace
                     else:
                         target_namespace = self.dic.aya.get_global_namespace()
@@ -2021,15 +2133,18 @@ class AyaFunction:
                         have_index = 0
                         index = None
                         if endpoint < len(line) and line[endpoint] == '[':
-                            end_of_block = line.find(']', endpoint+1)
+                            end_of_block = line.find(']', endpoint + 1)
                             if end_of_block < 0:
                                 if self.debug & 4:
-                                    print 'unbalanced "[" or illegal index in the string(%s)' % line
+                                    print 'unbalanced "[" or ' \
+                                          'illegal index in the string(%s)' % \
+                                          line
                                 startpoint = len(line)
                                 buffer = ''
                                 break
                             have_index = 1
-                            index_token = self.parse_token(line[endpoint+1:end_of_block])
+                            index_token = self.parse_token(
+                                line[endpoint + 1:end_of_block])
                             index = self.evaluate_token(namespace, index_token)
                             try:
                                 index = int(index)
@@ -2040,8 +2155,8 @@ class AyaFunction:
                         if value is not None:
                             content_of_var = value
                             history.append(content_of_var)
-                            buffer = string.join((buffer,
-                                                  self.format(content_of_var)), '')
+                            buffer = ''.join((buffer,
+                                              self.format(content_of_var)))
                             if have_index:
                                 startpoint = end_of_block + 1
                             else:
@@ -2050,12 +2165,12 @@ class AyaFunction:
                             break
                 endpoint -= 1
             if not replaced:
-                buffer = string.join((buffer, line[startpoint]), '')
+                buffer = ''.join((buffer, line[startpoint]))
                 startpoint += 1
         return buffer
 
     def format(self, input):
-        if type(input) is FloatType:
+        if isinstance(input, float):
             result = str(round(input, 6))
         else:
             result = str(input)
@@ -2069,11 +2184,13 @@ class AyaFunction:
                 ## assert argument[i] in [] ## FIXME
                 arguments.append(argument[i][1][1])
             else:
-                arguments.append(self.evaluate_statement(namespace, argument[i], 1))
+                arguments.append(self.evaluate_statement(namespace,
+                                                         argument[i], 1))
         if is_system_func:
             if name == 'NAMETOVALUE' and \
                len(arguments) == 1: # this is kluge
-                arguments[0] = self.evaluate_statement(namespace, argument[0], 1)
+                arguments[0] = self.evaluate_statement(namespace,
+                                                       argument[0], 1)
         return arguments
 
     def is_substitution(self, line):
@@ -2091,7 +2208,7 @@ class AyaFunction:
     def is_inc_or_dec(self, line):
         if len(line) <= 2:
             return 0
-        if line[-2:] in ['++', '--']:
+        if line.endswith('++') or line.endswith('--'):
             return 1
         else:
             return 0
@@ -2215,7 +2332,8 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
                 if errno is not None:
                     self.errno = errno
                 if self.debug & 4:
-                    print string.join((str(name), ': called with too few argument(s)'), '')
+                    print ''.join((str(name),
+                                   ': called with too few argument(s)'))
                 return 0
             return 1
 
@@ -2274,13 +2392,13 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
         while i:
             mod = i % 2
             i /= 2
-            line = string.join((str(mod), line), '')
-        line = string.join((numsin, line), '')
+            line = ''.join((str(mod), line))
+        line = ''.join((numsin, line))
         return line
 
     def TOHEXSTR(self, namespace, argv):
         try:
-            return "%x" % int(argv[0])
+            return '%x' % int(argv[0])
         except:
             return ''
 
@@ -2339,7 +2457,7 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
             bytes = int(argv[2])
         except:
             return ''
-        return line[start:start+bytes]
+        return line[start:start + bytes]
 
     def REPLACE(self, namespace, argv):
         line = str(argv[0])
@@ -2354,7 +2472,7 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
             bytes = int(argv[2])
         except:
             return ''
-        return string.join((line[:start], line[start+bytes:]), '')
+        return ''.join((line[:start], line[start + bytes:]))
 
     def INSERT(self, namespace, argv):
         line = str(argv[0])
@@ -2365,7 +2483,7 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
         to_insert = str(argv[2])
         if start < 0:
             start = 0
-        return string.join((line[:start], to_insert, line[start:]), '')
+        return ''.join((line[:start], to_insert, line[start:]))
 
     def MSTRLEN(self, namespace, argv):
         line = str(argv[0])
@@ -2453,7 +2571,7 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
                 n = 2
             i += n
             count += 1
-        return string.join((line[:start], line[end:]), '')
+        return ''.join((line[:start], line[end:]))
 
     def MINSERT(self, namespace, argv):
         line = str(argv[0])
@@ -2478,7 +2596,7 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
                     n = 2
                 i += n
                 count += 1
-        return string.join((line[:start], to_insert, line[start:]), '')
+        return ''.join((line[:start], to_insert, line[start:]))
 
     def CUTSPACE(self, namespace, argv):
         return line_strip(str(argv[0]))
@@ -2508,11 +2626,11 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
         return None
 
     def ARRAYSIZE(self, namespace, argv):
-        if type(argv[0]) is StringType:
+        if isinstance(argv[0], str):
             line = argv[0]
             if not line or line == '':
                 value = 0
-            elif line[0] == '"' and line[-1] == '"':
+            elif line.startswith('"') and line.endswith('"'):
                 value = line.count(',') + 1
             else:
                 target_namespace = self.select_namespace(namespace, line)
@@ -2543,21 +2661,20 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
         if argv[0] is None:
             return None
         logfile = argv[0]
-        line = string.join(('> function ', str(argv[1]), ' ¡§ ', str(argv[2])), '')
+        line = ''.join(('> function ', str(argv[1]), ' ¡§ ', str(argv[2])))
         if argv[3] is not None:
-            line = string.join((line, ' = '), '')
-            if type(argv[3]) is IntType or \
-               type(argv[3]) is FloatType:
-                line = string.join((line, str(argv[3])), '')
+            line = ''.join((line, ' = '))
+            if isinstance(argv[3], int) or isinstance(argv[3], float):
+                line = ''.join((line, str(argv[3])))
             else:
-                line = string.join((line, '"', str(argv[3]), '"'), '')
-        line = string.join((line, '\n'), '')
+                line = ''.join((line, '"', str(argv[3]), '"'))
+        line = ''.join((line, '\n'))
         logfile.write(line)
         logfile.write('\n')
         return None
 
     def RAND(self, namespace, argv):
-        if len(argv) == 0:
+        if not argv:
             return int(random.randrange(0, 100, 1))
         else:
             try:
@@ -2572,13 +2689,13 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
         except:
             return ''
         index = int(argv[0])
-        if index >= 0 and index < 0x80: ## FIXME
+        if 0 <= index < 0x80: ## FIXME
             return chr(index)
         else:
             return ' '
 
     def IASC(self, namespace, argv):
-        if type(argv[0]) is not StringType:
+        if isinstance(argv[0], str):
             return -1
         try:
             char = argv[0][0]
@@ -2600,32 +2717,31 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
 
     def ROUND(self, namespace, argv):
         try:
-            value = math.floor(float(argv[0])+0.5)
+            value = math.floor(float(argv[0]) + 0.5)
         except:
             return -1
         return int(value)
 
     def ISINSIDE(self, namespace, argv):
-        if argv[0] >= argv[1] and argv[0] <= argv[2]:
+        if argv[1] <= argv[0] <= argv[2]:
             return 1
         else:
             return 0
 
     def ISINTEGER(self, namespace, argv):
-        if type(argv[0]) is IntType:
+        if isinstance(argv[0], int):
             return 1
         else:
             return 0
 
     def ISREAL(self, namespace, argv):
-        if type(argv[0]) is FloatType or \
-           type(argv[0]) is IntType:
+        if isinstance(argv[0], float) or isinstance(argv[0], int):
             return 1
         else:
             return 0
 
     def ISFUNCTION(self, namespace, argv):
-        if type(argv[0]) is not StringType:
+        if not isinstance(argv[0], str):
             return 0
         elif self.aya.dic.get_function(argv[0]) is not None:
             return 1
@@ -2714,7 +2830,7 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
             return ''
 
     def REQ_VALUE(self, namespace, argv):
-        if type(argv[0]) is IntType:
+        if isinstance(argv[0], int):
             name = self.REQ_HEADER(namespace, [argv[0]])
         else:
             name = str(argv[0])
@@ -2744,7 +2860,10 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
         return None
 
     def REQUESTLIB(self, namespace, argv):
-        response = self.aya.saori_library.request(str(argv[0]), unicode(str(argv[1]), 'EUC-JP', 'ignore').encode('Shift_JIS', 'ignore')) ## FIXME
+        response = self.aya.saori_library.request(
+            str(argv[0]),
+            unicode(str(argv[1]), 'EUC-JP', 'ignore').encode('Shift_JIS',
+                                                             'ignore')) ## FIXME
         header = StringIO.StringIO(response)
         line = header.readline()
         self.saori_statuscode = ''
@@ -2764,7 +2883,7 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
                 colon = line.find(':')
                 if colon >= 0:
                     key = line_strip(line[:colon])
-                    value = line_strip(line[colon+1:])
+                    value = line_strip(line[colon + 1:])
                     if key:
                         self.saori_header.append(key)
                         self.saori_value[key] = value
@@ -2786,7 +2905,7 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
 
     def LIB_VALUE(self, namespace, argv):
         result = ''
-        if type(argv[0]) is IntType:
+        if isinstance(argv[0], int):
             header_list = self.saori_header
             if header_list and int(argv[0]) < len(header_list):
                 key = header_list[int(argv[0])]
@@ -2835,12 +2954,14 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
         result = -1
         if self.aya.filelist.has_key(norm_path):
             file = self.aya.filelist[norm_path]
-            result = unicode(file.readline(), 'Shift_JIS', 'ignore').encode('EUC-JP', 'ignore') ## FIXME
+            result = unicode(
+                file.readline(), 'Shift_JIS', 'ignore').encode('EUC-JP',
+                                                               'ignore') ## FIXME
             if not result:
                 result = -1
-            elif result[-2:] == '\r\n':
+            elif result.endswith('\r\n'):
                 result = result[:-2]
-            elif result[-1] == '\n':
+            elif result.endswith('\n'):
                 result = result[:-1]
         return result
 
@@ -2848,10 +2969,11 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
         filename = str(argv[0]).replace('\\', '/').lower()
         path = os.path.join(self.aya.aya_dir, filename)
         norm_path = os.path.normpath(path)
-        data = string.join((str(argv[1]), '\n'), '')
+        data = ''.join((str(argv[1]), '\n'))
         if self.aya.filelist.has_key(norm_path):
             file = self.aya.filelist[norm_path]
-            data = unicode(data, 'EUC-JP', 'ignore').encode('Shift_JIS', 'ignore') ## FIXME
+            data = unicode(
+                data, 'EUC-JP', 'ignore').encode('Shift_JIS', 'ignore') ## FIXME
             file.write(data)
         return None
 
@@ -2862,14 +2984,15 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
         data = str(argv[1])
         if self.aya.filelist.has_key(norm_path):
             file = self.aya.filelist[norm_path]
-            data = unicode(data, 'EUC-JP', 'ignore').encode('Shift_JIS', 'ignore') ## FIXME
+            data = unicode(
+                data, 'EUC-JP', 'ignore').encode('Shift_JIS', 'ignore') ## FIXME
             file.write(data)
         return None
 
     def FCOPY(self, namespace, argv):
         src = str(argv[0]).replace('\\', '/').lower()
         head, tail = os.path.split(src)
-        dst = string.join((str(argv[1]).replace('\\', '/').lower(), '/', tail), '')
+        dst = ''.join((str(argv[1]).replace('\\', '/').lower(), '/', tail))
         src_path = os.path.join(self.aya.aya_dir, src)
         dst_path = os.path.join(self.aya.aya_dir, dst)
         result = 0
@@ -2892,7 +3015,7 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
     def FMOVE(self, namespace, argv):
         src = str(argv[0]).replace('\\', '/').lower()
         head, tail = os.path.split(src)
-        dst = string.join((str(argv[1]).replace('\\', '/').lower(), '/', tail), '')
+        dst = ''.join((str(argv[1]).replace('\\', '/').lower(), '/', tail))
         src_path = os.path.join(self.aya.aya_dir, src)
         dst_path = os.path.join(self.aya.aya_dir, dst)
         result = 0
@@ -3022,10 +3145,10 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
             path = os.path.join(self.aya.aya_dir, dirname, list[index])
             mode = os.stat(path)[ST_MODE]
             if S_ISDIR(mode):
-                result = string.join((result, '\\'), '')
+                result = ''.join((result, '\\'))
             result += list[index]
-            if index != len(list)-1:
-                result = string.join((result, separator), '')
+            if index != len(list) - 1:
+                result = ''.join((result, separator))
         return result
 
     def select_math_type(self, value):
@@ -3035,7 +3158,7 @@ class AyaSystemFunctions: ## FIXME: EUC-JP -> Unicode (STRLEN, etc.)
             return value
 
     def select_namespace(self, namespace, name):
-        if name[0] == '_':
+        if name.startswith('_'):
             return namespace
         else:
             return self.aya.get_global_namespace()
@@ -3094,6 +3217,7 @@ class AyaNamespace:
         return result
 
 class AyaGlobalNamespace(AyaNamespace):
+
     __SYS_VARIABLES = ['year', 'month', 'day', 'weekday',
                        'hour', '12hour', 'ampm', 'minute', 'second',
                        'systemuptickcount', 'systemuptime',
@@ -3120,7 +3244,7 @@ class AyaGlobalNamespace(AyaNamespace):
         elif name == 'day':
             return t[2]
         elif name == 'weekday':
-            return (t[6]+1) % 7 
+            return (t[6] + 1) % 7 
         elif name == 'hour':
             return t[3]
         elif name == '12hour':
@@ -3135,13 +3259,13 @@ class AyaGlobalNamespace(AyaNamespace):
         elif name == 'second':
             return t[5]
         elif name == 'systemuptickcount':
-            return int(past*1000.0)
+            return int(past * 1000.0)
         elif name == 'systemuptime':
             return int(past)
         elif name == 'systemuphour':
-            return int(past/60.0/60.0)
+            return int(past / 60.0 / 60.0)
         elif name == 'systemupminute':
-            return int(past/60.0) % 60
+            return int(past / 60.0) % 60
         elif name == 'systemupsecond':
             return int(past) % 60
         elif name == 'memoryload' or \
@@ -3165,31 +3289,29 @@ class AyaGlobalNamespace(AyaNamespace):
         except:
             return 1
         line = file.readline()
-        if line[:14] != '# Format: v1.0' and \
-           line[:14] != '# Format: v1.1':
+        if not line.startswith('# Format: v1.0') and \
+           not line.startswith('# Format: v1.1'):
             file.close()
             return 1
         while 1:
             line = file.readline()
             if not line:
                 break
-            if len(line) == 0:
-                break
             comma = line.find(',')
             if comma >= 0:
                 key = line[:comma]
             else:
                 continue
-            value = line[comma+1:].strip()
+            value = line[comma + 1:].strip()
             comma = find_not_quoted(value, ',')
             if comma >= 0:
-                separator = value[comma+1:].strip()
+                separator = value[comma + 1:].strip()
                 separator = separator[1:-1]
                 value = value[:comma].strip()
                 value = value[1:-1]
                 self.put(key, str(value))
                 self.table[key].set_separator(str(separator))
-            elif value[0] == '"': # Format: v1.0
+            elif value.startswith('"'): # Format: v1.0
                 value = value[1:-1]
                 self.put(key, str(value))
             elif value != 'None':
@@ -3213,10 +3335,11 @@ class AyaGlobalNamespace(AyaNamespace):
         for key in self.table.keys():
             line = self.table[key].dump()
             if line is not None:
-                file.write(string.join((line, '\n'), ''))
+                file.write(''.join((line, '\n')))
         file.close()
 
 class AyaStatement:
+
     __SPECIAL_CHARS = '=+-*/<>|&!:'
 
     def __init__(self, line):
@@ -3243,20 +3366,20 @@ class AyaStatement:
                     self.append_unless_empty(line[token_startpoint:i].strip())
                     token_startpoint = i
                 position = i
-                while position < length-1:
+                while position < length - 1:
                     position += 1
                     if line[position] == '"':
                         break
                 i = position
                 if block_nest_level == 0:
-                    self.tokens.append(line[token_startpoint:position+1])
+                    self.tokens.append(line[token_startpoint:position + 1])
                     token_startpoint = position + 1
                 i += 1
             elif block_nest_level == 0 and (c == ' ' or c == '\t'):
                 self.append_unless_empty(line[token_startpoint:i].strip())
                 i += 1
                 token_startpoint = i
-            elif block_nest_level == 0 and line[i:i+2] == '¡¡':
+            elif block_nest_level == 0 and line[i:i + 2] == '¡¡':
                 self.append_unless_empty(line[token_startpoint:i].strip())
                 i += 2
                 token_startpoint = i
@@ -3277,16 +3400,16 @@ class AyaStatement:
                 ope_list = [':=', '+=', '-=', '*=', '/=', '%=',
                             '<=', '>=', '==', '!=', '&&', '||',
                             '+:=', '-:=', '*:=', '/:=', '%:=']
-                if line[i:i+2] in ope_list:
-                    self.tokens.append(line[i:i+2])
+                if line[i:i + 2] in ope_list:
+                    self.tokens.append(line[i:i + 2])
                     i += 2
                     token_startpoint = i
-                elif line[i:i+3] in ope_list:
-                    self.tokens.append(line[i:i+3])
+                elif line[i:i + 3] in ope_list:
+                    self.tokens.append(line[i:i + 3])
                     i += 3
                     token_startpoint = i
                 else:
-                    self.tokens.append(line[i:i+1])
+                    self.tokens.append(line[i:i + 1])
                     i += 1
                     token_startpoint = i
             else:
@@ -3295,7 +3418,7 @@ class AyaStatement:
         self.n_tokens = len(self.tokens)
 
     def append_unless_empty(self, token):
-        if len(token) > 0:
+        if token:
             self.tokens.append(token)
 
     def has_more_tokens(self):
@@ -3312,6 +3435,7 @@ class AyaStatement:
         return result
 
 class AyaVariable:
+
     __TYPE_STRING = 0
     __TYPE_INT = 1
     __TYPE_REAL = 2
@@ -3350,7 +3474,7 @@ class AyaVariable:
         return len(self.array)
 
     def get(self, index=None):
-        if index >= 0 and index < len(self.array):
+        if 0 <= index < len(self.array):
             value = self.array[index]
             if self.type == self.__TYPE_STRING:
                 return str(value)
@@ -3377,13 +3501,13 @@ class AyaVariable:
     def put(self, value, index=None):
         if index is None:
             self.line = str(value)
-            if type(value) == StringType:
+            if isinstance(value, str):
                 self.type = self.__TYPE_STRING
-            elif type(value) == IntType:
+            elif isinstance(value, int):
                 self.type = self.__TYPE_INT
-            elif type(value) == FloatType:
+            elif isinstance(value, float):
                 self.type = self.__TYPE_REAL
-            elif type(value) == ListType:
+            elif isinstance(value, list):
                 self.type = self.__TYPE_ARRAY
                 self.array = value
             self.reset()
@@ -3394,20 +3518,22 @@ class AyaVariable:
                 self.line = ''
                 for i in range(len(self.array)):
                     if i == index:
-                        self.line = string.join((self.line, str(value)), '')
+                        self.line = ''.join((self.line, str(value)))
                     else:
-                        self.line = string.join((self.line, self.array[i]), '')
+                        self.line = ''.join((self.line, self.array[i]))
                     if i != len(self.array)-1:
-                        self.line = string.join((self.line, self.separator), '')
+                        self.line = ''.join((self.line, self.separator))
                 if index >= len(self.array):
-                    for i in range(len(self.array), index+1):
+                    for i in range(len(self.array), index + 1):
                         if i == index:
-                            self.line = string.join((self.line, self.separator, str(value)), '')
+                            self.line = ''.join((self.line, self.separator,
+                                                 str(value)))
                         else:
-                            self.line = string.join((self.line, self.separator, ''), '')
+                            self.line = ''.join((self.line, self.separator,
+                                                 ''))
                 self.reset()
             elif self.type == self.__TYPE_ARRAY:
-                if index >= 0 and index < len(self.array):
+                if 0 <= index < len(self.array):
                     self.array[index] = value
             else:
                 pass # ERROR
@@ -3503,15 +3629,16 @@ class AyaSaoriLibrary:
             result = self.saori_list[name].request(req)
         return result
 
+
 def test(dir, function, argv):
     aya = Shiori('aya.dll')
     aya.load(dir)
     result = aya.dic.get_function(function).call(argv)
     print str(result)
 
-if __name__ == "__main__":
-    USAGE= "Usage(1): aya.py <dir> <function> [<arguments>]\n" \
-           "Usage(2): aya.py encrypt <in_file> <out_file>"
+if __name__ == '__main__':
+    USAGE= 'Usage(1): aya.py <dir> <function> [<arguments>]\n' \
+           'Usage(2): aya.py encrypt <in_file> <out_file>'
     if len(sys.argv) < 3:
         print USAGE
     elif sys.argv[1] == 'encrypt':
index cfcc9ed..d25a2d9 100644 (file)
@@ -20,6 +20,7 @@ try:
 except:
     _aya5 = None
 
+
 class Shiori:
 
     def __init__(self, dll_name):
@@ -33,18 +34,21 @@ class Shiori:
         if _aya5:
             if os.path.isfile(os.path.join(dir, 'aya5.txt')):
                 result = 205
-            elif dll_name is not None and os.path.isfile(os.path.join(dir, dll_name[:-3]+'txt')):
+            elif dll_name is not None and \
+                 os.path.isfile(os.path.join(dir,
+                                             ''.join((dll_name[:-3], 'txt')))):
                 result = 105
         return result
 
     def show_description(self):
-        sys.stdout.write('Shiori: Real Aya5 loader for ninix\n'
-                         '        Copyright (C) 2004 by linjian\n'
-                         '        Copyright (C) 2004, 2005 by Shyouzou Sugitani\n')
+        sys.stdout.write(
+            'Shiori: Real Aya5 loader for ninix\n'
+            '        Copyright (C) 2004 by linjian\n'
+            '        Copyright (C) 2004, 2005 by Shyouzou Sugitani\n')
 
     def get_charset(self, dir, dll_name): ## FIXME
         charset = 'Shift_JIS'
-        file = open(os.path.join(dir, dll_name[:-3] + 'txt'))
+        file = open(os.path.join(dir, ''.join((dll_name[:-3], 'txt'))))
         for line in file:
             pos = line.find('charset')
             if pos >= 0:
@@ -64,7 +68,7 @@ class Shiori:
             if self.dir[-1] == os.sep:
                 dir = self.dir
             else:
-                dir = self.dir + os.sep
+                dir = ''.join((self.dir, os.sep))
             _aya5.setcallback(self.saori_exist,
                               self.saori_load,
                               self.saori_unload,
@@ -124,7 +128,8 @@ class Shiori:
         if self.saori_list.has_key(saori):
             if self.saori_list[saori][1] == 0:
                 head, tail = os.path.split(saori)
-                self.saori_list[saori][1] = self.saori_list[saori][0].load(head)
+                self.saori_list[saori][1] = \
+                                          self.saori_list[saori][0].load(head)
             if self.saori_list[saori][1]:
                 result = self.saori_list[saori][0].request(req)
         return result
index 4ccd92a..1733e5e 100644 (file)
@@ -25,7 +25,7 @@ if os.environ.has_key('DISPLAY'):
     if not sys.modules.has_key('gtk'):
         try:
             import pygtk
-            pygtk.require("2.0")
+            pygtk.require('2.0')
         except ImportError:
             pass
     import gtk
@@ -38,6 +38,7 @@ else:
 import ninix.script
 from ninix.dll import SAORI
 
+
 class Saori(SAORI):
 
     def __init__(self):
@@ -72,7 +73,7 @@ class Saori(SAORI):
                 line = line.strip()
                 if not line:
                     continue
-                if line[:2] == '//':
+                if line.startswith('//'):
                     continue
                 start = line.find('[')
                 if start >= 0:
@@ -82,12 +83,12 @@ class Saori(SAORI):
                     end = line.find(']')
                     if end < 0:
                         end = len(line)
-                    name = line[start+1:end]
+                    name = line[start + 1:end]
                 else:
                     comma = line.find(',')
                     if comma >= 0:
                         key = line[:comma].strip()
-                        value = line[comma+1:].strip()
+                        value = line[comma + 1:].strip()
                         data[key] = value
             if name:
                 blns[name] = (data, {})
@@ -112,7 +113,7 @@ class Saori(SAORI):
         elif type == 'GET Version':
             return 'SAORI/1.0 204 No Content\r\n\r\n'
         elif type == 'EXECUTE':
-            if len(argument) == 0:
+            if not argument:
                 return 'SAORI/1.0 400 Bad Request\r\n\r\n'
             name = argument[0]
             if len(argument) >= 2:
@@ -148,7 +149,8 @@ class Saori(SAORI):
                     del bln[bln_id]
                 if text:
                     if update == 0 or not bln.has_key(bln_id):
-                        bln[bln_id] = Balloon(self.__ghost, self.dir, data, text,
+                        bln[bln_id] = Balloon(self.__ghost, self.dir,
+                                              data, text,
                                               offset_x, offset_y, name, bln_id)
                     else:
                         bln[bln_id].update_script(text, update)
@@ -165,7 +167,8 @@ class Saori(SAORI):
 
 class Balloon:
 
-    def __init__(self, ghost, dir, data, text, offset_x, offset_y, name, bln_id):
+    def __init__(self, ghost, dir, data,
+                 text, offset_x, offset_y, name, bln_id):
         self.dir = dir
         self.__ghost = ghost
         self.dragged = 0
@@ -176,7 +179,7 @@ class Balloon:
         else:
             self.position = data['position']
         self.window = gtk.Window(type=gtk.WINDOW_POPUP)
-        self.window.connect("delete_event", self.delete)
+        self.window.connect('delete_event', self.delete)
         if data.has_key('clickerase') and data['clickerase'] == 'off':
             self.clickerase = 'off'
         else:
@@ -191,10 +194,10 @@ class Balloon:
             self.dragmove_vertical = 1
         else:
             self.dragmove_vertical = 0
-        self.window.connect("button_press_event", self.button_press)
-        self.window.connect("button_release_event", self.button_release)
-        self.window.connect("motion_notify_event", self.motion_notify)
-        self.window.connect("leave_notify_event", self.leave_notify)
+        self.window.connect('button_press_event', self.button_press)
+        self.window.connect('button_release_event', self.button_release)
+        self.window.connect('motion_notify_event', self.motion_notify)
+        self.window.connect('leave_notify_event', self.leave_notify)
         self.window.set_events(gtk.gdk.BUTTON_PRESS_MASK|
                                gtk.gdk.BUTTON_RELEASE_MASK|
                                gtk.gdk.POINTER_MOTION_MASK|
@@ -202,15 +205,19 @@ class Balloon:
         scrn_w = gtk.gdk.screen_width()
         scrn_h = gtk.gdk.screen_height()
         scrn_h = scrn_h - self.get_sakura_status('getBottomMargin')
-        s0_shown, s0_x, s0_y, s0_w, s0_h = self.get_sakura_status('getSurfaceSakura')
-        s1_shown, s1_x, s1_y, s1_w, s1_h = self.get_sakura_status('getSurfaceKero')
-        b0_shown, b0_x, b0_y, b0_w, b0_h = self.get_sakura_status('getBalloonSakura')
-        b1_shown, b1_x, b1_y, b1_w, b1_h = self.get_sakura_status('getBalloonKero')
-        if s0_x + s0_w/2 > scrn_w/2:
+        s0_shown, s0_x, s0_y, s0_w, s0_h = \
+                  self.get_sakura_status('getSurfaceSakura')
+        s1_shown, s1_x, s1_y, s1_w, s1_h = \
+                  self.get_sakura_status('getSurfaceKero')
+        b0_shown, b0_x, b0_y, b0_w, b0_h = \
+                  self.get_sakura_status('getBalloonSakura')
+        b1_shown, b1_x, b1_y, b1_w, b1_h = \
+                  self.get_sakura_status('getBalloonKero')
+        if s0_x + s0_w / 2 > scrn_w / 2:
             self.direction0 = 0 # left
         else:
             self.direction0 = 1 # right
-        if s1_x + s1_w/2 > scrn_w/2:
+        if s1_x + s1_w / 2 > scrn_w / 2:
             self.direction1 = 0 # left
         else:
             self.direction1 = 1 # right            
@@ -247,18 +254,18 @@ class Balloon:
             self.x = scrn_w - w
             self.y = scrn_h - h
         elif self.position == 'center':
-            self.x = (scrn_w - w)/2
-            self.y = (scrn_h - h)/2
+            self.x = (scrn_w - w) / 2
+            self.y = (scrn_h - h) / 2
         elif self.position == 'leftcenter':
             self.x = 0
-            self.y = (scrn_h - h)/2
+            self.y = (scrn_h - h) / 2
         elif self.position == 'rightcenter':
             self.x = scrn_w -w
-            self.y = (scrn_h - h)/2
+            self.y = (scrn_h - h) / 2
         elif self.position == 'centertop':
-            self.x = (scrn_w - w)/2
+            self.x = (scrn_w - w) / 2
         elif self.position == 'centerbottom':
-            self.x = (scrn_w - w)/2
+            self.x = (scrn_w - w) / 2
             self.y = scrn_h - h
         elif self.position == 'sakura':
             if self.direction0: # right
@@ -314,7 +321,7 @@ class Balloon:
         self.script = None
         self.darea = gtk.DrawingArea()
         self.darea.set_events(gtk.gdk.EXPOSURE_MASK)
-        self.darea.connect("expose_event", self.redraw)
+        self.darea.connect('expose_event', self.redraw)
         self.darea.set_size_request(w, h)
         self.darea.show()
         self.window.add(self.darea)
@@ -322,7 +329,8 @@ class Balloon:
         self.surface_gc = self.darea.window.new_gc()
         self.darea.window.set_back_pixmap(image, False)
         self.layout = None
-        if text != 'noscript' and (self.right-self.left) and (self.bottom-self.top):
+        if text != 'noscript' and \
+           (self.right - self.left) and (self.bottom - self.top):
             self.script = text
             if data.has_key('font.color'):
                 fontcolor_r = int(data['font.color'][:2], 16)
@@ -330,14 +338,14 @@ class Balloon:
                 fontcolor_b = int(data['font.color'][4:6], 16)
                 cmap = self.darea.get_colormap()
                 self.surface_gc.foreground = cmap.alloc_color(
-                    "#%02x%02x%02x" % (fontcolor_r, fontcolor_g, fontcolor_b))
+                    '#%02x%02x%02x' % (fontcolor_r, fontcolor_g, fontcolor_b))
             self.font_size = 12 # default size
             if data.has_key('font.size'):
                 self.font_size = int(data['font.size'])
             self.layout = pango.Layout(self.darea.get_pango_context())
             self.font_desc = pango.FontDescription()
             self.font_desc.set_family('Sans') # FIXME
-            self.font_desc.set_size((self.font_size-3) * 1024) # size * PANGO_SCALE
+            self.font_desc.set_size((self.font_size - 3) * 1024) # size * PANGO_SCALE
             if data.has_key('font.bold') and data['font.bold'] == 'on':
                 self.font_desc.set_weight(pango.WEIGHT_BOLD)
             self.layout.set_font_description(self.font_desc)
@@ -423,12 +431,12 @@ class Balloon:
         self.text = ''
         self.script_wait = None
         self.quick_session = 0
-        self.script_parser = ninix.script.Parser(error="loose")
+        self.script_parser = ninix.script.Parser(error='loose')
         try:
             self.processed_script = self.script_parser.parse(self.script)
         except ninix.script.ParserError, e:
             self.processed_script = None
-            print "-" * 50
+            print '-' * 50
             print e
             print script                                    
         self.timeout_id = gobject.timeout_add(10, self.do_idle_tasks)
@@ -436,7 +444,7 @@ class Balloon:
     def update_script(self, text, mode):
         if text:
             if mode == 2 and self.script is not None:
-                self.script += text
+                self.script = ''.join((self.script, text))
             else:
                 self.script = text
             self.processed_script = None
@@ -448,7 +456,7 @@ class Balloon:
                 self.processed_script = self.script_parser.parse(self.script)
             except ninix.script.ParserError, e:
                 self.processed_script = None
-                print "-" * 50
+                print '-' * 50
                 print e
                 print script                                    
 
@@ -519,10 +527,14 @@ class Balloon:
     def do_idle_tasks(self):
         if not self.window:
             return None
-        s0_shown, s0_x, s0_y, s0_w, s0_h = self.get_sakura_status('getSurfaceSakura')
-        s1_shown, s1_x, s1_y, s1_w, s1_h = self.get_sakura_status('getSurfaceKero')
-        b0_shown, b0_x, b0_y, b0_w, b0_h = self.get_sakura_status('getBalloonSakura')
-        b1_shown, b1_x, b1_y, b1_w, b1_h = self.get_sakura_status('getBalloonKero')
+        s0_shown, s0_x, s0_y, s0_w, s0_h = \
+                  self.get_sakura_status('getSurfaceSakura')
+        s1_shown, s1_x, s1_y, s1_w, s1_h = \
+                  self.get_sakura_status('getSurfaceKero')
+        b0_shown, b0_x, b0_y, b0_w, b0_h = \
+                  self.get_sakura_status('getBalloonSakura')
+        b1_shown, b1_x, b1_y, b1_w, b1_h = \
+                  self.get_sakura_status('getBalloonKero')
         sakura_talking = self.get_sakura_status('isTalking')
         if self.state == 'orusuban':
             if self.visible:
@@ -554,35 +566,39 @@ class Balloon:
                     self.destroy()
                     return None
             else:
-                if time.time() - self.start_time >= self.startdelay * 0.001:
+                if time.time() - self.start_time >= self.startdelay * .001:
                     self.start_time = time.time()
                     self.visible = 1
                     self.window.show()
         if self.visible:
             if self.life_time:
-                if time.time() - self.start_time >= self.life_time * 0.001 and \
+                if time.time() - self.start_time >= self.life_time * .001 and \
                    not (self.processed_script or self.processed_text):
                     self.destroy()
                     return None
                 else:
-                    last_time = self.life_time * 0.001 + self.start_time - time.time()
+                    last_time = self.life_time * .001 + \
+                                self.start_time - time.time()
             if self.action:
                 if  self.action['method'] == 'sinwave':
                     offset = self.action['ref1'] \
                              * math.sin(2.0 * math.pi
-                                        * float(int((time.time() - self.start_time) * 1000) % self.action['ref2'])
+                                        * float(int((time.time() - \
+                                                     self.start_time) * 1000) \
+                                                % self.action['ref2'])
                                         / self.action['ref2'])
                     if self.action['ref0']:
                         self.action_y = offset
                     else:
                         self.action_x = offset
                 elif self.action['method'] == 'vibrate':
-                    offset = (int((time.time() - self.start_time) * 1000) / self.action['ref2']) % 2
+                    offset = (int((time.time() - self.start_time) * 1000) / \
+                              self.action['ref2']) % 2
                     self.action_x = offset * self.action['ref0']
                     self.action_y = offset * self.action['ref1']
             if (self.slide_vx != 0 or self.slide_vy != 0) and \
                    self.slide_autostop > 0 and \
-                   self.slide_autostop * 0.001 + 0.05 <= time.time() - self.start_time:
+                   self.slide_autostop * .001 + .05 <= time.time() - self.start_time:
                 self.vx = int((self.slide_autostop / 50.0 + 1) * self.slide_vx)
                 if (self.position == 'sakura' and not self.direction0) or \
                    (self.position == 'kero' and not self.direction1):
@@ -591,12 +607,12 @@ class Balloon:
                 self.vy = int((self.slide_autostop / 50.0 + 1) * self.slide_vy)
                 self.slide_vy = 0
             if self.slide_vx != 0:
-                self.vx = int(((time.time() - self.start_time) * self.slide_vx) / 50 * 1000.0)
+                self.vx = int(((time.time() - self.start_time) * self.slide_vx) / 50 * 1000.)
                 if (self.position == 'sakura' and not self.direction0) or \
                    (self.position == 'kero' and not self.direction1):
                     self.vx = -self.vx
             if self.slide_vy != 0:
-                self.vy = int(((time.time() - self.start_time) * self.slide_vy) / 50 * 1000.0)
+                self.vy = int(((time.time() - self.start_time) * self.slide_vy) / 50 * 1000.)
             self.window.move(int(self.x + self.action_x + self.vx),
                              int(self.y + self.action_y + self.vy))
             if self.processed_script or self.processed_text:
@@ -611,7 +627,8 @@ class Balloon:
         x, y, w, h = event.area
         self.darea.window.clear()
         if self.layout:
-            self.darea.window.draw_layout(self.surface_gc, self.left, self.top, self.layout)
+            self.darea.window.draw_layout(self.surface_gc,
+                                          self.left, self.top, self.layout)
 
     def get_state(self):
         return self.state
@@ -623,11 +640,11 @@ class Balloon:
             self.script_wait = None
         if self.processed_text:
             if self.quick_session or self.state == 'orusuban':
-                self.text += self.processed_text
+                self.text = ''.join((self.text, self.processed_text))
                 self.draw_text(self.text)
                 self.processed_text = ''
             else:
-                self.text += self.processed_text[0]
+                self.text = ''.join((self.text, self.processed_text[0]))
                 self.draw_text(self.text)
                 self.processed_text = self.processed_text[1:]
                 self.script_wait = time.time() + 0.014
@@ -636,10 +653,10 @@ class Balloon:
         if node[0] == ninix.script.SCRIPT_TAG:
             name, args = node[1], node[2:]
             if name == r'\n':
-                self.text += '\n'
+                self.text = ''.join((self.text, '\n'))
                 self.draw_text(self.text)
             elif name == r'\w':
-                if len(args) > 0:
+                if args:
                     try:
                         amount = int(args[0]) * 0.05 - 0.01
                     except ValueError:
@@ -649,7 +666,7 @@ class Balloon:
                 if amount > 0:
                     self.script_wait = time.time() + amount
             elif name == r'\b':
-                if len(args) > 0:
+                if args:
                     try:
                         amount = int(args[0])
                     except ValueError:
@@ -668,7 +685,7 @@ class Balloon:
         elif node[0] == ninix.script.SCRIPT_TEXT:
             text = ''
             for chunk in node[1]:
-                text += chunk[1]
+                text = ''.join((text, chunk[1]))
             self.processed_text = text
 
     def draw_text(self, text):
@@ -679,7 +696,8 @@ class Balloon:
         self.x_root = event.x_root
         self.y_root = event.y_root
         if event.type == gtk.gdk._2BUTTON_PRESS:
-            self.__ghost.notify_event('OnEBMouseDoubleClick', self.name, int(event.x), int(event.y), self.id)
+            self.__ghost.notify_event('OnEBMouseDoubleClick', self.name,
+                                      int(event.x), int(event.y), self.id)
         return True
 
     def button_release(self, window, event):
@@ -689,9 +707,13 @@ class Balloon:
         self.y_root = None
         if event.type == gtk.gdk.BUTTON_RELEASE:
             if event.button == 1:
-                self.__ghost.notify_event('OnEBMouseClick', self.name, int(event.x), int(event.y), self.id, 0)
+                self.__ghost.notify_event('OnEBMouseClick', self.name,
+                                          int(event.x), int(event.y),
+                                          self.id, 0)
             elif event.button == 3:
-                self.__ghost.notify_event('OnEBMouseClick', self.name, int(event.x), int(event.y), self.id, 1)
+                self.__ghost.notify_event('OnEBMouseClick', self.name,
+                                          int(event.x), int(event.y),
+                                          self.id, 1)
         if self.clickerase == 'on':
             self.destroy()
         return True
@@ -713,7 +735,8 @@ class Balloon:
                 self.y_root = event.y_root
         if self.move_notify_time is None or \
            time.time() - self.move_notify_time > 500 * 0.001:
-            self.__ghost.notify_event('OnEBMouseMove', self.name, int(event.x), int(event.y), self.id)
+            self.__ghost.notify_event('OnEBMouseMove', self.name,
+                                      int(event.x), int(event.y), self.id)
             self.move_notify_time = time.time()
         return True
 
index 3f57473..de129c0 100644 (file)
@@ -11,7 +11,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-#  $Id: hanayu.py,v 1.28 2005/07/29 08:25:59 shy Exp $
+#  $Id: hanayu.py,v 1.29 2005/08/09 00:41:52 shy Exp $
 #
 
 # TODO:
@@ -27,7 +27,7 @@ if os.environ.has_key('DISPLAY'):
     if not sys.modules.has_key('gtk'):
         try:
             import pygtk
-            pygtk.require("2.0")
+            pygtk.require('2.0')
         except ImportError:
             pass
     import gtk
@@ -38,7 +38,9 @@ else:
 
 from ninix.dll import SAORI
 
+
 class Saori(SAORI):
+
     __DBNAME = 'HANAYU.db'
 
     def __init__(self):
@@ -72,10 +74,10 @@ class Saori(SAORI):
                 line = line.strip()
                 if not line:
                     continue
-                if line[:2] == '//':
+                if line.startswith('//'):
                     continue
                 comma = line.find(',')
-                if line[0] == '[': # bln.txt like format
+                if line.startswith('['): # bln.txt like format
                     graphs[name] = data
                     data = {}
                     end = line.find(']')
@@ -92,7 +94,7 @@ class Saori(SAORI):
                     name = ''
                 elif comma >= 0:
                     key = line[:comma].strip()
-                    value = line[comma+1:].strip()
+                    value = line[comma + 1:].strip()
                     data[key] = value
                 elif not name:
                     tmp_name = line
@@ -111,14 +113,15 @@ class Saori(SAORI):
         return 1
 
     def time_to_key(self, secs, offset):
-        year = int(time.strftime("%Y", time.localtime(secs)))
-        month = int(time.strftime("%m", time.localtime(secs)))
-        day = int(time.strftime("%d", time.localtime(secs)))
-        target_time = time.mktime((year, month, day+offset, 0, 0, 0, -1, -1, -1))
-        year = int(time.strftime("%Y", time.localtime(target_time)))
-        month = int(time.strftime("%m", time.localtime(target_time)))
-        day = int(time.strftime("%d", time.localtime(target_time)))
-        key = str(year*10000 + month*100 + day)
+        year = int(time.strftime('%Y', time.localtime(secs)))
+        month = int(time.strftime('%m', time.localtime(secs)))
+        day = int(time.strftime('%d', time.localtime(secs)))
+        target_time = time.mktime(
+            (year, month, day + offset, 0, 0, 0, -1, -1, -1))
+        year = int(time.strftime('%Y', time.localtime(target_time)))
+        month = int(time.strftime('%m', time.localtime(target_time)))
+        day = int(time.strftime('%d', time.localtime(target_time)))
+        key = str(year * 10000 + month * 100 + day)
         return key, year, month, day
 
     def read_db(self):
@@ -147,7 +150,7 @@ class Saori(SAORI):
                 key = line[:comma]
                 for index in range(7):
                     if self.seven_days[index][0] == key:
-                        self.seven_days[index][4] = float(line[comma+1:])
+                        self.seven_days[index][4] = float(line[comma + 1:])
             file.close()
 
     def update_db(self):
@@ -165,7 +168,9 @@ class Saori(SAORI):
                     self.seven_days[j][4] = old_seven_days[i][4]
                     if j == 6:
                         self.seven_days[j][4] = self.seven_days[j][4] + \
-                                                (current_time - self.last_update) / (60.0 * 60.0)
+                                                (current_time - \
+                                                 self.last_update) / \
+                                                 (60.0 * 60.0)
         self.last_update = current_time
 
     def write_db(self):
@@ -177,11 +182,13 @@ class Saori(SAORI):
         else:
             file.write('# Format: v1.0\n')
             for index in range(7):
-                file.write('%s, %s\n' % (self.seven_days[index][0], self.seven_days[index][4]))
+                file.write('%s, %s\n' % \
+                           (self.seven_days[index][0],
+                            self.seven_days[index][4]))
             file.close()
 
     def execute(self, argument):
-        if len(argument) == 0:
+        if not argument:
             return 'SAORI/1.0 400 Bad Request\r\n\r\n'
         command = argument[0]
         if command == 'show':
@@ -194,7 +201,8 @@ class Saori(SAORI):
             if not self.data.has_key(name):
                 return 'SAORI/1.0 400 Bad Request\r\n\r\n'
             if self.data[name].has_key('graph') and \
-                   self.data[name]['graph'] in ['line', 'bar', 'radar', 'radar2']:
+                   self.data[name]['graph'] in ['line', 'bar',
+                                                'radar', 'radar2']:
                 type = self.data[name]['graph']
             else:
                 type = 'usetime'
@@ -202,21 +210,26 @@ class Saori(SAORI):
                 self.update_db()
                 new_args = []
                 for index in range(7):
-                    date = str(self.seven_days[index][2]) + \
-                           '/' + \
-                           str(self.seven_days[index][3])
+                    date = ''.join((str(self.seven_days[index][2]),
+                                    '/',
+                                    str(self.seven_days[index][3])))
                     new_args.append(date)
                     hours = self.seven_days[index][4]
                     new_args.append(hours)
-                self.graphs[name] = Line(self.dir, self.data[name], new_args, 0, 24)
+                self.graphs[name] = Line(
+                    self.dir, self.data[name], new_args, 0, 24)
             elif type == 'line':
-                self.graphs[name] = Line(self.dir, self.data[name], argument[2:])
+                self.graphs[name] = Line(
+                    self.dir, self.data[name], argument[2:])
             elif type == 'bar':
-                self.graphs[name] = Bar(self.dir, self.data[name], argument[2:])
+                self.graphs[name] = Bar(
+                    self.dir, self.data[name], argument[2:])
             elif type == 'radar':
-                self.graphs[name] = Radar(self.dir, self.data[name], argument[2:])
+                self.graphs[name] = Radar(
+                    self.dir, self.data[name], argument[2:])
             elif type == 'radar2':
-                self.graphs[name] = Radar2(self.dir, self.data[name], argument[2:])
+                self.graphs[name] = Radar2(
+                    self.dir, self.data[name], argument[2:])
         elif command == 'hide':
             if len(argument) >= 2:
                 name = argument[1]
@@ -231,6 +244,7 @@ class Saori(SAORI):
         return 'SAORI/1.0 204 No Content\r\n\r\n'
 
 class Graph:
+
     width = 450
     height = 340
 
@@ -251,15 +265,15 @@ class Graph:
         self.window.set_title('花柚') # UTF-8
         self.window.set_decorated(False)
         self.window.set_resizable(False)
-        self.window.connect("delete_event", self.delete)
-        self.window.connect("button_press_event", self.button_press)
+        self.window.connect('delete_event', self.delete)
+        self.window.connect('button_press_event', self.button_press)
         self.window.set_events(gtk.gdk.BUTTON_PRESS_MASK)
-        self.x = gtk.gdk.screen_width()/2
-        self.y = gtk.gdk.screen_height()/4
+        self.x = gtk.gdk.screen_width() / 2
+        self.y = gtk.gdk.screen_height() / 4
         self.window.move(self.x, self.y)
         self.darea = gtk.DrawingArea()
         self.darea.set_events(gtk.gdk.EXPOSURE_MASK)
-        self.darea.connect("expose_event", self.redraw)
+        self.darea.connect('expose_event', self.redraw)
         self.darea.set_size_request(self.width, self.height)
         self.darea.show()
         self.window.add(self.darea)
@@ -267,24 +281,25 @@ class Graph:
         self.layout = pango.Layout(self.darea.get_pango_context())
         pixbuf = None
         if self.data.has_key('background.filename'):
-            path = os.path.join(self.dir,
-                                self.data['background.filename'].replace('\\', '/'))
+            path = os.path.join(
+                self.dir, self.data['background.filename'].replace('\\', '/'))
             
             try:
                 pixbuf = ninix.pix.create_pixbuf_from_file(path, 'png')
             except:
                 pixbuf = None
-        self.surface_pixmap = gtk.gdk.Pixmap(None, self.width, self.height, gtk.gdk.visual_get_best_depth())
+        self.surface_pixmap = gtk.gdk.Pixmap(
+            None, self.width, self.height, gtk.gdk.visual_get_best_depth())
         cmap = self.darea.get_colormap()
         self.surface_gc = self.surface_pixmap.new_gc()
-        self.surface_gc.foreground = cmap.alloc_color("#FFFFFF")
+        self.surface_gc.foreground = cmap.alloc_color('#FFFFFF')
         self.surface_pixmap.draw_rectangle(self.surface_gc, True, 0, 0,
                                            self.width, self.height)
         if pixbuf:
             width = pixbuf.get_width()
             height = pixbuf.get_height()
-            xoffset = (self.width - width)/2
-            yoffset = (self.height - height)/2
+            xoffset = (self.width - width) / 2
+            yoffset = (self.height - height) / 2
             pixbuf.render_to_drawable(self.surface_pixmap, self.surface_gc,
                                       0, 0, xoffset, yoffset, width, height,
                                       gtk.gdk.RGB_DITHER_NONE, 0, 0)
@@ -306,19 +321,19 @@ class Graph:
                 fontcolor_b = int(self.data['font.color.b'])
         cmap = self.darea.get_colormap()
         self.surface_gc.foreground = cmap.alloc_color(
-            "#%02x%02x%02x" % (fontcolor_r, fontcolor_g, fontcolor_b))
+            '#%02x%02x%02x' % (fontcolor_r, fontcolor_g, fontcolor_b))
         if self.data.has_key('title'):
             self.title = unicode(self.data['title'], 'Shift_JIS', 'ignore')
         self.font_size = 12
         self.font_desc = pango.FontDescription()
         self.font_desc.set_family('Sans') # FIXME
         self.font_desc.set_size(self.font_size * 1024) # size * PANGO_SCALE
-        text = ""
+        text = ''
         i = 0
         while i < len(self.title):
             if text:
-                text += '\n'
-            text += self.title[i]
+                ''.join((text, '\n'))
+            ''.join((text, self.title[i]))
             i += 1
         self.layout.set_font_description(self.font_desc)
         self.layout.set_wrap(pango.WRAP_CHAR)
@@ -335,12 +350,14 @@ class Graph:
     def redraw(self, widget, event):
         x, y, w, h = event.area
         if self.surface_pixmap:
-            self.darea.window.draw_drawable(self.surface_gc, self.surface_pixmap,
-                                            x, y, x, y, w, h)
+            self.darea.window.draw_drawable(
+                self.surface_gc, self.surface_pixmap, x, y, x, y, w, h)
 
     def button_press(self, window, event):
         if event.type == gtk.gdk.BUTTON_PRESS:
-            self.window.begin_move_drag(event.button, int(event.x_root), int(event.y_root), gtk.get_current_event_time())
+            self.window.begin_move_drag(
+                event.button, int(event.x_root), int(event.y_root),
+                gtk.get_current_event_time())
         elif event.type == gtk.gdk._2BUTTON_PRESS: # double click
             self.destroy()
         return True
@@ -371,7 +388,7 @@ class Line(Graph):
                 framecolor_b = int(self.data['frame.color.b'])
         cmap = self.darea.get_colormap()
         self.surface_gc.foreground = cmap.alloc_color(
-            "#%02x%02x%02x" % (framecolor_r, framecolor_g, framecolor_b))
+            '#%02x%02x%02x' % (framecolor_r, framecolor_g, framecolor_b))
         frame_width = 2
         if self.data.has_key('frame.width'):
             frame_width = int(self.data['frame.width'])
@@ -382,28 +399,29 @@ class Line(Graph):
                                       60, 260, 420, 260)
 
     def draw_graph(self):
-        num = len(self.args)/2
+        num = len(self.args) / 2
         step = 368 / num 
         for index in range(num):
-            self.layout.set_text(self.args[index*2])
+            self.layout.set_text(self.args[index * 2])
             w, h = self.layout.get_pixel_size()
-            pos_x = 60 + index*step + step/2 - w/2
+            pos_x = 60 + index * step + step / 2 - w / 2
             pos_y = 268
-            self.surface_pixmap.draw_layout(self.surface_gc, pos_x, pos_y, self.layout)
+            self.surface_pixmap.draw_layout(
+                self.surface_gc, pos_x, pos_y, self.layout)
         if self.min is not None:
             min = self.min
         else:
             min = self.args[1]
             for index in range(2, num):
-                if self.args[index*2] < min:
-                    min = self.args[index*2]
+                if self.args[index * 2] < min:
+                    min = self.args[index * 2]
         if self.max is not None:
             max = self.max
         else:
             max = self.args[1]
             for index in range(2, num):
-                if self.args[index*2] > max:
-                    max = self.args[index*2]
+                if self.args[index * 2] > max:
+                    max = self.args[index * 2]
         linecolor_r = linecolor_g = linecolor = 0
         if self.data.has_key('line.color'):
             linecolor_r = int(self.data['line.color'][:2], 16)
@@ -418,39 +436,42 @@ class Line(Graph):
                 linecolor_b = int(self.data['line.color.b'])
         cmap = self.darea.get_colormap()
         self.surface_gc.foreground = cmap.alloc_color(
-            "#%02x%02x%02x" % (linecolor_r, linecolor_g, linecolor_b))
+            '#%02x%02x%02x' % (linecolor_r, linecolor_g, linecolor_b))
         line_width = 2
         if self.data.has_key('line.width'):
             line_width = int(self.data['line.width'])
         self.surface_gc.line_width = line_width
         for index in range(1, num):
-            src_x = 60 + (index-1)*step + step/2
-            src_y = 220 - int(168*self.args[(index-1)*2+1]/(max-min))
-            dst_x = 60 + index*step + step/2
-            dst_y = 220 - int(168*self.args[index*2+1]/(max-min))
+            src_x = 60 + (index - 1) * step + step / 2
+            src_y = 220 - int(
+                168 * self.args[(index - 1) * 2 + 1] / (max - min))
+            dst_x = 60 + index * step + step / 2
+            dst_y = 220 - int(168 * self.args[index * 2 + 1] / (max - min))
             self.surface_pixmap.draw_line(self.surface_gc,
                                           src_x, src_y, dst_x, dst_y)
         for index in range(num):
             image, mask = None, None
-            if self.args[index*2+1] == min and self.data.has_key('mark0.filename'):
-                path = os.path.join(self.dir,
-                                    self.data['mark0.filename'].replace('\\', '/'))
+            if self.args[index * 2 + 1] == min and \
+               self.data.has_key('mark0.filename'):
+                path = os.path.join(
+                    self.dir, self.data['mark0.filename'].replace('\\', '/'))
                 if os.path.exists(path):
                     try:
                         image, mask = ninix.pix.create_pixmap_from_file(path)
                     except:
                         image, mask = None, None
-            elif self.args[index*2+1] == max and self.data.has_key('mark2.filename'):
-                path = os.path.join(self.dir,
-                                    self.data['mark2.filename'].replace('\\', '/'))
+            elif self.args[index * 2 + 1] == max and \
+                 self.data.has_key('mark2.filename'):
+                path = os.path.join(
+                    self.dir, self.data['mark2.filename'].replace('\\', '/'))
                 if os.path.exists(path):
                     try:
                         image, mask = ninix.pix.create_pixmap_from_file(path)
                     except:
                         image, mask = None, None
             elif self.data.has_key('mark1.filename'):
-                path = os.path.join(self.dir,
-                                    self.data['mark1.filename'].replace('\\', '/'))
+                path = os.path.join(
+                    self.dir, self.data['mark1.filename'].replace('\\', '/'))
                 if os.path.exists(path):
                     try:
                         image, mask = ninix.pix.create_pixmap_from_file(path)
@@ -458,8 +479,9 @@ class Line(Graph):
                         image, mask = None, None
             if image:
                 w, h = image.get_size()
-                x = 60 + index*step + step/2 - w/2
-                y = 220 - int(168*self.args[index*2+1]/(max-min)) - h/2
+                x = 60 + index * step + step / 2 - w / 2
+                y = 220 - int(
+                    168 * self.args[index * 2 + 1] / (max - min)) - h / 2
                 gc = self.surface_pixmap.new_gc()
                 gc.set_clip_mask(mask)
                 gc.set_clip_origin(x, y)
@@ -482,12 +504,13 @@ class Bar(Graph):
         ##        barcolor_b = int(self.data['bar.color.b'])
         cmap = self.darea.get_colormap()
         self.surface_gc.foreground = cmap.alloc_color(
-            "#%02x%02x%02x" % (barcolor_r, barcolor_g, barcolor_b))
+            '#%02x%02x%02x' % (barcolor_r, barcolor_g, barcolor_b))
         if self.data.has_key('bar.width'):
             pass # FIXME
         ### NOT YET ###
 
 class Radar(Graph):
+
     width = 288
     height = 288
 
@@ -509,36 +532,36 @@ class Radar(Graph):
                 framecolor_b = int(self.data['frame.color.b'])
         cmap = self.darea.get_colormap()
         self.surface_gc.foreground = cmap.alloc_color(
-            "#%02x%02x%02x" % (framecolor_r, framecolor_g, framecolor_b))
+            '#%02x%02x%02x' % (framecolor_r, framecolor_g, framecolor_b))
         frame_width = 2
         if self.data.has_key('frame.width'):
             frame_width = int(self.data['frame.width'])
         self.surface_gc.line_width = frame_width
-        num = len(self.args)/2
+        num = len(self.args) / 2
         for index in range(num):
-            x = 146 + int(math.cos(math.pi*(0.5-2.0*index/num))*114)
-            y = 146 - int(math.sin(math.pi*(0.5-2.0*index/num))*114)
+            x = 146 + int(math.cos(math.pi * (0.5 - 2.0 * index / num)) * 114)
+            y = 146 - int(math.sin(math.pi * (0.5 - 2.0 * index / num)) * 114)
             self.surface_pixmap.draw_line(self.surface_gc,
                                           146, 146, x, y)
 
     def draw_graph(self):
-        num = len(self.args)/2
+        num = len(self.args) / 2
         for index in range(num):
             try:
-                value = self.args[index*2+1]
-                self.args[index*2+1] = float(value)
+                value = self.args[index * 2 + 1]
+                self.args[index * 2 + 1] = float(value)
             except:
-                self.args[index*2+1] = 0.0
-            if self.args[index*2+1] < 0:
-                self.args[index*2+1] = 0.0
+                self.args[index * 2 + 1] = 0.0
+            if self.args[index * 2 + 1] < 0:
+                self.args[index * 2 + 1] = 0.0
         min = self.args[1]
         for index in range(num):
-            if self.args[index*2+1] < min:
-                min = self.args[index*2+1]
+            if self.args[index * 2 + 1] < min:
+                min = self.args[index * 2 + 1]
         max = self.args[1]
         for index in range(num):
-            if self.args[index*2+1] > max:
-                max = self.args[index*2+1]
+            if self.args[index * 2 + 1] > max:
+                max = self.args[index * 2 + 1]
         linecolor_r = linecolor_g = linecolor = 0
         if self.data.has_key('line.color'):
             linecolor_r = int(self.data['line.color'][:2], 16)
@@ -553,24 +576,28 @@ class Radar(Graph):
                 linecolor_b = int(self.data['line.color.b'])
         cmap = self.darea.get_colormap()
         self.surface_gc.foreground = cmap.alloc_color(
-            "#%02x%02x%02x" % (linecolor_r, linecolor_g, linecolor_b))
+            '#%02x%02x%02x' % (linecolor_r, linecolor_g, linecolor_b))
         line_width = 2
         if self.data.has_key('line.width'):
             line_width = int(self.data['line.width'])
         self.surface_gc.line_width = line_width
         if max > 0:
-            value = self.args[(num-1)*2+1] / max
+            value = self.args[(num - 1) * 2 + 1] / max
         else:
             value = 1.0
-        src_x = 146 + int(math.cos(math.pi*(0.5-2.0*(num-1)/num))*value*100)
-        src_y = 146 - int(math.sin(math.pi*(0.5-2.0*(num-1)/num))*value*100)
+        src_x = 146 + int(math.cos(
+            math.pi * (0.5 - 2.0 * (num - 1) / num)) * value * 100)
+        src_y = 146 - int(math.sin(
+            math.pi * (0.5 - 2.0 * (num - 1) / num)) * value * 100)
         for index in range(num):
             if max > 0:
-                value = self.args[index*2+1] / max
+                value = self.args[index * 2 + 1] / max
             else:
                 value = 1.0
-            dst_x = 146 + int(math.cos(math.pi*(0.5-2.0*index/num))*value*100)
-            dst_y = 146 - int(math.sin(math.pi*(0.5-2.0*index/num))*value*100)
+            dst_x = 146 + int(
+                math.cos(math.pi * (0.5 - 2.0 * index / num)) * value * 100)
+            dst_y = 146 - int(
+                math.sin(math.pi * (0.5 - 2.0 * index / num)) * value * 100)
             self.surface_pixmap.draw_line(self.surface_gc,
                                           src_x, src_y, dst_x, dst_y)
             src_x = dst_x
@@ -591,26 +618,31 @@ class Radar(Graph):
                 fontcolor_b = int(self.data['font.color.b'])
         cmap = self.darea.get_colormap()
         self.surface_gc.foreground = cmap.alloc_color(
-            "#%02x%02x%02x" % (fontcolor_r, fontcolor_g, fontcolor_b))
+            '#%02x%02x%02x' % (fontcolor_r, fontcolor_g, fontcolor_b))
         for index in range(num):
             if max > 0:
-                value = self.args[index*2+1] / max
+                value = self.args[index * 2 + 1] / max
             else:
                 value = 1.0
-            x = 146 + int(math.cos(math.pi*(0.5-2.0*index/num))*value*100)
-            y = 146 - int(math.sin(math.pi*(0.5-2.0*index/num))*value*100)
-            self.layout.set_text(self.args[index*2])
-            self.surface_pixmap.draw_layout(self.surface_gc, x, y + 12, self.layout)
+            x = 146 + int(math.cos(
+                math.pi * (0.5 - 2.0 * index / num)) * value * 100)
+            y = 146 - int(math.sin(
+                math.pi * (0.5 - 2.0 * index / num)) * value * 100)
+            self.layout.set_text(self.args[index * 2])
+            self.surface_pixmap.draw_layout(
+                self.surface_gc, x, y + 12, self.layout)
 
 class Radar2(Graph):
+
     width = 288
     height = 288
 
     def __init__(self, dir, data, args=[]):
         Graph.__init__(self, dir, data, args)
 
-if __name__ == "__main__":
-    USAGE= "Usage: hanayu.py <dir>"
+
+if __name__ == '__main__':
+    USAGE= 'Usage: hanayu.py <dir>'
     if len(sys.argv) == 2:
         saori = Saori()
         data = saori.read_hanayu_txt(sys.argv[1])
index fd4887b..05d227b 100644 (file)
@@ -3,7 +3,7 @@
 #  kawari.py - a "華和梨" compatible Shiori module for ninix
 #  Copyright (C) 2001, 2002 by Tamito KAJIYAMA
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
-#  Copyright (C) 2002-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #  Copyright (C) 2003 by Shun-ichi TAHARA <jado@flowernet.gr.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-#  $Id: kawari.py,v 1.26 2005/07/29 08:25:59 shy Exp $
+#  $Id: kawari.py,v 1.27 2005/08/09 00:41:52 shy Exp $
 #
 
 import base64
 import os
 import re
-import string
 import time
 import random
 import sys
@@ -40,33 +39,33 @@ def read_dict(path, debug=0):
     for line in file:
         lineno = lineno + 1
         position = (lineno, path)
-        if line[:9] == "!KAWA0000":
+        if line.startswith('!KAWA0000'):
             line = decrypt(line[9:])
         if not line.strip() or \
-           line[0] =="#" or \
-           line[:6] == ":crypt" or \
-           line[:9] == ":endcrypt":
+           line.startswith('#') or \
+           line.startswith(':crypt') or \
+           line.startswith(':endcrypt'):
             continue
-        pos = line.find(":")
+        pos = line.find(':')
         if pos < 0:
             if debug & 4:
-                print "kawari.py: syntax error at line %d in %s:" % position
+                print 'kawari.py: syntax error at line %d in %s:' % position
                 print line.strip()
             continue
         entries = line[:pos].strip()
-        phrases = line[pos+1:].strip()
+        phrases = line[pos + 1:].strip()
         if not entries:
             if debug & 4:
-                print "kawari.py: syntax error at line %d in %s:" % position
+                print 'kawari.py: syntax error at line %d in %s:' % position
                 print line.strip()
             continue
         if not phrases:
             continue
-        if entries == "locale":
+        if entries == 'locale':
             try:
                 codecs.lookup(phrases)
             except:
-                print "kawari.py: unsupported charset %s" % phrases
+                print 'kawari.py: unsupported charset %s' % phrases
             else:
                 charset = phrases
         else:
@@ -79,14 +78,14 @@ def decrypt(data):
     buffer = []
     for c in base64.decodestring(data):
         buffer.append(chr(ord(c) ^ 0xcc))
-    return string.join(buffer, '')
+    return ''.join(buffer)
 
 def encrypt(data):
     buffer = []
     for c in data:
         buffer.append(chr(ord(c) ^ 0xcc))
-    line = "!KAWA0000" + base64.encodestring(string.join(buffer, ''))
-    return line.replace("\n", "")
+    line = ''.join(('!KAWA0000', base64.encodestring(''.join(buffer))))
+    return line.replace('\n', '')
 
 def create_dict(buffer, debug=0):
     rdict = {} # rules
@@ -96,10 +95,10 @@ def create_dict(buffer, debug=0):
         parsed_phrases = parse_phrases(phrases)
         if parsed_phrases is None:
             if debug & 4:
-                print "kawari.py: syntax error at line %d in %s:" % position
+                print 'kawari.py: syntax error at line %d in %s:' % position
                 print phrases.strip()
             continue
-        if entries[0] == "[":
+        if entries.startswith('['):
             add_phrases(kdict, tuple(parsed_entries), parsed_phrases)
             continue
         for entry in parsed_entries:
@@ -116,7 +115,7 @@ def add_phrases(dict, entry, phrases):
         dict[entry].append(tuple(phrase))
 
 def parse_entries(data):
-    if data[0] == "[" and data[-1] == "]":
+    if data.startswith('[') and data.endswith(']'):
         entries = []
         i = 0
         j = len(data)
@@ -127,10 +126,10 @@ def parse_entries(data):
             else:
                 i += 1
     else:
-        entries = [s.strip() for s in data.split(",")]
+        entries = [s.strip() for s in data.split(',')]
     return entries
 
-re_comma = re.compile(",")
+re_comma = re.compile(',')
 
 def parse_phrases(data):
     buffer = []
@@ -154,16 +153,16 @@ def parse(data, start, stop_pattern=None):
         elif data[i] == '"':
             i, text = parse_quotes(data, i)
             buffer.append('"%s"' % text)
-        elif data[i:i+2] == '${':
+        elif data[i:i + 2] == '${':
             i, text = parse_reference(data, i)
             buffer.append(text)
-        elif data[i:i+2] == '$(':
+        elif data[i:i + 2] == '$(':
             i, text = parse_inline_script(data, i)
             buffer.append(text)
-        elif data[i] == "$":
+        elif data[i] == '$':
             buffer.append(data[i])
             i += 1
-        elif data[i] == ";":
+        elif data[i] == ';':
             buffer.append(data[i])
             i += 1
         else:
@@ -192,14 +191,14 @@ def parse_quotes(data, start):
         elif data[i] == '\\':
             i += 1
             if i < j and data[i] == '"':
-                buffer.append('\\' + data[i])
+                buffer.append(''.join(('\\', data[i])))
                 i += 1
             else:
                 buffer.append('\\')
         else:
             buffer.append(data[i])
             i += 1
-    return i, string.join(buffer, '')
+    return i, ''.join(buffer)
 
 def parse_reference(data, start):
     i = start
@@ -227,10 +226,10 @@ def parse_inline_script(data, start):
         if data[i] == '"':
             i, text = parse_quotes(data, i)
             buffer.append('"%s"' % text)
-        elif data[i:i+2] == '${':
+        elif data[i:i + 2] == '${':
             i, text = parse_reference(data, i)
             buffer.append(text)
-        elif data[i:i+2] == '$(':
+        elif data[i:i + 2] == '$(':
             i, text = parse_inline_script(data, i)
             buffer.append(text)
         else:
@@ -242,7 +241,7 @@ def parse_inline_script(data, start):
             i += 1
         if npar == 0:
             break
-    return i, string.join(buffer, '')
+    return i, ''.join(buffer)
 
 def is_space(s):
     return not s.strip()
@@ -258,7 +257,7 @@ def parse_text(data, start, stop_pattern=None):
             break
         elif is_space(data[i]) != condition:
             break
-        elif data[i] == ";":
+        elif data[i] == ';':
             if i == start:
                 i += 1
             break
@@ -274,15 +273,18 @@ def read_local_script(path):
         line = file.readline()
         if not line:
             break
-        if line[0] == '#':
+        if line.startswith('#'):
             rdict[unicode(line.strip(), charset, 'ignore')] = \
                  [unicode(file.readline().strip(), charset, 'ignore')]
     return rdict, kdict
 
+
 ###   KAWARI   ###
 
 class Kawari:
+
     MAXDEPTH = 30
+
     def __init__(self, prefix, pathlist, rdictlist, kdictlist, debug=0):
         self.prefix = prefix
         self.pathlist = pathlist
@@ -295,27 +297,34 @@ class Kawari:
         self.expr_parser.kawari = self
         #end
         self.otherghost = {}
-        self.get_system_entry("OnLoad")
+        self.get_system_entry('OnLoad')
+
     def finalize(self):
-        self.get_system_entry("OnUnload")
+        self.get_system_entry('OnUnload')
+
     # SHIORI/1.0 API
     def getaistringrandom(self):
-        return self.get("sentence").encode(charset, 'ignore')
+        return self.get('sentence').encode(charset, 'ignore')
+
     def getaistringfromtargetword(self, word):
         word = unicode(word, charset, 'ignore')
-        return self.get("sentence").encode(charset, 'ignore') # XXX
+        return self.get('sentence').encode(charset, 'ignore') # XXX
+
     def getdms(self):
-        return self.getword("dms")
+        return self.getword('dms')
+
     def getword(self, type):
-        for delimiter in [".", "-"]:
-            name = "compatible" + delimiter + type
+        for delimiter in ['.', '-']:
+            name = ''.join(('compatible', delimiter, type))
             script = self.get(name, default=None)
             if script is not None:
                 return script.strip().encode(charset, 'ignore')
-        return ""
+        return ''
+
     def getstring(self, name):
         name = unicode(name, charset, 'ignore')
-        return self.get("resource.%s" % name).encode(charset, 'ignore')
+        return self.get('resource.%s' % name).encode(charset, 'ignore')
+
     # SHIORI/2.2 API
     def get_event_response(self, event,
                            ref0=None, ref1=None, ref2=None, ref3=None,
@@ -324,28 +333,30 @@ class Kawari:
             if ref is not None:
                 ref = unicode(str(ref), charset, 'ignore')
             return ref
-        ref = [proc(ref) for ref in [ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7]]
+        ref = [proc(ref) for ref in [ref0, ref1, ref2, ref3, ref4,
+                                     ref5, ref6, ref7]]
         for i in range(8):
             if ref[i] is not None:
                 value = ref[i]
-                self.system_entries["system.Reference%d" % i] = value
-                self.system_entries["system-Reference%d" % i] = value
+                self.system_entries['system.Reference%d' % i] = value
+                self.system_entries['system-Reference%d' % i] = value
         script = None
-        if event == "OnCommunicate":
-            self.system_entries["system.Sender"] = ref[0]
-            self.system_entries["system-Sender"] = ref[0]
-            self.system_entries["system.Sender.Path"] = 'local' # (local/unknown/external)
-            self.system_entries["system-Sender.Path"] = 'local' # (local/unknown/external)
-            if not self.system_entries.has_key("system.Age"):
-                self.system_entries["system.Age"] = '0'
-                self.system_entries["system-Age"] = '0'
-            self.system_entries["system.Sentence"] = ref[1]
-            self.system_entries["system-Sentence"] = ref[1]
+        if event == 'OnCommunicate':
+            self.system_entries['system.Sender'] = ref[0]
+            self.system_entries['system-Sender'] = ref[0]
+            self.system_entries['system.Sender.Path'] = 'local' # (local/unknown/external)
+            self.system_entries['system-Sender.Path'] = 'local' # (local/unknown/external)
+            if not self.system_entries.has_key('system.Age'):
+                self.system_entries['system.Age'] = '0'
+                self.system_entries['system-Age'] = '0'
+            self.system_entries['system.Sentence'] = ref[1]
+            self.system_entries['system-Sentence'] = ref[1]
             if self.otherghost.has_key(ref[0]):
                 s0, s1 = self.otherghost[ref[0]]
-                self.system_entries["system.Surface"] = string.join((str(s0), str(s1)), ',')
-                self.system_entries["system-Surface"] = string.join((str(s0), str(s1)), ',')
-            script = self.get_system_entry("OnResponse")
+                self.system_entries['system.Surface'] = ','.join((str(s0), str(s1)))
+                self.system_entries['system-Surface'] = ','.join((str(s0),
+                                                                  str(s1)))
+            script = self.get_system_entry('OnResponse')
             if not script:
                 for dict in self.kdictlist:
                     for entry in dict.keys():
@@ -356,12 +367,12 @@ class Kawari:
                             script = self.expand(random.choice(dict[entry]))
                             break
             if not script:
-                script = self.get_system_entry("OnResponseUnknown")
+                script = self.get_system_entry('OnResponseUnknown')
             if script is not None:
                 script = script.strip()
         else:
-            for delimiter in [".", "-"]:
-                name = "event" + delimiter + event
+            for delimiter in ['.', '-']:
+                name = ''.join(('event', delimiter, event))
                 script = self.get(name, default=None)
                 if script is not None:
                     script = script.strip()
@@ -369,19 +380,22 @@ class Kawari:
         if script is not None:
             script = script.encode(charset, 'ignore')
         return script
+
     # SHIORI/2.4 API
     def teach(self, word):
         word = unicode(word, charset, 'ignore')
-        self.system_entries["system.Sentence"] = word
-        self.system_entries["system-Sentence"] = word
-        return self.get_system_entry("OnTeach").encode(charset, 'ignore')
+        self.system_entries['system.Sentence'] = word
+        self.system_entries['system-Sentence'] = word
+        return self.get_system_entry('OnTeach').encode(charset, 'ignore')
+
     def get_system_entry(self, entry):
-        for delimiter in [".", "-"]:
-            name = "system" + delimiter + entry
+        for delimiter in ['.', '-']:
+            name = ''.join(('system', delimiter, entry))
             script = self.get(name, default=None)
             if script is not None:
                 return script.strip()
         return None
+
     def otherghostname(self, list):
         ghosts = []
         for ghost in list:
@@ -391,35 +405,37 @@ class Kawari:
         otherghost_name = []
         for ghost in ghosts:
             otherghost_name.append(ghost[0])
-        self.system_entries["system.OtherGhost"] = otherghost_name
-        self.system_entries["system-OtherGhost"] = otherghost_name
+        self.system_entries['system.OtherGhost'] = otherghost_name
+        self.system_entries['system-OtherGhost'] = otherghost_name
         otherghost_ex = []
         for ghost in ghosts:
-            otherghost_ex.append(string.join(ghost, chr(1)))
-        self.system_entries["system.OtherGhostEx"] = otherghost_ex
-        self.system_entries["system-OtherGhostEx"] = otherghost_ex
-        if len(ghosts) > 0:
-            self.get_system_entry("OnNotifyOther")
+            otherghost_ex.append(chr(1).join(ghost))
+        self.system_entries['system.OtherGhostEx'] = otherghost_ex
+        self.system_entries['system-OtherGhostEx'] = otherghost_ex
+        if ghosts:
+            self.get_system_entry('OnNotifyOther')
         return ''
+
     def communicate_to(self):
-        communicate = self.get_system_entry("communicate")
+        communicate = self.get_system_entry('communicate')
         if communicate:
             if communicate == 'stop':
-                self.system_entries["system.Age"] = '0'
-                self.system_entries["system-Age"] = '0'
+                self.system_entries['system.Age'] = '0'
+                self.system_entries['system-Age'] = '0'
                 communicate = None
             else:
-                if self.system_entries.has_key("system.Age"):
-                    age = int(self.system_entries["system.Age"]) + 1
-                    self.system_entries["system.Age"] = str(age)
-                    self.system_entries["system-Age"] = str(age)
+                if self.system_entries.has_key('system.Age'):
+                    age = int(self.system_entries['system.Age']) + 1
+                    self.system_entries['system.Age'] = str(age)
+                    self.system_entries['system-Age'] = str(age)
                 else:
-                    self.system_entries["system.Age"] = '0'
-                    self.system_entries["system-Age"] = '0'
-        self.clear("system.communicate")
+                    self.system_entries['system.Age'] = '0'
+                    self.system_entries['system-Age'] = '0'
+        self.clear('system.communicate')
         if communicate is not None:
             communicate = communicate.encode(charset, 'ignore')
         return communicate
+
     # internal
     def clear(self, name):
         if self.debug & 128:
@@ -427,6 +443,7 @@ class Kawari:
         for dict in self.rdictlist:
             if dict.has_key(name):
                 del dict[name]
+
     def get_internal_dict(self, name):
         for dict in self.rdictlist:
             if dict.has_key(name):
@@ -435,57 +452,71 @@ class Kawari:
             dict = self.rdictlist[0]
             dict[name] = []
         return dict
+
     def unshift(self, name, value):
         if self.debug & 128:
-            print ('*** unshift("%s", "%s")' % (name, value)).encode('UTF-8', 'ignore')
+            print ('*** unshift("%s", "%s")' % (name, value)).encode('UTF-8',
+                                                                     'ignore')
         dict = self.get_internal_dict(name)
         i, segments = parse(value, 0)
         dict[name].insert(0, segments)
+
     def shift(self, name):
         dict = self.get_internal_dict(name)
         value = self.expand(dict[name].pop(0))
         if self.debug & 128:
-            print ('*** shift("%s") => "%s"' % (name, value)).encode('UTF-8', 'ignore')
+            print ('*** shift("%s") => "%s"' % (name, value)).encode('UTF-8',
+                                                                     'ignore')
         return value
+
     def push(self, name, value):
         if self.debug & 128:
-            print ('*** push("%s", "%s")' % (name, value)).encode('UTF-8', 'ignore')
+            print ('*** push("%s", "%s")' % (name, value)).encode('UTF-8',
+                                                                  'ignore')
         dict = self.get_internal_dict(name)
         i, segments = parse(value, 0)
         dict[name].append(segments)
+
     def pop(self, name):
         dict = self.get_internal_dict(name)
         value = self.expand(dict[name].pop())
         if self.debug & 128:
-            print ('*** pop("%s") => "%s"' % (name, value)).encode('UTF-8', 'ignore')
+            print ('*** pop("%s") => "%s"' % (name, value)).encode('UTF-8',
+                                                                   'ignore')
         return value
+
     def set(self, name, value):
         self.clear(name)
         self.push(name, value)
-    def get(self, name, context=None, depth=0, default=""):
+
+    def get(self, name, context=None, depth=0, default=''):
         if depth == self.MAXDEPTH:
-            return ""
-        if name and name[0] == "@":
+            return ''
+        if name and name.startswith('@'):
             segments = random.choice(context[name])
         else:
-            if name.find("&") < 0:
+            if name.find('&') < 0:
                 selection = self.select_simple_phrase(name)
             else:
                 selection = self.select_compound_phrase(name)
             if selection is None:
                 if self.debug & 8:
-                    print "${%s} not found" % name.encode('UTF-8', 'ignore')
+                    print '${%s} not found' % name.encode('UTF-8', 'ignore')
                 return default
             segments, context = selection
         if self.debug & 16:
-            print name.encode('UTF-8', 'ignore'), "=>", string.join(segments, '').encode('UTF-8', 'ignore')
+            print name.encode('UTF-8', 'ignore'), '=>', \
+                  ''.join(segments).encode('UTF-8', 'ignore')
         return self.expand(segments, context, depth)
+
     def parse_all(self, data, start=0):
         i, segments = parse(data, start)
         return self.expand(segments)
+
     def parse_sub(self, data, start=0, stop_pattern=None):
         i, segments = parse(data, start, stop_pattern)
         return i, self.expand(segments)
+
     def expand(self, segments, context=None, depth=0):
         buffer = []
         references = []
@@ -495,7 +526,7 @@ class Kawari:
             segment = segments[i]
             if not segment:
                 pass
-            elif segment[:2] == "${" and segment[-1] == "}":
+            elif segment.startswith('${') and segment.endswith('}'):
                 newname = segment[2:-1]
                 if self.is_number(newname):
                     try:
@@ -503,40 +534,45 @@ class Kawari:
                     except IndexError:
                         pass
                 elif self.is_system_entry(newname):
-                    if newname in ["system.OtherGhost", "system-OtherGhost",
-                                   "system.OtherGhostEx", "system-OtherGhostEx"]:
+                    if newname in ['system.OtherGhost', 'system-OtherGhost',
+                                   'system.OtherGhostEx',
+                                   'system-OtherGhostEx']:
                         list = self.system_entries.get(newname)
                         if list:
                             segment = random.choice(list)
                         else:
                             segment = ''
-                    elif newname == "system.communicate":
-                        segment = self.get_system_entry("communicate")
+                    elif newname == 'system.communicate':
+                        segment = self.get_system_entry('communicate')
                     else:
                         segment = self.system_entries.get(newname, segment)
                 else:
                     segment = self.get(newname, context, depth + 1)
                 references.append(segment)
-            elif segment[:2] == "$(" and segment[-1] == ")":
+            elif segment.startswith('$(') and segment.endswith(')'):
                 i, segment = self.eval_inline_script(segments, i)
-            elif segment[0] == '"' and segment[-1] == '"':
-                segment = segment[1:-1].replace(r"\"", "\"")
+            elif segment.startswith('"') and segment.endswith('"'):
+                segment = segment[1:-1].replace(r'\"', '"')
             buffer.append(segment)
             i += 1
-        return string.join(buffer, '')
+        return ''.join(buffer)
+
     def atoi(self, s):
         try:
             return int(s)
         except ValueError:
             return 0
+
     def is_number(self, s):
         try:
             int(s)
         except ValueError:
             return 0
         return 1
+
     def is_system_entry(self, s):
-        return s[:7] in ["system-", "system."]
+        return s.startswith('system-') or s.startswith('system.')
+
     def select_simple_phrase(self, name):
         n = 0
         buffer = []
@@ -553,9 +589,10 @@ class Kawari:
                 break
             n -= m
         return c[n], d        
+
     def select_compound_phrase(self, name):
         buffer = []
-        for name in [s.strip() for s in name.split("&")]:
+        for name in [s.strip() for s in name.split('&')]:
             list = []
             for d in self.rdictlist:
                 list.extend([tuple(e) for e in d.get(name, [])])
@@ -571,49 +608,53 @@ class Kawari:
         if not candidates:
             return None
         return random.choice(candidates), None
+
     def eval_inline_script(self, segments, i):
         # check old 'if' syntax
-        if segments[i][:5] == "$(if " and i + 1 < len(segments) and \
-           segments[i+1][:7] == "$(then ":
+        if segments[i].startswith('$(if ') and i + 1 < len(segments) and \
+           segments[i + 1].startswith('$(then '):
             if_block = segments[i][5:-1].strip()
             i += 1
             then_block = segments[i][7:-1].strip()
-            if i + 1 < len(segments) and segments[i+1][:7] == "$(else ":
+            if i + 1 < len(segments) and segments[i + 1].startswith('$(else '):
                 i += 1
                 else_block = segments[i][7:-1].strip()
             else:
-                else_block = ""
-            if i + 1 < len(segments) and segments[i+1] == "$(endif)":
+                else_block = ''
+            if i + 1 < len(segments) and segments[i + 1] == '$(endif)':
                 i += 1
             else:
                 if self.debug & 32:
-                    print "kawari.py: syntax error: $(endif) expected"
-                return i, "" # syntax error
+                    print 'kawari.py: syntax error: $(endif) expected'
+                return i, '' # syntax error
             return i, self.exec_old_if(if_block, then_block, else_block)
         # execute command(s)
         values = []
         for command in self.split_commands(segments[i][2:-1]):
             argv = self.parse_argument(command)
             argv[0] = self.expand(argv[0])
-            if argv[0] == "silent":
+            if argv[0] == 'silent':
                 if len(argv) == 1:
                     values = []
                 elif self.debug & 32:
-                    print "kawari.py: syntax error:", segments[i].encode('UTF-8', 'ignore')
+                    print 'kawari.py: syntax error:', \
+                          segments[i].encode('UTF-8', 'ignore')
                 continue
             handler = self.kis_commands.get(argv[0])
             try:
                 if handler is None:
-                    raise RuntimeError, "invalid command"
+                    raise RuntimeError, 'invalid command'
                 values.append(handler(self, argv))
             except RuntimeError, message:
                 if self.debug & 32:
-                    print "kawari.py: %s: %s" % (message, segments[i].encode('UTF-8', 'ignore'))
-        result = string.join(values, '')
+                    print 'kawari.py: %s: %s' % \
+                          (message, segments[i].encode('UTF-8', 'ignore'))
+        result = ''.join(values)
         if self.debug & 64:
-            print ">>>", segments[i].encode('UTF-8', 'ignore')
-            print '"' + result.encode('UTF-8', 'ignore') + '"'
+            print '>>>', segments[i].encode('UTF-8', 'ignore')
+            print ''.join(('"', result.encode('UTF-8', 'ignore'), '"'))
         return i, result
+
     def split_commands(self, data):
         i, segments = parse(data, 0)
         # find multiple commands separated by semicolons
@@ -635,6 +676,7 @@ class Kawari:
             if is_space(command[-1]):
                 del command[-1]
         return buffer
+
     def parse_argument(self, segments):
         buffer = [[]]
         for segment in segments:
@@ -643,17 +685,19 @@ class Kawari:
             else:
                 buffer[-1].append(segment)
         return buffer
+
     def exec_new_if(self, argv):
         if len(argv) == 3:
             return self.exec_if(argv[1], argv[2], None)
         elif len(argv) == 4:
             return self.exec_if(argv[1], argv[2], argv[3])
         else:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
+
     def exec_old_if(self, if_block, then_block, else_block):
         # convert [...] into $([...])
-        if if_block and if_block[0] == '[' and if_block[-1] == ']':
-            if_block = "$(" + if_block + ")"
+        if if_block and if_block.startswith('[') and if_block.endswith(']'):
+            if_block = ''.join(('$(', if_block, ')'))
         # parse arguments
         i, if_block = parse(if_block, 0)
         i, then_block = parse(then_block, 0)
@@ -662,25 +706,27 @@ class Kawari:
         result = self.exec_if(if_block, then_block, else_block)
         if self.debug & 64:
             if else_block:
-                print ">>> $(if %s)$(then %s)$(else %s)$(endif)" % (
-                    string.join(if_block, "").encode('UTF-8', 'ignore'),
-                    string.join(then_block, "").encode('UTF-8', 'ignore'),
-                    string.join(else_block, "").encode('UTF-8', 'ignore'))
+                print '>>> $(if %s)$(then %s)$(else %s)$(endif)' % (
+                    ''.join(if_block).encode('UTF-8', 'ignore'),
+                    ''.join(then_block).encode('UTF-8', 'ignore'),
+                    ''.join(else_block).encode('UTF-8', 'ignore'))
             else:
-                print ">>> $(if %s)$(then %s)$(endif)" % (
-                    string.join(if_block, "").encode('UTF-8', 'ignore'),
-                    string.join(then_block, "").encode('UTF-8', 'ignore'))
-            print '"' + result.encode('UTF-8', 'ignore') + '"'
+                print '>>> $(if %s)$(then %s)$(endif)' % (
+                    ''.join(if_block).encode('UTF-8', 'ignore'),
+                    ''.join(then_block).encode('UTF-8', 'ignore'))
+            print ''.join(('"', result.encode('UTF-8', 'ignore'), '"'))
         return result
+
     def exec_if(self, if_block, then_block, else_block):
-        if self.expand(if_block) not in ["", "0", "false", "False"]:
+        if self.expand(if_block) not in ['', '0', 'false', 'False']:
             return self.expand(then_block)
         elif else_block:
             return self.expand(else_block)
-        return ""
+        return ''
+
     def exec_foreach(self, argv):
         if len(argv) != 4:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         temp = self.expand(argv[1])
         name = self.expand(argv[2])
         buffer = []
@@ -689,143 +735,162 @@ class Kawari:
                 self.set(temp, self.expand(segments))
                 buffer.append(self.expand(argv[3]))
         self.clear(temp)
-        return string.join(buffer, '')
+        return ''.join(buffer)
+
     def exec_loop(self, argv):
         if len(argv) != 3:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         try:
             n = int(self.expand(argv[1]))
         except ValueError:
-            raise RuntimeError, "invalid argument"
+            raise RuntimeError, 'invalid argument'
         buffer = []
         for i in range(n):
             buffer.append(self.expand(argv[2]))
-        return string.join(buffer, '')
+        return ''.join(buffer)
+
     def exec_while(self, argv):
         if len(argv) != 3:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         buffer = []
-        while self.expand(argv[1]) not in ["", "0", "false", "False"]:
+        while self.expand(argv[1]) not in ['', '0', 'false', 'False']:
             buffer.append(self.expand(argv[2]))
-        return string.join(buffer, '')
+        return ''.join(buffer)
+
     def exec_until(self, argv):
         if len(argv) != 3:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         buffer = []
-        while self.expand(argv[1]) in ["", "0", "false", "False"]:
+        while self.expand(argv[1]) in ['', '0', 'false', 'False']:
             buffer.append(self.expand(argv[2]))
-        return string.join(buffer, '')
+        return ''.join(buffer)
+
     def exec_set(self, argv):
         if len(argv) != 3:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         self.set(self.expand(argv[1]), self.expand(argv[2]))
-        return ""
+        return ''
+
     def exec_adddict(self, argv):
         if len(argv) != 3:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         self.push(self.expand(argv[1]), self.expand(argv[2]))
-        return ""
+        return ''
+
     def exec_array(self, argv): # XXX experimental
         if len(argv) != 3:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         name = self.expand(argv[1])
         n = self.atoi(self.expand(argv[2]))
         for d in self.rdictlist:
             c = d.get(name, [])
             if n < len(c):
-                return string.join([self.expand(s) for s in c[n]], "")
+                return ''.join([self.expand(s) for s in c[n]])
             n -= len(c)
         else:
-            raise RuntimeError, "invalid argument"
+            raise RuntimeError, 'invalid argument'
+
     def exec_clear(self, argv):
         if len(argv) != 2:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         self.clear(self.expand(argv[1]))
-        return ""
+        return ''
+
     def exec_enumerate(self, argv):
         if len(argv) != 2:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         name = self.expand(argv[1])
-        return string.join([self.expand(s) for s in self.enumerate(name)])
+        return ' '.join([self.expand(s) for s in self.enumerate(name)])
+
     def enumerate(self, name):
         buffer = []
         for dict in self.rdictlist:
             for segments in dict.get(name, []):
                 buffer.append(segments)
         return buffer
+
     def exec_size(self, argv):
         if len(argv) != 2:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         name = self.expand(argv[1])
         n = 0
         for d in self.rdictlist:
             c = d.get(name, [])
             n += len(c)
         return str(n)
+
     def exec_get(self, argv): # XXX experimental
         if len(argv) != 3:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         name = self.expand(argv[1])
         n = self.atoi(self.expand(argv[2]))
         for d in self.rdictlist:
             c = d.get(name, [])
             if n < len(c):
-                return string.join(c[n], "")
+                return ''.join(c[n])
             n -= len(c)
         else:
-            raise RuntimeError, "invalid argument"
+            raise RuntimeError, 'invalid argument'
+
     def exec_unshift(self, argv):
         if len(argv) != 3:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         self.unshift(self.expand(argv[1]), self.expand(argv[2]))
-        return ""
+        return ''
+
     def exec_shift(self, argv):
         if len(argv) != 2:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         return self.shift(self.expand(argv[1]))
+
     def exec_push(self, argv):
         if len(argv) != 3:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         self.push(self.expand(argv[1]), self.expand(argv[2]))
-        return ""
+        return ''
+
     def exec_pop(self, argv):
         if len(argv) != 2:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         return self.pop(self.expand(argv[1]))
+
     def exec_pirocall(self, argv):
         if len(argv) != 2:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         selection = self.select_simple_phrase(self.expand(argv[1]))
         if selection is None:
-            return ""
+            return ''
         return selection[0]
+
     def exec_split(self, argv):
         if len(argv) != 4:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         name = self.expand(argv[1])
         list = self.expand(argv[2]).split(self.expand(argv[3]))
         n = 0
         for word in list:
             n += 1
-            entry = "%s.%d" % (name, n)
+            entry = '%s.%d' % (name, n)
             self.set(entry, word)
-        self.set(name + '.size', str(n))
-        return ""
+        self.set(''.join((name, '.size')), str(n))
+        return ''
+
     def get_dict_path(self, path):
-        path = path.replace("\\", "/").lower()
+        path = path.replace('\\', '/').lower()
         if not path:
-            raise RuntimeError, "invalid argument"
-        if path[0] == '/':
+            raise RuntimeError, 'invalid argument'
+        if path.startswith('/'):
             return path
         return os.path.join(self.prefix, path)
+
     def exec_load(self, argv):
         if len(argv) != 2:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         path = self.get_dict_path(self.expand(argv[1]))
         try:
             rdict, kdict = create_dict(read_dict(path, self.debug))
         except IOError:
-            raise RuntimeError, "cannot read file"
+            raise RuntimeError, 'cannot read file'
         if path in self.pathlist:
             i = self.pathlist.index(path)
             self.rdictlist[i].update(rdict)
@@ -834,107 +899,121 @@ class Kawari:
             self.pathlist.insert(0, path)
             self.rdictlist.insert(0, rdict)
             self.kdictlist.insert(0, kdict)
-        return ""
+        return ''
+
     def exec_save(self, argv, crypt=0):
         if len(argv) < 2:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         path = self.get_dict_path(self.expand(argv[1]))
         try:
-            file = builtin_open(path, "w")
-            file.write("#\r\n# Kawari save file\r\n#\r\n")
+            file = builtin_open(path, 'w')
+            file.write('#\r\n# Kawari save file\r\n#\r\n')
             for i in range(2, len(argv)):
                 name = self.expand(argv[i])
                 if not name.strip():
                     continue
                 buffer = []
                 for segments in self.enumerate(name):
-                    buffer.append(string.join(segments, ''))
+                    buffer.append(''.join(segments))
                 name = name.encode(charset, 'ignore')
-                line = name + " : " + \
-                       string.join(buffer, " , ").encode(charset, 'ignore')
+                line = ''.join((name, ' : ',
+                                ' , '.join(buffer).encode(charset, 'ignore')))
                 if crypt:
                     line = encrypt(line)
-                file.write("# Entry %s\r\n%s\r\n" % (name, line))
+                file.write('# Entry %s\r\n%s\r\n' % (name, line))
             file.close()
         except IOError:
-            raise RuntimeError, "cannot write file"
-        return ""
+            raise RuntimeError, 'cannot write file'
+        return ''
+
     def exec_savecrypt(self, argv):
         return self.exec_save(argv, 1)
+
     def exec_textload(self, argv):
         if len(argv) != 3:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         path = self.get_dict_path(self.expand(argv[1]))
         try:
             linelist = builtin_open(path).readlines()
         except IOError:
-            raise RuntimeError, "cannot read file"
+            raise RuntimeError, 'cannot read file'
         name = self.expand(argv[2])
         n = 0
         for line in linelist:
             n += 1
-            entry = "%s.%d" % (name, n)
-            if line[-2:] == "\r\n":
+            entry = '%s.%d' % (name, n)
+            if line.endswith('\r\n'):
                 line = line[:-2]
-            elif line[-1] in "\r\n":
+            elif line.endswith('\r') or line.endswith('\n'):
                 line = line[:-1]
             if not line:
                 self.clear(entry)
             else:
-                self.set(entry, unicode(line, charset, "replace"))
-        self.set(name + ".size", str(n))
-        return ""
+                self.set(entry, unicode(line, charset, 'replace'))
+        self.set(''.join((name, '.size')), str(n))
+        return ''
+
     def exec_escape(self, argv):
-        data = string.join([self.expand(s) for s in argv[1:]])
-        data = data.replace("\\", r"\\")
-        data = data.replace("%", r"\%")
+        data = ' '.join([self.expand(s) for s in argv[1:]])
+        data = data.replace('\\', r'\\')
+        data = data.replace('%', r'\%')
         return data
+
     def exec_echo(self, argv):
-        return string.join([self.expand(s) for s in argv[1:]])
+        return ' '.join([self.expand(s) for s in argv[1:]])
+
     def exec_tolower(self, argv):
         return self.exec_echo(argv).lower()
+
     def exec_toupper(self, argv):
         return self.exec_echo(argv).upper()
+
     def exec_eval(self, argv):
         return self.parse_all(self.exec_echo(argv))
+
     def exec_entry(self, argv):
         if len(argv) == 2:
             return self.get(self.expand(argv[1]))
         elif len(argv) == 3:
             return self.get(self.expand(argv[1])) or self.expand(argv[2])
         else:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
+
     def exec_null(self, argv):
         if len(argv) != 1:
-            raise RuntimeError, "syntax error"
-        return ""
+            raise RuntimeError, 'syntax error'
+        return ''
+
     def exec_chr(self, argv):
         if len(argv) != 2:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         num = self.atoi(self.expand(argv[1]))
         if num < 256:
             return chr(num)
-        return chr((num >> 8) & 0xff) + chr(num & 0xff)
+        return ''.join((chr((num >> 8) & 0xff), chr(num & 0xff)))
+
     def exec_choice(self, argv):
         if len(argv) == 1:
-            return ""
+            return ''
         i = random.randrange(1, len(argv))        
         return self.expand(argv[i])
+
     def exec_rand(self, argv):
         if len(argv) != 2:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         bound = self.atoi(self.expand(argv[1]))
         if bound == 0:
             return str(0)
         elif bound > 0:
             return str(random.randrange(0, bound))
         else:
-            return str(random.randint(bound+1, 0))
+            return str(random.randint(bound + 1, 0))
+
     def exec_date(self, argv):
         if len(argv) == 1:
-            format = "%y/%m/%d %H:%M:%S"
+            format = '%y/%m/%d %H:%M:%S'
         else:
-            format = string.join([self.expand(s) for s in argv[1:]])
+            format = ' '.join([self.expand(s) for s in argv[1:]])
         buffer = []
         i = 0
         j = len(format)
@@ -948,31 +1027,31 @@ class Kawari:
                 else:
                     break
                 if c in ['y', 'Y']: # year (4 columns)
-                    buffer.append("%04d" % now[0])
+                    buffer.append('%04d' % now[0])
                 elif c == 'm': # month (01 - 12)
-                    buffer.append("%02d" % now[1])
+                    buffer.append('%02d' % now[1])
                 elif c == 'n': # month (1 - 12)
                     buffer.append(str(now[1]))
                 elif c == 'd': # day (01 - 31)
-                    buffer.append("%02d" % now[2])
+                    buffer.append('%02d' % now[2])
                 elif c == 'e': # day (1 - 31)
                     buffer.append(str(now[2]))
                 elif c == 'H': # hour (00 - 23)
-                    buffer.append("%02d" % now[3])
+                    buffer.append('%02d' % now[3])
                 elif c == 'k': # hour (0 - 23)
                     buffer.append(str(now[3]))
                 elif c == 'M': # minute (00 - 59)
-                    buffer.append("%02d" % now[4])
+                    buffer.append('%02d' % now[4])
                 elif c == 'N': # minute (0 - 59)
                     buffer.append(str(now[4]))
                 elif c == 'S': # second (00 - 59)
-                    buffer.append("%02d" % now[5])
+                    buffer.append('%02d' % now[5])
                 elif c == 'r': # second (0 - 59)
                     buffer.append(str(now[5]))
                 elif c == 'w': # weekday (0 = Sunday)
                     buffer.append(str([1, 2, 3, 4, 5, 6, 0][now[6]]))
                 elif c == 'j': # Julian day (001 - 366)
-                    buffer.append("%03d" % now[7])
+                    buffer.append('%03d' % now[7])
                 elif c == 'J': # Julian day (1 - 366)
                     buffer.append(str(now[7]))
                 elif c == '%':
@@ -983,7 +1062,8 @@ class Kawari:
             else:
                 buffer.append(format[i])
                 i += 1
-        return string.join(buffer, '')
+        return ''.join(buffer)
+
     def exec_inc(self, argv):
         def _inc(value, step, bound):
             value += step
@@ -991,7 +1071,8 @@ class Kawari:
                 return bound
             return value
         self.apply_counter_op(_inc, argv)
-        return ""
+        return ''
+
     def exec_dec(self, argv):
         def _dec(value, step, bound):
             value -= step
@@ -999,10 +1080,11 @@ class Kawari:
                 return bound
             return value
         self.apply_counter_op(_dec, argv)
-        return ""
+        return ''
+
     def apply_counter_op(self, func, argv):
         if len(argv) < 2 or len(argv) > 4:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         name = self.expand(argv[1])
         value = self.atoi(self.get(name))
         if len(argv) >= 3:
@@ -1014,63 +1096,66 @@ class Kawari:
         else:
             bound = None
         self.set(name, str(func(value, step, bound)))
+
     def exec_test(self, argv):
-        if argv[0] == "test" and len(argv) == 4 or \
-           argv[0] == "[" and len(argv) == 5 and self.expand(argv[4]) == "]":
+        if argv[0] == 'test' and len(argv) == 4 or \
+           argv[0] == '[' and len(argv) == 5 and self.expand(argv[4]) == ']':
             op1 = self.expand(argv[1])
             op  = self.expand(argv[2])
             op2 = self.expand(argv[3])
         else:
-            raise RuntimeError, "syntax error"
-        if op in ["=", "=="]:
+            raise RuntimeError, 'syntax error'
+        if op in ['=', '==']:
             return str(op1 == op2)
-        elif op == "!=":
+        elif op == '!=':
             return str(op1 != op2)
-        elif op == "<=":
+        elif op == '<=':
             return str(op1 <= op2)
-        elif op == ">=":
+        elif op == '>=':
             return str(op1 >= op2)
-        elif op == "<":
+        elif op == '<':
             return str(op1 < op2)
-        elif op == ">":
+        elif op == '>':
             return str(op1 > op2)
-        elif op == "-eq":
+        elif op == '-eq':
             return str(self.atoi(op1) == self.atoi(op2))
-        elif op == "-ne":
+        elif op == '-ne':
             return str(self.atoi(op1) != self.atoi(op2))
-        elif op == "-le":
+        elif op == '-le':
             return str(self.atoi(op1) <= self.atoi(op2))
-        elif op == "-ge":
+        elif op == '-ge':
             return str(self.atoi(op1) >= self.atoi(op2))
-        elif op == "-lt":
+        elif op == '-lt':
             return str(self.atoi(op1) < self.atoi(op2))
-        elif op == "-gt":
+        elif op == '-gt':
             return str(self.atoi(op1) > self.atoi(op2))
         else:
-            raise RuntimeError, "unknown operator"
+            raise RuntimeError, 'unknown operator'
+
     def exec_expr(self, argv):
         tree = self.expr_parser.parse(
-            string.join([string.join(e, '') for e in argv[1:]]))
+            ' '.join([''.join(e) for e in argv[1:]]))
         if tree is None:
-            raise RuntimeError, "syntax error"
+            raise RuntimeError, 'syntax error'
         try:
             value = self.interp_expr(tree)
         except ExprError:
-            raise RuntimeError, "runtime error"
+            raise RuntimeError, 'runtime error'
         return value
+
     def interp_expr(self, tree):
         if tree[0] == ExprParser.OR_EXPR:
             for subtree in tree[1:]:
                 value = self.interp_expr(subtree)
-                if value and value not in ["0", "False"]:
+                if value and value not in ['0', 'False']:
                     break
             return value
         elif tree[0] == ExprParser.AND_EXPR:
             buffer = []
             for subtree in tree[1:]:
                 value = self.interp_expr(subtree)
-                if not value or value in ["0", "False"]:
-                    return "0"
+                if not value or value in ['0', 'False']:
+                    return '0'
                 buffer.append(value)
             return buffer[0]
         elif tree[0] == ExprParser.CMP_EXPR:
@@ -1079,20 +1164,20 @@ class Kawari:
             if self.is_number(op1) and self.is_number(op2):
                 op1 = int(op1)
                 op2 = int(op2)
-            if tree[2] in ["=", "=="]:
+            if tree[2] in ['=', '==']:
                 return str(op1 == op2)
-            elif tree[2] == "!=":
+            elif tree[2] == '!=':
                 return str(op1 != op2)
-            elif tree[2] == "<=":
+            elif tree[2] == '<=':
                 return str(op1 <= op2)
-            elif tree[2] == ">=":
+            elif tree[2] == '>=':
                 return str(op1 >= op2)
-            elif tree[2] == "<":
+            elif tree[2] == '<':
                 return str(op1 < op2)
-            elif tree[2] == ">":
+            elif tree[2] == '>':
                 return str(op1 > op2)
             else:
-                raise RuntimeError, "unknown operator"
+                raise RuntimeError, 'unknown operator'
         elif tree[0] == ExprParser.ADD_EXPR:
             for i in range(1, len(tree), 2):
                 tree[i] = self.interp_expr(tree[i])
@@ -1100,10 +1185,10 @@ class Kawari:
                     raise ExprError
             value = int(tree[1])
             for i in range(2, len(tree), 2):
-                if tree[i] == "+":
-                    value += int(tree[i+1])
-                elif tree[i] == "-":
-                    value -= int(tree[i+1])
+                if tree[i] == '+':
+                    value += int(tree[i + 1])
+                elif tree[i] == '-':
+                    value -= int(tree[i + 1])
             return str(value)
         elif tree[0] == ExprParser.MUL_EXPR:
             for i in range(1, len(tree), 2):
@@ -1112,24 +1197,24 @@ class Kawari:
                     raise ExprError
             value = int(tree[1])
             for i in range(2, len(tree), 2):
-                if tree[i] == "*":
-                    value *= int(tree[i+1])
-                elif tree[i] == "/":
+                if tree[i] == '*':
+                    value *= int(tree[i + 1])
+                elif tree[i] == '/':
                     try:
-                        value /= int(tree[i+1])
+                        value /= int(tree[i + 1])
                     except ZeroDivisionError:
                         raise ExprError
-                elif tree[i] == "%":
+                elif tree[i] == '%':
                     try:
-                        value %= int(tree[i+1])
+                        value %= int(tree[i + 1])
                     except ZeroDivisionError:
                         raise ExprError
             return str(value)
         elif tree[0] == ExprParser.STR_EXPR:
-            if tree[1] == "length":
+            if tree[1] == 'length':
                 length = len(self.get_characters(self.interp_expr(tree[2])))
                 return str(length)
-            elif tree[1] == "index":
+            elif tree[1] == 'index':
                 s = self.get_characters(self.interp_expr(tree[2]))
                 c = self.get_characters(self.interp_expr(tree[3]))
                 for pos in range(len(s)):
@@ -1138,7 +1223,7 @@ class Kawari:
                 else:
                     pos = 0
                 return str(pos)
-            elif tree[1] == "match":
+            elif tree[1] == 'match':
                 try:
                     match = re.match(self.interp_expr(tree[3]),
                                      self.interp_expr(tree[2]))
@@ -1149,18 +1234,18 @@ class Kawari:
                 else:
                     length = 0
                 return str(length)
-            elif tree[1] == "find":
+            elif tree[1] == 'find':
                 s = self.interp_expr(tree[3])
                 if self.interp_expr(tree[2]).find(s) < 0:
-                    return ""
+                    return ''
                 return s
-            elif tree[1] == "findpos":
+            elif tree[1] == 'findpos':
                 s = self.interp_expr(tree[3])
                 pos = self.interp_expr(tree[2]).find(s);
                 if pos < 0:
-                    return ""
-                return str(pos+1)
-            elif tree[1] == "substr":
+                    return ''
+                return str(pos + 1)
+            elif tree[1] == 'substr':
                 s = self.interp_expr(tree[2])
                 p = self.interp_expr(tree[3])
                 n = self.interp_expr(tree[4])
@@ -1169,10 +1254,11 @@ class Kawari:
                     n = p + int(n)
                     if 0 <= p <= n:
                         characters = self.get_characters(s)
-                        return string.join(characters[p:n], '')
-                return ""
+                        return ''.join(characters[p:n])
+                return ''
         elif tree[0] == ExprParser.LITERAL:
             return self.expand(tree[1:])
+
     def get_characters(self, s):
         buffer = []
         i = 0
@@ -1181,59 +1267,60 @@ class Kawari:
             buffer.append(s[i])
             i += 1
         return buffer
+
     kis_commands = {
         # flow controls
-        "if":          exec_new_if,
-        "foreach":     exec_foreach,
-        "loop":        exec_loop,
-        "while":       exec_while,
-        "until":       exec_until,
+        'if':          exec_new_if,
+        'foreach':     exec_foreach,
+        'loop':        exec_loop,
+        'while':       exec_while,
+        'until':       exec_until,
         # dictionary operators
-        "adddict":     exec_adddict,
-        "array":       exec_array,
-        "clear":       exec_clear,
-        "enumerate":   exec_enumerate,
-        "set":         exec_set,
-        "load":        exec_load,
-        "save":        exec_save,
-        "savecrypt":   exec_savecrypt,
-        "textload":    exec_textload,
-        "size":        exec_size,
-        "get":         exec_get,
+        'adddict':     exec_adddict,
+        'array':       exec_array,
+        'clear':       exec_clear,
+        'enumerate':   exec_enumerate,
+        'set':         exec_set,
+        'load':        exec_load,
+        'save':        exec_save,
+        'savecrypt':   exec_savecrypt,
+        'textload':    exec_textload,
+        'size':        exec_size,
+        'get':         exec_get,
         # list operators
-        "unshift":     exec_unshift,
-        "shift":       exec_shift,
-        "push":        exec_push,
-        "pop":         exec_pop,
+        'unshift':     exec_unshift,
+        'shift':       exec_shift,
+        'push':        exec_push,
+        'pop':         exec_pop,
         # counter operators
-        "inc":         exec_inc,
-        "dec":         exec_dec,
+        'inc':         exec_inc,
+        'dec':         exec_dec,
         # expression evaluators
-        "expr":        exec_expr,
-        "test":        exec_test,
-        "[":           exec_test,
-        "entry":       exec_entry,
-        "eval":        exec_eval,
+        'expr':        exec_expr,
+        'test':        exec_test,
+        '[':           exec_test,
+        'entry':       exec_entry,
+        'eval':        exec_eval,
         # utility functions
-        "NULL":        exec_null,
-        "?":           exec_choice,
-        "date":        exec_date,
-        "rand":        exec_rand,
-        "echo":        exec_echo,
-        "escape":      exec_escape,
-        "tolower":     exec_tolower,
-        "toupper":     exec_toupper,
-        "pirocall":    exec_pirocall,
-        "split":       exec_split,
-        "urllist":     None,
-        "chr":         exec_chr,
-        "help":        None,
-        "ver":         None,
-        "searchghost": None,
-        "saoriregist": None,
-        "saorierase":  None,
-        "callsaori":   None,
-        "callsaorix":  None,
+        'NULL':        exec_null,
+        '?':           exec_choice,
+        'date':        exec_date,
+        'rand':        exec_rand,
+        'echo':        exec_echo,
+        'escape':      exec_escape,
+        'tolower':     exec_tolower,
+        'toupper':     exec_toupper,
+        'pirocall':    exec_pirocall,
+        'split':       exec_split,
+        'urllist':     None,
+        'chr':         exec_chr,
+        'help':        None,
+        'ver':         None,
+        'searchghost': None,
+        'saoriregist': None,
+        'saorierase':  None,
+        'callsaori':   None,
+        'callsaorix':  None,
         }
 
 ###   EXPR PARSER   ###
@@ -1242,16 +1329,20 @@ class ExprError(ValueError):
     pass
 
 class ExprParser:
+
     def __init__(self):
         self.debug = 0
         # bit 0 = trace get_expr()
         # bit 1 = trace all "get_" functions
+
     def show_progress(self, func, buffer):
         if buffer is None:
-            print "%s() -> syntax error" % func
+            print '%s() -> syntax error' % func
         else:
-            print "%s() -> %s" % (func, buffer)
+            print '%s() -> %s' % (func, buffer)
+
     re_token = re.compile('[():|&*/%+-]|[<>]=?|[!=]?=|match|index|findpos|find|substr|length|quote|(\\s+)')
+
     def tokenize(self, data):
         buffer = []
         i = 0
@@ -1265,35 +1356,44 @@ class ExprParser:
                 i, segments = parse(data, i, self.re_token)
                 buffer.extend(segments)
         return buffer
+
     def parse(self, data):
         self.tokens = self.tokenize(data)
         try:
             return self.get_expr()
         except ExprError:
             return None # syntax error
+
     # internal
     def done(self):
         return not self.tokens
+
     def pop(self):
         try:
             return self.tokens.pop(0)
         except IndexError:
             raise ExprError
+
     def look_ahead(self, index=0):
         try:
             return self.tokens[index]
         except IndexError:
             raise ExprError
+
     def match(self, s):
         if self.pop() != s:
             raise ExprError
+
     def match_space(self):
         if not is_space(self.pop()):
             raise ExprError
+
     def check(self, s, index=0):
         return self.look_ahead(index) == s
+
     def check_space(self, index=0):
         return is_space(self.look_ahead(index))
+
     # tree node types
     OR_EXPR  = 1
     AND_EXPR = 2
@@ -1302,13 +1402,15 @@ class ExprParser:
     MUL_EXPR = 5
     STR_EXPR = 6
     LITERAL  = 7
+
     def get_expr(self):
         buffer = self.get_or_expr()
         if not self.done():
             raise ExprError
         if self.debug & 1:
-            self.show_progress("get_expr", buffer)
+            self.show_progress('get_expr', buffer)
         return buffer
+
     def get_or_expr(self):
         buffer = [self.OR_EXPR]
         while 1:
@@ -1323,8 +1425,9 @@ class ExprParser:
         if len(buffer) == 2:
             buffer = buffer[1]
         if self.debug & 2:
-            self.show_progress("get_or_expr", buffer)
+            self.show_progress('get_or_expr', buffer)
         return buffer
+
     def get_and_expr(self):
         buffer = [self.AND_EXPR]
         while 1:
@@ -1339,14 +1442,15 @@ class ExprParser:
         if len(buffer) == 2:
             buffer = buffer[1]
         if self.debug & 2:
-            self.show_progress("get_and_expr", buffer)
+            self.show_progress('get_and_expr', buffer)
         return buffer
+
     def get_cmp_expr(self):
         buffer = [self.CMP_EXPR]
         buffer.append(self.get_add_expr())
         if not self.done() and \
            self.check_space() and \
-           self.look_ahead(1) in ["<=", ">=", "<", ">", "=", "==", "!="]:
+           self.look_ahead(1) in ['<=', '>=', '<', '>', '=', '==', '!=']:
             self.pop() # space
             buffer.append(self.pop()) # operator
             self.match_space()
@@ -1354,14 +1458,15 @@ class ExprParser:
         if len(buffer) == 2:
             buffer = buffer[1]
         if self.debug & 2:
-            self.show_progress("get_cmp_expr", buffer)
+            self.show_progress('get_cmp_expr', buffer)
         return buffer
+
     def get_add_expr(self):
         buffer = [self.ADD_EXPR]
         while 1:
             buffer.append(self.get_mul_expr())
             if not self.done() and \
-               self.check_space() and self.look_ahead(1) in ["+", "-"]:
+               self.check_space() and self.look_ahead(1) in ['+', '-']:
                 self.pop() # space
                 buffer.append(self.pop()) # operator
                 self.match_space()
@@ -1370,14 +1475,15 @@ class ExprParser:
         if len(buffer) == 2:
             buffer = buffer[1]
         if self.debug & 2:
-            self.show_progress("get_add_expr", buffer)
+            self.show_progress('get_add_expr', buffer)
         return buffer
+
     def get_mul_expr(self):
         buffer = [self.MUL_EXPR]
         while 1:
             buffer.append(self.get_mat_expr())
             if not self.done() and \
-               self.check_space() and self.look_ahead(1) in ["*", "/", "%"]:
+               self.check_space() and self.look_ahead(1) in ['*', '/', '%']:
                 self.pop() # space
                 buffer.append(self.pop()) # operator
                 self.match_space()
@@ -1386,14 +1492,15 @@ class ExprParser:
         if len(buffer) == 2:
             buffer = buffer[1]
         if self.debug & 2:
-            self.show_progress("get_mul_expr", buffer)
+            self.show_progress('get_mul_expr', buffer)
         return buffer
+
     def get_mat_expr(self):
         buffer = [self.STR_EXPR]
         buffer.append(self.get_str_expr())
         if not self.done() and \
            self.check_space() and self.check(':', 1):
-            buffer.insert(1, "match")
+            buffer.insert(1, 'match')
             self.pop() # space
             self.pop() # ':'
             self.match_space()
@@ -1401,22 +1508,23 @@ class ExprParser:
         if len(buffer) == 2:
             buffer = buffer[1]
         if self.debug & 2:
-            self.show_progress("get_mat_expr", buffer)
+            self.show_progress('get_mat_expr', buffer)
         return buffer
+
     def get_str_expr(self):
         argc = 0
-        if self.check("length"):
+        if self.check('length'):
             argc = 1
-        elif self.look_ahead() in ["match", "index", "find", "findpos"]:
+        elif self.look_ahead() in ['match', 'index', 'find', 'findpos']:
             argc = 2
-        elif self.check("substr"):
+        elif self.check('substr'):
             argc = 3
         if argc > 0:
             buffer = [self.STR_EXPR, self.pop()] # fuction
             for i in range(argc):
                 self.match_space()
                 buffer.append(self.get_str_expr())
-        elif self.check("quote"):
+        elif self.check('quote'):
             buffer = [self.LITERAL]
             self.pop()
             self.match_space()
@@ -1427,8 +1535,9 @@ class ExprParser:
         else:
             buffer = self.get_sub_expr()
         if self.debug & 2:
-            self.show_progress("get_str_expr", buffer)
+            self.show_progress('get_str_expr', buffer)
         return buffer
+
     def get_sub_expr(self):
         if self.check('('):
             self.pop()
@@ -1445,14 +1554,15 @@ class ExprParser:
             buffer = [self.LITERAL]
             buffer.extend(self.get_str_seq())
         if self.debug & 2:
-            self.show_progress("get_sub_expr", buffer)
+            self.show_progress('get_sub_expr', buffer)
         return buffer
+
     def get_str_seq(self):
         buffer = []
         while not self.done() and \
               not self.re_token.match(self.look_ahead()):
             buffer.append(self.pop())
-        if len(buffer) == 0:
+        if not buffer:
             raise ExprError
         return buffer
 
@@ -1481,12 +1591,13 @@ class ExprParser:
 # sp       := SPACE+ (white space)
 # str-seq  := STRING+ (literal, "...", ${...}, and/or $(...))
 
+
 ###   API   ###
 
 DICT_FILE, INI_FILE = range(2)
 
 def list_dict(kawari_dir, saori_ini={}, debug=0):
-    return scan_ini(kawari_dir, "kawari.ini", saori_ini, debug)
+    return scan_ini(kawari_dir, 'kawari.ini', saori_ini, debug)
 
 def scan_ini(kawari_dir, filename, saori_ini, debug=0):
     buffer = []
@@ -1497,34 +1608,34 @@ def scan_ini(kawari_dir, filename, saori_ini, debug=0):
         list = []
     read_as_dict = 0
     for entry, value, position in list:
-        if entry == "dict":
-            file = value.replace("\\", "/").lower().encode('utf-8')
+        if entry == 'dict':
+            file = value.replace('\\', '/').lower().encode('utf-8')
             path = os.path.join(kawari_dir, file)
             try:
                 builtin_open(path).read(64)
             except IOError, (errno, message):
                 if debug & 4:
-                    print "kawari.py: read error:", path
+                    print 'kawari.py: read error:', path
                 continue
             buffer.append((DICT_FILE, path))
-        elif entry == "include":
-            file = value.replace("\\", "/").lower().encode('utf-8')
+        elif entry == 'include':
+            file = value.replace('\\', '/').lower().encode('utf-8')
             buffer.extend(scan_ini(kawari_dir, file, saori_ini, debug))
-        elif entry == "set":
+        elif entry == 'set':
             read_as_dict = 1
-        elif entry in ["randomseed", "debug", "security", "set"]:
+        elif entry in ['randomseed', 'debug', 'security', 'set']:
             pass
-        elif entry == "saori":
+        elif entry == 'saori':
             list = value.split(',')
             path = list[0].strip().encode('utf-8')
             alias = list[1].strip()
             if len(list) == 3:
                 option = list[2].strip()
             else:
-                option = "loadoncall"
+                option = 'loadoncall'
             saori_ini[alias] = [path, option]
         elif debug & 4:
-            print "kawari.py: unknown entry:", entry
+            print 'kawari.py: unknown entry:', entry
     if read_as_dict:
         buffer.append((INI_FILE, ini_path))
     return buffer
@@ -1536,7 +1647,7 @@ def read_ini(path):
     except IOError:
         list = []
     for entry, value, position in list:
-        if entry == "set":
+        if entry == 'set':
             try:
                 entry, value = value.split(None, 1)
             except ValueError:
@@ -1544,17 +1655,21 @@ def read_ini(path):
             buffer.append((entry.strip(), value.strip(), position))
     return buffer
 
+
 class Shiori(Kawari):
+
     def __init__(self, dll_name, debug=0):
         self.debug = debug
         self.dll_name = dll_name
         self.saori_list = {}
-        self.kis_commands["saoriregist"] = self.exec_saoriregist
-        self.kis_commands["saorierase"] = self.exec_saorierase
-        self.kis_commands["callsaori"] = self.exec_callsaori
-        self.kis_commands["callsaorix"] = self.exec_callsaorix
+        self.kis_commands['saoriregist'] = self.exec_saoriregist
+        self.kis_commands['saorierase'] = self.exec_saorierase
+        self.kis_commands['callsaori'] = self.exec_callsaori
+        self.kis_commands['callsaorix'] = self.exec_callsaorix
+
     def use_saori(self, saori):
         self.saori = saori
+
     def load(self, kawari_dir):
         self.kawari_dir = kawari_dir
         pathlist = [None]
@@ -1568,16 +1683,20 @@ class Shiori(Kawari):
             elif is_local_script(path):
                 rdict, kdict = read_local_script(path)
             else:
-                rdict, kdict = create_dict(read_dict(path, self.debug), self.debug)
+                rdict, kdict = create_dict(read_dict(path, self.debug),
+                                           self.debug)
             rdictlist.append(rdict)
             kdictlist.append(kdict)
-        Kawari.__init__(self, kawari_dir, pathlist, rdictlist, kdictlist, self.debug)
+        Kawari.__init__(self, kawari_dir, pathlist, rdictlist, kdictlist,
+                        self.debug)
         for key in self.saori_ini.keys():
-            if self.saori_ini[key][1] == "preload":
-                head, tail = os.path.split(self.saori_ini[key][0].replace('\\', '/'))
+            if self.saori_ini[key][1] == 'preload':
+                head, tail = os.path.split(
+                    self.saori_ini[key][0].replace('\\', '/'))
                 self.saori_load(self.saori_ini[key][0],
                                 os.path.join(self.kawari_dir, head))
         return 1
+
     def unload(self):
         Kawari.finalize(self)
         for name in self.saori_list.keys():
@@ -1585,6 +1704,7 @@ class Shiori(Kawari):
             del self.saori_list[name]
         global charset
         charset = 'Shift_JIS' # reset
+
     def find(self, dir, dll_name):
         result = 0
         if list_dict(dir):
@@ -1592,12 +1712,15 @@ class Shiori(Kawari):
         global charset
         charset = 'Shift_JIS' # reset
         return result
+
     def show_description(self):
-        sys.stdout.write('Shiori: KAWARI compatible module for ninix\n'
-                         '        Copyright (C) 2001, 2002 by Tamito KAJIYAMA\n'
-                         '        Copyright (C) 2002, 2003 by MATSUMURA Namihiko\n'
-                         '        Copyright (C) 2002-2004 by Shyouzou Sugitani\n'
-                         '        Copyright (C) 2003 by Shun-ichi TAHARA\n')
+        sys.stdout.write(
+            'Shiori: KAWARI compatible module for ninix\n'
+            '        Copyright (C) 2001, 2002 by Tamito KAJIYAMA\n'
+            '        Copyright (C) 2002, 2003 by MATSUMURA Namihiko\n'
+            '        Copyright (C) 2002-2005 by Shyouzou Sugitani\n'
+            '        Copyright (C) 2003 by Shun-ichi TAHARA\n')
+
     def request(self, req_string):
         header = StringIO.StringIO(req_string)
         req_header = {}
@@ -1618,7 +1741,7 @@ class Shiori(Kawari):
                 colon = line.find(':')
                 if colon >= 0:
                     key = line[:colon].strip()
-                    value = line[colon+1:].strip()
+                    value = line[colon + 1:].strip()
                     try:
                         value = int(value)
                     except:
@@ -1635,16 +1758,17 @@ class Shiori(Kawari):
                 result = self.getdms()
             elif req_header['ID'] == 'OnAITalk':
                 result = self.getaistringrandom()
-            elif req_header['ID'] in ["\\ms", "\\mz", "\\ml", "\\mc", "\\mh", \
-                                      "\\mt", "\\me", "\\mp"]:
+            elif req_header['ID'] in ['\\ms', '\\mz', '\\ml', '\\mc', '\\mh', \
+                                      '\\mt', '\\me', '\\mp']:
                 result = self.getword(req_header['ID'][1:])
-            elif req_header['ID'] == "\\m?":
-                result = self.getword("m")
+            elif req_header['ID'] == '\\m?':
+                result = self.getword('m')
             elif req_header['ID'] == 'otherghostname':
                 otherghost = []
                 for n in range(128):
-                    if req_header.has_key('Reference'+str(n)):
-                        otherghost.append(req_header['Reference'+str(n)])
+                    if req_header.has_key(''.join(('Reference', str(n)))):
+                        otherghost.append(
+                            req_header[''.join(('Reference', str(n)))])
                 result = self.otherghostname(otherghost)
             elif req_header['ID'] == 'OnTeach':
                 if req_header.has_key('Reference0'):
@@ -1654,13 +1778,14 @@ class Shiori(Kawari):
                 if not result:
                     ref = []
                     for n in range(8):
-                        if req_header.has_key('Reference'+str(n)):
-                            ref.append(req_header['Reference'+str(n)])
+                        if req_header.has_key(''.join(('Reference', str(n)))):
+                            ref.append(req_header[''.join(('Reference', str(n)))])
                         else:
                             ref.append(None)
                     ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7 = ref
                     result = self.get_event_response(
-                        req_header['ID'], ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7)
+                        req_header['ID'], ref0, ref1, ref2, ref3, ref4,
+                        ref5, ref6, ref7)
             if result is None:
                 result = ''
             to = self.communicate_to()
@@ -1668,36 +1793,41 @@ class Shiori(Kawari):
                  'Sender: Kawari\r\n' \
                  'Value: %s\r\n' % result
         if to is not None:
-            result += 'Reference0: %s\r\n' % to
-        result += '\r\n'
+            result = ''.join((result, 'Reference0: %s\r\n' % to))
+        result = ''.join((result, '\r\n'))
         return result            
+
     def exec_saoriregist(self, kawari, argv):
         file = self.expand(argv[1])
         alias = self.expand(argv[2])
         if len(argv) == 4:
             option = self.expand(argv[3])
         else:
-            option = "loadoncall"
+            option = 'loadoncall'
         self.saori_ini[alias] = [file, option]
-        if self.saori_ini[alias][1] == "preload":
-            head, tail = os.path.split(self.saori_ini[alias][0].replace('\\', '/'))
+        if self.saori_ini[alias][1] == 'preload':
+            head, tail = os.path.split(
+                self.saori_ini[alias][0].replace('\\', '/'))
             self.saori_load(self.saori_ini[alias][0],
                             os.path.join(self.kawari_dir, head))
-        return ""
+        return ''
+
     def exec_saorierase(self, kawari, argv):
         alias = self.expand(argv[1])
         if self.saori_ini.has_key(alias):
             self.saori_unload(self.saori_ini[alias][0])
-        return ""
+        return ''
+
     def exec_callsaori(self, kawari, argv):
         alias = self.expand(argv[1])
         if not self.saori_ini.has_key(alias):
-            return ""
+            return ''
         if not self.saori_list.has_key(self.saori_ini[alias][0]):
-            if self.saori_ini[alias][1] == "preload":
-                return ""
+            if self.saori_ini[alias][1] == 'preload':
+                return ''
             else:
-                head, tail = os.path.split(self.saori_ini[alias][0].replace('\\', '/'))
+                head, tail = os.path.split(
+                    self.saori_ini[alias][0].replace('\\', '/'))
                 self.saori_load(self.saori_ini[alias][0],
                                 os.path.join(self.kawari_dir, head))
         saori_statuscode = ''
@@ -1709,13 +1839,15 @@ class Shiori(Kawari):
               'SecurityLevel: local\r\n' \
               'Charset: %s\r\n' % charset
         for i in range(2, len(argv)):
-            req += 'Argument%s: %s\r\n' % (i-2, self.expand(argv[i]))
-        req += '\r\n'
-        response = self.saori_request(self.saori_ini[alias][0], req.encode(charset, 'ignore'))
+            req = ''.join((req,
+                           'Argument%s: %s\r\n' % (i - 2, self.expand(argv[i]))))
+        req = ''.join((req, '\r\n'))
+        response = self.saori_request(self.saori_ini[alias][0],
+                                      req.encode(charset, 'ignore'))
         header = StringIO.StringIO(response)
         line = header.readline()
         if line:
-            if line[-1] == '\n':
+            if line.endswith('\n'):
                 line = line[:-1]
             line = line.strip()
             pos_space = line.find(' ')
@@ -1726,7 +1858,7 @@ class Shiori(Kawari):
                 line = header.readline()
                 if not line:
                     break # EOF
-                if line[-1] == '\n':
+                if line.endswith('\n'):
                     line = line[:-1]
                 line = line.strip()
                 if not line:
@@ -1734,7 +1866,7 @@ class Shiori(Kawari):
                 colon = line.find(':')
                 if colon >= 0:
                     key = line[:colon].strip()
-                    value = line[colon+1:].strip()
+                    value = line[colon + 1:].strip()
                     if key:
                         saori_header.append(key)
                         saori_value[key] = value
@@ -1742,19 +1874,21 @@ class Shiori(Kawari):
             result = saori_value['Result']
         else:
             result =  ''
-        if self.saori_ini[alias][1] == "noresident":
+        if self.saori_ini[alias][1] == 'noresident':
             self.saori_unload(self.saori_ini[alias][0])
         return result
+
     def exec_callsaorix(self, kawari, argv):
         alias = self.expand(argv[1])
         entry = self.expand(argv[2])
         if not self.saori_ini.has_key(alias):
-            return ""
+            return ''
         if not self.saori_list.has_key(self.saori_ini[alias][0]):
             if self.saori_ini[alias][1] == 'preload':
-                return ""
+                return ''
             else:
-                head, tail = os.path.split(self.saori_ini[alias][0].replace('\\', '/'))
+                head, tail = os.path.split(
+                    self.saori_ini[alias][0].replace('\\', '/'))
                 self.saori_load(self.saori_ini[alias][0],
                                 os.path.join(self.kawari_dir, head))
         saori_statuscode = ''
@@ -1765,13 +1899,15 @@ class Shiori(Kawari):
               'Sender: KAWARI\r\n' \
               'SecurityLevel: local\r\n'
         for i in range(3, len(argv)):
-            req += 'Argument%s: %s\r\n' % (i-3, self.expand(argv[i]))
-        req += '\r\n'
-        response = self.saori_request(self.saori_ini[alias][0], req.encode(charset, 'ignore'))
+            req = ''.join((req,
+                           'Argument%s: %s\r\n' % (i - 3, self.expand(argv[i]))))
+        req = ''.join((req, '\r\n'))
+        response = self.saori_request(self.saori_ini[alias][0],
+                                      req.encode(charset, 'ignore'))
         header = StringIO.StringIO(response)
         line = header.readline()
         if line:
-            if line[-1] == '\n':
+            if line.endswith('\n'):
                 line = line[:-1]
             line = line.strip()
             pos_space = line.find(' ')
@@ -1782,7 +1918,7 @@ class Shiori(Kawari):
                 line = header.readline()
                 if not line:
                     break # EOF
-                if line[-1] == '\n':
+                if line.endswith('\n'):
                     line = line[:-1]
                 line = line.strip()
                 if not line:
@@ -1790,19 +1926,20 @@ class Shiori(Kawari):
                 colon = line.find(':')
                 if colon >= 0:
                     key = line[:colon].strip()
-                    value = line[colon+1:].strip()
+                    value = line[colon + 1:].strip()
                     if key:
                         saori_header.append(key)
                         saori_value[key] = value
         result = {}
         for key in saori_value.keys():
-            if key[:5] == 'Value':
+            if key.startswith('Value'):
                 result[key] = saori_value[key]
         for key in result.keys():
-            self.set(string.join((entry, '.', key), ''), result[key])
-        if self.saori_ini[alias][1] == "noresident":
+            self.set(''.join((entry, '.', key)), result[key])
+        if self.saori_ini[alias][1] == 'noresident':
             self.saori_unload(self.saori_ini[alias][0])
         return len(result)
+
     def saori_load(self, saori, path):
         result = 0
         if self.saori_list.has_key(saori):
@@ -1813,17 +1950,20 @@ class Shiori(Kawari):
                 self.saori_list[saori] = module
                 result = self.saori_list[saori].load(path)
         return result
+
     def saori_unload(self, saori):
         result = 0
         if self.saori_list.has_key(saori):
             result = self.saori_list[saori].unload()
         return result
+
     def saori_request(self, saori, req):
         result = 'SAORI/1.0 500 Internal Server Error'
         if self.saori_list.has_key(saori):
             result = self.saori_list[saori].request(req)
         return result
 
+
 def open(kawari_dir, debug=0):
     pathlist = [None]
     rdictlist = [{}]
@@ -1842,46 +1982,47 @@ def open(kawari_dir, debug=0):
 
 def is_local_script(path):
     line = builtin_open(path).readline()
-    return line[:8] == "[SAKURA]"
+    return line.startswith('[SAKURA]')
 
 ###   TEST   ###
 
 def test():
     import sys, getopt
     try:
-        options, argv = getopt.getopt(sys.argv[1:], "d:", ["debug="])
+        options, argv = getopt.getopt(sys.argv[1:], 'd:', ['debug='])
     except getopt.error, e:
-        sys.stderr.write(str(e) + "\n")
+        sys.stderr.write(''.join((str(e), '\n')))
         sys.exit(1)
-    if len(argv) > 0:
+    if argv:
         kawari_dir = argv[0]
     else:
         kawari_dir = os.curdir
-    debug = 4+8+16+32+64+128
+    debug = 4 + 8 + 16 + 32 + 64 + 128
     for opt, val in options:
-        if opt in ["-d", "--debug"]:
+        if opt in ['-d', '--debug']:
             debug = int(val)
-    print "reading kawari.ini..."
+    print 'reading kawari.ini...'
     kawari = open(kawari_dir, debug)
     for rdict in kawari.rdictlist:
         for k, v in rdict.items():
             print k.encode('UTF-8', 'ignore')
             for p in v:
-                print "\t" + string.join(p, "").encode('UTF-8', 'ignore')
+                print ''.join(('\t', ''.join(p).encode('UTF-8', 'ignore')))
     for kdict in kawari.kdictlist:
         for k, v in kdict.items():
-            print '[ "' + string.join(k, '", "').encode('UTF-8', 'ignore') + '" ]'
+            print ''.join(
+                ('[ "', '", "'.join(k).encode('UTF-8', 'ignore'), '" ]'))
             for p in v:
-                print "\t" + string.join(p, "").encode('UTF-8', 'ignore')
+                print ''.join(('\t', ''.join(p).encode('UTF-8', 'ignore')))
     while 1:
-        print "=" * 40
+        print '=' * 40
         s = kawari.getaistringrandom()
-        print "-" * 40
+        print '-' * 40
         print unicode(s, charset, 'ignore').encode('UTF-8', 'ignore')
         try:
             raw_input()
         except (EOFError, KeyboardInterrupt):
             break
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     test()
index a0dc754..d27c006 100644 (file)
@@ -2,7 +2,7 @@
 #
 #  kawari8.py - a (Real) 華和梨 loader for ninix
 #  Copyright (C) 2002, 2003 by ABE Hideaki <abe-xx@eos.dricas.com>
-#  Copyright (C) 2002-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
 #
 #  This program is free software; you can redistribute it and/or modify it
@@ -12,7 +12,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-#  $Id: kawari8.py,v 1.8 2004/10/10 05:16:47 shy Exp $
+#  $Id: kawari8.py,v 1.9 2005/08/09 00:41:52 shy Exp $
 #
 
 import os
@@ -23,23 +23,30 @@ try:
 except:
     _kawari8 = None
 
+
 class Shiori:
+
     def __init__(self, dll_name):
         self.dll_name = dll_name
         self.handle = 0
+
     def use_saori(self, saori):
         self.saori = saori
+
     def find(self, dir, dll_name):
         result = 0
         if _kawari8:
             if os.path.isfile(os.path.join(dir, 'kawarirc.kis')):
                 result = 205
         return result
+
     def show_description(self):
-        sys.stdout.write('Shiori: Real Kawari8 loader for ninix\n'
-                         '        Copyright (C) 2002, 2003 by ABE Hideaki\n'
-                         '        Copyright (C) 2002-2004 by Shyouzou Sugitani\n'
-                         '        Copyright (C) 2002, 2003 by MATSUMURA Namihiko\n')
+        sys.stdout.write(
+            'Shiori: Real Kawari8 loader for ninix\n'
+            '        Copyright (C) 2002, 2003 by ABE Hideaki\n'
+            '        Copyright (C) 2002-2005 by Shyouzou Sugitani\n'
+            '        Copyright (C) 2002, 2003 by MATSUMURA Namihiko\n')
+
     def load(self, dir):
         self.dir = dir
         self.saori_list = {}
@@ -48,7 +55,7 @@ class Shiori:
             if self.dir[-1] == os.sep:
                 dir = self.dir
             else:
-                dir = self.dir + os.sep
+                dir = ''.join((self.dir, os.sep))
             _kawari8.setcallback(self.saori_exist,
                                  self.saori_load,
                                  self.saori_unload,
@@ -61,6 +68,7 @@ class Shiori:
                 return 0
         else:
             return 0
+
     def unload(self):
         if _kawari8:
             _kawari8.unload(self.handle)
@@ -68,11 +76,13 @@ class Shiori:
                 if self.saori_list[name][1]:
                     self.saori_list[name][0].unload()
                 del self.saori_list[name]
+
     def request(self, req_string):
         if _kawari8:
             return _kawari8.request(self.handle, req_string)
         else:
             return '' # FIXME
+
     def saori_exist(self, saori):
         module = self.saori.request(saori)
         if module:
@@ -80,24 +90,28 @@ class Shiori:
             return len(self.saori_list)
         else:
             return 0
+
     def saori_load(self, saori, path):
         result = 0
         if self.saori_list.has_key(saori) and self.saori_list[saori][1] == 0:
             result = self.saori_list[saori][0].load(path)
             self.saori_list[saori][1] = result
         return result
+
     def saori_unload(self, saori):
         result = 0
         if self.saori_list.has_key(saori) and self.saori_list[saori][1] != 0:
             result = self.saori_list[saori][0].unload()
             self.saori_list[saori][1] = 0
         return result
+
     def saori_request(self, saori, req):
         result = 'SAORI/1.0 500 Internal Server Error'
         if self.saori_list.has_key(saori):
             if self.saori_list[saori][1] == 0:
                 head, tail = os.path.split(saori)
-                self.saori_list[saori][1] = self.saori_list[saori][0].load(head)
+                self.saori_list[saori][1] = \
+                                          self.saori_list[saori][0].load(head)
             if self.saori_list[saori][1]:
                 result = self.saori_list[saori][0].request(req)
         return result
index f755fe7..60fc3c4 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: ascii -*-
 #
 #  lettuce.py - a LETTUCE compatible Saori module for ninix
-#  Copyright (C) 2002-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
 #
 #  This program is free software; you can redistribute it and/or modify it
@@ -11,7 +11,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-#  $Id: lettuce.py,v 1.8 2005/07/29 08:25:59 shy Exp $
+#  $Id: lettuce.py,v 1.9 2005/08/09 00:41:52 shy Exp $
 #
 
 import os
@@ -20,16 +20,21 @@ import socket
 
 from ninix.dll import SAORI
 
+
 class Saori(SAORI):
+
     module_name = 'LETTUCE'
     dll_name = 'lettuce.dll'
+
     def __init__(self):
        SAORI.__init__(self)
         self.files = {}
         self.sstpport = None
         self.__ghost = None
+
     def need_ghost_backdoor(self, ghost):
         self.__ghost = ghost
+
     def load(self, dir=os.curdir):
         self.dir = dir
         result = 0
@@ -40,6 +45,7 @@ class Saori(SAORI):
             self.loaded = 1
             result = 1
        return result
+
     def finalize(self):
         #for name in self.files.keys():
         #    pid = self.files[name]['pid']
@@ -48,6 +54,7 @@ class Saori(SAORI):
         #        os.waitpid(pid, 0)
         self.files = {}
         return 1
+
     def signal_handler(self, signum, frame):
         for name in self.files.keys():
             pid = self.files[name]['pid']
@@ -62,22 +69,26 @@ class Saori(SAORI):
                     self.files[name]['status'] = 'stop'
                     ### send SSTP message ###
                     if os.WIFEXITED(result[1]) and self.sstpport:
-                        address = ("", int(self.sstpport))
+                        address = ('', int(self.sstpport))
                         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                         try:
                             s.connect(address)
                         except socket.error:
-                            sys.stderr.write("%s: cannot connect to the SSTP server\n" % self.module_name)
+                            sys.stderr.write(
+                                '%s: cannot connect to the SSTP server\n' % \
+                                self.module_name)
                             return
-                        s.send("SEND SSTP/1.1\r\n"
-                               "Sender: %s\r\n" % self.module_name + \
-                               "Event: OnApplicationOperationFinish\r\n"
-                               "Reference0: %s\r\n" % self.dll_name + \
-                               "Reference1: play.finished\r\n"
-                               "Reference2: %s\r\n" % name + \
-                               "Charset: ASCII\r\n\r\n")
+                        s.send(
+                            ''.join(('SEND SSTP/1.1\r\n'
+                                     'Sender: %s\r\n' % self.module_name,
+                                     'Event: OnApplicationOperationFinish\r\n',
+                                     'Reference0: %s\r\n' % self.dll_name,
+                                     'Reference1: play.finished\r\n',
+                                     'Reference2: %s\r\n' % name,
+                                     'Charset: ASCII\r\n\r\n')))
                         s.recv(1024)
                         s.close()
+
     def request(self, req):
         type, argument = self.evaluate_request(req)
         if not type:
@@ -85,7 +96,7 @@ class Saori(SAORI):
         elif type == 'GET Version':
             return 'SAORI/1.0 200 OK\r\n\r\n'
         elif type == 'EXECUTE':
-            if len(argument) == 0:
+            if not argument:
                 return 'SAORI/1.0 400 Bad Request\r\n\r\n'
             command = argument[0]
             result = 0
@@ -100,7 +111,8 @@ class Saori(SAORI):
                     return 'SAORI/1.0 400 Bad Request\r\n\r\n'
                 else:
                     name = argument[1].replace('\\', '/').lower() ## FIXME: Shiori -> filename
-                    filepath = os.path.join(self.dir, './' + name + 'ogg')
+                    filepath = os.path.join(self.dir,
+                                            ''.join(('./', name, 'ogg')))
                 if self.files.has_key(name):
                     pid = self.files[name]['pid']
                     if pid and self.files[name]['status'] == 'play':
@@ -157,9 +169,10 @@ class Saori(SAORI):
             elif command == 'reset.loop':
                 pass # FIXME
             return 'SAORI/1.0 200 OK\r\nResult: %s\r\n\r\n' % result
+
     def execute_command(self, command, arg):
-        pos = command.find("%s")
+        pos = command.find('%s')
         if pos < 0:
-            sys.stderr.write("cannot execute command (%s missing)\n")
+            sys.stderr.write('cannot execute command (%s missing)\n')
             return
-        os.system(command[:pos] + arg + command[pos+2:])
+        os.system(''.join((command[:pos], arg, command[pos + 2:])))
index d1b8ba9..2bce8b0 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: ascii -*-
 #
 #  mciaudio.py - a MCIAUDIO compatible Saori module for ninix
-#  Copyright (C) 2002-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
 #
 #  This program is free software; you can redistribute it and/or modify it
@@ -11,7 +11,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-#  $Id: mciaudio.py,v 1.6 2005/07/29 08:25:59 shy Exp $
+#  $Id: mciaudio.py,v 1.7 2005/08/09 00:41:52 shy Exp $
 #
 
 import os
@@ -19,20 +19,25 @@ import signal
 
 from ninix.dll import SAORI
 
+
 class Saori(SAORI):
+
     def __init__(self):
         SAORI.__init__(self)
         self.pid = 0
         self.filepath = None
         self.__ghost = None
         self.pause = 0
+
     def need_ghost_backdoor(self, ghost):
         self.__ghost = ghost
+
     def check_import(self):
         if self.__ghost is not None:
             return 1
         else:
             return 0
+
     def finalize(self):
         if self.pid != 0:
             try:
@@ -43,6 +48,7 @@ class Saori(SAORI):
            self.pid = 0
         self.filepath = None
         return 1
+
     def execute(self, argv):
         argc = len(argv)
         if argc == 1:
@@ -86,11 +92,13 @@ class Saori(SAORI):
                         pass
                     self.pid = 0
                 filename = argv[1].replace('\\', '/').lower()
-                self.filepath = os.path.join(self.__ghost.get_prefix(), 'ghost/master', filename)
+                self.filepath = os.path.join(self.__ghost.get_prefix(),
+                                             'ghost/master', filename)
         return 'SAORI/1.0 204 No Content\r\n\r\n'
+
     def execute_command(self, command, arg):
-        pos = command.find("%s")
+        pos = command.find('%s')
         if pos < 0:
-            sys.stderr.write("cannot execute command (%s missing)\n")
+            sys.stderr.write('cannot execute command (%s missing)\n')
             return
-        os.system(command[:pos] + arg + command[pos+2:])
+        os.system(''.join((command[:pos], arg, command[pos + 2:])))
index ed5fa47..f3cf553 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: UTF-8 -*-
 #
 #  mciaudior.py - a MCIAUDIOR compatible Saori module for ninix
-#  Copyright (C) 2003, 2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2003-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #  Copyright (C) 2003 by MATSUMURA Namihiko <nie@counterghost.net>
 #
 #  This program is free software; you can redistribute it and/or modify it
@@ -11,7 +11,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-#  $Id: mciaudior.py,v 1.7 2005/07/29 08:25:59 shy Exp $
+#  $Id: mciaudior.py,v 1.8 2005/08/09 00:41:52 shy Exp $
 
 # TODO:
 # - loop 演奏.
@@ -21,20 +21,25 @@ import signal
 
 from ninix.dll import SAORI
 
+
 class Saori(SAORI):
+
     def __init__(self):
         SAORI.__init__(self)
         self.pid = 0
         self.filepath = None
         self.__ghost = None
         self.pause = 0
+
     def need_ghost_backdoor(self, ghost):
         self.__ghost = ghost
+
     def check_import(self):
         if self.__ghost is not None:
             return 1
         else:
             return 0
+
     def finalize(self):
         if self.pid != 0:
             try:
@@ -45,6 +50,7 @@ class Saori(SAORI):
            self.pid = 0
         self.filepath = None
         return 1
+
     def execute(self, argv):
         argc = len(argv)
         if argc == 1:
@@ -90,9 +96,10 @@ class Saori(SAORI):
                 filename = argv[1].replace('\\', '/').lower()
                 self.filepath = os.path.join(self.dir, filename)
         return 'SAORI/1.0 204 No Content\r\n\r\n'
+
     def execute_command(self, command, arg):
-        pos = command.find("%s")
+        pos = command.find('%s')
         if pos < 0:
-            sys.stderr.write("cannot execute command (%s missing)\n")
+            sys.stderr.write('cannot execute command (%s missing)\n')
             return
-        os.system(command[:pos] + arg + command[pos+2:])
+        os.system(''.join((command[:pos], arg, command[pos + 2:])))
index 75a4643..aa39d76 100644 (file)
@@ -12,7 +12,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: misaka.py,v 1.23 2005/07/29 08:25:59 shy Exp $
+# $Id: misaka.py,v 1.24 2005/08/09 00:41:52 shy Exp $
 #
 
 # TODO:
 
 import os
 import re
-import string
 import StringIO
 import sys
 import time
 import random
-from types import *
 
 builtin_open = open
 
+
 class MisakaError(ValueError):
     pass
 
+
 def lexical_error(path=None, position=None):
     if path is None and position is None:
-        error = "lexical error"
+        error = 'lexical error'
     elif path is None:
-        at = "line %d, column %d" % (position)
-        error = "lexical error at %s" % at
+        at = 'line %d, column %d' % (position)
+        error = 'lexical error at %s' % at
     elif position is None:
-        error = "lexical error in %s" % path
+        error = 'lexical error in %s' % path
     else:
-        at = "line %d, column %d" % (position)
-        error = "lexical error at %s in %s" % (at, path)
+        at = 'line %d, column %d' % (position)
+        error = 'lexical error at %s in %s' % (at, path)
     raise MisakaError, error
 
 def syntax_error(message, path=None, position=None):
     if path is None and position is None:
-        error = "syntax error (%s)" % message
+        error = 'syntax error (%s)' % message
     elif path is None:
-        at = "line %d, column %d" % position
-        error = "syntax error at %s (%s)" % (at, message)
+        at = 'line %d, column %d' % position
+        error = 'syntax error at %s (%s)' % (at, message)
     elif position is None:
-        error = "syntax error in %s (%s)" % (path, message)
+        error = 'syntax error in %s (%s)' % (path, message)
     else:
-        at = "line %d, column %d" % position
-        error = "syntax error at %s in %s (%s)" % (at, path, message)
+        at = 'line %d, column %d' % position
+        error = 'syntax error at %s in %s (%s)' % (at, path, message)
     raise MisakaError, error
 
 def list_dict(dir):
@@ -71,7 +71,7 @@ def list_dict(dir):
     return buffer
 
 def read_misaka_ini(dir, _debug=0):
-    path = os.path.join(dir, "misaka.ini")
+    path = os.path.join(dir, 'misaka.ini')
     file = builtin_open(path)
     filelist = []
     debug = 0
@@ -81,33 +81,33 @@ def read_misaka_ini(dir, _debug=0):
         if not line:
             break
         line = line.strip()
-        if not line or line[:2] == "//":
+        if not line or line.startswith('//'):
             continue
-        if line == "dictionaries":
+        if line == 'dictionaries':
             line = file.readline()
-            if line.strip() != "{":
-                syntax_error("expected an open brace", path)
+            if line.strip() != '{':
+                syntax_error('expected an open brace', path)
             while 1:
                 line = file.readline()
                 if not line:
-                    syntax_error("unexpected end of file", path)
+                    syntax_error('unexpected end of file', path)
                 line = line.strip()
-                if line == "}":
+                if line == '}':
                     break
-                if not line or line[:2] == "//":
+                if not line or line.startswith('//'):
                     continue
-                filelist.append(line.replace("\\", "/").lower())
-        elif line == "debug,0":
+                filelist.append(line.replace('\\', '/').lower())
+        elif line == 'debug,0':
             debug = 0
-        elif line == "debug,1":
+        elif line == 'debug,1':
             debug = 1
-        elif line == "error,0":
+        elif line == 'error,0':
             error = 0
-        elif line == "error,1":
+        elif line == 'error,1':
             error = 1
-        elif line == "propertyhandler,0":
+        elif line == 'propertyhandler,0':
             pass
-        elif line == "propertyhandler,1":
+        elif line == 'propertyhandler,1':
             pass
         elif _debug & 4:
             print "misaka.py: unknown directive '%s'" % line
@@ -131,48 +131,52 @@ TOKEN_OPERATOR      = 13
 TOKEN_DIRECTIVE     = 14
 TOKEN_TEXT          = 15
 
+
 class Lexer:
-    re_comment = re.compile(r"[ \t]*//[^\r\n]*")
-    re_newline = re.compile(r"\r\n|\r|\n")
+
+    re_comment = re.compile(r'[ \t]*//[^\r\n]*')
+    re_newline = re.compile(r'\r\n|\r|\n')
     patterns = [
         (TOKEN_NEWLINE,       re_newline),
-        (TOKEN_WHITESPACE,    re.compile(r"[ \t]+")),
-        (TOKEN_OPEN_BRACE,    re.compile(r"{")),
-        (TOKEN_CLOSE_BRACE,   re.compile(r"}")),
-        (TOKEN_OPEN_PAREN,    re.compile(r"\(")),
-        (TOKEN_CLOSE_PAREN,   re.compile(r"\)")),
-        (TOKEN_OPEN_BRACKET,  re.compile(r"\[")),
-        (TOKEN_CLOSE_BRACKET, re.compile(r"\]")),
+        (TOKEN_WHITESPACE,    re.compile(r'[ \t]+')),
+        (TOKEN_OPEN_BRACE,    re.compile(r'{')),
+        (TOKEN_CLOSE_BRACE,   re.compile(r'}')),
+        (TOKEN_OPEN_PAREN,    re.compile(r'\(')),
+        (TOKEN_CLOSE_PAREN,   re.compile(r'\)')),
+        (TOKEN_OPEN_BRACKET,  re.compile(r'\[')),
+        (TOKEN_CLOSE_BRACKET, re.compile(r'\]')),
         (TOKEN_DOLLAR,        re.compile(r'\$')),
         #(TOKEN_QUOTE,         re.compile(r'"')),
-        (TOKEN_COMMA,         re.compile(r",")),
-        (TOKEN_SEMICOLON,     re.compile(r";")),
-        (TOKEN_OPERATOR,      re.compile(r"[!=]=|[<>]=?|=[<>]|&&|\|\||\+\+|--|[+\-*/]?=|[+\-*/%\^]")),
-        (TOKEN_DIRECTIVE,     re.compile(r"#[_A-Za-z][_A-Za-z0-9]*")),
+        (TOKEN_COMMA,         re.compile(r',')),
+        (TOKEN_SEMICOLON,     re.compile(r';')),
+        (TOKEN_OPERATOR,      re.compile(r'[!=]=|[<>]=?|=[<>]|&&|\|\||\+\+|--|[+\-*/]?=|[+\-*/%\^]')),
+        (TOKEN_DIRECTIVE,     re.compile(r'#[_A-Za-z][_A-Za-z0-9]*')),
         #(TOKEN_TEXT,          re.compile(r"[!&|]|(\\[,\"]|[\x01\x02#'.0-9:?@A-Z\\_`a-z~]|[\x80-\xff].)+")),
         (TOKEN_TEXT,          re.compile(ur"(\"[^\"]*\")|[!&|]|(\\[,\"]|[\x01\x02#'.0-9:?@A-Z\\_`a-z~\"]|[\u0080-\uffff])+")),
         ]
     token_names = {
-        TOKEN_WHITESPACE:    "whitespace",
-        TOKEN_NEWLINE:       "a newline",
-        TOKEN_OPEN_BRACE:    "an open brace",
-        TOKEN_CLOSE_BRACE:   "a close brace",
-        TOKEN_OPEN_PAREN:    "an open paren",
-        TOKEN_CLOSE_PAREN:   "a close paren",
-        TOKEN_OPEN_BRACKET:  "an open bracket",
-        TOKEN_CLOSE_BRACKET: "a close bracket",
-        TOKEN_DOLLAR:        "a dollar",
-        #TOKEN_QUOTE:         "a quote",
-        TOKEN_COMMA:         "a comma",
-        TOKEN_SEMICOLON:     "a semicolon",
-        TOKEN_OPERATOR:      "an operator",
-        TOKEN_DIRECTIVE:     "an directive",
-        TOKEN_TEXT:          "text",
+        TOKEN_WHITESPACE:    'whitespace',
+        TOKEN_NEWLINE:       'a newline',
+        TOKEN_OPEN_BRACE:    'an open brace',
+        TOKEN_CLOSE_BRACE:   'a close brace',
+        TOKEN_OPEN_PAREN:    'an open paren',
+        TOKEN_CLOSE_PAREN:   'a close paren',
+        TOKEN_OPEN_BRACKET:  'an open bracket',
+        TOKEN_CLOSE_BRACKET: 'a close bracket',
+        TOKEN_DOLLAR:        'a dollar',
+        #TOKEN_QUOTE:         'a quote',
+        TOKEN_COMMA:         'a comma',
+        TOKEN_SEMICOLON:     'a semicolon',
+        TOKEN_OPERATOR:      'an operator',
+        TOKEN_DIRECTIVE:     'an directive',
+        TOKEN_TEXT:          'text',
         }
+
     def __init__(self, charset='Shift_JIS', debug=0):
         self.buffer = []
         self.debug = debug
         self.charset = charset
+
     def read(self, file, path=None):
         line = 1
         column = 0
@@ -194,36 +198,41 @@ class Lexer:
                     pos = match.end()
                     break
             else:
-                ###print data[pos:pos+100]
+                ###print data[pos:pos + 100]
                 lexical_error(path, (line, column))
             if token == TOKEN_NEWLINE:
                 line = line + 1
                 column = 0
             else:
                 column = column + len(lexeme)
-        self.buffer.append((TOKEN_NEWLINE, "", (line, column)))
+        self.buffer.append((TOKEN_NEWLINE, '', (line, column)))
         self.path = path
+
     def get_position(self):
         return self.position
+
     def pop(self):
         try:
             token, lexeme, self.position = self.buffer.pop(0)
         except IndexError:
-            syntax_error("unexpected end of file", self.path)
+            syntax_error('unexpected end of file', self.path)
         ###print token, repr(lexeme)
         return token, lexeme
+
     def pop_check(self, expected):
         token, lexeme = self.pop()
         if token != expected:
-            syntax_error("exptected " + self.token_names[expected],
+            syntax_error(''.join(('exptected ', self.token_names[expected])),
                          self.path, self.get_position())
         return lexeme
+
     def look_ahead(self, index=0):
         try:
             token, lexeme, position = self.buffer[index]
         except IndexError:
-            syntax_error("unexpected end of file", self.path)
+            syntax_error('unexpected end of file', self.path)
         return token, lexeme
+
     def skip_space(self, accept_eof=0):
         while self.buffer:
             token, lexeme = self.look_ahead()
@@ -231,14 +240,16 @@ class Lexer:
                 return 0
             self.pop()
         if not accept_eof:
-            syntax_error("unexpected end of file", self.path)
+            syntax_error('unexpected end of file', self.path)
         return 1
+
     def skip_line(self):
         while self.buffer:
             token, lexeme = self.pop()
             if token == TOKEN_NEWLINE:
                 break
 
+
 ###   PARSER   ###
 
 NODE_TEXT        = 1
@@ -256,13 +267,17 @@ NODE_ADD_EXPR    = 12
 NODE_MUL_EXPR    = 13
 NODE_POW_EXPR    = 14
 
+
 class Parser:
+
     def __init__(self, debug=0):
         self.lexer = Lexer(debug=debug)
         self.debug = debug
+
     def read(self, file, path=None):
         self.lexer.read(file, path)
         self.path = path
+
     def get_dict(self):
         common = None
         groups = []
@@ -271,12 +286,12 @@ class Parser:
             if self.lexer.skip_space(1):
                 return common, groups
             token, lexeme = self.lexer.look_ahead()
-            if token == TOKEN_DIRECTIVE and lexeme == "#_Common" or \
+            if token == TOKEN_DIRECTIVE and lexeme == '#_Common' or \
                token == TOKEN_DOLLAR:
                 break
             self.lexer.skip_line()
         token, lexeme = self.lexer.look_ahead()
-        if token == TOKEN_DIRECTIVE and lexeme == "#_Common":
+        if token == TOKEN_DIRECTIVE and lexeme == '#_Common':
             common = self.get_common()
             if self.lexer.skip_space(1):
                 return common, groups
@@ -284,6 +299,7 @@ class Parser:
             groups.append(self.get_group())
             if self.lexer.skip_space(1):
                 return common, groups
+
     def get_common(self):
         self.lexer.pop()
         token, lexeme = self.lexer.look_ahead()
@@ -293,6 +309,7 @@ class Parser:
         condition = self.get_brace_expr()
         self.lexer.pop_check(TOKEN_NEWLINE)
         return condition
+
     def get_group(self):
         # get group name
         buffer = []
@@ -300,17 +317,17 @@ class Parser:
         while 1:
             token, lexeme = self.lexer.look_ahead()
             ##if token == TOKEN_TEXT or \
-            ##   token == TOKEN_OPERATOR and lexeme in ["+", "-", "*", "/", "%"]:
+            ##   token == TOKEN_OPERATOR and lexeme in ['+', '-', '*', '/', '%']:
             ## XXX
             if token not in [TOKEN_NEWLINE, TOKEN_COMMA, TOKEN_SEMICOLON]:
                 token, lexeme = self.lexer.pop()
                 buffer.append(self.unescape(lexeme))
             else:
                 break
-        if len(buffer) == 0:
-            syntax_error("null identifier",
+        if not buffer:
+            syntax_error('null identifier',
                          self.path, self.lexer.get_position())
-        name = "$" + string.join(buffer, "")
+        name = ''.join(('$', ''.join(buffer)))
         # get group parameters
         parameters = []
         while 1:
@@ -323,7 +340,7 @@ class Parser:
             elif token in [TOKEN_COMMA, TOKEN_SEMICOLON]:
                 self.lexer.pop()
             else:
-                syntax_error("expected a delimiter",
+                syntax_error('expected a delimiter',
                              self.path, self.lexer.get_position())
             token, lexeme = self.lexer.look_ahead()
             if token == TOKEN_WHITESPACE:
@@ -338,7 +355,7 @@ class Parser:
                 token, lexeme = self.lexer.pop()
                 parameters.append([NODE_TEXT, self.unescape(lexeme)])
             else:
-                syntax_error("expected a parameter or brace expression",
+                syntax_error('expected a parameter or brace expression',
                              self.path, self.lexer.get_position())
         # get sentences
         self.lexer.pop_check(TOKEN_NEWLINE)
@@ -354,6 +371,7 @@ class Parser:
                 continue
             sentences.append(sentence)
         return (name, parameters, sentences)
+
     def get_sentence(self):
         token, lexeme = self.lexer.look_ahead()
         if token == TOKEN_OPEN_BRACE:
@@ -395,20 +413,23 @@ class Parser:
                 return None
         self.lexer.pop_check(TOKEN_NEWLINE)
         return line
+
     def is_whitespace(self, node):
         return node[0] == NODE_TEXT and not node[1].strip()
+
     def unescape(self, text):
         text = text.replace(r'\,', ',')
         text = text.replace(r'\"', '"')
         return text
+
     def get_word(self):
         buffer = []
         while 1:
             token, lexeme = self.lexer.look_ahead()
             if token == TOKEN_TEXT:
                 token, lexeme = self.lexer.pop()
-                if self.unescape(lexeme)[0] == '"' and \
-                   self.unescape(lexeme)[-1] == '"':
+                if self.unescape(lexeme).startswith('"') and \
+                   self.unescape(lexeme).endswith('"'):
                     buffer.append([NODE_STRING, self.unescape(lexeme)[1:-1]])
                 else:
                     buffer.append([NODE_TEXT, self.unescape(lexeme)])
@@ -422,11 +443,12 @@ class Parser:
             else:
                 break
         # strip whitespace at the beginning and/or end of line
-        if len(buffer) > 0 and self.is_whitespace(buffer[0]):
+        if buffer and self.is_whitespace(buffer[0]):
             del buffer[0]
-        if len(buffer) > 0 and self.is_whitespace(buffer[-1]):
+        if buffer and self.is_whitespace(buffer[-1]):
             del buffer[-1]
         return buffer
+
     def get_line(self):
         buffer = []
         while 1:
@@ -446,13 +468,14 @@ class Parser:
             elif token == TOKEN_OPEN_BRACE:
                 buffer.append(self.get_brace_expr())
             else:
-                raise RuntimeError, "should not reach here"
+                raise RuntimeError, 'should not reach here'
         # strip whitespace at the beginning and/or end of line
-        if len(buffer) > 0 and self.is_whitespace(buffer[0]):
+        if buffer and self.is_whitespace(buffer[0]):
             del buffer[0]
-        if len(buffer) > 0 and self.is_whitespace(buffer[-1]):
+        if buffer and self.is_whitespace(buffer[-1]):
             del buffer[-1]
         return buffer
+
     def get_string(self):
         buffer = []
         self.lexer.pop_check(TOKEN_QUOTE)
@@ -472,22 +495,23 @@ class Parser:
                 token, lexeme = self.lexer.pop()
                 buffer.append(lexeme)
             elif token == TOKEN_NEWLINE:
-                syntax_error("unexpected end of line", self.path)
+                syntax_error('unexpected end of line', self.path)
             else:
-                raise RuntimeError, "should not reach here"
+                raise RuntimeError, 'should not reach here'
         self.lexer.pop_check(TOKEN_QUOTE)
-        return [NODE_STRING, string.join(buffer, "")]
+        return [NODE_STRING, ''.join(buffer)]
+
     def get_brace_expr(self):
         self.lexer.pop_check(TOKEN_OPEN_BRACE)
         self.lexer.skip_space()
         self.lexer.pop_check(TOKEN_DOLLAR)
         self.lexer.skip_space()
         # get identifier (function or variable)
-        nodelist = [[NODE_TEXT, "$"]]
+        nodelist = [[NODE_TEXT, '$']]
         while 1:
             token, lexeme = self.lexer.look_ahead()
             if token == TOKEN_TEXT or \
-               token == TOKEN_OPERATOR and lexeme in ["+", "-", "*", "/", "%"]:
+               token == TOKEN_OPERATOR and lexeme in ['+', '-', '*', '/', '%']:
                 token, lexeme = self.lexer.pop()
                 nodelist.append([NODE_TEXT, self.unescape(lexeme)])
             elif token == TOKEN_OPEN_BRACE:
@@ -495,17 +519,17 @@ class Parser:
             else:
                 break
         if len(nodelist) == 1:
-            syntax_error("null identifier",
+            syntax_error('null identifier',
                          self.path, self.lexer.get_position())
         self.lexer.skip_space()
         token, lexeme = self.lexer.look_ahead()
         if token == TOKEN_OPEN_PAREN:
             # function
-            name = string.join([node[1] for node in nodelist], "")
-            if name == "$if":
+            name = ''.join([node[1] for node in nodelist])
+            if name == '$if':
                 cond_expr = self.get_cond_expr()
-                then_clause = [[NODE_TEXT, "true"]]
-                else_clause = [[NODE_TEXT, "false"]]
+                then_clause = [[NODE_TEXT, 'true']]
+                else_clause = [[NODE_TEXT, 'false']]
                 self.lexer.skip_space()
                 token, lexeme = self.lexer.look_ahead()
                 if token == TOKEN_OPEN_BRACE:
@@ -522,7 +546,7 @@ class Parser:
                         assert (token == TOKEN_NEWLINE)
                     self.lexer.skip_space()
                     token, lexeme = self.lexer.look_ahead()
-                    if token == TOKEN_TEXT and lexeme == "else":
+                    if token == TOKEN_TEXT and lexeme == 'else':
                         self.lexer.pop()
                         self.lexer.skip_space()
                         self.lexer.pop_check(TOKEN_OPEN_BRACE)
@@ -549,9 +573,9 @@ class Parser:
                                 break
                             assert (token == TOKEN_NEWLINE)
                     else:
-                        else_clause = [[NODE_TEXT, ""]]
+                        else_clause = [[NODE_TEXT, '']]
                 node = [NODE_IF, cond_expr, then_clause, else_clause]
-            elif name == "$calc":
+            elif name == '$calc':
                 node = [NODE_CALC, self.get_add_expr()]
             else:
                 self.lexer.pop_check(TOKEN_OPEN_PAREN)
@@ -574,17 +598,17 @@ class Parser:
             token, lexeme = self.lexer.look_ahead()
             if token == TOKEN_OPERATOR:
                 operator = self.lexer.pop_check(TOKEN_OPERATOR)
-                if operator in ["=", "+=", "-=", "*=", "/="]:
+                if operator in ['=', '+=', '-=', '*=', '/=']:
                     self.lexer.skip_space()
                     value = self.get_add_expr()
-                elif operator == "++":
-                    operator = "+="
-                    value = [[NODE_TEXT, "1"]]
-                elif operator == "--":
-                    operator = "-="
-                    value = [[NODE_TEXT, "1"]]
+                elif operator == '++':
+                    operator = '+='
+                    value = [[NODE_TEXT, '1']]
+                elif operator == '--':
+                    operator = '-='
+                    value = [[NODE_TEXT, '1']]
                 else:
-                    syntax_error("bad operator " + operator,
+                    syntax_error(''.join(('bad operator ', operator)),
                                  self.path, self.lexer.get_position())
                 node = [NODE_ASSIGNMENT, nodelist, operator, value]
             elif token == TOKEN_OPEN_BRACKET:
@@ -599,14 +623,15 @@ class Parser:
         self.lexer.skip_space()
         self.lexer.pop_check(TOKEN_CLOSE_BRACE)
         return node
+
     def get_argument(self):
         buffer = []
         while 1:
             token, lexeme = self.lexer.look_ahead()
             if token == TOKEN_TEXT:
                 token, lexeme = self.lexer.pop()
-                if self.unescape(lexeme)[0] == '"' and \
-                   self.unescape(lexeme)[-1] == '"':
+                if self.unescape(lexeme).startswith('"') and \
+                   self.unescape(lexeme).endswith('"'):
                     buffer.append([NODE_STRING, self.unescape(lexeme)[1:-1]])
                 else:
                     buffer.append([NODE_TEXT, self.unescape(lexeme)])
@@ -624,11 +649,12 @@ class Parser:
             else:
                 break
         # strip whitespace at the beginning and/or end of line
-        if len(buffer) > 0 and self.is_whitespace(buffer[0]):
+        if buffer and self.is_whitespace(buffer[0]):
             del buffer[0]
-        if len(buffer) > 0 and self.is_whitespace(buffer[-1]):
+        if buffer and self.is_whitespace(buffer[-1]):
             del buffer[-1]
         return buffer
+
     def get_cond_expr(self):
         self.lexer.pop_check(TOKEN_OPEN_PAREN)
         self.lexer.skip_space()
@@ -636,13 +662,14 @@ class Parser:
         self.lexer.skip_space()
         self.lexer.pop_check(TOKEN_CLOSE_PAREN)
         return or_expr
+
     def get_or_expr(self):
         buffer = [NODE_OR_EXPR]
         buffer.append(self.get_and_expr())
         while 1:
             self.lexer.skip_space()
             token, lexeme = self.lexer.look_ahead()
-            if not (token == TOKEN_OPERATOR and lexeme == "||"):
+            if not (token == TOKEN_OPERATOR and lexeme == '||'):
                 break
             self.lexer.pop()
             self.lexer.skip_space()
@@ -651,13 +678,14 @@ class Parser:
             return buffer
         else:
             return buffer[1]
+
     def get_and_expr(self):
         buffer = [NODE_AND_EXPR]
         buffer.append(self.get_sub_expr())
         while 1:
             self.lexer.skip_space()
             token, lexeme = self.lexer.look_ahead()
-            if not (token == TOKEN_OPERATOR and lexeme == "&&"):
+            if not (token == TOKEN_OPERATOR and lexeme == '&&'):
                 break
             self.lexer.pop()
             self.lexer.skip_space()
@@ -666,38 +694,41 @@ class Parser:
             return buffer
         else:
             return buffer[1]
+
     def get_sub_expr(self):
         token, lexeme = self.lexer.look_ahead()
         if token == TOKEN_OPEN_PAREN:
             return self.get_cond_expr()
         else:
             return self.get_comp_expr()
+
     def get_comp_expr(self):
         buffer = [NODE_COMP_EXPR]
         buffer.append(self.get_add_expr())
         self.lexer.skip_space()
         token, lexeme = self.lexer.look_ahead()
         if token == TOKEN_OPERATOR and \
-           lexeme in ["==", "!=", "<", "<=", "=<", ">", ">=", "=>"]:
-            if lexeme == "=<":
-                lexeme = "<="
-            elif lexeme == "=>":
-                lexeme = ">="
+           lexeme in ['==', '!=', '<', '<=', '=<', '>', '>=', '=>']:
+            if lexeme == '=<':
+                lexeme = '<='
+            elif lexeme == '=>':
+                lexeme = '>='
             buffer.append(lexeme)
             self.lexer.pop()
             self.lexer.skip_space()
             buffer.append(self.get_add_expr())
         if len(buffer) == 2:
-            buffer.append("==")
-            buffer.append([[NODE_TEXT, "true"]])
+            buffer.append('==')
+            buffer.append([[NODE_TEXT, 'true']])
         return buffer
+
     def get_add_expr(self):
         buffer = [NODE_ADD_EXPR]
         buffer.append(self.get_mul_expr())
         while 1:
             self.lexer.skip_space()
             token, lexeme = self.lexer.look_ahead()
-            if not (token == TOKEN_OPERATOR and lexeme in ["+", "-"]):
+            if not (token == TOKEN_OPERATOR and lexeme in ['+', '-']):
                 break
             buffer.append(lexeme)
             self.lexer.pop()
@@ -706,13 +737,14 @@ class Parser:
         if len(buffer) > 2:
             return [buffer]
         return buffer[1]
+
     def get_mul_expr(self):
         buffer = [NODE_MUL_EXPR]
         buffer.append(self.get_pow_expr())
         while 1:
             self.lexer.skip_space()
             token, lexeme = self.lexer.look_ahead()
-            if not (token == TOKEN_OPERATOR and lexeme in ["*", "/", "%"]):
+            if not (token == TOKEN_OPERATOR and lexeme in ['*', '/', '%']):
                 break
             buffer.append(lexeme)
             self.lexer.pop()
@@ -721,13 +753,14 @@ class Parser:
         if len(buffer) > 2:
             return [buffer]
         return buffer[1]
+
     def get_pow_expr(self):
         buffer = [NODE_POW_EXPR]
         buffer.append(self.get_unary_expr())
         while 1:
             self.lexer.skip_space()
             token, lexeme = self.lexer.look_ahead()
-            if not (token == TOKEN_OPERATOR and lexeme == "^"):
+            if not (token == TOKEN_OPERATOR and lexeme == '^'):
                 break
             self.lexer.pop()
             self.lexer.skip_space()
@@ -735,16 +768,18 @@ class Parser:
         if len(buffer) > 2:
             return [buffer]
         return buffer[1]
+
     def get_unary_expr(self):
         token, lexeme = self.lexer.look_ahead()
-        if token == TOKEN_OPERATOR and lexeme in ["+", "-"]:
-            buffer = [NODE_ADD_EXPR, [[NODE_TEXT, "0"]], lexeme]
+        if token == TOKEN_OPERATOR and lexeme in ['+', '-']:
+            buffer = [NODE_ADD_EXPR, [[NODE_TEXT, '0']], lexeme]
             self.lexer.pop()
             self.lexer.skip_space()
             buffer.append(self.get_unary_expr())
             return [buffer]
         else:
             return self.get_factor()
+
     def get_factor(self):
         token, lexeme = self.lexer.look_ahead()
         if token == TOKEN_OPEN_PAREN:
@@ -756,78 +791,82 @@ class Parser:
             return add_expr
         else:
             return self.get_word()
+
     # for debug
     def dump_list(self, nodelist, depth=0):
         for node in nodelist:
             self.dump_node(node, depth)
+
     def dump_node(self, node, depth):
-        indent = "  " * depth
+        indent = '  ' * depth
         if node[0] == NODE_TEXT:
-            print indent + "TEXT", '"' + node[1].encode('UTF-8', 'ignore') + '"'
+            print ''.join((indent, 'TEXT')), \
+                  ''.join(('"', node[1].encode('UTF-8', 'ignore'), '"'))
         elif node[0] == NODE_STRING:
-            print indent + "STRING", '"' + node[1].encode('UTF-8', 'ignore') + '"'
+            print ''.join((indent, 'STRING')), \
+                  ''.join(('"', node[1].encode('UTF-8', 'ignore'), '"'))
         elif node[0] == NODE_VARIABLE:
-            print indent + "VARIABLE"
-            self.dump_list(node[1], depth+1)
+            print ''.join((indent, 'VARIABLE'))
+            self.dump_list(node[1], depth + 1)
         elif node[0] == NODE_INDEXED:
-            print indent + "INDEXED"
-            self.dump_list(node[1], depth+1)
-            print indent + "index"
-            self.dump_list(node[2], depth+1)
+            print ''.join((indent, 'INDEXED'))
+            self.dump_list(node[1], depth + 1)
+            print ''.join((indent, 'index'))
+            self.dump_list(node[2], depth + 1)
         elif node[0] == NODE_ASSIGNMENT:
-            print indent + "ASSIGNMENT"
-            self.dump_list(node[1], depth+1)
-            print indent + "op", node[2]
-            self.dump_list(node[3], depth+1)
+            print ''.join((indent, 'ASSIGNMENT'))
+            self.dump_list(node[1], depth + 1)
+            print ''.join((indent, 'op')), node[2]
+            self.dump_list(node[3], depth + 1)
         elif node[0] == NODE_FUNCTION:
-            print indent + "FUNCTION", node[1]
+            print ''.join((indent, 'FUNCTION')), node[1]
             for i in range(len(node[2])):
-                print indent + "args[%d]" % i
-                self.dump_list(node[2][i], depth+1)
+                print ''.join((indent, 'args[%d]' % i))
+                self.dump_list(node[2][i], depth + 1)
         elif node[0] == NODE_IF:
-            print indent + "IF"
-            self.dump_node(node[1], depth+1)
-            print indent + "then"
-            self.dump_list(node[2], depth+1)
-            print indent + "else"
-            self.dump_list(node[3], depth+1)
+            print ''.join((indent, 'IF'))
+            self.dump_node(node[1], depth + 1)
+            print ''.join((indent, 'then'))
+            self.dump_list(node[2], depth + 1)
+            print ''.join((indent, 'else'))
+            self.dump_list(node[3], depth + 1)
         elif node[0] == NODE_CALC:
-            print indent + "CALC"
-            self.dump_list(node[1], depth+1)
+            print ''.join((indent, 'CALC'))
+            self.dump_list(node[1], depth + 1)
         elif node[0] == NODE_AND_EXPR:
-            print indent + "AND_EXPR"
+            print ''.join((indent, 'AND_EXPR'))
             for i in range(1, len(node)):
-                self.dump_node(node[i], depth+1)
+                self.dump_node(node[i], depth + 1)
         elif node[0] == NODE_OR_EXPR:
-            print indent + "OR_EXPR"
+            print ''.join((indent, 'OR_EXPR'))
             for i in range(1, len(node)):
-                self.dump_node(node[i], depth+1)
+                self.dump_node(node[i], depth + 1)
         elif node[0] == NODE_COMP_EXPR:
-            print indent + "COMP_EXPR"
-            self.dump_list(node[1], depth+1)
-            print indent + "op", node[2]
-            self.dump_list(node[3], depth+1)
+            print ''.join((indent, 'COMP_EXPR'))
+            self.dump_list(node[1], depth + 1)
+            print ''.join((indent, 'op')), node[2]
+            self.dump_list(node[3], depth + 1)
         elif node[0] == NODE_ADD_EXPR:
-            print indent + "ADD_EXPR"
-            self.dump_list(node[1], depth+1)
+            print ''.join((indent, 'ADD_EXPR'))
+            self.dump_list(node[1], depth + 1)
             for i in range(2, len(node), 2):
-                print indent + "op", node[i]
-                self.dump_list(node[i+1], depth+1)
+                print ''.join((indent, 'op')), node[i]
+                self.dump_list(node[i + 1], depth + 1)
         elif node[0] == NODE_MUL_EXPR:
-            print indent + "MUL_EXPR"
-            self.dump_list(node[1], depth+1)
+            print ''.join((indent, 'MUL_EXPR'))
+            self.dump_list(node[1], depth + 1)
             for i in range(2, len(node), 2):
-                print indent + "op", node[i]
-                self.dump_list(node[i+1], depth+1)
+                print ''.join((indent, 'op')), node[i]
+                self.dump_list(node[i + 1], depth + 1)
         elif node[0] == NODE_POW_EXPR:
-            print indent + "POW_EXPR"
-            self.dump_list(node[1], depth+1)
+            print ''.join((indent, 'POW_EXPR'))
+            self.dump_list(node[1], depth + 1)
             for i in range(2, len(node)):
-                print indent + "op ^"
-                self.dump_list(node[i], depth+1)
+                print ''.join((indent, 'op ^'))
+                self.dump_list(node[i], depth + 1)
         else:
             print node
-            raise RuntimeError, "should not reach here"
+            raise RuntimeError, 'should not reach here'
 
 # <<< syntax >>>
 # dict       := sp ( common sp )? ( group sp )*
@@ -887,25 +926,32 @@ class Parser:
 ###   INTERPRETER   ###
 
 class Group:
+
     def __init__(self, misaka, name, list=None):
         self.misaka = misaka
         self.name = name
         self.list = list or []
+
     def __len__(self):
         return len(self.list)
+
     def __getitem__(self, index):
         return self.list[index]
+
     def get(self):
         if not self.list:
             return None
         return random.choice(self.list)
+
     def copy(self, name):
         return Array(self.misaka, name, self.list[:])
 
 class NonOverlapGroup(Group):
+
     def __init__(self, misaka, name, list=None):
         Group.__init__(self, misaka, name, list)
         self.indexes = []
+
     def get(self):
         if not self.list:
             return None
@@ -915,9 +961,11 @@ class NonOverlapGroup(Group):
         return self.list[index]
 
 class SequentialGroup(Group):
+
     def __init__(self, misaka, name, list=None):
         Group.__init__(self, misaka, name, list)
         self.indexes = []
+
     def get(self):
         if not self.list:
             return None
@@ -927,38 +975,48 @@ class SequentialGroup(Group):
         return self.list[index]
 
 class Array(Group):
+
     def append(self, s):
         self.list.append([[NODE_TEXT, unicode(s)]])
+
     def index(self, s):
         for i in range(len(self.list)):
             if s == self.misaka.expand(self.list[i]):
                 return i
         return -1
+
     def pop(self):
         if not self.list:
             return None
         return self.list.pop(random.choice(range(len(self.list))))
+
     def popmatchl(self, s):
         buffer = []
         for i in range(len(self.list)):
             t = self.misaka.expand(self.list[i])
-            if s == t[:len(s)]:
+            if t.startswith(s):
                 buffer.append(i)
         if not buffer:
             return None
         return self.list.pop(random.choice(buffer))
 
+
 TYPE_SCHOLAR = 1
 TYPE_ARRAY   = 2
 
+
 class Shiori:
-    DBNAME = "misaka.db"
+
+    DBNAME = 'misaka.db'
+
     def __init__(self, dll_name, debug=0):
         self.dll_name = dll_name
         self.debug = debug
         self.charset = 'Shift_JIS'
+
     def use_saori(self, saori):
         self.saori = saori
+
     def find(self, dir, dll_name):
         result = 0
         if list_dict(dir):
@@ -966,11 +1024,14 @@ class Shiori:
         elif os.path.isfile(os.path.join(dir, 'misaka.ini')):
             result = 200
         return result
+
     def show_description(self):
-        sys.stdout.write('Shiori: MISAKA compatible module for ninix\n'
-                         '        Copyright (C) 2002 by Tamito KAJIYAMA\n'
-                         '        Copyright (C) 2002, 2003 by MATSUMURA Namihiko\n'
-                         '        Copyright (C) 2002-2004 by Shyouzou Sugitani\n')
+        sys.stdout.write(
+            'Shiori: MISAKA compatible module for ninix\n'
+            '        Copyright (C) 2002 by Tamito KAJIYAMA\n'
+            '        Copyright (C) 2002, 2003 by MATSUMURA Namihiko\n'
+            '        Copyright (C) 2002-2005 by Shyouzou Sugitani\n')
+
     def reset(self):
         self.dict = {}
         self.variable = {}
@@ -981,18 +1042,20 @@ class Shiori:
         self.mouse_move_count = {}
         self.random_talk = -1
         self.otherghost = []
-        self.communicate = ["", ""]
+        self.communicate = ['', '']
         self.reset_request()
+
     def load(self, misaka_dir=os.curdir):
         self.misaka_dir = misaka_dir
         self.dbpath = os.path.join(self.misaka_dir, self.DBNAME)
         self.saori_library = SaoriLibrary(self.saori, self.misaka_dir)
         self.reset()
         try:
-            filelist, debug, error = read_misaka_ini(self.misaka_dir, self.debug)
+            filelist, debug, error = read_misaka_ini(self.misaka_dir,
+                                                     self.debug)
         except IOError:
             if self.debug & 4:
-                print "cannot read misaka.ini"
+                print 'cannot read misaka.ini'
             return 0
         except MisakaError, error:
             if self.debug & 4:
@@ -1008,10 +1071,10 @@ class Shiori:
                 file = builtin_open(path)
             except IOError:
                 if self.debug & 4:
-                    print "cannot read", filename
+                    print 'cannot read', filename
                 continue
             basename, suffix = os.path.splitext(filename)
-            if suffix == ".__1":
+            if suffix == '.__1':
                 file = StringIO.StringIO(self.crypt(file.read()))
             try:
                 variables, constants = self.read(file, path)
@@ -1024,11 +1087,13 @@ class Shiori:
         self.eval_globals(global_variables, 0)
         self.load_database()
         self.eval_globals(global_constants, 1)
-        if self.dict.has_key("$_OnRandomTalk"):
+        if self.dict.has_key('$_OnRandomTalk'):
             self.random_talk = 0
         return 1
+
     def crypt(self, data):
-        return string.join(map(lambda c: chr(ord(c) ^ 0xff), data), "")
+        return ''.join(map(lambda c: chr(ord(c) ^ 0xff), data))
+
     def eval_globals(self, sentences, constant):
         for sentence in sentences:
             for node in sentence:
@@ -1036,6 +1101,7 @@ class Shiori:
                     self.eval_assignment(node[1], node[2], node[3], constant)
                 elif node[0] == NODE_FUNCTION:
                     self.eval_function(node[1], node[2])
+
     def read(self, file, path=None):
         parser = Parser(self.debug)
         parser.read(file, path)
@@ -1043,12 +1109,12 @@ class Shiori:
         variables = []
         constants = []
         for name, parameters, sentences in dict:
-            if len(sentences) == 0:
+            if not sentences:
                 continue
-            elif name == "$_Variable":
+            elif name == '$_Variable':
                 variables.extend(sentences)
                 continue
-            elif name == "$_Constant":
+            elif name == '$_Constant':
                 constants.extend(sentences)
                 continue
             GroupClass = Group
@@ -1058,9 +1124,9 @@ class Shiori:
             for node in parameters:
                 if node[0] == NODE_IF:
                     conditions.append(node)
-                elif node[0] == NODE_TEXT and node[1] == "nonoverlap":
+                elif node[0] == NODE_TEXT and node[1] == 'nonoverlap':
                     GroupClass = NonOverlapGroup
-                elif node[0] == NODE_TEXT and node[1] == "sequential":
+                elif node[0] == NODE_TEXT and node[1] == 'sequential':
                     GroupClass = SequentialGroup
                 else:
                     pass # ignore unknown parameters
@@ -1071,12 +1137,14 @@ class Shiori:
                 grouplist = self.dict[name] = []
             grouplist.append((group, conditions))
         return variables, constants
+
     def strip_newline(self, line):
-        if line[-2:] == "\r\n":
+        if line.endswith('\r\n'):
             return line[:-2]
-        elif line[-1] in "\r\n":
+        elif line.endswith('\r') or line.endswith('\n'):
             return line[:-1]
         return line
+
     def load_database(self):
         try:
             file = builtin_open(self.dbpath)
@@ -1087,7 +1155,7 @@ class Shiori:
             if not line:
                 break
             header = self.strip_newline(line).split()
-            if header[0] == "SCHOLAR":
+            if header[0] == 'SCHOLAR':
                 try:
                     name = unicode(header[1], 'UTF-8')
                 except UnicodeError:
@@ -1095,7 +1163,7 @@ class Shiori:
                         name = unicode(header[1], 'EUC-JP')
                     except UnicodeError:
                         if self.debug & 4:
-                            print "misaka.py: malformed database (ignored)"
+                            print 'misaka.py: malformed database (ignored)'
                         break
                 value = self.strip_newline(file.readline())
                 try:
@@ -1105,15 +1173,15 @@ class Shiori:
                         value = unicode(value, 'EUC-JP')
                     except UnicodeError:
                         if self.debug & 4:
-                            print "misaka.py: malformed database (ignored)"
+                            print 'misaka.py: malformed database (ignored)'
                         break
                 self.variable[name] = (TYPE_SCHOLAR, value)
-            elif header[0] == "ARRAY":
+            elif header[0] == 'ARRAY':
                 try:
                     size = int(header[1])
                 except ValueError:
                     if self.debug & 4:
-                        print "misaka.py: malformed database (ignored)"
+                        print 'misaka.py: malformed database (ignored)'
                     break
                 try:
                     name = unicode(header[2], 'UTF-8')
@@ -1122,7 +1190,7 @@ class Shiori:
                         name = unicode(header[2], 'EUC-JP')
                     except UnicodeError:
                         if self.debug & 4:
-                            print "misaka.py: malformed database (ignored)"
+                            print 'misaka.py: malformed database (ignored)'
                         break
                 array = Array(self, name)
                 for i in range(size):
@@ -1134,47 +1202,54 @@ class Shiori:
                             value = unicode(value, 'EUC-JP')
                         except UnicodeError:
                             if self.debug & 4:
-                                print "misaka.py: malformed database (ignored)"
+                                print 'misaka.py: malformed database (ignored)'
                             break
                     array.append(value)
                 self.variable[name] = (TYPE_ARRAY, array)
             else:
-                raise RuntimeError, "should not reach here"
+                raise RuntimeError, 'should not reach here'
         file.close()
+
     def save_database(self):
         try:
-            file = builtin_open(self.dbpath, "w")
+            file = builtin_open(self.dbpath, 'w')
         except IOError:
             if self.debug & 4:
-                print "misaka.py: cannot write database (ignored)"
+                print 'misaka.py: cannot write database (ignored)'
             return
         for name in self.variable.keys():
             type, value = self.variable[name]
             if type == TYPE_SCHOLAR:
-                if value == "":
+                if value == '':
                     continue
-                file.write("SCHOLAR %s\n%s\n" % (name.encode('UTF-8'), unicode(value).encode('UTF-8')))
+                file.write(
+                    'SCHOLAR %s\n%s\n' % \
+                    (name.encode('UTF-8'), unicode(value).encode('UTF-8')))
             elif type == TYPE_ARRAY:
-                file.write("ARRAY %d %s\n" % (len(value), name.encode('UTF-8')))
+                file.write(
+                    'ARRAY %d %s\n' % (len(value), name.encode('UTF-8')))
                 for item in value:
-                    file.write("%s\n" % self.expand(item).encode('UTF-8'))
+                    file.write('%s\n' % self.expand(item).encode('UTF-8'))
             else:
-                raise RuntimeError, "should not reach here"
+                raise RuntimeError, 'should not reach here'
         file.close()
+
     def unload(self):
         self.save_database()
         self.saori_library.unload()
         return 1
+
     def reset_request(self):
         self.req_command = ''
         self.req_protocol = ''
         self.req_key = []
         self.req_header = {}
+
     def request(self, req_string):
         header = StringIO.StringIO(req_string)
         line = header.readline()
         if line:
-            if line[-1] == '\n':
+            if line.endswith('\n'):
                 line = line[:-1]
             line = line.strip()
             list = line.split()
@@ -1185,7 +1260,7 @@ class Shiori:
                 line = header.readline()
                 if not line:
                     break # EOF
-                if line[-1] == '\n':
+                if line.endswith('\n'):
                     line = line[:-1]
                 line = line.strip()
                 if not line:
@@ -1193,7 +1268,7 @@ class Shiori:
                 colon = line.find(':')
                 if colon >= 0:
                     key = line[:colon].strip()
-                    value = line[colon+1:].strip()
+                    value = line[colon + 1:].strip()
                     try:
                         value = int(value)
                     except:
@@ -1213,7 +1288,7 @@ class Shiori:
         ref7 = self.get_ref(7)
         event = self.req_header['ID']
         script = None
-        if event == "otherghostname":
+        if event == 'otherghostname':
             n = 0
             refs = []
             while 1:
@@ -1227,25 +1302,25 @@ class Shiori:
             for ref in refs:
                 name, s0, s1 = ref.split(chr(1))
                 self.otherghost.append([name, s0, s1])
-        if event == "OnMouseMove":
+        if event == 'OnMouseMove':
             key = (ref3, ref4) # side, part
             count = self.mouse_move_count.get(key, 0)
             self.mouse_move_count[key] = count + 5
-        if event == "OnCommunicate":
+        if event == 'OnCommunicate':
             self.communicate = [ref0, ref1]
-            script = self.get("$_OnGhostCommunicateReceive", default=None)
-        elif event == "charset":
+            script = self.get('$_OnGhostCommunicateReceive', default=None)
+        elif event == 'charset':
             script = self.charset
         else:
             self.reference = (ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7)
-            script = self.get("$" + event, default=None)
-        if event == "OnSecondChange":
+            script = self.get(''.join(('$', event)), default=None)
+        if event == 'OnSecondChange':
             if self.random_talk == 0:
                 self.reset_random_talk_interval()
             elif self.random_talk > 0:
                 self.random_talk -= 1
                 if self.random_talk == 0:
-                    script = self.get("$_OnRandomTalk", default=None)
+                    script = self.get('$_OnRandomTalk', default=None)
         if script is not None:
             script = script.strip()
         else:
@@ -1254,50 +1329,58 @@ class Shiori:
         response = 'SHIORI/3.0 200 OK\r\n' \
                    'Sender: Misaka\r\n' \
                    'Value: %s\r\n' % script.encode(self.charset, 'ignore')
-        to = self.eval_variable([[NODE_TEXT, "$to"]])
+        to = self.eval_variable([[NODE_TEXT, '$to']])
         if to:
-            del self.variable["$to"]
-            response += 'Reference0: %s\r\n' % to.encode(self.charset, 'ignore')
-        response += '\r\n'
+            del self.variable['$to']
+            response = ''.join((response,
+                                'Reference0: %s\r\n' % \
+                                to.encode(self.charset, 'ignore')))
+        response = ''.join((response, '\r\n'))
         return response
+
     def get_ref(self, num):
-        key = 'Reference'+str(num)
+        key = ''.join(('Reference', str(num)))
         if self.req_header.has_key(key):
             return self.req_header[key]
         else:
             return None
+
     # internal
     def reset_random_talk_interval(self):
         interval = 0
-        type, value = self.variable.get("$_talkinterval", (TYPE_SCHOLAR, ""))
+        type, value = self.variable.get('$_talkinterval', (TYPE_SCHOLAR, ''))
         if type == TYPE_SCHOLAR:
             try:
                 interval = max(int(value), 0)
             except ValueError:
                 pass
         self.random_talk = int(interval * random.randint(5, 15) / 10.0)
-    def get(self, name, default=""):
+
+    def get(self, name, default=''):
         grouplist = self.dict.get(name)
         if grouplist is None:
             return default
         for group, conditions in grouplist:
-            if self.eval_and_expr(conditions) == "true":
+            if self.eval_and_expr(conditions) == 'true':
                 return self.expand(group.get())
         return default
+
     def expand(self, nodelist):
         if nodelist is None:
-            return ""
+            return ''
         buffer = []
         for node in nodelist:
             buffer.append(self.eval(node))
-        return string.join(buffer, "")
+        return ''.join(buffer)
+
     def expand_args(self, nodelist):
         tmp = self.expand(nodelist)
-        if tmp[0] == '$':
+        if tmp.startswith('$'):
             result = self.eval_variable(nodelist)
         else:
             result = tmp
         return result
+
     def eval(self, node):
         if node[0] == NODE_TEXT:
             return node[1]
@@ -1328,66 +1411,68 @@ class Shiori:
         elif node[0] == NODE_POW_EXPR:
             return self.eval_pow_expr(node[1:])
         ##print node
-        raise RuntimeError, "should not reach here"
+        raise RuntimeError, 'should not reach here'
+
     SYSTEM_VARIABLES = [
         # current date and time
-        "$year", "$month", "$day", "$hour", "$minute", "$second",
+        '$year', '$month', '$day', '$hour', '$minute', '$second',
         # day of week (0 = Sunday)
-        "$dayofweek",
+        '$dayofweek',
         # ghost uptime
-        "$elapsedhour", "$elapsedminute", "$elapsedsecond",
+        '$elapsedhour', '$elapsedminute', '$elapsedsecond',
         # OS uptime
-        "$elapsedhouros", "$elapsedminuteos", "$elapsedsecondos",
+        '$elapsedhouros', '$elapsedminuteos', '$elapsedsecondos',
         # OS accumlative uptime
-        "$elapsedhourtotal", "$elapsedminutetotal", "$elapsedsecondtotal",
+        '$elapsedhourtotal', '$elapsedminutetotal', '$elapsedsecondtotal',
         # system information
-        "$os.version",
-        "$os.name",
-        "$os.phisicalmemorysize",
-        "$os.freememorysize",
-        "$os.totalmemorysize",
-        "$cpu.vendorname",
-        "$cpu.name",
-        "$cpu.clockcycle",
+        '$os.version',
+        '$os.name',
+        '$os.phisicalmemorysize',
+        '$os.freememorysize',
+        '$os.totalmemorysize',
+        '$cpu.vendorname',
+        '$cpu.name',
+        '$cpu.clockcycle',
         # number of days since the last network update
-        "$daysfromlastupdate",
+        '$daysfromlastupdate',
         # number of days since the first boot
-        "$daysfromfirstboot",
+        '$daysfromfirstboot',
         # name of the ghost with which it has communicated
-        ##"$to",
-        "$sender",
-        "$lastsentence",
-        "$otherghostlist",
+        ##'$to',
+        '$sender',
+        '$lastsentence',
+        '$otherghostlist',
         ]
+
     def eval_variable(self, name):
         now = time.localtime(time.time())
         name = self.expand(name)
-        if name == "$year":
+        if name == '$year':
             return str(now[0])
-        elif name == "$month":
+        elif name == '$month':
             return str(now[1])
-        elif name == "$day":
+        elif name == '$day':
             return str(now[2])
-        elif name == "$hour":
+        elif name == '$hour':
             return str(now[3])
-        elif name == "$minute":
+        elif name == '$minute':
             return str(now[4])
-        elif name == "$second":
+        elif name == '$second':
             return str(now[5])
-        elif name == "$dayofweek":
+        elif name == '$dayofweek':
             return str([1, 2, 3, 4, 5, 6, 0][now[6]])
-        elif name == "$lastsentence":
+        elif name == '$lastsentence':
             return self.communicate[1]
-        elif name == "$otherghostlist":
-            if len(self.otherghost) > 0:
+        elif name == '$otherghostlist':
+            if self.otherghost:
                 ghost = random.choice(self.otherghost)
                 return ghost[0]
             else:
-                return ""
-        elif name == "$sender":
+                return ''
+        elif name == '$sender':
             return self.communicate[0]
         elif name in self.SYSTEM_VARIABLES:
-            return ""
+            return ''
         elif self.dict.has_key(name):
             return self.get(name)
         elif self.constant.has_key(name):
@@ -1400,7 +1485,8 @@ class Shiori:
             if type == TYPE_ARRAY:
                 return self.expand(value.get())
             return unicode(value)
-        return ""
+        return ''
+
     def eval_indexed(self, name, index):
         name = self.expand(name)
         index = self.expand(index)
@@ -1408,58 +1494,60 @@ class Shiori:
             index = int(index)
         except ValueError:
             index = 0
-        if name == "$otherghostlist":
+        if name == '$otherghostlist':
             group = []
             for ghost in self.otherghost:
                 group.append(ghost[0])
         elif name in self.SYSTEM_VARIABLES:
-            return ""
+            return ''
         elif self.dict.has_key(name):
             grouplist = self.dict[name]
             group, constraints = grouplist[0]
         elif self.constant.has_key(name):
-            return ""
+            return ''
         elif self.variable.has_key(name):
             type, group = self.variable[name]
             if type != TYPE_ARRAY:
-                return ""
+                return ''
         else:
-            return ""
+            return ''
         if index < 0 or index >= len(group):
-            return ""
+            return ''
         return self.expand(group[index])
+
     def eval_assignment(self, name, operator, value, constant=0):
         name = self.expand(name)
         value = self.expand(value)
-        if operator in ["+=", "-=", "*=", "/="]:
+        if operator in ['+=', '-=', '*=', '/=']:
             try:
                 operand = int(value)
             except ValueError:
                 operand = 0
-            type, value = self.constant.get(name, (None, ""))
+            type, value = self.constant.get(name, (None, ''))
             if type is None:
-                type, value = self.variable.get(name, (TYPE_SCHOLAR, ""))
+                type, value = self.variable.get(name, (TYPE_SCHOLAR, ''))
             if type == TYPE_ARRAY:
-                return ""
+                return ''
             try:
                 value = int(value)
             except ValueError:
                 value = 0
-            if operator == "+=":
+            if operator == '+=':
                 value += operand
-            elif operator == "-=":
+            elif operator == '-=':
                 value -= operand
-            elif operator == "*=":
+            elif operator == '*=':
                 value *= operand
-            elif operator == "/=" and operand != 0:
+            elif operator == '/=' and operand != 0:
                 value /= operand
         if constant or self.constant.has_key(name):
             self.constant[name] = (TYPE_SCHOLAR, value)
         else:
             self.variable[name] = (TYPE_SCHOLAR, value)
-        if name == "$_talkinterval":
+        if name == '$_talkinterval':
             self.reset_random_talk_interval()
-        return ""
+        return ''
+
     def eval_comp_expr(self, operand1, operator, operand2):
         value1 = self.expand(operand1)
         value2 = self.expand(operand2)
@@ -1469,26 +1557,29 @@ class Shiori:
         except ValueError:
             operand1 = value1
             operand2 = value2
-        if operator == "==" and operand1 == operand2 or \
-           operator == "!=" and operand1 != operand2 or \
-           operator == "<"  and operand1 <  operand2 or \
-           operator == "<=" and operand1 <= operand2 or \
-           operator == ">"  and operand1 >  operand2 or \
-           operator == ">=" and operand1 >= operand2:
-            return "true"
-        return "false"
+        if operator == '==' and operand1 == operand2 or \
+           operator == '!=' and operand1 != operand2 or \
+           operator == '<'  and operand1 <  operand2 or \
+           operator == '<=' and operand1 <= operand2 or \
+           operator == '>'  and operand1 >  operand2 or \
+           operator == '>=' and operand1 >= operand2:
+            return 'true'
+        return 'false'
+
     def eval_and_expr(self, conditions):
         for condition in conditions:
             boolean = self.eval(condition)
-            if boolean.strip() != "true":
-                return "false"
-        return "true"
+            if boolean.strip() != 'true':
+                return 'false'
+        return 'true'
+
     def eval_or_expr(self, conditions):
         for condition in conditions:
             boolean = self.eval(condition)
-            if boolean.strip() == "true":
-                return "true"
-        return "false"
+            if boolean.strip() == 'true':
+                return 'true'
+        return 'false'
+
     def eval_add_expr(self, expression):
         value = self.expand(expression[0])
         try:
@@ -1496,16 +1587,17 @@ class Shiori:
         except ValueError:
             value = 0
         for i in range(1, len(expression), 2):
-            operand = self.expand(expression[i+1])
+            operand = self.expand(expression[i + 1])
             try:
                 operand = int(operand)
             except ValueError:
                 operand = 0
-            if expression[i] == "+":
+            if expression[i] == '+':
                 value += operand
-            elif expression[i] == "-":
+            elif expression[i] == '-':
                 value -= operand
         return str(value)
+
     def eval_mul_expr(self, expression):
         value = self.expand(expression[0])
         try:
@@ -1513,18 +1605,19 @@ class Shiori:
         except ValueError:
             value = 0
         for i in range(1, len(expression), 2):
-            operand = self.expand(expression[i+1])
+            operand = self.expand(expression[i + 1])
             try:
                 operand = int(operand)
             except ValueError:
                 operand = 0
-            if expression[i] == "*":
+            if expression[i] == '*':
                 value *= operand
-            elif expression[i] == "/" and operand != 0:
+            elif expression[i] == '/' and operand != 0:
                 value /= operand
-            elif expression[i] == "%" and operand != 0:
+            elif expression[i] == '%' and operand != 0:
                 value %= operand
         return str(value)
+
     def eval_pow_expr(self, expression):
         value = self.expand(expression[-1])
         try:
@@ -1532,28 +1625,33 @@ class Shiori:
         except ValueError:
             value = 0
         for i in range(1, len(expression)):
-            operand = self.expand(expression[-i-1])
+            operand = self.expand(expression[-i - 1])
             try:
                 operand = int(operand)
             except ValueError:
                 operand = 0
-            value = operand ** value
+            value = operand**value
         return str(value)
+
     def eval_if(self, condition, then_clause, else_clause):
         boolean = self.eval(condition)
-        if boolean.strip() == "true":
+        if boolean.strip() == 'true':
             return self.expand(then_clause)
         else:
             return self.expand(else_clause)
+
     def eval_calc(self, expression):
         return self.expand(expression)
+
     def eval_function(self, name, args):
         function = self.SYSTEM_FUNCTIONS.get(name)
         if function is None:
-            return ""
+            return ''
         return function(self, args)
+
     def is_number(self, s):
-        return s and filter(lambda c: c in "0123456789", s) == s
+        return s and filter(lambda c: c in '0123456789', s) == s
+
     def split(self, s):
         buffer = []
         i, j = 0, len(s)
@@ -1562,52 +1660,57 @@ class Shiori:
                 buffer.append(s[i])
                 i += 1
             else:
-                buffer.append(s[i:i+2])
+                buffer.append(s[i:i + 2])
                 i += 2
         return buffer
+
     def exec_reference(self, args):
         if len(args) != 1:
-            return ""
+            return ''
         n = self.expand_args(args[0])
         if n in '01234567':
             value = self.reference[int(n)]
             if value is not None:
                 return unicode(value)
-        return ""
+        return ''
+
     def exec_random(self, args):
         if len(args) != 1:
-            return ""
+            return ''
         n = self.expand_args(args[0])
         try:
             return str(random.randrange(int(n)))
         except ValueError:
-            return "" # n < 1 or not a number
+            return '' # n < 1 or not a number
+
     def exec_choice(self, args):
-        if len(args) == 0:
-            return ""
+        if not args:
+            return ''
         return self.expand_args(random.choice(args))
+
     def exec_getvalue(self, args):
         if len(args) != 2:
-            return ""
+            return ''
         try:
             n = int(self.expand_args(args[1]))
         except ValueError:
-            return ""
+            return ''
         if n < 0:
-            return ""
-        list = self.expand_args(args[0]).split(",")
+            return ''
+        list = self.expand_args(args[0]).split(',')
         try:
             return list[n]
         except IndexError:
-            return ""
+            return ''
+
     def exec_search(self, args):
         namelist = []
         for arg in args:
             name = self.expand_args(arg)
             if name.strip():
                 namelist.append(name)
-        if len(namelist) == 0:
-            return ""
+        if not namelist:
+            return ''
         keylist = []
         for key in self.keys(): # dict, variable, constant
             for name in namelist:
@@ -1615,18 +1718,21 @@ class Shiori:
                     break
             else:
                 keylist.append(key)
-        if len(keylist) == 0:
-            return ""
+        if not keylist:
+            return ''
         return self.eval_variable([[NODE_TEXT, random.choice(keylist)]])
+
     def keys(self):
         buffer = self.dict.keys()
         buffer.extend(self.variable.keys())
         buffer.extend(self.constant.keys())
         return buffer
+
     def exec_backup(self, args):
-        if len(args) == 0:
+        if not args:
             self.save_database()
-        return ""
+        return ''
+
     def exec_getmousemovecount(self, args):
         if len(args) == 2:
             side = self.expand_args(args[0])
@@ -1637,7 +1743,8 @@ class Shiori:
                 pass
             else:
                 return str(self.mouse_move_count.get(key, 0))
-        return ""
+        return ''
+
     def exec_resetmousemovecount(self, args):
         if len(args) == 2:
             side = self.expand_args(args[0])
@@ -1648,90 +1755,99 @@ class Shiori:
                 pass
             else:
                 self.mouse_move_count[key] = 0
-        return ""
+        return ''
+
     def exec_substring(self, args):
         if len(args) != 3:
-            return ""
+            return ''
         value = self.expand_args(args[2])
         try:
             count = int(value)
         except ValueError:
-            return ""
+            return ''
         if count < 0:
-            return ""
+            return ''
         value = self.expand_args(args[1])
         try:
             offset = int(value)
         except ValueError:
-            return ""
+            return ''
         if offset < 0:
-            return ""
+            return ''
         s = self.expand_args(args[0]).encode(self.charset, 'replace')
-        return unicode(s[offset:offset+count], self.charset, 'replace')
+        return unicode(s[offset:offset + count], self.charset, 'replace')
+
     def exec_substringl(self, args):
         if len(args) != 2:
-            return ""
+            return ''
         value = self.expand_args(args[1])
         try:
             count = int(value)
         except ValueError:
-            return ""
+            return ''
         if count < 0:
-            return ""
+            return ''
         s = self.expand_args(args[0]).encode(self.charset, 'replace')
         return unicode(s[:count], self.charset, 'replace')
+
     def exec_substringr(self, args):
         if len(args) != 2:
-            return ""
+            return ''
         value = self.expand_args(args[1])
         try:
             count = int(value)
         except ValueError:
-            return ""
+            return ''
         if count < 0:
-            return ""
+            return ''
         s = self.expand_args(args[0]).encode(self.charset, 'replace')
-        return unicode(s[len(s)-count:], self.charset, 'replace')
+        return unicode(s[len(s) - count:], self.charset, 'replace')
+
     def exec_substringfirst(self, args):
         if len(args) != 1:
-            return ""
+            return ''
         buffer = self.expand_args(args[0])
         if not buffer:
-            return ""
+            return ''
         return buffer[0]
+
     def exec_substringlast(self, args):
         if len(args) != 1:
-            return ""
+            return ''
         buffer = self.expand_args(args[0])
         if not buffer:
-            return ""
+            return ''
         return buffer[-1]
+
     def exec_length(self, args):
         if len(args) != 1:
-            return ""
-        return str(len(self.expand_args(args[0]).encode(self.charset, 'replace')))
+            return ''
+        return str(
+            len(self.expand_args(args[0]).encode(self.charset, 'replace')))
+
     katakana2hiragana = {
-        "ァ": "ぁ", "ア": "あ", "ィ": "ぃ", "イ": "い", "ゥ": "ぅ",
-        "ウ": "う", "ェ": "ぇ", "エ": "え", "ォ": "ぉ", "オ": "お",
-        "カ": "か", "ガ": "が", "キ": "き", "ギ": "ぎ", "ク": "く",
-        "グ": "ぐ", "ケ": "け", "ゲ": "げ", "コ": "こ", "ゴ": "ご",
-        "サ": "さ", "ザ": "ざ", "シ": "し", "ジ": "じ", "ス": "す",
-        "ズ": "ず", "セ": "せ", "ゼ": "ぜ", "ソ": "そ", "ゾ": "ぞ",
-        "タ": "た", "ダ": "だ", "チ": "ち", "ヂ": "ぢ", "ッ": "っ",
-        "ツ": "つ", "ヅ": "づ", "テ": "て", "デ": "で", "ト": "と",
-        "ド": "ど", "ナ": "な", "ニ": "に", "ヌ": "ぬ", "ネ": "ね",
-        "ノ": "の", "ハ": "は", "バ": "ば", "パ": "ぱ", "ヒ": "ひ",
-        "ビ": "び", "ピ": "ぴ", "フ": "ふ", "ブ": "ぶ", "プ": "ぷ",
-        "ヘ": "へ", "ベ": "べ", "ペ": "ぺ", "ホ": "ほ", "ボ": "ぼ",
-        "ポ": "ぽ", "マ": "ま", "ミ": "み", "ム": "む", "メ": "め",
-        "モ": "も", "ャ": "ゃ", "ヤ": "や", "ュ": "ゅ", "ユ": "ゆ",
-        "ョ": "ょ", "ヨ": "よ", "ラ": "ら", "リ": "り", "ル": "る",
-        "レ": "れ", "ロ": "ろ", "ヮ": "ゎ", "ワ": "わ", "ヰ": "ゐ",
-        "ヱ": "ゑ", "ヲ": "を", "ン": "ん", "ヴ": "う゛",
+        'ァ': 'ぁ', 'ア': 'あ', 'ィ': 'ぃ', 'イ': 'い', 'ゥ': 'ぅ',
+        'ウ': 'う', 'ェ': 'ぇ', 'エ': 'え', 'ォ': 'ぉ', 'オ': 'お',
+        'カ': 'か', 'ガ': 'が', 'キ': 'き', 'ギ': 'ぎ', 'ク': 'く',
+        'グ': 'ぐ', 'ケ': 'け', 'ゲ': 'げ', 'コ': 'こ', 'ゴ': 'ご',
+        'サ': 'さ', 'ザ': 'ざ', 'シ': 'し', 'ジ': 'じ', 'ス': 'す',
+        'ズ': 'ず', 'セ': 'せ', 'ゼ': 'ぜ', 'ソ': 'そ', 'ゾ': 'ぞ',
+        'タ': 'た', 'ダ': 'だ', 'チ': 'ち', 'ヂ': 'ぢ', 'ッ': 'っ',
+        'ツ': 'つ', 'ヅ': 'づ', 'テ': 'て', 'デ': 'で', 'ト': 'と',
+        'ド': 'ど', 'ナ': 'な', 'ニ': 'に', 'ヌ': 'ぬ', 'ネ': 'ね',
+        'ノ': 'の', 'ハ': 'は', 'バ': 'ば', 'パ': 'ぱ', 'ヒ': 'ひ',
+        'ビ': 'び', 'ピ': 'ぴ', 'フ': 'ふ', 'ブ': 'ぶ', 'プ': 'ぷ',
+        'ヘ': 'へ', 'ベ': 'べ', 'ペ': 'ぺ', 'ホ': 'ほ', 'ボ': 'ぼ',
+        'ポ': 'ぽ', 'マ': 'ま', 'ミ': 'み', 'ム': 'む', 'メ': 'め',
+        'モ': 'も', 'ャ': 'ゃ', 'ヤ': 'や', 'ュ': 'ゅ', 'ユ': 'ゆ',
+        'ョ': 'ょ', 'ヨ': 'よ', 'ラ': 'ら', 'リ': 'り', 'ル': 'る',
+        'レ': 'れ', 'ロ': 'ろ', 'ヮ': 'ゎ', 'ワ': 'わ', 'ヰ': 'ゐ',
+        'ヱ': 'ゑ', 'ヲ': 'を', 'ン': 'ん', 'ヴ': 'う゛',
         }
+
     def exec_hiraganacase(self, args):
         if len(args) != 1:
-            return ""
+            return ''
         buffer = []
         str = unicode(self.expand_args(args[0]), self.charset, 'replace')
         #str = unicode(args[0], self.charset, 'replace')
@@ -1740,52 +1856,55 @@ class Shiori:
             c = self.katakana2hiragana.get(c, c)
             c = unicode(c, 'utf-8')
             buffer.append(c)
-        return string.join(buffer, "")
+        return ''.join(buffer)
+
     def exec_isequallastandfirst(self, args):
         if len(args) != 2:
-            return "false"
+            return 'false'
         buffer0 = self.expand_args(args[0])
         buffer1 = self.expand_args(args[1])
-        if len(buffer0) > 0 and lenf(buffer1) > 0 and \
-           buffer0[-1] == buffer1[0]:
-            return "true"
-        return "false"
+        if buffer0 and buffer1 and buffer0[-1] == buffer1[0]:
+            return 'true'
+        return 'false'
+
     def exec_append(self, args):
         if len(args) == 2:
             name = self.expand_args(args[0])
-            if name and name[0] == "$":
-                type, value = self.variable.get(name, (TYPE_SCHOLAR, ""))
+            if name and name.startswith('$'):
+                type, value = self.variable.get(name, (TYPE_SCHOLAR, ''))
                 if type == TYPE_SCHOLAR:
                     type = TYPE_ARRAY
                     array = Array(self, name)
-                    if value != "":
+                    if value != '':
                         array.append(value)
                     value = array
                 list = self.expand_args(args[1]).split(chr(1))
                 for member in list:
                     value.append(member)
                 self.variable[name] = (type, value)
-        return ""
+        return ''
+
     def exec_stringexists(self, args):
         if len(args) != 2:
-            return ""
+            return ''
         name = self.expand_args(args[0])
-        type, value = self.variable.get(name, (TYPE_SCHOLAR, ""))
+        type, value = self.variable.get(name, (TYPE_SCHOLAR, ''))
         if type == TYPE_SCHOLAR:
-            return ""
+            return ''
         if value.index(self.expand_args(args[1])) < 0:
-            return "false"
+            return 'false'
         else:
-            return "true"
+            return 'true'
+
     def exec_copy(self, args):
         if len(args) != 2:
-            return ""
+            return ''
         src_name = self.expand_args(args[0])
-        if not (src_name and src_name[0] == "$"):
-            return ""
+        if not (src_name and src_name.startswith('$')):
+            return ''
         new_name = self.expand_args(args[1])
-        if not (new_name and new_name[0] == "$"):
-            return ""
+        if not (new_name and new_name.startswith('$')):
+            return ''
         source = None
         if self.dict.has_key(src_name):
             grouplist = self.dict[src_name]
@@ -1799,21 +1918,24 @@ class Shiori:
         else:
             value = source.copy(new_name)
         self.variable[new_name] = (TYPE_ARRAY, value)
-        return ""
+        return ''
+
     def exec_pop(self, args):
         if len(args) == 1:
             name = self.expand_args(args[0])
-            type, value = self.variable.get(name, (TYPE_SCHOLAR, ""))
+            type, value = self.variable.get(name, (TYPE_SCHOLAR, ''))
             if type == TYPE_ARRAY:
                 return self.expand(value.pop())
-        return ""
+        return ''
+
     def exec_popmatchl(self, args):
         if len(args) == 2:
             name = self.expand_args(args[0])
-            type, value = self.variable.get(name, (TYPE_SCHOLAR, ""))
+            type, value = self.variable.get(name, (TYPE_SCHOLAR, ''))
             if type == TYPE_ARRAY:
                 return self.expand(value.popmatchl(self.expand_args(args[1])))
-        return ""
+        return ''
+
     def exec_index(self, args):
         if len(args) == 2:
             pos = self.expand_args(args[1]).find(self.expand_args(args[0]))
@@ -1821,89 +1943,97 @@ class Shiori:
                 s = self.expand_args(args[0])[pos]
                 pos = len(s.encode(self.charset, 'replace'))
             return str(pos)
-        return ""
+        return ''
+
     def exec_insentence(self, args):
-        if len(args) == 0:
-            return ""
+        if not args:
+            return ''
         s = self.expand_args(args[0])
         for i in range(1, len(args)):
             if s.find(self.expand_args(args[i])) < 0:
-                return "false"
-        return "true"
+                return 'false'
+        return 'true'
+
     def exec_substringw(self, args):
         if len(args) != 3:
-            return ""
+            return ''
         value = self.expand_args(args[2])
         try:
             count = int(value)
         except ValueError:
-            return ""
+            return ''
         if count < 0:
-            return ""
+            return ''
         value = self.expand_args(args[1])
         try:
             offset = int(value)
         except ValueError:
-            return ""
+            return ''
         if offset < 0:
-            return ""
+            return ''
         buffer = self.expand_args(args[0])
-        return buffer[offset:offset+count]
+        return buffer[offset:offset + count]
+
     def exec_substringwl(self, args):
         if len(args) != 2:
-            return ""
+            return ''
         value = self.expand_args(args[1])
         try:
             count = int(value)
         except ValueError:
-            return ""
+            return ''
         if count < 0:
-            return ""
+            return ''
         buffer = self.expand_args(args[0])
         return buffer[:count]
+
     def exec_substringwr(self, args):
         if len(args) != 2:
-            return ""
+            return ''
         value = self.expand_args(args[1])
         try:
             count = int(value)
         except ValueError:
-            return ""
+            return ''
         if count < 0:
-            return ""
+            return ''
         buffer = self.expand_args(args[0])
-        return buffer[len(buffer)-count:]
-    prefixes = ["さん", "ちゃん", "君", "くん", "様", "さま", "氏", "先生"]
+        return buffer[len(buffer) - count:]
+
+    prefixes = ['さん', 'ちゃん', '君', 'くん', '様', 'さま', '氏', '先生']
+
     def exec_adjustprefix(self, args):
         if len(args) != 2:
-            return ""
+            return ''
         s = self.expand_args(args[0])
         for prefix in self.prefixes:
             prefix = unicode(prefix, 'utf-8')
-            n = len(prefix)
-            if s[-n:] == prefix:
-                s = s[:-n] + self.expand_args(args[1])
+            if s.endswith(prefix):
+                s = ''.join((s[:-len(prefix)], self.expand_args(args[1])))
                 break
         return s
+
     def exec_count(self, args):
         if len(args) != 1:
-            return ""
+            return ''
         name = self.expand_args(args[0])
         try:
             type, value = self.variable[name]
             if type == TYPE_SCHOLAR:
-                return "1"
+                return '1'
             return str(len(value))
         except KeyError:
-            return "-1"
+            return '-1'
+
     def exec_inlastsentence(self, args):
-        if len(args) == 0:
-            return ""
+        if not args:
+            return ''
         s = self.communicate[1]
         for i in range(1, len(args)):
             if s.find(self.expand_args(args[i])) < 0:
-                return "false"
-        return "true"
+                return 'false'
+        return 'true'
+
     def saori(self, args):
         saori_statuscode = ''
         saori_header = []
@@ -1914,13 +2044,17 @@ class Shiori:
               'SecurityLevel: local\r\n' \
               'Charset: %s\r\n' % self.charset
         for i in range(1, len(args)):
-              req += 'Argument%s: %s\r\n' % (i, self.expand_args(args[i]).encode(self.charset, 'ignore'))
-        req += '\r\n'
+            req = ''.join(
+                (req,
+                 'Argument%s: %s\r\n' % \
+                 (i,
+                  self.expand_args(args[i]).encode(self.charset, 'ignore'))))
+        req = ''.join((req, '\r\n'))
         response = self.saori_library.request(self.expand_args(args[0]), req)
         header = StringIO.StringIO(response)
         line = header.readline()
         if line:
-            if line[-1] == '\n':
+            if line.endswith('\n'):
                 line = line[:-1]
             line = line.strip()
             pos_space = line.find(' ')
@@ -1931,7 +2065,7 @@ class Shiori:
                 line = header.readline()
                 if not line:
                     break # EOF
-                if line[-1] == '\n':
+                if line.endswith('\n'):
                     line = line[:-1]
                 line = line.strip()
                 if not line:
@@ -1939,7 +2073,7 @@ class Shiori:
                 colon = line.find(':')
                 if colon >= 0:
                     key = line[:colon].strip()
-                    value = line[colon+1:].strip()
+                    value = line[colon + 1:].strip()
                     if key:
                         saori_header.append(key)
                         saori_value[key] = value
@@ -1947,74 +2081,82 @@ class Shiori:
             return saori_value['Result']
         else:
             return ''
+
     def load_saori(self, args):
-        if len(args) == 0:
+        if not args:
             return ''
         else:
-            result = self.saori_library.load(self.expand_args(args[0]), self.misaka_dir)
+            result = self.saori_library.load(self.expand_args(args[0]),
+                                             self.misaka_dir)
             if not result:
                 result = ''
             return str(result)
+
     def unload_saori(self, args):
-        if len(args) == 0:
+        if not args:
             return ''
         else:
             result = self.saori_library.unload(self.expand_args(args[0]))
             if not result:
                 result = ''
             return str(result)
+
     def exec_isghostexists(self, args):
-        result = "false"
+        result = 'false'
         if len(args) != 1:
             if len(self.otherghost):
-                result = "true"
-                self.variable["$to"] = (TYPE_SCHOLAR, random.choice(self.otherghost)[0])
+                result = 'true'
+                self.variable['$to'] = (TYPE_SCHOLAR,
+                                        random.choice(self.otherghost)[0])
         else:
             for ghost in self.otherghost:
                 if ghost[0] == self.expand_args(args[0]):
-                    result = "true"
+                    result = 'true'
                     break
         return result
+
     SYSTEM_FUNCTIONS = {
-        "$reference":           exec_reference,
-        "$random":              exec_random,
-        "$choice":              exec_choice,
-        "$getvalue":            exec_getvalue,
-        "$inlastsentence":      exec_inlastsentence,
-        "$isghostexists":       exec_isghostexists,
-        "$search":              exec_search,
-        "$backup":              exec_backup,
-        "$getmousemovecount":   exec_getmousemovecount,
-        "$resetmousemovecount": exec_resetmousemovecount,
-        "$substring":           exec_substring,
-        "$substringl":          exec_substringl,
-        "$substringr":          exec_substringr,
-        "$substringfirst":      exec_substringfirst,
-        "$substringlast":       exec_substringlast,
-        "$length":              exec_length,
-        "$hiraganacase":        exec_hiraganacase,
-        "$isequallastandfirst": exec_isequallastandfirst,
-        "$append":              exec_append,
-        "$stringexists":        exec_stringexists,
-        "$copy":                exec_copy,
-        "$pop":                 exec_pop,
-        "$popmatchl":           exec_popmatchl,
-        "$index":               exec_index,
-        "$insentece":           exec_insentence,
-        "$substringw":          exec_substringw,
-        "$substringwl":         exec_substringwl,
-        "$substringwr":         exec_substringwr,
-        "$adjustprefix":        exec_adjustprefix,
-        "$count":               exec_count,
-        "$saori":               saori,
-        "$loadsaori":           load_saori,
-        "$unloadsaori":         unload_saori,
+        '$reference':           exec_reference,
+        '$random':              exec_random,
+        '$choice':              exec_choice,
+        '$getvalue':            exec_getvalue,
+        '$inlastsentence':      exec_inlastsentence,
+        '$isghostexists':       exec_isghostexists,
+        '$search':              exec_search,
+        '$backup':              exec_backup,
+        '$getmousemovecount':   exec_getmousemovecount,
+        '$resetmousemovecount': exec_resetmousemovecount,
+        '$substring':           exec_substring,
+        '$substringl':          exec_substringl,
+        '$substringr':          exec_substringr,
+        '$substringfirst':      exec_substringfirst,
+        '$substringlast':       exec_substringlast,
+        '$length':              exec_length,
+        '$hiraganacase':        exec_hiraganacase,
+        '$isequallastandfirst': exec_isequallastandfirst,
+        '$append':              exec_append,
+        '$stringexists':        exec_stringexists,
+        '$copy':                exec_copy,
+        '$pop':                 exec_pop,
+        '$popmatchl':           exec_popmatchl,
+        '$index':               exec_index,
+        '$insentece':           exec_insentence,
+        '$substringw':          exec_substringw,
+        '$substringwl':         exec_substringwl,
+        '$substringwr':         exec_substringwr,
+        '$adjustprefix':        exec_adjustprefix,
+        '$count':               exec_count,
+        '$saori':               saori,
+        '$loadsaori':           load_saori,
+        '$unloadsaori':         unload_saori,
         }
 
 class SaoriLibrary:
+
     def __init__(self, saori, dir):
         self.saori_list = {}
         self.saori = saori
+
     def load(self, name, dir):
         result = 0
         if not self.saori_list.has_key(name):
@@ -2024,6 +2166,7 @@ class SaoriLibrary:
         if self.saori_list.has_key(name):
             result = self.saori_list[name].load(dir)
         return result
+
     def unload(self, name=None):
         if name:
             if self.saori_list.has_key(name):
@@ -2033,12 +2176,14 @@ class SaoriLibrary:
             for key in self.saori_list.keys():
                 self.saori_list[key].unload()
         return None
+
     def request(self, name, req):
         result = '' # FIXME
         if name and self.saori_list.has_key(name):
             result = self.saori_list[name].request(req)
         return result
 
+
 def open(dir, debug=0):
     misaka = Shiori(dir, debug)
     misaka.load()
@@ -2048,38 +2193,38 @@ def open(dir, debug=0):
 
 def test_ini(dirlist):
     for dir in dirlist:
-        print "Reading", os.path.join(dir, "misaka.ini"), "..."
+        print 'Reading', os.path.join(dir, 'misaka.ini'), '...'
         filelist, debug, error = read_misaka_ini(dir, 4)
-        print "number of dictionaries =", len(filelist)
+        print 'number of dictionaries =', len(filelist)
         for filename in filelist:
             print filename
-        print "debug =", debug
-        print "error =", error
+        print 'debug =', debug
+        print 'error =', error
 
 def test_lexer(filelist):
     lexer = Lexer(debug=1)
     for filename in filelist:
-        print "Reading", filename, "..."
+        print 'Reading', filename, '...'
         lexer.read(builtin_open(filename))
     token_names = {
-        TOKEN_WHITESPACE:    "TOKEN_WHITESPACE",
-        TOKEN_NEWLINE:       "TOKEN_NEWLINE",
-        TOKEN_OPEN_BRACE:    "TOKEN_OPEN_BRACE",
-        TOKEN_CLOSE_BRACE:   "TOKEN_CLOSE_BRACE",
-        TOKEN_OPEN_PAREN:    "TOKEN_OPEN_PAREN",
-        TOKEN_CLOSE_PAREN:   "TOKEN_CLOSE_PAREN",
-        TOKEN_OPEN_BRACKET:  "TOKEN_OPEN_BRACKET",
-        TOKEN_CLOSE_BRACKET: "TOKEN_CLOSE_BRACKET",
-        TOKEN_DOLLAR:        "TOKEN_DOLLAR",
-        TOKEN_QUOTE:         "TOKEN_QUOTE",
-        TOKEN_COMMA:         "TOKEN_COMMA",
-        TOKEN_SEMICOLON:     "TOKEN_SEMICOLON",
-        TOKEN_OPERATOR:      "TOKEN_OPERATOR",
-        TOKEN_DIRECTIVE:     "TOKEN_DIRECTIVE",
-        TOKEN_TEXT:          "TOKEN_TEXT",
+        TOKEN_WHITESPACE:    'TOKEN_WHITESPACE',
+        TOKEN_NEWLINE:       'TOKEN_NEWLINE',
+        TOKEN_OPEN_BRACE:    'TOKEN_OPEN_BRACE',
+        TOKEN_CLOSE_BRACE:   'TOKEN_CLOSE_BRACE',
+        TOKEN_OPEN_PAREN:    'TOKEN_OPEN_PAREN',
+        TOKEN_CLOSE_PAREN:   'TOKEN_CLOSE_PAREN',
+        TOKEN_OPEN_BRACKET:  'TOKEN_OPEN_BRACKET',
+        TOKEN_CLOSE_BRACKET: 'TOKEN_CLOSE_BRACKET',
+        TOKEN_DOLLAR:        'TOKEN_DOLLAR',
+        TOKEN_QUOTE:         'TOKEN_QUOTE',
+        TOKEN_COMMA:         'TOKEN_COMMA',
+        TOKEN_SEMICOLON:     'TOKEN_SEMICOLON',
+        TOKEN_OPERATOR:      'TOKEN_OPERATOR',
+        TOKEN_DIRECTIVE:     'TOKEN_DIRECTIVE',
+        TOKEN_TEXT:          'TOKEN_TEXT',
         }
     for token, lexeme, position in lexer.buffer:
-        print "L%d : C%-3d :" % position, token_names[token], ":",
+        print 'L%d : C%-3d :' % position, token_names[token], ':',
         if token in [TOKEN_WHITESPACE, TOKEN_NEWLINE,
                      TOKEN_OPEN_BRACE, TOKEN_CLOSE_BRACE,
                      TOKEN_OPEN_PAREN, TOKEN_CLOSE_PAREN,
@@ -2092,24 +2237,24 @@ def test_lexer(filelist):
 
 def test_parser(filelist):
     for filename in filelist:
-        print "Reading", filename, "..."
+        print 'Reading', filename, '...'
         parser = Parser(debug=1)
         parser.read(builtin_open(filename))
         common, dict = parser.get_dict()
         if common is not None:
-            print "Common"
+            print 'Common'
             parser.dump_node(common, depth=2)
         for name, parameters, sentences in dict:
-            print "Group", name.encode('UTF-8', 'ignore')
+            print 'Group', name.encode('UTF-8', 'ignore')
             if parameters:
-                print "Parameter:"
+                print 'Parameter:'
                 for parameter in parameters:
-                    print ">>>", parameter
+                    print '>>>', parameter
                     parser.dump_node(parameter, depth=2)
             if sentences:
-                print "Sentence:"
+                print 'Sentence:'
                 for sentence in sentences:
-                    print ">>>", sentence
+                    print '>>>', sentence
                     parser.dump_list(sentence, depth=2)
 
 def test_interpreter(dir):
@@ -2118,36 +2263,36 @@ def test_interpreter(dir):
     misaka.load()
     while 1:
         try:
-            line = raw_input(">>> ")
+            line = raw_input('>>> ')
         except KeyboardInterrupt:
-            print "Break"
+            print 'Break'
             continue
         except EOFError:
             print
             break
         command = line.split()
-        if len(command) == 0:
+        if not command:
             continue
-        elif len(command) == 1 and command[0][0] == "$":
+        elif len(command) == 1 and command[0].startswith('$'):
             print misaka.eval_variable([[NODE_TEXT, command[0]]])
-        elif len(command) == 1 and command[0] == "reload":
+        elif len(command) == 1 and command[0] == 'reload':
             misaka.load()
         else:
-            print "list of commands:"
-            print "  $id     get variable value"
-            print "  reload  reload dictionaries"
+            print 'list of commands:'
+            print '  $id     get variable value'
+            print '  reload  reload dictionaries'
 
-if __name__ == "__main__":
-    USAGE= "Usage: misaka.py [ini|lexer|parser|interp] ..."
+if __name__ == '__main__':
+    USAGE= 'Usage: misaka.py [ini|lexer|parser|interp] ...'
     if len(sys.argv) == 1:
         print USAGE
-    elif sys.argv[1] == "ini":
+    elif sys.argv[1] == 'ini':
         test_ini(sys.argv[2:])
-    elif sys.argv[1] == "lexer":
+    elif sys.argv[1] == 'lexer':
         test_lexer(sys.argv[2:])
-    elif sys.argv[1] == "parser":
+    elif sys.argv[1] == 'parser':
         test_parser(sys.argv[2:])
-    elif sys.argv[1] == "interp":
+    elif sys.argv[1] == 'interp':
         test_interpreter(sys.argv[2])
     else:
         print USAGE
index c15b4f3..d4858b9 100644 (file)
@@ -3,7 +3,7 @@
 #  niseshiori.py - a "偽栞" compatible Shiori module for ninix
 #  Copyright (C) 2001, 2002 by Tamito KAJIYAMA
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
-#  Copyright (C) 2002-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #  Copyright (C) 2003 by Shun-ichi TAHARA <jado@flowernet.gr.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
@@ -13,7 +13,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: niseshiori.py,v 1.22 2005/07/29 08:25:59 shy Exp $
+# $Id: niseshiori.py,v 1.23 2005/08/09 00:41:52 shy Exp $
 #
 
 import random
@@ -21,9 +21,7 @@ import time
 import sys
 import os
 import re
-import string
 import StringIO
-from types import *
 
 import codecs
 
@@ -32,7 +30,7 @@ try:
 except ImportError:
     _niseshiori = None
 
-REVISION = "$Revision: 1.22 $"
+REVISION = '$Revision: 1.23 $'
 
 builtin_open = open
 
@@ -42,13 +40,15 @@ def list_dict(dir):
         filelist = os.listdir(dir)
     except OSError:
         filelist = []
-    re_dict_filename = re.compile(r"^ai.*\.(dtx|txt)$")
+    re_dict_filename = re.compile(r'^ai.*\.(dtx|txt)$')
     for file in filelist:
         if re_dict_filename.match(file):
             buffer.append(os.path.join(dir, file))
     return buffer
 
+
 class NiseShiori:
+
     def __init__(self, debug=0):
         self.debug = debug
         self.dict = {}
@@ -62,7 +62,7 @@ class NiseShiori:
         self.variables = {}
         self.dbpath = None
         self.expr_parser = ExprParser()
-        self.username = ""
+        self.username = ''
         self.ai_talk_interval = 180
         self.ai_talk_count = 0
         self.surf0 = 0
@@ -77,6 +77,7 @@ class NiseShiori:
         self.otherghost = []
         self.to = ''
         self.sender = ''
+
     def load(self, dir):
         # read dictionaries
         dictlist = list_dict(dir)
@@ -85,9 +86,10 @@ class NiseShiori:
         for path in dictlist:
             self.read_dict(path)
         # read variables
-        self.dbpath = os.path.join(dir, "niseshiori.db")
+        self.dbpath = os.path.join(dir, 'niseshiori.db')
         self.load_database(self.dbpath)
         return 0
+
     def load_database(self, path):
         try:
             file = builtin_open(path)
@@ -95,52 +97,56 @@ class NiseShiori:
             return
         dict = {}
         for line in file:
-            if line[:9] == "# ns_st: ":
+            if line.startswith('# ns_st: '):
                 try:
                     self.ai_talk_interval = int(line[9:])
                 except ValueError:
                     pass
                 continue
-            elif line[:9] == "# ns_tn: ":
+            elif line.startswith('# ns_tn: '):
                 self.username = line[9:].strip()
                 continue
             try:
-                name, value = [s.strip() for s in line.split("=")]
+                name, value = [s.strip() for s in line.split('=')]
             except ValueError:
-                print "niseshiori.py: malformed database (ignored)"
+                print 'niseshiori.py: malformed database (ignored)'
                 return
             dict[name] = value
         self.variables = dict
+
     def save_database(self):
         if self.dbpath is None:
             return
         try:
-            file = builtin_open(self.dbpath, "w")
+            file = builtin_open(self.dbpath, 'w')
         except IOError:
-            print "niseshiori.py: cannot write database (ignored)"
+            print 'niseshiori.py: cannot write database (ignored)'
             return
-        file.write("# ns_st: %d\n" % self.ai_talk_interval)
-        file.write("# ns_tn: %s\n" % self.username)
+        file.write('# ns_st: %d\n' % self.ai_talk_interval)
+        file.write('# ns_tn: %s\n' % self.username)
         for name, value in self.variables.items():
-            if name[0] != "_":
-                file.write("%s=%s\n" % (name, str(value)))
+            if not name.startswith('_'):
+                file.write('%s=%s\n' % (name, str(value)))
         file.close()
+
     def finalize(self):
         pass
-    re_type = re.compile(r"\\(m[szlchtep?]|[dk])")
-    re_user = re.compile(r"\\u[a-z]")
-    re_category = re.compile(r"\\(m[szlchtep]|[dk])?\[([^\]]+)\]")
+
+    re_type = re.compile(r'\\(m[szlchtep?]|[dk])')
+    re_user = re.compile(r'\\u[a-z]')
+    re_category = re.compile(r'\\(m[szlchtep]|[dk])?\[([^\]]+)\]')
+
     def read_dict(self, path):
         # read dict file and decrypt if necessary
         file = builtin_open(path)
-        if path[-4:] == ".dtx":
+        if path.endswith('.dtx'):
             buffer = self.decrypt(file.read())
         else:
             buffer = file.readlines()
         file.close()
         # omit empty lines and comments and merge continuous lines
         definitions = []
-        decode = lambda line: unicode(line, 'Shift_JIS', "replace")
+        decode = lambda line: unicode(line, 'Shift_JIS', 'replace')
         in_comment = 0
         i, j = 0, len(buffer)
         while i < j:
@@ -148,26 +154,27 @@ class NiseShiori:
             i += 1
             if not line:
                 continue
-            elif i == 1 and line[:9] == "#Charset:":
+            elif i == 1 and line.startswith('#Charset:'):
                 charset = line[9:].strip()
-                if charset == "UTF-8":
+                if charset == 'UTF-8':
                     decode = lambda line: unicode(line, 'utf-8')
-                elif charset in ["EUC-JP", "EUC-KR"]:
+                elif charset in ['EUC-JP', 'EUC-KR']:
                     decode = lambda line: unicode(line, charset)
                 continue
-            elif line[:2] == "/*":
+            elif line.startswith('/*'):
                 in_comment = 1
                 continue
-            elif line[:2] == "*/":
+            elif line.startswith('*/'):
                 in_comment = 0
                 continue
-            elif in_comment or line[0] == "#" or line[:2] == "//":
+            elif in_comment or line.startswith('#') or line.startswith('//'):
                 continue
             lines = [line]
-            while i < j and buffer[i] and buffer[i][0] in [" ", "\t"]:
+            while i < j and buffer[i] and \
+                  (buffer[i].startswith(' ') or buffer[i].startswith('\t')):
                 lines.append(buffer[i].strip())
                 i += 1
-            definitions.append(string.join(lines, ''))
+            definitions.append(''.join(lines))
         # parse each line
         for line in definitions:
             line = decode(line)
@@ -175,7 +182,7 @@ class NiseShiori:
             match = self.re_category.match(line)
             if match:
                 line = line[match.end():].strip()
-                if not line or line[0] != ",":
+                if not line or not line.startswith(','):
                     self.syntax_error(path, line)
                     continue
                 words = [s.strip() for s in self.split(line) if s.strip()]
@@ -190,7 +197,7 @@ class NiseShiori:
                         value.extend(words)
                         self.dict[key] = value
                 if type is not None:
-                    key = "\\" + type
+                    key = ''.join(('\\', type))
                     value = self.dict.get(key, [])
                     value.extend(words)
                     self.dict[key] = value
@@ -201,7 +208,7 @@ class NiseShiori:
             except ValueError:
                 self.syntax_error(path, line)
                 continue
-            if command == r"\ch":
+            if command == r'\ch':
                 argv = [s.strip() for s in self.split(argv)]
                 if len(argv) == 5:
                     t1, w1, t2, w2, c = argv
@@ -230,8 +237,8 @@ class NiseShiori:
                     list = self.type_chains.get(t2, [])
                     list.append((c, w2))
                     self.type_chains[t2] = list
-                m1 = "%" + t1[1:]
-                m2 = "%" + t2[1:]
+                m1 = ''.join(('%', t1[1:]))
+                m2 = ''.join(('%', t2[1:]))
                 key = (m1, w1)
                 dict = self.word_chains.get(key, {})
                 list = dict.get(m2, [])
@@ -259,11 +266,11 @@ class NiseShiori:
                 value = self.dict.get(command, [])
                 value.extend(words)
                 self.dict[command] = value
-            elif command in [r"\dms", r"\e"]:
+            elif command in [r'\dms', r'\e']:
                 value = self.dict.get(command, [])
                 value.append(argv)
                 self.dict[command] = value
-            elif command == r"\ft":
+            elif command == r'\ft':
                 argv = [s.strip() for s in self.split(argv, 2)]
                 if len(argv) != 3:
                     self.syntax_error(path, line)
@@ -273,69 +280,73 @@ class NiseShiori:
                     self.syntax_error(path, line)
                     continue
                 self.keywords[(w, t)] = s
-            elif command == r"\re":
+            elif command == r'\re':
                 argv = [s.strip() for s in self.split(argv, 1)]
                 if len(argv) == 2:
                     cond = self.parse_condition(argv[0])
                     list = self.responses.get(cond, [])
                     list.append(argv[1])
                     self.responses[cond] = list
-            elif command == r"\hl":
+            elif command == r'\hl':
                 argv = [s.strip() for s in self.split(argv, 1)]
                 if len(argv) == 2:
                     list = self.greetings.get(argv[0], [])
                     list.append(argv[1])
                     self.greetings[argv[0]] = list
-            elif command == r"\ev":
+            elif command == r'\ev':
                 argv = [s.strip() for s in self.split(argv, 1)]
                 if len(argv) == 2:
                     cond = self.parse_condition(argv[0])
                     list = self.events.get(cond, [])
                     list.append(argv[1])
                     self.events[cond] = list
-            elif command == r"\id":
+            elif command == r'\id':
                 argv = [s.strip() for s in self.split(argv, 1)]
                 if len(argv) == 2:
-                    if argv[0] in ["sakura.recommendsites",
-                                   "kero.recommendsites",
-                                   "sakura.portalsites"]:
-                        list = self.resources.get(argv[0], "")
+                    if argv[0] in ['sakura.recommendsites',
+                                   'kero.recommendsites',
+                                   'sakura.portalsites']:
+                        list = self.resources.get(argv[0], '')
                        if list:
-                            list += '\2'
-                       list += argv[1].replace(' ', '\1')
+                            list = ''.join((list, '\2'))
+                       list = ''.join((list, argv[1].replace(' ', '\1')))
                         self.resources[argv[0]] = list
                     else:
                         self.resources[argv[0]] = argv[1]
-            elif command == r"\tc":
+            elif command == r'\tc':
                 pass
             else:
                 self.syntax_error(path, line)
+
     def split(self, line, maxcount=None):
         buffer = []
         count = 0
         end = pos = 0
         while maxcount is None or count < maxcount:
-            pos = line.find(",", pos)
+            pos = line.find(',', pos)
             if pos < 0:
                 break
-            elif pos > 0 and line[pos-1] == "\\":
+            elif pos > 0 and line[pos - 1] == '\\':
                 pos += 1
             else:
                 buffer.append(line[end:pos])
                 count += 1
                 end = pos = pos + 1
         buffer.append(line[end:])
-        return [s.replace("\\,", ",") for s in  buffer]
+        return [s.replace('\\,', ',') for s in  buffer]
+
     def syntax_error(self, path, line):
         if self.debug & 4:
-            print "niseshiori.py: syntax error in", os.path.basename(path)
+            print 'niseshiori.py: syntax error in', os.path.basename(path)
             print line
-    re_comp_op = re.compile("<[>=]?|>=?|=")
+
+    re_comp_op = re.compile('<[>=]?|>=?|=')
     COND_COMPARISON = 1
     COND_STRING     = 2
+
     def parse_condition(self, condition):
         buffer = []
-        for expr in [s.strip() for s in condition.split("&")]:
+        for expr in [s.strip() for s in condition.split('&')]:
             match = self.re_comp_op.search(expr)
             if match:
                 buffer.append((self.COND_COMPARISON, (
@@ -345,6 +356,7 @@ class NiseShiori:
             else:
                 buffer.append((self.COND_STRING, expr))
         return tuple(buffer)
+
     def decrypt(self, data):
         if _niseshiori is not None:
             return _niseshiori.decrypt(data)
@@ -354,9 +366,9 @@ class NiseShiori:
         j = len(data)
         line = []
         while i < j:
-            if data[i] == "@":
+            if data[i] == '@':
                 i += 1
-                buffer.append(string.join(line, ''))
+                buffer.append(''.join(line))
                 line = []
                 continue
             y = ord(data[i])
@@ -369,20 +381,24 @@ class NiseShiori:
             a += 2
             if a > 0xdd:
                 a = 0x61
-            line.append(chr((x & 0x03) | ((y & 0x03) << 2) | ((y & 0x0c) << 2) | ((x & 0x0c) << 4)))
+            line.append(chr((x & 0x03) | ((y & 0x03) << 2) | \
+                            ((y & 0x0c) << 2) | ((x & 0x0c) << 4)))
         return buffer
 
     # SHIORI/1.0 API
     def getaistringrandom(self):
-        result = self.get_event_response("OnNSRandomTalk") or self.get(r"\e")
+        result = self.get_event_response('OnNSRandomTalk') or self.get(r'\e')
         return result.encode('utf-8', 'ignore')
+
     def getaistringfromtargetword(self, word):
         word = unicode(word, 'utf-8', 'ignore')
-        return self.get(r"\e").encode('utf-8', 'ignore') # XXX
+        return self.get(r'\e').encode('utf-8', 'ignore') # XXX
+
     def getdms(self):
-        return self.get(r"\dms").encode('utf-8', 'ignore')
+        return self.get(r'\dms').encode('utf-8', 'ignore')
+
     def getword(self, type):
-        return self.get("\\" + type).encode('utf-8', 'ignore')
+        return self.get(''.join(('\\', type))).encode('utf-8', 'ignore')
 
     # SHIORI/2.4 API
     def teach(self, word):
@@ -401,38 +417,40 @@ class NiseShiori:
                            ref0=None, ref1=None, ref2=None, ref3=None,
                            ref4=None, ref5=None, ref6=None, ref7=None):
         def proc(ref):
-            if ref is not None and type(ref) not in [IntType, FloatType]:
+            if ref is not None and \
+               not isinstance(ref, int) and not isinstance(ref, float):
                 ref = unicode(ref, 'utf-8', 'ignore')
             return ref
-        ref = [proc(ref) for ref in [ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7]]
-        if event in ["OnSecondChange", "OnMinuteChange"]:
+        ref = [proc(ref) for ref in [ref0, ref1, ref2, ref3, ref4,
+                                     ref5, ref6, ref7]]
+        if event in ['OnSecondChange', 'OnMinuteChange']:
             if ref[1]:
                 self.mikire += 1
-                script = self.get_event_response("OnNSMikireHappen")
+                script = self.get_event_response('OnNSMikireHappen')
                 if script is not None:
                     return script
             elif self.mikire > 0:
                 self.mikire = 0
-                return self.get_event_response("OnNSMikireSolve")
+                return self.get_event_response('OnNSMikireSolve')
             if ref[2]:
                 self.kasanari += 1
-                script = self.get_event_response("OnNSKasanariHappen")
+                script = self.get_event_response('OnNSKasanariHappen')
                 if script is not None:
                     return script
             elif self.kasanari > 0:
                 self.kasanari = 0
-                return self.get_event_response("OnNSKasanariHappen")
-            if event == "OnSecondChange" and self.ai_talk_interval > 0:
+                return self.get_event_response('OnNSKasanariHappen')
+            if event == 'OnSecondChange' and self.ai_talk_interval > 0:
                 self.ai_talk_count += 1
                 if self.ai_talk_count == self.ai_talk_interval:
                     self.ai_talk_count = 0
-                    if len(self.otherghost) > 0 and \
+                    if self.otherghost and \
                        random.randint(0, 10) == 0:
                         target = []
                         for name, s0, s1 in self.otherghost:
                             if self.greetings.has_key(name):
                                 target.append(name)
-                        if len(target) > 0:
+                        if target:
                             self.to = random.choice(target)
                         if self.to:
                             self.current_time = time.localtime(time.time())
@@ -444,24 +462,26 @@ class NiseShiori:
                                     if not match:
                                         break
                                     value = self.eval_ns_tag(match.group())
-                                    s = s[:match.start()] + str(value) + s[match.end():]
+                                    s = ''.join((s[:match.start()],
+                                                 str(value),
+                                                 s[match.end():]))
                             return s.encode('utf-8', 'ignore')
                     return self.getaistringrandom()
             return None
-        elif event == "OnMouseMove":
+        elif event == 'OnMouseMove':
             if self.motion_area != (ref[3], ref[4]):
                 self.motion_area = (ref[3], ref[4])
                 self.motion_count = 0
             else:
                 self.motion_count += 5 # sensitivity
-        elif event == "OnSurfaceChange":
+        elif event == 'OnSurfaceChange':
             self.surf0 = ref[0]
             self.surf1 = ref[1]
-        elif event == "OnUserInput" and ref[0] == "ninix.niseshiori.username":
+        elif event == 'OnUserInput' and ref[0] == 'ninix.niseshiori.username':
             self.username = ref[1]
             self.save_database()
-            return "\e"
-        elif event == "OnCommunicate":
+            return '\e'
+        elif event == 'OnCommunicate':
             self.event = ''
             self.reference = (ref[1], )
             if ref[0] == 'user':
@@ -474,11 +494,11 @@ class NiseShiori:
                     candidate.append(cond)
             script = None
             self.to = ref[0]
-            if len(candidate) > 0:
+            if candidate:
                 cond = random.choice(candidate)
                 script = random.choice(self.responses[cond])
-            if not script and self.responses.has_key("nohit"):
-                script = random.choice(self.responses["nohit"])
+            if not script and self.responses.has_key('nohit'):
+                script = random.choice(self.responses['nohit'])
             if not script:
                 self.to = ''
             else:
@@ -488,10 +508,12 @@ class NiseShiori:
                     if not match:
                         break
                     value = self.eval_ns_tag(match.group())
-                    scipt = script[:match.start()] + str(value) + script[match.end():]
+                    scipt = ''.join((script[:match.start()],
+                                     str(value),
+                                     script[match.end():]))
             self.sender = ''
             return script.encode('utf-8', 'ignore')
-        key = "action"
+        key = 'action'
         self.dict[key] = []
         self.event = event
         self.reference = tuple(ref)
@@ -507,21 +529,25 @@ class NiseShiori:
         if script is not None:
             script = script.encode('utf-8', 'ignore')
         return script
+
     def otherghostname(self, list):
         self.otherghost = []
         for ghost in list:
             name, s0, s1 = ghost.split(chr(1))
             self.otherghost.append([unicode(name, 'utf-8', 'ignore'), s0, s1])
         return ''
+
     def communicate_to(self):
         to = self.to
         self.to = ''
         return to.encode('utf-8', 'ignore')
+
     def eval_condition(self, condition):
         for type, expr in condition:
             if not self.eval_conditional_expression(type, expr):
                 return 0
         return 1
+
     def eval_conditional_expression(self, type, expr):
         if type == NiseShiori.COND_COMPARISON:
             value1 = self.expand_meta(expr[0])
@@ -532,17 +558,17 @@ class NiseShiori:
             except ValueError:
                 op1 = str(value1)
                 op2 = str(value2)
-            if expr[1] == ">=":
+            if expr[1] == '>=':
                 return op1 >= op2
-            elif expr[1] == "<=":
+            elif expr[1] == '<=':
                 return op1 <= op2
-            elif expr[1] == ">":
+            elif expr[1] == '>':
                 return op1 > op2
-            elif expr[1] == "<":
+            elif expr[1] == '<':
                 return op1 < op2
-            elif expr[1] == "=":
+            elif expr[1] == '=':
                 return op1 == op2
-            elif expr[1] == "<>":
+            elif expr[1] == '<>':
                 return op1 != op2
         elif type == NiseShiori.COND_STRING:
             if self.event.find(expr) >= 0:
@@ -552,28 +578,30 @@ class NiseShiori:
                     return 1
             return 0
 
-    re_ns_tag = re.compile(r"\\(ns_(st(\[[0-9]+\])?|cr|hl|rf\[[^\]]+\]|ce|tc\[[^\]]+\]|tn(\[[^\]]+\])?|jp\[[^\]]+\]|rt)|set\[[^\]]+\])")
-    def get(self, key, default=""):
+    re_ns_tag = re.compile(r'\\(ns_(st(\[[0-9]+\])?|cr|hl|rf\[[^\]]+\]|ce|tc\[[^\]]+\]|tn(\[[^\]]+\])?|jp\[[^\]]+\]|rt)|set\[[^\]]+\])')
+
+    def get(self, key, default=''):
         self.current_time = time.localtime(time.time())
-        s = self.expand(key, "", default)
+        s = self.expand(key, '', default)
         if s:
             while 1:
                 match = self.re_ns_tag.search(s)
                 if not match:
                     break
                 value = self.eval_ns_tag(match.group())
-                s = s[:match.start()] + str(value) + s[match.end():]
+                s = ''.join((s[:match.start()], str(value), s[match.end():]))
         return s
+
     def eval_ns_tag(self, tag):
-        value = ""
-        if tag == r"\ns_cr":
+        value = ''
+        if tag == r'\ns_cr':
             self.ai_talk_count = 0
-        elif tag == r"\ns_ce":
+        elif tag == r'\ns_ce':
             self.to = ''
-        elif tag == r"\ns_hl":
-            if len(self.otherghost) > 0:
+        elif tag == r'\ns_hl':
+            if self.otherghost:
                 self.to = random.choice(self.otherghost)[0]
-        elif tag[:7] == r"\ns_st[" and tag[-1:] == "]":
+        elif tag.startswith(r'\ns_st[') and tag.endswith(']'):
             try:
                 num = int(tag[7:-1])
             except ValueError:
@@ -591,39 +619,41 @@ class NiseShiori:
                     self.ai_talk_interval = min(max(num, 4), 999)
                 self.save_database()
                 self.ai_talk_count = 0
-        elif tag[:7] == r"\ns_jp[" and tag[-1:] == "]":
+        elif tag.startswith(r'\ns_jp[') and tag.endswith(']'):
             name = tag[7:-1]
             self.jump_entry = name
-            value = self.get_event_response("OnNSJumpEntry") or ""
+            value = self.get_event_response('OnNSJumpEntry') or ''
             self.jump_entry = None
-        elif tag[:5] == r"\set[" and tag[-1:] == "]":
+        elif tag.startswith(r'\set[') and tag.endswith(']'):
             statement = tag[5:-1]
-            pos = statement.find("=")
+            pos = statement.find('=')
             if pos > 0:
                 name = statement[:pos].strip()
-                expr = statement[pos+1:].strip()
+                expr = statement[pos + 1:].strip()
                 value = self.eval_expression(expr)
                 if value is not None:
                     self.variables[name] = value
-                    if name[0] != "_":
+                    if not name.startswith('_'):
                         self.save_database()
                     if self.debug & 2048:
                         print 'set %s = "%s"' % (name, value)
                 elif self.debug & 1024:
-                    print "niseshiori.py: syntax error"
+                    print 'niseshiori.py: syntax error'
                     print tag
             elif self.debug & 1024:
-                print "niseshiori.py: syntax error"
+                print 'niseshiori.py: syntax error'
                 print tag
-        elif tag == r"\ns_rt":
-            value = r"\a"
-        elif tag == r"\ns_tn":
-            value = r"\![open,inputbox,ninix.niseshiori.username,-1]"
-        elif tag[:7] == r"\ns_tn[" and tag[-1:] == "]":
+        elif tag == r'\ns_rt':
+            value = r'\a'
+        elif tag == r'\ns_tn':
+            value = r'\![open,inputbox,ninix.niseshiori.username,-1]'
+        elif tag.startswith(r'\ns_tn[') and tag.endswith(']'):
             self.username = tag[7:-1]
             self.save_database()
         return value
-    re_meta = re.compile(r"%((rand([1-9]|\[[0-9]+\])|selfname2?|sakuraname|keroname|username|friendname|year|month|day|hour|minute|second|week|ghostname|sender|ref[0-7]|surf[01]|word|ns_st|get\[[^\]]+\]|jpentry|plathome|platform|move|mikire|kasanari|ver)|(dms|(m[szlchtep?]|[dk])(\[[^\]]*\])?|\[[^\]]*\]|u[a-z])([2-9]?))")
+
+    re_meta = re.compile(r'%((rand([1-9]|\[[0-9]+\])|selfname2?|sakuraname|keroname|username|friendname|year|month|day|hour|minute|second|week|ghostname|sender|ref[0-7]|surf[01]|word|ns_st|get\[[^\]]+\]|jpentry|plathome|platform|move|mikire|kasanari|ver)|(dms|(m[szlchtep?]|[dk])(\[[^\]]*\])?|\[[^\]]*\]|u[a-z])([2-9]?))')
+
     def replace_meta(self, s):
         pos = 0
         buffer = []
@@ -638,7 +668,7 @@ class NiseShiori:
             meta = match.group()
             if match.group(4) is not None: # %ms, %dms, %ua, etc.
                 if not variables.has_key(meta):
-                    chained_meta = "%" + match.group(4)
+                    chained_meta = ''.join(('%', match.group(4)))
                     for chains in variable_chains:
                         if chains.has_key(chained_meta):
                             candidates_A, candidates_B = chains[chained_meta]
@@ -651,38 +681,44 @@ class NiseShiori:
                             if not candidates_A and not candidates_B:
                                 del chains[chained_meta]
                             if self.debug & 16:
-                                print "chained: %s => %s" % (meta, word)
+                                print 'chained: %s => %s' % (meta, word)
                             break
                     else:
                         if match.group(4) == 'm?':
-                            word = self.expand("\\" + random.choice(["ms", "mz", "ml", "mc", "mh", "mt", "me", "mp"]), s)
+                            word = self.expand(
+                                ''.join(('\\',
+                                         random.choice(['ms', 'mz', 'ml',
+                                                        'mc', 'mh', 'mt',
+                                                        'me', 'mp']))), s)
                         else:
-                            word = self.expand("\\" + match.group(4), s)
+                            word = self.expand(
+                                ''.join(('\\', match.group(4))), s)
                     chains = self.find_chains((chained_meta, word), s)
                     if self.debug & 16:
-                        prefix = "chain:"
+                        prefix = 'chain:'
                         for k in chains.keys():
                             candidates_A, candidates_B = chains[k]
                             for w in candidates_A:
-                                print prefix, "%s, %s" % (k, w)
-                                prefix = "      "
+                                print prefix, '%s, %s' % (k, w)
+                                prefix = '      '
                             for w in candidates_B:
-                                print prefix, "%s, %s" % (k, w)
-                                prefix = "      "
+                                print prefix, '%s, %s' % (k, w)
+                                prefix = '      '
                     variables[meta] = word
                     variable_chains.append(chains)
                 buffer.append(variables[meta])
             else:
                 buffer.append(str(self.expand_meta(meta)))
             pos = match.end()
-        t = string.join(buffer, '')
+        t = ''.join(buffer)
         return t
-    def expand(self, key, context, default=""):
+
+    def expand(self, key, context, default=''):
         choices = []
         for keyword, word in self.type_chains.get(key, []):
             if not context.find(keyword) < 0:
                 if self.debug & 16:
-                    print "chain keyword:", keyword
+                    print 'chain keyword:', keyword
                 choices.append(word)
         if not choices:
             match = self.re_category.match(key)
@@ -691,19 +727,21 @@ class NiseShiori:
             choices = self.dict.get(key)
         if not choices:
             if self.debug & 8:
-                if type(key) == type(()):
-                    key = "(%s, %s)" % key
-                sys.stderr.write("%s not found\n" % key)
+                if isinstance(key, tuple):
+                    key = '(%s, %s)' % key
+                sys.stderr.write('%s not found\n' % key)
             return default
         s = random.choice(choices)
         t = self.replace_meta(s)
         if self.debug & 16:
-            if type(key) == type(()):
-                key = "\\%s[%s]" % (key[0] or "", key[1])
-            print key.encode('UTF-8', 'ignore'), "=>", s.encode('UTF-8', 'ignore')
-            print " " * len(key),
-            print "=>", t.encode('UTF-8', 'ignore')
+            if isinstance(key, tuple):
+                key = '\\%s[%s]' % (key[0] or '', key[1])
+            print key.encode('UTF-8', 'ignore'), '=>', \
+                  s.encode('UTF-8', 'ignore')
+            print ' ' * len(key),
+            print '=>', t.encode('UTF-8', 'ignore')
         return t
+
     def find_chains(self, key, context):
         chains = {}
         dict = self.word_chains.get(key, {})
@@ -717,150 +755,159 @@ class NiseShiori:
                     candidates_B.append(chained_word)
             chains[chained_meta] = (candidates_A, candidates_B)
         return chains
-    WEEKDAY_NAMES = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
+
+    WEEKDAY_NAMES = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
+
     def expand_meta(self, name):
-        if name in ["%selfname", "%selfname2", "%keroname", "%friendname"]:
+        if name in ['%selfname', '%selfname2', '%keroname', '%friendname']:
             return name
-        elif name == "%sakuraname":
-            return "%selfname"
-        elif name == "%username":
-            return self.username or "%username"
-        elif name[:5] == "%get[" and name[-1] == "]":
-            value = self.variables.get(name[5:-1], "?")
+        elif name == '%sakuraname':
+            return '%selfname'
+        elif name == '%username':
+            return self.username or '%username'
+        elif name.startswith('%get[') and name.endswith(']'):
+            value = self.variables.get(name[5:-1], '?')
             try:
                 return int(value)
             except ValueError:
                 return value
-        elif name[:6] == "%rand[" and name[-1] == "]":
+        elif name.startswith('%rand[') and name.endswith(']'):
             n = int(name[6:-1])
             return random.randint(1, n)
-        elif name[:5] == "%rand" and len(name) == 6:
+        elif name.startswith('%rand') and len(name) == 6:
             n = int(name[5])
-            return random.randint(10**(n-1), 10**n-1)
-        elif name[:4] == "%ref" and len(name) == 5 and name[4] in "01234567":
+            return random.randint(10**(n - 1), 10**n - 1)
+        elif name.startswith('%ref') and len(name) == 5 and \
+             name[4] in '01234567':
             if self.reference is None:
-                return ""
+                return ''
             n = int(name[4])
             if self.reference[n] is None:
-                return ""
+                return ''
             return self.reference[n]
-        elif name == "%jpentry":
+        elif name == '%jpentry':
             if self.jump_entry is None:
-                return ""
+                return ''
             return self.jump_entry
-        elif name == "%year":
+        elif name == '%year':
             return str(self.current_time[0])
-        elif name == "%month":
+        elif name == '%month':
             return str(self.current_time[1])
-        elif name == "%day":
+        elif name == '%day':
             return str(self.current_time[2])
-        elif name == "%hour":
+        elif name == '%hour':
             return str(self.current_time[3])
-        elif name == "%minute":
+        elif name == '%minute':
             return str(self.current_time[4])
-        elif name == "%second":
+        elif name == '%second':
             return str(self.current_time[5])
-        elif name == "%week":
+        elif name == '%week':
             return self.WEEKDAY_NAMES[self.current_time[6]]
-        elif name == "%ns_st":
+        elif name == '%ns_st':
             return self.ai_talk_interval
-        elif name == "%surf0":
+        elif name == '%surf0':
             return str(self.surf0)
-        elif name == "%surf1":
+        elif name == '%surf1':
             return str(self.surf1)
-        elif name in ["%plathome", "%platform"]:
-            return "ninix"
-        elif name == "%move":
+        elif name in ['%plathome', '%platform']:
+            return 'ninix'
+        elif name == '%move':
             return str(self.motion_count)
-        elif name == "%mikire":
+        elif name == '%mikire':
             return str(self.mikire)
-        elif name == "%kasanari":
+        elif name == '%kasanari':
             return str(self.kasanari)
-        elif name == "%ver":
-            if REVISION[1:11] == "Revision: ":
-                return "偽栞 for ninix (rev.%s)" % REVISION[11:-2]
+        elif name == '%ver':
+            if REVISION[1:11] == 'Revision: ':
+                return '偽栞 for ninix (rev.%s)' % REVISION[11:-2]
             else:
-                return "偽栞 for ninix"
-        elif name == "%sender":
+                return '偽栞 for ninix'
+        elif name == '%sender':
             if self.sender:
                 return self.sender
             else:
                 return ''
-        elif name == "%ghost":
+        elif name == '%ghost':
             if self.to:
                 return self.to
-            elif len(self.otherghost) > 0:
+            elif self.otherghost:
                 return random.choice(self.otherghost)[0]
             else:
                 return ''
-        return "\\" + name
+        return ''.join(('\\', name))
+
     def eval_expression(self, expr):
         tree = self.expr_parser.parse(expr)
         if tree is None:
             return None
         return self.interp_expr(tree)
+
     def interp_expr(self, tree):
         if tree[0] == ExprParser.ADD_EXPR:
             value = self.interp_expr(tree[1])
             for i in range(2, len(tree), 2):
-                operand = self.interp_expr(tree[i+1])
+                operand = self.interp_expr(tree[i + 1])
                 try:
-                    if tree[i] == "+":
+                    if tree[i] == '+':
                         value = int(value) + int(operand)
-                    elif tree[i] == "-":
+                    elif tree[i] == '-':
                         value = int(value) - int(operand)
                 except ValueError:
-                    value = str(value) + tree[i] + str(operand)
+                    value = ''.join((str(value), tree[i], str(operand)))
             return value
         elif tree[0] == ExprParser.MUL_EXPR:
             value = self.interp_expr(tree[1])
             for i in range(2, len(tree), 2):
-                operand = self.interp_expr(tree[i+1])
+                operand = self.interp_expr(tree[i + 1])
                 try:
-                    if tree[i] == "*":
+                    if tree[i] == '*':
                         value = int(value) * int(operand)
-                    elif tree[i] == "/":
+                    elif tree[i] == '/':
                         value = int(value) / int(operand)
-                    elif tree[i] == "\\":
+                    elif tree[i] == '\\':
                         value = int(value) % int(operand)
                 except (ValueError, ZeroDivisionError):
-                    value = str(value) + tree[i] + str(operand)
+                    value = ''.join((str(value), tree[i], str(operand)))
             return value
         elif tree[0] == ExprParser.UNARY_EXPR:
             operand = self.interp_expr(tree[2])
             try:
-                if tree[1] == "+":
+                if tree[1] == '+':
                     return + int(operand)
-                elif tree[1] == "-":
+                elif tree[1] == '-':
                     return - int(operand)
             except ValueError:
-                return tree[1] + str(operand)
+                return ''.join((tree[1], str(operand)))
         elif tree[0] == ExprParser.PRIMARY_EXPR:
             if self.is_number(tree[1]):
                 return int(tree[1])
-            elif tree[1][0] == "%":
+            elif tree[1].startswith('%'):
                 return self.expand_meta(tree[1])
             try:
                 return self.variables[tree[1]]
             except KeyError:
-                return "?"
+                return '?'
     def is_number(self, s):
-        return s and filter(lambda c: c in "0123456789", s) == s
+        return s and filter(lambda c: c in '0123456789', s) == s
 
 class ExprError(ValueError):
     pass
 
 class ExprParser:
+
     def __init__(self):
         self.debug = 0
         # bit 0 = trace get_expr()
-        # bit 1 = trace all "get_" functions
+        # bit 1 = trace all 'get_' functions
+
     def show_progress(self, func, buffer):
         if buffer is None:
-            print "%s() -> syntax error" % func
+            print '%s() -> syntax error' % func
         else:
-            print "%s() -> %s" % (func, buffer)
+            print '%s() -> %s' % (func, buffer)
+
     re_token = re.compile(r'[()*/\+-]|\d+|\s+')
+
     def tokenize(self, data):
         buffer = []
         end = 0
@@ -887,72 +934,83 @@ class ExprParser:
                     buffer.append(data[end:])
                 break
         return buffer
+
     def parse(self, data):
         self.tokens = self.tokenize(data)
         try:
             return self.get_expr()
         except ExprError:
             return None # syntax error
+
     # internal
     def done(self):
         return not self.tokens
+
     def pop(self):
         try:
             return self.tokens.pop(0)
         except IndexError:
             raise ExprError
+
     def look_ahead(self, index=0):
         try:
             return self.tokens[index]
         except IndexError:
             raise ExprError
+
     def match(self, s):
         if self.pop() != s:
             raise ExprError
+
     # tree node types
     ADD_EXPR     = 1
     MUL_EXPR     = 2
     UNARY_EXPR   = 3
     PRIMARY_EXPR = 4
+
     def get_expr(self):
         buffer = self.get_add_expr()
         if not self.done():
             raise ExprError
         if self.debug & 3:
-            self.show_progress("get_expr", buffer)
+            self.show_progress('get_expr', buffer)
         return buffer
+
     def get_add_expr(self):
         buffer = [self.ADD_EXPR]
         while 1:
             buffer.append(self.get_mul_expr())
-            if self.done() or self.look_ahead() not in ["+", "-"]:
+            if self.done() or self.look_ahead() not in ['+', '-']:
                 break
             buffer.append(self.pop()) # operator
         if len(buffer) == 2:
             buffer = buffer[1]
         if self.debug & 2:
-            self.show_progress("get_add_expr", buffer)
+            self.show_progress('get_add_expr', buffer)
         return buffer
+
     def get_mul_expr(self):
         buffer = [self.MUL_EXPR]
         while 1:
             buffer.append(self.get_unary_expr())
-            if self.done() or self.look_ahead() not in ["*", "/", "\\"]:
+            if self.done() or self.look_ahead() not in ['*', '/', '\\']:
                 break
             buffer.append(self.pop()) # operator
         if len(buffer) == 2:
             buffer = buffer[1]
         if self.debug & 2:
-            self.show_progress("get_mul_expr", buffer)
+            self.show_progress('get_mul_expr', buffer)
         return buffer
+
     def get_unary_expr(self):
-        if self.look_ahead() in ["+", "-"]:
+        if self.look_ahead() in ['+', '-']:
             buffer = [self.UNARY_EXPR, self.pop(), self.get_unary_expr()]
         else:
             buffer = self.get_primary_expr()
         if self.debug & 2:
-            self.show_progress("get_unary_expr", buffer)
+            self.show_progress('get_unary_expr', buffer)
         return buffer
+
     def get_primary_expr(self):
         if self.look_ahead() == '(':
             self.match('(')
@@ -961,7 +1019,7 @@ class ExprParser:
         else:
             buffer = [self.PRIMARY_EXPR, self.pop()]
         if self.debug & 2:
-            self.show_progress("get_primary_expr", buffer)
+            self.show_progress('get_primary_expr', buffer)
         return buffer
 
 # <<< EXPRESSION SYNTAX >>>
@@ -975,25 +1033,32 @@ class ExprParser:
 # primary-expr := identifier | constant | '(' add-expr ')'
 
 class Shiori(NiseShiori):
+
     def __init__(self, dll_name, debug=0):
         NiseShiori.__init__(self, debug)
         self.dll_name = dll_name
+
     def load(self, dir):
         NiseShiori.load(self, dir)
         return 1
+
     def unload(self):
         NiseShiori.finalize(self)
+
     def find(self, dir, dll_name):
         result = 0
         if list_dict(dir):
             result = 100
         return result
+
     def show_description(self):
-        sys.stdout.write('Shiori: NiseShiori compatible module for ninix\n'
-                         '        Copyright (C) 2001, 2002 by Tamito KAJIYAMA\n'
-                         '        Copyright (C) 2002, 2003 by MATSUMURA Namihiko\n'
-                         '        Copyright (C) 2002-2004 by Shyouzou Sugitani\n'
-                         '        Copyright (C) 2003 by Shun-ichi TAHARA\n')
+        sys.stdout.write(
+            'Shiori: NiseShiori compatible module for ninix\n'
+            '        Copyright (C) 2001, 2002 by Tamito KAJIYAMA\n'
+            '        Copyright (C) 2002, 2003 by MATSUMURA Namihiko\n'
+            '        Copyright (C) 2002-2005 by Shyouzou Sugitani\n'
+            '        Copyright (C) 2003 by Shun-ichi TAHARA\n')
+
     def request(self, req_string):
         header = StringIO.StringIO(req_string)
         req_header = {}
@@ -1014,7 +1079,7 @@ class Shiori(NiseShiori):
                 colon = line.find(':')
                 if colon >= 0:
                     key = line[:colon].strip()
-                    value = line[colon+1:].strip()
+                    value = line[colon + 1:].strip()
                     try:
                         value = int(value)
                     except:
@@ -1031,16 +1096,18 @@ class Shiori(NiseShiori):
                 result = self.getdms()
             elif req_header['ID'] == 'OnAITalk':
                 result = self.getaistringrandom()
-            elif req_header['ID'] in ["\\ms", "\\mz", "\\ml", "\\mc", "\\mh", \
-                                      "\\mt", "\\me", "\\mp"]:
+            elif req_header['ID'] in ['\\ms', '\\mz', '\\ml', '\\mc', '\\mh',
+                                      '\\mt', '\\me', '\\mp']:
                 result = self.getword(req_header['ID'][1:])
-            elif req_header['ID'] == "\\m?":
-                result = self.getword(random.choice(["ms", "mz", "ml", "mc", "mh", "mt", "me", "mp"]))
+            elif req_header['ID'] == '\\m?':
+                result = self.getword(random.choice(['ms', 'mz', 'ml', 'mc',
+                                                     'mh', 'mt', 'me', 'mp']))
             elif req_header['ID'] == 'otherghostname':
                 otherghost = []
                 for n in range(128):
-                    if req_header.has_key('Reference'+str(n)):
-                        otherghost.append(req_header['Reference'+str(n)])
+                    if req_header.has_key(''.join(('Reference', str(n)))):
+                        otherghost.append(
+                            req_header[''.join(('Reference', str(n)))])
                 result = self.otherghostname(otherghost)
             elif req_header['ID'] == 'OnTeach':
                 if req_header.has_key('Reference0'):
@@ -1050,13 +1117,15 @@ class Shiori(NiseShiori):
                 if result is None:
                     ref = []
                     for n in range(8):
-                        if req_header.has_key('Reference'+str(n)):
-                            ref.append(req_header['Reference'+str(n)])
+                        if req_header.has_key(''.join(('Reference', str(n)))):
+                            ref.append(
+                                req_header[''.join(('Reference', str(n)))])
                         else:
                             ref.append(None)
                     ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7 = ref
                     result = self.get_event_response(
-                        req_header['ID'], ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7)
+                        req_header['ID'],
+                        ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7)
             if result is None:
                 result = ''
             to = self.communicate_to()
@@ -1064,10 +1133,11 @@ class Shiori(NiseShiori):
                  'Sender: Niseshiori\r\n' \
                  'Value: %s\r\n' % result
         if to is not None:
-            result = result + 'Reference0: %s\r\n' % to
-        result += '\r\n'
+            result = ''.join((result, 'Reference0: %s\r\n' % to))
+        result = ''.join((result, '\r\n'))
         return result
 
+
 def open(shiori_dir, debug=0):
     ns = NiseShiori(debug)
     ns.load(shiori_dir)
@@ -1079,9 +1149,9 @@ def test():
     else:
         dir = os.curdir
     if not list_dict(dir):
-        print "no dictionary"
+        print 'no dictionary'
         return
-    ns = open(dir, 4+8+16)
+    ns = open(dir, 4 + 8 + 16)
     dump_dict(ns)
     while 1:
         print ns.getaistringrandom()
@@ -1091,55 +1161,55 @@ def test():
             break
 
 def dump_dict(ns):
-    print "DICT"
+    print 'DICT'
     for k, v in ns.dict.items():
-        if type(k) == type(()):
-            k = "(%s, %s)" % k
+        if isinstance(key, tuple):
+            k = '(%s, %s)' % k
         print k.encode('UTF-8', 'ignore')
-        for e in v: print "\t", e.encode('UTF-8', 'ignore')
-    print "*" * 50
-    print "CHAINS"
+        for e in v: print '\t', e.encode('UTF-8', 'ignore')
+    print '*' * 50
+    print 'CHAINS'
     for t, list in ns.type_chains.items():
         print t.encode('UTF-8', 'ignore')
         for c, w in list:
-            print ("-> %s, %s" % (c, w)).encode('UTF_8', 'ignore')
+            print ('-> %s, %s' % (c, w)).encode('UTF_8', 'ignore')
     for key, dict in ns.word_chains.items():
-        print ("(%s, %s)" % key).encode('UTF-8', 'ignore')
+        print ('(%s, %s)' % key).encode('UTF-8', 'ignore')
         for t, list in dict.items():
-            prefix = "-> %s" % t.encode('UTF-8', 'ignore')
+            prefix = '-> %s' % t.encode('UTF-8', 'ignore')
             for c, w in list:
-                print prefix, ("-> %s, %s" % (c, w)).encode('UTF-8', 'ignore')
-                prefix = "   " + " " * len(t)
-    print "*" * 50
-    print "KEYWORDS"
+                print prefix, ('-> %s, %s' % (c, w)).encode('UTF-8', 'ignore')
+                prefix = ''.join(('   ', ' ' * len(t)))
+    print '*' * 50
+    print 'KEYWORDS'
     for (t, w), s in ns.keywords.items():
         print t.encode('UTF-8', 'ignore'), w.encode('UTF-8', 'ignore')
-        print "->", s.encode('UTF-8', 'ignore')
-    print "*" * 50
-    print "RESPONSES"
+        print '->', s.encode('UTF-8', 'ignore')
+    print '*' * 50
+    print 'RESPONSES'
     for k, v in ns.responses.items():
         print_condition(k)
-        print "->", v
-    print "*" * 50
-    print "GREETINGS"
+        print '->', v
+    print '*' * 50
+    print 'GREETINGS'
     for k, v in ns.greetings.items():
         print k.encode('UTF-8', 'ignore')
-        print "->", v
-    print "*" * 50
-    print "EVENTS"
+        print '->', v
+    print '*' * 50
+    print 'EVENTS'
     for k, v in ns.events.items():
         print_condition(k)
         for e in v:
-            print "->", e.encode('UTF-8', 'ignore')
+            print '->', e.encode('UTF-8', 'ignore')
     
 def print_condition(condition):
-    prefix = "Condition"
+    prefix = 'Condition'
     for type, expr in condition:
         if type == NiseShiori.COND_COMPARISON:
             print prefix, ("'%s' '%s' '%s'" % expr).encode('UTF-8', 'ignore')
         elif type == NiseShiori.COND_STRING:
             print prefix, "'%s'" % expr.encode('UTF-8', 'ignore')
-        prefix = "      and"
+        prefix = '      and'
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     test()
index d005880..c1a495e 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: ascii -*-
 #
 #  saori_cpuid.py - a saori_cpuid compatible Saori module for ninix
-#  Copyright (C) 2003, 2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2003-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
@@ -17,31 +17,34 @@ import random
 
 from ninix.dll import SAORI
 
+
 class Saori(SAORI):
-    entry = {'cpu.num': ["1", "2", "3", "5", "7", "11", "13"],
-             'cpu.vender': ["Inte1", "AM0", 'VlA'],
-             'cpu.ptype': ["Lazy"],
-             'cpu.family': ["780", "Bentium", "A+hlon"],
-             'cpu.model': ["Unknown"],
-             'cpu.stepping': ["Not Genuine"],
-             'cpu.mmx': ["Ready", "Not Ready"],
-             'cpu.sse': ["Ready", "Not Ready"],
-             'cpu.sse2': ["Ready", "Not Ready"],
-             'cpu.tdn': ["Ready", "Not Ready"],
-             'cpu.mmx+': ["Ready", "Not Ready"],
-             'cpu.tdn+': ["Ready", "Not Ready"],
-             'cpu.clock': ["0", "1000000"],
-             'cpu.clockex': ["0.001", "1.001"],
-             'mem.os': ["100", "10", "44", "50", "77", "99"],
-             'mem.phyt': ["0.1", "200000000"],
-             'mem.phya': ["0.00000001"],
-             'mem.pagt': ["1", "4"],
-             'mem.paga': ["1", "4"],
-             'mem.virt': ["0"],
-             'mem.vira': ["0"],
+
+    entry = {'cpu.num': ['1', '2', '3', '5', '7', '11', '13'],
+             'cpu.vender': ['Inte1', 'AM0', 'VlA'],
+             'cpu.ptype': ['Lazy'],
+             'cpu.family': ['780', 'Bentium', 'A+hlon'],
+             'cpu.model': ['Unknown'],
+             'cpu.stepping': ['Not Genuine'],
+             'cpu.mmx': ['Ready', 'Not Ready'],
+             'cpu.sse': ['Ready', 'Not Ready'],
+             'cpu.sse2': ['Ready', 'Not Ready'],
+             'cpu.tdn': ['Ready', 'Not Ready'],
+             'cpu.mmx+': ['Ready', 'Not Ready'],
+             'cpu.tdn+': ['Ready', 'Not Ready'],
+             'cpu.clock': ['0', '1000000'],
+             'cpu.clockex': ['0.001', '1.001'],
+             'mem.os': ['100', '10', '44', '50', '77', '99'],
+             'mem.phyt': ['0.1', '200000000'],
+             'mem.phya': ['0.00000001'],
+             'mem.pagt': ['1', '4'],
+             'mem.paga': ['1', '4'],
+             'mem.virt': ['0'],
+             'mem.vira': ['0'],
             }
+
     def execute(self, argument):
-        if len(argument) == 0:
+        if not argument:
             return 'SAORI/1.0 400 Bad Request\r\n\r\n'
         if len(argument) > 1 and argument[1] == 0:
             return 'SAORI/1.0 204 No Content\r\n\r\n'
index 9943466..f127a75 100644 (file)
@@ -3,7 +3,7 @@
 #  satori.py - a "Τ¡¹" compatible Shiori module for ninix
 #  Copyright (C) 2002 by Tamito KAJIYAMA
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
-#  Copyright (C) 2002-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #  Copyright (C) 2003, 2004 by Shun-ichi TAHARA <jado@flowernet.gr.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
@@ -13,7 +13,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: satori.py,v 1.56 2005/07/29 08:25:59 shy Exp $
+# $Id: satori.py,v 1.57 2005/08/09 00:41:52 shy Exp $
 #
 
 # TODO:
@@ -28,7 +28,6 @@
 # - ¥Þ¥ë¥Á¥­¥ã¥é¥¯¥¿
 
 import os
-import string
 import sys
 import re
 import time
@@ -61,7 +60,7 @@ def encrypt(s):
     for n in range(p):
         buffer.append(s[n])
         if len(s[p:]) > n:
-            buffer.append(s[-n-1])
+            buffer.append(s[-n - 1])
     return buffer
 
 def decrypt(s):
@@ -84,28 +83,33 @@ def list_dict(dir):
     except OSError:
         list = []
     for filename in list:
-        if filename[:3] == "dic" and filename[-4:] in [".txt", ".sat"] or \
-           filename in ["replace.txt", "replace_after.txt",
-                        "satori_conf.txt", "satori_conf.sat"]:
+        if filename.startswith('dic') and \
+           (filename.endswith('.txt') or filename.endswith('.sat')) or \
+           filename in ['replace.txt', 'replace_after.txt',
+                        'satori_conf.txt', 'satori_conf.sat']:
             buffer.append(os.path.join(dir, filename))
     return buffer
 
+
 class Filter:
+
     def __init__(self, rules):
         self.rules = []
         for pat, rep in rules:
             self.rules.append((self._split(pat), self._split(rep)))
+
     def _split(self, text):
         buffer = []
         i, j = 0, len(text)
         while i < j:
-            if text[i] < "\x80":
+            if text[i] < '\x80':
                 buffer.append(text[i])
                 i += 1
             else:
-                buffer.append(text[i:i+2])
+                buffer.append(text[i:i + 2])
                 i += 2
         return buffer
+
     # an implementation of the Boyer-Moore text searching algorithm
     def _find(self, text, pat, start=None, end=None):
         if start is None:
@@ -136,20 +140,23 @@ class Filter:
                 return i + 1
             k += skip.get(text[k], m)
         return -1
+
     def _replace(self, text, pat, rep):
         start = 0
         while start < len(text):
             pos = self._find(text, pat, start)
             if pos < 0:
                 break
-            text[pos:pos+len(pat)] = rep
+            text[pos:pos + len(pat)] = rep
             start = pos + len(rep)
         return text
+
     def apply(self, text):
         text = self._split(text)
         for pat, rep in self.rules:
             text = self._replace(text, pat, rep)
-        return string.join(text, "")
+        return ''.join(text)
+
 
 ###   PARSER   ###
 
@@ -159,29 +166,32 @@ def read_tab_file(path, encrypted=0, debug=0):
     buffer = []
     for line in file:
         lineno += 1
-        if line[-2:] == "\r\n":
+        if line.endswith('\r\n'):
             line = line[:-2]
-        elif line[-1] in "\r\n":
+        elif line.endswith('\r') or line.endswith('\n'):
             line = line[:-1]
         if encrypted:
-            line = string.join(decrypt(decrypt(line)), "")
+            line = ''.join(decrypt(decrypt(line)))
         try:
             line = unicode(line, 'Shift_JIS').encode('EUC-JP')
         except UnicodeError, e:
             if debug & 4:
-                print "satori.py: %s in %s (line %d)" % (e, path, lineno)
+                print 'satori.py: %s in %s (line %d)' % (e, path, lineno)
             continue
         try:
-            old, new = line.split("\t")
+            old, new = line.split('\t')
         except ValueError:
             if debug & 4:
-                print "satori.py: invalid line in %s (line %d)" % (path, lineno)
+                print 'satori.py: invalid line in %s (line %d)' % \
+                      (path, lineno)
             continue
         buffer.append((old, new))
     file.close()
     return buffer
 
+
 class Parser:
+
     def __init__(self, debug=0):
         self.debug = debug
         self.talk = {}
@@ -204,24 +214,29 @@ class Parser:
                       'Parenthesis': 0,
                       'Parentheres': 0, ## XXX
                       'Line':        0,}
+
     def set_saori(self, list):
         self.saori = list
+
     def get_count(self, name):
         if self.count.has_key(name):
             return self.count[name]
         else:
             return 0
+
     def load_replace_file(self, path):
         self.replace_filter = Filter(read_tab_file(path, debug=self.debug))
+
     def get_dict(self):
         return self.talk, self.word
+
     def read(self, path):
-        if path[-4:] == ".sat":
+        if path.endswith('.sat'):
             encrypted = 1
         else:
             encrypted = 0
         filename = os.path.basename(path)
-        if filename[:9] == "dicanchor":
+        if filename.startswith('dicanchor'):
             self.is_anchor = 1
         else:
             self.is_anchor = 0
@@ -230,38 +245,40 @@ class Parser:
         file.close()
         if self.is_anchor:
             self.anchor_filter = Filter(self.anchor_list)
+
     def read_file(self, file, path=None, encrypted=0):
         lineno = 0
         linelist = None
         for line in file:
             lineno += 1
-            if line[-2:] == "\r\n":
+            if line.endswith('\r\n'):
                 line = line[:-2]
-            elif line[-1] in "\r\n":
+            elif line.endswith('\r') or line.endswith('\n'):
                 line = line[:-1]
             if encrypted:
-                line = string.join(decrypt(decrypt(line)), "")
+                line = ''.join(decrypt(decrypt(line)))
             try:
                 line = unicode(line, 'Shift_JIS').encode('EUC-JP')
             except UnicodeError, e:
                 if self.debug & 4:
                     if path is None:
-                        print "satori.py: %s (line %d)" % (e, lineno)
+                        print 'satori.py: %s (line %d)' % (e, lineno)
                     else:
-                        print "satori.py: %s in %s (line %d)" % (e, path, lineno)
+                        print 'satori.py: %s in %s (line %d)' % \
+                              (e, path, lineno)
                 continue
-            if line[:2] == "¡ô":
+            if line.startswith('¡ô'):
                 continue
             ### FIXME: ¦Õ¦Õ¦Õ...¦Õ¡ô
-            pos = line.find("¡ô")
+            pos = line.find('¡ô')
             if pos > 0:
                 line = line[:pos]
-            if line[:2] == "¡ö":
+            if line.startswith('¡ö'):
                 if linelist:
                     parser(linelist)
                 parser = self.parse_talk
                 linelist = [lineno, line]
-            elif line[:2] == "¡÷":
+            elif line.startswith('¡÷'):
                 if linelist:
                     parser(linelist)
                 parser = self.parse_word_group
@@ -278,7 +295,7 @@ class Parser:
         for key in self.talk.keys():
             number = len(self.talk[key])
             talk += number
-            if key[:2] == 'On':
+            if key.startswith('On'):
                 eventtalk += number
         self.count['Talk'] = talk
         self.count['EventTalk'] = eventtalk
@@ -294,58 +311,61 @@ class Parser:
         self.count['Word'] = word
         self.count['Anchor'] = len(self.anchor_list)
         self.count['Variable'] = len(self.variable)
-        self.count['Parenthesis'] = self.count['Parentheres'] = self.parenthesis
+        self.count['Parenthesis'] = self.parenthesis
+        self.count['Parentheres'] = self.parenthesis
+
     def split(self, line):
         i, j = 0, len(line)
         buffer = []
         while i < j:
-            if line[i] < "\x80":
+            if line[i] < '\x80':
                 buffer.append(line[i])
                 i += 1
             else:
-                buffer.append(line[i:i+2])
+                buffer.append(line[i:i + 2])
                 i += 2
         return buffer
+
     def parse_talk(self, linelist):
         lineno = linelist[0]
         buffer = []
         line = linelist[1]
-        assert line[:2] == "¡ö"
+        assert line.startswith('¡ö')
         name = line[2:]
         while len(linelist) > 3 and not linelist[-1]:
             del linelist[-1]
-        prev = ""
+        prev = ''
         open = 0
         close = 0
         for n in range(2, len(linelist)):
             line = self.split(linelist[n])
-            open += line.count("¡Ê")
-            close += line.count("¡Ë")
+            open += line.count('¡Ê')
+            close += line.count('¡Ë')
             if open > 0 and open != close:
                 if n == len(linelist) - 1:
                     if self.debug & 4:
-                        print "satori.py: syntax error (unbalanced parens)"
+                        print 'satori.py: syntax error (unbalanced parens)'
                 else:
-                    prev += linelist[n]
+                    prev = ''.join((prev, linelist[n]))
                     continue 
             else:
                 open = 0
                 close = 0
-            line = self.split(prev + linelist[n])
-            prev = ""
-            if line and line[0] == "¡ð":
+            line = self.split(''.join((prev, linelist[n])))
+            prev = ''
+            if line and line[0] == '¡ð':
                 node = self.parse_assignment(line)
                 if node is not None:
                     buffer.append(node)
-            elif line and line[0] == "¡ä":
+            elif line and line[0] == '¡ä':
                 node = self.parse_jump(line)
                 if node is not None:
                     buffer.append(node)
-            elif line and line[0] == "¢ä":
+            elif line and line[0] == '¢ä':
                 node = self.parse_search(line)
                 if node is not None:
                     buffer.append(node)
-            elif line and line[0] == "¡²":
+            elif line and line[0] == '¡²':
                 node = self.parse_choice(line)
                 if node is not None:
                     buffer.append(node)
@@ -360,32 +380,34 @@ class Parser:
                 list = self.talk[name] = []
             list.append(buffer)
             if self.is_anchor:
-                self.anchor_list.append([name, "\\_a[%s]%s\\_a" % (name, name)])
+                self.anchor_list.append(
+                    [name, '\\_a[%s]%s\\_a' % (name, name)])
+
     def parse_word_group(self, linelist):
         lineno = linelist[0]
         buffer = []
         line = linelist[1]
-        assert line[:2] == "¡÷"
+        assert line.startswith('¡÷')
         name = line[2:]
-        prev = ""
+        prev = ''
         open = 0
         close = 0
         for n in range(2, len(linelist)):
             line = self.split(linelist[n])
-            open += line.count("¡Ê")
-            close += line.count("¡Ë")
+            open += line.count('¡Ê')
+            close += line.count('¡Ë')
             if open > 0 and open != close:
                 if n == len(linelist) - 1:
                     if self.debug & 4:
-                        print "satori.py: syntax error (unbalanced parens)"
+                        print 'satori.py: syntax error (unbalanced parens)'
                 else:
-                    prev += linelist[n]
+                    prev = ''.join((prev, linelist[n]))
                     continue 
             else:
                 open = 0
                 close = 0
-            line = self.split(prev + linelist[n])
-            prev = ""
+            line = self.split(''.join((prev, linelist[n])))
+            prev = ''
             if not line:
                 continue
             word = self.parse_word(line)
@@ -397,17 +419,18 @@ class Parser:
             except KeyError:
                 list = self.word[name] = []
             list.extend(buffer)
+
     def parse_assignment(self, line):
-        assert line[0] == "¡ð"
+        assert line[0] == '¡ð'
         for n in range(1, len(line)):
-            if line[n] in ["\t", " ", "¡¡", "¡á"]:
+            if line[n] in ['\t', ' ', '¡¡', '¡á']:
                 break
         else:
             if self.debug & 4:
-                print "satori.py: syntax error (expected a tab or equal)"
+                print 'satori.py: syntax error (expected a tab or equal)'
             return None
         name = self.parse_word(line[1:n])
-        if line[n] == "¡á":
+        if line[n] == '¡á':
             n += 1
         else:
             sep = line[n]
@@ -417,75 +440,81 @@ class Parser:
         if not name in self.variable:
             self.variable.append(name)
         return [NODE_ASSIGNMENT, name, value]
+
     def parse_jump(self, line):
-        assert line[0] == "¡ä"
+        assert line[0] == '¡ä'
         for n in range(1, len(line)):
-            if line[n] == "\t":
+            if line[n] == '\t':
                 break
         else:
             n = len(line)
         target = self.parse_word(line[1:n])
-        while n < len(line) and line[n] == "\t":
+        while n < len(line) and line[n] == '\t':
             n += 1
         if n < len(line):
             condition = self.parse_expression(line[n:])
         else:
             condition = None
         return [NODE_JUMP, target, condition]
+
     def parse_search(self, line):
         return [NODE_SEARCH]
+
     def parse_choice(self, line):
-        assert line[0] == "¡²"
+        assert line[0] == '¡²'
         for n in range(1, len(line)):
-            if line[n] == "\t":
+            if line[n] == '\t':
                 break
         else:
             n = len(line)
         label = self.parse_word(line[1:n])
-        while n < len(line) and line[n] == "\t":
+        while n < len(line) and line[n] == '\t':
             n += 1
         if n < len(line):
             id = self.parse_word(line[n:])
         else:
             id = None
         return [NODE_CHOICE, label, id]
+
     def parse_talk_word(self, line):
         buffer = self.parse_word(line)
-        buffer.append([NODE_TEXT, [r"\n"]])
+        buffer.append([NODE_TEXT, [r'\n']])
         return buffer
+
     def parse_word(self, line, depth=0, partial=0):
         buffer = []
         text = []
         while line:
-            if line[0] == "¡§" and depth == 0:
+            if line[0] == '¡§' and depth == 0:
                 if text:
                     buffer.append([NODE_TEXT, text])
                     text = []
                 buffer.append([NODE_SIDE, [line.pop(0)]])
-            elif line[0] == "¡Ê":
+            elif line[0] == '¡Ê':
                 self.parenthesis += 1
                 if text:
                     buffer.append([NODE_TEXT, text])
                     text = []
                 nodelist = [[NODE_TEXT, [line.pop(0)]]]
-                nodelist.extend(self.parse_word(line, depth+1))
-                if line and line[0] == "¡Ë":
+                nodelist.extend(self.parse_word(line, depth + 1))
+                if line and line[0] == '¡Ë':
                     nodelist.append([NODE_TEXT, [line.pop(0)]])
                     if nodelist[1][0] == NODE_TEXT:
-                        list = [string.join(nodelist[1][1], "")]
+                        list = [''.join(nodelist[1][1])]
                         for sep in ['\1', ',', '¡¤', '¡¢']:
                             buf = []
                             for item in list:
                                 buf.extend(item.split(sep))
                             list = buf
-                        if list[0] in ['ñ¸ì¤ÎÄɲÃ', 'sync', 'loop', 'call', 'set', 'remember']:
+                        if list[0] in ['ñ¸ì¤ÎÄɲÃ', 'sync', 'loop', 'call',
+                                       'set', 'remember']:
                             function = list[0]
-                            nodelist[1][1] = nodelist[1][1][len(function)+1:]
+                            nodelist[1][1] = nodelist[1][1][len(function) + 1:]
                             args = self.parse_argument(nodelist[1:-1])
                             buffer.append([NODE_CALL, function, args])
                         elif list[0] in self.saori:
                             function = list[0]
-                            nodelist[1][1] = nodelist[1][1][len(function)+1:]
+                            nodelist[1][1] = nodelist[1][1][len(function) + 1:]
                             args = self.parse_argument(nodelist[1:-1])
                             buffer.append([NODE_SAORI, function, args])
                         else:
@@ -496,13 +525,14 @@ class Parser:
                     buffer.extend(nodelist)
                 if partial:
                     break
-            elif line[0] == "¡Ë" and depth > 0:
+            elif line[0] == '¡Ë' and depth > 0:
                 break
             else:
                 text.append(line.pop(0))
         if text:
             buffer.append([NODE_TEXT, text])
         return buffer
+
     def parse_argument(self, nodelist):
         args = []
         buffer = []
@@ -511,7 +541,7 @@ class Parser:
                 text = []
                 for c in node[1]:
                     if c in ['\1', ',', '¡¤', '¡¢']:
-                        if len(text) > 0:
+                        if text:
                             buffer.append([NODE_TEXT, text])
                         args.append(buffer)
                         buffer = []
@@ -519,13 +549,14 @@ class Parser:
                     else:
                         text.append(c)  
                 else:
-                    if len(text) > 0:
+                    if text:
                         buffer.append([NODE_TEXT, text])
             else:
                 buffer.append(node)  
         else:
             args.append(buffer)
         return args
+
     def parse_expression(self, line):
         default = [[NODE_TEXT, line[:]]]
         try:
@@ -535,211 +566,221 @@ class Parser:
         if line:
             return default
         return buffer
+
     def get_or_expr(self, line):
         buffer = [NODE_OR_EXPR, self.get_and_expr(line)]
-        while line and line[0] in ["|", "¡Ã"]:
+        while line and line[0] in ['|', '¡Ã']:
             line.pop(0)
-            if line and line[0] in ["|", "¡Ã"]:
+            if line and line[0] in ['|', '¡Ã']:
                 line.pop(0)
             else:
-                raise ValueError, "broken OR operator"
+                raise ValueError, 'broken OR operator'
             buffer.append(self.get_and_expr(line))
         if len(buffer) == 2:
             return buffer[1]
         return [buffer]
+
     def get_and_expr(self, line):
         buffer = [NODE_AND_EXPR, self.get_comp_expr(line)]
-        while line and line[0] in ["&", "¡õ"]:
+        while line and line[0] in ['&', '¡õ']:
             line.pop(0)
-            if line and line[0] in ["&", "¡õ"]:
+            if line and line[0] in ['&', '¡õ']:
                 line.pop(0)
             else:
-                raise ValueError, "broken AND operator"
+                raise ValueError, 'broken AND operator'
             buffer.append(self.get_comp_expr(line))
         if len(buffer) == 2:
             return buffer[1]
         return [buffer]
+
     def get_comp_expr(self, line):
         buffer = self.get_add_expr(line)
-        if line and line[0] in ["<", "¡ã"]:
+        if line and line[0] in ['<', '¡ã']:
             line.pop(0)
-            op = "<"
-            if line and line[0] in ["=", "¡á"]:
+            op = '<'
+            if line and line[0] in ['=', '¡á']:
                 line.pop(0)
-                op = "<="
+                op = '<='
             return [[NODE_COMP_EXPR, buffer, op, self.get_add_expr(line)]]
-        elif line and line[0] in [">", "¡ä"]:
+        elif line and line[0] in ['>', '¡ä']:
             line.pop(0)
-            op = ">"
-            if line and line[0] in ["=", "¡á"]:
+            op = '>'
+            if line and line[0] in ['=', '¡á']:
                 line.pop(0)
-                op = ">="
+                op = '>='
             return [[NODE_COMP_EXPR, buffer, op, self.get_add_expr(line)]]
-        elif line and line[0] in ["=", "¡á"]:
+        elif line and line[0] in ['=', '¡á']:
             line.pop(0)
-            if line and line[0] in ["=", "¡á"]:
+            if line and line[0] in ['=', '¡á']:
                 line.pop(0)
             else:
-                raise ValueError, "broken EQUAL operator"
-            return [[NODE_COMP_EXPR, buffer, "==", self.get_add_expr(line)]]
-        elif line and line[0] in ["!", "¡ª"]:
+                raise ValueError, 'broken EQUAL operator'
+            return [[NODE_COMP_EXPR, buffer, '==', self.get_add_expr(line)]]
+        elif line and line[0] in ['!', '¡ª']:
             line.pop(0)
-            if line and line[0] in ["=", "¡á"]:
+            if line and line[0] in ['=', '¡á']:
                 line.pop(0)
             else:
-                raise ValueError, "broken NOT EQUAL operator"
-            return [[NODE_COMP_EXPR, buffer, "!=", self.get_add_expr(line)]]
+                raise ValueError, 'broken NOT EQUAL operator'
+            return [[NODE_COMP_EXPR, buffer, '!=', self.get_add_expr(line)]]
         return buffer
+
     def get_add_expr(self, line):
         buffer = [NODE_ADD_EXPR, self.get_mul_expr(line)]
-        while line and line[0] in ["+", "¡Ü", "-", "¡Ý"]:
-            if line[0] in ["+", "¡Ü"]:
-                buffer.append("+")
+        while line and line[0] in ['+', '¡Ü', '-', '¡Ý']:
+            if line[0] in ['+', '¡Ü']:
+                buffer.append('+')
             else:
-                buffer.append("-")
+                buffer.append('-')
             line.pop(0)
             buffer.append(self.get_mul_expr(line))
         if len(buffer) == 2:
             return buffer[1]
         return [buffer]
+
     def get_mul_expr(self, line):
         buffer = [NODE_MUL_EXPR, self.get_pow_expr(line)]
         while line and \
-              line[0] in ["*", "¡ö", "¡ß", "/", "¡¿", "¡à", "%", "¡ó"]:
-            if line[0] in ["*", "¡ö", "¡ß"]:
-                buffer.append("*")
-            elif line[0] in ["/", "¡¿", "¡à"]:
-                buffer.append("/")
+              line[0] in ['*', '¡ö', '¡ß', '/', '¡¿', '¡à', '%', '¡ó']:
+            if line[0] in ['*', '¡ö', '¡ß']:
+                buffer.append('*')
+            elif line[0] in ['/', '¡¿', '¡à']:
+                buffer.append('/')
             else:
-                buffer.append("%")
+                buffer.append('%')
             line.pop(0)
             buffer.append(self.get_pow_expr(line))
         if len(buffer) == 2:
             return buffer[1]
         return [buffer]
+
     def get_pow_expr(self, line):
         buffer = [NODE_POW_EXPR, self.get_unary_expr(line)]
-        while line and line[0] in ["^", "¡°"]:
+        while line and line[0] in ['^', '¡°']:
             line.pop(0)
             buffer.append(self.get_unary_expr(line))
         if len(buffer) == 2:
             return buffer[1]
         return [buffer]
+
     def get_unary_expr(self, line):
-        if line and line[0] in ["-", "¡Ý"]:
+        if line and line[0] in ['-', '¡Ý']:
             line.pop(0)
-            return [[NODE_UNARY_EXPR, "-", self.get_unary_expr(line)]]
-        if line and line[0] in ["!", "¡ª"]:
+            return [[NODE_UNARY_EXPR, '-', self.get_unary_expr(line)]]
+        if line and line[0] in ['!', '¡ª']:
             line.pop(0)
-            return [[NODE_UNARY_EXPR, "!", self.get_unary_expr(line)]]
-        if line and line[0] == "(":
+            return [[NODE_UNARY_EXPR, '!', self.get_unary_expr(line)]]
+        if line and line[0] == '(':
             line.pop(0)
             buffer = self.get_or_expr(line)
-            if line and line[0] == ")":
+            if line and line[0] == ')':
                 line.pop(0)
             else:
-                raise ValueError, "expected a close paren"
+                raise ValueError, 'expected a close paren'
             return buffer
         return self.get_factor(line)
+
     operators = [
-        "|", "¡Ã", "&", "¡õ", "<", "¡ã", ">", "¡ä", "=", "¡á", "!", "¡ª",
-        "+", "¡Ü", "-", "¡Ý", "*", "¡ö", "¡ß", "/", "¡¿", "¡à", "%", "¡ó",
-        "^", "¡°", "(", ")"]
+        '|', '¡Ã', '&', '¡õ', '<', '¡ã', '>', '¡ä', '=', '¡á', '!', '¡ª',
+        '+', '¡Ü', '-', '¡Ý', '*', '¡ö', '¡ß', '/', '¡¿', '¡à', '%', '¡ó',
+        '^', '¡°', '(', ')']
+
     def get_factor(self, line):
         buffer = []
         while line and line[0] not in self.operators:
-            if line and line[0] == "¡Ê":
+            if line and line[0] == '¡Ê':
                 buffer.extend(self.parse_word(line, partial=1))
                 continue
             text = []
-            while line and line[0] not in self.operators and line[0] != "¡Ê":
+            while line and line[0] not in self.operators and line[0] != '¡Ê':
                 text.append(line.pop(0))
             if text:
                 buffer.append([NODE_TEXT, text])
         if not buffer:
-            raise ValueError, "expected a constant"
+            raise ValueError, 'expected a constant'
         return buffer
+
     def print_nodelist(self, list, depth=0):
         for node in list:
-            indent = "  " * depth
+            indent = '  ' * depth
             if node[0] == NODE_TEXT:
-                print indent + 'NODE_TEXT "%s"' % string.join(node[1], "")
+                print ''.join((indent, 'NODE_TEXT "%s"' % ''.join(node[1])))
             elif node[0] == NODE_REF:
-                print indent + "NODE_REF"
-                self.print_nodelist(node[1], depth+1)
+                print ''.join((indent, 'NODE_REF'))
+                self.print_nodelist(node[1], depth + 1)
             elif node[0] == NODE_CALL:
-                print indent + "NODE_CALL"
+                print ''.join((indent, 'NODE_CALL'))
                 for i in range(len(node[2])):
-                    self.print_nodelist(node[2][i], depth+1)
+                    self.print_nodelist(node[2][i], depth + 1)
             elif node[0] == NODE_SAORI:
-                print indent + "NODE_SAORI"
+                print ''.join((indent, 'NODE_SAORI'))
                 for i in range(len(node[2])):
-                    self.print_nodelist(node[2][i], depth+1)
+                    self.print_nodelist(node[2][i], depth + 1)
             elif node[0] == NODE_SIDE:
-                print indent + "NODE_SIDE"
+                print ''.join((indent, 'NODE_SIDE'))
             elif node[0] == NODE_ASSIGNMENT:
-                print indent + "NODE_ASSIGNMENT"
-                print indent + "variable"
-                self.print_nodelist(node[1], depth+1)
-                print indent + "value"
-                self.print_nodelist(node[2], depth+1)
+                print ''.join((indent, 'NODE_ASSIGNMENT'))
+                print ''.join((indent, 'variable'))
+                self.print_nodelist(node[1], depth + 1)
+                print ''.join((indent, 'value'))
+                self.print_nodelist(node[2], depth + 1)
             elif node[0] == NODE_JUMP:
-                print indent + "NODE_JUMP"
-                print indent + "name"
-                self.print_nodelist(node[1], depth+1)
+                print ''.join((indent, 'NODE_JUMP'))
+                print ''.join((indent, 'name'))
+                self.print_nodelist(node[1], depth + 1)
                 if node[2] is not None:
-                    print indent + "condition"
-                    self.print_nodelist(node[2], depth+1)
+                    print ''.join((indent, 'condition'))
+                    self.print_nodelist(node[2], depth + 1)
             elif node[0] == NODE_SEARCH:
-                print indent + "NODE_SEARCH"
+                print ''.join((indent, 'NODE_SEARCH'))
             elif node[0] == NODE_CHOICE:
-                print indent + "NODE_CHOICE"
-                print indent + "label"
-                self.print_nodelist(node[1], depth+1)
+                print ''.join((indent, 'NODE_CHOICE'))
+                print ''.join((indent, 'label'))
+                self.print_nodelist(node[1], depth + 1)
                 if node[2] is not None:
-                    print indent + "id"
-                    self.print_nodelist(node[2], depth+1)
+                    print ''.join((indent, 'id'))
+                    self.print_nodelist(node[2], depth + 1)
             elif node[0] == NODE_OR_EXPR:
-                print indent + "NODE_OR_EXPR"
-                self.print_nodelist(node[1], depth+1)
+                print ''.join((indent, 'NODE_OR_EXPR'))
+                self.print_nodelist(node[1], depth + 1)
                 for i in range(2, len(node)):
-                    print indent + "op ||"
-                    self.print_nodelist(node[i], depth+1)
+                    print ''.join((indent, 'op ||'))
+                    self.print_nodelist(node[i], depth + 1)
             elif node[0] == NODE_AND_EXPR:
-                print indent + "NODE_ADD_EXPR"
-                self.print_nodelist(node[1], depth+1)
+                print ''.join((indent, 'NODE_ADD_EXPR'))
+                self.print_nodelist(node[1], depth + 1)
                 for i in range(2, len(node)):
-                    print indent + "op &&"
-                    self.print_nodelist(node[i], depth+1)
+                    print ''.join((indent, 'op &&'))
+                    self.print_nodelist(node[i], depth + 1)
             elif node[0] == NODE_COMP_EXPR:
-                print indent + "NODE_COMP_EXPR"
-                self.print_nodelist(node[1], depth+1)
-                print indent + "op", node[2]
-                self.print_nodelist(node[3], depth+1)
+                print ''.join((indent, 'NODE_COMP_EXPR'))
+                self.print_nodelist(node[1], depth + 1)
+                print ''.join((indent, 'op')), node[2]
+                self.print_nodelist(node[3], depth + 1)
             elif node[0] == NODE_ADD_EXPR:
-                print indent + "NODE_ADD_EXPR"
-                self.print_nodelist(node[1], depth+1)
+                print ''.join((indent, 'NODE_ADD_EXPR'))
+                self.print_nodelist(node[1], depth + 1)
                 for i in range(2, len(node), 2):
-                    print indent + "op", node[i]
-                    self.print_nodelist(node[i+1], depth+1)
+                    print ''.join((indent, 'op')), node[i]
+                    self.print_nodelist(node[i + 1], depth + 1)
             elif node[0] == NODE_MUL_EXPR:
-                print indent + "NODE_MUL_EXPR"
-                self.print_nodelist(node[1], depth+1)
+                print ''.join((indent, 'NODE_MUL_EXPR'))
+                self.print_nodelist(node[1], depth + 1)
                 for i in range(2, len(node), 2):
-                    print indent + "op", node[i]
-                    self.print_nodelist(node[i+1], depth+1)
+                    print ''.join((indent, 'op')), node[i]
+                    self.print_nodelist(node[i + 1], depth + 1)
             elif node[0] == NODE_POW_EXPR:
-                print indent + "NODE_POW_EXPR"
-                self.print_nodelist(node[1], depth+1)
+                print ''.join((indent, 'NODE_POW_EXPR'))
+                self.print_nodelist(node[1], depth + 1)
                 for i in range(2, len(node)):
-                    print indent + "op ^"
-                    self.print_nodelist(node[i], depth+1)
+                    print ''.join((indent, 'op ^'))
+                    self.print_nodelist(node[i], depth + 1)
             elif node[0] == NODE_UNARY_EXPR:
-                print indent + "NODE_UNARY_EXPR"
-                print indent + "op", node[1]
-                self.print_nodelist(node[2], depth+1)
+                print ''.join((indent, 'NODE_UNARY_EXPR'))
+                print ''.join((indent, 'op')), node[1]
+                self.print_nodelist(node[2], depth + 1)
             else:
-                raise RuntimeError, "should not reach here"
+                raise RuntimeError, 'should not reach here'
 
 # expression := or_expr
 # or_expr    := and_expr ( op_op and_expr )*
@@ -761,8 +802,10 @@ class Parser:
 ###   INTERPRETER   ###
 
 class Satori:
-    DBNAME = "satori_savedata.txt"
-    EDBNAME = "satori_savedata.sat"
+
+    DBNAME = 'satori_savedata.txt'
+    EDBNAME = 'satori_savedata.sat'
+
     def __init__(self, satori_dir=os.curdir, debug=0):
         self.satori_dir = satori_dir
         self.dbpath = os.path.join(satori_dir, self.DBNAME)
@@ -770,6 +813,7 @@ class Satori:
         self.saori_function = {}
         self.parser = Parser()
         self.reset()
+
     def reset(self):
         self.word = {}
         self.talk = {}
@@ -783,8 +827,8 @@ class Satori:
         self.current_surface = [0, 10]
         self.default_surface = [0, 10]
         self.add_to_surface = [0, 0]
-        self.newline = r"\n[half]"
-        self.newline_script = ""
+        self.newline = r'\n[half]'
+        self.newline_script = ''
         self.save_interval = 0
         self.save_timer = 0
         self.url_list = {}
@@ -802,15 +846,16 @@ class Satori:
         self.runtime = 0 # accumulative
         self.runcount = 1 # accumulative
         self.folder_change = 0
+
     def load(self):
         buffer = []
         for path in list_dict(self.satori_dir):
             filename = os.path.basename(path)
-            if filename == "replace.txt":
+            if filename == 'replace.txt':
                 self.parser.load_replace_file(path)
-            elif filename == "replace_after.txt":
+            elif filename == 'replace_after.txt':
                 self.load_replace_file(path)
-            elif filename in ["satori_conf.txt", "satori_conf.sat"]:
+            elif filename in ['satori_conf.txt', 'satori_conf.sat']:
                 self.load_config_file(path)
             else:
                 buffer.append(path)
@@ -819,18 +864,21 @@ class Satori:
         self.talk, self.word = self.parser.get_dict()
         self.load_database()
         self.time_start = time.time()
-        self.get_event_response("OnSatoriLoad")
-        self.boot_script = self.get_event_response("OnSatoriBoot")
+        self.get_event_response('OnSatoriLoad')
+        self.boot_script = self.get_event_response('OnSatoriBoot')
+
     def load_config_file(self, path):
         parser = Parser()
         parser.read(path)
         talk, word = parser.get_dict()
-        for nodelist in talk.get("½é´ü²½", []):
+        for nodelist in talk.get('½é´ü²½', []):
             self.expand(nodelist)
+
     def load_replace_file(self, path):
         self.replace_filter = Filter(read_tab_file(path, debug=self.debug))
+
     def load_database(self):
-        if  self.variable.get("¥»¡¼¥Ö¥Ç¡¼¥¿°Å¹æ²½") == "Í­¸ú":
+        if  self.variable.get('¥»¡¼¥Ö¥Ç¡¼¥¿°Å¹æ²½') == 'Í­¸ú':
             encrypted = 1
             self.dbpath = os.path.join(self.satori_dir, self.EDBNAME)
         else:
@@ -842,131 +890,139 @@ class Satori:
             database = []
         for name, value in database:
             self.assign(name, value)
+
     def save_database(self):
-        if  self.variable.get("¥»¡¼¥Ö¥Ç¡¼¥¿°Å¹æ²½") == "Í­¸ú":
+        if  self.variable.get('¥»¡¼¥Ö¥Ç¡¼¥¿°Å¹æ²½') == 'Í­¸ú':
             encrypted = 1
             self.dbpath = os.path.join(self.satori_dir, self.EDBNAME)
         else:
             encrypted = 0
             self.dbpath = os.path.join(self.satori_dir, self.DBNAME)
         try:
-            file = builtin_open(self.dbpath, "w")
+            file = builtin_open(self.dbpath, 'w')
         except IOError:
             if self.debug & 4:
-                print "satori.py: cannot write", self.dbpath
+                print 'satori.py: cannot write', self.dbpath
             return
         for name, value in self.variable.items():
-            if name in ["Á°²ó½ªÎ»»þ¥µ¡¼¥Õ¥§¥¹0", "Á°²ó½ªÎ»»þ¥µ¡¼¥Õ¥§¥¹1",
-                        "¥Ç¥Õ¥©¥ë¥È¥µ¡¼¥Õ¥§¥¹0", "¥Ç¥Õ¥©¥ë¥È¥µ¡¼¥Õ¥§¥¹1"]:
+            if name in ['Á°²ó½ªÎ»»þ¥µ¡¼¥Õ¥§¥¹0', 'Á°²ó½ªÎ»»þ¥µ¡¼¥Õ¥§¥¹1',
+                        '¥Ç¥Õ¥©¥ë¥È¥µ¡¼¥Õ¥§¥¹0', '¥Ç¥Õ¥©¥ë¥È¥µ¡¼¥Õ¥§¥¹1']:
                 continue
-            line = "%s\t%s" % (unicode(name, 'EUC-JP').encode('Shift_JIS'),
+            line = '%s\t%s' % (unicode(name, 'EUC-JP').encode('Shift_JIS'),
                                unicode(value, 'EUC-JP').encode('Shift_JIS'))
             if encrypted:
-                line = string.join(encrypt(encrypt(line)), "")
+                line = ''.join(encrypt(encrypt(line)))
             file.write(line)
-            file.write("\r\n")
+            file.write('\r\n')
         for side in [0, 1]:
-            name = "¥Ç¥Õ¥©¥ë¥È¥µ¡¼¥Õ¥§¥¹%d" % side
-            value = self.to_zenkaku("%d" % self.default_surface[side])
-            line = "%s\t%s" % (unicode(name, 'EUC-JP').encode('Shift_JIS'),
+            name = '¥Ç¥Õ¥©¥ë¥È¥µ¡¼¥Õ¥§¥¹%d' % side
+            value = self.to_zenkaku('%d' % self.default_surface[side])
+            line = '%s\t%s' % (unicode(name, 'EUC-JP').encode('Shift_JIS'),
                                unicode(value, 'EUC-JP').encode('Shift_JIS'))
             if encrypted:
-                line = string.join(encrypt(encrypt(line)), "")
+                line = ''.join(encrypt(encrypt(line)))
             file.write(line)
-            file.write("\r\n")
+            file.write('\r\n')
         for side in [0, 1]:
-            name = "Á°²ó½ªÎ»»þ¥µ¡¼¥Õ¥§¥¹%d" % side
-            value = self.to_zenkaku("%d" % self.current_surface[side])
-            line = "%s\t%s" % (unicode(name, 'EUC-JP').encode('Shift_JIS'),
+            name = 'Á°²ó½ªÎ»»þ¥µ¡¼¥Õ¥§¥¹%d' % side
+            value = self.to_zenkaku('%d' % self.current_surface[side])
+            line = '%s\t%s' % (unicode(name, 'EUC-JP').encode('Shift_JIS'),
                                unicode(value, 'EUC-JP').encode('Shift_JIS'))
             if encrypted:
-                line = string.join(encrypt(encrypt(line)), "")
+                line = ''.join(encrypt(encrypt(line)))
             file.write(line)
-            file.write("\r\n")
-        name = "µ¯Æ°²ó¿ô"
-        value = self.to_zenkaku("%d" % self.runcount)
-        line = "%s\t%s" % (unicode(name, 'EUC-JP').encode('Shift_JIS'),
+            file.write('\r\n')
+        name = 'µ¯Æ°²ó¿ô'
+        value = self.to_zenkaku('%d' % self.runcount)
+        line = '%s\t%s' % (unicode(name, 'EUC-JP').encode('Shift_JIS'),
                            unicode(value, 'EUC-JP').encode('Shift_JIS'))
         if encrypted:
-            line = string.join(encrypt(encrypt(line)), "")
+            line = ''.join(encrypt(encrypt(line)))
         file.write(line)
-        file.write("\r\n")
+        file.write('\r\n')
         for name in self.timer.keys():
             value = self.to_zenkaku(self.timer[name])
-            line = "%s\t%s" % (unicode(name, 'EUC-JP').encode('Shift_JIS'),
+            line = '%s\t%s' % (unicode(name, 'EUC-JP').encode('Shift_JIS'),
                                unicode(value, 'EUC-JP').encode('Shift_JIS'))
             if encrypted:
-                line = string.join(encrypt(encrypt(line)), "")
+                line = ''.join(encrypt(encrypt(line)))
             file.write(line)
-            file.write("\r\n")
+            file.write('\r\n')
         for name in self.reserved_talk.keys():
             value = self.to_zenkaku(self.reserved_talk[name])
-            line = "%s\t%s" % (unicode("¼¡¤«¤é" + value + "²óÌܤΥȡ¼¥¯", 'EUC-JP').encode('Shift_JIS'),
+            line = '%s\t%s' % (unicode(''.join(('¼¡¤«¤é', value, '²óÌܤΥȡ¼¥¯')), 'EUC-JP').encode('Shift_JIS'),
                                unicode(name, 'EUC-JP').encode('Shift_JIS'))
             if encrypted:
-                line = string.join(encrypt(encrypt(line)), "")
+                line = ''.join(encrypt(encrypt(line)))
             file.write(line)
-            file.write("\r\n")
+            file.write('\r\n')
         file.close()
+
     def finalize(self):
-        self.get_event_response("OnSatoriUnload")
+        self.get_event_response('OnSatoriUnload')
         accumulative_runtime = self.runtime + self.get_runtime()
-        self.assign("ñ½ãÎß·×ÉÃ", self.to_zenkaku(accumulative_runtime))
+        self.assign('ñ½ãÎß·×ÉÃ', self.to_zenkaku(accumulative_runtime))
         self.save_database()
+
     # SHIORI/1.0 API
     def getaistringrandom(self):
-        return self.get_script("")
+        return self.get_script('')
+
     def getaistringfromtargetword(self, word):
-        return ""
+        return ''
+
     def getdms(self):
-        return ""
+        return ''
+
     def getword(self, type):
-        return ""
+        return ''
+
     # SHIORI/2.2 API
     EVENT_MAP = {
-        "OnFirstBoot":         "½é²ó",
-        "OnBoot":              "µ¯Æ°",
-        "OnClose":             "½ªÎ»",
-        "OnGhostChanging":     "¾¤Î¥´¡¼¥¹¥È¤ØÊѹ¹",
-        "OnGhostChanged":      "¾¤Î¥´¡¼¥¹¥È¤«¤éÊѹ¹",
-        "OnVanishSelecting":   "¾ÃÌǻؼ¨",
-        "OnVanishCancel":      "¾ÃÌÇű²ó",
-        "OnVanishSelected":    "¾ÃÌÇ·èÄê",
-        "OnVanishButtonHold":  "¾ÃÌÇÃæÃÇ",
+        'OnFirstBoot':         '½é²ó',
+        'OnBoot':              'µ¯Æ°',
+        'OnClose':             '½ªÎ»',
+        'OnGhostChanging':     '¾¤Î¥´¡¼¥¹¥È¤ØÊѹ¹',
+        'OnGhostChanged':      '¾¤Î¥´¡¼¥¹¥È¤«¤éÊѹ¹',
+        'OnVanishSelecting':   '¾ÃÌǻؼ¨',
+        'OnVanishCancel':      '¾ÃÌÇű²ó',
+        'OnVanishSelected':    '¾ÃÌÇ·èÄê',
+        'OnVanishButtonHold':  '¾ÃÌÇÃæÃÇ',
         }
+
     def get_event_response(self, event,
                            ref0=None, ref1=None, ref2=None, ref3=None,
                            ref4=None, ref5=None, ref6=None, ref7=None):
         self.event = event
         self.reference = [ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7]
-        tail = "\e"
-        if event == "OnUpdateReady":
+        tail = '\e'
+        if event == 'OnUpdateReady':
             try:
                 ref0 = str(int(ref0) + 1)
                 self.reference[0] = ref0
             except:
                 pass
-        elif event == "OnMouseMove":
+        elif event == 'OnMouseMove':
             key = (ref3, ref4) # side, part
             count, timestamp = self.mouse_move_count.get(key, (0, 0))
             if int(time.time() - timestamp) > self.touch_timeout:
                 count = 0
             count += 1
             if count >= self.touch_threshold:
-                event = "%s%s¤Ê¤Ç¤é¤ì" % (str(ref3), str(ref4))
+                event = '%s%s¤Ê¤Ç¤é¤ì' % (str(ref3), str(ref4))
                 count = 0
             self.mouse_move_count[key] = (count, time.time())
-        elif event == "OnMouseWheel":
+        elif event == 'OnMouseWheel':
             key = (ref3, ref4) # side, part
             count, timestamp = self.mouse_wheel_count.get(key, (0, 0))
             if int(time.time() - timestamp) > 2:
                 count = 0
             count += 1
             if count >= 2:
-                event = "%s%s¤³¤í¤³¤í" % (str(ref3), str(ref4))
+                event = '%s%s¤³¤í¤³¤í' % (str(ref3), str(ref4))
                 count = 0
             self.mouse_wheel_count[key] = (count, time.time())
-        elif event == "OnSecondChange":
+        elif event == 'OnSecondChange':
             self.silent_time += 1
             if self.save_interval > 0:
                self.save_timer -= 1
@@ -986,7 +1042,7 @@ class Satori:
                         else:
                             self.reference[0] = self.to_zenkaku(0)
                         self.reference[1] = event
-                        script = self.get_script("OnTalk")
+                        script = self.get_script('OnTalk')
                         if script:
                             self.script_history.pop(0)
                             self.script_history.append(script)
@@ -1002,43 +1058,43 @@ class Satori:
                     del self.timer[name]
                     event = name[:-6]
                     break
-        elif event == "OnSurfaceChange":
+        elif event == 'OnSurfaceChange':
             self.current_surface[0] = ref0
             self.current_surface[1] = ref1
-        elif event == "OnChoiceSelect":
+        elif event == 'OnChoiceSelect':
             self.choice_id = ref0
             self.choice_label = ref1
             self.choice_number = ref2
-            if not self.talk.has_key("OnChoiceSelect"):
+            if not self.talk.has_key('OnChoiceSelect'):
                 event = ref0
-        elif event == "OnChoiceEnter":
+        elif event == 'OnChoiceEnter':
             self.choice_id = ref1
             self.choice_label = ref0
             self.choice_number = ref2
-        elif event == "OnAnchorSelect":
+        elif event == 'OnAnchorSelect':
             if self.talk.has_key(ref0):
                 event = ref0
-        elif event in ["sakura.recommendsites", "sakura.portalsites",
-                       "kero.recommendsites"]:
+        elif event in ['sakura.recommendsites', 'sakura.portalsites',
+                       'kero.recommendsites']:
             return self.get_url_list(event)
-        elif event == "OnRecommandedSiteChoice":
+        elif event == 'OnRecommandedSiteChoice':
             script = self.get_url_script(ref0, ref1)
             if script:
                 self.script_history.pop(0)
                 self.script_history.append(script)
             return script
         elif self.EVENT_MAP.has_key(event):
-            if event in ["OnBoot", "OnGhostChanged"]:
+            if event in ['OnBoot', 'OnGhostChanged']:
                 if self.boot_script:
                     script = self.boot_script
                     self.boot_script = None
                     self.script_history.pop(0)
                     self.script_history.append(script)
                     return script
-            if event in ["OnClose", "OnGhostChanging"]:
-                if event == "OnClose":
-                    tail = r"\-\e"
-                script = self.get_script("OnSatoriClose", tail=tail)
+            if event in ['OnClose', 'OnGhostChanging']:
+                if event == 'OnClose':
+                    tail = r'\-\e'
+                script = self.get_script('OnSatoriClose', tail=tail)
                 if script:
                     self.script_history.pop(0)
                     self.script_history.append(script)
@@ -1050,22 +1106,25 @@ class Satori:
             self.script_history.pop(0)
             self.script_history.append(script)
         return script
+
     # SHIORI/2.4 API
     def teach(self, word):
-        name = self.variable.get("¶µ¤ï¤ë¤³¤È")
+        name = self.variable.get('¶µ¤ï¤ë¤³¤È')
         if name is not None:
             self.variable[name] = word
-            script = self.get_script(name + "¤ò¶µ¤¨¤Æ¤â¤é¤Ã¤¿")
+            script = self.get_script(''.join((name, '¤ò¶µ¤¨¤Æ¤â¤é¤Ã¤¿')))
             self.script_history.pop(0)
             self.script_history.append(script)
             return script
         return None
+
     # SHIORI/2.5 API
     def getstring(self, name):
         word = self.word.get(name)
         if word is not None:
             return self.expand(random.choice(word))
         return None
+
     # internal
     def get_reserved_talk(self):
         reserved = None
@@ -1076,21 +1135,23 @@ class Satori:
         if reserved is not None:
             del self.reserved_talk[reserved]
         else:
-            reserved = ""
+            reserved = ''
         return reserved
-    re_reservation = re.compile("¼¡¤«¤é((£°|£±|£²|£³|£´|£µ|£¶|£·|£¸|£¹|[0-9])+)(¡Á((£°|£±|£²|£³|£´|£µ|£¶|£·|£¸|£¹|[0-9])+))?²óÌܤΥȡ¼¥¯")
+
+    re_reservation = re.compile('¼¡¤«¤é((£°|£±|£²|£³|£´|£µ|£¶|£·|£¸|£¹|[0-9])+)(¡Á((£°|£±|£²|£³|£´|£µ|£¶|£·|£¸|£¹|[0-9])+))?²óÌܤΥȡ¼¥¯')
+
     def assign(self, name, value):
-        if name[-6:] == "¥¿¥¤¥Þ":
+        if name.endswith('¥¿¥¤¥Þ'):
             if self.talk.has_key(name[:-6]):
                 self.add_timer(name, value)
-        elif name == "Á´¥¿¥¤¥Þ²ò½ü":
-            if value == "¼Â¹Ô":
+        elif name == 'Á´¥¿¥¤¥Þ²ò½ü':
+            if value == '¼Â¹Ô':
                 self.delete_all_timers()
-        elif name == "¼­½ñ¥ê¥í¡¼¥É":
-            if value == "¼Â¹Ô":
+        elif name == '¼­½ñ¥ê¥í¡¼¥É':
+            if value == '¼Â¹Ô':
                 self.reload()
-        elif name == "¼êÆ°¥»¡¼¥Ö":
-            if value == "¼Â¹Ô":
+        elif name == '¼êÆ°¥»¡¼¥Ö':
+            if value == '¼Â¹Ô':
                 self.save_database()
         elif self.re_reservation.match(name):
             if not value:
@@ -1098,7 +1159,8 @@ class Satori:
             match = self.re_reservation.match(name)
             number = self.to_integer(match.group(1))
             if match.group(4) is not None:
-                number = random.randint(number, self.to_integer(match.group(4)))
+                number = random.randint(number,
+                                        self.to_integer(match.group(4)))
             while 1:
                 for key in self.reserved_talk:
                     if self.reserved_talk[key] == number:
@@ -1107,7 +1169,7 @@ class Satori:
                 else:
                     break
             self.reserved_talk[value] = number
-        elif name ==  "¼¡¤Î¥È¡¼¥¯":
+        elif name ==  '¼¡¤Î¥È¡¼¥¯':
             if not value:
                 return None
             number = 1
@@ -1119,116 +1181,120 @@ class Satori:
                 else:
                     break
             self.reserved_talk[value] = number
-        elif name == "¥È¡¼¥¯Í½Ìó¤Î¥­¥ã¥ó¥»¥ë":
-            if value == "¡ö":
+        elif name == '¥È¡¼¥¯Í½Ìó¤Î¥­¥ã¥ó¥»¥ë':
+            if value == '¡ö':
                 self.reserved_talk = {}
             elif self.reserved_talk.has_key(value):
                 del self.reserved_talk[value]
-        elif name == "µ¯Æ°²ó¿ô":
+        elif name == 'µ¯Æ°²ó¿ô':
             self.runcount = self.to_integer(value) + 1
         elif not value:
             if self.variable.has_key(name):
                 del self.variable[name]
         else:
             self.variable[name] = value
-            if name in ["Ãý¤ê´Ö³Ö", "Ãý¤ê´Ö³Ö¸íº¹"]:
+            if name in ['Ãý¤ê´Ö³Ö', 'Ãý¤ê´Ö³Ö¸íº¹']:
                 self.reset_random_talk_interval()
-            elif name == "¶µ¤ï¤ë¤³¤È":
-                return r"\![open,teachbox]"
-            elif name == "²ñÏûþ¥µ¡¼¥Õ¥§¥¹Ìᤷ":
-                if value == "Í­¸ú":
+            elif name == '¶µ¤ï¤ë¤³¤È':
+                return r'\![open,teachbox]'
+            elif name == '²ñÏûþ¥µ¡¼¥Õ¥§¥¹Ìᤷ':
+                if value == 'Í­¸ú':
                     self.reset_surface = 1
-                elif value == "̵¸ú":
+                elif value == '̵¸ú':
                     self.reset_surface = 0
-            elif name == "¥Ç¥Õ¥©¥ë¥È¥µ¡¼¥Õ¥§¥¹0":
+            elif name == '¥Ç¥Õ¥©¥ë¥È¥µ¡¼¥Õ¥§¥¹0':
                 value = self.to_integer(value)
                 if value is not None:
                     self.default_surface[0] = value
-            elif name == "¥Ç¥Õ¥©¥ë¥È¥µ¡¼¥Õ¥§¥¹1":
+            elif name == '¥Ç¥Õ¥©¥ë¥È¥µ¡¼¥Õ¥§¥¹1':
                 value = self.to_integer(value)
                 if value is not None:
                     self.default_surface[1] = value
-            elif name == "¥µ¡¼¥Õ¥§¥¹²Ã»»ÃÍ0":
+            elif name == '¥µ¡¼¥Õ¥§¥¹²Ã»»ÃÍ0':
                 value = self.to_integer(value)
                 if value is not None:
                     self.default_surface[0] = value
                     self.add_to_surface[0] = value
-            elif name == "¥µ¡¼¥Õ¥§¥¹²Ã»»ÃÍ1":
+            elif name == '¥µ¡¼¥Õ¥§¥¹²Ã»»ÃÍ1':
                 value = self.to_integer(value)
                 if value is not None:
                     self.default_surface[1] = value
                     self.add_to_surface[1] = value
-            elif name == "ñ½ãÎß·×ÉÃ":
+            elif name == 'ñ½ãÎß·×ÉÃ':
                 self.runtime = self.to_integer(value)
-            elif name == "¤Ê¤Ç¤é¤ìÈ¿±þ²ó¿ô":
+            elif name == '¤Ê¤Ç¤é¤ìÈ¿±þ²ó¿ô':
                 self.touch_threshold = self.to_integer(value)
-            elif name == "¤Ê¤Ç¤é¤ì»ý³Éÿô":
+            elif name == '¤Ê¤Ç¤é¤ì»ý³Éÿô':
                 self.touch_timeout = self.to_integer(value)
-            elif name == "¥¹¥³¡¼¥×Àڤ괹¤¨»þ":
+            elif name == '¥¹¥³¡¼¥×Àڤ괹¤¨»þ':
                 self.newline = value
-            elif name == "¤µ¤¯¤é¥¹¥¯¥ê¥×¥È¤Ë¤è¤ë¥¹¥³¡¼¥×Àڤ괹¤¨»þ":
+            elif name == '¤µ¤¯¤é¥¹¥¯¥ê¥×¥È¤Ë¤è¤ë¥¹¥³¡¼¥×Àڤ괹¤¨»þ':
                 self.newline_script = value
-            elif name == "¼«Æ°ÁÞÆþ¥¦¥§¥¤¥È¤ÎÇÜΨ":
-                if value[-1] == '%':
+            elif name == '¼«Æ°ÁÞÆþ¥¦¥§¥¤¥È¤ÎÇÜΨ':
+                if value.endswith('%'):
                     value = value[:-1]
-                elif value[-2:] == '¡ó':
+                elif value.endswith('¡ó'):
                     value = value[:-2]
                 value = self.to_integer(value)
                 if value is not None and value >= 0 and value <= 1000:
                     self.wait_percent = value
-            elif name == "¼«Æ°¥»¡¼¥Ö´Ö³Ö":
+            elif name == '¼«Æ°¥»¡¼¥Ö´Ö³Ö':
                 self.save_interval = self.to_integer(value)
                 self.save_timer = self.save_interval
-            elif name == "¼­½ñ¥Õ¥©¥ë¥À":
+            elif name == '¼­½ñ¥Õ¥©¥ë¥À':
                 self.folder_change = 1
         return None
+
     def change_folder(self):
-        value = self.variable.get("¼­½ñ¥Õ¥©¥ë¥À")
+        value = self.variable.get('¼­½ñ¥Õ¥©¥ë¥À')
         list = value.split(',')
         self.parser = Parser()
         self.parser.set_saori(self.saori_function.keys())
         for path in list_dict(self.satori_dir):
             filename = os.path.basename(path)
-            if filename == "replace.txt":
+            if filename == 'replace.txt':
                 self.parser.load_replace_file(path)
-            elif filename == "replace_after.txt":
+            elif filename == 'replace_after.txt':
                 self.load_replace_file(path)
         buffer = []
         for dir in list:
             dict_dir = os.path.join(self.satori_dir, dir.lower())
             if not os.path.isdir(dict_dir):
                 if debug & 4:
-                    print "satori.py: cannot read", dict_dir
+                    print 'satori.py: cannot read', dict_dir
                 continue
             for path in list_dict(dict_dir):
                 filename = os.path.basename(path)
-                if filename == "replace.txt": ## XXX
+                if filename == 'replace.txt': ## XXX
                     self.parser.load_replace_file(path)
-                elif filename == "replace_after.txt": ## XXX
+                elif filename == 'replace_after.txt': ## XXX
                     self.load_replace_file(path)
-                elif filename in ["satori_conf.txt", "satori_conf.sat"]:
+                elif filename in ['satori_conf.txt', 'satori_conf.sat']:
                     pass
                 else:
                     buffer.append(path)
         for path in buffer:
             self.parser.read(path)
         self.talk, self.word = self.parser.get_dict()
+
     def reload(self):
         self.finalize()
         self.reset()
         self.load()
+
     def reset_random_talk_interval(self):
-        interval = self.get_integer("Ãý¤ê´Ö³Ö", "ignore")
+        interval = self.get_integer('Ãý¤ê´Ö³Ö', 'ignore')
         if interval is None or interval == 0:
             self.random_talk = -1
             return
-        rate = self.get_integer("Ãý¤ê´Ö³Ö¸íº¹", "ignore")
+        rate = self.get_integer('Ãý¤ê´Ö³Ö¸íº¹', 'ignore')
         if rate is None:
             rate = 0.1
         else:
             rate = min(max(rate, 1), 100) / 100.0
         diff = int(interval * rate)
         self.random_talk = random.randint(interval - diff, interval + diff)
+
     def add_timer(self, name, value):
         count = self.to_integer(value)
         if count is None or count == 0:
@@ -1236,27 +1302,30 @@ class Satori:
                 del self.timer[name]
         else:
             self.timer[name] = count
+
     def delete_all_timers(self):
         self.timer = {}
-    def get_script(self, name, head=r"\1", tail=r"\e"):
+
+    def get_script(self, name, head=r'\1', tail=r'\e'):
         if self.reset_surface:
             self.current_reset_surface = [1, 1]
         else:
             self.current_reset_surface = [0, 0]
         script = self.get(name, default=None)
-        if script is not None and script and script != "\\n":
+        if script is not None and script and script != '\\n':
             ##print 'make("%s")' % script
-            return self.make(head + script + tail)
+            return self.make(''.join((head, script, tail)))
         return None
+
     def get_url_list(self, name):
         self.url_list[name] = []
         list = self.talk.get(name)
         if list is None:
             return None
-        url_list = ""
-        for i in range(len(list)-1,-1,-1):
+        url_list = ''
+        for i in range(len(list)-1, -1, -1):
             nodelist = list[i]
-            title = ""
+            title = ''
             j = 0
             while j < len(nodelist):
                 node = nodelist[j]
@@ -1265,17 +1334,17 @@ class Satori:
                     if node[1] == ['\\n']:
                         break
                     else:
-                        title += string.join(node[1], "")
+                        title = ''.join((title, ''.join(node[1])))
                 else:
                    pass
             if not title:
                 continue
             if title == '-':
                 if url_list:
-                    url_list += chr(2)
-                url_list += title + chr(1)
+                    url_list = ''.join((url_list, chr(2)))
+                url_list = ''.join((url_list, title, chr(1)))
                 continue
-            url = ""
+            url = ''
             while j < len(nodelist):
                 node = nodelist[j]
                 j += 1
@@ -1283,12 +1352,12 @@ class Satori:
                     if node[1] == ['\\n']:
                         break
                     else:
-                        url += string.join(node[1], "")
+                        url = ''.join((url, ''.join(node[1])))
                 else:
                    pass
             if not url:
                 continue
-            bannar = ""
+            bannar = ''
             while j < len(nodelist):
                 node = nodelist[j]
                 j += 1
@@ -1296,20 +1365,21 @@ class Satori:
                     if node[1] == ['\\n']:
                         break
                     else:
-                        bannar += string.join(node[1], "")
+                        bannar = ''.join((bannar, ''.join(node[1])))
                 else:
                    pass
-            if len(nodelist[j:]) > 0:
+            if nodelist[j:]:
                 script = nodelist[j:]
             else:
                 script = None
             self.url_list[name].append([title, url, bannar, script])
             if url_list:
-                url_list += chr(2)
-            url_list += title + chr(1) + url + chr(1) + bannar
+                url_list = ''.join((url_list, chr(2)))
+            url_list = ''.join((url_list, title, chr(1), url, chr(1), bannar))
         if not url_list:
             url_list = None
         return url_list
+
     def get_url_script(self, title, url):
         script = None
         if self.reset_surface:
@@ -1321,23 +1391,25 @@ class Satori:
                 if item[0] == title and item[1] == url:
                     if item[3] is not None:
                         script = self.expand(item[3])
-                        if script is not None and script and script != "\\n":
-                            script = self.make(r"\1" + script + r"\e")
+                        if script is not None and script and script != '\\n':
+                            script = self.make(''.join((r'\1', script, r'\e')))
                             break
         return script
+
     redundant_tags = [
-        (re.compile(r"(\\[01hu])+(\\[01hu])"),   lambda m: m.group(2)),
-        (re.compile(r"(\\n)+(\\e|$)"),           lambda m: m.group(2)),
-        (re.compile(r"(\\e)+"),                  lambda m: m.group(1)),
+        (re.compile(r'(\\[01hu])+(\\[01hu])'),   lambda m: m.group(2)),
+        (re.compile(r'(\\n)+(\\e|$)'),           lambda m: m.group(2)),
+        (re.compile(r'(\\e)+'),                  lambda m: m.group(1)),
         ]
-    re_newline = re.compile(r"((\\n)*)(\\e)")
-    re_0 = re.compile(r"\\[0h]")
-    re_1 = re.compile(r"\\[1u]")
-    re_wait_after = re.compile(r"¡¢|¡£|¡¤|¡¥")
-    re_wait_before = re.compile(r"\\[01hunce]")
-    re_tag = re.compile(r"\\[ehunjcxtqzy*v0123456789fmia!&+---]|"
-                        r"\\[sb][0-9]?|\\w[0-9]|\\_[wqslvVbe+cumna]|"
-                        r"\\__[ct]|\\URL")
+    re_newline = re.compile(r'((\\n)*)(\\e)')
+    re_0 = re.compile(r'\\[0h]')
+    re_1 = re.compile(r'\\[1u]')
+    re_wait_after = re.compile(r'¡¢|¡£|¡¤|¡¥')
+    re_wait_before = re.compile(r'\\[01hunce]')
+    re_tag = re.compile(r'\\[ehunjcxtqzy*v0123456789fmia!&+---]|'
+                        r'\\[sb][0-9]?|\\w[0-9]|\\_[wqslvVbe+cumna]|'
+                        r'\\__[ct]|\\URL')
+
     def make(self, script):
         if script is None:
             return None
@@ -1355,7 +1427,7 @@ class Satori:
             else:
                 buffer.append(self.parser.anchor_filter.apply(script[i:]))
                 break
-        script = string.join(buffer, "")
+        script = ''.join(buffer)
         # apply replace_after.txt
         script = self.replace_filter.apply(script)
         # remove redundant tags
@@ -1365,10 +1437,11 @@ class Satori:
         match = self.re_newline.search(script)
         if match:
             tag = match.group(3)
-            if tag == r"\e":
-                script = script[:match.start()] + tag + script[match.end():]
+            if tag == r'\e':
+                script = ''.join((script[:match.start()],
+                                  tag, script[match.end():]))
             else:
-                raise RuntimeError, "should not reach here"
+                raise RuntimeError, 'should not reach here'
         # insert newline
         i = 1
         while 1:
@@ -1379,9 +1452,10 @@ class Satori:
                 if match:
                     start = match.start()
                     if start < len(self.newline) or \
-                       script[start-len(self.newline):start] != self.newline:
-                       script = r"%s%s%s" % (
-                        script[:match.end()], self.newline_script, script[match.end():])
+                       script[start - len(self.newline):start] != self.newline:
+                       script = r'%s%s%s' % (
+                        script[:match.end()], self.newline_script,
+                        script[match.end():])
                 else:
                     break
                 i = end
@@ -1396,9 +1470,10 @@ class Satori:
                 if match:
                     start = match.start()
                     if start < len(self.newline) or \
-                       script[start-len(self.newline):start] != self.newline:
-                       script = r"%s%s%s" % (
-                        script[:match.end()], self.newline_script, script[match.end():])
+                       script[start - len(self.newline):start] != self.newline:
+                       script = r'%s%s%s' % (
+                        script[:match.end()], self.newline_script,
+                        script[match.end():])
                 else:
                     break
                 i = end
@@ -1423,40 +1498,43 @@ class Satori:
                 n = 0
                 i = match.end()
                 continue
-            if script[i] == "[":
-                pos = script.find("]", i)
+            if script[i] == '[':
+                pos = script.find(']', i)
                 if pos > i:
-                    buffer.append(script[i:pos+1])
+                    buffer.append(script[i:pos + 1])
                     i = pos + 1
                     continue
             match = self.re_tag.match(script, i)
             if match:
                 buffer.append(script[i:match.end()])
                 i = match.end()
-            elif script[i] < "\x80":
+            elif script[i] < '\x80':
                 buffer.append(script[i])
                 n += 3
                 i += 1
             else:
-                buffer.append(script[i:i+2])
+                buffer.append(script[i:i + 2])
                 n += 6
                 i += 2
-        return string.join(buffer, "")
+        return ''.join(buffer)
+
     def make_wait(self, ms):
         buffer = []
         n = (ms + 25) * self.wait_percent / 100 / 50
         while n > 0:
-            buffer.append(r"\w%d" % min(n, 9))
+            buffer.append(r'\w%d' % min(n, 9))
             n -= 9
         return buffer
-    def get(self, name, default=""):
+
+    def get(self, name, default=''):
         list = self.talk.get(name)
         if list is None:
             return default
         return self.expand(random.choice(list))
+
     def expand(self, nodelist, caller_history=None, side=1):
         if nodelist is None:
-            return ""
+            return ''
         buffer = []
         history = []
         talk = 0
@@ -1475,9 +1553,13 @@ class Satori:
                         caller_history.append(value)
             elif node[0] == NODE_CALL:
                 if caller_history is not None:
-                    value = self.call_function(node[1], self.calc_args(node[2], caller_history), caller_history, side)
+                    value = self.call_function(
+                        node[1], self.calc_args(node[2], caller_history),
+                        caller_history, side)
                 else:
-                    value = self.call_function(node[1], self.calc_args(node[2], history), history, side)
+                    value = self.call_function(
+                        node[1], self.calc_args(node[2], history),
+                        history, side)
                 if value:
                     talk = 1
                     buffer.append(value)
@@ -1485,14 +1567,20 @@ class Satori:
                     if caller_history is not None:
                         caller_history.append(value)
             elif node[0] == NODE_SAORI:
-                if self.variable.get("SAORI°ú¿ô¤Î·×»»") == "̵¸ú":
+                if self.variable.get('SAORI°ú¿ô¤Î·×»»') == '̵¸ú':
                     expand_only = 1
                 else:
                     expand_only = 0
                 if caller_history is not None:
-                    value = self.call_saori(node[1], self.calc_args(node[2], caller_history, expand_only), caller_history, side)
+                    value = self.call_saori(
+                        node[1],
+                        self.calc_args(node[2], caller_history, expand_only),
+                        caller_history, side)
                 else:
-                    value = self.call_saori(node[1], self.calc_args(node[2], history, expand_only), history, side)
+                    value = self.call_saori(
+                        node[1],
+                        self.calc_args(node[2], history, expand_only),
+                        history, side)
                 if value:
                     talk = 1
                     buffer.append(value)
@@ -1512,21 +1600,22 @@ class Satori:
                     side = 1
                 else:
                     side = 0
-                buffer.append(r"\%d" % side)
+                buffer.append(r'\%d' % side)
                 if self.current_reset_surface[side]:
-                    buffer.append(r"\s[%d]" % self.default_surface[side])
+                    buffer.append(r'\s[%d]' % self.default_surface[side])
                     self.current_reset_surface[side] = 0
                 if newline[side] is not None:
-                    buffer.append(r"%s" % newline[side])
+                    buffer.append(r'%s' % newline[side])
             elif node[0] == NODE_ASSIGNMENT:
                 value = self.expand(node[2])
                 result = self.assign(self.expand(node[1]), value)
                 if result is not None:
                     buffer.append(result)
             elif node[0] == NODE_JUMP:
-                if node[2] is None or self.expand(node[2]) not in ["£°", "0", "False"]:
+                if node[2] is None or \
+                   self.expand(node[2]) not in ['£°', '0', 'False']:
                     target = self.expand(node[1])
-                    if target == "OnTalk":
+                    if target == 'OnTalk':
                         self.reference[1] = self.get_reserved_talk()
                         if self.reference[1]:
                             self.reference[0] = self.to_zenkaku(1)
@@ -1534,32 +1623,32 @@ class Satori:
                             self.reference[0] = self.to_zenkaku(0)
                     script = self.get(target, default=None)
                     if script is not None and script and script != '\\n':
-                        buffer.append(r"\1" + script)
+                        buffer.append(''.join((r'\1', script)))
                         break
             elif node[0] == NODE_SEARCH: ## FIXME
-                buffer.append("")
+                buffer.append('')
             elif node[0] == NODE_CHOICE:
                 label = self.expand(node[1])
                 if node[2] is None:
                     id = label
                 else:
                     id = self.expand(node[2])
-                buffer.append(r"\q[%s,%s]\n" % (label, id))
+                buffer.append(r'\q[%s,%s]\n' % (label, id))
                 talk = 1
             elif node[0] == NODE_OR_EXPR:
                 for i in range(1, len(node)):
-                    if self.expand(node[i]) not in ["£°", "0", "False"]:
-                        buffer.append("£±")
+                    if self.expand(node[i]) not in ['£°', '0', 'False']:
+                        buffer.append('£±')
                         break
                 else:
-                    buffer.append("£°")
+                    buffer.append('£°')
             elif node[0] == NODE_AND_EXPR:
                 for i in range(1, len(node)):
-                    if self.expand(node[i]) in ["£°", "0", "False"]:
-                        buffer.append("£°")
+                    if self.expand(node[i]) in ['£°', '0', 'False']:
+                        buffer.append('£°')
                         break
                 else:
-                    buffer.append("£±")
+                    buffer.append('£±')
             elif node[0] == NODE_COMP_EXPR:
                 operand1 = self.expand(node[1])
                 operand2 = self.expand(node[3])
@@ -1568,32 +1657,33 @@ class Satori:
                 if not (n1 is None or n2 is None):
                     operand1 = n1
                     operand2 = n2
-                elif n1 is None and n2 is None and node[2] in ["<", ">", "<=", ">="]:
+                elif n1 is None and n2 is None and \
+                     node[2] in ['<', '>', '<=', '>=']:
                     operand1 = len(operand1)
                     operand2 = len(operand2)
-                if node[2] == "==":
+                if node[2] == '==':
                     buffer.append(self.to_zenkaku(operand1 == operand2))
-                elif node[2] == "!=":
+                elif node[2] == '!=':
                     buffer.append(self.to_zenkaku(operand1 != operand2))
-                elif node[2] == "<":
+                elif node[2] == '<':
                     buffer.append(self.to_zenkaku(operand1 < operand2))
-                elif node[2] == ">":
+                elif node[2] == '>':
                     buffer.append(self.to_zenkaku(operand1 > operand2))
-                elif node[2] == "<=":
+                elif node[2] == '<=':
                     buffer.append(self.to_zenkaku(operand1 <= operand2))
-                elif node[2] == ">=":
+                elif node[2] == '>=':
                     buffer.append(self.to_zenkaku(operand1 >= operand2))
                 else:
-                    raise RuntimeError, "should not reach here"
+                    raise RuntimeError, 'should not reach here'
             elif node[0] == NODE_ADD_EXPR:
                 value_str = self.expand(node[1])
                 value = self.to_integer(value_str)
                 for i in range(2, len(node), 2):
-                    operand_str = self.expand(node[i+1])
+                    operand_str = self.expand(node[i + 1])
                     operand = self.to_integer(operand_str)
-                    if node[i] == "-":
+                    if node[i] == '-':
                         if value is None or operand is None:
-                            value_str = value_str.replace(operand_str, "")
+                            value_str = value_str.replace(operand_str, '')
                             value = None
                         else:
                             value -= operand
@@ -1603,10 +1693,10 @@ class Satori:
                         value = 0
                     if operand is None:
                         operand = 0
-                    if node[i] == "+":
+                    if node[i] == '+':
                         value += operand
                     else:
-                        raise RuntimeError, "should not reach here"
+                        raise RuntimeError, 'should not reach here'
                 if value is None:
                     buffer.append(value_str)
                 else:
@@ -1615,11 +1705,11 @@ class Satori:
                 value_str = self.expand(node[1])
                 value = self.to_integer(value_str)
                 for i in range(2, len(node), 2):
-                    operand_str = self.expand(node[i+1])
+                    operand_str = self.expand(node[i + 1])
                     operand = self.to_integer(operand_str)
-                    if node[i] == "*":
+                    if node[i] == '*':
                         if value is None and operand is None:
-                            value_str = ""
+                            value_str = ''
                             value = None
                         elif value is None:
                             value_str *= operand
@@ -1634,12 +1724,12 @@ class Satori:
                         value = 0
                     if operand is None:
                         operand = 0
-                    if node[i] == "/":
+                    if node[i] == '/':
                         value /= operand
-                    elif node[i] == "%":
+                    elif node[i] == '%':
                         value %= operand
                     else:
-                        raise RuntimeError, "should not reach here"
+                        raise RuntimeError, 'should not reach here'
                 if value is None:
                     buffer.append(value_str)
                 else:
@@ -1656,27 +1746,30 @@ class Satori:
                 buffer.append(self.to_zenkaku(value))
             elif node[0] == NODE_UNARY_EXPR:
                 value = self.expand(node[2])
-                if node[1] == "-":
+                if node[1] == '-':
                     value = self.to_integer(value)
                     if value is None:
                         value = 0
                     value = -value
-                elif node[1] == "!":
-                    value = (value in ["£°", "0", "False"])
+                elif node[1] == '!':
+                    value = (value in ['£°', '0', 'False'])
                 else:
-                    raise RuntimeError, "should not reach here"
+                    raise RuntimeError, 'should not reach here'
                 buffer.append(self.to_zenkaku(value))
             else:
-                raise RuntimeError, "should not reach here"
-        return string.join(buffer, "").strip()
-    re_random = re.compile("Íð¿ô((¡Ý|¡Ü|[-+])?(£°|£±|£²|£³|£´|£µ|£¶|£·|£¸|£¹|[0-9])+)¡Á((¡Ý|¡Ü|[-+])?(£°|£±|£²|£³|£´|£µ|£¶|£·|£¸|£¹|[0-9])+)")
-    re_is_empty = re.compile("(ÊÑ¿ô|ʸ|ñ¸ì·²)¡Ö(.*)¡×¤Î¸ºß")
-    re_n_reserved = re.compile("¼¡¤«¤é((£°|£±|£²|£³|£´|£µ|£¶|£·|£¸|£¹|[0-9])+)²óÌܤΥȡ¼¥¯")
-    re_is_reserved = re.compile("¥È¡¼¥¯¡Ö(.*)¡×¤ÎͽÌó̵ͭ")
+                raise RuntimeError, 'should not reach here'
+        return ''.join(buffer).strip()
+
+    re_random = re.compile('Íð¿ô((¡Ý|¡Ü|[-+])?(£°|£±|£²|£³|£´|£µ|£¶|£·|£¸|£¹|[0-9])+)¡Á((¡Ý|¡Ü|[-+])?(£°|£±|£²|£³|£´|£µ|£¶|£·|£¸|£¹|[0-9])+)')
+    re_is_empty = re.compile('(ÊÑ¿ô|ʸ|ñ¸ì·²)¡Ö(.*)¡×¤Î¸ºß')
+    re_n_reserved = re.compile('¼¡¤«¤é((£°|£±|£²|£³|£´|£µ|£¶|£·|£¸|£¹|[0-9])+)²óÌܤΥȡ¼¥¯')
+    re_is_reserved = re.compile('¥È¡¼¥¯¡Ö(.*)¡×¤ÎͽÌó̵ͭ')
+
     def get_reference(self, nodelist, history, side):
         key = self.expand(nodelist[1:-1], history)
         if self.word.has_key(key):
-            return self.expand(random.choice(self.word[key]), history, side=side)
+            return self.expand(random.choice(self.word[key]), history,
+                               side=side)
         elif self.talk.has_key(key):
             self.reference = [None] * 8
             return self.expand(random.choice(self.talk[key]), side=1)
@@ -1701,7 +1794,7 @@ class Satori:
                 if self.reserved_talk[key] == number:
                     return key
             else:
-                return ""
+                return ''
         elif self.re_is_reserved.match(key):
             match = self.re_is_reserved.match(key)
             name = match.group(1)
@@ -1713,44 +1806,44 @@ class Satori:
             match = self.re_is_empty.match(key)
             type = match.group(1)
             name = match.group(2)
-            if type == "ÊÑ¿ô":
+            if type == 'ÊÑ¿ô':
                 if self.variable.has_key(name):
                     return self.to_zenkaku(1)
                 else:
                     return self.to_zenkaku(0)
-            elif type == "ʸ":
+            elif type == 'ʸ':
                 if self.talk.has_key(name):
                     return self.to_zenkaku(1)
                 else:
                     return self.to_zenkaku(0)
-            elif type == "ñ¸ì·²":
+            elif type == 'ñ¸ì·²':
                 if self.word.has_key(name):
                     return self.to_zenkaku(1)
                 else:
                     return self.to_zenkaku(0)
         buffer = self.parser.split(key)
-        if buffer[0] in ["£Ò", "R"]:
+        if buffer[0] in ['£Ò', 'R']:
             n = self.to_integer(buffer[1:])
-            if n is not None and n >= 0 and n < len(self.reference):
+            if n is not None and 0 <= n < len(self.reference):
                 if self.reference[n] is None:
-                    return ""
+                    return ''
                 return str(self.reference[n])
-        elif buffer[0] in ["£È", "H"]:
-            ##print '["' + string.join(history, '", "') + '"]'
+        elif buffer[0] in ['£È', 'H']:
+            ##print ''.join(('["', '", "'.join(history), '"]'))
             n = self.to_integer(buffer[1:])
-            if n is not None and  n >= 1 and n < len(history) + 1:
+            if n is not None and 1 <= n < len(history) + 1:
                 return history[n-1]
         n = self.to_integer(buffer)
         if n is not None:
-            return r"\s[%d]" % (n + self.add_to_surface[side])
-        return "¡Ê%s¡Ë" % key
+            return r'\s[%d]' % (n + self.add_to_surface[side])
+        return '¡Ê%s¡Ë' % key
+
     def calc_args(self, args, history, expand_only=0):
         buffer = []
         for i in range(len(args)):
             value = self.expand(args[i], history)
             line = self.parser.split(value)
-            if not expand_only and \
-               len(line) > 0 and self.NUMBER.has_key(line[0]):
+            if not expand_only and line and self.NUMBER.has_key(line[0]):
                 expr = self.parser.get_add_expr(line)
                 result = str(self.to_integer(self.expand(expr, history)))
                 if result is None:
@@ -1760,6 +1853,7 @@ class Satori:
             else:
                 buffer.append(value)
         return buffer
+
     def call_function(self, name, args, history, side):
         if name == 'ñ¸ì¤ÎÄɲÃ': ## FIXME
             pass
@@ -1767,11 +1861,12 @@ class Satori:
             ref = args[0]
             args = args[1:]
             for i in range(len(args)):
-                name = '£Á' + self.to_zenkaku(i)
+                name = ''.join(('£Á', self.to_zenkaku(i)))
                 self.variable[name] = args[i]
-            result = self.get_reference([[NODE_TEXT, '¡Ê'], [NODE_TEXT, ref], [NODE_TEXT, '¡Ë']], history, side)
+            result = self.get_reference([[NODE_TEXT, '¡Ê'], [NODE_TEXT, ref],
+                                         [NODE_TEXT, '¡Ë']], history, side)
             for i in range(len(args)):
-                name = '£Á' + self.to_zenkaku(i)
+                name = ''.join(('£Á', self.to_zenkaku(i)))
                 del self.variable[name]
             return result
         elif name == 'remember':
@@ -1779,11 +1874,11 @@ class Satori:
             if number > 0 and number <= 64 and self.script_history[-number]:
                 return self.script_history[-number] 
             else:
-                return ""
+                return ''
         elif name == 'loop':
             ref = args[0]
             if len(args) < 2:
-                return ""
+                return ''
             elif len(args) == 2:
                 start = 1
                 end = self.to_integer(args[1]) + 1
@@ -1801,23 +1896,26 @@ class Satori:
                 elif step < 0:
                     end = end - 1
                 else:
-                    return "" # infinite loop
-            name = ref + '¥«¥¦¥ó¥¿'
+                    return '' # infinite loop
+            name = ''.join((ref, '¥«¥¦¥ó¥¿'))
             buffer = []
             for i in range(start, end, step):
                 self.variable[name] = self.to_zenkaku(i)
-                buffer.append(self.get_reference([[NODE_TEXT, '¡Ê'], [NODE_TEXT, ref], [NODE_TEXT, '¡Ë']], history, side))
+                buffer.append(self.get_reference([[NODE_TEXT, '¡Ê'],
+                                                  [NODE_TEXT, ref],
+                                                  [NODE_TEXT, '¡Ë']],
+                                                 history, side))
             del self.variable[name]
-            return string.join(buffer, "")
+            return ''.join(buffer)
         elif name == 'sync': ## FIXME
             pass
         elif name == 'set':
-            if len(args) < 1:
-                name = ""
+            if not args:
+                name = ''
             else:
                 name = args[0]
             if len(args) < 2:
-                value = ""
+                value = ''
             else:
                 value = args[1]
             if name:
@@ -1826,184 +1924,200 @@ class Satori:
                         del self.variable[name]
                 else:
                     self.variable[name] = value
-            return ""
+            return ''
         else:
-            raise RuntimeError, "should not reach here"
-        return ""
+            raise RuntimeError, 'should not reach here'
+        return ''
+
     def call_saori(self, name, args, history, side):
-        return ""
+        return ''
+
     def get_runtime(self):
         return int(time.time() - self.time_start)
-    def get_integer(self, name, error="strict"):
+
+    def get_integer(self, name, error='strict'):
         value = self.variable.get(name)
         if value is None:
             return None
         return self.to_integer(value, error)
+
     NUMBER = {
-        "£°": "0", "0": "0",
-        "£±": "1", "1": "1",
-        "£²": "2", "2": "2",
-        "£³": "3", "3": "3",
-        "£´": "4", "4": "4",
-        "£µ": "5", "5": "5",
-        "£¶": "6", "6": "6",
-        "£·": "7", "7": "7",
-        "£¸": "8", "8": "8",
-        "£¹": "9", "9": "9",
-        "¡Ü": "+", "+": "+",
-        "¡Ý": "-", "-": "-",
+        '£°': '0', '0': '0',
+        '£±': '1', '1': '1',
+        '£²': '2', '2': '2',
+        '£³': '3', '3': '3',
+        '£´': '4', '4': '4',
+        '£µ': '5', '5': '5',
+        '£¶': '6', '6': '6',
+        '£·': '7', '7': '7',
+        '£¸': '8', '8': '8',
+        '£¹': '9', '9': '9',
+        '¡Ü': '+', '+': '+',
+        '¡Ý': '-', '-': '-',
         }
-    def to_integer(self, line, error="strict"):
-        if type(line) == type(""):
+
+    def to_integer(self, line, error='strict'):
+        if isinstance(line, str):
             line = self.parser.split(line)
         buffer = []
         for char in line:
             try:
                 buffer.append(self.NUMBER[char])
             except KeyError:
-                if error == "strict":
+                if error == 'strict':
                     return None
         try:
-            return int(string.join(buffer, ""))
+            return int(''.join(buffer))
         except ValueError:
             return None
+
     def is_number(self, line):
         return self.to_integer(line) is not None
+
     ZENKAKU = {
-        "0": "£°", "1": "£±", "2": "£²", "3": "£³", "4": "£´",
-        "5": "£µ", "6": "£¶", "7": "£·", "8": "£¸", "9": "£¹",
-        "+": "¡Ü",  "-": "¡Ý",
+        '0': '£°', '1': '£±', '2': '£²', '3': '£³', '4': '£´',
+        '5': '£µ', '6': '£¶', '7': '£·', '8': '£¸', '9': '£¹',
+        '+': '¡Ü',  '-': '¡Ý',
         }
+
     def to_zenkaku(self, s):
         buffer = list(str(s))
         for i in range(len(buffer)):
             buffer[i] = self.ZENKAKU.get(buffer[i], buffer[i])
-        return string.join(buffer, "")
+        return ''.join(buffer)
+
     RESERVED = [
-        "¸½ºßǯ", "¸½ºß·î", "¸½ºßÆü", "¸½ºßÍËÆü",
-        "¸½ºß»þ", "¸½ºßʬ", "¸½ºßÉÃ",
-        "µ¯Æ°»þ", "µ¯Æ°Ê¬", "µ¯Æ°ÉÃ",
-        "Îß·×»þ", "Îß·×ʬ", "Îß·×ÉÃ",
-        "£Ï£Óµ¯Æ°»þ", "£Ï£Óµ¯Æ°Ê¬", "£Ï£Óµ¯Æ°ÉÃ",
-        "ñ½ãµ¯Æ°Ê¬", "ñ½ãµ¯Æ°ÉÃ",
-        "ñ½ãÎß·×ʬ", "ñ½ãÎß·×ÉÃ",
-        "ñ½ã£Ï£Óµ¯Æ°Ê¬", "ñ½ã£Ï£Óµ¯Æ°ÉÃ",
-        "ºÇ½ª¥È¡¼¥¯¤«¤é¤Î·Ð²áÉÃ",
-        "¥µ¡¼¥Õ¥§¥¹0", "¥µ¡¼¥Õ¥§¥¹1",
-        "ÁªÂò£É£Ä", "ÁªÂò¥é¥Ù¥ë", "ÁªÂòÈÖ¹æ",
-        "ͽÌó¥È¡¼¥¯¿ô",
-        "µ¯Æ°²ó¿ô",
-        "Sender", "Event", "Charset",
-        "Reference0", "Reference1", "Reference2", "Reference3",
-        "Reference4", "Reference5", "Reference6", "Reference7",
-        "countTalk", "countNoNameTalk", "countEventTalk", "countOtherTalk",
-        "countWords", "countWord", "countVariable", "countAnchor",
-        "countParenthesis", "countParentheres", "countLine",
+        '¸½ºßǯ', '¸½ºß·î', '¸½ºßÆü', '¸½ºßÍËÆü',
+        '¸½ºß»þ', '¸½ºßʬ', '¸½ºßÉÃ',
+        'µ¯Æ°»þ', 'µ¯Æ°Ê¬', 'µ¯Æ°ÉÃ',
+        'Îß·×»þ', 'Îß·×ʬ', 'Îß·×ÉÃ',
+        '£Ï£Óµ¯Æ°»þ', '£Ï£Óµ¯Æ°Ê¬', '£Ï£Óµ¯Æ°ÉÃ',
+        'ñ½ãµ¯Æ°Ê¬', 'ñ½ãµ¯Æ°ÉÃ',
+        'ñ½ãÎß·×ʬ', 'ñ½ãÎß·×ÉÃ',
+        'ñ½ã£Ï£Óµ¯Æ°Ê¬', 'ñ½ã£Ï£Óµ¯Æ°ÉÃ',
+        'ºÇ½ª¥È¡¼¥¯¤«¤é¤Î·Ð²áÉÃ',
+        '¥µ¡¼¥Õ¥§¥¹0', '¥µ¡¼¥Õ¥§¥¹1',
+        'ÁªÂò£É£Ä', 'ÁªÂò¥é¥Ù¥ë', 'ÁªÂòÈÖ¹æ',
+        'ͽÌó¥È¡¼¥¯¿ô',
+        'µ¯Æ°²ó¿ô',
+        'Sender', 'Event', 'Charset',
+        'Reference0', 'Reference1', 'Reference2', 'Reference3',
+        'Reference4', 'Reference5', 'Reference6', 'Reference7',
+        'countTalk', 'countNoNameTalk', 'countEventTalk', 'countOtherTalk',
+        'countWords', 'countWord', 'countVariable', 'countAnchor',
+        'countParenthesis', 'countParentheres', 'countLine',
         ]
+
     def is_reserved(self, s):
         return s in self.RESERVED
-    DAYOFWEEK = ["·î", "²Ð", "¿å", "ÌÚ", "¶â", "ÅÚ", "Æü"]
+
+    DAYOFWEEK = ['·î', '²Ð', '¿å', 'ÌÚ', '¶â', 'ÅÚ', 'Æü']
+
     def get_reserved(self, s):
         now = time.localtime(time.time())
-        if s == "¸½ºßǯ":
+        if s == '¸½ºßǯ':
             return self.to_zenkaku(now[0])
-        elif s == "¸½ºß·î":
+        elif s == '¸½ºß·î':
             return self.to_zenkaku(now[1])
-        elif s == "¸½ºßÆü":
+        elif s == '¸½ºßÆü':
             return self.to_zenkaku(now[2])
-        elif s == "¸½ºß»þ":
+        elif s == '¸½ºß»þ':
             return self.to_zenkaku(now[3])
-        elif s == "¸½ºßʬ":
+        elif s == '¸½ºßʬ':
             return self.to_zenkaku(now[4])
-        elif s == "¸½ºßÉÃ":
+        elif s == '¸½ºßÉÃ':
             return self.to_zenkaku(now[5])
-        elif s == "¸½ºßÍËÆü":
+        elif s == '¸½ºßÍËÆü':
             return self.DAYOFWEEK[now[6]]
         runtime = self.get_runtime()
-        if s == "µ¯Æ°»þ":
+        if s == 'µ¯Æ°»þ':
             return self.to_zenkaku(runtime / 3600)
-        elif s == "µ¯Æ°Ê¬":
+        elif s == 'µ¯Æ°Ê¬':
             return self.to_zenkaku(runtime / 60 % 60)
-        elif s == "µ¯Æ°ÉÃ":
+        elif s == 'µ¯Æ°ÉÃ':
             return self.to_zenkaku(runtime % 60)
-        elif s == "ñ½ãµ¯Æ°Ê¬":
+        elif s == 'ñ½ãµ¯Æ°Ê¬':
             return self.to_zenkaku(runtime / 60)
-        elif s == "ñ½ãµ¯Æ°ÉÃ":
+        elif s == 'ñ½ãµ¯Æ°ÉÃ':
             return self.to_zenkaku(runtime)
         accumulative_runtime = self.runtime + self.get_runtime()
-        if s == "Îß·×»þ":
+        if s == 'Îß·×»þ':
             return self.to_zenkaku(accumulative_runtime / 3600)
-        elif s == "Îß·×ʬ":
+        elif s == 'Îß·×ʬ':
             return self.to_zenkaku(accumulative_runtime / 60 % 60)
-        elif s == "Îß·×ÉÃ":
+        elif s == 'Îß·×ÉÃ':
             return self.to_zenkaku(accumulative_runtime % 60)
-        elif s == "ñ½ãÎß·×ʬ":
+        elif s == 'ñ½ãÎß·×ʬ':
             return self.to_zenkaku(accumulative_runtime / 60)
-        elif s == "ñ½ãÎß·×ÉÃ":
+        elif s == 'ñ½ãÎß·×ÉÃ':
             return self.to_zenkaku(accumulative_runtime)
-        elif s == "µ¯Æ°²ó¿ô":
+        elif s == 'µ¯Æ°²ó¿ô':
             return self.to_zenkaku(self.runcount)
-        elif s == "ºÇ½ª¥È¡¼¥¯¤«¤é¤Î·Ð²áÉÃ":
+        elif s == 'ºÇ½ª¥È¡¼¥¯¤«¤é¤Î·Ð²áÉÃ':
             return self.to_zenkaku(self.silent_time)
-        elif s == "¥µ¡¼¥Õ¥§¥¹0":
+        elif s == '¥µ¡¼¥Õ¥§¥¹0':
             return str(self.current_surface[0])
-        elif s == "¥µ¡¼¥Õ¥§¥¹1":
+        elif s == '¥µ¡¼¥Õ¥§¥¹1':
             return str(self.current_surface[1])
-        elif s == "ÁªÂò£É£Ä":
+        elif s == 'ÁªÂò£É£Ä':
             if self.choice_id is None:
-                return ""
+                return ''
             else:
                 return self.choice_id
-        elif s == "ÁªÂò¥é¥Ù¥ë":
+        elif s == 'ÁªÂò¥é¥Ù¥ë':
             if self.choice_label is None:
-                return ""
+                return ''
             else:
                 return self.choice_label
-        elif s == "ÁªÂòÈÖ¹æ":
+        elif s == 'ÁªÂòÈÖ¹æ':
             if self.choice_number is None:
-                return ""
+                return ''
             else:
                 return self.to_zenkaku(self.choice_number)
-        elif s == "ͽÌó¥È¡¼¥¯¿ô":
+        elif s == 'ͽÌó¥È¡¼¥¯¿ô':
             return self.to_zenkaku(len(self.reserved_talk))
-        elif s == "Sender":
-            return "ninix"
-        elif s == "Event":
+        elif s == 'Sender':
+            return 'ninix'
+        elif s == 'Event':
             return self.event
-        elif s == "Charset":
-            return "EUC-JP"
-        elif s[:9] == "Reference":
+        elif s == 'Charset':
+            return 'EUC-JP'
+        elif s.startswith('Reference'):
             n = int(s[9:])
             if self.reference[n] is None:
-                return ""
+                return ''
             return str(self.reference[n])
-        elif s[:5] == "count":
+        elif s.startswith('count'):
             return self.to_zenkaku(self.parser.get_count(s[5:]))
-        return "¡©"
+        return '¡©'
 
 class Shiori(Satori):
+
     def __init__(self, dll_name, debug=0):
         self.debug = debug
         self.dll_name = dll_name
         self.saori = None
         self.saori_function = {}
+
     def use_saori(self, saori):
         self.saori = saori
+
     def load(self, satori_dir):
         Satori.__init__(self, satori_dir, self.debug)
         self.saori_library = SatoriSaoriLibrary(self.saori, self)
         Satori.load(self)
         return 1
+
     def load_config_file(self, path):
         parser = Parser()
         parser.read(path)
         talk, word = parser.get_dict()
-        for nodelist in talk.get("½é´ü²½", []):
+        for nodelist in talk.get('½é´ü²½', []):
             self.expand(nodelist)
         self.saori_function = {}
-        for nodelist in word.get("SAORI", []):
+        for nodelist in word.get('SAORI', []):
             if nodelist[0][0] == NODE_TEXT:
-                list = string.join(nodelist[0][1], '').split(',')
+                list = ''.join(nodelist[0][1]).split(',')
                 if len(list) >= 2 and list[0] and list[1]:
                     head, tail = os.path.split(list[1])
                     dir = os.path.join(self.satori_dir, head)
@@ -2012,26 +2126,32 @@ class Shiori(Satori):
                         self.saori_function[list[0]] = list[1:]
                     else:
                         self.saori_function[list[0]] = None
-                        ##print "satori.py: cannot load %s" % list[1]
+                        ##print 'satori.py: cannot load %s' % list[1]
         self.parser.set_saori(self.saori_function.keys())
+
     def reload(self):
         self.finalize()
         self.reset()
         self.load(self.satori_dir)
+
     def unload(self):
         Satori.finalize(self)
         self.saori_library.unload()
+
     def find(self, dir, dll_name):
         result = 0
         if list_dict(dir):
             result = 100
         return result
+
     def show_description(self):
-        sys.stdout.write('Shiori: SATORI compatible module for ninix\n'
-                         '        Copyright (C) 2002 by Tamito KAJIYAMA\n'
-                         '        Copyright (C) 2002, 2003 by MATSUMURA Namihiko\n'
-                         '        Copyright (C) 2002-2004 by Shyouzou Sugitani\n'
-                         '        Copyright (C) 2003, 2004 by Shun-ichi TAHARA\n')
+        sys.stdout.write(
+            'Shiori: SATORI compatible module for ninix\n'
+            '        Copyright (C) 2002 by Tamito KAJIYAMA\n'
+            '        Copyright (C) 2002, 2003 by MATSUMURA Namihiko\n'
+            '        Copyright (C) 2002-2005 by Shyouzou Sugitani\n'
+            '        Copyright (C) 2003, 2004 by Shun-ichi TAHARA\n')
+
     def request(self, req_string):
         if self.folder_change:
             self.change_folder()
@@ -2055,7 +2175,7 @@ class Shiori(Satori):
                 colon = line.find(':')
                 if colon >= 0:
                     key = line[:colon].strip()
-                    value = line[colon+1:].strip()
+                    value = line[colon + 1:].strip()
                     try:
                         value = int(value)
                     except:
@@ -2072,14 +2192,15 @@ class Shiori(Satori):
                 result = self.getdms()
             elif req_header['ID'] == 'OnAITalk':
                 result = self.getaistringrandom()
-            elif req_header['ID'] in ["\\ms", "\\mz", "\\ml", "\\mc", "\\mh", \
-                                      "\\mt", "\\me", "\\mp", "\\m?"]:
+            elif req_header['ID'] in ['\\ms', '\\mz', '\\ml', '\\mc', '\\mh', \
+                                      '\\mt', '\\me', '\\mp', '\\m?']:
                 result = self.getword(req_header['ID'])
             elif req_header['ID'] == 'otherghostname': ## FIXME
                 ##otherghost = []
                 ##for n in range(128):
-                ##    if req_header.has_key('Reference'+str(n)):
-                ##        otherghost.append(req_header['Reference'+str(n)])
+                ##    if req_header.has_key(''.join(('Reference', str(n)))):
+                ##        otherghost.append(req_header[''.join(('Reference',
+                ##                                              str(n)])))
                 ##result = self.otherghostname(otherghost)
                 pass
             elif req_header['ID'] == 'OnTeach':
@@ -2090,13 +2211,15 @@ class Shiori(Satori):
                 if result is None:
                     ref = []
                     for n in range(8):
-                        if req_header.has_key('Reference'+str(n)):
-                            ref.append(req_header['Reference'+str(n)])
+                        if req_header.has_key(''.join(('Reference', str(n)))):
+                            ref.append(req_header[
+                                ''.join(('Reference', str(n)))])
                         else:
                             ref.append(None)
                     ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7 = ref
                     result = self.get_event_response(
-                        req_header['ID'], ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7)
+                        req_header['ID'], ref0, ref1, ref2, ref3, ref4,
+                        ref5, ref6, ref7)
             if result is None:
                 result = ''
             to = None ##self.communicate_to() ## FIXME
@@ -2106,9 +2229,10 @@ class Shiori(Satori):
                  'Sender: Satori\r\n' \
                  'Value: %s\r\n' % result
         if to is not None:
-            result += 'Reference0: %s\r\n' % to
-        result += '\r\n'
+            result = ''.join((result, 'Reference0: %s\r\n' % to))
+        result = ''.join((result, '\r\n'))
         return result
+
     def call_saori(self, name, args, history, side):
         if not self.saori_function.has_key(name) or \
            self.saori_function[name] is None:
@@ -2124,17 +2248,20 @@ class Shiori(Satori):
         default_args = self.saori_function[name][1:]
         n = len(default_args)
         for i in range(len(default_args)):
-              req += 'Argument%s: %s\r\n' % (i, default_args[i])
+              req = ''.join((req, 'Argument%s: %s\r\n' % (i, default_args[i])))
         for i in range(len(args)):
               argument = args[i]
               if argument:
-                  req += 'Argument%s: %s\r\n' % (i + n, argument)
-        req += '\r\n'
-        response = self.saori_library.request(self.saori_function[name][0], unicode(req, 'EUC-JP', 'ignore').encode('Shift_JIS', 'ignore'))
+                  req = ''.join((req,
+                                 'Argument%s: %s\r\n' % (i + n, argument)))
+        req = ''.join((req, '\r\n'))
+        response = self.saori_library.request(
+            self.saori_function[name][0],
+            unicode(req, 'EUC-JP', 'ignore').encode('Shift_JIS', 'ignore'))
         header = StringIO.StringIO(response)
         line = header.readline()
         if line:
-            if line[-1] == '\n':
+            if line.endswith('\n'):
                 line = line[:-1]
             line = line.strip()
             pos_space = line.find(' ')
@@ -2145,7 +2272,7 @@ class Shiori(Satori):
                 line = header.readline()
                 if not line:
                     break # EOF
-                if line[-1] == '\n':
+                if line.endswith('\n'):
                     line = line[:-1]
                 line = line.strip()
                 if not line:
@@ -2153,29 +2280,32 @@ class Shiori(Satori):
                 colon = line.find(':')
                 if colon >= 0:
                     key = line[:colon].strip()
-                    value = line[colon+1:].strip()
+                    value = line[colon + 1:].strip()
                     if key:
                         saori_header.append(key)
                         saori_value[key] = value
         for key in saori_value.keys():
-            if key[:5] != 'Value':
+            if not key.startswith('Value'):
                 continue
             try:
                 i = int(key[5:])
             except:
                 continue
-            name = '£Ó' + self.to_zenkaku(i)
+            name = ''.join(('£Ó', self.to_zenkaku(i)))
             self.variable[name] = saori_value[key]
         if saori_value.has_key('Result'):
-            return unicode(saori_value['Result'], 'Shift_JIS', 'ignore').encode('EUC-JP', 'ignore')
+            return unicode(saori_value['Result'],
+                           'Shift_JIS', 'ignore').encode('EUC-JP', 'ignore')
         else:
             return ''
 
 class SatoriSaoriLibrary:
+
     def __init__(self, saori, satori):
         self.saori_list = {}
         self.saori = saori
         self.satori = satori
+
     def load(self, name, dir):
         result = 0
         if self.saori and not self.saori_list.has_key(name):
@@ -2185,16 +2315,19 @@ class SatoriSaoriLibrary:
         if self.saori_list.has_key(name):
             result = self.saori_list[name].load(dir)
         return result
+
     def unload(self):
         for key in self.saori_list.keys():
             self.saori_list[key].unload()
         return None
+
     def request(self, name, req):
         result = '' # FIXME
         if name and self.saori_list.has_key(name):
             result = self.saori_list[name].request(req)
         return result
 
+
 def open(dir, debug=0):
     satori = Satori(dir, debug)
     satori.load()
@@ -2203,16 +2336,16 @@ def open(dir, debug=0):
 ###   TEST   ###
 
 def test():
-    if sys.argv[1] == "ini":
+    if sys.argv[1] == 'ini':
         test_ini(sys.argv[2])
-    elif sys.argv[1] == "parser":
+    elif sys.argv[1] == 'parser':
         test_parser(sys.argv[2])
-    elif sys.argv[1] == "interp":
+    elif sys.argv[1] == 'interp':
         test_interp(sys.argv[2])
 
 def test_ini(dir):
     list = list_dict(dir)
-    print "number of files =", len(list)
+    print 'number of files =', len(list)
     for dict in list:
         print dict
 
@@ -2221,13 +2354,13 @@ def test_parser(path):
     parser.read(path)
     for name, talk in parser.talk.items():
         for list in talk:
-            print "¡ö", name
+            print '¡ö', name
             parser.print_nodelist(list)
             print
     for name, word in parser.word.items():
-        print "¡÷", name
+        print '¡÷', name
         for list in word:
-            print ">>>", test_expand(list)
+            print '>>>', test_expand(list)
             parser.print_nodelist(list, 2)
         print
 
@@ -2239,8 +2372,8 @@ def test_expand(list):
         elif node[0] == NODE_REF:
             buffer.extend(test_expand(node[1]))
         else:
-            raise RuntimeError, "should not reach here"
-    return string.join(buffer, "")
+            raise RuntimeError, 'should not reach here'
+    return ''.join(buffer)
 
 def test_interp(dir):
     import readline
@@ -2248,15 +2381,15 @@ def test_interp(dir):
     satori.load()
     while 1:
         try:
-            name = raw_input(">>> ")
+            name = raw_input('>>> ')
         except:
             break
-        if name[:2] == "¡÷":
+        if name.startswith('¡÷'):
             print satori.getstring(name[2:])
-        elif name[:2] == "¡ö":
+        elif name.startswith('¡ö'):
             print satori.get_event_response(name[2:])
         else:
             print satori.get_event_response(name)
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     test()
index 14c52ce..4bb7eb3 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: UTF-8 -*-
 #
 #  ssu.py - a ssu compatible Saori module for ninix
-#  Copyright (C) 2003-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2003-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
@@ -21,7 +21,9 @@ import re
 
 from ninix.dll import SAORI
 
+
 class Saori(SAORI):
+
     def __init__(self):
        SAORI.__init__(self)
         self.function = {'is_empty':      [self.ssu_is_empty,      [0, 1]],
@@ -50,6 +52,7 @@ class Saori(SAORI):
                          'switch':        [self.ssu_switch,        [None]],
                          'if':            [self.ssu_if,            [2, 3]],
                          'unless':        [self.ssu_unless,        [2, 3]],}
+
     def request(self, req):
         type, argument, charset = self.evaluate_request(req)
         if not type:
@@ -67,51 +70,58 @@ class Saori(SAORI):
                 return 'SAORI/1.0 400 Bad Request\r\n\r\n'
             self.value = []
             result = self.function[name][0](argument, charset)
-            if result is not None and result is not "":
+            if result is not None and result is not '':
                 s = 'SAORI/1.0 200 OK\r\nResult: %s\r\n' % result
                 if self.value is not None and self.value is not []:
                     for i in range(len(self.value)):
-                        s += 'Value%d: %s\r\n' % (i, self.value[i])
-                s += 'Charset: %s\r\n' % charset
-                s += '\r\n'
+                        s = ''.join((s,
+                                     'Value%d: %s\r\n' % (i, self.value[i])))
+                s = ''.join((s, 'Charset: %s\r\n' % charset))
+                s = ''.join((s, '\r\n'))
                 return s
             else:
                 return 'SAORI/1.0 204 No Content\r\n\r\n'
+
     def ssu_is_empty(self, args, charset):
-        if len(args) == 0:
+        if not args:
             return 1
         else:
             return 0
+
     def ssu_is_digit(self, args, charset):
         s = unicode(args[0], charset, 'ignore')
         if s.isdigit():
             return 1
         else:
             return 0
+
     def ssu_is_alpha(self, args, charset):
         s = unicode(args[0], charset, 'ignore')
         if s.isalpha():
             return 1
         else:
             return 0
+
     def ssu_length(self, args, charset):
         s = unicode(args[0], charset, 'ignore')
         return len(s)
+
     def ssu_substr(self, args, charset):
         s = unicode(args[0], charset, 'ignore')
         if self.ssu_is_digit([args[1]], charset):
             start = int(self.ssu_zen2han([args[1]], charset))
             if start > len(s):
-                return ""
+                return ''
         else:
-            return ""
+            return ''
         if len(args) == 2:
             end = len(s)
         elif len(args) == 3 and self.ssu_is_digit([args[2]], charset):
             end = start + int(self.ssu_zen2han([args[2]], charset))
         else:
-            return ""
+            return ''
         return s[start:end].encode(charset, 'ignore')
+
     def ssu_sprintf(self, args, charset): ## FIXME
         for i in range(1, len(args)):
             if self.ssu_is_digit([args[i]], charset):
@@ -119,34 +129,41 @@ class Saori(SAORI):
         try:
             return args[0] % tuple(args[1:])
         except:
-            return ""
+            return ''
+
     ZEN = {'0': '0', '1': '1', '2': '2', '3': '3', '4': '4',
            '5': '5', '6': '6', '7': '7', '8': '8', '9': '9',
            '.': '.', '+': '+', '−': '-',}
     HAN = {'0': '0', '1': '1', '2': '2', '3': '3', '4': '4',
            '5': '5', '6': '6', '7': '7', '8': '8', '9': '9',
            '.': '.', '+': '+', '-': '−',}
+
     def ssu_zen2han(self, args, charset): ## FIXME
         s = unicode(args[0], charset, 'ignore')
-        buffer = ""
+        buffer = ''
         for i in range(len(s)):
             c = s[i].encode('utf-8', 'ignore')
             if self.ZEN.has_key(c):
-                buffer += unicode(self.ZEN[c], 'utf-8', 'ignore')
+                buffer = ''.join((buffer,
+                                  unicode(self.ZEN[c], 'utf-8', 'ignore')))
             else:
-                buffer += s[i]
+                buffer = ''.join((buffer, s[i]))
         return buffer.encode(charset, 'ignore')
+
     def ssu_han2zen(self, args, charset): ## FIXME
         s = unicode(args[0], charset, 'ignore')
-        buffer = ""
+        buffer = ''
         for i in range(len(s)):
             c = s[i].encode('utf-8', 'ignore')
             if self.HAN.has_key(c):
-                buffer += unicode(self.HAN[c], 'utf-8', 'ignore')
+                buffer = ''.join((buffer,
+                                  unicode(self.HAN[c], 'utf-8', 'ignore')))
             else:
-                buffer += s[i]
+                buffer = ''.join((buffer, s[i]))
         return buffer.encode(charset, 'ignore')
-    re_condition = re.compile(r"(>|<|==|>=|<=|!=|>|<|>=|<=|!=|==)")
+
+    re_condition = re.compile(r'(>|<|==|>=|<=|!=|>|<|>=|<=|!=|==)')
+
     def eval_condition(self, left, ope, right):
         if self.ssu_is_digit([left], 'utf-8') and \
            self.ssu_is_digit([right], 'utf-8'):
@@ -169,10 +186,12 @@ class Saori(SAORI):
         elif ope in ['!=', '!=']:
             result = left != right
         else:
-            pass # "should not reach here"   
+            pass # 'should not reach here'
         return result
+
     def ssu_if(self, args, charset):
-        condition = unicode(args[0], charset, 'ignore').encode('utf-8', 'ignore')
+        condition = unicode(
+            args[0], charset, 'ignore').encode('utf-8', 'ignore')
         match = self.re_condition.search(condition)
         if match is not None:
             left = condition[:match.start()]
@@ -184,9 +203,11 @@ class Saori(SAORI):
         if len(args) == 3:
             return args[2]
         else:
-            return ""
+            return ''
+
     def ssu_unless(self, args, charset):
-        condition = unicode(args[0], charset, 'ignore').encode('utf-8', 'ignore')
+        condition = unicode(
+            args[0], charset, 'ignore').encode('utf-8', 'ignore')
         match = self.re_condition.search(condition)
         if match is not None:
             left = condition[:match.start()]
@@ -198,14 +219,16 @@ class Saori(SAORI):
         if len(args) == 3:
             return args[2]
         else:
-            return ""
+            return ''
+
     def ssu_iflist(self, args, charset):
         left = unicode(args[0], charset, 'ignore').encode('utf-8', 'ignore')
         i = 1
         while 1:
             if len(args[i:]) < 2:
                 break
-            ope_right = unicode(args[i], charset, 'ignore').encode('utf-8', 'ignore')
+            ope_right = unicode(
+                args[i], charset, 'ignore').encode('utf-8', 'ignore')
             match = self.re_condition.search(ope_right)
             if match is not None:
                 ope = match.group(1)
@@ -214,47 +237,53 @@ class Saori(SAORI):
                 if result:
                     return args[i + 1]
             i += 2
-        return ""
+        return ''
+
     def ssu_nswitch(self, args, charset):
         num = unicode(args[0], charset, 'ignore').encode('utf-8', 'ignore')
         if self.ssu_is_digit([num], 'utf-8'):
             num = int(self.ssu_zen2han([num], 'utf-8'))
-            if num > 0 and num < len(args):
+            if 0 < num < len(args):
                 return args[num]
-        return ""
+        return ''
+
     def ssu_count(self, args, charset):
         return args[0].count(args[1])
+
     def ssu_compare(self, args, charset):
         if args[0] == args[1]:
             return 1
         else:
             return 0
+
     def ssu_compare_head(self, args, charset):
         s0 = args[0]
         s1 = args[1]
-        l0 = len(s0)
-        l1 = len(s1)
-        if l0 <= l1 and s1[:l0] == s0:
+        if s1.startswith(s0):
             return 1
         else:
             return 0
+
     def ssu_compare_tail(self, args, charset):
         s0 = args[0]
         s1 = args[1]
-        l0 = len(s0)
-        l1 = len(s1)
-        if l0 <= l1 and s1[-l0:] == s0:
+        if s1.endswith(s0):
             return 1
         else:
             return 0
+
     def ssu_erase(self, args, charset):
         return args[0].replace(args[1], '')
+
     def ssu_erase_first(self, args, charset):
         return args[0].replace(args[1], '', 1)
+
     def ssu_replace(self, args, charset):
         return args[0].replace(args[1], args[2])
+
     def ssu_replace_first(self, args, charset):
         return args[0].replace(args[1], args[2], 1)
+
     def ssu_split(self, args, charset):
         s0 = args[0]
         if len(args) >= 2:
@@ -270,6 +299,7 @@ class Saori(SAORI):
             list = s0.split(s1)
         self.value = list
         return len(list)
+
     def ssu_switch(self, args, charset):
         left = args[0]
         i = 1
@@ -280,15 +310,20 @@ class Saori(SAORI):
             if left == right:
                 return args[i + 1]
             i += 2
-        return ""
+        return ''
+
     def ssu_kata2hira(self, args, charset): ## FIXME
-        return ""
+        return ''
+
     def ssu_hira2kata(self, args, charset): ## FIXME
-        return ""
+        return ''
+
     def ssu_calc(self, args, charset): ## FIXME
         return 0
+
     def ssu_calc_float(self, args, charset): ## FIXME
         return 0
+
     def evaluate_request(self, req):
         type = None
         argument = []
@@ -297,20 +332,20 @@ class Saori(SAORI):
         line = header.readline()
         if not line:
             return type, argument
-        if line[-1] == '\n':
+        if line.endswith('\n'):
             line = line[:-1]
         line = line.strip()
         if not line:
             return type, argument
         for request in ['EXECUTE', 'GET Version']:
-            if line[:len(request)] == request:
+            if line.startswith(request):
                 type = request
                 break
         while 1:
             line = header.readline()
             if not line:
                 break # EOF
-            if line[-1] == '\n':
+            if line.endswith('\n'):
                 line = line[:-1]
             line = line.strip()
             if not line:
@@ -318,14 +353,15 @@ class Saori(SAORI):
             colon = line.find(':')
             if colon >= 0:
                 key = line[:colon].strip()
-                value = line[colon+1:].strip()
+                value = line[colon + 1:].strip()
                 if key == 'Charset':
                     charset = value
                     try:
                         codecs.lookup(charset)
                     except:
-                        sys.stderr.write("Unsupported charset %s" % repr(charset))
-                if key[:8] == 'Argument': ## FIXME
+                        sys.stderr.write(
+                            'Unsupported charset %s' % repr(charset))
+                if key.startswith('Argument'): ## FIXME
                     argument.append(value)
                 else:
                     continue
index 97c401a..c7f003a 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: ascii -*-
 #
 #  textcopy.py - a TEXTCOPY compatible Saori module for ninix
-#  Copyright (C) 2002-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
 #
 #  This program is free software; you can redistribute it and/or modify it
@@ -11,7 +11,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-#  $Id: textcopy.py,v 1.7 2005/07/29 08:25:59 shy Exp $
+#  $Id: textcopy.py,v 1.8 2005/08/09 00:41:52 shy Exp $
 #
 
 import os
@@ -23,33 +23,41 @@ else:
 
 from ninix.dll import SAORI
 
+
 class Saori(SAORI):
+
     def __init__(self):
         SAORI.__init__(self)
         self.window = None
         self.entry = None
+
     def check_import(self):
         if gtk is None:
             return 0
         else:
             return 1
+
     def setup(self):
         self.window = gtk.Window()
         self.entry = gtk.Entry()
         self.window.add(self.entry)
         self.entry.realize()
         return 1
+
     def finalize(self):
         self.entry = None
         self.window = None
         return 1
+
     def execute(self, argument):
-        if len(argument) == 0 or self.entry is None:
+        if not argument or self.entry is None:
             return 'SAORI/1.0 400 Bad Request\r\n\r\n'
         text = argument[0].encode('utf-8')
         self.entry.set_text(text)
         self.entry.select_region(0, len(text))
         if len(argument) >= 2 and argument[1] != 0:
-            return 'SAORI/1.0 200 OK\r\nResult: %s\r\n\r\n' % argument[0].encode(self.charset, 'replace')
+            return 'SAORI/1.0 200 OK\r\n' \
+                   'Result: %s\r\n\r\n' % \
+                   argument[0].encode(self.charset, 'replace')
         else:
             return 'SAORI/1.0 204 No Content\r\n\r\n'
index 5cf9112..79a29a9 100755 (executable)
@@ -1,7 +1,7 @@
 # -*- coding: ascii -*-
 #
 #  wmove.py - a wmove.dll compatible Saori module for ninix
-#  Copyright (C) 2003-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2003-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
@@ -21,7 +21,7 @@ if os.environ.has_key('DISPLAY'):
     if not sys.modules.has_key('gtk'):
         try:
             import pygtk
-            pygtk.require("2.0")
+            pygtk.require('2.0')
         except ImportError:
             pass
     import gtk
@@ -31,12 +31,16 @@ else:
 
 from ninix.dll import SAORI
 
+
 class Saori(SAORI):
+
     def __init__(self):
         SAORI.__init__(self)
         self.__ghost = None
+
     def need_ghost_backdoor(self, ghost):
         self.__ghost = ghost
+
     def load(self, dir=os.curdir):
         self.commands = [[], []]
         self.timeout_id = None
@@ -52,6 +56,7 @@ class Saori(SAORI):
             self.loaded = 1
             result = 1
        return result
+
     def finalize(self):
         if self.timeout_id:
             gobject.source_remove(self.timeout_id)
@@ -60,6 +65,7 @@ class Saori(SAORI):
         self.sakura_name = ''
         self.kero_name = ''
         return 1
+
     def request(self, req):
         type, argument = self.evaluate_request(req)
         if not type:
@@ -67,7 +73,7 @@ class Saori(SAORI):
         elif type == 'GET Version':
             return 'SAORI/1.0 204 No Content\r\n\r\n'
         elif type == 'EXECUTE':
-            if len(argument) == 0:
+            if not argument:
                 return 'SAORI/1.0 400 Bad Request\r\n\r\n'
             name = argument[0]
             if name in ['MOVE', 'MOVE_INSIDE']:
@@ -103,7 +109,11 @@ class Saori(SAORI):
                try:
                     x, y = self.__ghost.get_surface_position(side)
                     w, h = self.__ghost.get_surface_size(side)
-                    return 'SAORI/1.0 200 OK\r\nResult: %d\r\nValue0: %d\r\nValue1: %d\r\nValue2: %d\r\n\r\n' % (x, x, x + w / 2, x + w)
+                    return 'SAORI/1.0 200 OK\r\n' \
+                           'Result: %d\r\n' \
+                           'Value0: %d\r\n' \
+                           'Value1: %d\r\n' \
+                           'Value2: %d\r\n\r\n' % (x, x, x + w / 2, x + w)
                except:
                     return 'SAORI/1.0 500 Internal Server Error\r\n\r\n'
             elif name == 'GET_DESKTOP_SIZE':
@@ -113,7 +123,10 @@ class Saori(SAORI):
                    try:
                        scrn_w = gtk.gdk.screen_width()
                        scrn_h = gtk.gdk.screen_height()
-                        return 'SAORI/1.0 200 OK\r\nResult: %d\r\nValue0: %d\r\nValue1: %d\r\n\r\n' % (scrn_w, scrn_w, scrn_h)
+                        return 'SAORI/1.0 200 OK\r\n' \
+                               'Result: %d\r\n' \
+                               'Value0: %d\r\n' \
+                               'Value1: %d\r\n\r\n' % (scrn_w, scrn_w, scrn_h)
                    except:
                         return 'SAORI/1.0 500 Internal Server Error\r\n\r\n'
             elif name == 'WAIT':
@@ -135,8 +148,10 @@ class Saori(SAORI):
             if self.timeout_id is None:
                 self.do_idle_tasks()
             return 'SAORI/1.0 204 No Content\r\n\r\n'
+
     def enqueue_commands(self, command, args):
-       if command in ['MOVE', 'MOVE_INSIDE', 'MOVETO', 'MOVETO_INSIDE', 'ZMOVE', 'WAIT', 'NOTIFY']:
+       if command in ['MOVE', 'MOVE_INSIDE', 'MOVETO', 'MOVETO_INSIDE',
+                       'ZMOVE', 'WAIT', 'NOTIFY']:
             if args[0] == self.sakura_name: ## FIXME: HWND
                self.commands[0].append([command, args[1:]])
             elif args[0] == self.kero_name: ## FIXME: HWND
@@ -153,9 +168,10 @@ class Saori(SAORI):
                self.commands[0] = []
             elif args[0] == self.kero_name: ## FIXME: HWND
                self.commands[1] = []
+
     def do_idle_tasks(self):
        for side in [0, 1]:
-            if len(self.commands[side]) > 0:
+            if self.commands[side]:
                command, args = self.commands[side].pop(0)
                if command in ['MOVE', 'MOVE_INSIDE']:
                     x, y = self.__ghost.get_surface_position(side)
@@ -170,11 +186,15 @@ class Saori(SAORI):
                            vx = max(scrn_w - w - x, 0)
                    if abs(vx) > speed:
                        if vx > 0:
-                           self.__ghost.set_surface_position(side, x + speed, y)
-                           self.commands[side].insert(0, [command, [str(vx-speed), args[1]]])
+                           self.__ghost.set_surface_position(
+                                side, x + speed, y)
+                           self.commands[side].insert(
+                                0, [command, [str(vx - speed), args[1]]])
                        elif vx < 0:
-                           self.__ghost.set_surface_position(side, x - speed, y)
-                           self.commands[side].insert(0, [command, [str(vx+speed), args[1]]])
+                           self.__ghost.set_surface_position(
+                                side, x - speed, y)
+                           self.commands[side].insert(
+                                0, [command, [str(vx + speed), args[1]]])
                    else:
                        self.__ghost.set_surface_position(side, x + vx, y)
                elif command in ['MOVETO', 'MOVETO_INSIDE']:
@@ -190,10 +210,12 @@ class Saori(SAORI):
                            to = scrn_w - w
                    if abs(to - x) > speed:
                        if to - x > 0:
-                           self.__ghost.set_surface_position(side, x + speed, y)
+                           self.__ghost.set_surface_position(
+                                side, x + speed, y)
                            self.commands[side].insert(0, [command, args])
                        elif to - x < 0:
-                           self.__ghost.set_surface_position(side, x - speed, y)
+                           self.__ghost.set_surface_position(
+                                side, x - speed, y)
                            self.commands[side].insert(0, [command, args])
                    else:
                        self.__ghost.set_surface_position(side, to, y)
@@ -217,7 +239,7 @@ class Saori(SAORI):
                        self.commands[side].insert(0, ['WAIT', str(wait - 20)])
                elif command == 'NOTIFY':
                    apply(self.__ghost.notify_event, args)
-        if len(self.commands[0]) == 0 and len(self.commands[1]) == 0:
+        if not self.commands[0] and not self.commands[1]:
            if self.timeout_id is not None:
                 gobject.source_remove(self.timeout_id)
                 self.timeout_id = None
index 7c149a4..fb402d4 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: UTF-8 -*-
 #
 #  Copyright (C) 2001, 2002 by Tamito KAJIYAMA
-#  Copyright (C) 2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2004, 2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: entry_db.py,v 1.7 2004/06/23 05:57:04 shy Exp $
+# $Id: entry_db.py,v 1.8 2005/08/09 00:41:52 shy Exp $
 #
 
 import random
 
+
 class EntryDatabase:
+
     def __init__(self, db=None):
         self.__db = db or {}
+
     def add(self, id, script):
         entries = self.__db.get(id, [])
         entries.append(script)
         self.__db[id] = entries
+
     def get(self, id, default=None):
         entries = self.__db.get(id, [default])
         return random.choice(entries)
+
     def is_empty(self):
         return not self.__db
 
+
 def test():
     entry_db = EntryDatabase()
-    print "is_empty() =", entry_db.is_empty()
-    entry_db.add("#temp0", "\hふーん。\e")
-    entry_db.add("#temp0", "\hそうなのかぁ。\e")
-    entry_db.add("#temp0", "\hほうほう。\e")
-    entry_db.add("#temp2", "\hいい感じだね。\e")
-    entry_db.add("#temp3", "\hなるほど。\e")
+    print 'is_empty() =', entry_db.is_empty()
+    entry_db.add('#temp0', '\hふーん。\e')
+    entry_db.add('#temp0', '\hそうなのかぁ。\e')
+    entry_db.add('#temp0', '\hほうほう。\e')
+    entry_db.add('#temp2', '\hいい感じだね。\e')
+    entry_db.add('#temp3', '\hなるほど。\e')
     for i in range(5):
-        print "#temp0", entry_db.get("#temp0")
-    for id in ["#temp1", "#temp2", "#temp3"]:
+        print '#temp0', entry_db.get('#temp0')
+    for id in ['#temp1', '#temp2', '#temp3']:
         print id, entry_db.get(id)
-    print "is_empty() =", entry_db.is_empty()
+    print 'is_empty() =', entry_db.is_empty()
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     test()
index ac1deb8..38154bf 100644 (file)
 #
 
 import os
-import string
 import sys
 import time
 import random
 import StringIO
 import codecs
 
-if os.environ.has_key("DISPLAY"):
+if os.environ.has_key('DISPLAY'):
     import gtk ## FIXME
     import gobject
 
@@ -30,11 +29,12 @@ import ninix.update
 import ninix.sakura
 import ninix.version
 
+
 class Ghost:
 
     def __init__(self, app, data, default_path, communicate, debug=0):
         self.app = app
-        self.char = 2 # "sakura" and "kero"
+        self.char = 2 # 'sakura' and 'kero'
         self.__sender = 'ninix-aya'
         self.__sakura  = ninix.sakura.Sakura(debug)
         self.__sakura.set_ghost(self)
@@ -56,11 +56,13 @@ class Ghost:
         self.__charset = 'Shift_JIS'
         self.top_margin = 0
         self.bottom_margin = 0
-        desc, shiori_dir, use_makoto, surface_set, balloon, prefix, shiori_dll, shiori_name = data
-        self.new(desc, shiori_dir, use_makoto, surface_set, balloon, prefix, shiori_dll, shiori_name) ## FIXME
+        desc, shiori_dir, use_makoto, surface_set, balloon, prefix, \
+              shiori_dll, shiori_name = data
+        self.new(desc, shiori_dir, use_makoto, surface_set, balloon, prefix,
+                 shiori_dll, shiori_name) ## FIXME
 
     def notify_communicate(self, sender, sentence):
-        self.__sakura.enqueue_event("OnCommunicate", sender, sentence)
+        self.__sakura.enqueue_event('OnCommunicate', sender, sentence)
 
     def notify_surface_drag(self, side, x_delta, y_delta): ## FIXME
         if self.__sakura.passivemode:
@@ -76,11 +78,15 @@ class Ghost:
 
     def notify_surface_click(self, button, click, side, x, y): ## FIXME
         self.notify_observer('raise', (side)) ## FIXME: automagical raise 
-        if button == 1 and self.__sakura.mouse_button1 == ninix.sakura.BUTTON1_RAISE or \
-           button == 3 and self.__sakura.mouse_button3 == ninix.sakura.BUTTON3_RAISE:
+        if button == 1 and \
+           self.__sakura.mouse_button1 == ninix.sakura.BUTTON1_RAISE or \
+           button == 3 and \
+           self.__sakura.mouse_button3 == ninix.sakura.BUTTON3_RAISE:
             self.raise_all()
-        elif button == 1 and self.__sakura.mouse_button1 == ninix.sakura.BUTTON1_LOWER or \
-             button == 3 and self.__sakura.mouse_button3 == ninix.sakura.BUTTON3_LOWER:
+        elif button == 1 and \
+             self.__sakura.mouse_button1 == ninix.sakura.BUTTON1_LOWER or \
+             button == 3 and \
+             self.__sakura.mouse_button3 == ninix.sakura.BUTTON3_LOWER:
             self.lower_all()
         if self.__sakura.vanished:
             if side == 0 and button == 1:
@@ -88,7 +94,7 @@ class Ghost:
                     self.__sakura.sstp_request_handler.send_sstp_break()
                     self.__sakura.sstp_request_handler = None
                 self.__sakura.reset_script(1)
-                self.__sakura.notify_event("OnVanishButtonHold", default=r"\e")
+                self.__sakura.notify_event('OnVanishButtonHold', default=r'\e')
                 self.__sakura.vanished = 0
             return
         if self.updateman.is_active():
@@ -98,10 +104,12 @@ class Ghost:
         if self.__sakura.time_critical_session:
             return
         elif button in [1, 3] and click == 1:
-            if self.__sakura.passivemode and self.__sakura.processed_script is not None:
+            if self.__sakura.passivemode and \
+               self.__sakura.processed_script is not None:
                 return
             part = self.__surface.get_touched_region(side, x, y)
-            self.__sakura.notify_event("OnMouseClick", x, y, 0, side, part, button)
+            self.__sakura.notify_event('OnMouseClick',
+                                       x, y, 0, side, part, button)
         elif self.__sakura.passivemode:
             return
         elif button == 1 and click == 2:
@@ -109,7 +117,8 @@ class Ghost:
                 self.__sakura.sstp_request_handler.send_sstp_break()
                 self.__sakura.sstp_request_handler = None
             part = self.__surface.get_touched_region(side, x, y)
-            self.__sakura.notify_event("OnMouseDoubleClick", x, y, "", side, part)
+            self.__sakura.notify_event('OnMouseDoubleClick',
+                                       x, y, '', side, part)
 
     def position_all(self): ## FIXME
         self.__surface.reset_position()
@@ -224,8 +233,10 @@ class Ghost:
         x, y = self.get_surface_position(side)
         w, h = self.__surface.get_surface_size(side)
         if baseposition == 0 or baseposition not in [1, 2, 3]: # AKF
-            centerx = self.__surface.get_config_int(side, 'point.kinoko.centerx')
-            centery = self.__surface.get_config_int(side, 'point.kinoko.centery')
+            centerx = self.__surface.get_config_int(side,
+                                                    'point.kinoko.centerx')
+            centery = self.__surface.get_config_int(side,
+                                                    'point.kinoko.centery')
             if centerx is None or centery is None:
                 rect = self.__surface.get_collision_area(side, 'head')
                 if rect is not None:
@@ -409,9 +420,9 @@ class Ghost:
     def set_surface(self, desc, alias, surface, name, dir):
         self.__surface.new(desc, alias, surface, name, dir)
         for side in range(2, self.char):
-            default = self.desc.get("char%d.seriko.defaultsurface" % side)
+            default = self.desc.get('char%d.seriko.defaultsurface' % side)
             self.__surface.add_window(side, default)
-        icon = self.desc.get("icon", None)
+        icon = self.desc.get('icon', None)
         if icon is not None:
             icon_path = os.path.join(self.shiori_dir, icon)
             if not os.path.exists(icon_path):
@@ -466,14 +477,14 @@ class Ghost:
         if not self.__sakura.passivemode:
             self.__sakura.reset_script(1)
             self.__sakura.stand_by(1)
-            self.__sakura.notify_event("OnWindowStateMinimize")
+            self.__sakura.notify_event('OnWindowStateMinimize')
         self.notify_observer('iconified')
 
     def notify_deiconified(self):
         if self.__sakura.cantalk == 0:
             self.__sakura.set_cantalk(1)
             if not self.__sakura.passivemode:
-                self.__sakura.notify_event("OnWindowStateRestore")
+                self.__sakura.notify_event('OnWindowStateRestore')
         self.notify_observer('deiconified')
 
     def notify_event(self, event, *arglist, **argdict): ## FIXME
@@ -509,7 +520,7 @@ class Ghost:
     def get_own_balloon_name(self):
         if self.own_balloon:
             desc, balloon = self.own_balloon
-            name = desc.get('name', unicode(_("Own Balloon"), 'utf-8'))
+            name = desc.get('name', unicode(_('Own Balloon'), 'utf-8'))
         else:
             name = None
         return name
@@ -540,7 +551,8 @@ class Ghost:
             if getattr(self.shiori, 'show_description', None):
                 self.shiori.show_description()
         else:
-            sys.stderr.write('%s cannot load SHIORI(%s)\n' % (self.get_selfname(), self.shiori_name))
+            sys.stderr.write('%s cannot load SHIORI(%s)\n' % \
+                             (self.get_selfname(), self.shiori_name))
         self.__charset = 'Shift_JIS' # default
         charset = self.get_event_response('charset')
         if charset:
@@ -558,7 +570,8 @@ class Ghost:
                                 ninix.version.NUMBER,
                                 type='NOTIFY')
 
-    def new(self, desc, shiori_dir, use_makoto, surface_set, balloon, prefix, shiori_dll, shiori_name): ## FIXME
+    def new(self, desc, shiori_dir, use_makoto, surface_set, balloon, prefix,
+            shiori_dll, shiori_name): ## FIXME
         self.shiori = None
         self.desc = desc
         self.shiori_dir = shiori_dir
@@ -572,12 +585,12 @@ class Ghost:
         self.shiori = self.__dll.request(name)
         self.updateman = ninix.update.NetworkUpdate(self.__sakura)
         char = 2
-        while self.desc.get("char%d.seriko.defaultsurface" % char) is not None:
+        while self.desc.get('char%d.seriko.defaultsurface' % char) is not None:
             char += 1
         if char > 2:
             self.char = char
         # XXX
-        if self.desc.get('name') == "BTH小っちゃいってことは便利だねっ":
+        if self.desc.get('name') == 'BTH小っちゃいってことは便利だねっ':
             self.set_SSP_mode(1)
         else:
             self.set_SSP_mode(0)
@@ -589,15 +602,16 @@ class Ghost:
             default = ninix.version.VERSION_INFO
         if init:
             if self.get_ghost_time() == 0:
-                if not self.__sakura.notify_event("OnFirstBoot", self.get_vanished_count()):
-                    self.__sakura.notify_event("OnBoot", default=default)
+                if not self.__sakura.notify_event('OnFirstBoot',
+                                                  self.get_vanished_count()):
+                    self.__sakura.notify_event('OnBoot', default=default)
             else:
-                self.__sakura.notify_event("OnBoot", default=default)
-            self.__sakura.notify_event("OnDisplayChange",
+                self.__sakura.notify_event('OnBoot', default=default)
+            self.__sakura.notify_event('OnDisplayChange',
                                        gtk.gdk.visual_get_best_depth(),
                                        gtk.gdk.screen_width(),
                                        gtk.gdk.screen_height(),
-                                       type="NOTIFY")
+                                       type='NOTIFY')
         elif vanished:
             self.notify_ghost_changed(name, vanished, default)
         elif ghost_changed:
@@ -605,7 +619,8 @@ class Ghost:
         else:
             self.notify_shell_changed(name, path)
 
-    def start(self, item, init, temp, vanished, ghost_changed, ignore_default, prev_name):
+    def start(self, item, init, temp, vanished, ghost_changed, ignore_default,
+              prev_name):
         if self.is_running():
             if temp:
                 self.enter_temp_mode()
@@ -613,7 +628,8 @@ class Ghost:
                 if self.__temp_mode == 1:
                     self.__temp_mode = 2
                     self.load_shiori()
-                    self.notify_start(init, vanished, ghost_changed, prev_name, '')
+                    self.notify_start(init, vanished, ghost_changed,
+                                      prev_name, '')
             return
         self.set_ghost_time(0)
         self.set_vanished_count(0)
@@ -621,31 +637,35 @@ class Ghost:
         self.__temp_mode = temp
         self.current = item
         type, i, j = item
-        if type == "g":
-            print "ghost", item
+        if type == 'g':
+            print 'ghost', item
             if not self.surface_set:
                 shell_name, surface_set, balloon = self.app.request_shell(0)
-                name, surface_dir, surface_desc, surface_alias, surface = surface_set[0]
+                name, surface_dir, surface_desc, surface_alias, surface = \
+                      surface_set[0]
                 surface_set = None
             else:
-                name, surface_dir, surface_desc, surface_alias, surface = self.surface_set[j]
+                name, surface_dir, surface_desc, surface_alias, surface = \
+                      self.surface_set[j]
                 surface_set = self.surface_set
                 balloon = self.own_balloon
-        elif type == "s":
-            print "shell", item
+        elif type == 's':
+            print 'shell', item
             shell_name, surface_set, balloon = self.app.request_shell(i)
-            name, surface_dir, surface_desc, surface_alias, surface = surface_set[j]
+            name, surface_dir, surface_desc, surface_alias, surface = \
+                  surface_set[j]
         if not surface_set:
             surface_name = None
         elif len(surface_set) == 1:
-            surface_name = unicode(_("Master"), 'utf-8')
+            surface_name = unicode(_('Master'), 'utf-8')
         else:
             surface_name = name
         if ghost_changed:
             name = prev_name
-        self.set_surface(surface_desc, surface_alias, surface, surface_name, surface_dir)
+        self.set_surface(surface_desc, surface_alias, surface, surface_name,
+                         surface_dir)
         if ignore_default or not balloon:
-            balloon_name = self.desc.get("balloon", "")
+            balloon_name = self.desc.get('balloon', '')
             number = None
             if balloon_name:
                 number = self.app.find_balloon_by_name(balloon_name)
@@ -665,9 +685,9 @@ class Ghost:
     def save_history(self):
         path = os.path.join(self.get_prefix(), 'HISTORY')
         try:
-            file = open(path, "w")
+            file = open(path, 'w')
         except IOError, (code, message):
-            sys.stderr.write("cannot write %s\n" % path)
+            sys.stderr.write('cannot write %s\n' % path)
         else:
             time = self.get_ghost_time()
             vanished_count = self.get_vanished_count()
@@ -681,15 +701,15 @@ class Ghost:
             ghost_time = 0
             ghost_vanished_count = 0
             try:
-                file = open(path, "r")
+                file = open(path, 'r')
             except IOError, (code, message):
-                sys.stderr.write("cannot read %s\n" % path)
+                sys.stderr.write('cannot read %s\n' % path)
             else:
                 for line in file:
                     comma = line.find(',')
                     if comma >= 0:
                         key = line[:comma].strip()
-                        value = line[comma+1:].strip()
+                        value = line[comma + 1:].strip()
                     if key == 'time':
                         try:
                             ghost_time = int(value)
@@ -715,13 +735,13 @@ class Ghost:
             if self.use_makoto:
                 s = ninix.makoto.execute(s)
             else:
-                r = self.get_event_response("OnTranslate", s, translate=0)
+                r = self.get_event_response('OnTranslate', s, translate=0)
                 if r:
                     s = r
         return s
 
     def getaistringrandom(self): # obsolete
-        result = self.get_event_response("OnAITalk")
+        result = self.get_event_response('OnAITalk')
         return self.translate(result)
 
     def getdms(self):
@@ -736,22 +756,29 @@ class Ghost:
         return self.get_event_response(name)
 
     def get_name(self):
-        return self.desc.get("name", unicode(_("Sakura&Unyuu"), 'utf-8'))
+        return self.desc.get('name', unicode(_('Sakura&Unyuu'), 'utf-8'))
 
     def get_username(self):
-        return self.getstring("username") or self.__surface.get_username() or self.desc.get("user.defaultname", unicode(_("User"), 'utf-8'))
+        return self.getstring('username') or \
+               self.__surface.get_username() or \
+               self.desc.get('user.defaultname', unicode(_('User'), 'utf-8'))
 
     def get_selfname(self):
-        return self.__surface.get_selfname() or self.desc.get("sakura.name", unicode(_("Sakura"), 'utf-8'))
+        return self.__surface.get_selfname() or \
+               self.desc.get('sakura.name', unicode(_('Sakura'), 'utf-8'))
 
     def get_selfname2(self):
-        return self.__surface.get_selfname2() or self.desc.get("sakura.name2", unicode(_("Sakura"), 'utf-8'))
+        return self.__surface.get_selfname2() or \
+               self.desc.get('sakura.name2', unicode(_('Sakura'), 'utf-8'))
 
     def get_keroname(self):
-        return self.__surface.get_keroname() or self.desc.get("kero.name", unicode(_("Unyuu"), 'utf-8'))
+        return self.__surface.get_keroname() or \
+               self.desc.get('kero.name', unicode(_('Unyuu'), 'utf-8'))
 
     def get_friendname(self):
-        return self.__surface.get_friendname() or self.desc.get("sakura.friend.name", unicode(_("Tomoyo"), 'utf-8'))
+        return self.__surface.get_friendname() or \
+               self.desc.get('sakura.friend.name',
+                             unicode(_('Tomoyo'), 'utf-8'))
 
     def set_SSP_mode(self, flag): # XXX
         if flag:
@@ -767,14 +794,16 @@ class Ghost:
         ref = arglist
         type = argdict.get('type', 'GET')
         translate = argdict.get('translate', 1)
-        header = '%s SHIORI/3.0\r\n' % type + \
-                 'ID: %s\r\n' % event + \
-                 'Sender: %s\r\n' % self.__sender + \
-                 'SecurityLevel: local\r\n'
+        header = ''.join(('%s SHIORI/3.0\r\n' % type,
+                          'ID: %s\r\n' % event,
+                          'Sender: %s\r\n' % self.__sender,
+                          'SecurityLevel: local\r\n'))
         for i in range(len(ref)):
             if ref[i] is not None:
-                header += 'Reference' + str(i) + ': ' + str(ref[i]) + '\r\n'
-        header += '\r\n'
+                header = ''.join((header,
+                                  'Reference', str(i), ': ',
+                                  str(ref[i]), '\r\n'))
+        header = ''.join((header, '\r\n'))
         header = header.encode(self.__charset, 'ignore')
         response = self.shiori.request(header)
         if self.__sakura.cantalk:
@@ -783,12 +812,13 @@ class Ghost:
                 result = self.translate(result)
         else:
             result, to = '', None
-        if self.__temp_mode == 2 and event != "charset":
+        if self.__temp_mode == 2 and event != 'charset':
             result, to = '', None
         if result is None:
             result = ''
         if to and result:
-            self.communicate.send_message(to, self.__sakura.get_selfname(), result)
+            self.communicate.send_message(to, self.__sakura.get_selfname(),
+                                          result)
         return result
 
     def get_value(self, response): # FIXME: check return code
@@ -804,7 +834,7 @@ class Ghost:
             colon = line.find(':')
             if colon >= 0:
                 key = line[:colon].strip()
-                result[key] = line[colon+1:].strip()
+                result[key] = line[colon + 1:].strip()
             else:
                 continue
         for key in result.keys():
@@ -823,14 +853,17 @@ class Ghost:
     def update(self):
         if self.updateman.is_active():
             return
-        homeurl = self.getstring("homeurl")
+        homeurl = self.getstring('homeurl')
         if not homeurl:
-            self.__sakura.start_script(r"\t\h\s[0]" + unicode(_("I'm afraid I don't have Network Update yet."), 'utf-8') + r"\e")
+            self.__sakura.start_script(
+                ''.join((r'\t\h\s[0]',
+                         unicode(_("I'm afraid I don't have Network Update yet."), 'utf-8'),
+                         r'\e')))
             self.__sakura.balloon.hide_sstp_message()
             return
         ghostdir = self.get_prefix()
-        print "homeurl =", homeurl
-        print "ghostdir =", ghostdir
+        print 'homeurl =', homeurl
+        print 'ghostdir =', ghostdir
         self.updateman.start(homeurl, ghostdir)
 
     def quit(self):
@@ -862,7 +895,7 @@ class Ghost:
         self.set_balloon(desc, balloon)
         self.__sakura.set_balloon(self.__balloon)
         self.__balloon.set_balloon_default()
-        print "balloon", item
+        print 'balloon', item
 
     def enter_temp_mode(self):
         if not self.__temp_mode:
@@ -885,7 +918,8 @@ class Ghost:
             self.__sakura.process_script()
             if not self.__sakura.busy() and \
                not self.__sakura.script_queue and \
-               not (self.__sakura.processed_script or self.__sakura.processed_text):
+               not (self.__sakura.processed_script or \
+                    self.__sakura.processed_text):
                 if self.__temp_mode == 1:
                     time.sleep(1.4)
                     self.finalize()
@@ -899,7 +933,8 @@ class Ghost:
             else:
                 return True
         if self.reload_event and not self.__sakura.busy() and \
-           not (self.__sakura.processed_script or self.__sakura.processed_text):
+           not (self.__sakura.processed_script or \
+                self.__sakura.processed_text):
             self.hide_all()
             sys.stdout.write('reloading....\n')
             self.shiori.unload() ## FIXME
@@ -927,14 +962,14 @@ class Ghost:
         title, url = args
         if self.__sakura.is_URL(url):
             self.__sakura.launch_browser(url)
-        self.__sakura.enqueue_event("OnRecommandedSiteChoice", title, url)
+        self.__sakura.enqueue_event('OnRecommandedSiteChoice', title, url)
 
     def close(self):
         if self.busy():
             gtk.gdk.beep() ## FIXME
             return
         self.__sakura.reset_script(1)
-        self.__sakura.enqueue_event("OnClose")
+        self.__sakura.enqueue_event('OnClose')
 
     def about(self):
         if self.__sakura.busy():
@@ -959,23 +994,23 @@ class VanishDialog:
     def __init__(self, ghost):
         self.__ghost = ghost
         self.window = gtk.Dialog()
-        self.window.connect("delete_event", self.cancel)
-        self.window.set_title("Vanish")
+        self.window.connect('delete_event', self.cancel)
+        self.window.set_title('Vanish')
         self.window.set_modal(True)
         self.window.set_position(gtk.WIN_POS_CENTER)
-        self.label = gtk.Label(unicode(_("Vanish"), 'utf-8'))
+        self.label = gtk.Label(unicode(_('Vanish'), 'utf-8'))
         self.window.vbox.pack_start(self.label, padding=10)
         self.label.show()
         box = gtk.HButtonBox()
         box.set_layout(gtk.BUTTONBOX_END)
         self.window.action_area.pack_start(box)
         box.show()
-        button = gtk.Button(unicode(_("Yes"), 'utf-8'))
-        button.connect("clicked", self.ok)
+        button = gtk.Button(unicode(_('Yes'), 'utf-8'))
+        button.connect('clicked', self.ok)
         box.add(button)
         button.show()
-        button = gtk.Button(unicode(_("No"), 'utf-8'))
-        button.connect("clicked", self.cancel)
+        button = gtk.Button(unicode(_('No'), 'utf-8'))
+        button.connect('clicked', self.cancel)
         box.add(button)
         button.show()
 
@@ -995,8 +1030,9 @@ class VanishDialog:
         self.__ghost.notify_vanish_confirmation(0)
         return True
 
+
 def test():
     pass
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     test()
index 6204495..118b1f7 100644 (file)
@@ -2,7 +2,7 @@
 #
 #  Copyright (C) 2001, 2002 by Tamito KAJIYAMA
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
-#  Copyright (C) 2002-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: home.py,v 1.25 2005/03/22 06:08:49 shy Exp $
+# $Id: home.py,v 1.26 2005/08/09 00:41:52 shy Exp $
 #
 
 import os
 import re
-import string
 import sys
 
 import ninix.config
 import ninix.alias
 import ninix.dll
 
-NINIX_HOME = "~/.ninix"
+NINIX_HOME = '~/.ninix'
 NINIX_USER = None
 
 def print_error(message):
-    sys.stderr.write(message + "\n")
+    sys.stderr.write(''.join((message, '\n')))
 
 def get_ninix_home():
     return os.path.expanduser(NINIX_HOME)
@@ -38,16 +37,16 @@ def get_ninix_user():
     return os.path.expanduser(NINIX_USER)
 
 def get_gtkrc():
-    path = os.path.join(get_ninix_user(), "gtkrc")
+    path = os.path.join(get_ninix_user(), 'gtkrc')
     if os.path.exists(path):
         return path
-    return os.path.join(get_ninix_home(), "gtkrc")
+    return os.path.join(get_ninix_home(), 'gtkrc')
 
 def get_pango_fontrc():
-    return os.path.join(get_ninix_user(), "pango_fontrc")
+    return os.path.join(get_ninix_user(), 'pango_fontrc')
 
 def get_preferences():
-    return os.path.join(get_ninix_user(), "preferences")
+    return os.path.join(get_ninix_user(), 'preferences')
 
 def load_config():
     home_dir = get_ninix_home()
@@ -67,9 +66,9 @@ def get_shiori(path):
     for file in os.listdir(path):
         if is_readable(os.path.join(path, file)):
             name = None
-            if file[-3:] == '.py':
+            if file.endswith('.py'):
                 name =  file[:-3]
-            elif file[-4:] == '.pyc':
+            elif file.endswith('.pyc'):
                 name =  file[:-4]
             if name and not table.has_key(name):
                 shiori = shiori_lib.request(('', name))
@@ -85,13 +84,14 @@ def search_ghosts(home_dir, target=None):
         dirlist.extend(target)
     else:
         try:
-            dirlist = os.listdir(os.path.join(home_dir, "ghost"))
+            dirlist = os.listdir(os.path.join(home_dir, 'ghost'))
         except OSError:
             dirlist = []
-    shiori_table = get_shiori(os.path.join(os.environ['PYTHONPATH'], 'ninix/dll'))
+    shiori_table = get_shiori(
+        os.path.join(os.environ['PYTHONPATH'], 'ninix/dll'))
     for subdir in dirlist:
-        prefix = os.path.join(home_dir, "ghost", subdir)
-        ghost_dir = os.path.join(prefix, "ghost", "master")
+        prefix = os.path.join(home_dir, 'ghost', subdir)
+        ghost_dir = os.path.join(prefix, 'ghost', 'master')
         desc = read_descript_txt(ghost_dir)
         if desc is None:
             desc = ninix.config.null_config()
@@ -112,7 +112,7 @@ def search_ghosts(home_dir, target=None):
                 shells.append((shell_name, surface_set, balloon))
             continue
         shiori_name = candidate['name']
-        if desc.get("name") == "default":
+        if desc.get('name') == 'default':
             pos = 0
         else:
             pos = len(ghosts)
@@ -123,7 +123,7 @@ def search_ghosts(home_dir, target=None):
     return ghosts, shells
 
 def search_balloons(home_dir):
-    balloon_dir = os.path.join(home_dir, "balloon")
+    balloon_dir = os.path.join(home_dir, 'balloon')
     try:
         dirlist = os.listdir(balloon_dir)
     except OSError:
@@ -144,7 +144,7 @@ def search_balloons(home_dir):
             continue
         else:
             balloon_info['balloon_dir'] = subdir
-        if desc.get("name") == "default":
+        if desc.get('name') == 'default':
             pos = 0
         else:
             pos = len(buffer)
@@ -153,7 +153,7 @@ def search_balloons(home_dir):
 
 def search_plugins(home_dir):
     buffer = []
-    dir = os.path.join(home_dir, "plugin")
+    dir = os.path.join(home_dir, 'plugin')
     try:
         dirlist = os.listdir(dir)
     except OSError:
@@ -167,7 +167,7 @@ def search_plugins(home_dir):
 
 def search_nekoninni(home_dir): ## FIXME
     buffer = []
-    dir = os.path.join(home_dir, "nekodorif/skin")
+    dir = os.path.join(home_dir, 'nekodorif/skin')
     try:
         dirlist = os.listdir(dir)
     except OSError:
@@ -181,7 +181,7 @@ def search_nekoninni(home_dir): ## FIXME
 
 def search_katochan(home_dir): ## FIXME
     buffer = []
-    dir = os.path.join(home_dir, "nekodorif/katochan")
+    dir = os.path.join(home_dir, 'nekodorif/katochan')
     try:
         dirlist = os.listdir(dir)
     except OSError:
@@ -195,7 +195,7 @@ def search_katochan(home_dir): ## FIXME
 
 def search_kinoko(home_dir):
     buffer = []
-    dir = os.path.join(home_dir, "kinoko")
+    dir = os.path.join(home_dir, 'kinoko')
     try:
         dirlist = os.listdir(dir)
     except OSError:
@@ -234,18 +234,18 @@ def read_kinoko_ini(dir):
             lineno += 1
             if not line.strip():
                 continue
-            pos = line.find("=")
+            pos = line.find('=')
             if pos < 0:
-                error = "line %d: syntax error" % lineno
+                error = 'line %d: syntax error' % lineno
                 break
-            name, value = line[:pos].strip(), line[pos+1:].strip()
-            if name in ["title", "ghost", "category"]:
+            name, value = line[:pos].strip(), line[pos + 1:].strip()
+            if name in ['title', 'ghost', 'category']:
                 kinoko[name] = unicode(value, 'Shift_JIS', 'ignore')
-            elif name in ["offsetx", "offsety"]:
+            elif name in ['offsetx', 'offsety']:
                 kinoko[name] = int(value)
-            elif name in ["base", "animation", "extractpath"]:
+            elif name in ['base', 'animation', 'extractpath']:
                 kinoko[name] = value
-            elif name in ["ontop", "baseposition", "baseadjust"]:
+            elif name in ['ontop', 'baseposition', 'baseadjust']:
                 kinoko[name] = int(value)
         file.close()
     if kinoko['title']:
@@ -279,35 +279,35 @@ def read_katochan_txt(dir): ## FIXME
             lineno += 1
             if not line.strip():
                 continue
-            if line[0] == '#':
+            if line.startswith('#'):
                 name = line[1:].strip()
                 continue
             elif not name:
-                error = "line %d: syntax error" % lineno
+                error = 'line %d: syntax error' % lineno
                 break
             else:
                 value = line.strip()
-                if name in ["name", "category", "before.script", "hit.script",
-                            "after.script", "end.script", "dodge.script"]:
+                if name in ['name', 'category', 'before.script', 'hit.script',
+                            'after.script', 'end.script', 'dodge.script']:
                     katochan[name] = unicode(value, 'Shift_JIS', 'ignore')
-                elif name in ["before.fall.speed", "before.slide.magnitude",
-                              "before.slide.sinwave.degspeed",
-                              "before.appear.ofset.x",
-                              "before.appear.ofset.y",
-                              "hit.waittime", "hit.ofset.x", "hit.ofset.y",
-                              "after.fall.speed", "after.slide.magnitude",
-                              "after.slide.sinwave.degspeed"]:
+                elif name in ['before.fall.speed', 'before.slide.magnitude',
+                              'before.slide.sinwave.degspeed',
+                              'before.appear.ofset.x',
+                              'before.appear.ofset.y',
+                              'hit.waittime', 'hit.ofset.x', 'hit.ofset.y',
+                              'after.fall.speed', 'after.slide.magnitude',
+                              'after.slide.sinwave.degspeed']:
                     katochan[name] = int(value)
-                elif name in ["target",
-                              "before.fall.type", "before.slide.type",
-                              "before.wave", "before.wave.loop",
-                              "before.appear.direction",
-                              "hit.wave", "hit.wave.loop",
-                              "after.fall.type", "after.slide.type",
-                              "after.wave", "after.wave.loop",
-                              "end.wave", "end.wave.loop",
-                              "end.leave.direction",
-                              "dodge.wave", "dodge.wave.loop"]:
+                elif name in ['target',
+                              'before.fall.type', 'before.slide.type',
+                              'before.wave', 'before.wave.loop',
+                              'before.appear.direction',
+                              'hit.wave', 'hit.wave.loop',
+                              'after.fall.type', 'after.slide.type',
+                              'after.wave', 'after.wave.loop',
+                              'end.wave', 'end.wave.loop',
+                              'end.leave.direction',
+                              'dodge.wave', 'dodge.wave.loop']:
                     katochan[name] = value
                 name = None
         file.close()
@@ -317,46 +317,46 @@ def read_katochan_txt(dir): ## FIXME
         return None
 
 def read_descript_txt(dir):
-    path = os.path.join(dir, "descript.txt")
+    path = os.path.join(dir, 'descript.txt')
     if is_readable(path):
         return ninix.config.open(path)
     return None
 
 def read_install_txt(dir):
-    path = os.path.join(dir, "install.txt")
+    path = os.path.join(dir, 'install.txt')
     if is_readable(path):
         return ninix.config.open(path)
     return None
 
 def read_alias_txt(dir):
-    path = os.path.join(dir, "alias.txt")
+    path = os.path.join(dir, 'alias.txt')
     if is_readable(path):
         return ninix.alias.open(path)
     return None
 
 def find_makoto_dll(dir):
-    if is_readable(os.path.join(dir, "makoto.dll")):
+    if is_readable(os.path.join(dir, 'makoto.dll')):
         return 1
     return 0
 
 def find_surface_set(dir):
-    desc = read_descript_txt(os.path.join(dir, "ghost", "master"))
+    desc = read_descript_txt(os.path.join(dir, 'ghost', 'master'))
     if desc:
-        shell_name = desc.get("name")
+        shell_name = desc.get('name')
     else:
         shell_name = None
     if not shell_name:
         inst = read_install_txt(dir)
         if inst:
-            shell_name = inst.get("name")
+            shell_name = inst.get('name')
     surface_set = []
-    shell_dir = os.path.join(dir, "shell")
+    shell_dir = os.path.join(dir, 'shell')
     for name, desc, subdir in find_surface_dir(shell_dir):
         surface_dir = os.path.join(shell_dir, subdir)
         surface_info, alias = read_surface_info(surface_dir)
         if surface_info and \
-           surface_info.has_key("surface0") and \
-           surface_info.has_key("surface10"):
+           surface_info.has_key('surface0') and \
+           surface_info.has_key('surface10'):
             if alias is None:
                 alias = read_alias_txt(surface_dir)
             surface_set.append((name, surface_dir, desc, alias, surface_info))
@@ -364,7 +364,7 @@ def find_surface_set(dir):
 
 def find_surface_dir(dir):
     buffer = []
-    path = os.path.join(dir, "surface.txt")
+    path = os.path.join(dir, 'surface.txt')
     if os.path.exists(path):
         config = ninix.config.open(path)
         for name, subdir in config.itemlist:
@@ -381,11 +381,11 @@ def find_surface_dir(dir):
             desc = read_descript_txt(os.path.join(dir, subdir))
             if desc is None:
                 desc = ninix.config.null_config()
-            name = desc.get("name", subdir)
+            name = desc.get('name', subdir)
             buffer.append((name, desc, subdir))
     return buffer
 
-re_surface = re.compile("surface([0-9]+)\.(png|dgp)")
+re_surface = re.compile('surface([0-9]+)\.(png|dgp)')
 
 def read_surface_info(surface_dir):
     surface = {}
@@ -394,17 +394,18 @@ def read_surface_info(surface_dir):
     except OSError:
         filelist = []
     filename_alias = {}
-    path = os.path.join(surface_dir, "alias.txt")
+    path = os.path.join(surface_dir, 'alias.txt')
     if os.path.exists(path):
         dict = ninix.alias.open(path)
         for basename, alias in dict.items():
-            if basename[:7] == "surface":
+            if basename.startswith('surface'):
                 filename_alias[alias] = basename
     # find png image and associated configuration file
     for filename in filelist:
         basename, suffix = os.path.splitext(filename)
         if filename_alias.has_key(basename):
-            match = re_surface.match(filename_alias[basename] + suffix)
+            match = re_surface.match(
+                ''.join((filename_alias[basename], suffix)))
         else:
             match = re_surface.match(filename)
         if not match:
@@ -412,22 +413,22 @@ def read_surface_info(surface_dir):
         img = os.path.join(surface_dir, filename)
         if not is_readable(img):
             continue
-        key = "surface" + str(int(match.group(1)))
-        txt = os.path.join(surface_dir, basename + "s.txt")
+        key = ''.join(('surface', str(int(match.group(1)))))
+        txt = os.path.join(surface_dir, ''.join((basename, 's.txt')))
         if is_readable(txt):
             config = ninix.config.open(txt)
         else:
             config = ninix.config.null_config()
-        txt = os.path.join(surface_dir, basename + "a.txt")
+        txt = os.path.join(surface_dir, ''.join((basename, 'a.txt')))
         if is_readable(txt):
             config.update(ninix.config.open(txt))
         surface[key] = (img, config)
     # find surfaces.txt
     alias = None
     for key, config in read_surfaces_txt(surface_dir):
-        if key == "__alias__":
+        if key == '__alias__':
             alias = config
-        elif key[:7] == "surface":
+        elif key.startswith('surface'):
             try:
                 img, null_config = surface[key]
             except KeyError:
@@ -446,7 +447,7 @@ def read_surface_info(surface_dir):
 
 def read_surfaces_txt(surface_dir):
     list = []
-    path = os.path.join(surface_dir, "surfaces.txt")
+    path = os.path.join(surface_dir, 'surfaces.txt')
     try:
         file = open(path)
     except IOError:
@@ -456,7 +457,7 @@ def read_surfaces_txt(surface_dir):
         line = file.readline()
         if not line:
             break
-        if line[0] == "#" or line[:2] == "//":
+        if line.startswith('#') or line.startswith('//'):
             continue
         key = line.strip()
         if not key:
@@ -465,55 +466,55 @@ def read_surfaces_txt(surface_dir):
             while 1:
                 line = file.readline()
                 if not line:
-                    raise ValueError, "unexpected end of file"
-                line = line.replace("\x81\x40", "").strip()
+                    raise ValueError, 'unexpected end of file'
+                line = line.replace('\x81\x40', '').strip()
                 if not line:
                     continue
-                elif line == "{":
+                elif line == '{':
                     break
                 key = line # ignore the preceding key
             buffer = []
             while 1:
                 line = file.readline()
                 if not line:
-                    raise ValueError, "unexpected end of file"
-                line = line.replace("\x81\x40", "").strip()
+                    raise ValueError, 'unexpected end of file'
+                line = line.replace('\x81\x40', '').strip()
                 if not line:
                     continue
-                elif line == "}":
+                elif line == '}':
                     break
                 buffer.append(line)
-            if key in ["sakura.surface.alias", "kero.surface.alias"]:
+            if key in ['sakura.surface.alias', 'kero.surface.alias']:
                 alias_buffer.append(key)
-                alias_buffer.append("{")
+                alias_buffer.append('{')
                 alias_buffer.extend(buffer)
-                alias_buffer.append("}")
-            elif key[:7] == "surface":
+                alias_buffer.append('}')
+            elif key.startswith('surface'):
                 try:
-                    key = key[:7] + str(int(key[7:]))
+                    key = ''.join((key[:7], str(int(key[7:]))))
                 except ValueError:
                     pass
                 list.append((key, ninix.config.new_config(buffer)))
         except ValueError, error:
-            print_error("%s: %s (parsing not completed)" % (path, error))
+            print_error('%s: %s (parsing not completed)' % (path, error))
             break
     if alias_buffer:
-        list.append(("__alias__", ninix.alias.new_alias(alias_buffer)))
+        list.append(('__alias__', ninix.alias.new_alias(alias_buffer)))
     return list
 
 def list_surface_elements(config):
     buffer = []
     for n in range(256):
-        key = "element" + str(n)
+        key = ''.join(('element', str(n)))
         if not config.has_key(key):
             break
-        spec = [value.strip() for value in config[key].split(",")]
+        spec = [value.strip() for value in config[key].split(',')]
         try:
             method, filename, x, y = spec
             x = int(x)
             y = int(y)
         except ValueError:
-            print_error("invalid element spec for %s: %s" % (key, config[key]))
+            print_error('invalid element spec for %s: %s' % (key, config[key]))
             continue
         buffer.append((key, method, filename, x, y))
     return buffer
@@ -521,17 +522,17 @@ def list_surface_elements(config):
 def find_balloon(dir):
     inst = read_install_txt(dir)
     if inst:
-        balloon_dir = inst.get("balloon.directory")
+        balloon_dir = inst.get('balloon.directory')
         if balloon_dir:
-            path = os.path.join(dir, "ghost", "master", balloon_dir.lower())
+            path = os.path.join(dir, 'ghost', 'master', balloon_dir.lower())
             desc = read_descript_txt(path)
             info = read_balloon_info(path)
             if desc and info:
                 return (desc, info)
     return None
 
-re_balloon = re.compile("balloon([skc][0-9]+)\.(png)")
-re_annex   = re.compile("(arrow[01]|sstp)\.(png)")
+re_balloon = re.compile('balloon([skc][0-9]+)\.(png)')
+re_annex   = re.compile('(arrow[01]|sstp)\.(png)')
 
 def read_balloon_info(balloon_dir):
     balloon = {}
@@ -544,13 +545,13 @@ def read_balloon_info(balloon_dir):
         if not match:
             continue
         img = os.path.join(balloon_dir, filename)
-        if match.group(2) != "png" and \
-           is_readable(img[-3:] + "png"):
+        if match.group(2) != 'png' and \
+           is_readable(''.join((img[-3:], 'png'))):
                 continue
         if not is_readable(img):
             continue
         key = match.group(1)
-        txt = os.path.join(balloon_dir, "balloon%ss.txt" % key)
+        txt = os.path.join(balloon_dir, 'balloon%ss.txt' % key)
         if is_readable(txt):
             config = ninix.config.open(txt)
         else:
@@ -569,7 +570,7 @@ def read_balloon_info(balloon_dir):
     return balloon
 
 def read_plugin_txt(plugin_dir):
-    path = os.path.join(plugin_dir, "plugin.txt")
+    path = os.path.join(plugin_dir, 'plugin.txt')
     try:
         file = open(path)
     except IOError:
@@ -581,45 +582,45 @@ def read_plugin_txt(plugin_dir):
     lineno = 0
     for line in file:
         lineno += 1
-        if not line.strip() or line[0] == "#":
+        if not line.strip() or line.startswith('#'):
             continue
-        pos = line.find(":")
+        pos = line.find(':')
         if pos < 0:
-            error = "line %d: syntax error" % lineno
+            error = 'line %d: syntax error' % lineno
             break
-        name, value = line[:pos].strip(), line[pos+1:].strip()
-        if name == "charset":
+        name, value = line[:pos].strip(), line[pos + 1:].strip()
+        if name == 'charset':
             charset = value
-        elif name == "name":
+        elif name == 'name':
             plugin_name = unicode(value, charset, 'ignore')
-        elif name == "startup":
-            list = value.split(",")
+        elif name == 'startup':
+            list = value.split(',')
             list[0] = os.path.join(plugin_dir, list[0])
             if not os.path.exists(list[0]):
-                error = "line %d: invalid program name" % lineno
+                error = 'line %d: invalid program name' % lineno
                 break
             startup = list
-        elif name == "menuitem":
-            list = unicode(value, charset, 'ignore').split(",")
+        elif name == 'menuitem':
+            list = unicode(value, charset, 'ignore').split(',')
             if len(list) < 2:
-                error = "line %d: syntax error" % lineno
+                error = 'line %d: syntax error' % lineno
                 break
             list[1] = os.path.join(plugin_dir, list[1])
             if not os.path.exists(list[1]):
-                error = "line %d: invalid program name" % lineno
+                error = 'line %d: invalid program name' % lineno
                 break
             menu_items.append((list[0], list[1:]))
         else:
-            error = "line %d: syntax error" % lineno
+            error = 'line %d: syntax error' % lineno
             break
     else:
         if plugin_name is None:
-            error = 'the "name" header field is required'
+            error = "the 'name' header field is required"
         elif not startup and not menu_items:
-            error = 'either "startup" or "menuitem" header field is required'
+            error = "either 'startup' or 'menuitem' header field is required"
     file.close()
     if error:
-        sys.stderr.write("Error: %s\n%s (skipped)\n" % (error, path))
+        sys.stderr.write('Error: %s\n%s (skipped)\n' % (error, path))
         return None
     return plugin_name, plugin_dir, startup, menu_items
 
@@ -637,102 +638,103 @@ def test():
     locale.setlocale(locale.LC_ALL, '')
     global NINIX_HOME
     try:
-        NINIX_HOME = os.environ["NINIX_HOME"]
+        NINIX_HOME = os.environ['NINIX_HOME']
     except KeyError:
         pass
     config = load_config()
     if config is None:
-        sys.stderr.write("Home directory not found.\n")
+        sys.stderr.write('Home directory not found.\n')
         sys.exit(1)
     ghosts, shells, balloons, plugins, nekoninni, katochan, kinoko = config ## FIXME
     # ghosts
-    for desc, shiori_dir, use_makoto, surface_set, balloon, prefix, shiori_dll, shiori_name in ghosts:
-        print "GHOST", "=" * 50
+    for desc, shiori_dir, use_makoto, surface_set, balloon, prefix, shiori_dll, shiori_name in ghosts: ## FIXME
+        print 'GHOST', '=' * 50
         print prefix
         print str(desc).encode('utf-8', 'ignore')
         print shiori_dir
         print shiori_dll
         print shiori_name
-        print "use_makoto =", use_makoto
+        print 'use_makoto =', use_makoto
         if surface_set:
             for name, dir, desc, alias, surface in surface_set:
-                print "-" * 50
-                print "surface:", name.encode('utf-8', 'ignore')
+                print '-' * 50
+                print 'surface:', name.encode('utf-8', 'ignore')
                 print str(desc).encode('utf-8', 'ignore')
                 for k, v in surface.items():
-                    print k, "=", v[0]
+                    print k, '=', v[0]
                     print str(v[1]).encode('utf-8', 'ignore')
                 if alias:
                     buffer = []
                     for k, v in alias.items():
-                        if k in ["sakura.surface.alias", "kero.surface.alias"]:
-                            print k + ":"
+                        if k in ['sakura.surface.alias', 'kero.surface.alias']:
+                            print ''.join((k, ':'))
                             for id, list in v.items():
-                                print id, "= [" + string.join(list, ", ") + "]"
+                                print id, \
+                                      ''.join(('= [', ', '.join(list), ']'))
                             print
                         else:
                             buffer.append((k, v))
                     if buffer:
-                        print "filename alias:"
+                        print 'filename alias:'
                         for k, v in buffer:
-                            print k, "=", v
+                            print k, '=', v
                         print
         if balloon:
-            print "-" * 50
+            print '-' * 50
             desc, balloon = balloon
             print str(desc).encode('utf-8', 'ignore')
             for k, v in balloon.items():
-                print k, "=", v[0]
+                print k, '=', v[0]
                 print str(v[1]).encode('utf-8', 'ignore')
     # shells
     for shell_name, surface_set, balloon in shells:
-        print "SHELL", "=" * 50
+        print 'SHELL', '=' * 50
         print shell_name.encode('utf-8', 'ignore')
         for name, dir, desc, alias, surface in surface_set:
-            print "-" * 50
-            print "surface:", name.encode('utf-8', 'ignore')
+            print '-' * 50
+            print 'surface:', name.encode('utf-8', 'ignore')
             print str(desc).encode('utf-8', 'ignore')
             for k, v in surface.items():
-                print k, "=", v[0]
+                print k, '=', v[0]
                 print str(v[1]).encode('utf-8', 'ignore')
             if alias:
                 buffer = []
                 for k, v in alias.items():
-                    if k in ["sakura.surface.alias", "kero.surface.alias"]:
-                        print k + ":"
+                    if k in ['sakura.surface.alias', 'kero.surface.alias']:
+                        print ''.join((k, ':'))
                         for id, list in v.items():
-                            print id, "= [" + string.join(list, ", ") + "]"
+                            print id, ''.join(('= [', ', '.join(list), ']'))
                         print
                     else:
                         buffer.append((k, v))
                 if buffer:
-                    print "filename alias:"
+                    print 'filename alias:'
                     for k, v in buffer:
-                        print k, "=", v
+                        print k, '=', v
                     print
         if balloon:
-            print "-" * 50
+            print '-' * 50
             desc, balloon = balloon
             print str(desc).encode('utf-8', 'ignore')
             for k, v in balloon.items():
-                print k, "=", v[0]
+                print k, '=', v[0]
                 print str(v[1]).encode('utf-8', 'ignore')
     # balloons
     for desc, balloon in balloons:
-        print "BALLOON", "=" * 50
+        print 'BALLOON', '=' * 50
         print str(desc).encode('utf-8', 'ignore')
         for k, v in balloon.items():
-            print k, "=", v[0]
+            print k, '=', v[0]
             print str(v[1]).encode('utf-8', 'ignore')
     # plugins
     for plugin_name, plugin_dir, startup, menu_items in plugins:
-        print "PLUGIN", "=" * 50
-        print "name =", plugin_name.encode('utf-8', 'ignore')
+        print 'PLUGIN', '=' * 50
+        print 'name =', plugin_name.encode('utf-8', 'ignore')
         if startup:
-            print "startup =", '["' + string.join(startup, '", "') + '"]'
+            print 'startup =', ''.join(('["', '", "'.join(startup), '"]'))
         for label, argv in menu_items:
-            print 'menuitem "%s" =' % label.encode('utf-8', 'ignore'),
-            print '["' + string.join(argv, '", "') + '"]'
+            print "menuitem '%s' =" % label.encode('utf-8', 'ignore'),
+            print ''.join(('["', '", "'.join(argv), '"]'))
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     test()
index f960dda..89dd120 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: ascii -*-
 #
 #  Copyright (C) 2002 by Tamito KAJIYAMA
-#  Copyright (C) 2003, 2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2003-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
 import gtk
 
 keymap_old = {
-    gtk.keysyms.BackSpace: "",
-    gtk.keysyms.Tab: "",
-    gtk.keysyms.KP_Tab: "",
-    gtk.keysyms.Clear: "",
-    gtk.keysyms.Return: "",
-    gtk.keysyms.KP_Enter: "",
-    gtk.keysyms.Menu: "",
-    gtk.keysyms.Pause: "",
-    gtk.keysyms.Kanji: "",
-    gtk.keysyms.Escape: "",
-    gtk.keysyms.Henkan: "",
-    gtk.keysyms.Muhenkan: "",
-    gtk.keysyms.space: "",
-    gtk.keysyms.Prior: "",
-    gtk.keysyms.Next: "",
-    gtk.keysyms.End: "",
-    gtk.keysyms.Home: "",
-    gtk.keysyms.Left: "",
-    gtk.keysyms.Up: "",
-    gtk.keysyms.Right: "",
-    gtk.keysyms.Down: "",
-    gtk.keysyms.Select: "",
-    gtk.keysyms.Print: "",
-    gtk.keysyms.Execute: "",
-    gtk.keysyms.Insert: "",
-    gtk.keysyms.Delete: "",
-    gtk.keysyms.Help: "",
-    gtk.keysyms._0: "0",
-    gtk.keysyms._1: "1",
-    gtk.keysyms._2: "2",
-    gtk.keysyms._3: "3",
-    gtk.keysyms._4: "4",
-    gtk.keysyms._5: "5",
-    gtk.keysyms._6: "6",
-    gtk.keysyms._7: "7",
-    gtk.keysyms._8: "8",
-    gtk.keysyms._9: "9",
-    gtk.keysyms.a: "a",
-    gtk.keysyms.b: "b",
-    gtk.keysyms.c: "c",
-    gtk.keysyms.d: "d",
-    gtk.keysyms.e: "e",
-    gtk.keysyms.f: "f",
-    gtk.keysyms.g: "g",
-    gtk.keysyms.h: "h",
-    gtk.keysyms.i: "i",
-    gtk.keysyms.j: "j",
-    gtk.keysyms.k: "k",
-    gtk.keysyms.l: "l",
-    gtk.keysyms.m: "m",
-    gtk.keysyms.n: "n",
-    gtk.keysyms.o: "o",
-    gtk.keysyms.p: "p",
-    gtk.keysyms.q: "q",
-    gtk.keysyms.r: "r",
-    gtk.keysyms.s: "s",
-    gtk.keysyms.t: "t",
-    gtk.keysyms.u: "u",
-    gtk.keysyms.v: "v",
-    gtk.keysyms.w: "w",
-    gtk.keysyms.x: "x",
-    gtk.keysyms.y: "y",
-    gtk.keysyms.z: "z",
-    gtk.keysyms.KP_0: "0",
-    gtk.keysyms.KP_1: "1",
-    gtk.keysyms.KP_2: "2",
-    gtk.keysyms.KP_3: "3",
-    gtk.keysyms.KP_4: "4",
-    gtk.keysyms.KP_5: "5",
-    gtk.keysyms.KP_6: "6",
-    gtk.keysyms.KP_7: "7",
-    gtk.keysyms.KP_8: "8",
-    gtk.keysyms.KP_9: "9",
-    gtk.keysyms.KP_Multiply: "*",
-    gtk.keysyms.KP_Add: "+",
-    gtk.keysyms.KP_Separator: "",
-    gtk.keysyms.KP_Subtract: "-",
-    gtk.keysyms.KP_Decimal: "",
-    gtk.keysyms.KP_Divide: "/",
-    gtk.keysyms.F1: "f1",
-    gtk.keysyms.F2: "f2",
-    gtk.keysyms.F3: "f3",
-    gtk.keysyms.F4: "f4",
-    gtk.keysyms.F5: "f5",
-    gtk.keysyms.F6: "f6",
-    gtk.keysyms.F7: "f7",
-    gtk.keysyms.F8: "f8",
-    gtk.keysyms.F9: "f9",
-    gtk.keysyms.F10: "f10",
-    gtk.keysyms.F11: "f11",
-    gtk.keysyms.F12: "f12",
-    gtk.keysyms.F13: "f13",
-    gtk.keysyms.F14: "f14",
-    gtk.keysyms.F15: "f15",
-    gtk.keysyms.F16: "f16",
-    gtk.keysyms.F17: "f17",
-    gtk.keysyms.F18: "f18",
-    gtk.keysyms.F19: "f19",
-    gtk.keysyms.F20: "f20",
-    gtk.keysyms.F21: "f21",
-    gtk.keysyms.F22: "f22",
-    gtk.keysyms.F23: "f23",
-    gtk.keysyms.F24: "f24",
-    gtk.keysyms.Num_Lock: "",
-    gtk.keysyms.Scroll_Lock: "",
-    gtk.keysyms.Shift_L: "",
-    gtk.keysyms.Shift_R: "",
-    gtk.keysyms.Control_L: "",
-    gtk.keysyms.Control_R: "",
+    gtk.keysyms.BackSpace: '',
+    gtk.keysyms.Tab: '',
+    gtk.keysyms.KP_Tab: '',
+    gtk.keysyms.Clear: '',
+    gtk.keysyms.Return: '',
+    gtk.keysyms.KP_Enter: '',
+    gtk.keysyms.Menu: '',
+    gtk.keysyms.Pause: '',
+    gtk.keysyms.Kanji: '',
+    gtk.keysyms.Escape: '',
+    gtk.keysyms.Henkan: '',
+    gtk.keysyms.Muhenkan: '',
+    gtk.keysyms.space: '',
+    gtk.keysyms.Prior: '',
+    gtk.keysyms.Next: '',
+    gtk.keysyms.End: '',
+    gtk.keysyms.Home: '',
+    gtk.keysyms.Left: '',
+    gtk.keysyms.Up: '',
+    gtk.keysyms.Right: '',
+    gtk.keysyms.Down: '',
+    gtk.keysyms.Select: '',
+    gtk.keysyms.Print: '',
+    gtk.keysyms.Execute: '',
+    gtk.keysyms.Insert: '',
+    gtk.keysyms.Delete: '',
+    gtk.keysyms.Help: '',
+    gtk.keysyms._0: '0',
+    gtk.keysyms._1: '1',
+    gtk.keysyms._2: '2',
+    gtk.keysyms._3: '3',
+    gtk.keysyms._4: '4',
+    gtk.keysyms._5: '5',
+    gtk.keysyms._6: '6',
+    gtk.keysyms._7: '7',
+    gtk.keysyms._8: '8',
+    gtk.keysyms._9: '9',
+    gtk.keysyms.a: 'a',
+    gtk.keysyms.b: 'b',
+    gtk.keysyms.c: 'c',
+    gtk.keysyms.d: 'd',
+    gtk.keysyms.e: 'e',
+    gtk.keysyms.f: 'f',
+    gtk.keysyms.g: 'g',
+    gtk.keysyms.h: 'h',
+    gtk.keysyms.i: 'i',
+    gtk.keysyms.j: 'j',
+    gtk.keysyms.k: 'k',
+    gtk.keysyms.l: 'l',
+    gtk.keysyms.m: 'm',
+    gtk.keysyms.n: 'n',
+    gtk.keysyms.o: 'o',
+    gtk.keysyms.p: 'p',
+    gtk.keysyms.q: 'q',
+    gtk.keysyms.r: 'r',
+    gtk.keysyms.s: 's',
+    gtk.keysyms.t: 't',
+    gtk.keysyms.u: 'u',
+    gtk.keysyms.v: 'v',
+    gtk.keysyms.w: 'w',
+    gtk.keysyms.x: 'x',
+    gtk.keysyms.y: 'y',
+    gtk.keysyms.z: 'z',
+    gtk.keysyms.KP_0: '0',
+    gtk.keysyms.KP_1: '1',
+    gtk.keysyms.KP_2: '2',
+    gtk.keysyms.KP_3: '3',
+    gtk.keysyms.KP_4: '4',
+    gtk.keysyms.KP_5: '5',
+    gtk.keysyms.KP_6: '6',
+    gtk.keysyms.KP_7: '7',
+    gtk.keysyms.KP_8: '8',
+    gtk.keysyms.KP_9: '9',
+    gtk.keysyms.KP_Multiply: '*',
+    gtk.keysyms.KP_Add: '+',
+    gtk.keysyms.KP_Separator: '',
+    gtk.keysyms.KP_Subtract: '-',
+    gtk.keysyms.KP_Decimal: '',
+    gtk.keysyms.KP_Divide: '/',
+    gtk.keysyms.F1: 'f1',
+    gtk.keysyms.F2: 'f2',
+    gtk.keysyms.F3: 'f3',
+    gtk.keysyms.F4: 'f4',
+    gtk.keysyms.F5: 'f5',
+    gtk.keysyms.F6: 'f6',
+    gtk.keysyms.F7: 'f7',
+    gtk.keysyms.F8: 'f8',
+    gtk.keysyms.F9: 'f9',
+    gtk.keysyms.F10: 'f10',
+    gtk.keysyms.F11: 'f11',
+    gtk.keysyms.F12: 'f12',
+    gtk.keysyms.F13: 'f13',
+    gtk.keysyms.F14: 'f14',
+    gtk.keysyms.F15: 'f15',
+    gtk.keysyms.F16: 'f16',
+    gtk.keysyms.F17: 'f17',
+    gtk.keysyms.F18: 'f18',
+    gtk.keysyms.F19: 'f19',
+    gtk.keysyms.F20: 'f20',
+    gtk.keysyms.F21: 'f21',
+    gtk.keysyms.F22: 'f22',
+    gtk.keysyms.F23: 'f23',
+    gtk.keysyms.F24: 'f24',
+    gtk.keysyms.Num_Lock: '',
+    gtk.keysyms.Scroll_Lock: '',
+    gtk.keysyms.Shift_L: '',
+    gtk.keysyms.Shift_R: '',
+    gtk.keysyms.Control_L: '',
+    gtk.keysyms.Control_R: '',
 }
 
 keymap_new = {
-    gtk.keysyms.BackSpace: "8",
-    gtk.keysyms.Tab: "9",
-    gtk.keysyms.KP_Tab: "9",
-    gtk.keysyms.Clear: "12",
-    gtk.keysyms.Return: "13",
-    gtk.keysyms.KP_Enter: "13",
-    gtk.keysyms.Menu: "18",
-    gtk.keysyms.Pause: "19",
-    gtk.keysyms.Kanji: "25",
-    gtk.keysyms.Escape: "27",
-    gtk.keysyms.Henkan: "28",
-    gtk.keysyms.Muhenkan: "29",
-    gtk.keysyms.space: "32",
-    gtk.keysyms.Prior: "33",
-    gtk.keysyms.Next: "34",
-    gtk.keysyms.End: "35",
-    gtk.keysyms.Home: "36",
-    gtk.keysyms.Left: "37",
-    gtk.keysyms.Up: "38",
-    gtk.keysyms.Right: "39",
-    gtk.keysyms.Down: "40",
-    gtk.keysyms.Select: "41",
-    gtk.keysyms.Print: "42",
-    gtk.keysyms.Execute: "43",
-    gtk.keysyms.Insert: "45",
-    gtk.keysyms.Delete: "46",
-    gtk.keysyms.Help: "47",
-    gtk.keysyms._0: "48",
-    gtk.keysyms._1: "49",
-    gtk.keysyms._2: "50",
-    gtk.keysyms._3: "51",
-    gtk.keysyms._4: "52",
-    gtk.keysyms._5: "53",
-    gtk.keysyms._6: "54",
-    gtk.keysyms._7: "55",
-    gtk.keysyms._8: "56",
-    gtk.keysyms._9: "57",
-    gtk.keysyms.a: "65",
-    gtk.keysyms.b: "66",
-    gtk.keysyms.c: "67",
-    gtk.keysyms.d: "68",
-    gtk.keysyms.e: "69",
-    gtk.keysyms.f: "70",
-    gtk.keysyms.g: "71",
-    gtk.keysyms.h: "72",
-    gtk.keysyms.i: "73",
-    gtk.keysyms.j: "74",
-    gtk.keysyms.k: "75",
-    gtk.keysyms.l: "76",
-    gtk.keysyms.m: "77",
-    gtk.keysyms.n: "78",
-    gtk.keysyms.o: "79",
-    gtk.keysyms.p: "80",
-    gtk.keysyms.q: "81",
-    gtk.keysyms.r: "82",
-    gtk.keysyms.s: "83",
-    gtk.keysyms.t: "84",
-    gtk.keysyms.u: "85",
-    gtk.keysyms.v: "86",
-    gtk.keysyms.w: "87",
-    gtk.keysyms.x: "88",
-    gtk.keysyms.y: "89",
-    gtk.keysyms.z: "90",
-    gtk.keysyms.KP_0: "96",
-    gtk.keysyms.KP_1: "97",
-    gtk.keysyms.KP_2: "98",
-    gtk.keysyms.KP_3: "99",
-    gtk.keysyms.KP_4: "100",
-    gtk.keysyms.KP_5: "101",
-    gtk.keysyms.KP_6: "102",
-    gtk.keysyms.KP_7: "103",
-    gtk.keysyms.KP_8: "104",
-    gtk.keysyms.KP_9: "105",
-    gtk.keysyms.KP_Multiply: "106",
-    gtk.keysyms.KP_Add: "107",
-    gtk.keysyms.KP_Separator: "108",
-    gtk.keysyms.KP_Subtract: "109",
-    gtk.keysyms.KP_Decimal: "110",
-    gtk.keysyms.KP_Divide: "111",
-    gtk.keysyms.F1: "112",
-    gtk.keysyms.F2: "113",
-    gtk.keysyms.F3: "114",
-    gtk.keysyms.F4: "115",
-    gtk.keysyms.F5: "116",
-    gtk.keysyms.F6: "117",
-    gtk.keysyms.F7: "118",
-    gtk.keysyms.F8: "119",
-    gtk.keysyms.F9: "120",
-    gtk.keysyms.F10: "121",
-    gtk.keysyms.F11: "122",
-    gtk.keysyms.F12: "123",
-    gtk.keysyms.F13: "124",
-    gtk.keysyms.F14: "125",
-    gtk.keysyms.F15: "126",
-    gtk.keysyms.F16: "127",
-    gtk.keysyms.F17: "128",
-    gtk.keysyms.F18: "129",
-    gtk.keysyms.F19: "130",
-    gtk.keysyms.F20: "131",
-    gtk.keysyms.F21: "132",
-    gtk.keysyms.F22: "133",
-    gtk.keysyms.F23: "134",
-    gtk.keysyms.F24: "135",
-    gtk.keysyms.Num_Lock: "144",
-    gtk.keysyms.Scroll_Lock: "145",
-    gtk.keysyms.Shift_L: "160",
-    gtk.keysyms.Shift_R: "161",
-    gtk.keysyms.Control_L: "162",
-    gtk.keysyms.Control_R: "163",
+    gtk.keysyms.BackSpace: '8',
+    gtk.keysyms.Tab: '9',
+    gtk.keysyms.KP_Tab: '9',
+    gtk.keysyms.Clear: '12',
+    gtk.keysyms.Return: '13',
+    gtk.keysyms.KP_Enter: '13',
+    gtk.keysyms.Menu: '18',
+    gtk.keysyms.Pause: '19',
+    gtk.keysyms.Kanji: '25',
+    gtk.keysyms.Escape: '27',
+    gtk.keysyms.Henkan: '28',
+    gtk.keysyms.Muhenkan: '29',
+    gtk.keysyms.space: '32',
+    gtk.keysyms.Prior: '33',
+    gtk.keysyms.Next: '34',
+    gtk.keysyms.End: '35',
+    gtk.keysyms.Home: '36',
+    gtk.keysyms.Left: '37',
+    gtk.keysyms.Up: '38',
+    gtk.keysyms.Right: '39',
+    gtk.keysyms.Down: '40',
+    gtk.keysyms.Select: '41',
+    gtk.keysyms.Print: '42',
+    gtk.keysyms.Execute: '43',
+    gtk.keysyms.Insert: '45',
+    gtk.keysyms.Delete: '46',
+    gtk.keysyms.Help: '47',
+    gtk.keysyms._0: '48',
+    gtk.keysyms._1: '49',
+    gtk.keysyms._2: '50',
+    gtk.keysyms._3: '51',
+    gtk.keysyms._4: '52',
+    gtk.keysyms._5: '53',
+    gtk.keysyms._6: '54',
+    gtk.keysyms._7: '55',
+    gtk.keysyms._8: '56',
+    gtk.keysyms._9: '57',
+    gtk.keysyms.a: '65',
+    gtk.keysyms.b: '66',
+    gtk.keysyms.c: '67',
+    gtk.keysyms.d: '68',
+    gtk.keysyms.e: '69',
+    gtk.keysyms.f: '70',
+    gtk.keysyms.g: '71',
+    gtk.keysyms.h: '72',
+    gtk.keysyms.i: '73',
+    gtk.keysyms.j: '74',
+    gtk.keysyms.k: '75',
+    gtk.keysyms.l: '76',
+    gtk.keysyms.m: '77',
+    gtk.keysyms.n: '78',
+    gtk.keysyms.o: '79',
+    gtk.keysyms.p: '80',
+    gtk.keysyms.q: '81',
+    gtk.keysyms.r: '82',
+    gtk.keysyms.s: '83',
+    gtk.keysyms.t: '84',
+    gtk.keysyms.u: '85',
+    gtk.keysyms.v: '86',
+    gtk.keysyms.w: '87',
+    gtk.keysyms.x: '88',
+    gtk.keysyms.y: '89',
+    gtk.keysyms.z: '90',
+    gtk.keysyms.KP_0: '96',
+    gtk.keysyms.KP_1: '97',
+    gtk.keysyms.KP_2: '98',
+    gtk.keysyms.KP_3: '99',
+    gtk.keysyms.KP_4: '100',
+    gtk.keysyms.KP_5: '101',
+    gtk.keysyms.KP_6: '102',
+    gtk.keysyms.KP_7: '103',
+    gtk.keysyms.KP_8: '104',
+    gtk.keysyms.KP_9: '105',
+    gtk.keysyms.KP_Multiply: '106',
+    gtk.keysyms.KP_Add: '107',
+    gtk.keysyms.KP_Separator: '108',
+    gtk.keysyms.KP_Subtract: '109',
+    gtk.keysyms.KP_Decimal: '110',
+    gtk.keysyms.KP_Divide: '111',
+    gtk.keysyms.F1: '112',
+    gtk.keysyms.F2: '113',
+    gtk.keysyms.F3: '114',
+    gtk.keysyms.F4: '115',
+    gtk.keysyms.F5: '116',
+    gtk.keysyms.F6: '117',
+    gtk.keysyms.F7: '118',
+    gtk.keysyms.F8: '119',
+    gtk.keysyms.F9: '120',
+    gtk.keysyms.F10: '121',
+    gtk.keysyms.F11: '122',
+    gtk.keysyms.F12: '123',
+    gtk.keysyms.F13: '124',
+    gtk.keysyms.F14: '125',
+    gtk.keysyms.F15: '126',
+    gtk.keysyms.F16: '127',
+    gtk.keysyms.F17: '128',
+    gtk.keysyms.F18: '129',
+    gtk.keysyms.F19: '130',
+    gtk.keysyms.F20: '131',
+    gtk.keysyms.F21: '132',
+    gtk.keysyms.F22: '133',
+    gtk.keysyms.F23: '134',
+    gtk.keysyms.F24: '135',
+    gtk.keysyms.Num_Lock: '144',
+    gtk.keysyms.Scroll_Lock: '145',
+    gtk.keysyms.Shift_L: '160',
+    gtk.keysyms.Shift_R: '161',
+    gtk.keysyms.Control_L: '162',
+    gtk.keysyms.Control_R: '163',
 }
 
 def test():
     import gtk
     def key_press(widget, event):
         try:
-            print keymap_old[event.keyval], keymap_new[event.keyval], "(%d)" % event.keyval
+            print keymap_old[event.keyval], \
+                  keymap_new[event.keyval], '(%d)' % event.keyval
         except KeyError:
             if event.string:
-                print repr(event.string), "(%d)" % event.keyval
+                print repr(event.string), '(%d)' % event.keyval
             else:
-                print "unknown keyval:", event.keyval
+                print 'unknown keyval:', event.keyval
     win = gtk.Window()
     win.set_events(gtk.gdk.KEY_PRESS_MASK)
-    win.connect("destroy", gtk.main_quit)
-    win.connect("key_press_event", key_press)
+    win.connect('destroy', gtk.main_quit)
+    win.connect('key_press_event', key_press)
     win.show()
     gtk.main()
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     test()
index 9d03ad6..7c4851a 100644 (file)
@@ -18,7 +18,7 @@
 import os
 import sys
 
-if os.environ.has_key("DISPLAY"):
+if os.environ.has_key('DISPLAY'):
     import gtk
     import gobject
     import pango
@@ -27,6 +27,7 @@ if os.environ.has_key("DISPLAY"):
 import ninix.config
 import ninix.seriko
 
+
 class Menu:
 
     def __init__(self, kinoko, accelgroup):
@@ -53,7 +54,7 @@ class Menu:
                          '/ui/popup/Exit'],
             }
         self.__skin_list = None
-        actions = gtk.ActionGroup("Actions")
+        actions = gtk.ActionGroup('Actions')
         entry = []
         for key in self.__menu_list.keys():
             entry.append(self.__menu_list[key][0])
@@ -61,7 +62,7 @@ class Menu:
         ui_manager = gtk.UIManager()
         ui_manager.insert_action_group(actions, 0)
         ui_manager.add_ui_from_string(ui_info)
-        self.__popup_menu = ui_manager.get_widget("/ui/popup")
+        self.__popup_menu = ui_manager.get_widget('/ui/popup')
         for key in self.__menu_list.keys():
             path = self.__menu_list[key][-1]
             self.__menu_list[key][1] = ui_manager.get_widget(path)
@@ -69,7 +70,8 @@ class Menu:
     def popup(self, button):
         skin_list = self.__kinoko.get_skin_list()
         self.__set_skin_menu(skin_list)
-        self.__popup_menu.popup(None, None, None, button, gtk.get_current_event_time())
+        self.__popup_menu.popup(
+            None, None, None, button, gtk.get_current_event_time())
 
     def __set_skin_menu(self, list): ## FIXME
         key = 'skin'
@@ -77,7 +79,7 @@ class Menu:
             menu = gtk.Menu()
             for skin in list:
                 item = gtk.MenuItem(skin['title'])
-                item.connect("activate", self.__kinoko.select_skin, (skin))
+                item.connect('activate', self.__kinoko.select_skin, (skin))
                 menu.add(item)
                 item.show()
             self.__menu_list[key][1].set_submenu(menu)
@@ -197,14 +199,14 @@ class Skin:
         self.__scale = scale
         self.__shown = 0
         self.window = gtk.Window()
-        ##self.window.set_title('surface.' + name)
+        ##self.window.set_title(''.join(('surface.', name)))
         self.window.set_decorated(False)
         self.window.set_resizable(False)
-        self.window.connect("delete_event", self.delete)
-        self.window.connect("button_press_event", self.button_press)
-        self.window.connect("button_release_event", self.button_release)
-        self.window.connect("motion_notify_event", self.motion_notify)
-        self.window.connect("leave_notify_event", self.leave_notify)
+        self.window.connect('delete_event', self.delete)
+        self.window.connect('button_press_event', self.button_press)
+        self.window.connect('button_release_event', self.button_release)
+        self.window.connect('motion_notify_event', self.motion_notify)
+        self.window.connect('leave_notify_event', self.leave_notify)
         self.window.set_events(gtk.gdk.BUTTON_PRESS_MASK|
                                gtk.gdk.BUTTON_RELEASE_MASK|
                                gtk.gdk.POINTER_MOTION_MASK|
@@ -225,7 +227,8 @@ class Skin:
             if self.__scale != 100:
                 w = surface_pixbuf.get_width() * self.__scale / 100
                 h = surface_pixbuf.get_height() * self.__scale / 100
-                surface_pixbuf = surface_pixbuf.scale_simple(w, h, gtk.gdk.INTERP_BILINEAR)
+                surface_pixbuf = surface_pixbuf.scale_simple(
+                    w, h, gtk.gdk.INTERP_BILINEAR)
             image, mask = surface_pixbuf.render_pixmap_and_mask(255)
         except: ## FIXME
             self.kinoko.close(None)
@@ -238,7 +241,7 @@ class Skin:
         self.window.shape_combine_mask(self.mask_pixmap, 0, 0)
         self.darea = gtk.DrawingArea()
         self.darea.set_events(gtk.gdk.EXPOSURE_MASK)
-        self.darea.connect("expose_event", self.redraw)
+        self.darea.connect('expose_event', self.redraw)
         self.darea.set_size_request(self.w, self.h)
         self.darea.show()
         self.window.add(self.darea)
@@ -247,7 +250,7 @@ class Skin:
         self.show()
         self.reset_overlays()
         for actor in self.seriko:
-            if actor.get_interval() == "runonce":
+            if actor.get_interval() == 'runonce':
                 actor.invoke()
         if self.data['ontop']:
             self.window.set_keep_above(True)
@@ -265,7 +268,8 @@ class Skin:
             self.__shown = 0
 
     def set_position(self, xoffset=0, yoffset=0): ## FIXME
-        base_x, base_y = self.kinoko.target.get_kinoko_position(self.data['baseposition'])
+        base_x, base_y = self.kinoko.target.get_kinoko_position(
+            self.data['baseposition'])
         a, b = [(0.5, 1), (0.5, 0), (0, 0.5), (1, 0.5), (0, 1),
                 (1, 1), (0, 0), (1, 0), (0.5, 0.5)][self.data['baseadjust']]
         offsetx = self.data['offsetx']
@@ -296,7 +300,7 @@ class Skin:
         self.darea.queue_draw()
 
     def get_pixbuf(self, id):
-        path = os.path.join(self.data['dir'], 'surface' + id + '.png')
+        path = os.path.join(self.data['dir'], ''.join(('surface', id, '.png')))
         pixbuf = ninix.pix.create_pixbuf_from_file(path)
         return pixbuf
 
@@ -306,7 +310,7 @@ class Skin:
         actors.sort(lambda a1, a2: cmp(a1.get_id(), a2.get_id()))
         for actor in actors:
             id, x, y = self.overlays[actor]
-            ##print "actor=%d, id=%s, x=%d, y=%d" % (actor.get_id(), id, x, y)
+            ##print 'actor=%d, id=%s, x=%d, y=%d' % (actor.get_id(), id, x, y)
             try:
                 pixbuf = self.get_pixbuf(id)
                 w = pixbuf.get_width()
@@ -331,12 +335,16 @@ class Skin:
                 h += y
             else:
                 dest_y = y
-            pixbuf.composite(surface_pixbuf, dest_x, dest_y, w, h, x, y, 1.0, 1.0, gtk.gdk.INTERP_BILINEAR, 255)
+            pixbuf.composite(
+                surface_pixbuf, dest_x, dest_y, w, h, x, y, 1.0, 1.0,
+                gtk.gdk.INTERP_BILINEAR, 255)
         if self.__scale != 100:
             w = surface_pixbuf.get_width() * self.__scale / 100
             h = surface_pixbuf.get_height() * self.__scale / 100
-            surface_pixbuf = surface_pixbuf.scale_simple(w, h, gtk.gdk.INTERP_BILINEAR)
-        self.surface_pixmap, self.mask_pixmap = surface_pixbuf.render_pixmap_and_mask(255)
+            surface_pixbuf = surface_pixbuf.scale_simple(
+                w, h, gtk.gdk.INTERP_BILINEAR)
+        self.surface_pixmap, self.mask_pixmap = \
+                             surface_pixbuf.render_pixmap_and_mask(255)
         self.w, self.h = self.surface_pixmap.get_size()
         self.show_surface()
 
@@ -349,9 +357,9 @@ class Skin:
         self.reset_overlays()
 
     def add_overlay(self, actor, id, x, y):
-        if id == "-2":
+        if id == '-2':
             self.terminate()
-        if id in ["-1", "-2"]:
+        if id in ['-1', '-2']:
             self.remove_overlay(actor)
             return
         self.overlays[actor] = (id, x, y)
index d2dcb91..120a7c4 100755 (executable)
@@ -4,7 +4,7 @@
 #  Copyright (C) 2001, 2002 by Tamito KAJIYAMA
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
 #  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
-#  Copyright (C) 2003, 2004 by Shun-ichi TAHARA <jado@flowernet.gr.jp>
+#  Copyright (C) 2003-2005 by Shun-ichi TAHARA <jado@flowernet.gr.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: main.py,v 1.129 2005/07/29 08:25:59 shy Exp $
+# $Id: main.py,v 1.130 2005/08/09 00:41:52 shy Exp $
 #
 
 import getopt
 import os
 import signal
 import socket
-import string
 import sys
 import time
 import random
@@ -31,11 +30,11 @@ import fcntl
 
 gettext.install('ninix')
 
-if os.environ.has_key("DISPLAY"):
+if os.environ.has_key('DISPLAY'):
     if not sys.modules.has_key('gtk'):
         try:
             import pygtk
-            pygtk.require("2.0")
+            pygtk.require('2.0')
         except ImportError:
             pass
     import gtk
@@ -58,14 +57,14 @@ import ninix.ngm
 import ninix.nekodorif
 import ninix.kinoko
 
-USAGE = """\
+USAGE = '''\
 Usage: ninix [options]
 Options:
   -H, --homedir DIR   ninix home directory (default: ~/.ninix)
   -U, --userdir DIR   user data directory (default: ninix home directory)
   --sstp-port NUM     additional port for listening SSTP requests
   -h, --help          show this message
-"""
+'''
 
 def usage():
     sys.stderr.write(USAGE)
@@ -75,10 +74,10 @@ def _traceback(type, value, tb):
     response_id = 1
     dialog = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_NONE,
                                _('A ninix-aya error has been detected.'))
-    dialog.set_title(_("Bug Detected"))
+    dialog.set_title(_('Bug Detected'))
     dialog.set_position(gtk.WIN_POS_CENTER)
     dialog.set_gravity(gtk.gdk.GRAVITY_CENTER)
-    button = dialog.add_button(_("Show Details"), response_id)
+    button = dialog.add_button(_('Show Details'), response_id)
     dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
     textview = gtk.TextView()
     textview.set_editable(False)
@@ -108,7 +107,7 @@ def _traceback(type, value, tb):
     dialog.destroy()
     sys.exit(1)
 
-if os.environ.has_key("DISPLAY"):
+if os.environ.has_key('DISPLAY'):
     if sys.modules.has_key('gtk'):
         sys.excepthook = _traceback
 
@@ -116,50 +115,50 @@ def main():
     # reopen stderr to avoid IOError
     sys.stderr = os.fdopen(sys.stderr.fileno(), 'w')
     # check if X is running
-    if not os.environ.has_key("DISPLAY"):
-        sys.stderr.write("Error: cannot open display (abort)\n")
+    if not os.environ.has_key('DISPLAY'):
+        sys.stderr.write('Error: cannot open display (abort)\n')
         sys.exit(1)
     # parse command line arguments
     try:
-        options, rest = getopt.getopt(sys.argv[1:], "H:U:R:ph",
-            ["homedir=", "userdir=", "sstp-port=", "debug=", "help"])
+        options, rest = getopt.getopt(sys.argv[1:], 'H:U:R:ph',
+            ['homedir=', 'userdir=', 'sstp-port=', 'debug=', 'help'])
     except getopt.error, e:
-        sys.stderr.write("Error: %s\n" % str(e))
+        sys.stderr.write('Error: %s\n' % str(e))
         usage()
     if rest:
         usage()
-    home_dir = os.environ.get("NINIX_HOME")
-    user_dir = os.environ.get("NINIX_USER")
+    home_dir = os.environ.get('NINIX_HOME')
+    user_dir = os.environ.get('NINIX_USER')
     sstp_port = [9801, 11000]
     debug = 0
     # check environment variables
-    val = os.environ.get("NINIX_SSTP_PORT")
+    val = os.environ.get('NINIX_SSTP_PORT')
     if val:
         port = []
-        for num in val.split(","):
+        for num in val.split(','):
             try:
                 num = int(num)
                 if num < 1024:
                     raise ValueError
                 port.append(num)
             except ValueError:
-                sys.stderr.write("Invalid NINIX_SSTP_PORT number (ignored)\n")
+                sys.stderr.write('Invalid NINIX_SSTP_PORT number (ignored)\n')
                 break
         else:
             sstp_port.extend(port)
     # parse command line options
     for opt, val in options:
-        if opt in ["-H", "--homedir"]:
+        if opt in ['-H', '--homedir']:
             home_dir = val
-        elif opt in ["-U", "--userdir"]:
+        elif opt in ['-U', '--userdir']:
             user_dir = val
-        elif opt == "--sstp-port":
+        elif opt == '--sstp-port':
             num = int(val)
             if num < 1024:
-                sys.stderr.write("Invalid --sstp-port number (ignored)\n")
+                sys.stderr.write('Invalid --sstp-port number (ignored)\n')
             else:
                 sstp_port.append(num)
-        elif opt == "--debug":
+        elif opt == '--debug':
             debug = int(val)
         else:
             usage()
@@ -173,7 +172,7 @@ def main():
         ninix.home.NINIX_USER = user_dir
     config = ninix.home.load_config()
     if config is None:
-        sys.stderr.write("Home directory not found (abort)\n")
+        sys.stderr.write('Home directory not found (abort)\n')
         sys.exit(1)
     # aquire Inter Process Mutex (not Global Mutex)
     lockfile = open(os.path.join(ninix.home.get_ninix_home(), '.lock'), 'w')
@@ -185,46 +184,50 @@ def main():
     # check if at least one set of ghost, surface, and balloon
     ghosts, shells, balloons, plugins, nekoninni, katochan, kinoko = config ## FIXME
     if not ghosts:
-        sys.stderr.write("Error: no ghost found\n")
+        sys.stderr.write('Error: no ghost found\n')
         sys.exit(1)
     elif not shells and \
          not filter(lambda ghost: ghost[3], ghosts):
-        sys.stderr.write("Error: no shell found\n")
+        sys.stderr.write('Error: no shell found\n')
         sys.exit(1)
     elif not balloons:
-        sys.stderr.write("Error: no balloon found\n")
+        sys.stderr.write('Error: no balloon found\n')
         sys.exit(1)
     for desc, shiori_dir, use_makoto, surface_set, balloon, prefix, shiori_dll, shiori_name in ghosts:
-        print "ghost:", desc.get("name", "<none>").encode('utf-8', 'ignore')
-        for name, surface_dir, surface_desc, surface_alias, surface in surface_set:
+        print 'ghost:', desc.get('name', '<none>').encode('utf-8', 'ignore')
+        for name, surface_dir, surface_desc, surface_alias, surface in \
+                surface_set:
             if name:
-                print "\tsurface:", name.encode('utf-8', 'ignore'),
+                print '\tsurface:', name.encode('utf-8', 'ignore'),
             if surface_alias is not None:
-                print "(w/alias)",
+                print '(w/alias)',
             print
         if balloon:
-            print "\tballoon:", balloon[0].get("name", "<none>").encode('utf-8', 'ignore')
+            print '\tballoon:', \
+                  balloon[0].get('name', '<none>').encode('utf-8', 'ignore')
     for shell_name, surface_set, balloon in shells:
-        print "shell:", (shell_name or "<none>").encode('utf-8', 'ignore')
-        for name, surface_dir, surface_desc, surface_alias, surface in surface_set:
+        print 'shell:', (shell_name or '<none>').encode('utf-8', 'ignore')
+        for name, surface_dir, surface_desc, surface_alias, surface in \
+                surface_set:
             if name:
-                print "\tsurface:", name.encode('utf-8', 'ignore'),
+                print '\tsurface:', name.encode('utf-8', 'ignore'),
             if surface_alias is not None:
-                print "(w/alias)",
+                print '(w/alias)',
             print
         if balloon:
-            print "\tballoon:", balloon[0].get("name", "<none>").encode('utf-8', 'ignore')
+            print '\tballoon:', \
+                  balloon[0].get('name', '<none>').encode('utf-8', 'ignore')
     for desc, balloon in balloons:
-        print "balloon:", desc.get("name", "<none>").encode('utf-8', 'ignore')
+        print 'balloon:', desc.get('name', '<none>').encode('utf-8', 'ignore')
     for plugin_name, plugin_dir, startup, menu_items in plugins:
-        print "plugin:", plugin_name.encode('utf-8', 'ignore')
+        print 'plugin:', plugin_name.encode('utf-8', 'ignore')
     # read gtkrc
     gtk.rc_parse(ninix.home.get_gtkrc())
     # start
-    sys.stdout.write("loading...")
+    sys.stdout.write('loading...')
     sys.stdout.flush()
     app = Application(config, sstp_port, debug)
-    sys.stdout.write("done.\n")
+    sys.stdout.write('done.\n')
     app.run()
     try:
         fcntl.flock(lockfile.flieno(), fcntl.LOCK_UN)
@@ -236,36 +239,39 @@ def get_default_surface_scale():
     return ninix.surface.range_scale[0][1]
 
 def get_default_script_speed():
-    i = len(ninix.sakura.range_script_speed)/2
+    i = len(ninix.sakura.range_script_speed) / 2
     return ninix.sakura.range_script_speed[i][1]
 
+
 class Application:
-    PREFS_SAKURA_NAME       = "sakura_name"
-    PREFS_SAKURA_SURFACE    = "sakura_surface"
-    PREFS_DEFAULT_BALLOON   = "default_balloon"
-    PREFS_IGNORE_DEFAULT    = "ignore_default"
-    PREFS_SCRIPT_SPEED      = "script_speed"
-    PREFS_SURFACE_SCALE     = "surface_scale"
-    PREFS_BALLOON_SCALLING  = "balloon_scalling"
-    PREFS_EVENT_KILL_LIST   = "event_kill_list"
-    PREFS_MOUSE_BUTTON1     = "mouse_button1"
-    PREFS_MOUSE_BUTTON3     = "mouse_button3"
-    PREFS_BROWSER           = "browser"
-    PREFS_HELPER_PATTERN    = "helper_%d_pattern"
-    PREFS_HELPER_COMMAND    = "helper_%d_command"
-    PREFS_TOP_MARGIN        = "top_margin"
-    PREFS_BOTTOM_MARGIN     = "bottom_margin"
-    PREFS_BALLOON_FONTS     = "balloon_fonts"
-    PREFS_ALLOWEMBRYO       = "allowembryo"
-    PREFS_CHECK_COLLISION   = "check_collision"
-    PREFS_USE_PNA           = "use_pna"
-    PREFS_SINK_AFTER_TALK   = "sink_after_talk"
-    PREFS_SURFACE_ALPHA     = "surface_alpha"
-    PREFS_BALLOON_ALPHA     = "balloon_alpha"
-    PREFS_RAISE_BEFORE_TALK = "raise_before_talk"
+
+    PREFS_SAKURA_NAME       = 'sakura_name'
+    PREFS_SAKURA_SURFACE    = 'sakura_surface'
+    PREFS_DEFAULT_BALLOON   = 'default_balloon'
+    PREFS_IGNORE_DEFAULT    = 'ignore_default'
+    PREFS_SCRIPT_SPEED      = 'script_speed'
+    PREFS_SURFACE_SCALE     = 'surface_scale'
+    PREFS_BALLOON_SCALLING  = 'balloon_scalling'
+    PREFS_EVENT_KILL_LIST   = 'event_kill_list'
+    PREFS_MOUSE_BUTTON1     = 'mouse_button1'
+    PREFS_MOUSE_BUTTON3     = 'mouse_button3'
+    PREFS_BROWSER           = 'browser'
+    PREFS_HELPER_PATTERN    = 'helper_%d_pattern'
+    PREFS_HELPER_COMMAND    = 'helper_%d_command'
+    PREFS_TOP_MARGIN        = 'top_margin'
+    PREFS_BOTTOM_MARGIN     = 'bottom_margin'
+    PREFS_BALLOON_FONTS     = 'balloon_fonts'
+    PREFS_ALLOWEMBRYO       = 'allowembryo'
+    PREFS_CHECK_COLLISION   = 'check_collision'
+    PREFS_USE_PNA           = 'use_pna'
+    PREFS_SINK_AFTER_TALK   = 'sink_after_talk'
+    PREFS_SURFACE_ALPHA     = 'surface_alpha'
+    PREFS_BALLOON_ALPHA     = 'balloon_alpha'
+    PREFS_RAISE_BEFORE_TALK = 'raise_before_talk'
 
     def __init__(self, config, sstp_port=[9801, 11000], debug=0):
-        self.ghosts, self.shells, self.balloons, self.plugins, self.nekoninni, self.katochan, self.kinoko = config
+        self.ghosts, self.shells, self.balloons, self.plugins, \
+                     self.nekoninni, self.katochan, self.kinoko = config
         self.sstp_port = sstp_port
         self.debug = debug
         self.plugin_pids = []
@@ -281,8 +287,12 @@ class Application:
         # create ghost manager
         self.__ngm = ninix.ngm.NGM(self)
 
-    def enqueue_script_if_ghost(self, if_ghost, script, sender, handle, address, show_sstp_marker, use_translator, entry_db):
-        self.__sstp_queue.append((if_ghost, script, sender, handle, address, show_sstp_marker, use_translator, entry_db))
+    def enqueue_script_if_ghost(self, if_ghost, script, sender, handle,
+                                address, show_sstp_marker,
+                                use_translator, entry_db):
+        self.__sstp_queue.append(
+            (if_ghost, script, sender, handle, address, show_sstp_marker,
+             use_translator, entry_db))
 
     def set_sstp_flag(self, sender):
         self.__sstp_flag = 1
@@ -293,7 +303,7 @@ class Application:
         self.__current_sender = None        
 
     def handle_sstp_queue(self):
-        if self.__sstp_flag or len(self.__sstp_queue) == 0:
+        if self.__sstp_flag or not self.__sstp_queue:
             return
         if_ghost = self.__sstp_queue[0][0]
         ghost = self.get_ghost(if_ghost)
@@ -302,7 +312,8 @@ class Application:
         elif not self.get_allowembryo(): # Refuse
             self.__sstp_queue.pop(0)
             return
-        if_ghost, script, sender, handle, address, show_sstp_marker, use_translator, entry_db = self.__sstp_queue.pop(0)
+        if_ghost, script, sender, handle, address, show_sstp_marker, \
+                  use_translator, entry_db = self.__sstp_queue.pop(0)
         self.set_sstp_flag(sender)
         ghost = self.ghost_list[self.current_sakura[1]]['instance']
         ghost.enter_temp_mode()
@@ -316,13 +327,14 @@ class Application:
             for sstp_server in self.sstp_servers:
                 sstp_server.handle_request()
         except socket.error, (code, message):
-            sys.stderr.write("socket.error: %s (%d)\n" % (message, code))
+            sys.stderr.write('socket.error: %s (%d)\n' % (message, code))
         except ValueError: # may happen when ninix is terminated
             return
 
     def create_ghost(self, data, debug):
         default_path = os.path.join(os.environ['PYTHONPATH'], 'ninix/dll')
-        ghost = ninix.ghost.Ghost(self, data, default_path, self.__communicate, debug)
+        ghost = ninix.ghost.Ghost(self, data, default_path,
+                                  self.__communicate, debug)
         ghost.set_top_margin(self.get_top_margin())
         ghost.set_bottom_margin(self.get_bottom_margin())
         ghost.set_balloon_fonts(self.get_balloon_fonts())
@@ -366,13 +378,15 @@ class Application:
         self.prefs[self.PREFS_SURFACE_SCALE] = str(scale)
 
     def get_surface_scale(self):
-        return self.prefs.getint(self.PREFS_SURFACE_SCALE, get_default_surface_scale())
+        return self.prefs.getint(self.PREFS_SURFACE_SCALE,
+                                 get_default_surface_scale())
 
     def set_script_speed(self, speed):
         self.prefs[self.PREFS_SCRIPT_SPEED] = str(speed)
 
     def get_script_speed(self):
-        return self.prefs.getint(self.PREFS_SCRIPT_SPEED, get_default_script_speed())
+        return self.prefs.getint(self.PREFS_SCRIPT_SPEED,
+                                 get_default_script_speed())
 
     def set_top_margin(self, margin):
         self.prefs[self.PREFS_TOP_MARGIN] = str(margin)
@@ -404,6 +418,7 @@ class Application:
         return self.prefs.getint(self.PREFS_IGNORE_DEFAULT, 0)
 
     def set_balloon_fonts(self, fonts):
+        self.prefs[self.PREFS_BALLOON_FONTS] = fonts
         for ghost in self.get_working_ghost():
             ghost.set_balloon_fonts(fonts)
 
@@ -416,7 +431,8 @@ class Application:
             ghost.set_mouse_button1(button1)
 
     def get_mouse_button1(self):
-        return self.prefs.get(self.PREFS_MOUSE_BUTTON1, ninix.sakura.BUTTON1_RAISE)
+        return self.prefs.get(self.PREFS_MOUSE_BUTTON1,
+                              ninix.sakura.BUTTON1_RAISE)
 
     def set_mouse_button3(self, button3):
         self.prefs[self.PREFS_MOUSE_BUTTON3] = button3
@@ -424,15 +440,17 @@ class Application:
             ghost.set_mouse_button3(button3)
 
     def get_mouse_button3(self):
-        return self.prefs.get(self.PREFS_MOUSE_BUTTON3, ninix.sakura.BUTTON3_CLOSE)
+        return self.prefs.get(self.PREFS_MOUSE_BUTTON3,
+                              ninix.sakura.BUTTON3_CLOSE)
 
     def set_event_kill_list(self, list):
-        self.prefs[self.PREFS_EVENT_KILL_LIST] = string.join(list)
+        self.prefs[self.PREFS_EVENT_KILL_LIST] = ' '.join(list)
         for ghost in self.get_working_ghost():
             ghost.set_event_kill_list(list)
 
     def get_browser(self):
-        return self.prefs.get(self.PREFS_BROWSER, ninix.sakura.DEFAULT_BROWSER)
+        return self.prefs.get(self.PREFS_BROWSER,
+                              ninix.sakura.DEFAULT_BROWSER)
 
     def set_browser(self, command):
         self.prefs[self.PREFS_BROWSER] = command
@@ -534,17 +552,18 @@ class Application:
         if self.ghosts[i] is None:
             return None
         type = 'g'
-        desc, shiori_dir, use_makoto, surface_set, balloon, prefix, shiori_dll, shiori_name = \
-              self.ghosts[i]
-        icon = desc.get("icon", None)
+        desc, shiori_dir, use_makoto, surface_set, balloon, prefix, \
+              shiori_dll, shiori_name = self.ghosts[i]
+        icon = desc.get('icon', None)
         if icon is not None:
             icon_path = os.path.join(shiori_dir, icon)
             if not os.path.exists(icon_path):
                 icon_path = None
         else:
             icon_path = None
-        name = desc.get("name",
-                        unicode(_("Ghost"), 'utf-8') + "#%d" % (i + 1))
+        name = desc.get('name',
+                        ''.join((unicode(_('Ghost'), 'utf-8'),
+                                 '#%d' % (i + 1))))
         shell_list = []
         for j in range(len(surface_set)):
             value = (type, i, j)
@@ -577,7 +596,7 @@ class Application:
         for i in range(len(self.shells)):
             name, surface_set, balloon = self.shells[i]
             if name is None:
-                name = unicode(_("Shell") + "#%d" % (i + 1), 'utf-8')
+                name = unicode(''.join((_('Shell'), '#%d' % (i + 1))), 'utf-8')
             shell_list = []
             for j in range(len(surface_set)):
                 value = (type, i, j)
@@ -594,8 +613,9 @@ class Application:
         list = []
         for i in range(len(self.balloons)):
             desc, balloon = self.balloons[i]
-            name = desc.get("name",
-                            unicode(_("Balloon"), 'utf-8') + "#%d" % (i + 1))
+            name = desc.get('name',
+                            ''.join((unicode(_('Balloon'), 'utf-8'),
+                                     '#%d' % (i + 1))))
             item = {}
             item['name'] = name
             item['icon'] = None
@@ -659,12 +679,12 @@ class Application:
         for i in range(len(self.ghosts)):
             if self.ghosts[i] is None:
                 continue
-            desc, shiori_dir, use_makoto, surface_set, balloon, prefix, shiori_dll, shiori_name = \
-                  self.ghosts[i]
+            desc, shiori_dir, use_makoto, surface_set, balloon, prefix, \
+                  shiori_dll, shiori_name = self.ghosts[i]
             try:
-                if desc.get("name") == name:
+                if desc.get('name') == name:
                     if not surface_set or surface < len(surface_set):
-                        return ("g", i, surface)
+                        return ('g', i, surface)
             except: # old preferences(EUC-JP)
                 pass
         return None
@@ -674,7 +694,7 @@ class Application:
             shell_name, surface_set, balloon = self.shells[i]
             try:
                 if shell_name == name and surface < len(surface_set):
-                    return ("s", i, surface)
+                    return ('s', i, surface)
             except: # old preferences(EUC-JP)
                 pass
         return None
@@ -683,17 +703,17 @@ class Application:
         for i in range(len(self.ghosts)):
             if self.ghosts[i] is None:
                 continue
-            desc, shiori_dir, use_makoto, surface_set, balloon, prefix, shiori_dll, shiori_name = \
-                  self.ghosts[i]
+            desc, shiori_dir, use_makoto, surface_set, balloon, prefix, \
+                  shiori_dll, shiori_name = self.ghosts[i]
             if surface_set:
-                return ("g", i, 0)
-        return ("s", 0, 0)
+                return ('g', i, 0)
+        return ('s', 0, 0)
 
     def find_balloon_by_name(self, name):
         for i in range(len(self.balloons)):
             desc, balloon = self.balloons[i]
             try:
-                if desc.get("name") == name:
+                if desc.get('name') == name:
                     return i
                 if balloon['balloon_dir'] == name.encode('utf-8').lower(): # XXX
                     return i
@@ -710,10 +730,10 @@ class Application:
             try:
                 server = ninix.sstp.SSTPServer(('', port), self)
             except socket.error, (code, message):
-                sys.stderr.write("Port %d: %s (ignored)\n" % (port, message))
+                sys.stderr.write('Port %d: %s (ignored)\n' % (port, message))
                 continue
             self.sstp_servers.append(server)
-            print "Serving SSTP on port", port
+            print 'Serving SSTP on port', port
         # start plugins
         try:
             os.setpgid(0, 0)
@@ -731,9 +751,10 @@ class Application:
     def check_request_queue(self, sender):
         count = 0
         for request in self.__sstp_queue:
-            if string.split(request[2], ' / ')[0] == string.split(sender, ' / ')[0]:
+            if request[2].split(' / ')[0] == sender.split(' / ')[0]:
                 count += 1
-        if self.__sstp_flag and string.split(self.__current_sender, ' / ')[0] == string.split(sender, ' / ')[0]:
+        if self.__sstp_flag and \
+           self.__current_sender.split(' / ')[0] == sender.split(' / ')[0]:
             count += 1
         return str(count), str(len(self.__sstp_queue))
 
@@ -774,9 +795,9 @@ class Application:
                     continue
                 ghost = item['instance']
                 assert ghost is not None
-                names = "%s,%s" % (ghost.get_selfname(),
+                names = '%s,%s' % (ghost.get_selfname(),
                                    ghost.get_keroname())
-                name =  "%s" % ghost.get_selfname()
+                name =  '%s' % ghost.get_selfname()
                 if ifghost in [name, names]:
                     if not ghost.is_running():
                         self.current_sakura = item['shell'][0][1] ## FIXME
@@ -792,9 +813,7 @@ class Application:
                 self.current_sakura = random.choice(list).current
 
     def remove_ghost(self, ghost): ## FIXME
-        type, i, j = ghost.current
-        list = self.get_working_ghost()
-        if len(list) == 0:
+        if not self.get_working_ghost():
             self.quit()
         elif self.current_sakura == ghost.current:
             self.select_current_sakura()
@@ -813,10 +832,10 @@ class Application:
     def save_preferences(self): ## FIXME
         # last ghost/shell
         type, i, j = self.current_sakura
-        if type == "g":
-            desc, shiori_dir, use_makoto, surface_set, balloon, prefix, shiori_dll, shiori_name = \
-                  self.ghosts[i]
-            name = desc.get("name", "")
+        if type == 'g':
+            desc, shiori_dir, use_makoto, surface_set, balloon, prefix, \
+                  shiori_dll, shiori_name = self.ghosts[i]
+            name = desc.get('name', '')
         else:
             name, surface_set, balloon = self.shells[i]
         self.prefs[self.PREFS_SAKURA_NAME] = name
@@ -825,13 +844,13 @@ class Application:
         try:
             self.prefs.save()
         except IOError:
-            sys.stderr.write("Cannot write preferences to file (ignored).\n")
+            sys.stderr.write('Cannot write preferences to file (ignored).\n')
 
     def select_ghost(self, ghost, sequential, event=1):
         if len(self.range_ghosts()) < 2:
             return
         type, i, j = ghost.current
-        if type == "s":
+        if type == 's':
             i = 0
         if sequential: ## FIXME
             i += 1
@@ -841,20 +860,20 @@ class Application:
             list = self.range_ghosts()
             list.remove(i)
             i = random.choice(list)
-        self.change_sakura(ghost, ('g', i, 0), "automatic", event)
+        self.change_sakura(ghost, ('g', i, 0), 'automatic', event)
 
     def select_ghost_by_name(self, ghost, name, event=1):
         item = self.find_ghost_by_name(name, 0)
         if item is None:
             return
-        self.change_sakura(ghost, item, "automatic", event)
+        self.change_sakura(ghost, item, 'automatic', event)
 
     def select_sakura(self, event, args):
         ghost, item = args
         if ghost.busy():
             gtk.gdk.beep()
             return
-        self.change_sakura(ghost, item, "manual")
+        self.change_sakura(ghost, item, 'manual')
 
     def change_sakura(self, ghost, item, method, event=1, vanished=0):
         type, i, j = item
@@ -862,19 +881,22 @@ class Application:
         if ghost.current == item: ## FIXME: needs reloading?
             ghost.notify_ghost_changed(ghost.get_selfname(), 0, None)
             return
-        if type == "g":
-            desc, shiori_dir, use_makoto, surface_set, balloon, prefix, shiori_dll, shiori_name = \
-                  self.ghosts[i]
+        if type == 'g':
+            desc, shiori_dir, use_makoto, surface_set, balloon, prefix, \
+                  shiori_dll, shiori_name = self.ghosts[i]
             if surface_set:
-                name, surface_dir, surface_desc, surface_alias, surface = surface_set[j]
+                name, surface_dir, surface_desc, surface_alias, surface = \
+                      surface_set[j]
             else:
                 shell_name, surface_set, balloon = self.shells[0]
-                name, surface_dir, surface_desc, surface_alias, surface = surface_set[0]
-        elif type == "s":
-            desc, shiori_dir, use_makoto, surface_set, balloon, prefix, shiori_dll, shiori_name = \
-                  self.ghosts[0] ## FIXME: this should be default
+                name, surface_dir, surface_desc, surface_alias, surface = \
+                      surface_set[0]
+        elif type == 's':
+            desc, shiori_dir, use_makoto, surface_set, balloon, prefix, \
+                  shiori_dll, shiori_name = self.ghosts[0] ## FIXME: this should be default
             shell_name, surface_set, shell_balloon = self.shells[i]
-            name, surface_dir, surface_desc, surface_alias, surface = surface_set[j]
+            name, surface_dir, surface_desc, surface_alias, surface = \
+                  surface_set[j]
         def proc(self=self, item=item):
             self.stop_sakura(ghost, self.start_sakura, item, ghost.current) ## FIXME
         if vanished:
@@ -887,7 +909,7 @@ class Application:
             assert ghost.current[2] != j
             ghost.notify_shell_changing(name, surface_dir, proc)
         else:
-            name = surface_desc.get("sakura.name", desc.get("sakura.name"))
+            name = surface_desc.get('sakura.name', desc.get('sakura.name'))
             ghost.notify_ghost_changing(name, method, proc)
 
     def stop_sakura(self, ghost, starter=None, *args): ## FIXME
@@ -936,7 +958,8 @@ class Application:
         ghost.set_surface_alpha(self.get_surface_alpha())
         ghost.set_balloon_alpha(self.get_balloon_alpha())
         ghost.set_script_speed(self.get_script_speed())
-        ghost.start(item, init, temp, vanished, ghost_changed, self.get_ignore_default(), name)
+        ghost.start(item, init, temp, vanished, ghost_changed,
+                    self.get_ignore_default(), name)
 
     def start_sakura_cb(self, event, item):
         self.start_sakura(item, init=1)
@@ -944,7 +967,7 @@ class Application:
     def get_balloon_description(self, name):
         number = self.find_balloon_by_name(name)
         if number is None:
-            ##print "Balloon %s not found." % name
+            ##print 'Balloon %s not found.' % name
             default_balloon = self.get_default_balloon()
             number = self.find_balloon_by_name(default_balloon) or 0
         desc, balloon = self.balloons[number]
@@ -961,11 +984,12 @@ class Application:
     def reload_current_sakura(self, ghost):
         self.save_preferences()
         type, i, j = ghost.current
-        if type == "s":
+        if type == 's':
             i = 0
         home_dir = ninix.home.get_ninix_home()
         ghost_dir = ghost.get_prefix()
-        ghost_conf, shell_conf = ninix.home.search_ghosts(home_dir, [ghost_dir])
+        ghost_conf, shell_conf = ninix.home.search_ghosts(home_dir,
+                                                          [ghost_dir])
         if ghost_conf:
             self.ghosts[i] = ghost_conf[0]
         else:
@@ -977,15 +1001,16 @@ class Application:
 
     def reload_config(self): ## FIXME
         self.save_preferences()
-        sys.stdout.write("reloading...")
+        sys.stdout.write('reloading...')
         sys.stdout.flush()
         config = ninix.home.load_config()
         if config is None:
-            sys.stdout.write("failed! (abort)\n")
+            sys.stdout.write('failed! (abort)\n')
             sys.exit(1)
-        self.ghosts, self.shells, self.balloons, self.plugins, self.nekoninni, self.katochan, self.kinoko = config ## FIXME: check number of ghosts/balloons
+        self.ghosts, self.shells, self.balloons, self.plugins, \
+                     self.nekoninni, self.katochan, self.kinoko = config ## FIXME: check number of ghosts/balloons
         self.load()
-        sys.stdout.write("done.\n")
+        sys.stdout.write('done.\n')
 
     def reload_sakura(self): ## FIXME
         self.ghost.unload_shiori() ## FIXME
@@ -999,13 +1024,13 @@ class Application:
         prefix = ghost.get_prefix()
         for file in os.listdir(prefix):
             if file != 'HISTORY':
-                command = "rm -rf " + os.path.join(prefix, file)
+                command = ''.join(('rm -rf ', os.path.join(prefix, file)))
                 print command
                 if os.system(command):
-                    print "***FAILED***"
+                    print '***FAILED***'
         # select another ghost
         type, i, j = ghost.current
-        if type == "s":
+        if type == 's':
             i = 0
         list = self.range_ghosts()
         list.remove(i)
@@ -1016,7 +1041,7 @@ class Application:
         # reload and start the new ghost
         self.ghosts[i] = None
         self.update_ghost_list(i, ghost)
-        self.change_sakura(ghost, ('g', next_i, 0), "automatic", vanished=1)
+        self.change_sakura(ghost, ('g', next_i, 0), 'automatic', vanished=1)
 
     def select_plugin(self, event, item):
         i, j = item
@@ -1037,12 +1062,12 @@ class Application:
             try:
                 (pid, status) = os.waitpid(pid, os.WNOHANG)
             except OSError:
-                ##print "Process %d not found." % pid
+                ##print 'Process %d not found.' % pid
                 self.plugin_pids.remove(pid)
             if pid > 0:
-                ##print "Process %d terminated." % pid
+                ##print 'Process %d terminated.' % pid
                 self.plugin_pids.remove(pid)
-        ##print "Running subprocesses:", self.plugin_pids
+        ##print 'Running subprocesses:', self.plugin_pids
 
     def get_sstp_port(self):
         if not self.sstp_servers:
@@ -1050,27 +1075,27 @@ class Application:
         return self.sstp_servers[0].server_address[1]
 
     def exec_plugin(self, plugin_dir, argv):
-        ##print "exec_plugin:", string.join(argv)
+        ##print 'exec_plugin:', ' '.join(argv)
         if not os.path.exists(argv[0]):
             return
         port = self.get_sstp_port()
         if port is None:
-            port = "none"
+            port = 'none'
         environ = os.environ.copy()
-        environ["NINIX_PID"] = str(os.getpid())
-        environ["NINIX_SSTP_PORT"] = str(port)
-        environ["NINIX_PLUGIN_DIR"] = plugin_dir
+        environ['NINIX_PID'] = str(os.getpid())
+        environ['NINIX_SSTP_PORT'] = str(port)
+        environ['NINIX_PLUGIN_DIR'] = plugin_dir
         try:
             pid = os.fork()
         except OSError:
-            sys.stderr.write("Error: %s failed (ignored)\n" % argv[0])
+            sys.stderr.write('Error: %s failed (ignored)\n' % argv[0])
             return
         if pid == 0:
             os.chdir(plugin_dir)
             try:
                 os.execve(argv[0], argv, environ)
             except OSError:
-                sys.stderr.write("Error: %s failed (abort)\n" % argv[0])
+                sys.stderr.write('Error: %s failed (abort)\n' % argv[0])
                 os._exit(1)
         self.plugin_pids.append(pid)
 
@@ -1174,15 +1199,17 @@ class Application:
             if self.ghosts[i] is None:
                 continue
             desc = self.ghosts[i][0]
-            name = desc.get("name", unicode(_("Ghost"), 'utf-8') + "#%d" % (i + 1))
+            name = desc.get('name',
+                            ''.join((unicode(_('Ghost'), 'utf-8'),
+                                     '#%d' % (i + 1))))
             ghost_time = 0
             prefix = self.ghosts[i][5]
             path = os.path.join(prefix, 'HISTORY')
             if os.path.exists(path):
                 try:
-                    file = open(path, "r")
+                    file = open(path, 'r')
                 except IOError, (code, message):
-                    sys.stderr.write("cannot read %s\n" % path)
+                    sys.stderr.write('cannot read %s\n' % path)
                 else:
                     while 1:
                         line = file.readline()
@@ -1191,7 +1218,7 @@ class Application:
                         comma = line.find(',')
                         if comma >= 0:
                             key = line[:comma].strip()
-                            value = line[comma+1:].strip()
+                            value = line[comma + 1:].strip()
                         if key == 'time':
                             try:
                                 ghost_time = int(value)
@@ -1220,37 +1247,38 @@ class PreferenceDialog:
     def __init__(self, app):
         self.app = app
         self.window = gtk.Dialog()
-        self.window.set_title("Preferences")
-        self.window.connect("delete_event", self.cancel)
+        self.window.set_title('Preferences')
+        self.window.connect('delete_event', self.cancel)
         self.notebook = gtk.Notebook()
         self.notebook.set_tab_pos(gtk.POS_TOP)
         self.window.vbox.pack_start(self.notebook)
         self.notebook.show()
         for name, constructor in [
-            (_("Event"),           self.make_page_events),
-            (_("Font"),            self.make_page_fonts),
-            (_("Mouse"),           self.make_page_mouse),
-            (_("Browser"),         self.make_page_browser),
-            (_("Helper"),          self.make_page_helper),
-            (_("Surface&Balloon"), self.make_page_surface_n_balloon),
-            (_("Misc"),            self.make_page_misc),
-            (_("Debug"),           self.make_page_debug),
+            (_('Event'),           self.make_page_events),
+            (_('Font'),            self.make_page_fonts),
+            (_('Mouse'),           self.make_page_mouse),
+            (_('Browser'),         self.make_page_browser),
+            (_('Helper'),          self.make_page_helper),
+            (_('Surface&Balloon'), self.make_page_surface_n_balloon),
+            (_('Misc'),            self.make_page_misc),
+            (_('Debug'),           self.make_page_debug),
             ]:
-            self.notebook.append_page(constructor(), gtk.Label(unicode(name, 'utf-8')))
+            self.notebook.append_page(constructor(),
+                                      gtk.Label(unicode(name, 'utf-8')))
         box = gtk.HButtonBox()
         box.set_layout(gtk.BUTTONBOX_END)
         self.window.action_area.pack_start(box)
         box.show()
-        button = gtk.Button("OK")
-        button.connect("clicked", self.ok)
+        button = gtk.Button('OK')
+        button.connect('clicked', self.ok)
         box.add(button)
         button.show()
-        button = gtk.Button("Apply")
-        button.connect("clicked", self.apply)
+        button = gtk.Button('Apply')
+        button.connect('clicked', self.apply)
         box.add(button)
         button.show()
-        button = gtk.Button("Cancel")
-        button.connect("clicked", self.cancel)
+        button = gtk.Button('Cancel')
+        button.connect('clicked', self.cancel)
         box.add(button)
         button.show()
         self.rule_editor = RuleEditor(self.window)
@@ -1274,7 +1302,7 @@ class PreferenceDialog:
         self.window.hide()
 
     def make_page_events(self):
-        frame = gtk.Frame(unicode(_("Event(s) to be ignored"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('Event(s) to be ignored'), 'utf-8'))
         frame.set_size_request(480, 300)
         frame.set_border_width(5)
         frame.show()
@@ -1288,20 +1316,20 @@ class PreferenceDialog:
         box.pack_start(table, False)
         table.show()
         events = [
-            "OnBoot",          "OnClose",
-            "OnGhostChanging", "OnGhostChanged",
-            "OnShellChanging", "OnShellChanged",
-            "OnSurfaceChange", "OnSurfaceRestore",
-            "OnMinuteChange",  "OnSecondChange",
-            "OnMouseClick",    "OnMouseDoubleClick",
-            "OnMouseMove",     "OnMouseWheel",
-            "OnKeyPress",
+            'OnBoot',          'OnClose',
+            'OnGhostChanging', 'OnGhostChanged',
+            'OnShellChanging', 'OnShellChanged',
+            'OnSurfaceChange', 'OnSurfaceRestore',
+            'OnMinuteChange',  'OnSecondChange',
+            'OnMouseClick',    'OnMouseDoubleClick',
+            'OnMouseMove',     'OnMouseWheel',
+            'OnKeyPress',
             ]
         self.event_kill_list = {}
         for i in range(len(events)):
             y, x = divmod(i, 2)
             button = gtk.CheckButton(events[i])
-            table.attach(button, x, x+1, y, y+1)
+            table.attach(button, x, x + 1, y, y + 1)
             button.show()
             self.event_kill_list[events[i]] = button
         return frame
@@ -1310,7 +1338,7 @@ class PreferenceDialog:
         page = gtk.VBox(spacing=5)
         page.set_border_width(5)
         # font
-        frame = gtk.Frame(unicode(_("Font(s) for balloons"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('Font(s) for balloons'), 'utf-8'))
         frame.set_size_request(480, -1)
         page.pack_start(frame)
         frame.show()
@@ -1323,7 +1351,7 @@ class PreferenceDialog:
     def make_page_mouse(self):
         page = gtk.VBox(spacing=5)
         page.set_border_width(5)
-        frame = gtk.Frame(unicode(_("Left button"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('Left button'), 'utf-8'))
         frame.set_size_request(400, 125)
         frame.show()
         page.pack_start(frame)
@@ -1331,13 +1359,16 @@ class PreferenceDialog:
         frame.add(box)
         box.show()
         box.set_border_width(5)
-        button1 = gtk.RadioButton(None, unicode(_("delete balloon(s)"), 'utf-8'))
+        button1 = gtk.RadioButton(None,
+                                  unicode(_('delete balloon(s)'), 'utf-8'))
         box.pack_start(button1, False)
         button1.show()
-        button2 = gtk.RadioButton(button1, unicode(_("raise all windows"), 'utf-8'))
+        button2 = gtk.RadioButton(button1,
+                                  unicode(_('raise all windows'), 'utf-8'))
         box.pack_start(button2, False)
         button2.show()
-        button3 = gtk.RadioButton(button1, unicode(_("lower all windows"), 'utf-8'))
+        button3 = gtk.RadioButton(button1,
+                                  unicode(_('lower all windows'), 'utf-8'))
         box.pack_start(button3, False)
         button3.show()
         self.mouse_button1 = {
@@ -1345,7 +1376,7 @@ class PreferenceDialog:
             ninix.sakura.BUTTON1_RAISE: button2,
             ninix.sakura.BUTTON1_LOWER: button3,
             }
-        frame = gtk.Frame(unicode(_("Right button"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('Right button'), 'utf-8'))
         frame.set_size_request(400, 125)
         frame.show()
         page.pack_start(frame)
@@ -1353,13 +1384,16 @@ class PreferenceDialog:
         box.set_border_width(5)
         frame.add(box)
         box.show()
-        button1 = gtk.RadioButton(None, unicode(_("delete balloon(s)"), 'utf-8'))
+        button1 = gtk.RadioButton(None,
+                                  unicode(_('delete balloon(s)'), 'utf-8'))
         box.pack_start(button1, False)
         button1.show()
-        button2 = gtk.RadioButton(button1, unicode(_("raise all windows"), 'utf-8'))
+        button2 = gtk.RadioButton(button1,
+                                  unicode(_('raise all windows'), 'utf-8'))
         box.pack_start(button2, False)
         button2.show()
-        button3 = gtk.RadioButton(button1, unicode(_("lower all windows"), 'utf-8'))
+        button3 = gtk.RadioButton(button1,
+                                  unicode(_('lower all windows'), 'utf-8'))
         box.pack_start(button3, False)
         button3.show()
         self.mouse_button3 = {
@@ -1374,7 +1408,7 @@ class PreferenceDialog:
         page = gtk.VBox(spacing=5)
         page.set_border_width(5)
         # browser
-        frame = gtk.Frame(unicode(_("Browser"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('Browser'), 'utf-8'))
         frame.set_size_request(480, -1)
         page.pack_start(frame)
         frame.show()
@@ -1394,11 +1428,11 @@ class PreferenceDialog:
         box.set_border_width(5)
         frame.add(box)
         box.show()
-        label = gtk.Label(unicode(_("- %s in this command line will be replaced with the URL"), 'utf-8'))
+        label = gtk.Label(unicode(_('- %s in this command line will be replaced with the URL'), 'utf-8'))
         label.set_alignment(0, -1)
         box.pack_start(label, False)
         label.show()
-        label = gtk.Label(unicode(_("- trailing & is not required.(automagically added)"), 'utf-8'))
+        label = gtk.Label(unicode(_('- trailing & is not required.(automagically added)'), 'utf-8'))
         label.set_alignment(0, -1)
         box.pack_start(label, False)
         label.show()
@@ -1408,7 +1442,7 @@ class PreferenceDialog:
     def make_page_helper(self):
         page = gtk.VBox(spacing=5)
         page.set_border_width(5)
-        frame = gtk.Frame(unicode(_("Application"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('Application'), 'utf-8'))
         frame.set_size_request(480, -1)
         page.pack_start(frame)
         frame.show()
@@ -1422,9 +1456,9 @@ class PreferenceDialog:
         swin.show()
         lstore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
         self.helpers = gtk.TreeView(lstore)
-        column = gtk.TreeViewColumn("Pattern", gtk.CellRendererText(), text=0)
+        column = gtk.TreeViewColumn('Pattern', gtk.CellRendererText(), text=0)
         self.helpers.append_column(column)
-        column = gtk.TreeViewColumn("Command", gtk.CellRendererText(), text=1)
+        column = gtk.TreeViewColumn('Command', gtk.CellRendererText(), text=1)
         self.helpers.append_column(column)
         swin.add(self.helpers)
         self.helpers.show()
@@ -1434,24 +1468,24 @@ class PreferenceDialog:
         bbox.set_border_width(5)
         box.pack_start(bbox, False)
         bbox.show()
-        button = gtk.Button("New")
-        button.connect("clicked", self.rule_new)
+        button = gtk.Button('New')
+        button.connect('clicked', self.rule_new)
         bbox.pack_start(button)
         button.show()
-        button = gtk.Button("Edit")
-        button.connect("clicked", self.rule_edit)
+        button = gtk.Button('Edit')
+        button.connect('clicked', self.rule_edit)
         bbox.pack_start(button)
         button.show()
-        button = gtk.Button("Delete")
-        button.connect("clicked", self.rule_delete)
+        button = gtk.Button('Delete')
+        button.connect('clicked', self.rule_delete)
         bbox.pack_start(button)
         button.show()
-        button = gtk.Button("Up")
-        button.connect("clicked", self.rule_up)
+        button = gtk.Button('Up')
+        button.connect('clicked', self.rule_up)
         bbox.pack_start(button)
         button.show()
-        button = gtk.Button("Down")
-        button.connect("clicked", self.rule_down)
+        button = gtk.Button('Down')
+        button.connect('clicked', self.rule_down)
         bbox.pack_start(button)
         button.show()
         frame = gtk.Frame()
@@ -1462,11 +1496,11 @@ class PreferenceDialog:
         box.set_border_width(5)
         frame.add(box)
         box.show()
-        label = gtk.Label(unicode(_("- %s in this command line will be replaced with the filename"), 'utf-8'))
+        label = gtk.Label(unicode(_('- %s in this command line will be replaced with the filename'), 'utf-8'))
         label.set_alignment(0, -1)
         box.pack_start(label, False)
         label.show()
-        label = gtk.Label(unicode(_("- trailing & is not required.(automagically added)"), 'utf-8'))
+        label = gtk.Label(unicode(_('- trailing & is not required.(automagically added)'), 'utf-8'))
         label.set_alignment(0, -1)
         box.pack_start(label, False)
         label.show()
@@ -1477,7 +1511,7 @@ class PreferenceDialog:
         page = gtk.VBox(spacing=5)
         page.set_border_width(5)
         page.show()
-        frame = gtk.Frame(unicode(_("Surface Scaling"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('Surface Scaling'), 'utf-8'))
         frame.set_size_request(480, -1)
         page.pack_start(frame, False)
         frame.show()
@@ -1488,7 +1522,7 @@ class PreferenceDialog:
         hbox = gtk.HBox(spacing=5)
         box.pack_start(hbox, False)
         hbox.show()
-        label = gtk.Label(unicode(_("Default Setting"), 'utf-8'))
+        label = gtk.Label(unicode(_('Default Setting'), 'utf-8'))
         hbox.pack_start(label, False)
         label.show()
         self.surface_scale_combo = gtk.combo_box_new_text()
@@ -1496,11 +1530,11 @@ class PreferenceDialog:
             self.surface_scale_combo.append_text(label)
         hbox.pack_start(self.surface_scale_combo, False)
         self.surface_scale_combo.show()
-        button = gtk.CheckButton(unicode(_("Scale Balloon"), 'utf-8'))
+        button = gtk.CheckButton(unicode(_('Scale Balloon'), 'utf-8'))
         self.balloon_scalling_button = button
         box.pack_start(button, False)
         button.show()
-        frame = gtk.Frame(unicode(_("Default Balloon"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('Default Balloon'), 'utf-8'))
         frame.set_size_request(480, -1)
         page.pack_start(frame)
         frame.show()
@@ -1515,22 +1549,22 @@ class PreferenceDialog:
         scrolled.show()
         model = gtk.ListStore(gobject.TYPE_STRING)
         for desc, balloon in self.app.balloons:
-            name = desc.get("name", "")
+            name = desc.get('name', '')
             iter = model.append()
             model.set_value(iter, 0, name)
         treeview = gtk.TreeView(model)
         column = gtk.TreeViewColumn(
-            _("Balloon Name"), gtk.CellRendererText(), text=0)
+            _('Balloon Name'), gtk.CellRendererText(), text=0)
         treeview.append_column(column)
         treeview.get_selection().set_mode(gtk.SELECTION_SINGLE)
         self.balloon_treeview = treeview
         scrolled.add(treeview)
         treeview.show()
-        button = gtk.CheckButton(unicode(_("Always Use This Balloon"), 'utf-8'))
+        button = gtk.CheckButton(unicode(_('Always Use This Balloon'), 'utf-8'))
         self.ignore_button = button
         box.pack_start(button, False)
         button.show()
-        frame = gtk.Frame(unicode(_("Translucency"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('Translucency'), 'utf-8'))
         frame.set_size_request(480, -1)
         page.pack_start(frame, False)
         frame.show()
@@ -1538,7 +1572,7 @@ class PreferenceDialog:
         box.set_border_width(5)
         frame.add(box)
         box.show()
-        button = gtk.CheckButton(unicode(_("Use PNA file"), 'utf-8'))
+        button = gtk.CheckButton(unicode(_('Use PNA file'), 'utf-8'))
         self.use_pna_button = button
         box.pack_start(button, False)
         button.show()
@@ -1569,22 +1603,22 @@ class PreferenceDialog:
         page = gtk.VBox(spacing=5)
         page.set_border_width(5)
         page.show()
-        frame = gtk.Frame(unicode(_("SSTP Setting"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('SSTP Setting'), 'utf-8'))
         frame.set_size_request(480, -1)
         page.pack_start(frame, False)
         frame.show()
-        button = gtk.CheckButton(unicode(_("Allowembryo"), 'utf-8'))
+        button = gtk.CheckButton(unicode(_('Allowembryo'), 'utf-8'))
         self.allowembryo_button = button
         frame.add(button)
         button.show()
-        frame = gtk.Frame(unicode(_("Script Wait"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('Script Wait'), 'utf-8'))
         frame.set_size_request(480, -1)
         page.pack_start(frame, False)
         frame.show()
         hbox = gtk.HBox(spacing=5)
         frame.add(hbox)
         hbox.show()
-        label = gtk.Label(unicode(_("Default Setting"), 'utf-8'))
+        label = gtk.Label(unicode(_('Default Setting'), 'utf-8'))
         hbox.pack_start(label, False)
         label.show()
         self.script_speed_combo = gtk.combo_box_new_text()
@@ -1592,7 +1626,7 @@ class PreferenceDialog:
             self.script_speed_combo.append_text(label)
         hbox.pack_start(self.script_speed_combo, False)
         self.script_speed_combo.show()
-        frame = gtk.Frame(unicode(_("Top & Bottom Margin"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('Top & Bottom Margin'), 'utf-8'))
         frame.set_size_request(480, -1)
         page.pack_start(frame, False)
         frame.show()
@@ -1603,24 +1637,24 @@ class PreferenceDialog:
         hbox = gtk.HBox(spacing=5)
         box.add(hbox)
         hbox.show()
-        label = gtk.Label(unicode(_("Top Margin"), 'utf-8'))
+        label = gtk.Label(unicode(_('Top Margin'), 'utf-8'))
         hbox.pack_start(label, False)
         label.show()
-        self.top_adjustment = gtk.Adjustment(0, 0, scrn_h/4, 1)
+        self.top_adjustment = gtk.Adjustment(0, 0, scrn_h / 4, 1)
         button = gtk.SpinButton(self.top_adjustment)
         hbox.pack_start(button, False)
         button.show()
         hbox = gtk.HBox(spacing=5)
         box.add(hbox)
         hbox.show()
-        label = gtk.Label(unicode(_("Bottom Margin"), 'utf-8'))
+        label = gtk.Label(unicode(_('Bottom Margin'), 'utf-8'))
         hbox.pack_start(label, False)
         label.show()
-        self.bottom_adjustment = gtk.Adjustment(0, 0, scrn_h/4, 1)
+        self.bottom_adjustment = gtk.Adjustment(0, 0, scrn_h / 4, 1)
         button = gtk.SpinButton(self.bottom_adjustment)
         hbox.pack_start(button, False)
         button.show()
-        frame = gtk.Frame(unicode(_("Raise & Lower"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('Raise & Lower'), 'utf-8'))
         frame.set_size_request(480, -1)
         page.pack_start(frame, False)
         frame.show()
@@ -1628,11 +1662,11 @@ class PreferenceDialog:
         box.set_border_width(5)
         frame.add(box)
         box.show()
-        button = gtk.CheckButton(unicode(_("Sink after Talk"), 'utf-8'))
+        button = gtk.CheckButton(unicode(_('Sink after Talk'), 'utf-8'))
         self.sink_after_talk_button = button
         box.pack_start(button, False)
         button.show()
-        button = gtk.CheckButton(unicode(_("Raise before Talk"), 'utf-8'))
+        button = gtk.CheckButton(unicode(_('Raise before Talk'), 'utf-8'))
         self.raise_before_talk_button = button
         box.pack_start(button, False)
         button.show()
@@ -1642,20 +1676,20 @@ class PreferenceDialog:
         page = gtk.VBox(spacing=5)
         page.set_border_width(5)
         page.show()
-        frame = gtk.Frame(unicode(_("Surface Debugging"), 'utf-8'))
+        frame = gtk.Frame(unicode(_('Surface Debugging'), 'utf-8'))
         frame.set_size_request(480, -1)
         page.pack_start(frame, False)
         frame.show()
-        button = gtk.CheckButton(unicode(_("Display Collision Area"), 'utf-8'))
+        button = gtk.CheckButton(unicode(_('Display Collision Area'), 'utf-8'))
         self.check_collision_button = button
         frame.add(button)
         button.show()
         return page
 
     def rule_new(self, widget):
-        self.rule_editor.set_pattern("")
-        self.rule_editor.set_command("")
-        if self.rule_editor.run("New rule..."):
+        self.rule_editor.set_pattern('')
+        self.rule_editor.set_command('')
+        if self.rule_editor.run('New rule...'):
             pattern = self.rule_editor.get_pattern()
             command = self.rule_editor.get_command()
             lstore = self.helpers.get_model()
@@ -1671,7 +1705,7 @@ class PreferenceDialog:
         command = lstore.get_value(iter, 1)
         self.rule_editor.set_pattern(pattern)
         self.rule_editor.set_command(command)
-        if self.rule_editor.run("Edit rule..."):
+        if self.rule_editor.run('Edit rule...'):
             pattern = self.rule_editor.get_pattern()
             command = self.rule_editor.get_command()
             lstore.set(iter, 0, pattern, 1, command)
@@ -1706,7 +1740,7 @@ class PreferenceDialog:
 
     def set_event_kill_list(self, kill_list):
         for name in self.event_kill_list.keys():
-            if name == "OnFirstBoot":
+            if name == 'OnFirstBoot':
                 continue
             if name in kill_list:
                 self.event_kill_list[name].set_active(True)
@@ -1718,8 +1752,8 @@ class PreferenceDialog:
         for name in self.event_kill_list.keys():
             if self.event_kill_list[name].get_active():
                 buffer.append(name)
-                if name == "OnBoot":
-                    buffer.append("OnFirstBoot")
+                if name == 'OnBoot':
+                    buffer.append('OnFirstBoot')
         return buffer
 
     def set_balloon_fonts(self, name):
@@ -1939,7 +1973,7 @@ class RuleEditor:
 
     def __init__(self, master=None):
         self.dialog = gtk.Dialog()
-        self.dialog.connect("delete_event", self.cancel)
+        self.dialog.connect('delete_event', self.cancel)
         self.dialog.set_modal(True)
         self.dialog.set_position(gtk.WIN_POS_CENTER)
         if master is not None:
@@ -1950,25 +1984,25 @@ class RuleEditor:
         table.set_col_spacings(5)
         table.set_border_width(10)
         self.dialog.vbox.pack_start(table)
-        label = gtk.Label("Pattern")
+        label = gtk.Label('Pattern')
         table.attach(label, 0, 1, 0, 1, xoptions=gtk.FILL)
         self.pattern_entry = gtk.Entry()
         self.pattern_entry.set_size_request(300, -1)
-        self.pattern_entry.connect("changed", self.changed)
+        self.pattern_entry.connect('changed', self.changed)
         table.attach(self.pattern_entry, 1, 2, 0, 1)
-        label = gtk.Label("Command")
+        label = gtk.Label('Command')
         table.attach(label, 0, 1, 1, 2, xoptions=gtk.FILL)
         self.command_entry = gtk.Entry()
         self.command_entry.set_size_request(300, -1)
-        self.command_entry.connect("changed", self.changed)
+        self.command_entry.connect('changed', self.changed)
         table.attach(self.command_entry, 1, 2, 1, 2)
         self.dialog.vbox.show_all()
         # buttons
-        self.ok_button = gtk.Button("OK")
-        self.ok_button.connect("clicked", self.ok)
+        self.ok_button = gtk.Button('OK')
+        self.ok_button.connect('clicked', self.ok)
         self.dialog.action_area.pack_start(self.ok_button)
-        button = gtk.Button("Cancel")
-        button.connect("clicked", self.cancel)
+        button = gtk.Button('Cancel')
+        button.connect('clicked', self.cancel)
         self.dialog.action_area.pack_start(button)
         self.dialog.action_area.show_all()
 
@@ -2015,22 +2049,22 @@ class UsageDialog:
 
     def __init__(self):
         self.window = gtk.Dialog()
-        self.window.set_title("Usage")
-        self.window.connect("delete_event", self.close)
+        self.window.set_title('Usage')
+        self.window.connect('delete_event', self.close)
         self.darea = gtk.DrawingArea()
         self.darea.set_events(gtk.gdk.EXPOSURE_MASK)
         self.size = (550, 330)
         apply(self.darea.set_size_request, self.size)
-        self.darea.connect("configure_event", self.configure)
-        self.darea.connect("expose_event", self.redraw)
+        self.darea.connect('configure_event', self.configure)
+        self.darea.connect('expose_event', self.redraw)
         self.window.vbox.pack_start(self.darea)
         self.darea.show()
         box = gtk.HButtonBox()
         box.set_layout(gtk.BUTTONBOX_END)
         self.window.action_area.pack_start(box)
         box.show()
-        button = gtk.Button("Close")
-        button.connect("clicked", self.close)
+        button = gtk.Button('Close')
+        button.connect('clicked', self.close)
         box.add(button)
         button.show()
         self.opened = 0
@@ -2045,7 +2079,7 @@ class UsageDialog:
             self.items.append((name, clock, path))
         self.items.sort(lambda x, y: cmp(y[1], x[1]))
         list = self.items[0][2]
-        if len(list) > 0:
+        if list:
             path = random.choice(list)
             assert os.path.exists(path)
             self.pixbuf = ninix.pix.create_pixbuf_from_file(path, type='png')
@@ -2080,7 +2114,7 @@ class UsageDialog:
         black_gc = darea.get_style().black_gc
         cmap = darea.get_colormap()
         gray_gc = darea.window.new_gc()
-        gray_gc.foreground = cmap.alloc_color("#cfcfcf")
+        gray_gc.foreground = cmap.alloc_color('#cfcfcf')
         # redraw graph
         w, h = self.size
         darea.window.draw_rectangle(white_gc, True, 0, 0, w, h)
@@ -2092,40 +2126,42 @@ class UsageDialog:
         for name, clock, path in self.items[:14]:
             layout.set_text(name)
             name_w, name_h = layout.get_pixel_size()
-            rate = "%.1f%%" % (clock / total * 100)
+            rate = '%.1f%%' % (clock / total * 100)
             layout.set_text(rate)
             rate_w, rate_h = layout.get_pixel_size()
             w3 = max(rate_w, w3)
-            time = "%d:%02d" % divmod(clock / 60, 60)
+            time = '%d:%02d' % divmod(clock / 60, 60)
             layout.set_text(time)
             time_w, time_h = layout.get_pixel_size()
             w4 = max(time_w, w4)
-            rows.append((clock, name, name_w, name_h, rate, rate_w, rate_h, time, time_w, time_h))
+            rows.append((clock, name, name_w, name_h, rate, rate_w, rate_h,
+                         time, time_w, time_h))
         w1 = 280
         w2 = w - w1 - w3 - w4 - 70
         x = 20
         y = 15
         x += w1 + 10
-        label = "name"
+        label = 'name'
         layout.set_text(label)
         label_name_w, label_name_h = layout.get_pixel_size()
         darea.window.draw_layout(gray_gc, x, y, layout)
         x = x + w2 + 10
-        label = "rate"
+        label = 'rate'
         layout.set_text(label)
         label_rate_w, label_rate_h = layout.get_pixel_size()
         darea.window.draw_layout(gray_gc, x + w3 - label_rate_w, y, layout)
         x += w3 + 10
-        label = "time"
+        label = 'time'
         layout.set_text(label)
         label_time_w, label_time_h = layout.get_pixel_size()
         darea.window.draw_layout(gray_gc, x + w4 - label_time_w, y, layout)
         y += max([label_name_h, label_rate_h, label_time_h]) + 4
-        for clock, name, name_w, name_h, rate, rate_w, rate_h, time, time_w, time_h  in rows:
+        for clock, name, name_w, name_h, rate, rate_w, rate_h, time, time_w, \
+                time_h  in rows:
             x = 20
             bw = int(clock / total * w1)
             bh = max([name_h, rate_h, time_h]) - 1
-            darea.window.draw_rectangle(gray_gc,  False, x+1, y+1, bw, bh)
+            darea.window.draw_rectangle(gray_gc,  False, x + 1, y + 1, bw, bh)
             darea.window.draw_rectangle(white_gc, False, x, y, bw, bh)
             darea.window.draw_rectangle(black_gc, False, x, y, bw, bh)
             x += w1 + 10
@@ -2135,7 +2171,7 @@ class UsageDialog:
                 w, h = layout.get_pixel_size()
                 if w > 168:
                     end -= 1
-                    layout.set_text(name[:end] + u'...')
+                    layout.set_text(''.join((name[:end], u'...')))
                 else:
                     break
             darea.window.draw_layout(black_gc, x, y, layout)
@@ -2147,5 +2183,6 @@ class UsageDialog:
             darea.window.draw_layout(black_gc, x + w4 - time_w, y, layout)
             y += max([name_h, rate_h, time_h]) + 4
 
-if __name__ == "__main__":
+
+if __name__ == '__main__':
     main()
index d4b880b..f93f130 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: ascii -*-
 #
 #  Copyright (C) 2001, 2002 by Tamito KAJIYAMA
-#  Copyright (C) 2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2004, 2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: makoto.py,v 1.6 2004/06/23 05:57:04 shy Exp $
+# $Id: makoto.py,v 1.7 2005/08/09 00:41:52 shy Exp $
 #
 
-import string
 import random
 
 def execute(s):
@@ -23,7 +22,7 @@ def execute(s):
     while i < j:
         i, text = expand(s, i)
         buffer.append(text)
-    return string.join(buffer, '')
+    return ''.join(buffer)
 
 def expand(s, start):
     segments = []
@@ -34,14 +33,14 @@ def expand(s, start):
     buffer = []
     while i < j:
         if s[i] == '\\':
-            if i + 1 < j and s[i+1] in ['(', '|', ')']:
-                buffer.append(s[i+1])
+            if i + 1 < j and s[i + 1] in ['(', '|', ')']:
+                buffer.append(s[i + 1])
             else:
-                buffer.append(s[i:i+2])
+                buffer.append(s[i:i + 2])
             i += 2
         elif s[i] == '(':
             if validity == 0:
-                segments.append(string.join(buffer, ''))
+                segments.append(''.join(buffer))
                 buffer = []
                 i += 1
             else:
@@ -49,13 +48,13 @@ def expand(s, start):
                 buffer.append(text)
             validity = 1
         elif s[i] == '|' and validity > 0:
-            segments.append(string.join(buffer, ''))
+            segments.append(''.join(buffer))
             buffer = []
             i += 1
         elif s[i] == ')' and validity > 0:
-            segments.append(string.join(buffer, ''))
+            segments.append(''.join(buffer))
             i += 1
-            if i < j and s[i] in "123456789":
+            if i < j and s[i] in '123456789':
                 repeat_count = int(s[i])
                 i += 1
             validity = 2
@@ -69,49 +68,49 @@ def expand(s, start):
             expanded = expanded * random.randint(0, repeat_count)
         return i, segments[0] + expanded
     elif validity == 0:
-        return j, string.join(buffer, '')
+        return j, ''.join(buffer)
     else:
         return j, s[start:]
 
 def test(verbose=0):
-    for test, expected in [(r"a(1)b", ["a1b"]),
-                           (r"a(1|2)b", ["a1b", "a2b"]),
-                           (r"a(1)2b", ["ab", "a1b", "a11b"]),
-                           (r"a(1|2)1b", ["ab", "a1b", "a2b"]),
-                           (r"(1|2)(a|b)", ["1a", "1b", "2a", "2b"]),
-                           (r"((1|2)|(a|b))", ["1", "2", "a", "b"]),
-                           (r"()", [""]),
-                           (r"()2", [""]),
-                           (r"a()b", ["ab"]),
-                           (r"a()2b", ["ab"]),
-                           (r"a\(1\|2\)b", ["a(1|2)b"]),
-                           (r"\((1|2)\)", ["(1)", "(2)"]),
-                           (r"\(1)", ["(1)"]),
-                           (r"a|b", ["a|b"]),
+    for test, expected in [(r'a(1)b', ['a1b']),
+                           (r'a(1|2)b', ['a1b', 'a2b']),
+                           (r'a(1)2b', ['ab', 'a1b', 'a11b']),
+                           (r'a(1|2)1b', ['ab', 'a1b', 'a2b']),
+                           (r'(1|2)(a|b)', ['1a', '1b', '2a', '2b']),
+                           (r'((1|2)|(a|b))', ['1', '2', 'a', 'b']),
+                           (r'()', ['']),
+                           (r'()2', ['']),
+                           (r'a()b', ['ab']),
+                           (r'a()2b', ['ab']),
+                           (r'a\(1\|2\)b', ['a(1|2)b']),
+                           (r'\((1|2)\)', ['(1)', '(2)']),
+                           (r'\(1)', ['(1)']),
+                           (r'a|b', ['a|b']),
                            # errornous cases
-                           (r"(1", ["(1"]),
-                           (r"(1\)", ["(1\)"]),
-                           (r"(1|2", ["(1|2"]),
-                           (r"(1|2\)", ["(1|2\)"]),
-                           (r"(1|2)(a|b", ["1(a|b", "2(a|b"]),
-                           (r"((1|2)|(a|b)", ["((1|2)|(a|b)"]),
+                           (r'(1', ['(1']),
+                           (r'(1\)', ['(1\)']),
+                           (r'(1|2', ['(1|2']),
+                           (r'(1|2\)', ['(1|2\)']),
+                           (r'(1|2)(a|b', ['1(a|b', '2(a|b']),
+                           (r'((1|2)|(a|b)', ['((1|2)|(a|b)']),
                            ]:
         result = execute(test)
         if verbose:
-            print repr(test), "=>", repr(result), "...",
+            print repr(test), '=>', repr(result), '...',
         try:
             if expected is None:
                 assert(result == test)
             else:
                 assert(result in expected)
             if verbose:
-                print  "OK"
+                print  'OK'
         except AssertionError:
             if verbose:
-                print  "NG"
+                print  'NG'
             raise
 
-if __name__ == "__main__":
-    print "testing..."
+if __name__ == '__main__':
+    print 'testing...'
     for i in range(1000): test()
     test(1)
index 2aa5feb..b4f41a0 100644 (file)
 
 import os
 import re
-import types
 
-if os.environ.has_key("DISPLAY"):
+if os.environ.has_key('DISPLAY'):
     import gtk
     import ninix.pix
 
 import ninix.sakura
 import ninix.surface
 
+
 class Menu:
 
     def __init__(self, ghost, surface):
@@ -89,7 +89,8 @@ class Menu:
                                '', lambda *a: self.__ghost.edit_preferences()),
                               None, 1, 1],
             'File/Manager': [('Manager', None, _('Ghost Manager(_M)'), None,
-                              '', lambda *a: self.__ghost.open_ghost_manager()),
+                              '',
+                              lambda *a: self.__ghost.open_ghost_manager()),
                              None, 1, 1],
             'File/Usage': [('Usage', None, _('Usage graph(_A)'), None,
                             '', lambda *a: self.__ghost.show_usage()),
@@ -130,9 +131,9 @@ class Menu:
         self.__shell_list = None
         self.__balloon_list = None
         self.__plugin_list = None
-        self.__fontcolor = "#000000" ## FIXME
+        self.__fontcolor = '#000000' ## FIXME
         self.__sidebar_width = 0
-        actions = gtk.ActionGroup("Actions")
+        actions = gtk.ActionGroup('Actions')
         entry = []
         for key in self.__menu_list.keys():
             if key != 'Stick':
@@ -142,7 +143,7 @@ class Menu:
         self.ui_manager = gtk.UIManager()
         self.ui_manager.insert_action_group(actions, 0)
         self.ui_manager.add_ui_from_string(ui_info)
-        self.__popup_menu = self.ui_manager.get_widget("/popup")
+        self.__popup_menu = self.ui_manager.get_widget('/popup')
         self.__create_scale_menu()
         self.__create_speed_menu()
 
@@ -153,7 +154,7 @@ class Menu:
             item.set_active(True)
         else:
             item.set_active(False)
-        item.connect("activate", self.toggle_balloon_scalling)
+        item.connect('activate', self.toggle_balloon_scalling)
         menu.add(item)
         item.show()
         item = gtk.SeparatorMenuItem()
@@ -162,13 +163,13 @@ class Menu:
         group = None
         for label, value in ninix.surface.range_scale:
             item = group = gtk.RadioMenuItem(group, label)
-            item.set_name("popup menu item")
-            item.connect("activate", self.select_surface_scale, value)
+            item.set_name('popup menu item')
+            item.connect('activate', self.select_surface_scale, value)
             if value == self.__ghost.get_surface_scale():
                 item.set_active(True)
             item.show()
             menu.append(item)
-        menuitem = self.ui_manager.get_widget('/popup/' + 'Scaling')
+        menuitem = self.ui_manager.get_widget(''.join(('/popup/', 'Scaling')))
         menuitem.set_submenu(menu)
         self.__menu_list['Scaling'][3] = 1 # changed
 
@@ -177,22 +178,22 @@ class Menu:
         group = None
         for label, value in ninix.sakura.range_script_speed:
             item = group = gtk.RadioMenuItem(group, unicode(label, 'utf-8'))
-            item.set_name("popup menu item")
-            item.connect("activate", self.select_script_speed, value)
+            item.set_name('popup menu item')
+            item.connect('activate', self.select_script_speed, value)
             if value == self.__surface.sakura.get_script_speed(): ## FIXME
                 item.set_active(True)
             item.show()
             menu.append(item)
-        menuitem = self.ui_manager.get_widget('/popup/' + 'Wait')
+        menuitem = self.ui_manager.get_widget(''.join(('/popup/', 'Wait')))
         menuitem.set_submenu(menu)
         self.__menu_list['Wait'][3] = 1 # changed
 
     def select_surface_scale(self, widget, value):
-        ##print "select_surface_scale", value
+        ##print 'select_surface_scale', value
         self.__ghost.set_surface_scale(value)
 
     def select_script_speed(self, widget, value):
-        ##print "select_script_speed", value
+        ##print 'select_script_speed', value
         self.__surface.sakura.set_script_speed(value) ## FIXME
 
     def toggle_balloon_scalling(self, widget, value=None):
@@ -203,13 +204,14 @@ class Menu:
         self.__ghost.set_balloon_scalling(balloon_scalling)
 
     def set_fontcolor(self, r, g ,b):
-        self.__fontcolor = "#%02x%02x%02x" % (r, g, b)
+        self.__fontcolor = '#%02x%02x%02x' % (r, g, b)
 
     def set_pixmap(self, path_background, path_sidebar):
         pixbuf = None
         if path_background and os.path.exists(path_background):
             try:
-                pixbuf = ninix.pix.create_pixbuf_from_file(path_background, 'png')
+                pixbuf = ninix.pix.create_pixbuf_from_file(path_background,
+                                                           'png')
             except:
                 pixbuf = None
         if pixbuf is None:
@@ -221,7 +223,8 @@ class Menu:
         pixbuf_sidebar = None
         if path_sidebar and os.path.exists(path_sidebar):
             try:
-                pixbuf_sidebar = ninix.pix.create_pixbuf_from_file(path_sidebar, 'png')
+                pixbuf_sidebar = ninix.pix.create_pixbuf_from_file(
+                    path_sidebar, 'png')
             except:
                 pixbuf_sidebar = None
         if pixbuf_sidebar:
@@ -258,7 +261,8 @@ class Menu:
     def __set_mayuna_menu(self, side):
         if len(self.__mayuna_menu) > side and \
            self.__mayuna_menu[side] is not None:
-            menuitem = self.ui_manager.get_widget('/popup/' + 'Costume')
+            menuitem = self.ui_manager.get_widget(
+                ''.join(('/popup/', 'Costume')))
             menuitem.set_submenu(self.__mayuna_menu[side])
             if self.__pixmap:
                 tearoff = self.__mayuna_menu[side].get_children()[0]
@@ -280,12 +284,13 @@ class Menu:
                     key, name, state = mayuna_menu[side][j]
                     if key != '-':
                         item = gtk.CheckMenuItem(name)
-                        item.set_name("popup menu item")
+                        item.set_name('popup menu item')
                         if state:
                             item.set_active(True)
                         else:
                             item.set_active(False)
-                        item.connect("activate", self.__surface.toggle_bind, (index, key))
+                        item.connect('activate', self.__surface.toggle_bind,
+                                     (index, key))
                     else:
                         item = gtk.SeparatorMenuItem()
                     item.show()
@@ -303,10 +308,19 @@ class Menu:
     def __cut_mnemonic(self, caption):
         return self.__re_mnemonic.sub('', caption)
 
-    __ui = {'File/Update': ([["updatebuttoncaption", "updatebutton.caption"], ["updatebuttoncaption", "updatebutton.caption"]], "(_U)", [[],[]]),
-            'File/Vanish': ([["vanishbuttoncaption", "vanishbutton.caption"], ["vanishbuttoncaption", "vanishbutton.caption"]], "(_F)", [["vanishbuttonvisible", "vanishbutton.visible"], ["vanishbuttonvisible", "vanishbutton.visible"]]),
-            'Portal': ([["sakura.portalbuttoncaption", "portalrootbutton.caption"], []], "(_P)", [[], None]),
-            'Recommend': ([["sakura.recommendbuttoncaption", "recommendrootbutton.caption"], ["kero.recommendbuttoncaption"]], "(_R)", [[], []]),
+    __ui = {'File/Update': ([['updatebuttoncaption', 'updatebutton.caption'],
+                             ['updatebuttoncaption', 'updatebutton.caption']],
+                            '(_U)', [[],[]]),
+            'File/Vanish': ([['vanishbuttoncaption', 'vanishbutton.caption'],
+                             ['vanishbuttoncaption', 'vanishbutton.caption']],
+                            '(_F)',
+                            [['vanishbuttonvisible', 'vanishbutton.visible'],
+                             ['vanishbuttonvisible', 'vanishbutton.visible']]),
+            'Portal': ([['sakura.portalbuttoncaption',
+                         'portalrootbutton.caption'], []], '(_P)', [[], None]),
+            'Recommend': ([['sakura.recommendbuttoncaption',
+                            'recommendrootbutton.caption'],
+                           ['kero.recommendbuttoncaption']], '(_R)', [[], []]),
            }
 
     def __update_ui(self, side):
@@ -315,11 +329,11 @@ class Menu:
                 continue
             if side > 1:
                 if key in ['File/Update', 'File/Vanish']:
-                    list = self.__ui[key][0][1] # same as "kero"
+                    list = self.__ui[key][0][1] # same as 'kero'
                 elif key == 'Portal':
-                    list = [] # same as "kero"
+                    list = [] # same as 'kero'
                 elif key == 'Recommend':
-                    list = ["char%d.recommendbuttoncaption" % side]
+                    list = ['char%d.recommendbuttoncaption' % side]
             else:
                 list = self.__ui[key][0][side]
             if list: # caption
@@ -330,10 +344,10 @@ class Menu:
                 if caption:
                     caption = self.__modify_shortcut(caption)
                     if caption == self.__cut_mnemonic(caption):
-                        caption += self.__ui[key][1]
+                        caption = ''.join((caption, self.__ui[key][1]))
                     self.__set_caption(key, caption)
             if side > 1:
-                list = self.__ui[key][2][1] # same as "kero"
+                list = self.__ui[key][2][1] # same as 'kero'
             else:
                 list = self.__ui[key][2][side]
             if list: # visible
@@ -341,7 +355,7 @@ class Menu:
                     visible = self.__ghost.getstring(name)
                     if visible is not None:
                         break
-                if visible == "0":
+                if visible == '0':
                     self.__set_visible(key, 0)
                 else:
                     self.__set_visible(key, 1)
@@ -350,7 +364,7 @@ class Menu:
 
     def set_submenu_back_pixmap(self, submenu, pixmap):
         item_list = submenu.get_children()
-        if len(item_list) > 0:
+        if item_list:
             item = item_list[0]
             item.realize()
             item.window.set_back_pixmap(self.__pixmap, False)
@@ -363,10 +377,11 @@ class Menu:
         for item in submenu.get_children():
             # reset label
             children = item.get_children()
-            if len(children) > 0:
+            if children:
                 label = children[0]
                 text = label.get_text()
-                markup = '<span foreground="%s">%s</span>' % (self.__fontcolor, text)
+                markup = '<span foreground="%s">%s</span>' % \
+                         (self.__fontcolor, text)
                 label.set_markup_with_mnemonic(markup)
             submenu = item.get_submenu()
             if submenu:
@@ -374,25 +389,25 @@ class Menu:
 
     def popup(self, button, side):
         if side > 1:
-            string = "char%d" % side
+            string = 'char%d' % side
         else:
             assert side in [0, 1]
-            string = ["sakura", "kero"][side]
-        string += ".popupmenu.visible"
+            string = ['sakura', 'kero'][side]
+        string = ''.join((string, '.popupmenu.visible'))
         if self.__ghost.getstring(string) == '0':
             return
         self.__update_ui(side)
         if side == 0:
-            portal = self.__ghost.getstring("sakura.portalsites")
+            portal = self.__ghost.getstring('sakura.portalsites')
         else:
             portal = None
         self.__set_portal_menu(side, portal)
         if side > 1:
-            string = "char%d" % side
+            string = 'char%d' % side
         else:
             assert side in [0, 1]
-            string = ["sakura", "kero"][side]
-        string += ".recommendsites"
+            string = ['sakura', 'kero'][side]
+        string = ''.join((string, '.recommendsites'))
         recommend = self.__ghost.getstring(string)
         self.__set_recommend_menu(side, recommend)
         self.__set_ghost_menu()
@@ -403,7 +418,7 @@ class Menu:
         self.__set_nekodorif_menu()
         self.__set_kinoko_menu()
         for key in self.__menu_list.keys():
-            item = self.ui_manager.get_widget('/popup/' + key)
+            item = self.ui_manager.get_widget(''.join(('/popup/', key)))
             visible = self.__menu_list[key][2]
             changed = self.__menu_list[key][3]
             if item and changed:
@@ -411,21 +426,25 @@ class Menu:
                 if visible:
                     label = item.get_children()[0]
                     text = label.get_text()
-                    markup = '<span foreground="%s">%s</span>' % (self.__fontcolor, text)
+                    markup = '<span foreground="%s">%s</span>' % \
+                             (self.__fontcolor, text)
                     label.set_markup_with_mnemonic(markup)
                     item.show()
                     submenu = item.get_submenu()
                     if self.__pixmap:
                         if key == 'File':
                             item.realize()
-                            item.window.set_back_pixmap(self.__pixmap_with_sidebar, False)
+                            item.window.set_back_pixmap(
+                                self.__pixmap_with_sidebar, False)
                         if submenu:
-                            self.set_submenu_back_pixmap(submenu, self.__pixmap)
+                            self.set_submenu_back_pixmap(
+                                submenu, self.__pixmap)
                     if submenu:
                         self.set_submenu_fontcolor(submenu, self.__fontcolor)
                 else:
                     item.hide()
-        self.__popup_menu.popup(None, None, None, button, gtk.get_current_event_time())
+        self.__popup_menu.popup(None, None, None, button,
+                                gtk.get_current_event_time())
         for item in self.__popup_menu.get_children():
             if gtk.REALIZED & item.flags():
                 allocation = item.get_allocation()
@@ -436,8 +455,8 @@ class Menu:
 
     def __set_caption(self, name, caption):
         assert self.__menu_list.has_key(name)
-        assert type(caption) in [types.StringType, types.UnicodeType]
-        item = self.ui_manager.get_widget('/popup/' + name)
+        assert isinstance(caption, basestring)
+        item = self.ui_manager.get_widget(''.join(('/popup/', name)))
         if item:
             label = item.get_children()[0]
             label.set_text(caption)
@@ -460,7 +479,7 @@ class Menu:
                 list = portal.split(chr(2))
                 for site in list:
                     entry = site.split(chr(1))
-                    if len(entry) < 1:
+                    if not entry:
                         continue
                     title = entry[0]
                     if title == '-':
@@ -474,10 +493,12 @@ class Menu:
                         else:
                             bannar = None
                         item = gtk.MenuItem(title)
-                        item.connect("activate", self.__ghost.launch_browser, (title, url))
+                        item.connect('activate', self.__ghost.launch_browser,
+                                     (title, url))
                     menu.add(item)
                     item.show()
-                menuitem = self.ui_manager.get_widget('/popup/' + 'Portal')
+                menuitem = self.ui_manager.get_widget(
+                    ''.join(('/popup/', 'Portal')))
                 menuitem.set_submenu(menu)
                 menu.show()
                 self.__set_visible('Portal', 1)
@@ -491,7 +512,7 @@ class Menu:
             list = recommend.split(chr(2))
             for site in list:
                 entry = site.split(chr(1))
-                if len(entry) < 1:
+                if not entry:
                     continue
                 title = entry[0]
                 if title == '-':
@@ -505,10 +526,12 @@ class Menu:
                     else:
                         bannar = None
                     item = gtk.MenuItem(title)
-                    item.connect("activate", self.__ghost.launch_browser, (title, url))
+                    item.connect('activate', self.__ghost.launch_browser,
+                                 (title, url))
                 menu.add(item)
                 item.show()
-            menuitem =  self.ui_manager.get_widget('/popup/' + 'Recommend')
+            menuitem =  self.ui_manager.get_widget(
+                ''.join(('/popup/', 'Recommend')))
             menuitem.set_submenu(menu)
             menu.show()
             self.__set_visible('Recommend', 1)
@@ -529,7 +552,8 @@ class Menu:
             pixbuf = None
             if icon_path is not None:
                 try:
-                    pixbuf = ninix.pix.create_pixbuf_from_file(icon_path, 'ico')
+                    pixbuf = ninix.pix.create_pixbuf_from_file(icon_path,
+                                                               'ico')
                 except:
                     pixbuf = None
             shell_list = list[i]['shell']
@@ -542,22 +566,24 @@ class Menu:
                 item.set_image(image)
             else:
                 item = gtk.MenuItem(name)
-            item.set_name("popup menu item")
+            item.set_name('popup menu item')
             item.show()
             ghost_menu.append(item)
             if len(shell_list) <= 1:
                 shell_name, value = shell_list[0]
-                item.connect("activate", self.__ghost.app.select_sakura, (self.__ghost, value)) ## FIXME
+                item.connect('activate', self.__ghost.app.select_sakura,
+                             (self.__ghost, value)) ## FIXME
                 if list[i]['instance'].is_running():
                     item.set_sensitive(False)
             else:
                 submenu = gtk.Menu()
-                submenu.set_name("popup menu")
+                submenu.set_name('popup menu')
                 item.set_submenu(submenu)
                 for shell_name, value in shell_list:
                     item = gtk.MenuItem(shell_name)
-                    item.set_name("popup menu item")
-                    item.connect("activate", self.__ghost.app.select_sakura, (self.__ghost, value)) ## FIXME
+                    item.set_name('popup menu item')
+                    item.connect('activate', self.__ghost.app.select_sakura,
+                                 (self.__ghost, value)) ## FIXME
                     item.show()
                     if list[i]['instance'].is_running():
                         if self.__ghost.current[1] != value[1]:
@@ -565,7 +591,7 @@ class Menu:
                         elif self.__ghost.current[2] == value[2]:
                             item.set_sensitive(False)
                     submenu.append(item)
-        menuitem =  self.ui_manager.get_widget('/popup/' + 'Change')
+        menuitem =  self.ui_manager.get_widget(''.join(('/popup/', 'Change')))
         menuitem.set_submenu(ghost_menu)
         self.__menu_list['Change'][3] = 1
         self.__ghost_list = list
@@ -588,7 +614,8 @@ class Menu:
             pixbuf = None
             if icon_path is not None:
                 try:
-                    pixbuf = ninix.pix.create_pixbuf_from_file(icon_path, 'ico')
+                    pixbuf = ninix.pix.create_pixbuf_from_file(icon_path,
+                                                               'ico')
                 except:
                     pixbuf = None
             shell_list = list[i]['shell']
@@ -601,27 +628,29 @@ class Menu:
                 item.set_image(image)
             else:
                 item = gtk.MenuItem(name)
-            item.set_name("popup menu item")
+            item.set_name('popup menu item')
             item.show()
             ghost_menu.append(item)
             if len(shell_list) <= 1:
                 shell_name, value = shell_list[0]
-                item.connect("activate", self.__ghost.app.start_sakura_cb, value) ## FIXME
+                item.connect('activate', self.__ghost.app.start_sakura_cb,
+                             value) ## FIXME
                 if list[i]['instance'].is_running():
                     item.set_sensitive(False)
             else:
                 submenu = gtk.Menu()
-                submenu.set_name("popup menu")
+                submenu.set_name('popup menu')
                 item.set_submenu(submenu)
                 for shell_name, value in shell_list:
                     item = gtk.MenuItem(shell_name)
-                    item.set_name("popup menu item")
-                    item.connect("activate", self.__ghost.app.start_sakura_cb, value) ## FIXME
+                    item.set_name('popup menu item')
+                    item.connect('activate', self.__ghost.app.start_sakura_cb,
+                                 value) ## FIXME
                     item.show()
                     if list[i]['instance'].is_running():
                         item.set_sensitive(False)
                     submenu.append(item)
-        menuitem = self.ui_manager.get_widget('/popup/' + 'Summon')
+        menuitem = self.ui_manager.get_widget(''.join(('/popup/', 'Summon')))
         menuitem.set_submenu(ghost_menu)
         self.__menu_list['Summon'][3] = 1
         self.__ghost_list = list
@@ -634,28 +663,30 @@ class Menu:
         for i in range(len(list)):
             name = list[i]['name']
             item = gtk.MenuItem(name)
-            item.set_name("popup menu item")
+            item.set_name('popup menu item')
             item.show()
             shell_menu.append(item)
             shell_list = list[i]['shell']
             if len(shell_list) <= 1:
                 shell_name, value = shell_list[0]
-                item.connect("activate", self.__ghost.app.select_sakura, (self.__ghost, value)) ## FIXME
+                item.connect('activate', self.__ghost.app.select_sakura,
+                             (self.__ghost, value)) ## FIXME
                 ##if working:
                 ##    item.set_sensitive(False)
             else:
                 submenu = gtk.Menu()
-                submenu.set_name("popup menu")
+                submenu.set_name('popup menu')
                 item.set_submenu(submenu)
                 for shell_name, value in shell_list:
                     item = gtk.MenuItem(shell_name)
-                    item.set_name("popup menu item")
-                    item.connect("activate", self.__ghost.app.select_sakura, (self.__ghost, value)) ## FIXME
+                    item.set_name('popup menu item')
+                    item.connect('activate', self.__ghost.app.select_sakura,
+                                 (self.__ghost, value)) ## FIXME
                     item.show()
                     ##if working: ## FIXME
                     ##    item.set_sensitive(False)
                     submenu.append(item)
-        menuitem = self.ui_manager.get_widget('/popup/' + 'Shell')
+        menuitem = self.ui_manager.get_widget(''.join(('/popup/', 'Shell')))
         menuitem.set_submenu(shell_menu)
         self.__menu_list['Shell'][3] = 1
         self.__shell_list = list
@@ -673,8 +704,9 @@ class Menu:
         name_own = self.__ghost.get_own_balloon_name()
         if name_own is not None:
             item = group = gtk.RadioMenuItem(group, name_own)
-            item.set_name("popup menu item")
-            hid = item.connect("activate", self.__ghost.select_balloon, name_own)
+            item.set_name('popup menu item')
+            hid = item.connect('activate', self.__ghost.select_balloon,
+                               name_own)
             item.show()
             balloon_menu.append(item)
         item = gtk.SeparatorMenuItem()
@@ -683,15 +715,15 @@ class Menu:
         for i in range(len(list)):
             name = list[i]['name']
             item = group = gtk.RadioMenuItem(group, name)
-            item.set_name("popup menu item")
-            hid = item.connect("activate", self.__ghost.select_balloon, name)
+            item.set_name('popup menu item')
+            hid = item.connect('activate', self.__ghost.select_balloon, name)
             item.show()
             balloon_menu.append(item)
             if name == self.__ghost.get_current_balloon_name():
                 item.handler_block(hid)
                 item.activate()
                 item.handler_unblock(hid)
-        menuitem = self.ui_manager.get_widget('/popup/' + 'Balloon')
+        menuitem = self.ui_manager.get_widget(''.join(('/popup/', 'Balloon')))
         menuitem.set_submenu(balloon_menu)
         self.__menu_list['Balloon'][3] = 1
         self.__balloon_list = list
@@ -708,28 +740,29 @@ class Menu:
         for i in range(len(list)):
             name = list[i]['name']
             item = gtk.MenuItem(name)
-            item.set_name("popup menu item")
+            item.set_name('popup menu item')
             item.show()
             plugin_menu.append(item)
             item_list = list[i]['items']
             if len(item_list) <= 1:
                 label, value = item_list[0]
-                item.connect("activate", self.__ghost.app.select_plugin, value) ## FIXME
+                item.connect('activate', self.__ghost.app.select_plugin, value) ## FIXME
                 ##if working:
                 ##    item.set_sensitive(False)
             else:
                 submenu = gtk.Menu()
-                submenu.set_name("popup menu")
+                submenu.set_name('popup menu')
                 item.set_submenu(submenu)
                 for label, value in item_list:
                     item = gtk.MenuItem(label)
-                    item.set_name("popup menu item")
-                    item.connect("activate", self.__ghost.app.select_plugin, value) ## FIXME
+                    item.set_name('popup menu item')
+                    item.connect('activate', self.__ghost.app.select_plugin,
+                                 value) ## FIXME
                     item.show()
                     ##if working:
                     ##    item.set_sensitive(False)
                     submenu.append(item)
-        menuitem = self.ui_manager.get_widget('/popup/' + 'Plugin')
+        menuitem = self.ui_manager.get_widget(''.join(('/popup/', 'Plugin')))
         menuitem.set_submenu(plugin_menu)
         self.__menu_list['Plugin'][3] = 1
         self.__plugin_list = list
@@ -746,13 +779,15 @@ class Menu:
         for i in range(len(list)):
             name = list[i]['name']
             item = gtk.MenuItem(name)
-            item.set_name("popup menu item")
+            item.set_name('popup menu item')
             item.show()
             nekodorif_menu.append(item)
-            item.connect("activate", self.__ghost.app.select_nekodorif, (self.__ghost, list[i]['dir'])) ## FIXME
+            item.connect('activate', self.__ghost.app.select_nekodorif,
+                         (self.__ghost, list[i]['dir'])) ## FIXME
             ##if working:
             ##    item.set_sensitive(False)
-        menuitem = self.ui_manager.get_widget('/popup/' + 'Nekodorif')
+        menuitem = self.ui_manager.get_widget(
+            ''.join(('/popup/', 'Nekodorif')))
         menuitem.set_submenu(nekodorif_menu)
         self.__menu_list['Nekodorif'][3] = 1
         self.__nekodorif_list = list
@@ -769,13 +804,14 @@ class Menu:
         for i in range(len(list)):
             name = list[i]['title']
             item = gtk.MenuItem(name)
-            item.set_name("popup menu item")
+            item.set_name('popup menu item')
             item.show()
             kinoko_menu.append(item)
-            item.connect("activate", self.__ghost.app.select_kinoko, (self.__ghost, list[i])) ## FIXME
+            item.connect('activate', self.__ghost.app.select_kinoko,
+                         (self.__ghost, list[i])) ## FIXME
             ##if working:
             ##    item.set_sensitive(False)
-        menuitem = self.ui_manager.get_widget('/popup/' + 'Kinoko')
+        menuitem = self.ui_manager.get_widget(''.join(('/popup/', 'Kinoko')))
         menuitem.set_submenu(kinoko_menu)
         self.__menu_list['Kinoko'][3] = 1
         self.__kinoko_list = list
@@ -785,14 +821,15 @@ class Menu:
         self.__update_kinoko_menu(list)
 
     def get_stick(self):
-        item =  self.ui_manager.get_widget('/popup/' + 'Stick')
+        item =  self.ui_manager.get_widget(''.join(('/popup/', 'Stick')))
         if item and item.get_active():
             return 1
         else:
             return 0
 
+
 def test():
     pass
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     test()
index 29924b0..ff3e565 100644 (file)
@@ -50,12 +50,13 @@ import os
 import sys
 import random
 
-if os.environ.has_key("DISPLAY"):
+if os.environ.has_key('DISPLAY'):
     import gtk
     import gobject
     import pango
     import ninix.pix
 
+
 class Menu:
 
     def __init__(self, nekoninni, accelgroup):
@@ -82,7 +83,7 @@ class Menu:
                          '/ui/popup/Exit'],
             }
         self.__katochan_list = None
-        actions = gtk.ActionGroup("Actions")
+        actions = gtk.ActionGroup('Actions')
         entry = []
         for key in self.__menu_list.keys():
             entry.append(self.__menu_list[key][0])
@@ -90,7 +91,7 @@ class Menu:
         ui_manager = gtk.UIManager()
         ui_manager.insert_action_group(actions, 0)
         ui_manager.add_ui_from_string(ui_info)
-        self.__popup_menu = ui_manager.get_widget("/ui/popup")
+        self.__popup_menu = ui_manager.get_widget('/ui/popup')
         for key in self.__menu_list.keys():
             path = self.__menu_list[key][-1]
             self.__menu_list[key][1] = ui_manager.get_widget(path)
@@ -98,7 +99,8 @@ class Menu:
     def popup(self, button):
         katochan_list = self.__nekoninni.get_katochan_list()
         self.__set_katochan_menu(katochan_list)
-        self.__popup_menu.popup(None, None, None, button, gtk.get_current_event_time())
+        self.__popup_menu.popup(
+            None, None, None, button, gtk.get_current_event_time())
 
     def __set_katochan_menu(self, list): ## FIXME
         key = 'katochan'
@@ -106,7 +108,8 @@ class Menu:
             menu = gtk.Menu()
             for katochan in list:
                 item = gtk.MenuItem(katochan['name'])
-                item.connect("activate", self.__nekoninni.select_katochan, (katochan))
+                item.connect(
+                    'activate', self.__nekoninni.select_katochan, (katochan))
                 menu.add(item)
                 item.show()
             self.__menu_list[key][1].set_submenu(menu)
@@ -149,7 +152,7 @@ class Nekoninni:
             pass
 
     def load(self, dir, katochan, target):
-        if len(katochan) == 0:
+        if not katochan:
             return 0
         self.dir = dir
         self.target = target
@@ -253,14 +256,14 @@ class Skin:
         else:
             self.omni = 0
         self.window = gtk.Window()
-        ##self.window.set_title('surface.' + name)
+        ##self.window.set_title(''.join(('surface.', name)))
         self.window.set_decorated(False)
         self.window.set_resizable(False)
-        self.window.connect("delete_event", self.delete)
-        self.window.connect("button_press_event", self.button_press)
-        self.window.connect("button_release_event", self.button_release)
-        self.window.connect("motion_notify_event", self.motion_notify)
-        self.window.connect("leave_notify_event", self.leave_notify)
+        self.window.connect('delete_event', self.delete)
+        self.window.connect('button_press_event', self.button_press)
+        self.window.connect('button_release_event', self.button_release)
+        self.window.connect('motion_notify_event', self.motion_notify)
+        self.window.connect('leave_notify_event', self.leave_notify)
         self.window.set_events(gtk.gdk.BUTTON_PRESS_MASK|
                                gtk.gdk.BUTTON_RELEASE_MASK|
                                gtk.gdk.POINTER_MOTION_MASK|
@@ -270,7 +273,7 @@ class Skin:
         self.window.add_accel_group(self.accelgroup)
         self.darea = gtk.DrawingArea()
         self.darea.set_events(gtk.gdk.EXPOSURE_MASK)
-        self.darea.connect("expose_event", self.redraw)
+        self.darea.connect('expose_event', self.redraw)
         self.id = [0, None]
         self.darea.show()
         self.window.add(self.darea)
@@ -298,7 +301,9 @@ class Skin:
         self.y_root = event.y_root
         if event.button == 1:
             if event.type == gtk.gdk.BUTTON_PRESS:
-                ##self.window.begin_move_drag(event.button, int(event.x_root), int(event.y_root), gtk.get_current_event_time())
+                ##self.window.begin_move_drag(
+                ##    event.button, int(event.x_root), int(event.y_root),
+                ##    gtk.get_current_event_time())
                 pass
             elif event.type == gtk.gdk._2BUTTON_PRESS: # double click
                 if self.nekoninni.has_katochan():
@@ -311,7 +316,8 @@ class Skin:
 
     def set_surface(self):
         if self.id[1] is not None:
-            path = os.path.join(self.dir, 'surface%d%d.png' % (self.id[0], self.id[1]))
+            path = os.path.join(self.dir,
+                                'surface%d%d.png' % (self.id[0], self.id[1]))
             if not os.path.exists(path):
                 self.id[1] = None
                 self.set_surface()
@@ -403,6 +409,7 @@ class Balloon:
         pass
 
 class Katochan:
+
     CATEGORY_LIST = ['pain',      # 痛い
                      'stab',      # 刺さる
                      'surprise',  # びっくり
@@ -463,27 +470,30 @@ class Katochan:
         pass
 
     def set_movement(self, timing):
-        key = timing + 'fall.type'
+        key = ''.join((timing, 'fall.type'))
         if self.data.has_key(key) and \
            self.data[key] in ['gravity', 'evenspeed', 'none']:
             self.settings['fall.type'] = self.data[key]
         else:
             self.settings['fall.type'] = 'gravity'
-        self.settings['fall.speed'] = self.data.get(timing + 'fall.speed', 1)
+        self.settings['fall.speed'] = self.data.get(
+            ''.join((timing, 'fall.speed')), 1)
         if self.settings['fall.speed'] < 1:
             self.settings['fall.speed'] = 1
         if self.settings['fall.speed'] > 100:
             self.settings['fall.speed'] = 100
-        key = timing + 'slide.type'
+        key = ''.join((timing, 'slide.type'))
         if self.data.has_key(key) and \
            self.data[key] in ['none', 'sinwave', 'leaf']:
             self.settings['slide.type'] = self.data[key]
         else:
             self.settings['slide.type'] = 'none'
-        self.settings['slide.magnitude'] = self.data.get(timing + 'slide.magnitude', 0)
-        self.settings['slide.sinwave.degspeed'] = self.data.get(timing + 'slide.sinwave.degspeed', 30)
-        self.settings['wave'] = self.data.get(timing + 'wave', None)
-        if self.data.get(timing + 'wave.loop') == 'on':
+        self.settings['slide.magnitude'] = self.data.get(
+            ''.join((timing, 'slide.magnitude')), 0)
+        self.settings['slide.sinwave.degspeed'] = self.data.get(
+            ''.join((timing, 'slide.sinwave.degspeed')), 30)
+        self.settings['wave'] = self.data.get(''.join((timing, 'wave')), None)
+        if self.data.get(''.join((timing, 'wave.loop'))) == 'on':
             self.settings['wave.loop'] = 1
         else:
             self.settings['wave.loop'] = 0
@@ -502,7 +512,8 @@ class Katochan:
         target_w, target_h = self.target.get_surface_size(self.side)
         self.top_margin = self.target.get_top_margin()
         self.bottom_margin = self.target.get_bottom_margin()
-        self.x = target_x + target_w / 2 - self.w / 2 + self.offset_x * self.__scale / 100
+        self.x = target_x + target_w / 2 - self.w / 2 + \
+                 self.offset_x * self.__scale / 100
         self.y = self.top_margin + self.offset_y * self.__scale / 100
         self.window.move(self.x, self.y)
 
@@ -534,7 +545,7 @@ class Katochan:
             list = self.data['category'].split(',')
             if list:
                 if list[0] not in self.CATEGORY_LIST:
-                    print "WARNING: unknown major category - ", list[0]
+                    print 'WARNING: unknown major category - ', list[0]
                     ##self.data['category'] = self.CATEGORY_LIST[-1]
             else:
                 self.data['category'] = self.CATEGORY_LIST[-1]
@@ -574,13 +585,13 @@ class Katochan:
         self.offset_x = offset_x
         self.offset_y = offset_y
         self.window = gtk.Window()
-        ##self.window.set_title('surface.' + name)
+        ##self.window.set_title(''.join(('surface.', name)))
         self.window.set_decorated(False)
         self.window.set_resizable(False)
-        self.window.connect("delete_event", self.delete)
+        self.window.connect('delete_event', self.delete)
         self.darea = gtk.DrawingArea()
         self.darea.set_events(gtk.gdk.EXPOSURE_MASK)
-        self.darea.connect("expose_event", self.redraw)
+        self.darea.connect('expose_event', self.redraw)
         self.darea.show()
         self.window.add(self.darea)
         self.darea.realize()
@@ -607,7 +618,8 @@ class Katochan:
             pass
         else:
             if self.settings['fall.type'] == 'gravity':
-                self.y += int(self.settings['fall.speed'] * (self.time / 20.0)**2)
+                self.y += int(self.settings['fall.speed'] * \
+                              (self.time / 20.0)**2)
             elif  self.settings['fall.type'] == 'evenspeed':
                 self.y += self.settings['fall.speed']
             else:
@@ -625,8 +637,8 @@ class Katochan:
             target_w, target_h = self.target.get_surface_size(side)
             center_x = self.x + self.w / 2
             center_y = self.y + self.h / 2
-            if center_x > target_x and center_x < target_x + target_w and \
-                   center_y > target_y and center_y < target_y + target_h:
+            if target_x < center_x < target_x + target_w and \
+               target_y < center_y < target_y + target_h:
                 self.side = side
                 return 1
         else:
index 5ea3375..48b23e3 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
 #  Copyright (C) 2001-2004 by MATSUMURA Namihiko <nie@counterghost.net>
-#  Copyright (C) 2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2004, 2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
@@ -23,7 +23,7 @@ from xml.dom import pulldom
 
 import ninix.home
 
-if os.environ.has_key("DISPLAY"):
+if os.environ.has_key('DISPLAY'):
     import gtk
     import pango
 
@@ -34,7 +34,7 @@ if os.environ.has_key("DISPLAY"):
 # - アクセスには帯域を多く使用しますので,
 #   必ず日時指定の差分アクセスをし余分な負荷をかけないようお願いします.
 #   (差分アクセスの方法については本プログラムの実装が参考になると思います.)
-MASTERLIST_URL = "http://www.aqrs.jp/cgi-bin/ghostdb/request2.cgi"
+MASTERLIST_URL = 'http://www.aqrs.jp/cgi-bin/ghostdb/request2.cgi'
 
 # 10000以上のIDを持つデータは仮登録
 ID_LIMIT = 10000
@@ -49,7 +49,9 @@ ELEMENTS = ['Name', 'SakuraName', 'KeroName', 'GhostType',
             'InstallDir', 'ArchiveName', 'UpdateUrl',
             'AnalysisError', 'InstallCount']
 
+
 class Catalog_xml:
+
     #public methods
     def __init__(self, datadir):
         self.data = {}
@@ -58,7 +60,7 @@ class Catalog_xml:
         self.datadir = datadir
         if not os.path.exists(self.datadir):
             os.makedirs(self.datadir)
-        self.last_update = "1970-01-01 00:00:00"
+        self.last_update = '1970-01-01 00:00:00'
         self.load_MasterList()
 
     # data handling functions
@@ -71,8 +73,8 @@ class Catalog_xml:
     # updates etc
     def network_update(self):
         last_update = self.last_update
-        self.last_update = time.strftime("%Y-%m-%d %H:%M:%S")
-        if len(self.cgi) > 0:
+        self.last_update = time.strftime('%Y-%m-%d %H:%M:%S')
+        if self.cgi:
             priority = self.cgi.keys()
             priority.sort()
             url = self.cgi[priority[-1]]
@@ -80,7 +82,7 @@ class Catalog_xml:
             url = MASTERLIST_URL
         try:
             f = urllib.urlopen(url, urllib.urlencode(
-                {"time": '"%s"' % last_update, "charset": "EUC-JP"}))
+                {'time': '"%s"' % last_update, 'charset': 'EUC-JP'}))
         except:
             return ## FIXME
         self.import_from_fileobj(f)
@@ -90,14 +92,14 @@ class Catalog_xml:
     # private methods
     def load_MasterList(self):
         try:
-            f = open(os.path.join(self.datadir, "MasterList.xml"), 'r')
+            f = open(os.path.join(self.datadir, 'MasterList.xml'), 'r')
             self.import_from_fileobj(f)
             f.close()
         except IOError:
             return
 
     def save_MasterList(self):
-        f = open(os.path.join(self.datadir, "MasterList.xml"), 'w')
+        f = open(os.path.join(self.datadir, 'MasterList.xml'), 'w')
         self.export_to_fileobj(f)
         f.close()
 
@@ -118,7 +120,7 @@ class Catalog_xml:
         try:
             codecs.lookup(encoding)
         except:
-            sys.stderr.write("Unsupported encoding %s" % repr(encoding))
+            sys.stderr.write('Unsupported encoding %s' % repr(encoding))
             sys.exit(-1)
         nest = 0
         new_entry = {}
@@ -216,7 +218,9 @@ class Catalog_xml:
         list.reverse()
         for priority in list:
             for url in self.cgi[priority]:
-                fileobj.write('<RequestCgiUrl Priority="%d">%s</RequestCgiUrl>\n' % (priority, url))
+                fileobj.write(
+                    '<RequestCgiUrl Priority="%d">%s</RequestCgiUrl>\n' % \
+                    (priority, url))
         ids = self.data.keys()
         ids.sort()
         for id in ids:
@@ -231,14 +235,14 @@ class Catalog(Catalog_xml):
     TYPE = ['Sakura', 'Kero']
 
     def image_filename(self, id, side):
-        p = "%s_%d.png" % (self.TYPE[side], id)
+        p = '%s_%d.png' % (self.TYPE[side], id)
         d = os.path.join(self.datadir, p)
         if os.path.exists(d):
             return d
         return None
 
     def retrieve_image(self, id, side):
-        p = "%s_%d.png" % (self.TYPE[side], id)
+        p = '%s_%d.png' % (self.TYPE[side], id)
         d = os.path.join(self.datadir, p)
         if not os.path.exists(d):
             entry = self.data[id]
@@ -247,7 +251,7 @@ class Catalog(Catalog_xml):
             else:
                 url = self.url['KeroPreviewBaseUrl']
             try:
-                urllib.urlretrieve(url + p, d)
+                urllib.urlretrieve(''.join((url, p)), d)
             except:
                 return ## FIXME
 
@@ -260,7 +264,7 @@ class InstallationManager(UserList.UserList):
         self.current_ghost = id
 
     def install_ghost(self, dialog):
-        a = self.master.ui.catalog.get(self.current_ghost, "ArchiveUrl")
+        a = self.master.ui.catalog.get(self.current_ghost, 'ArchiveUrl')
         os.system("%s '%s'" % (self.master.ninix_install_cmd, a))
 
 class SearchDialog:
@@ -268,20 +272,20 @@ class SearchDialog:
     def __init__(self, ui):
         self.ui = ui
         self.dialog = gtk.Dialog()
-        self.dialog.connect("delete_event", self.cancel)
+        self.dialog.connect('delete_event', self.cancel)
         self.dialog.set_modal(True)
         self.dialog.set_position(gtk.WIN_POS_CENTER)
-        label = gtk.Label(_("Search for"))
+        label = gtk.Label(_('Search for'))
         self.dialog.vbox.pack_start(label)
         self.pattern_entry = gtk.Entry()
         self.pattern_entry.set_size_request(300, -1)
         self.dialog.vbox.pack_start(self.pattern_entry)
         self.dialog.vbox.show_all()
-        self.ok_button = gtk.Button(_("OK"))
-        self.ok_button.connect("clicked", self.ok)
+        self.ok_button = gtk.Button(_('OK'))
+        self.ok_button.connect('clicked', self.ok)
         self.dialog.action_area.pack_start(self.ok_button)
-        button = gtk.Button(_("Cancel"))
-        button.connect("clicked", self.cancel)
+        button = gtk.Button(_('Cancel'))
+        button.connect('clicked', self.cancel)
         self.dialog.action_area.pack_start(button)
         self.dialog.action_area.show_all()
 
@@ -337,40 +341,40 @@ class UI:
           </menubar>
         </ui>'''
         self.entries = (
-            ( "FileMenu", None, _("_File") ),
-            ( "ViewMenu", None, _("_View") ),
-            ( "ArchiveMenu", None, _("_Archive") ),
-            ( "HelpMenu", None, _("_Help") ),
-            ( "Search", None,                  # name, stock id
-              _("Search(_F)"), "<control>F",   # label, accelerator
-              "Search",                        # tooltip
+            ( 'FileMenu', None, _('_File') ),
+            ( 'ViewMenu', None, _('_View') ),
+            ( 'ArchiveMenu', None, _('_Archive') ),
+            ( 'HelpMenu', None, _('_Help') ),
+            ( 'Search', None,                  # name, stock id
+              _('Search(_F)'), '<control>F',   # label, accelerator
+              'Search',                        # tooltip
               lambda *a: self.open_search_dialog() ),
-            ( "Search Forward", None,
-              _("Search Forward(_S)"), "F3",
+            ( 'Search Forward', None,
+              _('Search Forward(_S)'), 'F3',
               None,
               lambda *a: self.search_forward() ),
-            ( "Settings", None,
-              _("Settings(_O)"), None,
+            ( 'Settings', None,
+              _('Settings(_O)'), None,
               None,
               lambda *a: self.ngm.open_preference_dialog() ),
-            ( "DB Network Update", None,
-              _("DB Network Update(_N)"), None,
+            ( 'DB Network Update', None,
+              _('DB Network Update(_N)'), None,
               None,
               lambda *a: self.network_update() ),
-            ( "Close", None,
-              _("Close(_X)"), None,
+            ( 'Close', None,
+              _('Close(_X)'), None,
               None,
               lambda *a: self.close() ),
-            ( "Mask", None,
-              _("Mask(_M)"), None,
+            ( 'Mask', None,
+              _('Mask(_M)'), None,
               None,
               lambda *a: self.ngm.open_mask_dialog() ),
-            ( "Reset to Default", None,
-              _("Reset to Default(_Y)"), None,
+            ( 'Reset to Default', None,
+              _('Reset to Default(_Y)'), None,
               None,
               lambda *a: self.ngm.reset_to_default() ),
-            ( "Show All", None,
-              _("Show All(_Z)"), None,
+            ( 'Show All', None,
+              _('Show All(_Z)'), None,
               None,
               lambda *a: self.ngm.show_all() ),
             )
@@ -388,10 +392,10 @@ class UI:
         self.window = gtk.Window()
         self.window.set_title(_('Ghost Manager'))
         self.window.set_resizable(False)
-        self.window.connect("delete_event", lambda *a: self.close())
+        self.window.connect('delete_event', lambda *a: self.close())
         self.window.set_position(gtk.WIN_POS_CENTER)
         self.window.set_gravity(gtk.gdk.GRAVITY_CENTER)
-        actions = gtk.ActionGroup("Actions")
+        actions = gtk.ActionGroup('Actions')
         actions.add_actions(self.entries)
         ui = gtk.UIManager()
         ui.insert_action_group(actions, 0)
@@ -399,11 +403,11 @@ class UI:
         try:
             mergeid = ui.add_ui_from_string(self.ui_info)
         except gobject.GError, msg:
-            print "building menus failed: %s" % msg
+            print 'building menus failed: %s' % msg
         vbox = gtk.VBox(False, 0)
         self.window.add(vbox)
         vbox.show()
-        vbox.pack_start(ui.get_widget("/MenuBar"), False, False, 0)
+        vbox.pack_start(ui.get_widget('/MenuBar'), False, False, 0)
         separator = gtk.HSeparator()
         vbox.pack_start(separator, False, True, 0)
         separator.show()
@@ -421,12 +425,12 @@ class UI:
         vbox.pack_start(box, False, True, 4)
         box.show()
         button = gtk.Button(_('Previous'))
-        button.connect("clicked", lambda b, w=self: w.show_previous())
+        button.connect('clicked', lambda b, w=self: w.show_previous())
         box.add(button)
         button.show()
         self.button['previous'] = button
         button = gtk.Button(_('Next'))
-        button.connect("clicked", lambda b, w=self: w.show_next())
+        button.connect('clicked', lambda b, w=self: w.show_next())
         box.add(button)
         button.show()
         self.button['next'] = button
@@ -515,12 +519,12 @@ class UI:
         box.set_layout(gtk.BUTTONBOX_SPREAD)
         box.show()
         button = gtk.Button(_('Install'))
-        button.connect("clicked", lambda b, w=self: w.ngm.install_current())
+        button.connect('clicked', lambda b, w=self: w.ngm.install_current())
         box.add(button)
         button.show()
         self.button['install'] = button
         button = gtk.Button(_('Update'))
-        button.connect("clicked", lambda b, w=self: w.ngm.update_current())
+        button.connect('clicked', lambda b, w=self: w.ngm.update_current())
         box.add(button)
         button.show()
         self.button['update'] = button
@@ -532,14 +536,17 @@ class UI:
         button.set_relief(gtk.RELIEF_NONE)
         self.url['HP'] = [None, button.get_child()]
         vbox2.pack_start(button, False, True, 0)
-        button.connect("clicked", lambda b, w=self: w.launch_browser(self.url['HP'][0]))
+        button.connect('clicked',
+                       lambda b, w=self: w.launch_browser(self.url['HP'][0]))
         button.show()
         button = gtk.Button('')
         button.set_relief(gtk.RELIEF_NONE)
         button.set_use_underline(True)
         self.url['Public'] = [None, button.get_child()]
         vbox2.pack_start(button, False, True, 0)
-        button.connect("clicked", lambda b, w=self: w.launch_browser(self.url['Public'][0]))
+        button.connect(
+            'clicked',
+            lambda b, w=self: w.launch_browser(self.url['Public'][0]))
         button.show()
         vbox.pack_start(hbox, False, True, 0)
         hbox.show()
@@ -553,11 +560,11 @@ class UI:
 
     def launch_browser(self, url):
         command = self.ngm.app.get_browser()
-        pos = command.find("%s")
+        pos = command.find('%s')
         if pos < 0:
-            sys.stderr.write("cannot execute command (%s missing)\n")
+            sys.stderr.write('cannot execute command (%s missing)\n')
             return
-        os.system(command[:pos] + url + command[pos+2:] + " &")
+        os.system(''.join((command[:pos], url, command[pos + 2:], ' &')))
 
     def update_info_area(self):
         list = [(_('Author:'), 'Author'),
@@ -567,11 +574,17 @@ class UI:
                 (_('Version:'), 'Version'),
                 (_('AIName:'), 'AIName')]
         text = ''
-        text += self.ngm.get('Name') + '\n'
+        text = ''.join((text, self.ngm.get('Name'), '\n'))
         for item in list:
-            text += item[0] + self.ngm.get(item[1]) + '\n'
-        text += self.ngm.get('SakuraName') + _('SurfaceList:') + self.ngm.get('SakuraSurfaceList') + '\n'
-        text += self.ngm.get('KeroName') + _('SurfaceList:') + self.ngm.get('KeroSurfaceList') + '\n'
+            text = ''.join((text, item[0], self.ngm.get(item[1]), '\n'))
+        text = ''.join((text,
+                        self.ngm.get('SakuraName'),
+                        _('SurfaceList:'), self.ngm.get('SakuraSurfaceList'),
+                        '\n'))
+        text = ''.join((text,
+                        self.ngm.get('KeroName'),
+                        _('SurfaceList:'), self.ngm.get('KeroSurfaceList'),
+                        '\n'))
         textbuffer = self.info.get_buffer()
         textbuffer.set_text(text)
         url = self.ngm.get('HPUrl')
@@ -580,7 +593,7 @@ class UI:
         label = self.url['HP'][1]
         label.set_markup('<span foreground="blue">%s</span>' % text)
         url = self.ngm.get('PublicUrl')
-        text = self.ngm.get('Name') + _(' Web Page')
+        text = ''.join((self.ngm.get('Name'), _(' Web Page')))
         self.url['Public'][0] = url
         label = self.url['Public'][1]
         label.set_markup('<span foreground="blue">%s</span>' % text)
@@ -657,7 +670,7 @@ class NGM:
         return False
 
     def search_forward(self, word):
-        return self.search(word, id=self.current+1)
+        return self.search(word, id=self.current + 1)
 
     def open_preference_dialog(self):
         pass
@@ -716,5 +729,6 @@ class NGM:
             self.app.start_sakura(item, init=1)
         ghost.update()
 
-if __name__ == "__main__":
+
+if __name__ == '__main__':
     pass
index 47a81fe..e04c306 100644 (file)
@@ -22,7 +22,7 @@ def get_translucent_cmap():
         visual = gtk.gdk.visual_get_best_with_depth(32) # RGBA
         return gtk.gdk.Colormap(visual, True)
     except:
-        sys.stderr.write("Translucency is not available on this Xserver.\n")
+        sys.stderr.write('Translucency is not available on this Xserver.\n')
         return None
 
 def create_blank_pixbuf(width, height):
@@ -35,26 +35,26 @@ def create_pixbuf_from_DGP_file(path):
     filename = tail
     m_half = md5.new(filename[:len(filename) / 2]).hexdigest()
     m_full = md5.new(filename).hexdigest()
-    tmp = m_full + filename
+    tmp = ''.join((m_full, filename))
     key = ''
     j = 0
     for i in range(len(tmp)):
         value = ord(tmp[i]) ^ ord(m_half[j])
         if not value:
             break
-        key += chr(value)
+        key = ''.join((key, chr(value)))
         j += 1
         if j >= len(m_half):
             j = 0
     key_length = len(key)
     if key_length == 0:
-        print filename + ' generates a null key.'
+        print ''.join((filename, ' generates a null key.'))
         pixbuf = gtk.gdk.pixbuf_new_from_file(filename)
         return pixbuf # not encrypted
-    key = key[1:] + key[0]
+    key = ''.join((key[1:], key[0]))
     key_pos = 0
     file = open(path, 'r')
-    loader = gtk.gdk.PixbufLoader("png")
+    loader = gtk.gdk.PixbufLoader('png')
     while 1:
         c = file.read(1)
         if c == '':
@@ -116,7 +116,7 @@ def create_pixbuf_from_file(path, type='pnr', use_pna=0):
                         for k in range(4):
                             array[i][j][k] = 0
     if use_pna:
-        path = os.path.join(head, basename + '.pna')
+        path = os.path.join(head, ''.join((basename, '.pna')))
         if os.path.exists(path):
             add_alpha_from_PNA_file(pixbuf, path)
     return pixbuf
@@ -139,12 +139,12 @@ def reduce_pixbuf(target_pixbuf, pixbuf, dest_x, dest_y):
                 if array[i][j][3] == 0: # alpha
                     x = j + dest_x
                     y = i + dest_y
-                    if x >= 0 and x < dest_w and \
-                       y >= 0 and y < dest_h:
+                    if 0 <= x < dest_w and 0 <= y < dest_h:
                         for k in range(4):
                             target_array[y][x][k] = 0
     return target_pixbuf
 
+
 class TranslucentWindow(gtk.Window):
 
     def __init__(self, type=gtk.WINDOW_TOPLEVEL):
@@ -158,4 +158,4 @@ class TranslucentWindow(gtk.Window):
         gtk.Window.__init__(self, type)
         if self.translucency:
             gtk.widget_pop_colormap()
-            self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("black"))
+            self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse('black'))
index f8a3991..dbae188 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: ascii -*-
 #
 #  Copyright (C) 2001, 2002 by Tamito KAJIYAMA
-#  Copyright (C) 2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2004, 2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
@@ -10,7 +10,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: prefs.py,v 1.4 2004/04/13 05:21:59 shy Exp $
+# $Id: prefs.py,v 1.5 2005/08/09 00:41:52 shy Exp $
 #
 
 import mimetools
@@ -19,10 +19,13 @@ import UserDict
 
 import ninix.home
 
+
 class Preferences(UserDict.UserDict):
+
     def __init__(self, filename):
         UserDict.UserDict.__init__(self)
         self.filename = filename
+
     def load(self):
         try:
             file = open(self.filename)
@@ -32,17 +35,19 @@ class Preferences(UserDict.UserDict):
         for key, value in prefs.items():
             self[key] = value
         file.close()
+
     def save(self):
         try:
             os.makedirs(os.path.dirname(self.filename))
         except OSError:
             pass
-        file = open(self.filename, "w")
+        file = open(self.filename, 'w')
         keys = self.keys()
         keys.sort()
         for key in keys:
-            file.write("%s: %s\n" % (key, self[key]))
+            file.write('%s: %s\n' % (key, self[key]))
         file.close()
+
     def _get(self, name, default, conv):
         value = self.get(name)
         if value:
@@ -51,11 +56,14 @@ class Preferences(UserDict.UserDict):
             except ValueError:
                 pass
         return default
+
     def getint(self, name, default=None):
         return self._get(name, default, int)
+
     def getfloat(self, name, default=None):
         return self._get(name, default, float)
 
+
 def new_prefs():
     filename = ninix.home.get_preferences()
     return Preferences(filename)
index f9f5385..8afe5b2 100644 (file)
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: sakura.py,v 1.144 2005/07/21 03:59:17 shy Exp $
+# $Id: sakura.py,v 1.145 2005/08/09 00:41:52 shy Exp $
 #
 
 import os
 import re
 import socket
 import select
-import string
 import sys
 import time
 import random
 
-if os.environ.has_key("DISPLAY"):
+if os.environ.has_key('DISPLAY'):
     import gtk ## FIXME
 
 import ninix.main
@@ -32,28 +31,30 @@ import ninix.script
 import ninix.version
 
 # left mouse button
-BUTTON1_CLOSE = "close"
-BUTTON1_RAISE = "raise"
-BUTTON1_LOWER = "lower"
+BUTTON1_CLOSE = 'close'
+BUTTON1_RAISE = 'raise'
+BUTTON1_LOWER = 'lower'
 
 # right mouse button
-BUTTON3_CLOSE = "close"
-BUTTON3_RAISE = "raise"
-BUTTON3_LOWER = "lower"
+BUTTON3_CLOSE = 'close'
+BUTTON3_RAISE = 'raise'
+BUTTON3_LOWER = 'lower'
 
 # default browser
 DEFAULT_BROWSER = "netscape -remote 'openURL(%s,new-window)'"
 
-range_script_speed = [(_("None"), -1),
-                      ("1 (" + _("Fast") + ")", 0),
-                      ("2", 1),
-                      ("3", 2),
-                      ("4", 3),
-                      ("5", 4),
-                      ("6", 6),
-                      ("7 (" + _("Slow") + ")", 8)]
+range_script_speed = [(_('None'), -1),
+                      (''.join(('1 (', _('Fast'), ')')), 0),
+                      ('2', 1),
+                      ('3', 2),
+                      ('4', 3),
+                      ('5', 4),
+                      ('6', 6),
+                      (''.join(('7 (', _('Slow'), ')')), 8)]
+
 
 class Sakura:
+
     BALLOON_LIFE   = 10  # sec (0: never closed automatically)
     SELECT_TIMEOUT = 15  # sec
     PAUSE_TIMEOUT  = 30  # sec
@@ -77,9 +78,9 @@ class Sakura:
         self.sstp_entry_db = None
         self.sstp_request_handler = None
         if self.debug & 16384: ## FIXME
-            self.script_parser = ninix.script.Parser(error="strict")
+            self.script_parser = ninix.script.Parser(error='strict')
         else:
-            self.script_parser = ninix.script.Parser(error="loose")
+            self.script_parser = ninix.script.Parser(error='loose')
         self.script_queue = []
         self.script_mode = self.BROWSE_MODE
         self.script_post_proc = None
@@ -119,7 +120,9 @@ class Sakura:
         self.balloon = balloon
 
     def is_URL(self, s):
-        return s[:7] == "http://" or s[:6] == "ftp://" or s[:6] == "file:/"
+        return s.startswith('http://') or \
+               s.startswith('ftp://') or \
+               s.startswith('file:/')
 
     def is_anchor(self, id):
         if len(id) == 2 and id[0] == 'anchor':
@@ -132,11 +135,11 @@ class Sakura:
         self.execute_command(command, url)
 
     def execute_command(self, command, arg): ## FIXME
-        pos = command.find("%s")
+        pos = command.find('%s')
         if pos < 0:
-            sys.stderr.write("cannot execute command (%s missing)\n")
+            sys.stderr.write('cannot execute command (%s missing)\n')
             return
-        os.system(command[:pos] + arg + command[pos+2:] + " &")
+        os.system(''.join((command[:pos], arg, command[pos + 2:], ' &')))
 
     ###   CALLBACK   ###
     def reset_idle_time(self):
@@ -148,16 +151,16 @@ class Sakura:
             self.sstp_request_handler.send_answer(text)
             self.sstp_request_handler = None
         if self.is_anchor(id):
-            self.notify_event("OnAnchorSelect", id[1])
+            self.notify_event('OnAnchorSelect', id[1])
         elif self.is_URL(id):
             self.launch_browser(id)
             self.reset_script(1)
             self.stand_by(0)
         elif self.sstp_entry_db:
             # leave the previous sstp message as it is
-            self.start_script(self.sstp_entry_db.get(id, r"\e"))
+            self.start_script(self.sstp_entry_db.get(id, r'\e'))
             self.sstp_entry_db = None
-        elif not self.notify_event("OnChoiceSelect", id, text, number):
+        elif not self.notify_event('OnChoiceSelect', id, text, number):
             self.reset_script(1)
             self.stand_by(0)
 
@@ -202,7 +205,7 @@ class Sakura:
             if self.sstp_request_handler:
                 self.sstp_request_handler.send_sstp_break()
                 self.sstp_request_handler = None
-            self.notify_event("OnMouseDoubleClick", "", "", "", side, "")
+            self.notify_event('OnMouseDoubleClick', '', '', '', side, '')
         elif button == 1 and self.mouse_button1 == BUTTON1_CLOSE or \
              button == 3 and self.mouse_button3 == BUTTON3_CLOSE:
             if self.sstp_request_handler:
@@ -215,20 +218,20 @@ class Sakura:
         event = None
         for path in list:
             if os.path.isdir(path) and event is None:
-                event = "OnDirectoryDrop"
+                event = 'OnDirectoryDrop'
             elif os.path.isfile(path):
                 for regex, command in self.helpers:
                     if regex.search(path):
-                        event = "OnFileDropping"
+                        event = 'OnFileDropping'
                         self.execute_command(command, path)
                         break
         if event is None:
-            event = "OnFileDropped"
+            event = 'OnFileDropped'
         self.enqueue_event(event, path, side)
 
     def notify_user_communicate(self, data): ## FIXME: ghost
         if data is not None:
-            self.notify_event("OnCommunicate", "user", data)
+            self.notify_event('OnCommunicate', 'user', data)
 
     def notify_user_teach(self, data): ## FIXME: ghost
         if data is not None:
@@ -242,18 +245,17 @@ class Sakura:
         if data is None:
             data = ''
         ## CHECK: symbol
-        if symbol == "OnUserInput" and self.notify_event("OnUserInput", data):
+        if symbol == 'OnUserInput' and self.notify_event('OnUserInput', data):
             pass
-        elif self.notify_event("OnUserInput", symbol, data):
+        elif self.notify_event('OnUserInput', symbol, data):
             pass
         elif self.notify_event(symbol, data):
             pass
         self.user_interaction = 0
 
-    month_names = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
-                   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
-
-    boot_event = ["OnBoot", "OnFirstBoot", "OnGhostChanged", "OnShellChanged"]
+    month_names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+                   'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+    boot_event = ['OnBoot', 'OnFirstBoot', 'OnGhostChanged', 'OnShellChanged']
 
     def notify_event(self, event, *arglist, **argdict): ## FIXME: ghost&sakura
         #if self.time_critical_session:
@@ -265,28 +267,30 @@ class Sakura:
         type = argdict.get('type', 'GET')
         default = argdict.get('default', None)
         argdict = {'type': type} ## FIXME
-        script = self.ghost.get_event_response(event, *arglist, **argdict) or default
+        script = self.ghost.get_event_response(event, *arglist, **argdict) or \
+                 default
         if self.debug & 1 and script or \
-           self.debug & 2 and not script and event != "OnSecondChange":
+           self.debug & 2 and not script and event != 'OnSecondChange':
             t = time.localtime(time.time())
-            m = self.month_names[t[1]-1]
-            print "\n[%02d/%s/%d:%02d:%02d:%02d %+05d]" % (
-                t[2], m, t[0], t[3], t[4], t[5], -time.timezone/36)
-            print "Event:", event
+            m = self.month_names[t[1] - 1]
+            print '\n[%02d/%s/%d:%02d:%02d:%02d %+05d]' % (
+                t[2], m, t[0], t[3], t[4], t[5], - time.timezone / 36)
+            print 'Event:', event
             for n in range(len(arglist)):
                 value = arglist[n]
                 if value is not None:
-                    print "Reference%d:" % n, '%s' % str(value).encode('utf-8', 'ignore')
+                    print 'Reference%d:' % n, '%s' % \
+                          str(value).encode('utf-8', 'ignore')
         if not script: # an empty script is ignored
             if event in self.boot_event:
                 self.surface_bootup()
-            if event == "OnMouseClick" and arglist[5] == 3:
+            if event == 'OnMouseClick' and arglist[5] == 3:
                 self.surface.open_popup_menu(arglist[5], arglist[3])
             return 0
         if self.debug & 1:
             print '=> "%s"' % script.encode('utf-8', 'ignore')
         if self.passivemode and \
-           (event == "OnSecondChange" or event == "OnMinuteChange"):
+           (event == 'OnSecondChange' or event == 'OnMinuteChange'):
             return 0
         self.start_script(script)
         self.balloon.hide_sstp_message()
@@ -303,7 +307,8 @@ class Sakura:
     def enqueue_script(self, script, sender, handle,
                        host, show_sstp_marker, use_translator,
                        db=None, request_handler=None):
-        if not self.script_queue and not self.time_critical_session and not self.passivemode:
+        if not self.script_queue and \
+           not self.time_critical_session and not self.passivemode:
             if self.sstp_request_handler:
                 self.sstp_request_handler.send_sstp_break()
                 self.sstp_request_handler = None
@@ -318,9 +323,18 @@ class Sakura:
         self.event_queue.append((event, arglist, argdict))
 
     EVENT_SCRIPTS = {
-        "OnUpdateBegin":    r"\t\h\s[0]" + unicode(_("Network Update has begun."), 'utf-8') + r"\e",
-        "OnUpdateComplete": r"\t\h\s[5]" + unicode(_("Network Update completed successfully."), 'utf-8') + r"\e",
-        "OnUpdateFailure":  r"\t\h\s[4]" + unicode(_("Network Update failed."), 'utf-8') + r"\e",
+        'OnUpdateBegin': \
+        ''.join((r'\t\h\s[0]',
+                 unicode(_('Network Update has begun.'), 'utf-8'),
+                 r'\e')),
+        'OnUpdateComplete': \
+        ''.join((r'\t\h\s[5]',
+                 unicode(_('Network Update completed successfully.'), 'utf-8'),
+                 r'\e')),
+        'OnUpdateFailure': \
+        ''.join((r'\t\h\s[4]',
+                 unicode(_('Network Update failed.'), 'utf-8'),
+                 r'\e')),
         }
 
     def handle_event(self): ## FIXME: ghost
@@ -352,21 +366,21 @@ class Sakura:
         return self.script_speed
 
     def set_event_kill_list(self, list): ## FIXME: ghost
-        ##print "Sakura.set_event_kill_list:", list
+        ##print 'Sakura.set_event_kill_list:', list
         self.event_kill_list = list
 
     def get_event_kill_list(self):  ## FIXME: ghost
         return self.event_kill_list
 
     def set_mouse_button1(self, name): ## FIXME: ghost
-        ##print "Sakura.set_mouse_button1:", name
+        ##print 'Sakura.set_mouse_button1:', name
         self.mouse_button1 = name
 
     def get_mouse_button1(self): ## FIXME: ghost
         return self.mouse_button1
 
     def set_mouse_button3(self, name): ## FIXME: ghost
-        ##print "Sakura.set_mouse_button3:", name
+        ##print 'Sakura.set_mouse_button3:', name
         self.mouse_button3 = name
 
     def get_mouse_button3(self): ## FIXME: ghost
@@ -379,7 +393,7 @@ class Sakura:
         return self.browser
 
     def set_helpers(self, list): ## FIXME: ghost
-        ##print "Sakura.set_helpers:", list
+        ##print 'Sakura.set_helpers:', list
         self.helpers = []
         for pattern, command in list:
             try:
@@ -441,14 +455,14 @@ class Sakura:
         self.balloon.hide_sstp_message()
         if reset_surface:
             self.ghost.set_surface_default()
-            self.notify_event("OnSurfaceChange",
+            self.notify_event('OnSurfaceChange',
                               self.ghost.get_surface_id(0),
                               self.ghost.get_surface_id(1))
             self.balloon.set_balloon_default()
-        elif self.ghost.get_surface_id(0) != "0" or \
-             self.ghost.get_surface_id(1) != "10":
+        elif self.ghost.get_surface_id(0) != '0' or \
+             self.ghost.get_surface_id(1) != '10':
             self.__surface_life = random.randint(20, 30)
-            ##print "surface_life =", self.__surface_life
+            ##print 'surface_life =', self.__surface_life
 
     def start(self): ## FIXME: ghost
         self.start_time = time.time()
@@ -468,47 +482,48 @@ class Sakura:
 
     def notify_ghost_changing(self, name, method, proc): ## FIXME: ghost
         self.reset_script(1)
-        self.enqueue_event("OnGhostChanging", name, method, proc=proc)
+        self.enqueue_event('OnGhostChanging', name, method, proc=proc)
 
     def notify_shell_changing(self, name, path, proc): ## FIXME: ghost
         self.reset_script(1)
-        self.enqueue_event("OnShellChanging", name, path, proc=proc)
+        self.enqueue_event('OnShellChanging', name, path, proc=proc)
 
     def notify_vanish_selecting(self): ## FIXME: ghost
         self.reset_script(1)
-        self.notify_event("OnVanishSelecting")
+        self.notify_event('OnVanishSelecting')
 
     def notify_vanish_selected(self, proc): ## FIXME: ghost
         self.reset_script(1)
-        self.enqueue_event("OnVanishSelected", proc=proc)
+        self.enqueue_event('OnVanishSelected', proc=proc)
         self.vanished = 1
 
     def notify_vanish_cancel(self): ## FIXME: ghost
         self.reset_script(1)
-        self.notify_event("OnVanishCancel")
+        self.notify_event('OnVanishCancel')
 
     def notify_ghost_changed(self, name, vanished, default): ## FIXME: ghost
         if self.ghost.get_ghost_time() == 0:
-            if self.notify_event("OnFirstBoot", self.ghost.get_vanished_count()):
+            if self.notify_event('OnFirstBoot',
+                                 self.ghost.get_vanished_count()):
                 return 
         elif vanished:
-            if self.notify_event("OnVanished", name):
+            if self.notify_event('OnVanished', name):
                 return
         else:
-            if self.notify_event("OnGhostChanged", name):
+            if self.notify_event('OnGhostChanged', name):
                 return
-        self.notify_event("OnBoot", default=default)
+        self.notify_event('OnBoot', default=default)
 
     def notify_shell_changed(self, name, path): ## FIXME: ghost
-        self.notify_event("OnShellChanged", name, name, path)
+        self.notify_event('OnShellChanged', name, name, path)
 
     def notify_ninix_reloading(self, proc): ## FIXME: ghost
         self.reset_script(1)
-        self.enqueue_event("OnNinixReloading", proc=proc)
+        self.enqueue_event('OnNinixReloading', proc=proc)
 
     def notify_ninix_reloaded(self): ## FIXME: ghost
-        self.notify_event("OnNinixReloaded")
-        self.notify_event("OnBoot", default=ninix.version.VERSION_INFO)
+        self.notify_event('OnNinixReloaded')
+        self.notify_event('OnBoot', default=ninix.version.VERSION_INFO)
 
     def notify_about(self): ## FIXME: ghost
         self.start_script(ninix.version.VERSION_INFO)
@@ -528,7 +543,8 @@ class Sakura:
                 self.get_selfname(),
                 self.ghost.get_surface_id(0),
                 self.ghost.get_surface_id(1))
-            otherghostname = self.ghost.communicate.get_otherghostname(self.get_selfname())
+            otherghostname = self.ghost.communicate.get_otherghostname(
+                self.get_selfname())
             if otherghostname != self.old_otherghostname:
                 args = []
                 args.extend(otherghostname)
@@ -557,7 +573,7 @@ class Sakura:
                 if self.sstp_request_handler:
                     self.sstp_request_handler.send_timeout()
                     self.sstp_request_handler = None
-                if not self.notify_event("OnChoiceTimeout"):
+                if not self.notify_event('OnChoiceTimeout'):
                     self.stand_by(0)
         elif self.sstp_handle is not None:
             self.close_sstp_handle()
@@ -588,20 +604,22 @@ class Sakura:
             if now - self.silent_time > self.SILENT_TIME:
                 self.keep_silence(0)
         elif self.clock[0] != second and \
-             self.notify_event("OnSecondChange", self.get_uptime(),
-                               mikire, kasanari, not self.passivemode and self.cantalk):
+             self.notify_event('OnSecondChange', self.get_uptime(),
+                               mikire, kasanari,
+                               not self.passivemode and self.cantalk):
             pass
         elif self.clock[1] != minute and \
-             self.notify_event("OnMinuteChange", self.get_uptime(),
-                               mikire, kasanari, not self.passivemode and self.cantalk):
+             self.notify_event('OnMinuteChange', self.get_uptime(),
+                               mikire, kasanari,
+                               not self.passivemode and self.cantalk):
             pass
         elif self.surface_mouse_motion is not None:
             side, x, y, part = self.surface_mouse_motion
-            self.notify_event("OnMouseMove", x, y, "", side, part)
+            self.notify_event('OnMouseMove', x, y, '', side, part)
             self.surface_mouse_motion = None
         elif idle > self.__surface_life > 0 and not self.passivemode:
             self.__surface_life = 0
-            self.notify_event("OnSurfaceRestore",
+            self.notify_event('OnSurfaceRestore',
                               self.ghost.get_surface_id(0),
                               self.ghost.get_surface_id(1))
         self.clock = (second, minute)
@@ -612,15 +630,15 @@ class Sakura:
             return
         self.script_origin = origin or self.FROM_GHOST
         self.reset_script(1)
-        if script.rstrip()[-2:] != r"\e":
-            script += r"\e"
+        if not script.rstrip().endswith(r'\e'):
+            script = ''.join((script, r'\e'))
         self.processed_script = []
         while 1:
             try:
                 self.processed_script.extend(self.script_parser.parse(script))
             except ninix.script.ParserError, e:
-                sys.stderr.write("-" * 50 + "\n")
-                sys.stderr.write(("%s\n" % e).encode('utf-8', 'ignore'))
+                sys.stderr.write(''.join(('-' * 50, '\n')))
+                sys.stderr.write(('%s\n' % e).encode('utf-8', 'ignore'))
                 done, script = e
                 self.processed_script.extend(done)
             else:
@@ -658,25 +676,25 @@ class Sakura:
         node = self.processed_script.pop(0)
         if node[0] == ninix.script.SCRIPT_TAG:
             name, args = node[1], node[2:]
-            if name == r"\e":
+            if name == r'\e':
                 id = self.ghost.get_surface_id(self.script_side)
                 self.surface.invoke_yen_e(self.script_side, id)
                 self.reset_script()
                 self.__balloon_life = self.BALLOON_LIFE
-            elif name in [r"\0", r"\h"]:
+            elif name in [r'\0', r'\h']:
                 ##self.balloon.show(0)
                 self.script_side = 0
-            elif name in [r"\1", r"\u"]:
+            elif name in [r'\1', r'\u']:
                 ##self.balloon.show(1)
                 self.script_side = 1
-            elif name == r"\p":
+            elif name == r'\p':
                 try:
                     id = int(args[0])
                 except:
                     return
                 if id >= 0:
                     self.script_side = id
-            elif name == r"\4": ## FIXME
+            elif name == r'\4': ## FIXME
                 if self.script_side == 0:
                     sw, sh = self.ghost.get_surface_size(1)
                     sx, sy = self.ghost.get_surface_position(1)
@@ -688,11 +706,12 @@ class Sakura:
                 w, h = self.ghost.get_surface_size(self.script_side)
                 x, y = self.ghost.get_surface_position(self.script_side)
                 scrn_w = gtk.gdk.screen_width() ## FIXME
-                scrn_h = gtk.gdk.screen_height() - self.ghost.get_bottom_margin()
+                scrn_h = gtk.gdk.screen_height() - \
+                         self.ghost.get_bottom_margin()
                 if sx + sw / 2 > scrn_w / 2:
-                    new_x = sx - w - int(scrn_w/20)
+                    new_x = sx - w - int(scrn_w / 20)
                 else:
-                    new_x = sx + sw + int(scrn_w/20)
+                    new_x = sx + sw + int(scrn_w / 20)
                 new_x = max(new_x, 0)
                 new_x = min(new_x, scrn_w - w)
                 if x > new_x:
@@ -702,11 +721,12 @@ class Sakura:
                 if abs(sx - new_x) < abs(sx - x):
                     return
                 for current_x in range(x, new_x, step):
-                    self.ghost.set_surface_position(self.script_side, current_x, y)
+                    self.ghost.set_surface_position(self.script_side,
+                                                    current_x, y)
                     self.balloon.reset_balloon_all()
                 self.ghost.set_surface_position(self.script_side, new_x, y)
                 self.balloon.reset_balloon_all()
-            elif name == r"\5": ## FIXME
+            elif name == r'\5': ## FIXME
                 if self.script_side == 0:
                     sw, sh = self.ghost.get_surface_size(1)
                     sx, sy = self.ghost.get_surface_position(1)
@@ -718,9 +738,9 @@ class Sakura:
                 w, h = self.ghost.get_surface_size(self.script_side)
                 x, y = self.ghost.get_surface_position(self.script_side)
                 scrn_w = gtk.gdk.screen_width() ## FIXME
-                scrn_h = gtk.gdk.screen_height() - self.ghost.get_bottom_margin()
-                if sx + sw/2 > x and sx + sw/2 < x + w or \
-                   x + w/2 > sx and x + w/2 < sx + sw:
+                scrn_h = gtk.gdk.screen_height() - \
+                         self.ghost.get_bottom_margin()
+                if x < sx + sw / 2 < x + w or sx < x + w / 2 < sx + sw:
                     return
                 if sx + sw / 2 > x + w / 2:
                     new_x = sx - w / 2 + 1
@@ -733,27 +753,28 @@ class Sakura:
                 else:
                     step = 10
                 for current_x in range(x, new_x, step):
-                    self.ghost.set_surface_position(self.script_side, current_x, y)
+                    self.ghost.set_surface_position(self.script_side,
+                                                    current_x, y)
                     self.balloon.reset_balloon_all()
                 self.ghost.set_surface_position(self.script_side, new_x, y)
                 self.balloon.reset_balloon_all()
-            elif name == r"\s":
+            elif name == r'\s':
                 id = args[0]
-                if id == "-1":
+                if id == '-1':
                     self.ghost.hide_surface(self.script_side)
                 else:
                     self.ghost.set_surface_id(self.script_side, id)
                     self.ghost.show_surface(self.script_side)
                     ## FIXME: self.script_side > 1
-                    self.notify_event("OnSurfaceChange",
+                    self.notify_event('OnSurfaceChange',
                                       self.ghost.get_surface_id(0),
                                       self.ghost.get_surface_id(1))
                     self.ghost.position_balloons() ## FIXME
                 if self.script_side in [0, 1] and \
                        not self.__boot[self.script_side]:
                     self.__boot[self.script_side] = 1
-            elif name == r"\b":
-                if args[0] == "-1":
+            elif name == r'\b':
+                if args[0] == '-1':
                     self.balloon.hide(self.script_side)
                 else:
                     try:
@@ -762,23 +783,23 @@ class Sakura:
                         id = 0
                     else:
                         self.balloon.set_balloon(self.script_side, id)
-            elif name == r"\_b":
+            elif name == r'\_b':
                 filename, x, y = self.expand_meta(args[0]).split(',')
                 filename = filename.lower()
                 path = os.path.join(self.ghost.get_prefix(), 'ghost/master',
                                     filename.replace('\\', '/'))
                 if os.path.isfile(path):
                     self.balloon.append_image(self.script_side, path, x, y)
-            elif name == r"\n":
-                if len(args) > 0 and self.expand_meta(args[0]) == 'half':
-                    self.balloon.append_text(self.script_side, u"\n[half]")
+            elif name == r'\n':
+                if args and self.expand_meta(args[0]) == 'half':
+                    self.balloon.append_text(self.script_side, u'\n[half]')
                 else:
-                    self.balloon.append_text(self.script_side, u"\n")
-            elif name == r"\c":
+                    self.balloon.append_text(self.script_side, u'\n')
+            elif name == r'\c':
                 self.balloon.clear_text(self.script_side)
-            elif name in [r"\w", r"\_w"]:
+            elif name in [r'\w', r'\_w']:
                 if not self.quick_session and self.script_speed >= 0:
-                    if name == r"\w":
+                    if name == r'\w':
                         unit = 0.05  # 50ms
                     else:
                         unit = 0.001  # 1ms
@@ -788,16 +809,16 @@ class Sakura:
                         amount = 0
                     if amount > 0:
                         self.script_wait = time.time() + amount
-            elif name == r"\t":
+            elif name == r'\t':
                 self.time_critical_session = not self.time_critical_session
-            elif name == r"\_q":
+            elif name == r'\_q':
                 self.quick_session = not self.quick_session
-            elif name == r"\_s":
+            elif name == r'\_s':
                 self.set_synchronized_session([int(arg) for arg in args])
-            elif name == r"\_e":
+            elif name == r'\_e':
                 self.balloon.hide(self.script_side)
                 self.balloon.clear_text(self.script_side)
-            elif name == r"\q":
+            elif name == r'\q':
                 newline_required = 0
                 if len(args) == 3: # traditional syntax
                     num, id, text = args
@@ -805,21 +826,22 @@ class Sakura:
                 else: # new syntax
                     text, id = args
                 text = self.expand_meta(text)
-                self.balloon.append_link(self.script_side, id, text, newline_required)
+                self.balloon.append_link(self.script_side, id, text,
+                                         newline_required)
                 self.script_mode = self.SELECT_MODE
-            elif name == r"\URL":
+            elif name == r'\URL':
                 text = self.expand_meta(args[0])
                 if len(args) == 1:
                     link = text
                 else:
-                    link = "#cancel"
+                    link = '#cancel'
                 self.balloon.append_link(self.script_side, link, text)
                 for i in range(1, len(args), 2):
                     link = self.expand_meta(args[i])
-                    text = self.expand_meta(args[i+1])
+                    text = self.expand_meta(args[i + 1])
                     self.balloon.append_link(self.script_side, link, text)
                 self.script_mode = self.SELECT_MODE
-            elif name == r"\_a":
+            elif name == r'\_a':
                 if self.anchor:
                     id = self.anchor[0]
                     text = self.anchor[1]
@@ -828,81 +850,82 @@ class Sakura:
                 else:
                     id = args[0]
                     self.anchor = [('anchor', id), '']
-            elif name == r"\x":
+            elif name == r'\x':
                 if self.script_mode == self.BROWSE_MODE:
                     self.script_mode = self.PAUSE_MODE
                     self.balloon.redraw_arrow(self.script_side, 1)
-                    self.balloon.append_text(self.script_side, u"\n")
-            elif name == r"\a": # obsolete # only for old SHIORI
+                    self.balloon.append_text(self.script_side, u'\n')
+            elif name == r'\a': # obsolete # only for old SHIORI
                 self.start_script(self.ghost.getaistringrandom())
-            elif name == r"\i":
+            elif name == r'\i':
                 try:
                     id = int(args[0])
                 except ValueError:
                     pass
                 else:
                     self.surface.invoke(self.script_side, id)
-            elif name == r"\j":
+            elif name == r'\j':
                 id = args[0]
                 if self.is_URL(id):
                     self.launch_browser(id)
                 elif self.sstp_entry_db:
-                    self.start_script(self.sstp_entry_db.get(id, r"\e"))
-            elif name == r"\-":
+                    self.start_script(self.sstp_entry_db.get(id, r'\e'))
+            elif name == r'\-':
                 self.ghost.quit()
-            elif name == r"\+":
+            elif name == r'\+':
                 self.ghost.select_ghost(1)
-            elif name == r"\_+":
+            elif name == r'\_+':
                 self.ghost.select_ghost(0)
-            elif name == r"\m":
+            elif name == r'\m':
                 self.write_sstp_handle(self.expand_meta(args[0]))
-            elif name == r"\&":
+            elif name == r'\&':
                 if self.name2codepoint is not None:
                     text = unichr(self.name2codepoint.get(args[0]))
                 else:
                     text = None
                 if text is None:
-                    text = "?"
+                    text = '?'
                 self.balloon.append_text(self.script_side, text)
-            elif name == r"\_m":
+            elif name == r'\_m':
                 try:
                     num = int(args[0], 16)
                 except ValueError:
                     num = 0
-                if num >= 0x20 and num <= 0x7e:
+                if 0x20 <= num <= 0x7e:
                     text = chr(num)
                 else:
-                    text = "?"
+                    text = '?'
                 self.balloon.append_text(self.script_side, text)
-            elif name == r"\_u":
-                if re.match("0x[a-fA-F0-9]{4}", args[0]):
-                    text = eval("u\"\\u" + args[0][2:] + "\"")
+            elif name == r'\_u':
+                if re.match('0x[a-fA-F0-9]{4}', args[0]):
+                    text = eval(''.join(('u"\\u', args[0][2:], '"')))
                     self.balloon.append_text(self.script_side, text)
                 else:
-                    self.balloon.append_text(self.script_side, u"?")
-            elif name == r"\_v":
+                    self.balloon.append_text(self.script_side, u'?')
+            elif name == r'\_v':
                 filename = self.expand_meta(args[0])
                 filename = filename.lower()
-                path = os.path.join(self.ghost.get_prefix(), 'ghost/master', filename)
+                path = os.path.join(self.ghost.get_prefix(), 'ghost/master',
+                                    filename)
                 if os.path.isfile(path):
                     for regex, command in self.helpers:
                         if regex.search(path):
                             self.execute_command(command, path)
                             break
-            elif name == r"\!" and len(args) > 0:
+            elif name == r'\!' and args:
                 argc = len(args)
                 args = [self.expand_meta(s) for s in args]
-                if args[0] == "raise" and argc >= 2:
+                if args[0] == 'raise' and argc >= 2:
                     apply(self.notify_event, tuple(args[1:10]))
-                elif args[0:2] == ["open", "browser"] and argc > 2:
+                elif args[0:2] == ['open', 'browser'] and argc > 2:
                     self.launch_browser(args[2])
-                elif args[0:2] == ["open", "communicatebox"]:
+                elif args[0:2] == ['open', 'communicatebox']:
                     if not self.passivemode:
                         self.open_communicatebox()
-                elif args[0:2] == ["open", "teachbox"]:
+                elif args[0:2] == ['open', 'teachbox']:
                     if not self.passivemode:
                         self.open_teachbox()
-                elif args[0:2] == ["open", "inputbox"] and argc > 2:
+                elif args[0:2] == ['open', 'inputbox'] and argc > 2:
                     if not self.passivemode:
                         if argc > 4:
                             self.open_inputbox(args[2], args[3], args[4])
@@ -910,73 +933,73 @@ class Sakura:
                             self.open_inputbox(args[2], args[3])
                         else:
                             self.open_inputbox(args[2])
-                elif args[0:2] == ["open", "configurationdialog"]:
+                elif args[0:2] == ['open', 'configurationdialog']:
                     self.ghost.edit_preferences()
-                elif args[0:2] == ["change", "ghost"] and argc > 2:
-                    if args[2] == "random":
+                elif args[0:2] == ['change', 'ghost'] and argc > 2:
+                    if args[2] == 'random':
                         self.ghost.select_ghost(0, 0)
                     else:
                         self.ghost.select_ghost_by_name(args[2], 0)
-                elif args[0:1] == ["updatebymyself"]:
+                elif args[0:1] == ['updatebymyself']:
                     if not self.busy():
                         self.ghost.update()
-                elif args[0:1] == ["vanishbymyself"]: ## FIXME
+                elif args[0:1] == ['vanishbymyself']: ## FIXME
                     self.vanished = 1
                     count = self.ghost.get_vanished_count()
                     self.ghost.set_vanished_count(count + 1)
                     self.ghost.set_ghost_time(0)
                     self.ghost.app.stop_sakura(self.ghost.app.vanish_sakura)
-                elif args[1:2] == ["repaint"]:
-                    if args[0:1] == ["lock"]:
+                elif args[1:2] == ['repaint']:
+                    if args[0:1] == ['lock']:
                         self.lock_repaint = 1
-                    elif args[0:1] == ["unlock"]:
+                    elif args[0:1] == ['unlock']:
                         self.lock_repaint = 0
-                elif args[1:2] == ["passivemode"]:
-                    if args[0:1] == ["enter"]:
+                elif args[1:2] == ['passivemode']:
+                    if args[0:1] == ['enter']:
                         self.passivemode = 1
-                    elif args[0:1] == ["leave"]:
+                    elif args[0:1] == ['leave']:
                         self.passivemode = 0
-                elif args[0:2] == ["set", "alignmentondesktop"]:
-                    if args[2] == "bottom":
+                elif args[0:2] == ['set', 'alignmentondesktop']:
+                    if args[2] == 'bottom':
                         if self.synchronized_session:
                             for id in self.synchronized_session:
                                 self.ghost.align_bottom(id)
                         else:
                             self.ghost.align_bottom(self.script_side)
-                    elif args[2] == "top":
+                    elif args[2] == 'top':
                         if self.synchronized_session:
                             for id in self.synchronized_session:
                                 self.ghost.align_top(id)
                         else:
                             self.ghost.align_top(self.script_side)
-                elif args[0:2] == ["set", "alignmenttodesktop"]:
-                    if args[2] == "free":
+                elif args[0:2] == ['set', 'alignmenttodesktop']:
+                    if args[2] == 'free':
                         if self.synchronized_session:
                             for id in self.synchronized_session:
                                 self.surface.set_alignment(id, 2)
                         else:
                             self.surface.set_alignment(self.script_side, 2)
-                elif args[0:2] == ["set", "windowstate"]:
-                    if args[2] == "minimize":
+                elif args[0:2] == ['set', 'windowstate']:
+                    if args[2] == 'minimize':
                         self.surface.window_iconify(True)
-                    ##elif args[2] == "!minimize":
+                    ##elif args[2] == '!minimize':
                     ##    self.surface.window_iconify(False)
-                    elif args[2] == "stayontop":
+                    elif args[2] == 'stayontop':
                         self.surface.window_stayontop(True)
-                    elif args[2] == "!stayontop":
+                    elif args[2] == '!stayontop':
                         self.surface.window_stayontop(False)
                 elif args[0] == '*':
                     self.balloon.append_sstp_marker(self.script_side)
-            elif name == r"\__c":
+            elif name == r'\__c':
                 self.open_communicatebox()
-            elif name == r"\__t":
+            elif name == r'\__t':
                 self.open_teachbox()
-            elif name == r"\v":
+            elif name == r'\v':
                 self.ghost.raise_surface(self.script_side)
         elif node[0] == ninix.script.SCRIPT_TEXT:
             text = self.expand_meta(node[1])
             if self.anchor:
-                self.anchor[1] = self.anchor[1] + text
+                self.anchor[1] = ''.join((self.anchor[1], text))
             elif not self.quick_session and self.script_speed >= 0:
                 self.processed_text = text
             else:
@@ -991,7 +1014,7 @@ class Sakura:
     def open_teachbox(self): ## FIXME: ghost&sakura
         if self.user_interaction:
             return
-        self.notify_event("OnTeachStart")
+        self.notify_event('OnTeachStart')
         self.balloon.show_teachbox()
         self.user_interaction = 1
 
@@ -1006,7 +1029,7 @@ class Sakura:
             self.script_mode = self.BROWSE_MODE
             self.script_post_proc = None
         self.processed_script = None
-        self.processed_text = ""
+        self.processed_text = ''
         self.time_critical_session = 0
         self.quick_session = 0
         self.set_synchronized_session(reset=1)
@@ -1029,42 +1052,44 @@ class Sakura:
         for chunk in text_node:
             if chunk[0] == ninix.script.TEXT_STRING:
                 buffer.append(chunk[1])
-            elif chunk[1] == "%month":
+            elif chunk[1] == '%month':
                 buffer.append(str(self.current_time[1]))
-            elif chunk[1] == "%day":
+            elif chunk[1] == '%day':
                 buffer.append(str(self.current_time[2]))
-            elif chunk[1] == "%hour":
+            elif chunk[1] == '%hour':
                 buffer.append(str(self.current_time[3]))
-            elif chunk[1] == "%minute":
+            elif chunk[1] == '%minute':
                 buffer.append(str(self.current_time[4]))
-            elif chunk[1] == "%second":
+            elif chunk[1] == '%second':
                 buffer.append(str(self.current_time[5]))
-            elif chunk[1] in ["%username", "%c"]:
+            elif chunk[1] in ['%username', '%c']:
                 buffer.append(self.get_username())
-            elif chunk[1] == "%selfname":
+            elif chunk[1] == '%selfname':
                 buffer.append(self.get_selfname())
-            elif chunk[1] == "%selfname2":
+            elif chunk[1] == '%selfname2':
                 buffer.append(self.get_selfname2())
-            elif chunk[1] == "%keroname":
+            elif chunk[1] == '%keroname':
                 buffer.append(self.get_keroname())
-            elif chunk[1] == "%friendname":
+            elif chunk[1] == '%friendname':
                 buffer.append(self.get_friendname())
-            elif chunk[1] == "%screenwidth":
+            elif chunk[1] == '%screenwidth':
                 buffer.append(str(gtk.gdk.screen_width())) ## FIXME
-            elif chunk[1] == "%screenheight":
+            elif chunk[1] == '%screenheight':
                 buffer.append(str(gtk.gdk.screen_height())) ## FIXME
-            elif chunk[1] == "%et":
-                buffer.append(unicode("%d万年" % self.current_time[7], 'UTF-8'))
-            elif chunk[1] == "%exh":
+            elif chunk[1] == '%et':
+                buffer.append(
+                    unicode('%d万年' % self.current_time[7], 'UTF-8'))
+            elif chunk[1] == '%exh':
                 buffer.append(str(self.get_uptime()))
-            elif chunk[1] in ["%ms", "%mz", "%ml", "%mc", "%mh", \
-                              "%mt", "%me", "%mp", "%m?"]:
-                buffer.append(self.ghost.getword('\\' + chunk[1][1:]))
-            elif chunk[1] == "%dms":
+            elif chunk[1] in ['%ms', '%mz', '%ml', '%mc', '%mh', \
+                              '%mt', '%me', '%mp', '%m?']:
+                buffer.append(
+                    self.ghost.getword(''.join(('\\', chunk[1][1:]))))
+            elif chunk[1] == '%dms':
                 buffer.append(self.ghost.getdms())
             else: # %c, %songname
                 buffer.append(chunk[1])
-        return string.join(buffer, '')
+        return ''.join(buffer)
 
     ###   SEND SSTP/1.3   ###
     def open_sstp_handle(self, path):
@@ -1073,7 +1098,7 @@ class Sakura:
             handle.connect(path)
         except socket.error:
             handle = None # discard socket object
-            sys.stderr.write("cannot open Unix socket: %s\n" % path)
+            sys.stderr.write('cannot open Unix socket: %s\n' % path)
         return handle
 
     def _send_sstp_handle(self, data):
@@ -1081,29 +1106,30 @@ class Sakura:
         if not w:
             return
         try:
-            self.sstp_handle.send(data + "\n")
+            self.sstp_handle.send(''.join((data, '\n')))
         except socket.error:
             pass
 
     def write_sstp_handle(self, data):
         if self.sstp_handle is None:
             return
-        self._send_sstp_handle("+" + data)
-        ##print "write_sstp_handle(%s)" % repr(data)
+        self._send_sstp_handle(''.join(('+', data)))
+        ##print 'write_sstp_handle(%s)' % repr(data)
 
     def close_sstp_handle(self):
         if self.sstp_handle is None:
             return
-        self._send_sstp_handle("-")
-        ##print "close_sstp_handle()"
+        self._send_sstp_handle('-')
+        ##print 'close_sstp_handle()'
         try:
             self.sstp_handle.close()
         except socket.error:
             pass
         self.sstp_handle = None
 
+
 def test():
     pass
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     test()
index bcdaddd..64b18b5 100644 (file)
@@ -2,7 +2,7 @@
 #
 #  script.py - a Sakura Script parser
 #  Copyright (C) 2001, 2002 by Tamito KAJIYAMA
-#  Copyright (C) 2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2004, 2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: script.py,v 1.12 2005/06/12 02:30:57 shy Exp $
+# $Id: script.py,v 1.13 2005/08/09 00:41:52 shy Exp $
 #
 
 import re
-import string
 import sys
 
 TOKEN_TAG         = 1
@@ -26,18 +25,18 @@ TOKEN_NUMBER      = 5
 TOKEN_STRING      = 6
 
 patterns = [
-    (TOKEN_TAG, re.compile(r"\\[ehunjcxtpqzy*v0123456789fmia!&+---]|"
-                           r"\\[sb][0-9]?|\\w[0-9]|\\_[wqslvVbe+cumna]|"
-                           r"\\__[ct]|\\URL")),
-    (TOKEN_META, re.compile(r"%month|%day|%hour|%minute|%second|%username|"
-                            r"%selfname2?|%keroname|%friendname|%songname|"
-                            r"%screen(width|height)|%exh|%et|%m[szlchtep?]|"
-                            r"%dms|%j|%c")),
-    (TOKEN_NUMBER, re.compile(r"[0-9]+")),
-    (TOKEN_OPENED_SBRA, re.compile(r"\[")),
-    (TOKEN_CLOSED_SBRA, re.compile(r"\]")),
-    (TOKEN_STRING, re.compile(r"(\\\\|\\%|\\\]|[^\\\[\]%0-9])+")),
-    (TOKEN_STRING, re.compile(r"[%\\]")),
+    (TOKEN_TAG, re.compile(r'\\[ehunjcxtpqzy*v0123456789fmia!&+---]|'
+                           r'\\[sb][0-9]?|\\w[0-9]|\\_[wqslvVbe+cumna]|'
+                           r'\\__[ct]|\\URL')),
+    (TOKEN_META, re.compile(r'%month|%day|%hour|%minute|%second|%username|'
+                            r'%selfname2?|%keroname|%friendname|%songname|'
+                            r'%screen(width|height)|%exh|%et|%m[szlchtep?]|'
+                            r'%dms|%j|%c')),
+    (TOKEN_NUMBER, re.compile(r'[0-9]+')),
+    (TOKEN_OPENED_SBRA, re.compile(r'\[')),
+    (TOKEN_CLOSED_SBRA, re.compile(r'\]')),
+    (TOKEN_STRING, re.compile(r'(\\\\|\\%|\\\]|[^\\\[\]%0-9])+')),
+    (TOKEN_STRING, re.compile(r'[%\\]')),
     ]
 
 SCRIPT_TAG  = 1
@@ -46,61 +45,69 @@ SCRIPT_TEXT = 2
 TEXT_META   = 1
 TEXT_STRING = 2
 
+
 class ParserError(Exception):
-    def __init__(self, message, error="strict",
+
+    def __init__(self, message, error='strict',
                  script=None, src=None, column=None, length=None, skip=None):
-        if error not in ["strict", "loose"]:
-            raise ValueError, "unknown error scheme: %s" % str(error)
+        if error not in ['strict', 'loose']:
+            raise ValueError, 'unknown error scheme: %s' % str(error)
         self.message = message
         self.error = error
         self.script = script or []
-        self.src = src or ""
+        self.src = src or ''
         self.column = column
         self.length = length or 0
         self.skip = skip or 0
+
     def __getitem__(self, n):
         if n == 0:
-            if self.error == "strict":
+            if self.error == 'strict':
                 return []
             else:
                 return self.script
         elif n == 1:
-            if self.error == "strict" or self.column is None:
-                return ""
+            if self.error == 'strict' or self.column is None:
+                return ''
             else:
-                return self.src[self.column+self.skip:]
+                return self.src[self.column + self.skip:]
         else:
-            raise IndexError("tuple index out of range")
+            raise IndexError('tuple index out of range')
+
     def __str__(self):
         if self.column is not None:
             column = self.column
             if self.src:
-                dump = self.src[:column] + '\x1b[7m' + \
-                       (self.src[column:column+self.length] or " ") + \
-                       '\x1b[m' + self.src[column+self.length:]
+                dump = ''.join((self.src[:column],
+                                '\x1b[7m',
+                                (self.src[column:column + self.length] or ' '),
+                                '\x1b[m',
+                                self.src[column + self.length:]))
             else:
-                dump = ""
+                dump = ''
         else:
-            column = "??"
+            column = '??'
             dump = self.src
-        return "ParserError: column %s: %s\n%s" % (column, self.message, dump)
+        return 'ParserError: column %s: %s\n%s' % (column, self.message, dump)
 
 class Parser:
-    def __init__(self, error="strict"):
-        if error not in ["strict", "loose"]:
-            raise ValueError, "unknown error scheme: %s" % str(error)
+
+    def __init__(self, error='strict'):
+        if error not in ['strict', 'loose']:
+            raise ValueError, 'unknown error scheme: %s' % str(error)
         self.error = error
-    def perror(self, msg, position="column", skip=None):
-        if position not in ["column", "eol"]:
-            raise ValueError, "unknown position scheme: %s" % str(position)
-        if skip not in ["length", "rest", None]:
-            raise ValueError, "unknown skip scheme: %s" % str(skip)
-        if position == "column":
+
+    def perror(self, msg, position='column', skip=None):
+        if position not in ['column', 'eol']:
+            raise ValueError, 'unknown position scheme: %s' % str(position)
+        if skip not in ['length', 'rest', None]:
+            raise ValueError, 'unknown skip scheme: %s' % str(skip)
+        if position == 'column':
             column = self.column
             length = self.length
-            if skip == "length":
+            if skip == 'length':
                 skip = length
-            elif skip == "rest":
+            elif skip == 'rest':
                 skip = len(self.src[column:])
             else:
                 skip = 0
@@ -110,6 +117,7 @@ class Parser:
             skip = 0
         return ParserError(msg, self.error,
                            self.script, self.src, column, length, skip)
+
     def tokenize(self, s):
         tokens = []
         pos = 0
@@ -120,18 +128,20 @@ class Parser:
                 if match:
                     break
             else:
-                raise RuntimeError, "should not reach here"
+                raise RuntimeError, 'should not reach here'
             tokens.append((token, s[pos:match.end()]))
             pos = match.end()
         return tokens
+
     def next_token(self):
         try:
             token, lexeme = self.tokens.pop(0)
         except IndexError:
-            raise self.perror("unexpected end of script", position="eol")
+            raise self.perror('unexpected end of script', position='eol')
         self.column += self.length
         self.length = len(lexeme)
         return token, lexeme
+
     def parse(self, s):
         if not s: return []
         # tokenize the script
@@ -147,28 +157,28 @@ class Parser:
         anchor = None
         while self.tokens:
             token, lexeme = self.next_token()
-            if token == TOKEN_STRING and lexeme == "\\":
+            if token == TOKEN_STRING and lexeme == '\\':
                 if string_chunks:
-                    text.append((TEXT_STRING, string.join(string_chunks, '')))
+                    text.append((TEXT_STRING, ''.join(string_chunks)))
                 if text:
                     self.script.append((SCRIPT_TEXT, tuple(text)))
-                raise self.perror("unknown tag", skip="length")
-            elif token == TOKEN_STRING and lexeme == "%":
+                raise self.perror('unknown tag', skip='length')
+            elif token == TOKEN_STRING and lexeme == '%':
                 string_chunks.append(lexeme)
-                text.append((TEXT_STRING, string.join(string_chunks, '')))
+                text.append((TEXT_STRING, ''.join(string_chunks)))
                 self.script.append((SCRIPT_TEXT, tuple(text)))
-                raise self.perror("unknown meta string", skip="length")
+                raise self.perror('unknown meta string', skip='length')
             if token in [TOKEN_NUMBER, TOKEN_OPENED_SBRA,
                          TOKEN_STRING, TOKEN_CLOSED_SBRA]:
-                lexeme = lexeme.replace(r"\\", "\\")
-                lexeme = lexeme.replace(r"\%", "%")
+                lexeme = lexeme.replace(r'\\', '\\')
+                lexeme = lexeme.replace(r'\%', '%')
                 string_chunks.append(lexeme)
                 continue
             if string_chunks:
-                text.append((TEXT_STRING, string.join(string_chunks, '')))
+                text.append((TEXT_STRING, ''.join(string_chunks)))
                 string_chunks = []
             if token == TOKEN_META:
-                if lexeme == "%j":
+                if lexeme == '%j':
                     argument = self.read_sbra_id()
                     text.append((TEXT_META, lexeme, argument))
                 else:
@@ -177,60 +187,62 @@ class Parser:
             if text:
                 self.script.append((SCRIPT_TEXT, tuple(text)))
                 text = []
-            if lexeme in ["\\a", "\\c", "\\e", "\\t", "\\_e",
-                          "\\v", "\\x", "\\y", "\\z", "\\_q",
-                          "\\4", "\\5", "\\6", "\\7",
-                          "\\2", "\\*", "\\-", "\\+", "\\_+",
-                          "\\_n", "\\_V", "\\__c", "\\__t"]:
+            if lexeme in ['\\a', '\\c', '\\e', '\\t', '\\_e',
+                          '\\v', '\\x', '\\y', '\\z', '\\_q',
+                          '\\4', '\\5', '\\6', '\\7',
+                          '\\2', '\\*', '\\-', '\\+', '\\_+',
+                          '\\_n', '\\_V', '\\__c', '\\__t']:
                 self.script.append((SCRIPT_TAG, lexeme))
-            elif lexeme in ["\\0", "\\h"]:
+            elif lexeme in ['\\0', '\\h']:
                 self.script.append((SCRIPT_TAG, lexeme))
                 scope = 0
-            elif lexeme in ["\\1", "\\u"]:
+            elif lexeme in ['\\1', '\\u']:
                 self.script.append((SCRIPT_TAG, lexeme))
                 scope = 1
-            elif lexeme in ["\\s", "\\b", "\\p"]:
+            elif lexeme in ['\\s', '\\b', '\\p']:
                 argument = self.read_sbra_id()
                 self.script.append((SCRIPT_TAG, lexeme, argument))
-            elif lexeme[:2] in ["\\s", "\\b", "\\w"]:
+            elif lexeme.startswith('\\s') or \
+                 lexeme.startswith('\\b') or \
+                 lexeme.startswith('\\w'):
                 num = lexeme[2]
-                if lexeme[:2] == "\\s" and scope == 1:
+                if lexeme.startswith('\\s') and scope == 1:
                     num = str(int(num) + 10)
                 self.script.append((SCRIPT_TAG, lexeme[:2], num))
-            elif lexeme in ["\\_w"]:
+            elif lexeme in ['\\_w']:
                 argument = self.read_sbra_number()
                 self.script.append((SCRIPT_TAG, lexeme, argument))
-            elif lexeme in ["\\i", "\\j", "\\&", "\\_u", "\\_m"]:
+            elif lexeme in ['\\i', '\\j', '\\&', '\\_u', '\\_m']:
                 argument = self.read_sbra_id()
                 self.script.append((SCRIPT_TAG, lexeme, argument))
-            elif lexeme in ["\\_b", "\\_c", "\\_l", "\\_v", "\\m",
-                            "\\3", "\\8", "\\9"]:
+            elif lexeme in ['\\_b', '\\_c', '\\_l', '\\_v', '\\m',
+                            '\\3', '\\8', '\\9']:
                 argument = self.read_sbra_text()
                 self.script.append((SCRIPT_TAG, lexeme, argument))
-            elif lexeme in ["\\n"]:
+            elif lexeme in ['\\n']:
                 if self.tokens and self.tokens[0][0] == TOKEN_OPENED_SBRA:
                     argument = self.read_sbra_text()
                     self.script.append((SCRIPT_TAG, lexeme, argument))
                 else:
                     self.script.append((SCRIPT_TAG, lexeme))
-            elif lexeme in ["\\URL"]:
+            elif lexeme in ['\\URL']:
                 buffer = [self.read_sbra_text()]
                 while self.tokens and self.tokens[0][0] == TOKEN_OPENED_SBRA:
                     buffer.append(self.read_sbra_text())
                     buffer.append(self.read_sbra_text())
                 self.script.append((SCRIPT_TAG, lexeme) + tuple(buffer))
-            elif lexeme in ["\\!"]:
+            elif lexeme in ['\\!']:
                 args = self.split_params(self.read_sbra_text())
                 self.script.append((SCRIPT_TAG, lexeme) + tuple(args))
-            elif lexeme in ["\\q"]:
+            elif lexeme in ['\\q']:
                 if self.tokens and self.tokens[0][0] == TOKEN_OPENED_SBRA:
                     args = self.split_params(self.read_sbra_text())
                     if len(args) != 2:
-                        raise self.perror("wrong number of arguments",
-                                          skip="length")
-                    if len(args[1]) != 1 or len(args[1][0][1]) == 0:
-                        raise self.perror("syntax error (expected an ID)",
-                                          skip="length")
+                        raise self.perror('wrong number of arguments',
+                                          skip='length')
+                    if len(args[1]) != 1 or not args[1][0][1]:
+                        raise self.perror('syntax error (expected an ID)',
+                                          skip='length')
                     arg1 = args[0]
                     arg2 = args[1][0][1]
                     self.script.append((SCRIPT_TAG, lexeme, arg1, arg2))
@@ -239,31 +251,33 @@ class Parser:
                     arg2 = self.read_sbra_id()
                     arg3 = self.read_sbra_text()
                     self.script.append((SCRIPT_TAG, lexeme, arg1, arg2, arg3))
-            elif lexeme in ["\\_s"]:
+            elif lexeme in ['\\_s']:
                 if self.tokens and self.tokens[0][0] == TOKEN_OPENED_SBRA:
-                    args = [arg[0][1] for arg in self.split_params(self.read_sbra_text())]
+                    args = [arg[0][1] for arg in \
+                            self.split_params(self.read_sbra_text())]
                     self.script.append((SCRIPT_TAG, lexeme) + tuple(args))
                 else:
                     self.script.append((SCRIPT_TAG, lexeme))
-            elif lexeme in ["\\_a"]:
+            elif lexeme in ['\\_a']:
                 if anchor is None:
-                    anchor = self.perror(r"syntax error (unbalanced \_a tag)",
-                                         skip="rest")
-                    self.script.append((SCRIPT_TAG, lexeme, self.read_sbra_id()))
+                    anchor = self.perror(r'syntax error (unbalanced \_a tag)',
+                                         skip='rest')
+                    self.script.append(
+                        (SCRIPT_TAG, lexeme, self.read_sbra_id()))
                 else:
                     anchor = None
                     self.script.append((SCRIPT_TAG, lexeme))
             else:
-                raise self.perror("unknown tag (%s)" % lexeme, skip="length")
+                raise self.perror('unknown tag (%s)' % lexeme, skip='length')
         if anchor:
-            if self.script[-1] == (SCRIPT_TAG, r"\e"):
-                self.script.insert(len(self.script) - 1, (SCRIPT_TAG, r"\_a"))
+            if self.script[-1] == (SCRIPT_TAG, r'\e'):
+                self.script.insert(len(self.script) - 1, (SCRIPT_TAG, r'\_a'))
             else:
-                self.script.append((SCRIPT_TAG, r"\_a"))
+                self.script.append((SCRIPT_TAG, r'\_a'))
             anchor.script=self.script
             raise anchor
         if string_chunks:
-            text.append((TEXT_STRING, string.join(string_chunks, '')))
+            text.append((TEXT_STRING, ''.join(string_chunks)))
         if text:
             self.script.append((SCRIPT_TEXT, tuple(text)))
         return self.script
@@ -271,27 +285,28 @@ class Parser:
     def read_number(self):
         token, number = self.next_token()
         if token != TOKEN_NUMBER:
-            raise self.perror("syntax error (expected a number)")
+            raise self.perror('syntax error (expected a number)')
         return number
 
     def read_sbra_number(self):
         token, lexeme = self.next_token()
         if token != TOKEN_OPENED_SBRA:
-            raise self.perror("syntax error (expected a square bracket)")
+            raise self.perror('syntax error (expected a square bracket)')
         token, number = self.next_token()
         if token != TOKEN_NUMBER:
-            raise self.perror("syntax error (expected a number)", skip="length")
+            raise self.perror('syntax error (expected a number)',
+                              skip='length')
         token, lexeme = self.next_token()
         if token != TOKEN_CLOSED_SBRA:
-            raise self.perror("syntax error (expected a square bracket)",
-                              skip="length")
+            raise self.perror('syntax error (expected a square bracket)',
+                              skip='length')
         return number
 
     def read_sbra_id(self):
         text = self.read_sbra_text()
         if len(text) != 1:
-            raise self.perror("syntax error (expected a single ID)",
-                              skip="length")
+            raise self.perror('syntax error (expected a single ID)',
+                              skip='length')
         try:
             id = str(int(text[0][1]))
         except:
@@ -303,34 +318,35 @@ class Parser:
     def read_sbra_text(self):
         token, lexeme = self.next_token()
         if token != TOKEN_OPENED_SBRA:
-            raise self.perror("syntax error (expected a square bracket)")
+            raise self.perror('syntax error (expected a square bracket)')
         text = []
         string_chunks = []
         while self.tokens:
             token, lexeme = self.next_token()
             if token in [TOKEN_NUMBER, TOKEN_STRING, TOKEN_OPENED_SBRA,
                          TOKEN_TAG]:
-                lexeme = lexeme.replace(r"\\", "\\")
-                lexeme = lexeme.replace(r"\%", "%")
-                lexeme = lexeme.replace(r"\]", "]")
+                lexeme = lexeme.replace(r'\\', '\\')
+                lexeme = lexeme.replace(r'\%', '%')
+                lexeme = lexeme.replace(r'\]', ']')
                 string_chunks.append(lexeme)
                 continue
             if string_chunks:
-                text.append((TEXT_STRING, string.join(string_chunks, '')))
+                text.append((TEXT_STRING, ''.join(string_chunks)))
                 string_chunks = []
             if token == TOKEN_CLOSED_SBRA:
                 break
             elif token == TOKEN_META:
                 text.append((TEXT_META, lexeme))
             else:
-                raise self.perror("syntax error (wrong type of argument)",
-                                  skip="length")
+                raise self.perror('syntax error (wrong type of argument)',
+                                  skip='length')
         else:
-            raise self.perror("unexpected end of script", position="eol")
+            raise self.perror('unexpected end of script', position='eol')
         return tuple(text)
 
     re_param = re.compile('("[^"]*"|[^,])*')
     re_quote = re.compile('"([^"]*)"')
+
     def split_params(self, text):
         params = []
         buffer = []
@@ -350,7 +366,7 @@ class Parser:
                     buffer = []
                     i = match.end()
                     if i < j:
-                        assert lexeme[i] == ","
+                        assert lexeme[i] == ','
                         i += 1
             if i < j:
                 buffer.append((token, lexeme[i:]))
@@ -358,63 +374,64 @@ class Parser:
             params.append(tuple(buffer))
         return params
 
+
 # Tests
 
 testcases = [
     # legal cases
-    r"\s[4]ちゃんと選んでよう〜っ。\w8\uまあ、ユーザさんも忙しいんやろ‥‥\e",
-    r"%selfnameと%keroname\e",
-    r"エスケープのテスト \\, \%, [, ], \] どーかな?\e",
-    r"\j[http://www.asahi.com]\e",
-    r"\j[http://www.asahi.com/[escape\]/\%7Etest]\e",
-    r"\j[http://www.asahi.com/%7Etest/]\e",
-    r"\h\s[0]%usernameさんは今どんな感じ?\n\n\q0[#temp0][まあまあ]\q1[#temp1][今ひとつ]\z",
-    r"\q0[#temp0][今日は%month月%day日だよ]\e",
-    r"\q0[#cancel][行かない]\q1[http://www.asahi.com/%7Etest/][行く]\e",
-    r"\q[テスト,test]\q[%month月%day日,date]\e",
-    r"\q[テスト,http://www.asahi.com/]\e",
-    r"\q[テスト,http://www.asahi.com/%7Etest/]\e",
-    r"\h\s[0]%j[#temp0]\e",
-    r"\URL[http://www.asahi.com/]\e",
-    r"\URL[http://www.asahi.com/%7Etest/]\e",
-    r"\URL[行かない][http://www.asahi.com/][トップ][http://www.asahi.com/%7Etest/][テスト]\e",
-    r"\_s\s5\w44えんいー%c\e",
-    r"\h%m?\e",
-    r"\URL[http://www.foo.jp/%7Ebar/]",
-    r"\b[0]\b[normal]\i[0]\i[eyeblink]",
-    r"\c\x\t\_q\*\1\2\4\5\-\+\_+\a\__c\__t\_n",
-    r"\_l[0,0]\_v[test.wav]\_V\_c[test]",
-    r"\h\s0123\u\s0123\h\s1234\u\s1234",
-    r"\s[-1]\b[-1]",
-    r"\_u[0x0010]\_m[0x01]\&[Uuml]\&[uuml]",
-    r"\n\n[half]\n",
-    r"\![open,teachbox]\e",
+    r'\s[4]ちゃんと選んでよう〜っ。\w8\uまあ、ユーザさんも忙しいんやろ‥‥\e',
+    r'%selfnameと%keroname\e',
+    r'エスケープのテスト \\, \%, [, ], \] どーかな?\e',
+    r'\j[http://www.asahi.com]\e',
+    r'\j[http://www.asahi.com/[escape\]/\%7Etest]\e',
+    r'\j[http://www.asahi.com/%7Etest/]\e',
+    r'\h\s[0]%usernameさんは今どんな感じ?\n\n\q0[#temp0][まあまあ]\q1[#temp1][今ひとつ]\z',
+    r'\q0[#temp0][今日は%month月%day日だよ]\e',
+    r'\q0[#cancel][行かない]\q1[http://www.asahi.com/%7Etest/][行く]\e',
+    r'\q[テスト,test]\q[%month月%day日,date]\e',
+    r'\q[テスト,http://www.asahi.com/]\e',
+    r'\q[テスト,http://www.asahi.com/%7Etest/]\e',
+    r'\h\s[0]%j[#temp0]\e',
+    r'\URL[http://www.asahi.com/]\e',
+    r'\URL[http://www.asahi.com/%7Etest/]\e',
+    r'\URL[行かない][http://www.asahi.com/][トップ][http://www.asahi.com/%7Etest/][テスト]\e',
+    r'\_s\s5\w44えんいー%c\e',
+    r'\h%m?\e',
+    r'\URL[http://www.foo.jp/%7Ebar/]',
+    r'\b[0]\b[normal]\i[0]\i[eyeblink]',
+    r'\c\x\t\_q\*\1\2\4\5\-\+\_+\a\__c\__t\_n',
+    r'\_l[0,0]\_v[test.wav]\_V\_c[test]',
+    r'\h\s0123\u\s0123\h\s1234\u\s1234',
+    r'\s[-1]\b[-1]',
+    r'\_u[0x0010]\_m[0x01]\&[Uuml]\&[uuml]',
+    r'\n\n[half]\n',
+    r'\![open,teachbox]\e',
     r'\![raise,OnUserEvent,"0,100"]\e',
     r'\![raise,"On"User"Event",%username,,"",a"","""","foo,bar"]\e',
     r'\_a[http://www.asahi.com/]Asahi.com\_a\_s\_a[test]foo\_a\e',
     r'\_a[test]%j[http://www.asahi.com]%hour時%minute分%second秒\_a',
-    r"\![raise,OnWavePlay,voice\hello.mp3]\e",
-    r"\q[Asahi.com,新聞を読む]",
-    r"\j[\s4]\e",
-    r"\p[2]\s[100]3人目",
-    r"\_s[0,2]keroは\_s仲間はずれ\_sです。\e",
+    r'\![raise,OnWavePlay,voice\hello.mp3]\e',
+    r'\q[Asahi.com,新聞を読む]',
+    r'\j[\s4]\e',
+    r'\p[2]\s[100]3人目',
+    r'\_s[0,2]keroは\_s仲間はずれ\_sです。\e',
     # illegal cases (to be passed)
-    r"20%終了 (%hour時%minute分%second秒)",
-    r"\g",
+    r'20%終了 (%hour時%minute分%second秒)',
+    r'\g',
     # illegal cases
-    r"\j[http://www.asahi",
-    r"\s\e",
-    r"\j4\e",
-    r"\q0[#temp0]\e",
-    r"\q[test]\e",
-    r"\q[foo,bar,test]\e",
-    r"\q[起動時間,%exh時間]\e",
-    r"\q[,]\e",
-    r"\URL[しんぶーん][http://www.asahi.com/]\e",
-    r"\_atest\_a",
-    r"\_a[test]",
-    r"\s[normal]",
-    r"\s[0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]",
+    r'\j[http://www.asahi',
+    r'\s\e',
+    r'\j4\e',
+    r'\q0[#temp0]\e',
+    r'\q[test]\e',
+    r'\q[foo,bar,test]\e',
+    r'\q[起動時間,%exh時間]\e',
+    r'\q[,]\e',
+    r'\URL[しんぶーん][http://www.asahi.com/]\e',
+    r'\_atest\_a',
+    r'\_a[test]',
+    r'\s[normal]',
+    r'\s[0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]',
     ]
 
 def test_tokenizer():
@@ -425,58 +442,59 @@ def test_tokenizer():
         except ParserError, e:
             print e
 
-def test_parser(error="strict"):
+def test_parser(error='strict'):
     parser = Parser(error)
     for test in testcases:
-        print "*" * 60
+        print '*' * 60
         print test
         script = []
         while 1:
             try:
                 script.extend(parser.parse(test))
             except ParserError, e:
-                print "-" * 60
+                print '-' * 60
                 print e
                 done, test = e
                 script.extend(done)
             else:
                 break
-        print "-" * 60
+        print '-' * 60
         print_script_tree(script)
 
 def print_script_tree(tree):
     for node in tree:
         if node[0] == SCRIPT_TAG:
             name, args = node[1], node[2:]
-            print "TAG", name
+            print 'TAG', name
             for n in range(len(args)):
-                if type(args[n]) == type(''):
-                    print "\tARG#%d\t%s" % (n+1, args[n])
+                if isinstance(args[n], str):
+                    print '\tARG#%d\t%s' % (n + 1, args[n])
                 else:
-                    print "\tARG#%d\tTEXT" % (n+1)
+                    print '\tARG#%d\tTEXT' % (n + 1)
                     print_text(args[n], 2)
         elif node[0] == SCRIPT_TEXT:
-            print "TEXT"
+            print 'TEXT'
             print_text(node[1], 1)
 
 def print_text(text, indent):
     for chunk in text:
         if chunk[0] == TEXT_STRING:
-            print "\t" * indent + 'STRING\t"%s"' % chunk[1]
+            print ''.join(('\t' * indent, 'STRING\t"%s"' % chunk[1]))
         elif chunk[0] == TEXT_META:
             name, args = chunk[1], chunk[2:]
-            print "\t" * indent + "META\t" + name
+            print ''.join(('\t' * indent, 'META\t', name))
             for n in range(len(args)):
-                print "\t" * indent + "\tARG#%d\t%s" % (n+1, args[n])
+                print ''.join(('\t' * indent, '\tARG#%d\t%s' % (n + 1, args[n])))
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     import os, sys
-    if len(sys.argv) == 2 and sys.argv[1] == "tokenizer":
+    if len(sys.argv) == 2 and sys.argv[1] == 'tokenizer':
         test_tokenizer()
-    elif len(sys.argv) == 3 and sys.argv[1] == "parser":
+    elif len(sys.argv) == 3 and sys.argv[1] == 'parser':
         test_parser(sys.argv[2])
     else:
-        print "Usage:", os.path.basename(sys.argv[0]), "[tokenizer|parser [strict|loose]]"
+        print 'Usage:', os.path.basename(sys.argv[0]), \
+              '[tokenizer|parser [strict|loose]]'
 
 # Syntax of the Sakura Script:
 #   "\e"
index 8d99077..a4ff543 100644 (file)
@@ -11,7 +11,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: seriko.py,v 1.15 2005/01/25 05:16:25 shy Exp $
+# $Id: seriko.py,v 1.16 2005/08/09 00:41:52 shy Exp $
 #
 
 import re
@@ -19,7 +19,8 @@ import sys
 import random
 
 def print_error(message):
-    sys.stderr.write(message + "\n")
+    sys.stderr.write(''.join((message, '\n')))
+
 
 class Actor:
 
@@ -55,21 +56,21 @@ class Actor:
         pass
 
     def show_pattern(self, window, surface, method, args):
-        if self.last_method in ["overlay", "overlayfast"]:
+        if self.last_method in ['overlay', 'overlayfast']:
             window.remove_overlay(self)
-        if method == "move":
+        if method == 'move':
             window.move_surface(args[0], args[1])
-        elif method in ["overlay", "overlayfast"]:
+        elif method in ['overlay', 'overlayfast']:
             window.add_overlay(self, surface, args[0], args[1])
-        elif method == "base":
+        elif method == 'base':
             window.surface_id = self.surface_id # This is kluge.
             window.set_surface(surface, restart=0)
-        elif method == "start":
+        elif method == 'start':
             window.invoke(args[0], update=1)
-        elif method == "alternativestart":
+        elif method == 'alternativestart':
             window.invoke(random.choice(args), update=1)
         else:
-            raise RuntimeError, "should not reach here"
+            raise RuntimeError, 'should not reach here'
         self.last_method = method
 
 class ActiveActor(Actor): # always
@@ -197,13 +198,14 @@ class Mayuna(Actor):
     def show_pattern(self, window, surface, method, args):
         pass
 
-re_seriko_interval = re.compile("^([0-9]+)interval$")
-re_seriko_interval_value = re.compile("^(sometimes|rarely|random,[0-9]+|always|runonce|yesn-e|talk,[0-9]+|never)$")
-re_seriko_pattern = re.compile(r"^([0-9]+|-[12])\s*,\s*([+-]?[0-9]+)\s*,\s*(overlay|overlayfast|base|move|start|alternativestart|)\s*,?\s*([+-]?[0-9]+)?\s*,?\s*([+-]?[0-9]+)?\s*,?\s*(\[[0-9]+(\.[0-9]+)*\])?$")
 
-re_seriko2_interval = re.compile("^animation([0-9]+)\.interval$")
-re_seriko2_interval_value = re.compile("^(sometimes|rarely|random,[0-9]+|always|runonce|yesn-e|talk,[0-9]+|never)$")
-re_seriko2_pattern = re.compile(r"^(overlay|overlayfast|base|move|start|alternativestart|)\s*,\s*([0-9]+|-[12])\s*,\s*([+-]?[0-9]+)\s*,?\s*([+-]?[0-9]+)?\s*,?\s*([+-]?[0-9]+)?\s*,?\s*(\([0-9]+(\.[0-9]+)*\))?$")
+re_seriko_interval = re.compile('^([0-9]+)interval$')
+re_seriko_interval_value = re.compile('^(sometimes|rarely|random,[0-9]+|always|runonce|yesn-e|talk,[0-9]+|never)$')
+re_seriko_pattern = re.compile(r'^([0-9]+|-[12])\s*,\s*([+-]?[0-9]+)\s*,\s*(overlay|overlayfast|base|move|start|alternativestart|)\s*,?\s*([+-]?[0-9]+)?\s*,?\s*([+-]?[0-9]+)?\s*,?\s*(\[[0-9]+(\.[0-9]+)*\])?$')
+
+re_seriko2_interval = re.compile('^animation([0-9]+)\.interval$')
+re_seriko2_interval_value = re.compile('^(sometimes|rarely|random,[0-9]+|always|runonce|yesn-e|talk,[0-9]+|never)$')
+re_seriko2_pattern = re.compile(r'^(overlay|overlayfast|base|move|start|alternativestart|)\s*,\s*([0-9]+|-[12])\s*,\s*([+-]?[0-9]+)\s*,?\s*([+-]?[0-9]+)?\s*,?\s*([+-]?[0-9]+)?\s*,?\s*(\([0-9]+(\.[0-9]+)*\))?$')
 
 def get_actors(config):
     version = None
@@ -233,36 +235,36 @@ def get_actors(config):
         buffer.append((int(match.group(1)), value))
     actors = []
     for id, interval in buffer:
-        if interval == "always":
+        if interval == 'always':
             actor = ActiveActor(id, interval)
-        elif interval == "sometimes":
+        elif interval == 'sometimes':
             actor = RandomActor(id, interval, 0, 1000) # 0 to 10 seconds
-        elif interval == "rarely":
+        elif interval == 'rarely':
             actor = RandomActor(id, interval, 2000, 6000)
-        elif interval[:6] == "random":
+        elif interval.startswith('random'):
             actor = RandomActor(id, interval, 0, 100 * int(interval[7]))
-        elif interval == "runonce":
+        elif interval == 'runonce':
             actor = OneTimeActor(id, interval)
-        elif interval == "yen-e":
+        elif interval == 'yen-e':
             actor = PassiveActor(id, interval)
-        elif interval[:4] == "talk":
+        elif interval.startswith('talk'):
             actor = PassiveActor(id, interval)
-        elif interval == "never":
+        elif interval == 'never':
             actor = PassiveActor(id, interval)
         if version == 1:
-            key = str(id) + 'option'
+            key = ''.join((str(id), 'option'))
         else:
-            key = 'animation' + str(id) + '.option'
+            key = ''.join(('animation', str(id), '.option'))
         if config.has_key(key) and config[key] == 'exclusive':
             actor.set_exclusive()
         try:
             for n in range(128): # up to 128 patterns (0 - 127)
                 if version == 1:
-                    key = str(id) + "pattern" + str(n)
+                    key = ''.join((str(id), 'pattern', str(n)))
                 else:
-                    key = 'animation' + str(id) + ".pattern" + str(n)
+                    key = ''.join(('animation', str(id), '.pattern', str(n)))
                 if not config.has_key(key):
-                    key = str(id) + "patturn" + str(n) # only for version 1
+                    key = ''.join((str(id), 'patturn', str(n))) # only for version 1
                     if not config.has_key(key):
                         break
                 pattern = config[key]
@@ -271,7 +273,7 @@ def get_actors(config):
                 else:
                     match = re_seriko2_pattern.match(pattern)
                 if not match:
-                    raise ValueError, "unsupported pattern: %s" % pattern
+                    raise ValueError, 'unsupported pattern: %s' % pattern
                 if version == 1:
                     surface = str(int(match.group(1)))
                     interval = abs(int(match.group(2)))
@@ -280,20 +282,20 @@ def get_actors(config):
                     method = match.group(1)
                     surface = str(int(match.group(2)))
                     interval = abs(int(match.group(3))) / 10 ## FIXME
-                if method == "":
-                    method = "base"
-                if method == "start":
+                if method == '':
+                    method = 'base'
+                if method == 'start':
                     group = match.group(4)
                     if group is None:
-                        raise ValueError, "syntax error: %s" % pattern
+                        raise ValueError, 'syntax error: %s' % pattern
                     args = [int(group)]
-                elif method == "alternativestart":
+                elif method == 'alternativestart':
                     list = match.group(6)
                     if list is None:
-                        raise ValueError, "syntax error: %s" % pattern
-                    args = [int(s) for s in list[1:-1].split(".")]
+                        raise ValueError, 'syntax error: %s' % pattern
+                    args = [int(s) for s in list[1:-1].split('.')]
                 else:
-                    if surface in ["-1", "-2"]:
+                    if surface in ['-1', '-2']:
                         x = 0
                         y = 0
                     else:
@@ -302,22 +304,23 @@ def get_actors(config):
                     args = [x, y]
                 actor.add_pattern(surface, interval, method, args)
         except ValueError, error:
-            print_error("seriko.py: " + str(error))
+            print_error(''.join(('seriko.py: ', str(error))))
             continue
         if not actor.get_patterns():
-            print_error("seriko.py: animation group #%d has no pattern (ignored)" % id)
+            print_error(
+                'seriko.py: animation group #%d has no pattern (ignored)' % id)
             continue
         actors.append(actor)
     actors.sort(lambda a1, a2: cmp(a1.get_id(), a2.get_id()))
     return actors
 
-re_mayuna_interval = re.compile("^([0-9]+)interval$")
-re_mayuna_interval_value = re.compile("^(bind)$")
-re_mayuna_pattern = re.compile(r"^([0-9]+|-[12])\s*,\s*([0-9]+)\s*,\s*(bind|add|reduce|insert)\s*,?\s*([+-]?[0-9]+)?\s*,?\s*([+-]?[0-9]+)?\s*,?\s*(\[[0-9]+(\.[0-9]+)*\])?$")
+re_mayuna_interval = re.compile('^([0-9]+)interval$')
+re_mayuna_interval_value = re.compile('^(bind)$')
+re_mayuna_pattern = re.compile(r'^([0-9]+|-[12])\s*,\s*([0-9]+)\s*,\s*(bind|add|reduce|insert)\s*,?\s*([+-]?[0-9]+)?\s*,?\s*([+-]?[0-9]+)?\s*,?\s*(\[[0-9]+(\.[0-9]+)*\])?$')
 
-re_mayuna2_interval = re.compile("^animation([0-9]+)\.interval$")
-re_mayuna2_interval_value = re.compile("^(bind)$")
-re_mayuna2_pattern = re.compile(r"^(bind|add|reduce|insert)\s*,\s*([0-9]+|-[12])\s*,\s*([0-9]+)\s*,?\s*([+-]?[0-9]+)?\s*,?\s*([+-]?[0-9]+)?\s*,?\s*(\([0-9]+(\.[0-9]+)*\))?$")
+re_mayuna2_interval = re.compile('^animation([0-9]+)\.interval$')
+re_mayuna2_interval_value = re.compile('^(bind)$')
+re_mayuna2_pattern = re.compile(r'^(bind|add|reduce|insert)\s*,\s*([0-9]+|-[12])\s*,\s*([0-9]+)\s*,?\s*([+-]?[0-9]+)?\s*,?\s*([+-]?[0-9]+)?\s*,?\s*(\([0-9]+(\.[0-9]+)*\))?$')
 
 def get_mayuna(config):
     version = None
@@ -347,16 +350,16 @@ def get_mayuna(config):
         buffer.append((int(match.group(1)), value))
     mayuna = []
     for id, interval in buffer:
-        ##assert interval == "bind"
+        ##assert interval == 'bind'
         actor = Mayuna(id, interval)
         try:
             for n in range(128): # up to 128 patterns (0 - 127)
                 if version == 1:
-                    key = str(id) + "pattern" + str(n)
+                    key = ''.join((str(id), 'pattern', str(n)))
                 else:
-                    key = 'animation' + str(id) + ".pattern" + str(n)
+                    key = ''.join(('animation', str(id), '.pattern', str(n)))
                 if not config.has_key(key):
-                    key = str(id) + "patturn" + str(n) # only for version 1
+                    key = ''.join((str(id), 'patturn', str(n))) # only for version 1
                     if not config.has_key(key):
                         break
                 pattern = config[key]
@@ -365,7 +368,7 @@ def get_mayuna(config):
                 else:
                     match = re_mayuna2_pattern.match(pattern)
                 if not match:
-                    raise ValueError, "unsupported pattern: %s" % pattern
+                    raise ValueError, 'unsupported pattern: %s' % pattern
                 if version == 1:
                     surface = str(int(match.group(1)))
                     interval = abs(int(match.group(2)))
@@ -374,10 +377,10 @@ def get_mayuna(config):
                     method = match.group(1)
                     surface = str(int(match.group(2)))
                     interval = abs(int(match.group(3))) / 10 ## FIXME
-                if method not in ["bind", "add", "reduce", "insert"]:
+                if method not in ['bind', 'add', 'reduce', 'insert']:
                     continue
                 else:
-                    if surface in ["-1", "-2"]:
+                    if surface in ['-1', '-2']:
                         x = 0
                         y = 0
                     else:
@@ -386,10 +389,11 @@ def get_mayuna(config):
                     args = [x, y]
                 actor.add_pattern(surface, interval, method, args)
         except ValueError, error:
-            print_error("seriko.py: " + str(error))
+            print_error(''.join(('seriko.py: ', str(error))))
             continue
         if not actor.get_patterns():
-            print_error("seriko.py: animation group #%d has no pattern (ignored)" % id)
+            print_error(
+                'seriko.py: animation group #%d has no pattern (ignored)' % id)
             continue
         mayuna.append(actor)
     mayuna.sort(lambda a1, a2: cmp(a1.get_id(), a2.get_id()))
@@ -400,23 +404,23 @@ def test():
     import sys
     import ninix.config
     if len(sys.argv) == 1:
-        print "Usage:", sys.argv[0], "[surface??a.txt ...]"
+        print 'Usage:', sys.argv[0], '[surface??a.txt ...]'
     for file in sys.argv[1:]:
-        print "Reading", file, "..."
+        print 'Reading', file, '...'
         for actor in get_actors(ninix.config.open(file)):
-            print "#%d" % actor.get_id(),
+            print '#%d' % actor.get_id(),
             print actor.__class__.__name__,
-            print "(%s)" % actor.get_interval()
-            print "number of patterns =", len(actor.get_patterns())
+            print '(%s)' % actor.get_interval()
+            print 'number of patterns =', len(actor.get_patterns())
             for pattern in actor.get_patterns():
-                print "surface=%s, interval=%d, method=%s, args=%s" % pattern
+                print 'surface=%s, interval=%d, method=%s, args=%s' % pattern
         for actor in get_mayuna(ninix.config.open(file)):
-            print "#%d" % actor.get_id(),
+            print '#%d' % actor.get_id(),
             print actor.__class__.__name__,
-            print "(%s)" % actor.get_interval()
-            print "number of patterns =", len(actor.get_patterns())
+            print '(%s)' % actor.get_interval()
+            print 'number of patterns =', len(actor.get_patterns())
             for pattern in actor.get_patterns():
-                print "surface=%s, interval=%d, method=%s, args=%s" % pattern
+                print 'surface=%s, interval=%d, method=%s, args=%s' % pattern
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     test()
index f43df55..2e83be6 100644 (file)
@@ -11,7 +11,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: sstp.py,v 1.16 2005/03/22 06:08:49 shy Exp $
+# $Id: sstp.py,v 1.17 2005/08/09 00:41:52 shy Exp $
 #
 
 import codecs
@@ -22,6 +22,7 @@ import ninix.version
 
 from sstplib import AsynchronousSSTPServer, BaseSSTPRequestHandler
 
+
 class SSTPServer(AsynchronousSSTPServer):
 
     def __init__(self, address, app):
@@ -41,7 +42,8 @@ class SSTPServer(AsynchronousSSTPServer):
 
     def send_answer(self, value):
         self.send_response(200, # OK
-                           value.encode('utf-8', 'ignore') + "\r\nCharset: UTF-8\r\n")
+                           ''.join((value.encode('utf-8', 'ignore'),
+                                    '\r\nCharset: UTF-8\r\n')))
 
     def send_no_content(self):
         self.send_response(204) # No Content
@@ -67,8 +69,12 @@ class SSTPServer(AsynchronousSSTPServer):
     def check_request_queue(self, sender):
         return self.__app.check_request_queue(sender)
 
-    def enqueue_script_if_ghost(self, if_ghost, script, sender, handle, address, show_sstp_marker, use_translator, entry_db):
-        self.__app.enqueue_script_if_ghost(if_ghost, script, sender, handle, address, show_sstp_marker, use_translator, entry_db)
+    def enqueue_script_if_ghost(
+        self, if_ghost, script, sender, handle,
+        address, show_sstp_marker, use_translator, entry_db):
+        self.__app.enqueue_script_if_ghost(
+            if_ghost, script, sender, handle,
+            address, show_sstp_marker, use_translator, entry_db)
 
 class SSTPRequestHandler(BaseSSTPRequestHandler):
 
@@ -127,7 +133,8 @@ class SSTPRequestHandler(BaseSSTPRequestHandler):
             if entry_db is None:
                 return
         if version == 1.4:
-            self.enqueue_script_if_ghost(if_ghost, sender, handle, script, entry_db)
+            self.enqueue_script_if_ghost(
+                if_ghost, sender, handle, script, entry_db)
         else:
             self.enqueue_script(sender, handle, script, entry_db)
 
@@ -166,7 +173,8 @@ class SSTPRequestHandler(BaseSSTPRequestHandler):
             return
         self.enqueue_script(sender, None, script, entry_db)
 
-    def enqueue_script_if_ghost(self, if_ghost, sender, handle, script, entry_db):
+    def enqueue_script_if_ghost(self, if_ghost, sender, handle,
+                                script, entry_db):
         try:
             address = self.client_address[0]
         except:
@@ -200,7 +208,7 @@ class SSTPRequestHandler(BaseSSTPRequestHandler):
                 entry_db, self.server)
             self.server.request_handler = self # keep alive
 
-    PROHIBITED_TAGS = [r"\j", r"\-", r"\+", r"\_+", r"\!"]
+    PROHIBITED_TAGS = [r'\j', r'\-', r'\+', r'\_+', r'\!']
 
     def check_script(self, script):
         if not self.local_request():
@@ -218,31 +226,31 @@ class SSTPRequestHandler(BaseSSTPRequestHandler):
                 if node[0] == ninix.script.SCRIPT_TAG and \
                    node[1] in self.PROHIBITED_TAGS:
                     self.send_response(400) # Bad Request
-                    self.log_error("Script: tag %s not allowed" % node[1])
+                    self.log_error('Script: tag %s not allowed' % node[1])
                     return 1
         return 0
 
     def get_script(self):
-        charset = self.headers.get("charset", "Shift_JIS")
-        script = self.headers.get("script", None)
+        charset = self.headers.get('charset', 'Shift_JIS')
+        script = self.headers.get('script', None)
         if script is None:
             self.send_response(400) # Bad Request
-            self.log_error("Script: header field not found")
+            self.log_error('Script: header field not found')
             return None
-        return unicode(script, charset, "replace")
+        return unicode(script, charset, 'replace')
 
     def get_script_if_ghost(self, current=0):
-        charset = self.headers.get("charset", "Shift_JIS")
+        charset = self.headers.get('charset', 'Shift_JIS')
         default = None
         i, j = 0, len(self.headers.headers)
         while i < j:
-            line = unicode(self.headers.headers[i], charset, "replace")
+            line = unicode(self.headers.headers[i], charset, 'replace')
             i += 1
-            if line[:8].lower() == "ifghost:" and i < j:
+            if line.lower().startswith('ifghost:') and i < j:
                 if_ghost = line[8:].strip()
-                line = unicode(self.headers.headers[i], charset, "replace")
+                line = unicode(self.headers.headers[i], charset, 'replace')
                 i += 1
-                if line[:7].lower() != "script:":
+                if not line.lower().startswith('script:'):
                     continue
                 script = line[7:].strip()
                 if current: # NOTIFY
@@ -259,11 +267,11 @@ class SSTPRequestHandler(BaseSSTPRequestHandler):
         return default
 
     def get_entry_db(self):
-        charset = self.headers.get("charset", "Shift_JIS")
+        charset = self.headers.get('charset', 'Shift_JIS')
         entry_db = ninix.entry_db.EntryDatabase()
-        for line in self.headers.getallmatchingheaders("entry"):
-            value = unicode(line[6:], charset, "replace")
-            entry = value.split(",", 1)
+        for line in self.headers.getallmatchingheaders('entry'):
+            value = unicode(line[6:], charset, 'replace')
+            entry = value.split(',', 1)
             if len(entry) != 2:
                 self.send_response(400) # Bad Request
                 return None
@@ -271,61 +279,61 @@ class SSTPRequestHandler(BaseSSTPRequestHandler):
         return entry_db
 
     def get_event(self):
-        charset = self.headers.get("charset", "Shift_JIS")
-        event = self.headers.get("event", None)
+        charset = self.headers.get('charset', 'Shift_JIS')
+        event = self.headers.get('event', None)
         if event is None:
             self.send_response(400) # Bad Request
-            self.log_error("Event: header field not found")
+            self.log_error('Event: header field not found')
             return None
-        buffer = [unicode(event, charset, "replace")]
+        buffer = [unicode(event, charset, 'replace')]
         for i in range(8):
-            value = self.headers.get("reference" + str(i), None)
+            value = self.headers.get(''.join(('reference', str(i))), None)
             if value is not None:
-                value = unicode(value, charset, "replace")
+                value = unicode(value, charset, 'replace')
             buffer.append(value)
         return tuple(buffer)
 
     def get_sender(self):
-        charset = self.headers.get("charset", "Shift_JIS")
-        sender = self.headers.get("sender", None)
+        charset = self.headers.get('charset', 'Shift_JIS')
+        sender = self.headers.get('sender', None)
         if sender is None:
             self.send_response(400) # Bad Request
-            self.log_error("Sender: header field not found")
+            self.log_error('Sender: header field not found')
             return None
-        return unicode(sender, charset, "replace")
+        return unicode(sender, charset, 'replace')
 
     def get_handle(self):
-        path = self.headers.get("hwnd", None)
+        path = self.headers.get('hwnd', None)
         if path is None:
             self.send_response(400) # Bad Request
-            self.log_error("HWnd: header field not found")
+            self.log_error('HWnd: header field not found')
             return None
         sakura = self.server.get_current_sakura()
         handle = sakura.open_sstp_handle(path)
         if handle is None:
             self.send_response(400) # Bad Request
-            self.log_error("Invalid HWnd: header field")
+            self.log_error('Invalid HWnd: header field')
             return None
         return handle
 
     def check_decoder(self):
-        charset = self.headers.get("charset", "Shift_JIS")
+        charset = self.headers.get('charset', 'Shift_JIS')
         try:
             codecs.lookup(charset)
         except:
-            self.send_response(420, "Refuse (unsupported charset)")
-            self.log_error("Unsupported charset %s" % repr(charset))
+            self.send_response(420, 'Refuse (unsupported charset)')
+            self.log_error('Unsupported charset %s' % repr(charset))
         else:
             return 1
         return 0
 
     def get_options(self):
         show_sstp_marker = use_translator = 1
-        for option in self.headers.get("option", "").split(","):
+        for option in self.headers.get('option', '').split(','):
             option = option.strip()
-            if option == "nodescript" and self.local_request():
+            if option == 'nodescript' and self.local_request():
                 show_sstp_marker = 0
-            elif option == "notranslate":
+            elif option == 'notranslate':
                 use_translator = 0
         return show_sstp_marker, use_translator
 
@@ -336,12 +344,12 @@ class SSTPRequestHandler(BaseSSTPRequestHandler):
             result = 1
         except:
             host, port = self.client_address
-            result = host ==  "127.0.0.1"
+            result = host ==  '127.0.0.1'
         return result
 
     def ghost_names(self):
         sakura = self.server.get_current_sakura()
-        return "%s,%s" % (sakura.get_selfname(),
+        return '%s,%s' % (sakura.get_selfname(),
                           sakura.get_keroname())
 
     # EXECUTE
@@ -355,7 +363,7 @@ class SSTPRequestHandler(BaseSSTPRequestHandler):
         if not self.local_request():
             host, port = self.client_address
             self.send_response(420)
-            self.log_error("Unauthorized EXECUTE/1.3 request from %s" % host)
+            self.log_error('Unauthorized EXECUTE/1.3 request from %s' % host)
             return
         self.handle_command()
 
@@ -363,7 +371,7 @@ class SSTPRequestHandler(BaseSSTPRequestHandler):
         if not self.local_request():
             host, port = self.client_address
             self.send_response(420)
-            self.log_error("Unauthorized EXECUTE/1.5 request from %s" % host)
+            self.log_error('Unauthorized EXECUTE/1.5 request from %s' % host)
             return
         self.handle_command()
 
@@ -376,48 +384,49 @@ class SSTPRequestHandler(BaseSSTPRequestHandler):
         command = self.get_command()
         if command is None:
             return
-        elif command == "getname":
+        elif command == 'getname':
             self.send_response(200)
             name = self.ghost_names()
-            self.wfile.write(name.encode('utf-8', 'ignore') + '\r\n')
+            self.wfile.write(''.join((name.encode('utf-8', 'ignore'), '\r\n')))
             self.wfile.write('Charset: UTF-8\r\n')
-        elif command == "getversion":
+        elif command == 'getversion':
             self.send_response(200)
-            self.wfile.write("ninix-aya %s\r\n" % ninix.version.VERSION)
-        elif command == "quiet":
+            self.wfile.write('ninix-aya %s\r\n' % ninix.version.VERSION)
+        elif command == 'quiet':
             self.send_response(200)
             sakura = self.server.get_current_sakura()
             sakura.keep_silence(1)
-        elif command == "restore":
+        elif command == 'restore':
             self.send_response(200)
             sakura = self.server.get_current_sakura()
             sakura.keep_silence(0)
-        elif command == "reload":
+        elif command == 'reload':
             self.send_response(200)
             sakura = self.server.get_current_sakura()
             sakura.reload()
-        elif command == "getnames":
+        elif command == 'getnames':
             self.send_response(200)
             for name in self.server.get_ghost_names():
-                self.wfile.write(name.encode('utf-8', 'ignore') + '\r\n')
+                self.wfile.write(
+                    ''.join((name.encode('utf-8', 'ignore'), '\r\n')))
             self.wfile.write('Charset: UTF-8\r\n')
-        elif command == "checkqueue":
+        elif command == 'checkqueue':
             self.send_response(200)
             count, total = self.server.check_request_queue(sender)
-            self.wfile.write(count + '\r\n')
-            self.wfile.write(total + '\r\n')
+            self.wfile.write(''.join((count, '\r\n')))
+            self.wfile.write(''.join((total, '\r\n')))
         else:
             self.send_response(501) # Not Implemented
-            self.log_error("Not Implemented (%s)" % command)
+            self.log_error('Not Implemented (%s)' % command)
 
     def get_command(self):
-        charset = self.headers.get("charset", "Shift_JIS")
-        command = self.headers.get("command", None)
+        charset = self.headers.get('charset', 'Shift_JIS')
+        command = self.headers.get('command', None)
         if command is None:
             self.send_response(400) # Bad Request
-            self.log_error("Command: header field not found")
+            self.log_error('Command: header field not found')
             return None
-        return unicode(command, charset, "replace").lower()
+        return unicode(command, charset, 'replace').lower()
 
     def do_COMMUNICATE_1_1(self): ## FIXME
         if not self.check_decoder():
@@ -430,14 +439,14 @@ class SSTPRequestHandler(BaseSSTPRequestHandler):
             return
         self.send_response(200) # OK
         sakura = self.server.get_current_sakura()
-        sakura.enqueue_event("OnCommunicate", sender, sentence)
+        sakura.enqueue_event('OnCommunicate', sender, sentence)
         return
 
     def get_sentence(self):
-        charset = self.headers.get("charset", "Shift_JIS")
-        sentence = self.headers.get("sentence", None)
+        charset = self.headers.get('charset', 'Shift_JIS')
+        sentence = self.headers.get('sentence', None)
         if sentence is None:
             self.send_response(400) # Bad Request
-            self.log_error("Sentence: header field not found")
+            self.log_error('Sentence: header field not found')
             return None
-        return unicode(sentence, charset, "replace")
+        return unicode(sentence, charset, 'replace')
index d21a78e..ff5e348 100644 (file)
@@ -18,9 +18,8 @@ import re
 import sys
 import urlparse
 import random
-import types
 
-if os.environ.has_key("DISPLAY"):
+if os.environ.has_key('DISPLAY'):
     import gtk
 
 import ninix.seriko
@@ -28,20 +27,22 @@ import ninix.menu
 
 import pix
 
-range_scale = [(" 100%",  100),
-               ("  90%",   90),
-               ("  80%",   80),
-               ("  70%",   70),
-               ("  60%",   60),
-               ("  50%",   50),
-               ("  40%",   40),
-               (" 200%",  200),
-               (" 300%",  300),
-               ("1000%", 1000)]
+range_scale = [(' 100%',  100),
+               ('  90%',   90),
+               ('  80%',   80),
+               ('  70%',   70),
+               ('  60%',   60),
+               ('  50%',   50),
+               ('  40%',   40),
+               (' 200%',  200),
+               (' 300%',  300),
+               ('1000%', 1000)]
+
 
 class Surface:
+
     # keyval/name mapping
-    if os.environ.has_key("DISPLAY"):
+    if os.environ.has_key('DISPLAY'):
         from ninix.keymap import keymap_old, keymap_new
     else:
         keymap_old = {}
@@ -106,9 +107,9 @@ class Surface:
         window.set_title(title)
         window.set_decorated(False)
         window.set_resizable(False)
-        window.connect("delete_event", self.delete)
-        window.connect("key_press_event", self.key_press)
-        window.connect("window_state_event", self.window_state)
+        window.connect('delete_event', self.delete)
+        window.connect('key_press_event', self.key_press)
+        window.connect('window_state_event', self.window_state)
         window.set_events(gtk.gdk.KEY_PRESS_MASK)
         window.realize()
         return window
@@ -121,7 +122,8 @@ class Surface:
     def window_iconify(self, flag):
         gtk_window = self.window[0].window
         if flag:
-            if not gtk_window.window.get_state() & gtk.gdk.WINDOW_STATE_ICONIFIED:
+            if not gtk_window.window.get_state() & \
+               gtk.gdk.WINDOW_STATE_ICONIFIED:
                 gtk_window.iconify()
         else:
             if gtk_window.window.get_state() & gtk.gdk.WINDOW_STATE_ICONIFIED:
@@ -135,12 +137,16 @@ class Surface:
                 self.sakura.ghost.notify_iconified() ## FIXME
             for surface_window in self.window:
                 gtk_window = surface_window.window
-                if gtk_window != window and not gtk_window.window.get_state() & gtk.gdk.WINDOW_STATE_ICONIFIED:
+                if gtk_window != window and \
+                   not gtk_window.window.get_state() & \
+                   gtk.gdk.WINDOW_STATE_ICONIFIED:
                     gtk_window.iconify()
         else:
             for surface_window in self.window:
                 gtk_window = surface_window.window
-                if gtk_window != window and gtk_window.window.get_state() & gtk.gdk.WINDOW_STATE_ICONIFIED:
+                if gtk_window != window and \
+                   gtk_window.window.get_state() & \
+                   gtk.gdk.WINDOW_STATE_ICONIFIED:
                     gtk_window.deiconify()
             if window == self.window[0].window:
                 self.sakura.ghost.notify_deiconified() ## FIXME
@@ -154,7 +160,7 @@ class Surface:
         name = self.keymap_old.get(event.keyval, event.string)
         keycode = self.keymap_new.get(event.keyval, event.string)
         if name or keycode:
-            self.sakura.notify_event("OnKeyPress", name, keycode)
+            self.sakura.notify_event('OnKeyPress', name, keycode)
         return True
 
     def window_stick(self, action):
@@ -168,7 +174,7 @@ class Surface:
     def open_popup_menu(self, button, side):
         self.__menu.popup(button, side)
 
-    re_surface_id = re.compile("^surface([0-9]+)$")
+    re_surface_id = re.compile('^surface([0-9]+)$')
 
     def new(self, desc, alias, surface, name, prefix):
         self.desc = desc
@@ -177,8 +183,8 @@ class Surface:
         if alias is None:
             alias0 = alias1 = None
         else:
-            alias0 = alias.get("sakura.surface.alias")
-            alias1 = alias.get("kero.surface.alias")
+            alias0 = alias.get('sakura.surface.alias')
+            alias1 = alias.get('kero.surface.alias')
         # load pixmap
         pixbufs = {}
         elements = {}
@@ -188,9 +194,9 @@ class Surface:
                 continue
             if not os.path.exists(path):
                 name, suffix = os.path.splitext(path)
-                dgp_path = name + '.dgp'
+                dgp_path = ''.join((name, '.dgp'))
                 if not os.path.exists(dgp_path):
-                    print "%s: file not found (ignored)" % path
+                    print '%s: file not found (ignored)' % path
                     continue
                 else:
                     path = dgp_path
@@ -208,15 +214,15 @@ class Surface:
                 continue
             key = match.group(1)
             path, config = surface[basename]
-            if config.has_key("element0"):
+            if config.has_key('element0'):
                 if self.debug & 8192:
-                    print "surface", key
+                    print 'surface', key
                 composite_pixbuf[key] = self.compose_elements(elements, config)
         pixbufs.update(composite_pixbuf)
         # check if necessary surfaces have been loaded
-        for key in ["0", "10"]:
+        for key in ['0', '10']:
             if not pixbufs.has_key(key):
-                sys.stderr.write("cannot load surface #%s (abort)\n" % key)
+                sys.stderr.write('cannot load surface #%s (abort)\n' % key)
                 sys.exit(1)
         self.__pixbufs = pixbufs
         # arrange surface configurations
@@ -233,10 +239,11 @@ class Surface:
             # define collision areas
             buffer = []
             for n in range(256):
-                rect = config.get("collision" + str(n)) # "redo" syntax
+                # "redo" syntax
+                rect = config.get(''.join(('collision', str(n))))
                 if rect is None:
                     continue
-                values = rect.split(",")
+                values = rect.split(',')
                 if len(values) != 5:
                     continue
                 try:
@@ -244,12 +251,13 @@ class Surface:
                 except ValueError:
                     continue
                 buffer.append((values[4].strip(), x1, y1, x2, y2))
-            for part in ["head", "face", "bust"]:
-                rect = config.get("collision." + part) # "inverse" syntax
+            for part in ['head', 'face', 'bust']:
+                # "inverse" syntax
+                rect = config.get(''.join(('collision.', part)))
                 if not rect:
                     continue
                 try:
-                    x1, y1, x2, y2 = [int(value) for value in rect.split(",")]
+                    x1, y1, x2, y2 = [int(value) for value in rect.split(',')]
                 except ValueError:
                     pass
                 buffer.append((part.capitalize(), x1, y1, x2, y2))
@@ -267,15 +275,17 @@ class Surface:
             # define animation patterns
             mayuna[key] = ninix.seriko.get_mayuna(config)
         bind = {}
-        for side in ["sakura", "kero"]:
+        for side in ['sakura', 'kero']:
             bind[side] = {}
             for index in range(128):
-                name = self.desc.get('%s.bindgroup%d.name' % (side, index), None)
-                default = self.desc.get('%s.bindgroup%d.default' % (side, index), 0)
+                name = self.desc.get(
+                    '%s.bindgroup%d.name' % (side, index), None)
+                default = self.desc.get(
+                    '%s.bindgroup%d.default' % (side, index), 0)
                 if name is not None:
                     bind[side][index] = [name, default]
         self.mayuna = {}
-        for side in ["sakura", "kero"]:
+        for side in ['sakura', 'kero']:
             self.mayuna[side] = []
             for index in range(128):
                 key = self.desc.get('%s.menuitem%d' % (side, index), None)
@@ -289,16 +299,20 @@ class Surface:
                     else:
                         if bind[side].has_key(key):
                             name = bind[side][key][0].split(',')
-                            self.mayuna[side].append([key, name[1], bind[side][key][1]])
+                            self.mayuna[side].append([key, name[1],
+                                                      bind[side][key][1]])
         # create surface windows
         for surface_window in self.window:
             surface_window.destroy()
         self.window = []
-        for name, side, default, alias in [('sakura', 0, "0", alias0), ('kero', 1, "10", alias1)]:
-            if name == "sakura":
-                title = self.sakura.get_selfname() or 'surface.' + name
+        for name, side, default, alias in [('sakura', 0, '0', alias0),
+                                           ('kero', 1, '10', alias1)]:
+            if name == 'sakura':
+                title = self.sakura.get_selfname() or \
+                        ''.join(('surface.', name))
             else:
-                title = self.sakura.get_keroname() or 'surface.' + name
+                title = self.sakura.get_keroname() or \
+                        ''.join(('surface.', name))
             gtk_window = self.create_gtk_window(title)
             surface_window = SurfaceWindow(
                 gtk_window, side, self.sakura, desc, alias, surface,
@@ -308,24 +322,27 @@ class Surface:
         self.__surface = surface
         self.__menu = ninix.menu.Menu(self.sakura.ghost, self) ## FIXME
         dir = self.prefix
-        name = self.desc.get("menu.background.bitmap.filename", "menu_background.png")
+        name = self.desc.get('menu.background.bitmap.filename',
+                             'menu_background.png')
         name = name.replace('\\', '/')
         path = os.path.join(dir, name)
         if not os.path.exists(path):
-            dir = os.path.join(self.sakura.ghost.get_prefix(), "ghost", "master") ## FIXME
-            path = os.path.join(dir, "menu_background.png")
+            dir = os.path.join(self.sakura.ghost.get_prefix(),
+                               'ghost', 'master') ## FIXME
+            path = os.path.join(dir, 'menu_background.png')
             if os.path.exists(path):
                 path_background = path
             else:
                 path_background = None
-            path = os.path.join(dir, "menu_sidebar.png")
+            path = os.path.join(dir, 'menu_sidebar.png')
             if os.path.exists(path):
                 path_sidebar = path
             else:
                 path_sidebar = None
         else:
             path_background = path
-            name = self.desc.get("menu.sidebar.bitmap.filename", "menu_sidebar.png")
+            name = self.desc.get('menu.sidebar.bitmap.filename',
+                                 'menu_sidebar.png')
             name = name.replace('\\', '/')
             path = os.path.join(dir, name)
             if os.path.exists(path):
@@ -342,8 +359,8 @@ class Surface:
 
     def add_window(self, side, default):
         assert side >= 2 and len(self.window) == side ## FIXME
-        name = "char%d" % side
-        title = 'surface.' + name
+        name = 'char%d' % side
+        title = ''.join(('surface.', name))
         gtk_window = self.create_gtk_window(title)
         surface_window = SurfaceWindow(
             gtk_window, side, self.sakura, self.desc, None, self.__surface,
@@ -356,44 +373,44 @@ class Surface:
     def get_mayuna_menu(self):
         for side, index in [('sakura', 0), ('kero', 1)]:
             for menu in self.mayuna[side]:
-                if menu[0] != '-':
+                if not menu.startswith('-'):
                     menu[2] = self.window[index].bind[menu[0]][1]
         return self.mayuna
 
     def compose_elements(self, elements, config):
         error = None
         for n in range(256):
-            key = "element" + str(n)
+            key = ''.join(('element', str(n)))
             if not config.has_key(key):
                 break
-            spec = [value.strip() for value in config[key].split(",")]
+            spec = [value.strip() for value in config[key].split(',')]
             try:
                 method, filename, x, y = spec
                 x = int(x)
                 y = int(y)
             except ValueError:
-                error = "invalid element spec for %s: %s" % (key, config[key])
+                error = 'invalid element spec for %s: %s' % (key, config[key])
                 break
             basename, suffix = os.path.splitext(filename)
-            if suffix.lower() != ".png":
-                error = "unsupported file format for %s: %s" % (key, filename)
+            if suffix.lower() != '.png':
+                error = 'unsupported file format for %s: %s' % (key, filename)
                 break
             basename = basename.lower()
             if not elements.has_key(basename):
-                error = "%s file not found: %s" % (key, filename)
+                error = '%s file not found: %s' % (key, filename)
                 break
             pixbuf = elements[basename][0][0]
             if n == 0: # base surface
                 pixbuf_list = [pixbuf]
-            elif method == "overlay":
+            elif method == 'overlay':
                 pixbuf_list.append((pixbuf, x, y))
-            elif method == "base":
+            elif method == 'base':
                 pixbuf_list.append((pixbuf, x, y))
             else:
-                error = "unknown method for %s: %s" % (key, method)
+                error = 'unknown method for %s: %s' % (key, method)
                 break
             if self.debug & 8192:
-                print "%s: %s %s, x=%d, y=%d, w=%d, h=%d" % (
+                print '%s: %s %s, x=%d, y=%d, w=%d, h=%d' % (
                     key, method, filename, x, y, w, h)
         if error is not None:
             print error
@@ -462,7 +479,7 @@ class Surface:
             elif align == 1:
                 by = max(y + soy + oy, 0 + top_margin)
             else:
-                if y + soy < scrn_h/2:
+                if y + soy < scrn_h / 2:
                     by = max(y + soy + oy, 0 + top_margin)
                 else:
                     by = min(y + soy + oy, scrn_h - bh)
@@ -510,7 +527,7 @@ class Surface:
             elif align == 1:
                 by = max(y + oy, 0 + top_margin)
             else:
-                if y < scrn_h/2:
+                if y < scrn_h / 2:
                     by = max(y + oy, 0 + top_margin)
                 else:
                     by = min(y + oy, scrn_h - bh)
@@ -617,15 +634,13 @@ class Surface:
         x1, y1 = self.get_position(1)
         s0w, s0h = self.get_surface_size(0)
         s1w, s1h = self.get_surface_size(1)
-        if x0 + s0w/4 < 0 or x0 + s0w*3/4 > scrn_w or \
-           y0 + s0h/4 < 0 or y0 + s0h*3/4 > scrn_h:
+        if x0 + s0w / 4 < 0 or x0 + s0w * 3 / 4 > scrn_w or \
+           y0 + s0h / 4 < 0 or y0 + s0h * 3 / 4 > scrn_h:
             self.__mikire = 1
         else:
             self.__mikire = 0
-        if (x1 + s1w/2 > x0 and x1 + s1w/2 < x0 + s0w and \
-            y1 + s1h/2 > y0 and y1 + s1h/2 < y0 + s0h) or \
-           (x0 + s0w/2 > x1 and x0 + s0w/2 < x1 + s1w and \
-            y0 + s0h/2 > y1 and y0 + s0h/2 < y1 + s1h):
+        if (x0 < x1 + s1w / 2 < x0 + s0w and y0 < y1 + s1h / 2 < y0 + s0h) or \
+           (x1 < x0 + s0w / 2 < x1 + s1w and y1 < y0 + s0h / 2 < y1 + s1h):
             self.__kasanari = 1
         else:
             self.__kasanari = 0
@@ -641,53 +656,53 @@ class Surface:
         if self.desc is None:
             return
         else:
-            return self.desc.get("user.defaultname")
+            return self.desc.get('user.defaultname')
 
     def get_selfname(self):
         if self.desc is None:
             return
         else:
-            return self.desc.get("sakura.name")
+            return self.desc.get('sakura.name')
 
     def get_selfname2(self):
         if self.desc is None:
             return
         else:
-            return self.desc.get("sakura.name2")
+            return self.desc.get('sakura.name2')
 
     def get_keroname(self):
         if self.desc is None:
             return
         else:
-            return self.desc.get("kero.name")
+            return self.desc.get('kero.name')
 
     def get_friendname(self):
         if self.desc is None:
             return
         else:
-            return self.desc.get("sakura.friend.name")
+            return self.desc.get('sakura.friend.name')
 
     def get_balloon_offset(self, side):
         if side == 0:
             x, y = self.window[side].get_balloon_offset()
             if x is None:
-                x = self.desc.getint("sakura.balloon.offsetx", 0)
+                x = self.desc.getint('sakura.balloon.offsetx', 0)
             if y is None:
-                y = self.desc.getint("sakura.balloon.offsety", 0)
+                y = self.desc.getint('sakura.balloon.offsety', 0)
         elif side == 1:
             x, y = self.window[side].get_balloon_offset()
             if x is None:
-                x = self.desc.getint("kero.balloon.offsetx", 0)
+                x = self.desc.getint('kero.balloon.offsetx', 0)
             if y is None:
-                y = self.desc.getint("kero.balloon.offsety", 0)
+                y = self.desc.getint('kero.balloon.offsety', 0)
         else:
             x, y = None, None
             if len(self.window) > side:
                 x, y = self.window[side].get_balloon_offset()
             if x is None:
-                x = self.desc.getint("char%d.balloon.offsetx" % side, 0)
+                x = self.desc.getint('char%d.balloon.offsetx' % side, 0)
             if y is None:
-                y = self.desc.getint("char%d.balloon.offsety" % side, 0)
+                y = self.desc.getint('char%d.balloon.offsety' % side, 0)
         if self.__scale != 100:
             x = x * self.__scale / 100
             y = y * self.__scale / 100
@@ -711,14 +726,15 @@ class Surface:
 
     def get_config_int(self, side, name):
         if len(self.window) > side:
-            basename = 'surface' +  self.window[side].surface_id
+            basename = ''.join(('surface', self.window[side].surface_id))
             path, config = self.window[side].surface[basename]
             return config.getint(name)
 
 class SurfaceWindow:
+
     # DnD data types
     dnd_targets = [
-        ("text/plain", 0, 0),
+        ('text/plain', 0, 0),
         ]
 
     def __init__(self, window, side, sakura, desc, alias, surface,
@@ -765,12 +781,12 @@ class SurfaceWindow:
                               gtk.gdk.POINTER_MOTION_HINT_MASK|
                               gtk.gdk.SCROLL_MASK)
         self.callbacks = []
-        for signal, func in [("expose_event",         self.redraw),
-                             ("button_press_event",   self.button_press),
-                             ("button_release_event", self.button_release),
-                             ("motion_notify_event",  self.motion_notify),
-                             ("drag_data_received",   self.drag_data_received),
-                             ("scroll_event",         self.scroll),
+        for signal, func in [('expose_event',         self.redraw),
+                             ('button_press_event',   self.button_press),
+                             ('button_release_event', self.button_release),
+                             ('motion_notify_event',  self.motion_notify),
+                             ('drag_data_received',   self.drag_data_received),
+                             ('scroll_event',         self.scroll),
                              ]:
             self.callbacks.append(self.darea.connect(signal, func))
         self.darea.drag_dest_set(gtk.DEST_DEFAULT_ALL, self.dnd_targets,
@@ -808,15 +824,15 @@ class SurfaceWindow:
 
     def drag_data_received(self, widget, context, x, y, data, info, time):
         if self.debug & 8192:
-            print "Content-type:", data.type
-            print "Content-length:", data.length
+            print 'Content-type:', data.type
+            print 'Content-length:', data.length
             print repr(data.data)
-        if str(data.type) == "text/plain":
+        if str(data.type) == 'text/plain':
             list = []
-            for line in data.data.split("\r\n"):
+            for line in data.data.split('\r\n'):
                 scheme, host, path, params, query, fragment = \
                         urlparse.urlparse(line)
-                if scheme == "file" and os.path.exists(path):
+                if scheme == 'file' and os.path.exists(path):
                     list.append(path)
             if list:
                 self.sakura.notify_file_drop(list, self.side)
@@ -838,7 +854,7 @@ class SurfaceWindow:
         if not self.seriko.has_key(id):
             return
         for actor in self.seriko[id]:
-            if actor.get_interval() == "yen-e":
+            if actor.get_interval() == 'yen-e':
                 actor_id = actor.get_id()
                 self.invoke(actor_id)
                 break
@@ -849,7 +865,7 @@ class SurfaceWindow:
         interval_count = None
         for actor in self.seriko[id]:
             interval = actor.get_interval()
-            if interval[:4] == "talk":
+            if interval.startswith('talk'):
                 interval_count = int(interval[5])
                 actor_id = actor.get_id()
                 break
@@ -902,12 +918,12 @@ class SurfaceWindow:
     def set_surface(self, id, restart=1):
         if self.alias is not None and self.alias.has_key(id):
             aliases = self.alias.get(id)
-            if len(aliases) > 0:
+            if aliases:
                 id = random.choice(aliases)
-        if id == "-2" or restart:
+        if id == '-2' or restart:
             self.terminate()
         not_update = 0
-        if id in ["-1", "-2"]:
+        if id in ['-1', '-2']:
             pass
         elif not self.pixbuf.has_key(id):
             self.surface_id = self.default_id
@@ -922,7 +938,7 @@ class SurfaceWindow:
             self.exclusive_actor = None
             if self.seriko.has_key(self.base_id):
                 for actor in self.seriko[self.base_id]:
-                    if actor.get_interval() == "runonce":
+                    if actor.get_interval() == 'runonce':
                         actor.invoke()
                         if actor.exclusive:
                             self.exclusive_actor = actor
@@ -933,15 +949,16 @@ class SurfaceWindow:
         x, y = self.get_position()
         w, h = self.get_surface_size(self.surface_id)
         dw, dh = self.get_surface_size(self.default_id) # default surface size
-        xoffset = (dw - w)/2
+        xoffset = (dw - w) / 2
         if self.get_alignment() == 0:
             yoffset = dh - h
-            scrn_h = gtk.gdk.screen_height() - self.sakura.ghost.get_bottom_margin() ## FIXME
+            scrn_h = gtk.gdk.screen_height() - \
+                     self.sakura.ghost.get_bottom_margin() ## FIXME
             y = scrn_h - dh
         elif self.get_alignment() == 1:
             yoffset = 0
         else:
-            yoffset = (dh - h)/2
+            yoffset = (dh - h) / 2
         self.window_offset = (xoffset, yoffset)
         if not_update:
             return
@@ -979,14 +996,17 @@ class SurfaceWindow:
                         h += y
                     else:
                         dest_y = y
-                    pixbuf.composite(surface_pixbuf, dest_x, dest_y, w, h, x, y, 1.0, 1.0, gtk.gdk.INTERP_BILINEAR, 255)
+                    pixbuf.composite(surface_pixbuf, dest_x, dest_y,
+                                     w, h, x, y, 1.0, 1.0,
+                                     gtk.gdk.INTERP_BILINEAR, 255)
             elif method == 'reduce':
                 if self.pixbuf.has_key(surface):
                     x, y = args
                     pixbuf = self.get_pixbuf(surface)
                     w = pixbuf.get_width()
                     h = pixbuf.get_height()
-                    surface_pixbuf = pix.reduce_pixbuf(surface_pixbuf, pixbuf, x, y)
+                    surface_pixbuf = pix.reduce_pixbuf(
+                        surface_pixbuf, pixbuf, x, y)
             elif method == 'insert':
                 index = args[0]
                 for actor in self.mayuna[self.surface_id]:
@@ -995,11 +1015,12 @@ class SurfaceWindow:
                         if self.bind.has_key(id) and self.bind[id][1] and \
                            id not in done:
                             done.append(id)
-                            sueface_pixbuf = self.compose_surface(surface_pixbuf, actor, done)
+                            sueface_pixbuf = self.compose_surface(
+                                surface_pixbuf, actor, done)
                         else:
                             break
             else:
-                raise RuntimeError, "should not reach here"
+                raise RuntimeError, 'should not reach here'
         return surface_pixbuf
 
     def reset_pixbuf_cache(self):
@@ -1013,18 +1034,20 @@ class SurfaceWindow:
         if self.pixbuf[id][1] is not None:
             pixbuf = self.pixbuf[id][1]
         else:
-            if len(self.pixbuf[id][0]) == 0:
+            if not self.pixbuf[id][0]:
                 pixbuf = pix.create_blank_pixbuf(8, 8)
             else:
                 try:
-                    pixbuf = pix.create_pixbuf_from_file(self.pixbuf[id][0][0], use_pna=self.__use_pna)
+                    pixbuf = pix.create_pixbuf_from_file(
+                        self.pixbuf[id][0][0], use_pna=self.__use_pna)
                 except:
                     if self.debug & 4:
                         print 'cannot load surface #%d' % id
                     return pix.create_blank_pixbuf(8, 8)
                 for element, x, y in self.pixbuf[id][0][1:]:
                     try:
-                        overlay = pix.create_pixbuf_from_file(element, use_pna=self.__use_pna)
+                        overlay = pix.create_pixbuf_from_file(
+                            element, use_pna=self.__use_pna)
                     except:
                         continue
                     w = overlay.get_width()
@@ -1045,10 +1068,13 @@ class SurfaceWindow:
                         h += y
                     else:
                         dest_y = y
-                    overlay.composite(pixbuf, dest_x, dest_y, w, h, x, y, 1.0, 1.0, gtk.gdk.INTERP_BILINEAR, 255)
+                    overlay.composite(pixbuf, dest_x, dest_y,
+                                      w, h, x, y, 1.0, 1.0,
+                                      gtk.gdk.INTERP_BILINEAR, 255)
             self.pixbuf[id][1] = pixbuf
             for key in self.pixbuf.keys():
-                if key not in [id, '0', '10'] and self.pixbuf[key][2] is not None:
+                if key not in [id, '0', '10'] and \
+                   self.pixbuf[key][2] is not None:
                     self.pixbuf[key][2] = self.pixbuf[key][2] - 1
                     if self.pixbuf[key][2] < 0:
                         self.pixbuf[key][1] = None
@@ -1071,14 +1097,17 @@ class SurfaceWindow:
                     if self.bind.has_key(id) and self.bind[id][1] and \
                        id not in done:
                         done.append(id)
-                        sueface_pixbuf = self.compose_surface(surface_pixbuf, actor, done)
+                        sueface_pixbuf = self.compose_surface(
+                            surface_pixbuf, actor, done)
                 self.surface_cache[self.surface_id] = surface_pixbuf
         if self.__scale != 100:
             w = w * self.__scale / 100
             h = h * self.__scale / 100
-            surface_pixbuf = surface_pixbuf.scale_simple(w, h, gtk.gdk.INTERP_BILINEAR)
+            surface_pixbuf = surface_pixbuf.scale_simple(
+                w, h, gtk.gdk.INTERP_BILINEAR)
         self.surface_pixbuf = surface_pixbuf
-        surface_pixmap, self.mask_pixmap = surface_pixbuf.render_pixmap_and_mask(1)
+        surface_pixmap, self.mask_pixmap = \
+                        surface_pixbuf.render_pixmap_and_mask(1)
 
     def draw_region(self):
         surface_gc = self.darea.window.new_gc()
@@ -1089,7 +1118,8 @@ class SurfaceWindow:
                 x2 = x2 * self.__scale / 100
                 y1 = y1 * self.__scale / 100
                 y2 = y2 * self.__scale / 100
-            self.darea.window.draw_rectangle(surface_gc, 0, x1, y1, x2 - x1, y2 - y1)
+            self.darea.window.draw_rectangle(
+                surface_gc, 0, x1, y1, x2 - x1, y2 - y1)
 
     def show_surface(self):
         self.darea.queue_draw()
@@ -1101,7 +1131,8 @@ class SurfaceWindow:
             pix.modify_pixbuf_alpha(pixbuf, self.__alpha_channel)
             darea.window.draw_pixbuf(None, pixbuf, 0, 0, 0, 0, -1, -1)
         else:
-            darea.window.draw_pixbuf(None, self.surface_pixbuf, 0, 0, 0, 0, -1, -1)
+            darea.window.draw_pixbuf(
+                None, self.surface_pixbuf, 0, 0, 0, 0, -1, -1)
         if self.debug & 4096:
             self.draw_region()
 
@@ -1115,15 +1146,15 @@ class SurfaceWindow:
             pass
 
     def add_overlay(self, actor, id, x, y):
-        if id == "-2":
+        if id == '-2':
             self.terminate()
-        if id in ["-1", "-2"]:
+        if id in ['-1', '-2']:
             self.remove_overlay(actor)
             return
         self.overlays[actor] = (id, x, y)
 
     def draw_overlays(self):
-        ##print "draw_overlays()"
+        ##print 'draw_overlays()'
         pixbuf = self.get_pixbuf(self.surface_id)
         w = pixbuf.get_width()
         h = pixbuf.get_height()
@@ -1138,13 +1169,14 @@ class SurfaceWindow:
                     if self.bind.has_key(id) and self.bind[id][1] and \
                        id not in done:
                         done.append(id)
-                        sueface_pixbuf = self.compose_surface(surface_pixbuf, actor, done)
+                        sueface_pixbuf = self.compose_surface(
+                            surface_pixbuf, actor, done)
                 self.surface_cache[self.surface_id] = surface_pixbuf.copy()
         actors = self.overlays.keys()
         actors.sort(lambda a1, a2: cmp(a1.get_id(), a2.get_id()))
         for actor in actors:
             id, x, y = self.overlays[actor]
-            ##print "actor=%d, id=%s, x=%d, y=%d" % (actor.get_id(), id, x, y)
+            ##print 'actor=%d, id=%s, x=%d, y=%d' % (actor.get_id(), id, x, y)
             try:
                 pixbuf = self.get_pixbuf(id)
                 w = pixbuf.get_width()
@@ -1168,13 +1200,17 @@ class SurfaceWindow:
                 h += y
             else:
                 dest_y = y
-            pixbuf.composite(surface_pixbuf, dest_x, dest_y, w, h, x, y, 1.0, 1.0, gtk.gdk.INTERP_BILINEAR, 255)
+            pixbuf.composite(surface_pixbuf, dest_x, dest_y,
+                             w, h, x, y, 1.0, 1.0,
+                             gtk.gdk.INTERP_BILINEAR, 255)
         if self.__scale != 100:
             w = surface_pixbuf.get_width() * self.__scale / 100
             h = surface_pixbuf.get_height() * self.__scale / 100
-            surface_pixbuf = surface_pixbuf.scale_simple(w, h, gtk.gdk.INTERP_BILINEAR)
+            surface_pixbuf = surface_pixbuf.scale_simple(
+                w, h, gtk.gdk.INTERP_BILINEAR)
         self.surface_pixbuf = surface_pixbuf
-        surface_pixmap, self.mask_pixmap = surface_pixbuf.render_pixmap_and_mask(1)
+        surface_pixmap, self.mask_pixmap = \
+                        surface_pixbuf.render_pixmap_and_mask(1)
         self.show_surface()
 
     def __move(self, xoffset=0, yoffset=0):
@@ -1187,13 +1223,13 @@ class SurfaceWindow:
         self.sakura.ghost.notify_surface_move(self.side, xoffset, yoffset) ## FIXME
 
     def get_balloon_offset(self):
-        path, config = self.surface['surface' + self.surface_id]
+        path, config = self.surface[''.join(('surface', self.surface_id))]
         if self.side == 0:
-            x = config.getint("sakura.balloon.offsetx")
-            y = config.getint("sakura.balloon.offsety")
+            x = config.getint('sakura.balloon.offsetx')
+            y = config.getint('sakura.balloon.offsety')
         else:
-            x = config.getint("kero.balloon.offsetx")
-            y = config.getint("kero.balloon.offsety")
+            x = config.getint('kero.balloon.offsetx')
+            y = config.getint('kero.balloon.offsety')
         return x, y
 
     def get_surface(self):
@@ -1217,9 +1253,9 @@ class SurfaceWindow:
     def get_touched_region(self, x, y):
         for part, x1, y1, x2, y2 in self.collisions:
             if x1 <= x <= x2 and y1 <= y <= y2:
-                ##print part, "touched"
+                ##print part, 'touched'
                 return part
-        return ""
+        return ''
 
     def get_direction(self):
         return self.direction
@@ -1246,7 +1282,8 @@ class SurfaceWindow:
 
     def set_alignment(self, align):
         if align == 0:
-            scrn_h = gtk.gdk.screen_height() - self.sakura.ghost.get_bottom_margin() ## FIXME
+            scrn_h = gtk.gdk.screen_height() - \
+                     self.sakura.ghost.get_bottom_margin() ## FIXME
             sw, sh = self.get_surface_size()
             sx, sy = self.get_position()
             sy = scrn_h - sh
@@ -1310,7 +1347,8 @@ class SurfaceWindow:
             click = 1
         else:
             click = 2
-        self.sakura.ghost.notify_surface_click(event.button, click, self.side, x, y) ## FIXME
+        self.sakura.ghost.notify_surface_click(
+            event.button, click, self.side, x, y) ## FIXME
         return True
 
     def button_release(self, window, event):
@@ -1332,7 +1370,8 @@ class SurfaceWindow:
                     x_delta = int(event.x_root - self.x_root)
                     y_delta = int(event.y_root - self.y_root)
                     self.dragged = 1
-                    self.sakura.ghost.notify_surface_drag(self.side, x_delta, y_delta) ## FIXME
+                    self.sakura.ghost.notify_surface_drag(
+                        self.side, x_delta, y_delta) ## FIXME
                     self.x_root = event.x_root
                     self.y_root = event.y_root
             elif state & gtk.gdk.BUTTON1_MASK or \
@@ -1365,7 +1404,7 @@ class SurfaceWindow:
             count = 0
         if count != 0:
             part = self.get_touched_region(x, y)
-            self.sakura.notify_event("OnMouseWheel",
+            self.sakura.notify_event('OnMouseWheel',
                                      x, y, count, self.side, part)
         return True
 
@@ -1376,8 +1415,9 @@ class SurfaceWindow:
             self.surface_cache = {}
             self.reset_surface()
 
+
 def test():
     pass
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     test()
index 56cb00c..a53842f 100644 (file)
@@ -2,7 +2,7 @@
 #
 #  Copyright (C) 2001, 2002 by Tamito KAJIYAMA
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
-#  Copyright (C) 2002-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: update.py,v 1.12 2004/11/24 02:36:37 shy Exp $
+# $Id: update.py,v 1.13 2005/08/09 00:41:52 shy Exp $
 #
 
 import urlparse
-import string
 import StringIO
 import os
 import md5
 import time
 import httplib
 
+
 class NetworkUpdate:
-    __BACKUP_SUFFIX = ".BACKUP"
+
+    __BACKUP_SUFFIX = '.BACKUP'
+
     def __init__(self, sakura):
         self.sakura = sakura
         self.event_queue = []
@@ -31,27 +33,35 @@ class NetworkUpdate:
         self.backups = []
         self.newfiles = []
         self.newdirs = []
+
     def is_active(self):
         return self.state is not None
+
     def enqueue_event(self, event,
                       ref0=None, ref1=None, ref2=None, ref3=None,
                       ref4=None, ref5=None, ref6=None, ref7=None):
         self.event_queue.append(
             (event, ref0, ref1, ref2, ref3, ref4, ref5, ref6, ref7))
+
     def get_event(self):
         if not self.event_queue:
             return None
         return self.event_queue.pop(0)
+
     def has_events(self):
-        return len(self.event_queue) > 0
+        if self.event_queue:
+            return 1
+        else:
+            return 0
+
     def start(self, homeurl, ghostdir, timeout=60):
         url = urlparse.urlparse(homeurl)
-        if not (url[0] == "http" and url[3] == url[4] == url[5] == ''):
-            self.enqueue_event("OnUpdateFailure", "bad home URL")
+        if not (url[0] == 'http' and url[3] == url[4] == url[5] == ''):
+            self.enqueue_event('OnUpdateFailure', 'bad home URL')
             self.state = None
             return            
         try:
-            self.host, port = url[1].split(":")
+            self.host, port = url[1].split(':')
             self.port = int(port)
         except ValueError:
             self.host = url[1]
@@ -60,12 +70,14 @@ class NetworkUpdate:
         self.ghostdir = ghostdir
         self.timeout = timeout
         self.state = 0
+
     def interrupt(self):
         self.event_queue = []
         if self.sakura:
-            self.sakura.enqueue_event("OnUpdateFailure", "artificial")
+            self.sakura.enqueue_event('OnUpdateFailure', 'artificial')
         self.state = None
         self.stop(revert=1)
+
     def stop(self, revert=0):
         self.buffer = []
         if revert:
@@ -85,10 +97,13 @@ class NetworkUpdate:
         self.backups = []
         self.newfiles = []
         self.newdirs = []
+
     def reset_timeout(self):
         self.timestamp = time.time()
+
     def check_timeout(self):
         return time.time() - self.timestamp > self.timeout
+
     def run(self):
         if self.state is None or (self.sakura and self.sakura.event_queue):
             return 0
@@ -120,50 +135,56 @@ class NetworkUpdate:
             filename, checksum = self.schedule.pop(0)
             self.update_file(filename, checksum)
         return 1
+
     def start_updates(self):
-        self.download(os.path.join(self.path, "updates2.dau"))
-        self.enqueue_event("OnUpdateBegin")
+        self.download(os.path.join(self.path, 'updates2.dau'))
+        self.enqueue_event('OnUpdateBegin')
+
     def download(self, locator, event=0):
         self.locator = self.encode(locator)
         self.http = httplib.HTTPConnection(self.host, self.port)
         if event:
-            self.enqueue_event("OnUpdate.OnDownloadBegin",
+            self.enqueue_event('OnUpdate.OnDownloadBegin',
                                os.path.basename(locator),
                                self.file_number, self.num_files)
         self.state += 1
         self.reset_timeout()
+
     def encode(self, path):
-        return string.join([self.encode_special(c) for c in path], "")
+        return ''.join([self.encode_special(c) for c in path])
+
     def encode_special(self, c):
-        if "\x20" < c < "\x7e":
+        if '\x20' < c < '\x7e':
             return c
-        return "%%%02x" % ord(c)
+        return '%%%02x' % ord(c)
+
     def connect(self):
         try:
             self.http.connect()
         except:
-            self.enqueue_event("OnUpdateFailure", "connection failed")
+            self.enqueue_event('OnUpdateFailure', 'connection failed')
             self.state = None
             self.stop(revert=1)
             return
         if self.check_timeout():
-            self.enqueue_event("OnUpdateFailure", "timeout")
+            self.enqueue_event('OnUpdateFailure', 'timeout')
             self.state = None
             self.stop(revert=1)
             return
-        self.http.request("GET", self.locator)
+        self.http.request('GET', self.locator)
         self.state += 1
         self.reset_timeout()
+
     def wait_response(self):
         try:
             self.response = self.http.getresponse()
         except:
-            self.enqueue_event("OnUpdateFailure", "no HTTP response")
+            self.enqueue_event('OnUpdateFailure', 'no HTTP response')
             self.state = None
             self.stop(revert=1)
             return
         if self.check_timeout():
-            self.enqueue_event("OnUpdateFailure", "timeout")
+            self.enqueue_event('OnUpdateFailure', 'timeout')
             self.state = None
             self.stop(revert=1)
             return
@@ -174,34 +195,35 @@ class NetworkUpdate:
         elif code == 302 and self.redirect():
             return
         elif self.state == 2: # updates2.dau
-            self.enqueue_event("OnUpdateFailure", str(code))
+            self.enqueue_event('OnUpdateFailure', str(code))
             self.state = None
             return
         else:
             filename, checksum = self.schedule.pop(0)
-            print "failed to download %s (%d %s)" % (filename, code, message)
+            print 'failed to download %s (%d %s)' % (filename, code, message)
             self.file_number += 1
             self.state += 3
             return
         self.buffer = []
-        size = self.response.getheader("content-length", None)
+        size = self.response.getheader('content-length', None)
         if size is None:
             self.size = None
         else:
             self.size = int(size)
         self.state += 1
         self.reset_timeout()
+
     def redirect(self):
-        location = self.response.getheader("location", None)
+        location = self.response.getheader('location', None)
         if location is None:
             return 0
         url = urlparse.urlparse(location)
-        if not (url[0] == "http" and url[3] == url[4] == url[5] == ''):
+        if not (url[0] == 'http' and url[3] == url[4] == url[5] == ''):
             return 0
-        print "redirected to", location
+        print 'redirected to', location
         self.http.close()
         try:
-            self.host, port = url[1].split(":")
+            self.host, port = url[1].split(':')
             self.port = int(port)
         except ValueError:
             self.host = url[1]
@@ -210,18 +232,19 @@ class NetworkUpdate:
         self.state -= 2
         self.download(url[2])
         return 1
+
     def get_content(self):
         data = self.response.read()
         if not data:
             if self.check_timeout():
-                self.enqueue_event("OnUpdateFailure", "timeout")
+                self.enqueue_event('OnUpdateFailure', 'timeout')
                 self.state = None
                 self.stop(revert=1)
                 return
             elif data is None:
                 return
         elif data < 0:
-            self.enqueue_event("OnUpdateFailure", "data retrieval failed")
+            self.enqueue_event('OnUpdateFailure', 'data retrieval failed')
             self.state = None
             self.stop(revert=1)
             return
@@ -235,31 +258,36 @@ class NetworkUpdate:
             return
         self.http.close()
         self.state += 1
+
     def make_checksum(self, digest):
-        return string.join(["%02x" % ord(x) for x in digest], '')
-    ROOT_FILES = ["install.txt", "delete.txt", "readme.txt", "thumbnail.png"]
+        return ''.join(['%02x' % ord(x) for x in digest])
+
+    ROOT_FILES = ['install.txt', 'delete.txt', 'readme.txt', 'thumbnail.png']
+
     def adjust_path(self, filename):
         filename = filename.lower()
         if filename in self.ROOT_FILES or os.path.dirname(filename):
             return filename
-        return os.path.join("ghost", "master", filename)
+        return os.path.join('ghost', 'master', filename)
+
     def make_schedule(self):
         schedule = self.parse_updates2_dau()
         if schedule is not None:
             self.num_files = len(schedule) - 1
             self.file_number = 0
             if self.num_files >= 0:
-                self.enqueue_event("OnUpdateReady", self.num_files)
+                self.enqueue_event('OnUpdateReady', self.num_files)
             self.state += 1
         return schedule
+
     def parse_updates2_dau(self):
         schedule = []
-        file = StringIO.StringIO(string.join(self.buffer, ''))
+        file = StringIO.StringIO(''.join(self.buffer))
         for line in file:
             try:
-                filename, checksum, newline = line.split("\001", 2)
+                filename, checksum, newline = line.split('\001', 2)
             except ValueError:
-                self.enqueue_event("OnUpdateFailure", "broken updates2.dau")
+                self.enqueue_event('OnUpdateFailure', 'broken updates2.dau')
                 self.state = None
                 return None
             if not filename:
@@ -277,8 +305,9 @@ class NetworkUpdate:
             schedule.append((filename, checksum))
         self.updated_files = []
         return schedule
+
     def update_file(self, filename, checksum):
-        data = string.join(self.buffer, '')
+        data = ''.join(self.buffer)
         m = md5.new()
         m.update(data)
         digest = self.make_checksum(m.digest())
@@ -298,29 +327,30 @@ class NetworkUpdate:
                     os.makedirs(subdir)
                 except OSError:
                     self.enqueue_event(
-                        "OnUpdateFailure", "can't mkdir " + subdir)
+                        'OnUpdateFailure', ''.join(("can't mkdir ", subdir)))
                     self.state = None
                     self.stop(revert=1)
                     return
             if os.path.exists(path):
                 if os.path.isfile(path):
-                    backup = path + self.__BACKUP_SUFFIX
+                    backup = ''.join((path, self.__BACKUP_SUFFIX))
                     os.rename(path, backup)
                     self.backups.append(backup)
             else:
                 self.newfiles.append(path)
             try:
-                open(path, "w").write(data)
+                open(path, 'w').write(data)
             except IOError:
                 self.enqueue_event(
-                    "OnUpdateFailure", "can't write " + os.path.basename(path))
+                    'OnUpdateFailure',
+                    ''.join(("can't write ", os.path.basename(path))))
                 self.state = None
                 self.stop(revert=1)
                 return
             self.updated_files.append(filename)
-            event = "OnUpdate.OnMD5CompareComplete"
+            event = 'OnUpdate.OnMD5CompareComplete'
         else:
-            event = "OnUpdate.OnMD5CompareFailure"
+            event = 'OnUpdate.OnMD5CompareFailure'
             self.enqueue_event(event, filename, checksum, digest)
             self.state = None
             self.stop(revert=1)
@@ -328,6 +358,7 @@ class NetworkUpdate:
         self.enqueue_event(event, filename, checksum, digest)
         self.file_number += 1
         self.state += 1
+
     def end_updates(self):
         filelist = self.parse_delete_txt()
         if filelist:
@@ -336,20 +367,21 @@ class NetworkUpdate:
                 if os.path.exists(path) and os.path.isfile(path):
                     try:
                         os.unlink(path)
-                        print "deleted", path
+                        print 'deleted', path
                     except OSError, e:
                         print e
-        list = string.join(self.updated_files, ',')
+        list = ','.join(self.updated_files)
         if not list:
-            self.enqueue_event("OnUpdateComplete", "none")
+            self.enqueue_event('OnUpdateComplete', 'none')
         else:
-            self.enqueue_event("OnUpdateComplete", "changed", list)
+            self.enqueue_event('OnUpdateComplete', 'changed', list)
         self.state = None
         self.stop()
+
     def parse_delete_txt(self):
         filelist = []
         try:
-            file = open(os.path.join(self.ghostdir, "delete.txt"))
+            file = open(os.path.join(self.ghostdir, 'delete.txt'))
         except IOError:
             return None
         error = None
@@ -358,16 +390,17 @@ class NetworkUpdate:
             if not line:
                 continue
             filename = line
-            filelist.append(filename.replace("\\", "/").lower())
+            filelist.append(filename.replace('\\', '/').lower())
         if error is not None:
             print error
             return None
         return filelist
 
+
 def test():
     import sys
     if len(sys.argv) != 3:
-        sys.stderr.write("Usage: update.py homeurl ghostdir\n")
+        sys.stderr.write('Usage: update.py homeurl ghostdir\n')
         sys.exit(1)
     update = NetworkUpdate(None)
     update.start(sys.argv[1], sys.argv[2], timeout=60)
@@ -378,7 +411,7 @@ def test():
         e = time.time()
         delta = e - s
         if delta > 0.1:
-            print "Warning: state = %d (%f sec)" % (state, delta)
+            print 'Warning: state = %d (%f sec)' % (state, delta)
         while 1:
             event = update.get_event()
             if not event:
@@ -387,10 +420,10 @@ def test():
         if code == 0:
             break
         if update.state == 5 and update.schedule:
-            print "File(s) to be update:"
+            print 'File(s) to be update:'
             for filename, checksum in update.schedule:
-                print "   ", filename
+                print '   ', filename
     update.stop()
 
-if __name__ == "__main__":
+if __name__ == '__main__':
     test()
index 3288dd4..c6cdf1d 100644 (file)
@@ -14,11 +14,13 @@ NUMBER = '3.5.9'
 CODENAME = 'clover key'
 
 VERSION = '%s (%s)' % (NUMBER, CODENAME)
-VERSION_INFO = (r'\h\s[0]\w8ninix-aya %s\n' % VERSION +
-                unicode(_('Are igai No Nanika with \"Nin\'i\" for X'), 'utf-8') + r'\n'
-                r'\_q'
-                r'Copyright (c) 2001, 2002 Tamito KAJIYAMA\n'
-                r'Copyright (c) 2002-2005 MATSUMURA Namihiko\n'
-                r'Copyright (c) 2002-2005 Shyouzou Sugitani\n'
-                r'Copyright (c) 2002, 2003 ABE Hideaki\n'
-                r'Copyright (c) 2003, 2004 Shun-ichi TAHARA\e')
+VERSION_INFO = (''.join((r'\h\s[0]\w8ninix-aya %s\n' % VERSION,
+                         unicode(_('Are igai No Nanika with "Nin\'i" for X'),
+                                 'utf-8'),
+                         r'\n',
+                         r'\_q'
+                         r'Copyright (c) 2001, 2002 Tamito KAJIYAMA\n'
+                         r'Copyright (c) 2002-2005 MATSUMURA Namihiko\n'
+                         r'Copyright (c) 2002-2005 Shyouzou Sugitani\n'
+                         r'Copyright (c) 2002, 2003 ABE Hideaki\n'
+                         r'Copyright (c) 2003-2005 Shun-ichi TAHARA\e')))
index e711043..12c2a8e 100644 (file)
@@ -3,7 +3,7 @@
 #  sstplib.py - an SSTP library module in Python
 #  Copyright (C) 2001, 2002 by Tamito KAJIYAMA
 #  Copyright (C) 2002, 2003 by MATSUMURA Namihiko <nie@counterghost.net>
-#  Copyright (C) 2002-2004 by Shyouzou Sugitani <shy@users.sourceforge.jp>
+#  Copyright (C) 2002-2005 by Shyouzou Sugitani <shy@users.sourceforge.jp>
 #
 #  This program is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License (version 2) as
@@ -12,7 +12,7 @@
 #  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 #  PURPOSE.  See the GNU General Public License for more details.
 #
-# $Id: sstplib.py,v 1.5 2004/04/13 05:21:59 shy Exp $
+# $Id: sstplib.py,v 1.6 2005/08/09 00:41:52 shy Exp $
 #
 
 import mimetools
@@ -23,10 +23,12 @@ import SocketServer
 import sys
 import time
 
+
 class SSTPServer(SocketServer.TCPServer):
     pass
 
 class AsynchronousSSTPServer(SSTPServer):
+
     def handle_request(self, timeout=0):
         r, w, e = select.select([self.socket], [], [], timeout)
         if not r:
@@ -34,65 +36,73 @@ class AsynchronousSSTPServer(SSTPServer):
         SSTPServer.handle_request(self)
 
 class BaseSSTPRequestHandler(SocketServer.StreamRequestHandler):
+
     responses = {
-        200: "OK",
-        204: "No Content",
-        210: "Break",
-        400: "Bad Request",
-        408: "Request Timeout",
-        409: "Conflict",
-        420: "Refuse",
-        501: "Not Implemented",
-        503: "Service Unavailable",
-        510: "Not Local IP",
-        511: "In Black List",
-        512: "Invisible",
+        200: 'OK',
+        204: 'No Content',
+        210: 'Break',
+        400: 'Bad Request',
+        408: 'Request Timeout',
+        409: 'Conflict',
+        420: 'Refuse',
+        501: 'Not Implemented',
+        503: 'Service Unavailable',
+        510: 'Not Local IP',
+        511: 'In Black List',
+        512: 'Invisible',
         }
     MessageClass = mimetools.Message
-    re_requestsyntax = re.compile("^([A-Z]+) SSTP/([0-9]\\.[0-9])$")
+    re_requestsyntax = re.compile('^([A-Z]+) SSTP/([0-9]\\.[0-9])$')
+
     def parse_request(self, requestline):
-        if requestline[-2:] == '\r\n':
+        if requestline.endswith('\r\n'):
             requestline = requestline[:-2]
-        elif requestline[-1:] == '\n':
+        elif requestline.endswith('\n'):
             requestline = requestline[:-1]
         self.requestline = requestline
         match = self.re_requestsyntax.match(requestline)
         if not match:
-            self.requestline = "-"
-            self.send_error(400, "Bad Request %s" % repr(requestline))
+            self.requestline = '-'
+            self.send_error(400, 'Bad Request %s' % repr(requestline))
             return 0
         self.command, self.version = match.groups()
         self.headers = self.MessageClass(self.rfile, 0)
         return 1
+
     def handle(self):
         self.error = self.version = None
         if not self.parse_request(self.rfile.readline()):
             return
-        name = "do_%s_%s_%s" % (self.command, self.version[0], self.version[2])
+        name = 'do_%s_%s_%s' % (self.command, self.version[0], self.version[2])
         if not hasattr(self, name):
-            self.send_error(501, "Not Implemented (%s/%s)" % (
+            self.send_error(501, 'Not Implemented (%s/%s)' % (
                 self.command, self.version))
             return
         method = getattr(self, name)
         method()
+
     def send_error(self, code, message=None):
         self.error = code
         self.log_error(message or self.responses[code])
         self.send_response(code, self.responses[code])
+
     def send_response(self, code, message=None):
         self.log_request(code, message)
-        self.wfile.write("SSTP/%s %d %s\r\n\r\n" % (
-            self.version or "1.0", code, self.responses[code]))
+        self.wfile.write('SSTP/%s %d %s\r\n\r\n' % (
+            self.version or '1.0', code, self.responses[code]))
+
     def log_error(self, message):
-        sys.stderr.write("[%s] %s\n" % (self.timestamp(), message))
+        sys.stderr.write('[%s] %s\n' % (self.timestamp(), message))
+
     def log_request(self, code, message=None):
-        if self.requestline == "-":
+        if self.requestline == '-':
             request = self.requestline
         else:
-            request = '"' + self.requestline + '"'
+            request = ''.join(('"', self.requestline, '"'))
         sys.stderr.write('%s [%s] %s %d %s\n' % (
             self.client_hostname(), self.timestamp(),
             request, code, message or self.responses[code]))
+
     def client_hostname(self):
         try:
             host, port = self.client_address
@@ -104,19 +114,22 @@ class BaseSSTPRequestHandler(SocketServer.StreamRequestHandler):
         except socket.error:
             hostname = host
         return hostname
-    month_names = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
-                   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+
+    month_names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+                   'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+
     def timestamp(self):
         t = time.localtime(time.time())
         m = self.month_names[t[1]-1]
-        return "%02d/%s/%d:%02d:%02d:%02d %+05d" % (
-            t[2], m, t[0], t[3], t[4], t[5], -time.timezone/36)
+        return '%02d/%s/%d:%02d:%02d:%02d %+05d' % (
+            t[2], m, t[0], t[3], t[4], t[5], -time.timezone / 36)
+
 
 def test(ServerClass = SSTPServer,
          HandlerClass = BaseSSTPRequestHandler,
          port = 9801): # or 11000
     sstpd = ServerClass(('', port), HandlerClass)
-    print "Serving SSTP on port %d ..." % port
+    print 'Serving SSTP on port %d ...' % port
     sstpd.serve_forever()
 
 if __name__ == '__main__':