書き忘れたけどさっきの update_schema.pl は
./script/myapp_update_schema.pl dbi:mysql:tablename username password
見たいな感じで DSN を渡す必要がある。めんどう。
ここら辺があれでまだヘルパーにはなってない。
Schema::Loader 使い方
僕の中で流行ってる使い方があるのでかぶせて書いておいてみる。mizzy さんの二個目の例を自分ルール化させた感じ?
作業は一般的なCatalystアプリのディレクトリ構造上であるとして、そこに新しく schema というディレクトリを作成。
そんで、
- schema/lib/Schema/{TableName}.pm
に各テーブルのリレーション定義とかメソッドとかを自分で書く。実際にこのライブラリは Catalyst にロードされない。
上記ファイルを元に Schema::Loader の make_schema_at を使い
- lib/MyApp/Schema.pm
- lib/MyApp/Schema/*.pm
にコードを自動生成して、そちらをロードするという感じ。こちらのコードは自分では書き換えない。
コード自動生成は script/myapp_update_schema.pl にこんなのを書いてそれを実行している。
#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use File::Spec;
use lib File::Spec->catfile( $FindBin::Bin, qw/.. schema lib/ );
use DBIx::Class::Schema::Loader qw/make_schema_at/;
die unless @ARGV;
make_schema_at(
'MyApp::Schema',
{ components => ['ResultSetManager', 'UTF8Columns'],
dump_directory => File::Spec->catfile( $FindBin::Bin, '..', 'lib' ),
dump_overwrite => 1,
debug => 1,
},
\@ARGV,
);
@INC に schema/lib をくっつけてから make_schema_at してるだけ。ワンライナーでもできるけど見通しが悪いので。
これで普通の make_schema_at でつくられる Schema ファイルに自分で schema/lib/Schema/ 以下に書いた定義がくっついて出力されるという寸法。
Schema::Loader でダイナミックロードを使っていると各テーブルクラスにはリレーション定義やメソッド拡張のコードだけをかけばいいのでシンプルになって好きなんだけど、そうすると起動時のオーバーヘッドがあるし、ResultSetManagerがつかえなくていやんというときに、これだとまぁイイとこどりのような感じにできる。
実際にいじるファイルは schema/lib 以下のファイルで、それらのファイルを更新するたびに update.pl を実行するというのがあれだけどまぁ自動化できる。してないけど。
難点は、schema/lib 以下のファイルでsyntax errorがあっても何も言われないこと。
何も言われないというか、syntax error があるファイルは
# Loaded external class definition for 'MyApp::Schema::TableName'
ってのが出ないだけという。どこがエラってるのかとかがわからないので、がーーって書いてどこか typo してたりするとはまるかも。
X-Sendfile の逆がほしい
ファイルアップロードしたときに、サーバーが自動でどっかファイルに保存しつつ受信して、fastcgi にはファイルを渡さずファイル名を渡す。
結構でかいファイルだと Webサーバー <-> FastCGI 間のファイルデータのやり取りに時間かかってすげー無駄だ。
lighty が実装しねーかなぁ。
perlbal でできたりするのかな。
inflate_column + time_zone
んー
for my $date_column (qw/created_date modified_date/) {
__PACKAGE__->inflate_column(
$date_column => {
inflate => sub { DateTime::Format::MySQL->parse_datetime(shift)->set_time_zone('UTC') },
deflate => sub { DateTime::Format::MySQL->format_datetime(shift->set_time_zone('UTC')) },
}
);
{
no strict 'refs';
*{"$date_column\_for"} = sub {
my ($self, $user) = @_;
($user && $user->info && $user->info->time_zone)
? $self->$date_column->set_time_zone( $user->info->time_zone )
: $self->$date_column;
}
}
}
Yet Another IRC Gateway for Twitter
作った!
空前の Twitter - IRC ゲートウェイ作成ブーム。
ソースこの辺です。ライセンスは GPLv2。(たぶん。PoCo::Jabberのせいです。)
これの特徴は
- Jabber 使ってるのでリアルタイム性が高い
- nick に @ つけているのでクライアントによってはバグる
などです。
二個目は LimeChat でおかしくなることを確認。
まー僕の使ってる irssi で動けばいいのです。
irssi は nick の補完ができるので、@ をつけておけばいい感じで twitter 形式のレスができるってわけです。
使い方
- svn co
- yaml いじる (jabberアカウントと、IRCのポートとIRCクライアントの文字コード)
- ./script/twirc.pl
- IRCクライアントでつないで #twitter に join
あと、2で設定するjabber(or gtalk)アカウントはあらかじめtwitterで使えるように設定しておく必要があります。
Log::Dispatch::Config
Log::Dispatch は大好きなモジュールのひとつなんだけど、これだけだとイマイチ微妙。
Log::Dispatch::Config を使うことですげーー便利になる。必須。
miyagawa さんは 5 年以上も前にこれ作ったんだなぁ。
Catalyst で Log::Dispatch を使うの法
同僚から聞かれたので、僕のやり方を書いておく。
すでにCPANに Catalyst::Plugin::Log::Dispatch というのがあるのだけど、なんかいけてないのでそれは使わず、以下のようにしている。
まず MyApp::Logger とかいうのをかく
package MyApp::Logger;
use strict;
use warnings;
use Log::Dispatch::Config;
use Log::Dispatch::Configurator::YAML;
use Catalyst::Utils;
use NEXT;
{
package MyApp::Logger::Backend;
use base qw/Log::Dispatch::Config/;
}
sub setup {
my $c = shift;
my $class = ref $c || $c;
$c->log->_flush if $c->log->can('_flush');
my $config = $c->config->{log}{config}
|| $c->path_to( Catalyst::Utils::appprefix($class) . '_log.yml' );
MyApp::Logger::Backend->configure_and_watch(
Log::Dispatch::Configurator::YAML->new($config) );
$class->log( MyApp::Logger::Backend->instance );
$c->NEXT::setup(@_);
}
1;
んでこれをプラグインとしてロード。
use Catalyst qw/+MyApp::Logger/;
ログの設定ファイルを書く(デフォルトmyapp_log.yml)
---
dispatchers:
- file
- screen
file:
class: Log::Dispatch::File
min_level: debug
filename: /path/to/log
mode: append
format: '[%d] [%p] %m at %F line %L%n'
screen:
class: Log::Dispatch::Screen
min_level: debug
stderr: 1
format: '[%p] %m%n'
以上。
MyApp::Logger::Backend とかしてるのは mod_perl 対策。まーつかわんのだけど。
これ、さっきヘルパーにした。
これ使えば
./script/myapp_create.pl Log::Dispatch
すると Logger クラスとサンプルの yml ファイルを生成してくれる。
Catalyst + 外部認証API
今作ってるサービス。
use Catalyst qw/
...
Authentication
Authentication::Credential::Password
Authentication::Credential::OpenID
Authentication::Credential::TypeKey
Authentication::Credential::Hatena
Authentication::Credential::JugemKey
+MyApp::UserStore
...
/;
MyApp::UserStore は A::Store::DBIC のちょっとしたサブクラスで、Cred::Password のときは auto_create_user しないようにしただけのもの。
最近の Store::DBIC の auto_create_user 機能つかうと外部認証使うサービス簡単に作れる。
Cred::Password 使わないなら (独自ユーザーを使わないなら) 、Store::DBIC そのまま使えばいける。
すばらしいなー。
リリースしたらちゃんとした記事を書きたい。
YAPC の IRC の機械翻訳を lingr に投げ続けるスクリプト
YAPC 今年もきましたね! 楽しんでますか!
IRCあるけど英語わからんとか、日本語チャンネルあるけど日本語わからんとかいうひと用にIRCの機械翻訳をリアルタイムにlingrに流すスクリプトを作りました!
ソースはこんな感じ
http://svn.unknownplace.org/public/scratch/yapc_irc2lingr/irc2lingr.pl
