Archive for 6月, 2009

jQuery + Bing APIで動画検索するコード書いてみた

Bing APIでjsonpを使って動画検索するコードを書いてみた。個人的にはちょっと使えないかもなーって感じだったのだけどせっかくなのでまとめて公開してみる。
まずBing APIを使うにはアプリケーションIDが必要になる。下記のCreate an AppIDってとこから取得できる。Live IDが必要になるが簡単にとれる。
http://www.bing.com/developers/
とったアプリケーションIDをクエリのパラメータに含めることになる。API Basicってドキュメントの終わりの方にやんないといけないこと、やっちゃいけないこととか書いてあり、その中にリクエストはIPごとに1秒間に7回以下に抑えろとある。このアプリケーションIDとIPで計測されたりするのだろう。

Restrict your usage to less than 7 queries per second (QPS) per IP address. You may be permitted to exceed this limit under some conditions, but this must be approved through discussion with api_tou@microsoft.com.

IPごととか言われると、サーバサイドでやるよりクライアントサイドでやった方がいいよね。って話になるので今回はjsonpを使う。
まずjQueryにjQuery.ajaxライクなbing関数を拡張。

/*
* jquery.bing
*
* Copyright (c) 2009 makoto_kw (makoto.kw@gmail.com)
* Dual licensed under the MIT and GPL licenses.
*
* Version: 1.0
*/
(function($) {
$.extend({
/* options = {
*	appId: 'xxxxx',
*	query: 'sushi',
*	sources: 'web',
*	offset: 0,
*	count: 10,
*	callback: function(data){}
*	}
*/
bing: function(options) {
var sources = options.sources || 'web';
var params = {
AppId: options.appId,
query: options.query,
sources: sources
}
if (sources.indexOf('+')==-1) {
params[sources+'.offset'] = options.offset || 0,
params[sources+'.count'] = options.count || 10
} else {
// TODO:
}
// video
if (sources.indexOf('video')!=-1) {
params['video.sortby'] = options.video_sortby || 'Relevance'; // Relevance or Date
}
$.getJSON('http://api.search.live.net/json.aspx?Jsontype=callback&Jsoncallback=?', params, options.callback);
}
});
})(jQuery);

一応こんな感じで使う。callbackではBing APIのレスポンスを特に整形していないまま渡す。ちなみにリクエスト先はhttp://api.search.live.net/になっていて、bingってブランドはついてるけど実際にはlive searchのmajor version upって扱いかな。

$.bing({appid:\'Your AppID\', query:\'sushi\',callback:function(data){
//
});

で、動画の検索をするときはsourceにvideoを指定する(デフォルトはweb)。特定の動画サイトで検索する場合はクエリに(filterui:msite-nicovideo.jp OR filterui:msite-dailymotion.com OR filterui:msite-youtube.com)を追加すればよい。
フォームと合わせてサンプルを書いてみる。

