環境変数で config を切替えるためのクラス
id:cho45 さんが作成された Config::ENV という Perl モジュールがとても便利で、最近設定ファイルが必要な場合には、ほとんどのケースでこのモジュールを利用しています。
使い方については Advent Calendar に掲載された、以下の記事を読んでください。
- 環境変数で config を切替えるためのモジュール
- http://perl-users.jp/articles/advent-calendar/2011/hacker/1
ということで、まれによく使う PHP でも同じことが出来たら便利なんじゃないかと思い、作成してみました。
- php-Config-ENV
- https://github.com/hatyuki/php-Config-ENV
Perl のように DSL っぽい書き方は出来ませんが、だいたい同じようなことができます。
続きを読むunstable からパッケージを借りて nginx 1.4.1 をインストール
Debian/weedy がリリースされたため、普段利用している環境も Debian/jessie へとアップグレードされました。
ということで(?)、前回の記事で CentOS に nginx 1.4.0 をインストールしましたが Debian/jessie にも SPDY 対応版の nginx をインストールすることに。
ただし jessie 標準パッケージでは nginx のバージョンが 1.2.6 となっているので、sid (unstable) からパッケージを借りてのインストールとなりました。
Debian のバージョンや、インストールするパッケージに依存せず、unstable からパッケージを借りてのインストールする場合の作業方法となるため、メモメモ。
nginx 1.4.0 の SPDY を試してみる
nginx 1.3 の頃より patch をあてて SPDY を有効する方法を、色々な方が試されていますので、今更という感じはしますが nginx 1.4 がリリースされ SPDY と WebSocket が正式にサポートされたということで、改めて導入してみました。
ということでインストールメモ。
HTML5 の canvas をさわってみた
仕事をしている時、ちょっと QR コードが欲しくなったけれど、手軽に生成できるサイトが見つけられなかったので、HTML5 の練習も含めて作ってみることにしました。
作ったのはこんな感じ。
- Zebra
- http://qr.magicalhat.jp/
- github
- https://github.com/hatyuki/Zebra
テキストエリアに何か入力すると、それをリアルタイムで QR コードに変換してくれます。
たとえば般若心経を入力するとこんな QR コードが生成されます。誰得なんでしょうね。
って、何の変哲もない QR コードなんだけど。。。
jperl と jcode.pl から卒業する
何をいまさらな話題ですが、文字コードが EUC-JP が主流だった時代に作られた jperl と jcode.pl に依存しているレガシーなシステムをモダンな Perl に書き換える場合には、Encode に加えて Encode::EUCJPMS を使うと簡単でした。
というメモ。
- Encode-EUCJPMS
- http://search.cpan.org/~naruse/Encode-EUCJPMS/
これで機種依存文字を恐れず処理することができました。
Unicode にさえなってしまえば後はやり放題で、日本語の「全角←→半角」変換などは Lingua::JA::Regular::Unicode が便利でした。
- Lingua-JA-Regular-Unicode
- http://search.cpan.org/~tokuhirom/Lingua-JA-Regular-Unicode/
use utf8; use Encode::EUCJPMS; use Encode ( ); # eucJP-ms な DB から値を取得して my $row = $sth->fetchrow_hashref( ); # Perl の世界に decode して my $utf8 = Encode::decode('eucJP-ms', $row->{japanese}); ... # なんか処理して ... # eucJP-ms で戻してあげる $dbh->execute(Encode::encode('eucJP-ms', $japanese));
こんな感じ。
ちなみに、今回は DB からいろいろ取得して、文字列処理をして DB に戻す。という、だいたい完了まで 30分くらい処理にかかるようなスクリプトを書き直したのですが、書き直した後も実行時間は特に変わらず *1 Encode でいったん EUC-JP から Unicode に変換し、再び EUC-JP に戻すこと自体はパフォーマンス的なマイナスはないと思います。
むしろ jperl から脱却することによるメリットの方がおおきいですね。
これで「触らぬ Script に障害なし」とか言う謎の遺言からも解放です。
わーい。楽ちんですね。
*1:実際は 5分くらい早くなった
Debian/Wheezy を TimeMachine のディスクとして使う
TimeCapsule はちょっとオーバースペックなんだもの。
ということで、Debian/Wheezy に netatalk をインストールして TimeMachine のディスクとして利用してみました。
調べてみると netatalk のバージョンが 2.1 未満の場合はソースからコンパイルして〜。みたいなことがあるようですが、Wheezy では最初から 2.2 がインストールされたので、作業は本当に netatalk をインストールしただけでした。
# aptitude install netatalk
おわり。
申し訳程度に以下の設定ファイルをちょっと編集しました。
- /etc/netatalk/AppleVolumes.default
--- AppleVolumes.default 2013-01-04 00:50:31.000000000 +0900 +++ /etc/netatalk/AppleVolumes.default 2013-01-03 12:55:25.000000000 +0900 @@ -174,6 +174,7 @@ :DEFAULT: options:upriv,usedots # By default all users have access to their home directories. -~/ "Home Directory" +# ~/ "Home Directory" +/path/to/TimeMachine/dir "TimeMachine" options:tm volsizelimit:100000 # End of File
TimeMachine で利用するディレクトリの指定と、クォータの設定をしただけっていう。すごく簡単ですね。
これで無事にバックアップが作成されるようになりました。わーい。
WebSocket を使って Amon2 でチャットプログラムを書いてみる
ずいぶん前ですが Amon2 が WebSocket に対応したということで、今更感のあるチャットプログラムを書いてみることに。
今更とは言いつつも社内では IRC を使うことができないので、ちょっとしたメッセージがやりとりできるものを作ってみようかなと思い、そのベースとなるようなイメージで作ってみました。
オマケで以前から使ってみたいなぁと思っていた Redis や Proclet なんかも (無駄に) 使ってみました。
適当な Heartbeat で WebSocket を維持していたり、エラー処理が適当すぎて Member の一覧が嘘つきだったり *1 と、まだまだイケてない部分ばかりですが、最近時間がなかなか取れないこともあり、とりあえず動くし晒してみようかと思います。
Twincle の名前は昔テストで Twitter Client を作ったときに押さえた ID をそのまま踏襲しただけで、特に意味はないです。
README すらないご覧のザマだよ。
- hatyuki / twincle
- https://github.com/hatyuki/twincle
セッションで Socket を管理しているため、同一ブラウザで2つウィンドウ立ち上げてもうまく動きません。この辺は Hash::MultiValue をうまく使えばいいのかなー。などと検討中。
なんとなく工夫した気がするところ
WebSocket ではバイナリデータを送受信することができるので、今回は Perl (Amon2) ←→ JavaScript 間を MessagePack でバイナリ化してやりとりをしてみました。
Amon2 では下位のレイヤーでは Protocol::WebSocket を利用して WebSocket のやりとりをしていますが、その部分は見事に隠蔽されており、プログラムするときは Protocol::WebSocket の存在を意識せずに、文字列を単に渡すだけで WebSocket を扱うことができます。
- MyApp::Web::Dispatcher
get '/socket' => sub { my $c = shift; $c->websocket( sub { my $ws = shift; $ws->send_message("文字列を渡すだけで OK"); # ... } ); };
が、バイナリデータを送受信するためには Protocol::WebSocket::Frame のコンストラクタで送信したいフレームがバイナリデータであることを指定する必要があるため、ちょっと都合が悪いこととなります。
そこで、Amon2::Plugin::Web::WebSocket をちょっとだけ編集して、文字列だけではなく Protocol::WebSocket::Frame そのものも渡せるようにしました。
- MyApp::Plugin::Web::WebSocket
# ... (中略) $ws->{send_message} = sub { my $message = shift; # Protocol::WebSocket::Frame オブジェクトを受け付けるように unless (eval { $message->isa('Protocol::WebSocket::Frame') }) { $message = Protocol::WebSocket::Frame->new($message); } $h->push_write($message->to_bytes); }; # ... (中略)
これにより以下のように、バイナリフレームを送信することができるようになります。
- MyApp::Web::Dispatcher
get '/socket' => sub { my $c = shift; $c->websocket( sub { my $ws = shift; # バイナリフレームを作成して my $frame = Protocol::WebSocket::Frame->new( type => 'binary', buffer => $binary_strings, ); # 送信 $ws->send_message($frame); # ... } ); };
無駄にハマって解決できていないところ
手元の Mac では再現しませんが、Debian 上で実行するとなぜか LWP::UserAgent がすごい時間がかかる。
具体的には不自然に必ず30秒以上かかる。なんかタイムアウトを待っているみたいな。。。
そのせいで Net::Twitter::Lite を使った Twitter の認証に必要以上の時間がかかってしまい、困ったことになりました。
とりあえずの対処として、Net::Twitter::Lite が LWP::UserAgent ではなく Furl を使うように無理矢理パッチをあてました。
package Twincle::Auth::Site::Twitter; use strict; use warnings; use Furl; use Net::Twitter::Lite; sub import { no warnings 'redefine'; # "default_header" メソッドがないとエラーになるので申し訳程度に追加 *Furl::default_header = sub { }; my $orig = *Net::Twitter::Lite::new{CODE}; *Net::Twitter::Lite::new = sub { my ($class, %args) = @_; # UserAgent を LWP::UserAgent から Furl に差し替え $args{ua} = Furl->new; $args{legacy_lists_api} = 0; $orig->($class, %args); }; } 1;
LWP::UserAgent が遅い原因については据え置き中。
時間があるときに調べてみよっと。
まとめ
Amon2 の WebSocket サポートを使うと、すごく簡単に WebSocket を使うアプリケーションが作成できました。
バイナリデータを送受信するために改良した部分は、もう少し確認して本家の方へ pull request してみたいなぁと思います。
まだまだ追加したい機能はたくさんありますが WebSocket や Redis など、使ってみたかったものを使いつつ動くということで
わーい。
*1:きちんとログアウトしないと幽霊部員になる