WebService::AudioscrobblerをCatalystのModelに

Catalystのモデルを書くの面倒だなーと思っていて、Catalyst::Model::LastFMがあると便利な気がしてたんだけど、微妙に放置してた。

が、Catalyst::Model::Adaptorを使ってみたをみて、コレだーって思った。

Catalyst::Model::Adaptor

$ script/drkcore_create.pl model LastFM Adaptor WebService::Audioscrobbler new

とやるだけで、WebService::AudioscrobblerがCatalystのモデルになる。らくちんだ。

last.fmのチャートを表示するようにしてみた。

おーblur意外に聴いてんな。On The Way To The Clubヘビーローテしてたからかな。

ProductName Think Tank
Blur
Virgin / ¥ 1,986 (2003-05-06)
通常24時間以内に発送

Catalyst本の第5章を読んだ

久しぶりに。

ProductName Catalyst: Accelerating Perl Web Application Development
Jonathan Rockway
Packt Publishing / 3545円 ( 2007-11-30 )


perlのスレッドでIPアドレス逆引き

昨日の続き

use strict;
use warnings;
use Socket;
use threads;
use threads::shared;
use Thread::Queue;

my $thread_num =10;
my %cache : shared;
my $DataQueue = Thread::Queue->new();

for (0..$thread_num){threads->create(\&getaddress);}

while(<DATA>){
  chomp;
  $DataQueue->enqueue($_);
}
for (0..$thread_num){$DataQueue->enqueue(undef);}

$_->join for threads->list;

sub getaddress {
  while(my $DataElement = $DataQueue->dequeue()){
    my $address;
    if ( $cache{$DataElement}){
      print "[cache] ",$cache{$DataElement},"\n";
    }
    else {
      ($address) =  gethostbyaddr(inet_aton($DataElement),AF_INET);
      if ($address){
            print "$address\n";
            {
              lock %cache;
              $cache{$DataElement} = $address;
            }
      }
      else {
            {
              lock %cache;
              $cache{$DataElement} = $DataElement;
            }
            print $DataElement, "\n";
      }
    }
  }
}
__DATA__
222.228.235.193
157.113.18.68

これで結構オッケーなんだけど、アクセスログだとIPアドレスが連続してるのでキャッシュされてない且つ逆引き出来ないアドレスが続いてるとすべてのスレッドがそのアドレスを問い合わせにいってしまって遅かったりする。

どれかのスレッドが問い合わせ中のアドレスは問い合わせにいかないというような処理を入れたくなったけど、どういう風にしたらよいのかわからない。

perlでスレッド処理

javaの入門書を読んでいたら突然スレッド処理が気になりだした。そういえばどう書くにスレッド処理の問題あったな。

あった

  • ログを順次読み取り処理する部分を,データを共有しつついかに並列化するか

pythonだとthreadingとかtwisted使った解答があって参考になった。というかtwistedは興味があるけどよくわからん。今度また改めて。で、thread使ったperlの解答がなかったので少し考えてみた。初めてのthreadプログラミング。

use strict;
use warnings;
use Socket;
use threads;
use Thread::Queue;

my $DataQueue = Thread::Queue->new();
my $thr1 = threads->create(\&getaddress);
my $thr2 = threads->create(\&getaddress);
my $thr3 = threads->create(\&getaddress);
my $thr4 = threads->create(\&getaddress);

while(<DATA>){
  $DataQueue->enqueue($_);
}
$DataQueue->enqueue(undef);
$DataQueue->enqueue(undef);
$DataQueue->enqueue(undef);
$DataQueue->enqueue(undef);
$thr1->join();
$thr2->join();
$thr3->join();
$thr4->join();

sub getaddress {
  while(my $DataElement = $DataQueue->dequeue()){
    my ($address) =  gethostbyaddr(inet_aton($DataElement),AF_INET);
    print "$address\n" if $address;
  }
}
__DATA__
74.6.16.244
203.104.98.219
219.111.208.65

ログの順次読み取りはThread::Queueをつかってキューに突っ込みつつそれぞれのスレッドがdequeueをしながら必要なデータをとってくようにすればよさげだけど、終了のさせ方がいまいちアレ。これだとスレッド生成の数だけundefをqueueに突っ込まないと終わらないですよな。

あとキャッシュを共有化してDNSサーバの負荷を軽減させないといけない。ロックかけないといけないのかな。perlthrtutあたりをじっくり読む必要があるな。