<table><tr><td width="100%">
<p>bingで動画検索</p>
<form id="search_form" method="POST">
<input id="search_keyword" name="search_keyword" value="Janne Da Arc"/>
<select id="sortby" name="sortby">
<option value=Relevance>Relevance</option>
<option value="Date">Date</option>
</select>
<input type="submit" value="SEARCH"/>
<br style="clear:both"/>
</form>
<div id="search_results"></div>
</td>
<td width="200"></td></tr></table>
<script>
(function($) {
$(document).ready(function(){
var $form = $('#search_form'), $input = $('#search_keyword'), $results = $('#search_results');
var $sortby = $('#sortby');
$form.bind('submit', function() {
$form.find('.error_list').remove();
var keyword = $input.val();
if (keyword=='') {
$form.prepend('<ul class="error_list"><li>キーワードを入力してください</li></ul>');
return false;
}
$results.html('<div class="video_loading">NOW LOADING...</div>');
$.bing({
appId:'Your AppID',
query:keyword+' (filterui:msite-nicovideo.jp OR filterui:msite-dailymotion.com OR filterui:msite-youtube.com)',
sources:'video',
video_sortby:$sortby.val(),
count:20,
callback: function(data) {
var $videos = $('<ul class="video_list"/>');
var video = data.SearchResponse.Video;
var total = video.Total || 0, offset = video.Offset || 0, items = video.Results || [];
for (var i=0, len=items.length; i<len; i++) {
var v = items[i];
var thumb = v.StaticThumbnail || {};
var thumbWidth = 160, thumbHeight = 120;
if (thumb.Height>0) {
thumbHeight = Math.min(120, thumb.Height);
thumbWidth = Math.floor(120*thumb.Width/thumb.Height);
}
var $a = $('<a/>').attr('href',v.PlayUrl).attr('rel',v.SourceTitle).
click(function(e){
e.stopImmediatePropagation();
return false;
});
var date = new Date(v.RunTime);
var tm = date.getMinutes(), ts = date.getSeconds();
if (tm<10) tm = '0'+tm;
if (ts<10) ts = '0'+ts;
var duration = tm  + ':' + ts;
$videos.append($('<li class="rowvideo"/>')
.append($('<div/>').append($a.clone(true).html('<img src="'+thumb.Url+'" width="'+thumbWidth+'" height="'+thumbHeight+'"/>')))
.append($('<div/>').append($a.clone(true).html(v.Title))).append('<span class="source">'+v.SourceTitle+'</span><span class="duration">'+duration+'</span>')
);
}
$results.empty().append($videos);
}
});
return false;
});
});
})(jQuery);
</script>

これはニコ動とYouTubeとDailyMotionの動画を検索するサンプルで、デモは↓。
http://labs.makotokw.com/s/sandbox/bing/search/video
サクサク動いて良い感じなんだけど、ソートがRelevanceかDateしかないのが不便なところ。動画の場合再生数とかでソートしたくなるのでものによってはやっぱりYouTube DATA APIを使うほうが良い場合もありそう。

ScanSnapに紙を吸い込ませるのが何故か病みつきになる

なんかMacBook買ってからなぜか部屋の整頓したい気にかられて捨てる勇気を持っていろいろ捨てている。
で、中でも紙という紙を捨てまくっているのだけど、ScanSnapでPDF化しまくってる。ポータブルなScanSnap S300を使ってるけど久々に自分の中でヒット商品。
しかし、ScanSnapに紙を吸い込ませるのが病みつきになってる。以前は学生時代からのノートをひたすらPDF化にしたが、今回はセミナーのあらゆるレジュメをPDF化してやった。冊子っぽいやつも分離させて取り込みまくっている。楽しい。
本をデジタルな機器で(アナログ同等な感じで)読める時代が早くきて欲しいなぁ。iPhoneとかのタッチパネルとか結構良い感じに来てるんだけどね。KindleとかSonyも(USで)eBook作ったりしてるけど、データはデジタルで良いんだけど、本をめくったりする触感を以下にリアルにするかがポイントなんじゃないかなと思う。
背中の本棚が全部デジタル化できる日がいつかくるのだろうか。

地デジアプリが安定している件について

Mac買い換えた理由の一つとしてパソコンの地デジアプリが安定していることがあげられる。
おまかせ録画的な機能を使っているのだけど、途中で録画アプリがフリーズしていてそのまましばらく経ってから見たい番組が全然録れていないことに気がつくとかが結構あって、あったま来てもうブルーレイレコーダ買うよ。いやでもMac欲しいしどうしようみたいな葛藤があった。
そもそもフリーズしていることに気がつかないってのはそれだけ録画したものを見ようとしていないってことなので、レコーダいる?って話はさておき。
で今は結構安定していて、何をしたかいうとチューナーのドライバ更新しただけ。だけなんだけどそれまで俺はやっちゃいけないことをやっていたのよ。
録画アプリのページを定期的に確認して録画アプリだけはマメにアップデートしていたのに同時リリースされていたドライバはまったくアップデートしていなかった。
元メーカの人間なので想像できるんだけど、こういうのってドライバがこう動くっていうのを想定してその上のソフトを書いたりするから互換性を絶対に保たないといけないんだよね。。。
http://buffalo.jp/download/driver/multi/dt-h50_pciew.html

