NEXT、C3

僕はわりと好きかも。

by typester / at 2007-12-26T11:18:00 / perl / Comment

lighttpd+fastcgiで

fastcgiだけ再起動したい場合に、再起動中にアクセスあるとfastcgiプロセスが上がったあとも500になってしまうことがあるのだけど、みんなどうしてる?

by typester / at 2007-12-20T01:14:00 / lighttpd · perl / Comment

タグクラウドモジュール

いろいろあるけどなんでどれもこれもHTML作っちゃうんだろう。もっとシンプルなのほしい。hashで返してくれればいいよ。

とりあえず WWW::CloudCreator つかって

$c->stash->{tags} = [
    map +{
        name  => $_->[0],
        level => do { $_->[2] =~ /(\d+)pt/ },
        link  => $c->uri_for('/tag', $_->[0]),
        count => $_->[1]
    },
    grep {ref} $cloud->gencloud
];

こんなことして希望通りのものを作ってみてる。こういうのがほしいのだが。

上記の謎の grep {ref} はWWW::CloudCreatorがタグが空な場合空配列かえせばいいのになぜか空文字かえしてくるといううんこな実装なのでそれ対策。

by typester / at 2007-11-14T21:42:00 / perl / Comment

mobirc-irssi が実用に耐えうるようになりましたのでお知らせします

この間ちょっと紹介したirssiのプラグインスクリプトとしてmobircをつかうmobirc.plスクリプトですが、実用に耐えうる段階まできましたので再度紹介しておきます。

画面サンプルはこんな感じ。(スクリーンショットが取れるPSPでの画面です)

psp x mobirc x twirc

素のmobircはIRCクライアント機能と、HTTPD機能を両方持ち、tiarraなどのIRCプロクシにつなぐことで使用するものになっていますが、こちらのirssiプラグインではmobircのIRCクライアント機能はirssiプラグインとして実装していますので、irssiさえあれは利用することができます。

イメージ的にはirssiがHTTPDを立てている感じになってます。

またキーワード設定などもirssiのハイライト設定を使用していますので、別途mobirc側でキーワード設定をする必要がないのもちょっとうれしいところです。

実際の使い方(インストールの仕方)としては

  • mobirc.plをirssiのスクリプトディレクトリ (~/.irssi/scripts) にコピーor symlink

  • irssi起動時にmobircのlibパスを環境変数に入れとく

    PERL5LIB=/path/to/mobirc/lib irssi

    とか。同じ意味なら何でも。

  • irssi起動したらmobirc.plをロードする ( /script load mobirc )

    ここで Can't locate XXX.pm in @INC とか言われる場合モジュール足りないのでそれいれる。

  • ロードしたら config.yaml 自分用にいじって、そのパスをirssiで設定する

    /set mobirc_config_path /path/to/config.yaml

  • 設定完了したら /mobirc start すると HTTPD がたちあがる

  • mobirc started ってirssiコンソールに出てればOK。httpでつないで確認する。

とかでOK。

ほか機能としては、

  • /mobirc stop でhttpd停止。
  • /mobirc stop -> /mobirc start でyaml読み直してHTTPD再起
  • /set mobirc_auto_start on しておけば次回から /script load mobirc するだけでHTTPDたちあがる
  • /script load するのさえめんどいというひとはスクリプトを ~/.irssi/scripts におくかわりに ~/.irssi/scripts/autorun におけば irssi 起動時に自動起動する

という感じ。irssi使いには必須のスクリプトかと思います!

Enjoy!

by typester / at 2007-11-01T12:13:00 / perl · irssi / Comment

mobirc クールすぎる

mobirc 0.01 released - TokuLog 改め だまってコードを書けよハゲ

すばらしすぎる!

ソース見ると、IRCクライアント部分とHTTPD部分わかれてるから、IRCクライアント部分を丸々irssiプラグインで置き換えるのも簡単にできそう。

irssi使うようになってからtiarraみたいなプロクシを使わなくなったので、irssiプラグインだけでkeitairc見たいの作りたかったんだよなー。tokuhirom++

てわけで日本シリーズ見ながら作ってみた。

mobirc.pl

こんなんで一応動く。

irssiプラグイン内でPOEセッション(POE::Session::Irssi)作って、その中で Mobirc::HTTPD 動かしてる。

動くことは動くけど、設定決め打ちだし、unloadもできないのでプラグイン再起動イコールirssi再起動で、まだ実用には耐えない。

とりあえず動くことはわかったのであとは暇なときにでも。

