maaash.jp

what I create

nodejsのrequestでログをはく

nodejsを使っているみなさまは http requestを簡単に発行するために https://github.com/mikeal/request を使っていると思いますが、

そのソースを読んでいると、ふと以下のような行が目にとまりました。

if (process.logging) {
  var log = process.logging('request')
}
... 中略
if (log) log('%method %href', self)

ところが process.logging の痕跡はどこにもありません。

ということで、 log 関数に渡している引数を眺めて、以下のようなロガーをこさえてみました。

こんなログを吐きます。

// require('request').get( "http://google.com/" );
[request] GET http://google.com/
[request] Redirect to { protocol: 'http:',
  slashes: true,
  host: 'www.google.com',
  hostname: 'www.google.com',
  href: 'http://www.google.com/',
  pathname: '/',
  path: '/' }
[request] GET http://www.google.com/
[request] Redirect to { protocol: 'http:',
  slashes: true,
  host: 'www.google.co.jp',
  hostname: 'www.google.co.jp',
  href: 'http://www.google.co.jp/',
  pathname: '/',
  path: '/' }
[request] GET http://www.google.co.jp/

お手軽かも

zshのregionからpbcopy

zshでCtrl+A,F,B,Eでカーソル移動して
Ctrl+Spaceで範囲指定して
Ctrl+Wでクリップボードにコピーしたい

x-copy-region-as-kill () {
  zle copy-region-as-kill
  REGION_ACTIVE=0
  print -rn $CUTBUFFER | pbcopy
}
zle -N x-copy-region-as-kill
bindkey '^W' x-copy-region-as-kill

NinNin – casual background processing for perl

https://github.com/mash/NinNin というのをつくった。

よくGearman::Workerを使うんだけれど
gearman-starter.plのようなもので
gearmanのworker poolをつくっていて
裏(gearman worker)で動かしたいコードと、
httpリクエストを同期的に処理してるコードの場所が離れるから行ったり来たりしたりするのが嫌だったりする。

もっとカジュアルに裏にまわしたい!

ということで、subroutine referenceを渡すと裏に回してくれるのが NinNin (ニンニン)。

予めgearman worker poolを用意しておけば

NinNin->setup({
  backend => NinNin::Backend::Gearman->new({
    job_servers => [ '127.0.0.1:4730' ]
  })
});

って感じでbackendを指定しておき、
ちょっと時間かかるかもしれないから裏に回したいってコードがあったら

ninnin(
  sub {
    my (@args) = @_;
    # run in gearman worker
    # ...heavy work...
  },
  (@args) # argument for sub
);

のようにして裏に回す。

my $coderef = ninnin( sub { ... } );
$coderef->( @args );

インターフェースは↑の方がいいかも、とtypesterは言った。

実装は
B::Deparse でsubroutine referenceからソースコードに戻して、
ソースコードと引数をまとめてjobにして、

evalしてsubrefを取り出して引数を渡して実行するものを register_function しておく、という感じ。

evalするところでimportしてるのが見えなくなったり、行番号がおかしかったり、その辺大変そうだけど、いいんじゃない?

FaceDetection – Integral Image

昨日、Flashや画像や音声やらいろいろ強い人とお会いするきっかけがあり、
今まで話したことが無かったので
Marilena (OpenCV顔認識のas3実装)をつくった時に感動した、
Integral Imageというアルゴリズムについて話しました。

一文で説明すると、
二次元配列で表されるデータがある時に(この場合は顔検出する対象の画像の明るさ)
二次元配列の中の矩形範囲のデータの合計を、高速に求める手法です。

発表資料を置いておきますのでよろしければ
integral_image_opencv_face_detection.pdf

計算してみるためのスプレッドシート
Integral Image Calculator

こちらの方がわかりやすいかもしれません
integral imageについて調べた

資料の中に数式が入るとどや顔の度が増しますね なおやんは寝てましたけど

UINavigationController pushViewControllerしてpopViewControllerした時のUIViewControllerのメソッドの呼ばれ方

今さらながらmemo

RootViewControllerがapp.navigationControllerの先頭にある

2011-05-28 21:23:43.771 navcontrollertest[12548:207] RootViewController/viewDidLoad
2011-05-28 21:23:43.773 navcontrollertest[12548:207] RootViewController/viewWillAppear:
2011-05-28 21:23:43.775 navcontrollertest[12548:207] RootViewController/viewDidAppear:

そこにSecondViewControllerをpush

1
2
3
SecondViewController* c = [[SecondViewController alloc] initWithNibName: nil bundle: nil];<br />
[ self.navigationController pushViewController: c animated: YES ];<br />
[ c release ];<br />