つか、思いっきり両方更新しろって書いてあったし。録画アプリのブックマークから直接確認してたので上記のページまったく経由してなかった。
欲を言うと、ドライバとソフトで同期をとって更新しないといけないなら両方更新する一つのインストーラを作ってくれよって話なんだけど。

Apache Shindig 1.1 (OpenSocial Spec 0.9)入れてみた

OpenSocialなOpenSourceのApache Shindig、PHP版入れてみた。
Apache Shindig
前にも入れたことがあるんだけど、調子にのってShindig 1.1 (OpenSocial Spec 0.9)を入れた。
またサブディレクトリで運用してみたんだけど、以前よりはまった。どうもweb_prefixの他、container.jsもいろいろ直さないといけないらしい。
だいたいやったことはこんな感じ。
1. ダウンロードしたファイルを/shindigというフォルダに置く
2. /shindig/.htaccessにRewriteBase /shindigを追加
3. /shindig/config/container.phpの’web_prefix’ => ”,を
‘web_prefix’ => ‘shindig’,にする
4. /shindig/config/container.jsで、URLらしきところでhttp://%host%ってあるところをひたすら
http://%host%/shindigにする
あと、PHP 5.2.x with the json, simplexml, mcrypt and curl extentions enabledってあるけど、openssl extensionも要求されてるっぽいよ。
例によってhttp://www.labpixies.com/campaigns/todo/todo.xmlは動いたけどUnknown RPC service: set_prefとか怒られる。
この辺、DBに保存するなり良きに計らい実装せよってことなのかな。確かにApache Shindig(OpenSocial)では特にどういうやり方でデータを保存するかは規定していないので必要なものありがちなMySQLなどのデータベースシステムは言及してない。
1から作るのMAXめんどくせ。Partuza使った方が早いかも。

実はエスパニョールの方がリスクが少ないのではという考えもあるのかも

俊輔がエスパニョール移籍ほぼ決定らしい。結構懐疑的に見てたんだけどなー。
でもよく考えると、今横浜に来ても俊輔のポジションが用意されてるとは思えないんだよね。ヨーロッパ帰りの選手って結構みんな苦戦しているし、横浜で出場機会に恵まれなければ間違いなく代表から外れちゃうと思う。そういう意味では同じ出場機会が恵まれない場合でもスペインリーグなら代表に選ばれると思うのよね。
というわけで実はスペインに行く方がリスクが少ないとかいう考え方もできるのかなと。
まぁ、一番リスクの少ない選択はセルティックに残ることなので、決断はすばらしいと思う。
しかし、俊輔がらみのニュースは偏ったものが多くて何が真実なのかよくわからないからなぁ。リーグのレベルからすれば長谷部や松井の活躍の方がもっと取り上げられてしかるべきだよ。とくに長谷部なんてブンデス優勝に貢献したのにまるでカップ戦優勝並みにしか報道されてないよね・・・
今ですらスペインで活躍してるくらいな報道なのに、これからスペインで活躍したらどうなるのか。メッシやクリロナ級の賛美になるに違いない。。。

iPhone OS 3.0 + jailbreak