by typester / at 2007-10-29T01:49:00 / perl · irssi / Comment

IRCで呼ばれたらIMで通知するirssiスクリプト

僕は以前からIRCでキーワード反応した時に GNU screen のステータスコードに通知を出すようにしている のだけど、ターミナル見てないときがつかないので、またまた im.kayac.com をつかって、IMに通知する irssi のスクリプトを書いてみた。

http://coderepos.org/share/browser/lang/perl/irssi/scripts/hilight2im.pl

使い方は

/set im_kayac_com_username ユーザー名

で自分のim.kayac.comユーザー名をセットするだけ!

あとはirssiで設定したキーワード(irssiではhilightという)を含んだメッセージを受信するとIMに通知される。

by typester / at 2007-10-20T15:30:00 / perl · irssi / Comment

ustreamの録画flvデータのURLを得るスクリプト

Clouder::Blogger: ustreamの録画した動画のflvをダウンロードする方法

これは想像ですが、swf内でhttp://gw.ustream.tv/gateway.phpをPOSTしているのはわかっているので、そこで取得しているのか、もしくはJavaScriptでAjaxをつかってどこかから取得しているのか、といったところだと思いますが、いずれにしてももう少し解析が必要です。

とあるのをみて、gateway.php を調べてみました。

これはFlashのAMFのRPCサーバーで、録画されたものを再生するときには client.watch_video という関数を呼んでいるようです。

as3で書くと

package {
    import flash.display.*;
    import flash.net.*;

    public class gw extends Sprite {
        public function gw() {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;

            var cid:String = stage.loaderInfo.parameters["cid"];
            if (cid) {
                var nc:NetConnection = new NetConnection();
                nc.objectEncoding = ObjectEncoding.AMF0;
                nc.connect("http://gw.ustream.tv/gateway.php");
                nc.call("client.watch_video", new Responder(gatewayHandler), { cid: cid });
            }
        }

        private function gatewayHandler(res:Object):void {
            for (var i:String in res) {
                log(i+": "+res[i]);
            }
        }
    }
}

こんな感じになります。cid は再生URL http://ustream.tv/recorded/RLdKCmCouWOpkkEznZH4QA とかの RLdKCmCouWOpkkEznZH4QA 部分です。

これをperlで呼ぶにはどうしたらいいか! ということでがんばってみました。

CPANにこのAPIのサーバー側の実装 (AMF::Perl) があったのでそれを適当に読んだり、実際API呼んでるときのパケットと見比べたりしつつして以下のようにすればできました。

#!/usr/bin/env perl

use strict;
use warnings;

use AMF::Perl;
use LWP::UserAgent;

my $cid = shift || '5Fq8cQp9eHsEEknbQ22OOZniqS2xUiuz';

my $amf = AMF::Perl::Util::Object->new;
$amf->addBody('client.watch_video', '/1', { cid => $cid });

my $outputstream = AMF::Perl::IO::OutputStream->new;
my $serializer = AMF::Perl::IO::Serializer->new($outputstream, 'utf-8');
$serializer->serialize($amf);

my $amfdata = $outputstream->flush;

$amfdata =~ s/\xff\xff\xff\xff/\0\0\0\x31\x0a\0\0\0\x01/;

my $ua = LWP::UserAgent->new;

my $req = HTTP::Request->new( POST => 'http://gw.ustream.tv/gateway.php' );
$req->content( $output );
$req->content_type('application/x-amf');
$req->content_length( length $amfdata );

my $res = $ua->request($req);

my $deserializer = AMF::Perl::IO::Deserializer->new(AMF::Perl::IO::InputStream->new($res->content), 'utf-8');

use YAML;
print Dump $deserializer->getObject->getBodyAt(0)->{value};

これで

---
err_desc: ok
server_id: 9
success: 1
user_id: 32983
video_length: 366.207
video_name: broadcast/35957/1191239239348
video_type: broadcast

とかいう出力がでます。これから

http://flash{server_id}.ustream.tv:18881/{video_name}.flv

というflvのURLが作れます。

perlソースの途中の謎の置換 s/\xff\xff\xff\xff/\0\0\0\x31\x0a\0\0\0\x01/; してて、これはなにかよくわかってません。ただ実際のパケットと見比べて違う部分置換してみたらいけたという代物です。

あとこれで得られるflvデータの音声部分が謎のcodecで変換できない! だれかこれをmp3とかにする方法ご存知のかたいましたらぜひともお知らせください!

by typester / at 2007-10-03T19:18:00 / perl · ustream / Comment

CatalystアプリのスタータースクリプトをCodeReposに

