やることリスト
- trackback ping打てるようにしとく
- Tagのサジェスト機能をつける
- 二重投稿を防ぐ
やることリスト
昨日ちょっと気になったので触ってみた。
ヘルパーがあるので
script/myapp_create.pl create model Net::Amazon Net::Amazon
でモデル作成。yamlに
Model::Net::Amazon:
token: 'amazon_token'
locale: 'jp'
を設定して、Root.pmに
sub default : Private {
my ( $self, $c ) = @_;
my $ua = $c->model('Net::Amazon');
my $response = $ua->search( asin => '4873112109' );
if ( $response->is_success ) {
$c->response->body( $response->as_string );
} else {
$c->response->body( $response->message );
}
}
で、ルートにアクセスすると
[1] マーク ルッツ/デイビッド アスカー, "初めてのPython 第2版", 2004, ¥ 5,040, 4873112109
と表示される。あとは/ASIN/XXXXXXのURLでJSON返すようにすればMochikit(javascript)からいい感じで扱えるはず。うーんナイス!
さらに、Net::Amazonはキャッシュが使えるのでCatalyst::Model::Net::Amazonでもキャッシュを効かせたい。C::M::Net::Amazonに直接書いた。
use Cache::File;
use base qw/ Catalyst::Model::Net::Amazon /;
my $cache = Cache::File->new(
cache_root => '/tmp/amazon_cache',
default_expires => '30 min',
);
__PACKAGE__->config(cache => $cache);
Net::AmazonがCache::Fileオブジェクトをとるので、このようにModelに直接書いたのだけど、cache_rootとかdefault_expiresを設定ファイルに追い出すことはできないのだろうか?
blosxomでいうところのawsxomみたいなのが欲しいんだけど、コントローラーからNet::Amazonを使ってASIN:XXXXXXっていう部分を直接書き換えるようにするのがいいのか、それともCatalyst::Model::Net::AmazonのModelと適当なクラス名を用意して、Javascript+JSONで扱ったほうがよいのだろうかと考えていた。
後者だとMochikitでいろいろやれそうな感じになってよさげな気がするが、後で試してみよう。
個別のエントリのページでタイトルがエントリータイトルでなくDrkcoreとなっている部分を修正。あと、新規投稿をCtrl-.に変更。ちなみにDrkcoreはDrum'n'Bassのダークコアからとったわけですなこれが。
今回さらに、ピコピコ押す感がちょっと楽しげなはてなスター付けてみた。
はてなスター日記みながら、
Hatena.Star.headerTagAndClassName = ['h2','entry-title'];
で上書きかませばいいらしいんだけど、なんか上書きされてナイっぽい。
ので、Hatena.Star.EntryLoader.loadEntriesを上書きしたらOK。というより、サンプルちょこちょこといじって済ませた。かなりやっつけ。
Hatena.Star.Entry.Drkcore = new Ten.Class({
initialize: function(doc) {
this.doc = doc;
var h2 = doc.getElementsByTagName('h2','title')[0];
this.title = Ten.DOM.scrapeText(h2);
var widget = \
Ten.DOM.getElementsByTagAndClassName('div','widget_bottom',doc)[0];
this.uri = widget.getElementsByTagName('a')[0].href;
this.comment_container = \
Hatena.Star.EntryLoader.createCommentContainer();
h2.appendChild(this.comment_container);
this.star_container = Hatena.Star.EntryLoader.createStarContainer();
h2.appendChild(this.star_container);
}
});
ただ、comment_conteinarとstar_conteinarをDOMの好きなところにぶら下げれば別にタイトルの隣じゃないところに持っていくことができるな(コメント欄とか)。
個別のエントリのタイトルのとこが変だ。
あとで直す。
あと、Ctrl-cで新規入力はコピペがしにくくなるので駄目だった。キーの割り当てを変える。
CatalystでTT使ってRSS2.0のフィードを吐き出したかったんだけど、datetimeのあたりでRFC822のフォーマットで時刻を出力しないといけないらしい。
都合のいいプラグインがみつからなかったので、Template::Plugin::DtFormatterを使って。
[% USE DtFormatter(patterns => { 'rfc822' => '%a, %d %b %Y %H:%M:%S %z', time_zone => 'Asia/Tokyo' }) -%] ... <pubDate>[% DtFormatter.format(ub.clip_time, 'rfc822') %]</pubDate>
フォーマットはDateTime::Format::Mailを参考に。
TT使わないでXML::Feedを使ったほうが良いのかな?
わからん。
タグのテーブルなんかでタグをカウントしてtagname(count)とか出力したいときにDBICだとどうやんのかな?と。
http://5net.com/blog/2006/11/dbic_count_order_by.html
$c->stash->{t_it} = $c->model('DBIC::TableName')->search( $query_ref, { select => [ 'user_id', { count => 'user_id' } ], as => [qw/ user_id posts_count /], group_by => ['user_id'], order_by => 'count(user_id) DESC', }, );
とasを指定しておけば、TTのほうで
t.get_column('posts_count')
でカウントが表示できる。
タグの名前とカウント数を表示させたい場合にはこのままTTでいいと思うが、タグクラウドにしたい場合は、コントローラーでHTML::TagCloud::ExtendedとかHTML::TagCloud を使ったほうがいいのかもと。
あとYAPCのチケットとった。DBICネタが密かに楽しみだったり。
ありがたい。色々勉強になりました。
Hatena::Diary::Neko::kak 500 Internal Server Error - CatはしらんけどSledgeなら
基本コントローラーでRSを作りまくってstashにぶち込みまくって Viewの方で実際にクエリを実行する感じですね。
というわけでcookbookみながら悩んでみた。いじってるのは、こんな感じのテーブルなので、
user_bookmarksテーブルに対してイテレータをまわすことにした。 あとcatlystだとautoっていう最初(のほうに)に呼ばれるメソッドがあるので、そこにユーザーが存在するかどうかのバリデーション書いた。
sub auto : Private { my ($self, $c, $action, $username) = @_; $c->stash->{user} = $c->model('PblDB::User')->single({name => $username}); unless (defined($c->stash->{user}) || $c->req->path =~ m!^bookmarks/?$!) { $c->response->redirect($c->uri_for('/')); return 0; } return 1; } sub default : Private { my ( $self, $c ) = @_; $c->stash->{user_bookmark_it} = $c->model('PblDB::UserBookmark')->search( {user_id => $c->stash->{user}->id}, { prefetch => [qw/user bookmark/], join => [qw/user bookmark/], order_by => 'me.id DESC' } ); }
あと、ユーザーバリデーションしてる件に関しては、
livedoor クリップ - Hatena::Diary::Neko::kak 500 Internal Server Error - CatはしらんけどSledgeなら
個人的には、バリデーションでユーザがいるかどうかはチェックしないなー。 そこでユーザの存在がわかっちゃうとあれかなと。まぁ、場合によるね。
とか
ってやった場合に、ユーザがいない場合にそんなメソッドがないよってエラーになっちゃうので、バリデーションしたというのが経緯なのだが、join使えば、
sub default : Private { my ( $self, $c, $action, $username ) = @_; $c->model('PblDB::UserBookmark')->search( {'user.name' => $username}, { prefetch => [qw/user bookmark/], join => [qw/user bookmark/], order_by => 'me.id DESC' } ); }
と書けばよいのでこれでもいいかもしれんと思った。
あと、実際のサービスでそういった場合の処理はどうしてんのかなと気になったので僕が使っているSBSで調べてみた。
ふむー。
かなりボケボケだった。
こういうことらしい。
DBIx::Class::Relationship - Inter-table relationships - search.cpan.org
PACKAGE>$method_name('relname', 'Foreign::Class', $cond, $attrs);
というわけで、こんな感じの理解で。
__PACKAGE__->belongs_to(アクセサ名(任意) => '従うクラス','従うクラスのIDを持つ属性名'); __PACKAGE__->has_many(アクセサ名(任意) => 'クラス','自分のクラスのIDをもつ属性名'); __PACKAGE__->many_to_many(アクセサ名(任意) => 'has_manyでのアクセサ名','belongs_toでのアクセサ名');
データベースを指しているのかクラスを属性を指してるのか良く分かってなかった。というかO/RマッパーでDBのカラム名っておかしいよって何で気づかなかったんだろう。
なんとなくこんな感じか。
31032006 Catalyst
この前書いたのイマイチ かつYAPCのCatalyst話参考になったので、早速書き直してみた。
__PACKAGE__->config( tagcloud =>{ levels => 10, limit => 3 } );
な感じでレベルとリミット設定できるようにした。
でも、実際に使ってみると、
sub default : Private { my ( $self, $c ) = @_; my $tags = [ {tag=>"tag1",url=>"url1",count=>5}, {tag=>"tag2",url=>"url2",count=>15}, {tag=>"tag3",url=>"url3",count=>8}, {tag=>"tag4",url=>"url4",count=>20}, {tag=>"tag5",url=>"url5",count=>3}]; my $html = $c->create_tagcloud($tags,"html_and_css"); # Hello World $c->response->body( $html ); }
みたいに配列のリファレンスを用意しないといけないのが駄目ゲ?セーフゲ?わからん。
な感じで、やりかけだけど、ココから落とせます。もっと、小洒落たやりかたがあれば指摘してもらえると助かります。