jailbreak待ちだったのでみんなが3.0入れてるのがウラヤマシスだったのですが、3.0対応のPwnageToolがリリースされてみるたいです。勢いで3.0を購入して、iPod touch 1Gに入れてみました。
http://blog.iphone-dev.org/
(2009/06/20時点では) MacOSX用のPwnageToolのみのリリースです。Windowsで使えるQuickPwnもすぐにリリースされるようですが。yellowsn0wやってる人はなんかいろいろ書いてあるので読んだ方が良いかも。こちとらiPod touchなのでスルーです。あと、iPod touch 2Gはサポートしていないらしいので注意。
(iPod touchはclean(jailbreakしていない)な3.0な状態)
1. iPod touchをMacにつないでおく
2. PwnageToolをdevteamから落とす http://blog.iphone-dev.org/
3. iTunesを起動しておく
4. PwnageToolを起動する
– ExpertModeでいく
– iPod touchを選択する
– カスタムfirmwareをbuildする前にカスタムロゴのチェックを外しておく
– build後pwnaged済みかと聞かれたらNoと答える
– DFUモードに入るので言われたとおりにする、基本的に下記
— a) パワーボタンとホームボタンの長押し
— b) パワーボタンを放して、ホームボタンだけ長押し継続
– ここでiTunesでリカバリモードのiPod発見と言われ復元モードになる
5. PwnageToolをcloseする
6. iTunesからCustom Firmwareで復元する
– iTunesの復元ボタンをOptionキーを押しながらクリックし、Pwnageで作成したcustom firmwareを選択する
# IntelMacはCustom Firmwareのビルドがはえー

redmineとMylynを連携させる

MylynというのはEclipseのタスク管理用のプラグインなんだけど、こいつとプロジェクト管理ツールを連動させると開発環境の中でタスクが管理できて便利なのである。
Redmine – HowTo Mylyn – Redmine
tracやBugzillaなどでは専用のconnectorなるものも用意されているが、残念ながらredmineには今のところ専用のConnectorが存在するわけではなく、Mylyn Incubator にある、Mylyn Connector: Web Templates を使う。
この Web Templates ではチケット一覧のURLを指定するとHTMLのソースに対して正規表現を適応していチケット一覧を作成してくれる代物のようだ。ただそれ以外のチケットの新規作成やコメントの更新についてはただ新規チケットWebページに飛ばされるのでmylynの恩恵を受けることはできない。(ただ内部ブラウザで開くだけになる)
ちなみにorg.eclipse.ltk.core.refactoring_3.4.2.r342_v20081028-0800.jar が満たせないとかどーとか怒られてMylyn Connector: Web Templatesがうまくインストールできずに困っていたのがMylynを Ganymede 更新サイト > コラボレーション・ツール
入れるとバージョンが違ってうまくいかないようだ。どうもEclipse 3.4 用 Mylynから入れないといけないっぽい。前者バージョンが3.0.5で後者が3.1.1になっている。これ、はまるよ。
1) ヘルプ -> ソフトウェア更新 > 使用可能なソフトウェア > サイトの管理 > で下記を有効にする

http://download.eclipse.org/tools/mylyn/update/e3.4

2) ヘルプ -> ソフトウェア更新 > Eclipse 3.4用 Mylyn( http://download.eclipse.org/tools/mylyn/update/e3.4 )の下記を選択しインストール
Mylyn ブリッジ: Eclipse IDE ( Mylyn Bridge: Eclipse IDE )
Mylyn フォーカス UI ( Mylyn Foucused UI )
Mylyn タスク・リスト ( Mylyn Task List )
で3.1.1のMylynが入る。
Web Templates は
1) ヘルプ -> ソフトウェア更新 > 使用可能なソフトウェア > サイトの管理 > で下記を追加する

http://download.eclipse.org/tools/mylyn/update/incubator