ProductName WEB+DB PRESS Vol.42
相馬 純平
技術評論社 / ?円 ( 2007-12-22 )


WEB+DB PressのPerlスレッドプログラミングのところもかなり参考にした。というかこの号は色々読みどころが多くて好きだ。

IO::Allでircクライアント

telnetでしゃべらナイトってことで、

telnet hostname 6667

で会話をしてみた。ついでにIO::Allでもやってみた。

my $io = io("192.168.xxx.xxx:6667");
$io->print("NICK test\n");
$io->print("USER test 192.168.xxx.xxx 192.168.xxx.xxx test\n");
$io->print("JOIN #info\n");
$io->print("PRIVMSG #info : hello irc!\n");
$io->print("QUIT\n");

ログインして一言なんか申して去っていく感じのクライアント

論文からdoiを抜き出すperlのサンプル

文献はpdfを自作のイントラソーシャルブックマークサービスっぽいのを使って管理しているのだけど、pubmedにのるよりもペーパーの方が早かったりすることのほうが多く、pmidをつけることが出来なくてもどかしい思いをしてばかりいる。

use strict;
use warnings;
use CAM::PDF;

my $pdfname = $ARGV[0];
my $pdf = CAM::PDF->new($pdfname);
my $page1 = $pdf->getPageContent(1);
my ($result) = $page1 =~ m!\d+\.\d+\/.+?(?=\))!gx;
print $result if $result;

抽出したdoiをeutilsに問い合わせて、あとは適度な塩加減を加えつつゴニョルとよさげ。

で、そのソーシャルブックマークサービスはpmidをプライマリキーにしてるもんだから始末に負えない、というかそのうち、匠的にリフォームする気概で、今日もだましだまし使った。

IPアドレスを24ビットカラーに

Image::Identiconを参考にした。

use Digest::SHA qw(sha1);
my $ip = "172.16.84.33";

my $num = join '', split /\./, $ip;

my $code = unpack("N",sha1($num));

my $blue  = (($code >> 6) & 0x0ff);
my $green = (($code >> 15) & 0x0ff);
my $red   = (($code >> 24) & 0x0ff);

print $blue,",",$green,",",$red;

saltをまぶしたほうがよいのかな。

Catalyst本の4章

4章は3章でつくったアドレスブックに色々つけていく

ProductName Catalyst: Accelerating Perl Web Application Development
Jonathan Rockway
Packt Publishing / 3404円 ( 2007-11-30 )


セッションと認証を入れて、検索とページングを実装。

検索以外はdrkcore作るときにやったのをちゃんと覚えてたので流し読み。検索はDBICのクエリの作り方が参考になった。今度これにも実装してみよう。

Catalyst本の三章をやった

久しぶりにCatalystを触った気が。

ProductName Catalyst: Accelerating Perl Web Application Development
Jonathan Rockway
Packt Publishing / 3404円 ( 2007-11-30 )


3章はC::C::FormBuilderとかTTSiteを使ってちょっとしたアドレスブックを作って見ましょうぜという章。

DBICでcascading_deleteを設定すると親子関係のあるデータが一緒に消してくれるとか。なんで今まで見つけられなかったんだろうか的な内容があったりとかで、写経にしては結構楽しめた。

ただ、FormBuilderのあたりとTTSiteの埋め込みのコードが間違っているので注意

flickrの上限いったのでどうしようかと悩んでいる

flickrにパスタの写真を置いたら200枚超えた。これ以上は有料らしい。うーん別にproアカウントにしてもいいんだけど、サーバー立ててるからそっちで管理するようにしてもいいんだよなー(blosxom使ってたときみたいに)。

で、なぜflickr使ってたんだろかって思い返してみると、flickr uploaderはドラッグドロップするだけでいいから便利だったんだと。

つまり、ドラッグドロップできるクライアントを書けばいいんじゃないかってことだ。wxpythonかAIRでやってみれっていう神のお告げに違いない!早速flex3を入れてみたらfcshが同梱されていた。

さらに、ここはひとつCatalyst::Controller::Atompubと組み合わせるべきかもな気がしてきた。

とぅるっとぅー(だっけ?今朝の目覚ましでやってたのは)

といってもDrkcoreにはCatalyst::Plugin::AtomServerを使っていたのだった。

さてこれもどうしようかなぁ。