2011-05-28 21:23:47.191 navcontrollertest[12548:207] SecondViewController/viewDidLoad
2011-05-28 21:23:47.192 navcontrollertest[12548:207] RootViewController/viewWillDisappear:
2011-05-28 21:23:47.192 navcontrollertest[12548:207] SecondViewController/viewWillAppear:
2011-05-28 21:23:47.548 navcontrollertest[12548:207] RootViewController/viewDidDisappear:
2011-05-28 21:23:47.549 navcontrollertest[12548:207] SecondViewController/viewDidAppear:

backボタンを押した

2011-05-28 21:23:53.395 navcontrollertest[12548:207] SecondViewController/viewWillDisappear:
2011-05-28 21:23:53.396 navcontrollertest[12548:207] RootViewController/viewWillAppear:
2011-05-28 21:23:53.749 navcontrollertest[12548:207] SecondViewController/viewDidDisappear:
2011-05-28 21:23:53.750 navcontrollertest[12548:207] RootViewController/viewDidAppear:
2011-05-28 21:23:53.751 navcontrollertest[12548:207] SecondViewController/dealloc

viewDidUnloadは呼ばれないが、deallocはちゃんと呼ばれている。

how twitter @anywhere works

ということでOAuth2のImplicitGrant方式(または古いドラフトではUserAgent方式)ってのはどうなってるのか実例を見ようと、twitterの@anywhereのJSのソース(http://platform.twitter.com/anywhere.js)を読んでみた。

JSがminifyされてるので JsDecoder で読みやすくしたり ChromeのDeveloper ToolsでどんなURLにアクセスしてるのか見てさらに掘り進んでいったり。

blog.twitter.comに@anywhereがはいってるのでそこで確認してみた。

  1. @Twitter にマウスオーバーするとオーバーレイが出て「フォローする」ってボタンがある
  2. それを押すとポップアップが開き、oauth2の、Clientを認証するか?って聞くダイアログが出るっぽいURL(https://oauth.twitter.com/2/authorize?oauth_callback_url=&#8230;%E7%95%A5%EF%BC%89%E3%81%A0%E3%81%8C%E3%80%81%E3%81%BE%E3%81%9A%E3%81%AFTwitter%E3%81%AB%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AETwitterID(またはメアド)とパスワードが聞かれるフォームが表示される、ただしsubmitボタンが「連携する」になってる
  3. 「連携する」を押すと、リダイレクトされ、#以降に何やら入っているURLがちらっと表示された後に、ポップアップが閉じる
  4. 何事もなかったかのようだが、もう一度 @Twitter にマウスオーバーすると、「フォローしている」と表示される

ここでおもむろにConsoleで localStorage.twttr_anywhere とうつと、なにやらtokenがあるようだ。 localStorage.twttr_anywhere_expiry というのもあって、2時間の有効期限を表して自分で無効化したりするのかな

@Twitterをフォローするリクエストは、これを使って行なわれたようだ。iframe使ったクロスドメインかな Chrome Developer ToolsのNetworkタブに履歴が残っていたのでそれを再現すると、こんな感じ。

OAuth2のaccess_tokenのような権力をもつtokenだがAuthorizationヘッダが必要な何かみたい。

ということで、JSのみでaccess_tokenとってきたらlocalStorageにいれておいてあって、 それをフォローしたりするリクエストで使っていることがわかりました。 localStorageは

User agents must raise a SECURITY_ERR exception whenever any of the members of a Storage object originally returned by the localStorage attribute are accessed by scripts whose effective script origin is not the same as the origin of the Document of the Window object on which the localStorage attribute was accessed.

http://dev.w3.org/html5/webstorage/#security-localStorage

だからaccess_tokenをAuthzサーバからClientにリダイレクトしてきたURLの#から誰よりも早く取り出して、 localStorageに保存して、 他のスクリプトからは取れなく(window.closeなど)すれば 安全だってことでいいのかな?

yokohama.pm #7行ってきた

今日来てた人たちのモジュールやコードを使わせていただいているなー、
っていろんな人の顔を見ながら思った!

発表資料
yokohama.pm slide ナカマップのなにか

最後の方のコードはいろいろおかしいので参考になさらないほうがよいでしょう。
でもSocket.IOはクライアント側すごく短くかけてドメイン超えれるし魅力的だなー
なんとかしたい

なんとかしようと思ったときに、
Authorization Code方式(またはImplicit Grant方式)でaccess_token取得した後に、
そのaccess_tokenをSocket.IOのJavaScriptクライアントに渡せるとよいが、どういう経路で安全に渡すことができるんだろう。

Twitterの@anywhereのドキュメントには、
“` The higher the anywhere.js file is on the page, the sooner it can process the access token.
[/code]
ってある。

OAuth2のImplicit Grant方式では
Authorization Serverからリダイレクトされてきた時にaccess_tokenが#フラグメント以降に入ってるんだけど
それを他のJavaScriptコードとかから読み取られる前(最初のscriptタグ)にanywhere.jsがあれば
安全ってことなのかな?

上の方にanywhere.js置いてね、って書いてあるけど
スクリプト設置した人が下の方においたら、htmlの上から設置場所までの間にxssでなんか仕込めたらTwitterのaccess_tokenとられちゃうんだよね?

access_tokenの有効期限が短いってことだけどそれでいいのかな?

で@anywhere使ってTwitter認証してリダイレクトされてきたらTwitterにログイン状態で
@anywhereの貼ってあるページ上で誰かをフォローできる、ってことは
access_tokenなのか同様の力を持つものがブラウザにCookieなりlocalStorageなりで保存されてるってこと?
CSRF対策用のトークンみたいなワンタイムな感じなのかな?

わからないことが多すぎる><
anywhere.js を読んでみよう

Math::Random::MT benchmark

randのばらつき方が均等になる、という理由でMath::Random::MTが使われているようです。(身近で

macにXS版を入れようとすると

1
2
3
4
5
6
7
8
9
10
11
12
In file included from _mt.c:1:<br />
mt.h:17: error: expected specifier-qualifier-list before ‘uint32_t’<br />
mt.h:21: error: expected ‘)’ before ‘seed’<br />
mt.h:22: error: expected ‘)’ before ‘*’ token<br />
_mt.c:17: error: expected declaration specifiers or ‘...’ before ‘uint32_t’<br />
_mt.c: In function ‘mt_init_seed’:<br />
_mt.c:20: error: ‘uint32_t’ undeclared (first use in this function)<br />
_mt.c:20: error: (Each undeclared identifier is reported only once<br />
_mt.c:20: error: for each function it appears in.)<br />
_mt.c:20: error: ‘mt’ undeclared (first use in this function)<br />
_mt.c:22: error: ‘struct mt’ has no member named ‘mt’<br />
_mt.c:23: error: ‘seed’ undeclared (first use in this function)<br />

っていうようなエラーがでてmakeがこけるところは、

1
2
3
4
5
6
7
8
9
10
#if defined(_MSC_VER) && (_MSC_VER < = 1300)<br />
typedef unsigned __int32 uint32_t;<br />
#elif defined(__linux__) || defined(__GLIBC__) || defined(__WIN32__)<br />
#include <stdint.h><br />
#elif defined(__osf__)<br />
#include <inttypes .h><br />
#else<br />
#include <sys /types.h><br />
#endif<br />
</sys></inttypes>

このifdefがうまくいってないようだったのでとりあえず

1
#include <inttypes.h>

と手で書いてあげたりするとうまくmake && make testが通るようになりました この辺はどう書くのが鉄板なんでしょうね?

ということでベンチマーク

ここがボトルネックになることはあまり無いとは思いますが。

iTunesの重複曲を削除する – perl

家のPCのWindowsを入れなおすついでに家のiTunesとmacbookのiTunesの中身を同期しようと思い、何も考えずにiTunesのホームネットワークに追加して曲をコピペしたら大量に重複曲ができていっこいっこ手で削除するなんてめんどくさくてできない場合の話。

iTunesには「重複する項目を表示」って機能はあるのに重複してる曲を削除する、っていう便利機能は無い。

ただし、同じアーティスト名、同じアルバム名(つまり同じディレクトリ)の同名曲は、 ファイル名の末尾に数字をつけてincrementしていく、ってルールでコピーしてきたファイルを置くようだ。

そこで、perlで重複曲を削除してみる

1
% perl remove-duplicate.pl /Users/mash/Music/iTunes/iTunes\ Media/Music/<br />

って実行すると重複してるっぽい曲だけ消してくれる

その後、実体が無いけど曲のリストがあるiTunesを開き、上から順に →カーソルキー を押しっぱなしにしたりすると

のようにびっくりマークがつくので、表示項目に「追加日」を追加して、 びっくりマークを目印に、複数選択しながら消していくとまあ許容できるめんどくささになった

1
Term::Prompt

がなんか楽しくて意味もなく “really?” とか聞くちょっとしたスクリプトを書く今日このごろ

PS. iTunes Music Library.xml をいっしょに編集したりすればもっと簡単なのかもしれない

daemontoolsのmultilogでエラーだけ抜き出す

ここ: multilogによるログ収集 を読みましょう

この設定は: - t: タイムスタンプつける - 全部の行をこのrunスクリプトのあるディレクトリに吐く ファイルサイズ最大16MBで100世代まで - [error]の含まれる行のみを errorsディレクトリ以下に吐く ファイルサイズ最大16MBで100世代まで

1
svc -u /service/app/log<br />

ってするとmultilogが立ち上がって、runスクリプトのあるディレクトリ、errorsディレクトリにcurrentって空のファイルができる

appのログに[error]の含まれる行が出てきたら、 errors/current ってファイルに書き込まれるので、 errors/current ってファイルを監視してれば眠れない夜になったりならなかったり

1
svc -a /service/app/log<br />

ってするとログローテーションされてcurrentはまた空ファイルになるのでいらっとしたらこれ。