2) Mylyn Incubator ( http://download.eclipse.org/tools/mylyn/update/incubator ) の下記を選択しインストール
Mylyn Incubator > Mylyn コネクター: Web Templates
で入れられる。
あとはビューのタスク・リポジトリーを開いて、リポジトリを追加する。コネクターにWeb Templatesを選択して、remineのページを参考に設定を入れる。
自分の場合はremineをサブディレクトリで運用しているため
クエリー・パターン(P)を

<td class="subject">.*?<a href="/redmine/issues/show/(\d+)">(.+?)</a></td>

というようにしてリンクのところを少し変る必要があった。今後redmineの出力するhtmlもどうなるかわからないので実際に出力されているhtmlからクエリパターンを作ったほうが確実かもしれん。
Eclipseのビューのタスクリストではいくつもクエリが作成できる。remineのデフォルトの設定だと全プロジェクトのチケット一覧になってしまうが、プロジェクトごとにチケット一覧を取得するには、
クエリー・リクエスト URL(Q): ${serverUrl}/projects/foo/issues
とかにすると良いと思われる。(fooのところがproject名)
逆に新規タスクURL(N):${serverUrl}/projects/foo/issues/newでプロジェクト依存になってしまう。正直プロジェクト単位でタスク・リポジトリをmylynに作るのもだるいので複数プロジェクトを使っている場合は、チケットの新規登録をmylyn上でやらずにwebでやった方が良いかもしれない
tracと比べると新規登録もそうだけど、コメントを追加するときにブラウザでページ開いたりするんでやっぱ微妙といえば微妙。専用のコネクタが欲しいところである。

メモとかタスクの記録媒体が発散中

うーん。最近なんというか過渡期というか

  • trac
  • redmine
  • pukiwiki
  • evernote
  • tumblr
  • キャンパスノート C罫 A7
  • ニーシモネ A4

使いこなせてない。。。
デジタル、アナログ
TODO, テキストメモ、Webのリンクメモ、設計図的なもの
など用途がばらばらなので仕方がない面もあるのだが。
アナログもスキャナで取り込んで、evernoteで一括管理すればいいのかな?とりあえずやってみようか。ただ案外pukiwikiとかテキストエディタのサクサク感が良くてevernoteに完全移行できない自分がいる。
redmineも重いので個人のTODOをそこに入れるのはどうかなぁってのがある。まぁ超短期的なTODOはアナログで良いんだけど、中・長期的なやつはどうしてそういうプロジェクトツールに入れたほうが忘れないし、大きなタスクは作業履歴を入れられるのが良いんだよね。
あ、この辺で困ってるの会社のことじゃないです、会社とは関係ない個人の作業です。なので時間があくと何をどこまでやったか忘れちゃうんすよね。それゆえ、作業履歴を残すことが自分の中では結構重要な作業だったりします。
うーん、タスクはまぁそれほどたくさんの機能は必要ないので、redmineじゃなくて trac + mylarでやった方が良いかなぁ。んで、デジタルなメモはevernoteに統一するか。
ちょっくらpukiwiki2evernote xmlスクリプトでも書くかー。

iBook G4->MacBook Pro(5) MacPortsのmysql5 +serverはもう古いらしい

WebでMacPortsでMAMPの構築ネタを探すと、

sudo port install apache2
sudo port install mysql5 +server
sudo port install php5 +apache2 +mysql5 +pear

phpのvariantは多少増減するにせよこんな感じのおまじないがあるわけで、実際にこの指定でiBookにはインストールしていたわけなので何も考えずに今回もこれでインストールしていた。
でありきたりなおまじないなので、ちゃんと出力とかを見ていなくて実際にテーブルいれるかーってときにmysqlがうまく起動できなくて、なんか設定見落としてるのかもしれないと思い入れ直し。
出力を注意して見てるとmysql5 +serverはもう古くてmysql5-serverを使いなさいとか言われてた。

# port variants mysql5
mysql5 has the variants:
server: Obsolete; install mysql5-server port instead
universal: Build for multiple architectures

インストール進捗を見ていなかったので正直これが原因だったのかよくわからないのだが、とりあえず今後のおまじないはこれを使おう。

sudo port install apache2
sudo port install mysql5 mysql5-server
sudo port install php5 +apache2 +mysql5 +pear

一応無事インスコできた。

iBook G4->MacBook Pro(4) synergyの設定メモ

いろいろ忘れそうなのでsynergyの概念とか設定の備忘録。
サーバとクライアント
まず、synergyにおいては、キーボードやマウスを直接操作するマシンがサーバ、入力をリモートで受け取る側がクライアントになる。
自分の場合はWindows Vistaをsynergyのサーバ、Leopardがsynergyのクライアントにしている。
で、あらかじめどのマシンをクライアントとして使うか、またそのクライアントを自分のディスプレイの左右上下どこに置くのかなどの設定はSyngeryのサーバ側で行っておかないといけないようだ。
インストール
Windowsの場合はGUI付きのアプリが用意されていて、そのアプリでサーバになるのかクライアントになるのか選択でき、サーバになる場合はクライアントの構成もGUIで行える。
Windows以外のOSでサーバになる場合は、オフィシャルなGUI付きアプリは用意されていないのにで基本的には設定はsynergy.confというファイルにかいて/etcに置いたりする。今回はLeopardはクライアントなので詳しくは調べていない。
WindowsにSynergyのサーバを導入するには、synergyのLatest Releaseからバイナリを落としてインストールするだけで良い。
Leopardの場合はバイナリもあるがソースからビルドもできる。synergyはしばらくリリースがされていないようでInterlMacだとDaemonで起動できないなど少々問題もあるらしい。ただ有志により修正パッチが配布されており、今回はソースコードにパッチをあててビルドすることにした。
1) synergy-1.3.1.tar.gzを http://sourceforge.net/project/downloading.php?group_id=59275&filename=synergy-1.3.1.tar.gz&a=41349074から落とす。
2) synergy-1.3.1.tar.gzを展開しておく
3) synergy.patchをhttp://sourceforge.net/tracker/download.php?group_id=59275&atid=490469&file_id=263982&aid=1880984から落とす
4) ターミナルで展開したsynergy-1.3.1に移動してパッチを適応してビルドする、ダウンロード先が~/Downloadsであれば下記のような感じになる