あげた。

もともと使ってるのはpmsetupを改造したので雛形つくるだけだったんだけど、毎回DBとか使うわけでもないので、ついでにそこを選べるように改造した。

ほぼ僕専用ルールにのっとった雛形を作成しますので他の方はまったく使えないと思いますが、参考にはなるかもしれません。

他の方のも見てみたいのでぜひともcodereposで共有しましょう!

あ、Catalyst自分規約カンファレンス、とかおもしろいかもしれない。

by typester / at 2007-09-13T16:48:00 / perl · catalyst / Comment

HTML::TreeBuilder::XPath + WWW::Mechanize なスクリプトを永続化させようとしてはまった

WWW::Mechanize でコンテンツとってきて TreeBuilder::XPath で解析するようなのを今まで単機能スクリプトなどでは便利に使っていたのだけど、それを永続的なプロセスで使おうとしたらメモリ使いまくってとんでもないことになったという話。

まずどんどんメモリが増えていくのでタイミングよく読んでいたjrockwayの記事などを参考に、

perl -MDevel::Leak::Object=GLOBAL_bless

付きでスクリプトを実行してみる。

少しソースをいじってまずはループを一回で止めるようにしたときの出力

Tracked objects by class:
Config                                   1
DBI                                      1
DBI::var                                 5
DBIx::Class::ResultSource::Table         1
DateTime::Duration                       2
DateTime::Format::Builder::Parser        3
DateTime::Format::Builder::Parser::Regex 10
DateTime::Infinite::Future               1
DateTime::Infinite::Past                 1
DateTime::Locale::en                     1
DateTime::TimeZone::Asia::Tokyo          1
DateTime::TimeZone::Floating             2
Encode::Internal                         1
Encode::utf8                             2
Errno                                    1
FileHandle                               3
HTML::Element                            1799
HTML::Element::_travsignal               5
HTML::TreeBuilder::XPath                 1
XML::XPathEngine                         1
XML::XPathEngine::Expr                   19
XML::XPathEngine::Function               6
XML::XPathEngine::Literal                9
XML::XPathEngine::LocationPath           4
XML::XPathEngine::Root                   1
XML::XPathEngine::Step                   9
utf8                                     2

つぎ、少しループしてから止めたときの出力

Tracked objects by class:
Config                                   1
DBI                                      1
DBI::var                                 5
DBIx::Class::ResultSource::Table         1
DateTime::Duration                       2
DateTime::Format::Builder::Parser        3
DateTime::Format::Builder::Parser::Regex 10
DateTime::Infinite::Future               1
DateTime::Infinite::Past                 1
DateTime::Locale::en                     1
DateTime::TimeZone::Asia::Tokyo          1
DateTime::TimeZone::Floating             2
Encode::Internal                         1
Encode::utf8                             2
Errno                                    1
FileHandle                               3
HTML::Element                            7378
HTML::Element::_travsignal               5
HTML::TreeBuilder::XPath                 4
XML::XPathEngine                         1
XML::XPathEngine::Expr                   19
XML::XPathEngine::Function               6
XML::XPathEngine::Literal                9
XML::XPathEngine::LocationPath           4
XML::XPathEngine::Root                   1
XML::XPathEngine::Step                   9
utf8                                     2

となって、TreeBuilderがなんかやばいことになってるくさい。

で、マニュアル読んでたら $tree->delete やれよ!って書いてあった。

TreeBuilderは明示的にdeleteメソッド呼ばないと綺麗になくならないらしい。たぶん常識なのだが、いままでやってなかったわぁ。。

これやったらずいぶんメモリ増えなくなった、でもまだなんか少しずつ増える。でも、Devel::Leak::Objectの出力は処理数あげてもかわらない。

あとはmechがあやしいなぁとおもって毎回newするようにしたらメモリ増えなくなったのであれれとおもってマニュアル見たら、デフォルトではヒストリを無限に記録していくらしい。

なので

WWW::Mechanize->new( stack_depth => 1 )

とかしたら大丈夫になった。これでとりあえず大丈夫かな。

まぁ結論としては、マニュアル読めということです。あと Devel::Leak::Object は簡単で便利。

by typester / at 2007-09-10T18:51:00 / perl / Comment

Class::Component

subtech - sexさんのブログ - Class::Component::Plugin の init()

こういうのは経験的にweakenったほうがいい希ガス。なんともいえませんが。

by typester / at 2007-08-22T17:55:00 / perl / Comment

5 6 7 8 9 10 11 12 13 14

(Page 9 of 30)