cd ~/Downloads/synergy-1.3.1
patch -p0 < ~/Downloads/synergy.patch
./configure
make
sudo make install

サーバ側の起動とコンピュータ名の設定
WindowsではC:\Program Files\Synergy\synergy.exeを起動するだけ。

サーバになるので「Share this computre’s keyborard and mouse(server)」のチェックを選択し、Configure…からクライアントを設定する。
Syngeryの世界ではサーバ・クライアントも含めてマシンのことをScreenという概念で扱うようだ。「Screens」にサーバとなる自分のマシンやクライアントの名前をつけて定義する。

Screen Nameには実際のマシン名ではなく管理しやすい好きな名前を入れて良い。マシン名とは違う名前を入れた場合にはAliasesにマシン名を入れる。Windowsの場合コンピュータ名は(マイ)コンピュータの右クリックのプロパティから確認や変更ができる。
MacOSXはローカルネットワークではマシン名.localという名前で参照することができる。Macの場合はシステム環境設定 > 共有からコンピュータ名の確認・変更ができる。

画面の設定
Windowsをサーバにしている場合、Linksというところに仮想スクリーンの設定できる。

このマシンをあのマシンの右に置くとか左におくとかマシンの相対方向で指定する。
Leopardの右にVista (localhost is right of gemini.local)
Vistaの左にLeopard (gemini.loca. is left of localhost)
という感じ。
注意しないと行けないのは双方向の設定をしておかないとマウスカーソルが戻ってこれなくなるところ(マウスがクライアントにあるということはキーボードのフォーカスもそっちになるので操作できなくなって焦る)。デフォルトで双方向にして欲しいところなのだが・・・
サーバの開始とクライアントの接続
Linksの設定ができたらStartを押してサーバを開始する。次にクライアントを接続させる。
MacやLinuxではクライアントがsynergyc, サーバがsynergysとバイナリが分かれている。今回はLeopardがクライアントなのでsynergycを実行する。
個人的にMacBook Proは外に持ち出したりしたいのでsynergyクライアントはDaemonではなくforegroundで必要なときに実行するつもり。

# synergyc -f 192.168.1.1

(make installした場合は、/usr/local/bin/synergycに入ってる)
で起動する。-fがforegroundで実行。192.168.1.1はsynergyサーバのIPアドレスやhostnameを指定する。Windowsならコマンドラインでipconfigと打つとinterfaceのIPアドレスが表示されるのでそれで確認すべし。
キーボード配列の差異の吸収などはまたわかったらメモることにする。