Archive for February, 2008

サーバ引っ越し

February 28th, 2008  |  Published in Uncategorized

これまで、うちのMac miniで動かしていた blog.deadbeaf.org をレンタルサーバ上に引っ越ししました。 レンタルサーバの候補として、XREA / さくらインターネット / ロリポ の3つを試用しています。 現在いちばんレスポンスの良いXREAに移していますが、さくらインターネットと接戦かな。

デザインもついでなのですっきりさせようと思っていて、とりあえず google:”wordpress テーマ”で首位だったwp.vicunaさんのものに手を入れて使っています。

なんで引っ越したかというと、最近の過負荷のせいか、どうもMac miniがよくスラッシングから返ってこなくなってしまい、 サーバが止まる回数が増えてきていたから。 外出中にサーバが止まってたりすると、どうも心臓に良くない。

しかしこの8年くらいずっと自宅サーバだったので、レンタルサーバ浦島状態です。 自宅/レンタルのpros/consをあとでまとめてみようかなと。

Tags: ,

QSTwitter 1.3

February 22nd, 2008  |  Published in Uncategorized

QuicksilverからTwitterに投稿するプラグイン、QSTwitterを1.3にアップデートしました。 ダウンロードはこちら。 若干バギーです :)

変更点

Friendの補完

自分がfollowしているひと (= Friend) をカタログに保持し、 Quicksilverから補完入力できるようにしました。 アイコンが表示されるのがキュート。

Reply Action

補完入力したFriendに対して、reply Action でメッセージを送れるようにしました。 自動的に、@だれそれがメッセージの先頭につきます。

HTTP プロキシ

環境変数に、http_proxyが設定されている場合に、そのプロキシサーバを使うようにしました。

Action名の変更

これまでは、TwitterというActionでメッセージを送っていましたが、 postというActionに名前を変えました。

スクリーンショット

スクリーンキャスト

百聞は一見にしかずということで。

注意事項

  • Mac OS X 10.5.2 でしか確認していません。Leopardが必須です。RubyCocoaがインストールされているTigerでも、ひょっとしたらビルドできるかも。
  • JSONのRubyライブラリが必要です。sudo gem install jsonなどとしてインストールしてください。
  • インストールした直後、Quicksilverが固まります。これは、Friendすべてをダウンロードしてカタログ化しているためです。
  • 初回のカタログが生成されたあと、Quicksilverがクラッシュしたり暴走したりします。Quicksilverを再起動すると、ちゃんと動くようです。 (調査中)

中のつくりについて

これまではObjective-Cで書いていたのですが、RubyCocoaで書き直しました。 メリットとしては、以下のようなものがあります。

  • JSONが簡単に扱える
  • HTTP POST via プロキシができる (NSURLConnectionではなかなかうまくいかない)
  • デバッグがラク ( /reload と postすると、Rubyスクリプトが再読み込みされるようになってる)

また、コードを見てもらえると分かるのですが、カタログ化のためにダウンロードしたFriendのJSONを、 Marshal.dumpでPluginがインストールされた場所にキャッシュしています。 なんという手抜き。

コード

CodeRepos : TwitterPlugin

以前のバージョン

  • 1.2 : 2008.01.23
  • 1.1 : 2007.12.22

関連エントリ

  • Quicksilver Twitter Plugin (日本語)
  • QSTwitter 1.1 (Quicksilver Twitter Plugin)
  • QSTwitter 1.2
  • RubyCocoaを使ってQuicksilverプラグインを書く
  • もっとRubyCocoaでQuicksilverプラグインを書く
Tags: , , , ,

P2Pネットワーク実験協議会シンポジウムに行ってきた

February 20th, 2008  |  Published in Uncategorized

FMMC 財団法人マルチメディア振興センター – P2Pネットワーク実験協議会 シンポジウム 「P2P技術の利用・サービスに関わる取組・実験の最新動向」 に参加するため、東大まで行ってきました。 目的は2つ。

  • P2P技術のおさらい
  • 最新動向のキャッチアップ

まず簡単に、印象に残っているとこの覚え書きを。

キーノートスピーチ (浅見教授)

今日は最近の話題である、P2Pの商用CDNでの利用についてやりますよ、と。 P2Pがトラフィックの8割を占めているというデータに驚いた。HTTPとかテラ少ない。

アーキテクチャの概要/動向 (西谷さんコミュ)

書いてます。 P2Pといってもいろんなアーキテクチャがありますよ。詳しくは本で! スーパーノード型というのは、GFSに通じるものがあるかな。

悪意のあるPeerってのが、著作権を犯してるファイルを配ってたりすると。 そういうPeerはSPAMフィルタみたくベイズ理論ではじけないもんかなー、とかぼんやり考えてました。

P2P技術による効果 (首藤さん@ウタゴエ)

P2Pでインターネットを軽くしたい! の話。

実際にやってみたところ、配るPeerともらうPeerが半々で50%程度の帯域削減になると。 んでP2Pでは、ISP/キャリアの負担はあまり変わらないかも。一番うれしいのは配信サイド(供給者)。

P2Pには、かき集めとばら撒きの2種類がある、というのはとてもわかりやすかった。 それはそうと首藤さんかっこいい。

BitTorrentでの実証結果 (室川さん)

人気がないコンテンツでも、Peerが1つか2つもいれば、 オフロード率 (オリジナルの配信元から出る通信量と、全体との割合) が40%にもなる。 これはすごいんじゃないか。

コミュニティFM向けネットテレビ放送 (高野さん@ビットメディア)

今回のベストプレゼン。笑いまくった。

時代を先取りし続けてきて、今やってるのは地域FMを世界に配信するというもの。 ただし、曲は流しませんw 代わりにDJの舞台裏をストリーミング放映。


朝の部で、だいたい僕が参加した目的は果たせました。よかった。

後半CDNでの実施例の話を聞くにつれ、これってサーバサイドの負荷分散の話だよなー、と。 ファイル共有じゃない、違う視点からP2Pを見るという話をもっと聞ければよかったかなと思います。 P2PなWikiとかP2PなファイルシステムとかP2PなSNSとか3分でつくるよP2Pとか。

あと、これだけP2Pな競合がいるのにUstream.tvが流行ってるのはなんでだろうと考えてて、それは ブラウザだけで即配信できるからなんかなと。 今日発表されていたプロダクツはだいたい、何かをインストールする必要がありました。そこの差なんかなと。 なにかを流行らせるためには、使ってもらうための障壁を限りなく下げないと、という教訓ですね。 あとUstream.tvも内部でP2P的な負荷分散してるのかなーと想像してました。 そうじゃないとしたら、いまP2PなUstream.tvつくればあたるよ!

P2Pな世界はまだまだこれからです。フロンティアがある。 みんなどしどしコード書いて、自分のプロトコルをデファクトにするとよいよ。

あと、 suztomoは捕捉できたんですが、 ハチロク世代の人がちょこちょこいたぽいので、話せてたらよかったなと。

まとめ

知見がちょっと広がってよかったです。 あと、みんなでP2Pのコードを書いて世界を変えよう、とかおもった (デブサミ2008的な意味で)


posted with amazlet on 08.02.20
江崎 浩
インプレスR&D (2007/12/22)
売り上げランキング: 24485
Tags: , P2P

LeopardでのQuartzComposerカスタムプラグインづくり

February 19th, 2008  |  Published in Uncategorized

Ruby会議2008CFPとして、RubyCocoaでインタラクティブにMacのプラグインをつくるよ、みたいなものを書いて出してみました。 出してから、そういえばLeopardになってからQuartzComposerで遊んでないなあと気づき、ちょっと触ってみたらえらく変わっていたので、今日調べたことをカスタムプラグインをつくるという観点でメモっときます。

カスタムプラグインがオフィシャルに

最大の変更点はこれです。 Appleの丁寧なドキュメント Introduction to Quartz Composer Custom Patch Programming Guide を読めば、たちまちつくれるようになるのではないかと。サンプルも充実してて、/Developer/Examples/Quartz\ Composer/Plugins/にごろごろ転がってます。 これまで、kineme.net:Xcode Template for Custom Quartz Composer Patches を使い、非公開のAPIでプログラミングしていたのに対して大きな進歩です。

Port指定にはpropertyをつかう

Objective-C 2.0で導入された、propertyという機能をつかって入出力Portの指定をコードでやるようになっています。 これまでは、インスタンス変数名の先頭にinput/outputがあれば、それがPortになっていました。

Portの増減が動的にできる

RubyCocoaでpropertyを使う方法を知らないのでどうしようかなあと思ってたのですが、 addinputPortWithTypeとかaddOutputPortWithTypeというメソッドを使えば動的にPortが加えられます。

注意すべきことは、これらのメソッドはプラグインのexecuteメソッドに入れてはいけないことです (例外があがってQuartzComposerが止まってしまいます)。んじゃどうするかということで、ExampleのCommandLineToolFreeFrameHostを調べてみると、どうやらQuartzComposerのインスペクタから受け取るイベントのハンドラで、これらのメソッドを呼ぶようにしています。なるほど。

インストール場所が変わっている

これまでは、/Library/Graphics/Patch にプラグインを置くのが流儀だったのですが、Leopardからは/Library/Graphics/Quartz\ Composer\ Plug-Ins/ になりました(~/Library以下でもOK)。


カスタムプラグインをつくるという点から、Leopardになって気づいたことをまとめました。次はいよいよ、RubyCocoaでカスタムプラグインづくりです。

関連エントリ

  • RubyCocoaでQuartzComposerパッチ
  • SocketReaderPatch
  • IRCのメッセージをQuartzComposerに表示
  • QuartzComposer の CustomPatch をつくるための Xcode template
  • QuartzComposer の CustomPatch で Signal を生成する方法
  • ApacheLogPatch 0.1
  • RubyCocoa で QuartzComposer CustomPatch をつくりたい
  • RubyCocoa で QuartzComposer CustomPatch (2)
Tags: , ,

デブサミ 2008 (2)

February 15th, 2008  |  Published in Uncategorized

二日連続で雅叙園でした。 聴いたものとその感想を簡単に。

和田さんのライブTDD

実際に日々TDDをやってる人の実演を見るのはとても参考になった。Eclipse+Javaの補完すごい。Vim+C++でもあれくらいできれば…

竹迫アワー

  • koizukaさんの在宅話 : セルフコントロールと信頼が必須だなあと。
  • モバゲー : 手作り、手作業、目視、少人数。大変だけどやりがいのありそうな現場だなー。
  • Wassr : タバコ部屋トークをノンスモーカーにも。気楽なトークを就業時間内にやるのがポイントかなと。
  • Asiajin : 海外にどうやって広めようかというときに、日本のみんなに協力を仰いだというのが印象に残った。
  • Yappo++

全体でみて。

しょっぱなのジョエルトークを筆頭にして聴衆を楽しませようとする人が少なめで、そうでなく単調に話し続けるだけの人が多かった。 文化の違いもあるんだろうけど、聴く側に届けたいものをはっきりさせて、笑いで場をつくることで心を開いてもらう、というサービス精神はだいじだなと。 自分が話す機会があれば、サービスサービスしよう。

1つのセッションが40分くらいで、LT慣れしてる感覚からするとものすごい長かった。 LTてのは優れたプレゼンフレームワークだなー。


ということで、さっそく英語ブログをはじめました。これまでもここでちょこちょこと英語エントリ書いてたんだけど、日本語を1文字も表示させないようにというakky tipsだったので独立。越境してコードで世界を変えるのです。

自分なりの気づきをいくつか見つけることができました。参加してよかった。

Tags: , P2P

デブサミ 2008 (1)

February 13th, 2008  |  Published in Uncategorized

デブサミ1日目に行ってきました。 見てきたのは、

あたり。印象に残ったのは、Joel, 咳さん、amachangでした。


Joelのは、二級品じゃなくて一級品をつくるには、といった話。サービス精神あふれる、ブログでのユーモアそのままなプレゼンを見せてくれた。さすが。 ユーザのことをほんとうに考えてものをつくるにはどうしたらいいか、のヒントがあった。

咳さんのチームでの開発話は、自分に置き換えながら聴いてた。 XPをやるんじゃなくて、仕事を終わらせるのがだいじ、と。方法論に踊らされず、自分の血肉にしないとね。僕もチームづくりでいろいろトライしてるんだけど、価値観を共有するのがまず最初にやることだなと再確認。がんばろ。

amachangのJavascriptのOO側面の話はとてもよく分かった。 どんどんはなし、ストーリーがうまくなってるなー。 テクニックは、他人が書いたコードを読むために身につけてきた、というのは新しい視点だな。 この前のWEB+DB PRESS Tech Meetingのときもそうだったんだけど、もっと自分がつくったものの話をしてもいいんじゃない? とか思った。


その他雑感。

  • 通訳はいらないかな、と。せっかくJoelがおもしろいネタを披露してるのに、間があいてしまうのはなー。
  • コードで世界を変えようとしてたのは、amachangくらいに感じた。イベントサブタイトルに違和感。
  • パネルディスカッションは、異なる見方をいっぺんに知ることができるのがいいのかな、と。それでもやっぱり、聴衆とのインタラクションがないとなあとか思う。
  • オライリーブースで と を買って、REST TシャツとJavascriptマグ、その他グッズを手に入れました。やったね。

Rubyのパネルディスカッションで、みんなもっと貢献するといいよという話を聞いてて、J.F.ケネディのあれを思い出してました。

Rubyがあなたに何をしてくれるのではなく、あなたがRubyに何ができるかを問うべきだ

ではまた明日!

Tags:

もっとRubyCocoaでQuicksilverプラグインを書く

February 6th, 2008  |  Published in Uncategorized

RubyCocoaを使ってQuicksilverプラグインを書く の続編です。 前回書いたあと、hisaさんからアドバイスをもらい、RubyCocoaプラグインを書くことができるようになりました。

ポイントは以下の2つ。

  • NSPrincipalClass
  • RubyActionClass < OSX::QSActionProvider

コードは、CodeReposのものをupdateしておきました。 hisaさんコードがたくさん入っていますが、煮るなり焼くなり好きにせよとのことなので、前回と同じ修正BSDライセンスとします。

NSPrincipalClass

Quicksilver プラグインに限らず、Cocoaで何らかのBundleを書く際には、Info.plistの NSPrincipalClass にクラス名を指定しておくと、そのクラスの +load() メソッドが呼ばれてプラグインが組み込まれるようです。 なので、ここでRBBundleInit()を呼んでRubyCocoaを初期化すると。とてもスマート。 前回はこのことを知らずに、無理矢理なハックをしていたのでした。

RCLoader.m:

ここでは、NSPrincipalClassにRCLoaderというクラスを指定しています。

 RCLoader

  • (void)load { static bool installed = 0;

    if (! installed) { if (! RBBundleInit("load_ruby.rb", [self class], self)) { installed = true; } } }


load_ruby.rb:



そんで、RubyCocoaの初期化の中で、必要な.rbを読み込んでおく、と。
def load_ruby_programs(bundle, logger)
  path = bundle.resourcePath.fileSystemRepresentation
  rbfiles = Dir.entries(path).select {|x| /.rb\z/ =~ x}
  rbfiles -= [ File.basename(FILE) ]
  rbfiles.each do |path|
    require( File.basename(path) )
  end
end


OSX.init_for_bundle do |bundle, param, logger| load_ruby_programs(bundle, logger) end

RubyActionClass < OSX::QSActionProvider



前回説明したように、QuicksilverのActionを記述するには、QSActionProviderを継承したクラスでメソッドを用意します。 今回は、RubyのクラスでQSActionProviderを実装します。RubyCocoaのパワーがすごすぎる。
class RubyAction < OSX::QSActionProvider
  def act(arg)
    val = arg.stringValue
    OSX::QSObject.objectWithString('Hello world, ' + val)
  end
end


あとは、このRubyActionクラスを、Info.plistのactionClassに、actionSelectoract:に指定しておけば、ちゃんとactが呼ばれます。

疑問


  • OSX.require_framework とか使わないで、QSActionProviderとかのQS frameworkが使えてるのはなぜ?
  • hisaさんは、この方法だとCPU usageが高くなると懸念されているのですが、僕のところではいまひとつ高くなってるように見えません。why?

まとめ



RubyCocoaで、Quicsilverプラグインを書く方法をまとめました。 これで、あとはRubyのクラスとInfo.plistを書くだけでどんどんプラグインが書けますね。みんながんばれ!
あと、自分でもイマイチだなーと思うことでも、何かしら書いて晒すことが大事なんだなと。そんで改善していければOKなんだ。 hisaさん、ありがとうございました。
Tags: , , ,

Write a Quicksilver plugin with RubyCocoa

February 3rd, 2008  |  Published in Uncategorized

I wrote a Quicksilver plugin with RubyCocoa, that adds “hello world” to the passed string.

  • Xcode project codes : in CodeRepos
  • License : revised BSD

It should work on Tiger/Leopard if RubyCocoa is installed.

How does it work

As I mentioned in QuartzComposer CustomPatch with RubyCocoa, we just call RBBundleInit() function in plugin initializaiton phase to write some plugin with RubyCocoa. But wait, where should be the initializaiton code in Quicksilver plugin ?

We write actual plugin behavior in the class that inherits QSActionProvider, so I tried to call RBBundleInit() in the init() method in that class… however, that resulted in crashing Quicksilver :(

Then I called RBBundleInit() at only first time in performActionOnObject() of the actual Action class, and made references between Objective-C and Ruby class instances.

After that, I implemented an actual action behavior in Ruby class, and delegates from Objective-C to Ruby method, thats’ all. This is ugly, confusing, … I know, but it does work well :)

Code Snippets

ActionProvider in Objective-C:

 (QSObject *)performActionOnObject:(QSObject *)dObject{
  // initialize RubyCocoa
  static bool loaded = false;
  if (!loaded) {
    if (RBBundleInit("qs_action.rb", [self class], self)) {
      NSLog(@"[RubyCocoaPluginAction.performActionOnObject] RBBundleInit failed"
);
      abort();
    }
    loaded = true;
  }


// delegate actual action to Ruby class QSObject *ret = [QSObject objectWithString:[rb_ act:dObject]]; return ret; }

RubyCocoa side:

class Action
  def initialize(logger)
     = logger
  end


# write something great :) # - arg : QSObject def act(arg) val = arg.stringValue (val) 'Hello world, ' + val end end # Action
require 'osx/cocoa' OSX.init_for_bundle do |bdl, owner, log| # bdl - the bundle related with the 2nd argument of RBBundleInit # owner - the 3rd argument of RBBundleInit as optional data # log - logger for this block
act = Action.new(log) owner.setInstance act end

Future works

  • Better initializaiton. It should be in constractor of some class)
  • Inherits QSActionProvider by Ruby class (more pure Ruby)
  • Use ns_import ?

It should not be “With RubyCocoa”, but rather “By RubyCocoa”.

Conclusion

I made a start point to write a Quicksilver plugin by RubyCocoa. It is timing of initialization that is to be considered about writing some bundle in RubyCocoa. I made it in this article somehow. This article is for someone who wants to create Quicksilver plugin by Ruby, not learning unfamiliar Objective-C.

Reference

  • QuartzComposer CustomPatch by RubyCocoa
  • PyObjC Plug-ins : Article about writing Quicksilver plugin by PyObjC (a bit obsolete…)
Tags: , , ,

RubyCocoaを使ってQuicksilverプラグインを書く

February 3rd, 2008  |  Published in Uncategorized

RubyCocoaを使って、Quicksilverのプラグインを書いてみました。 受けとった文字列に、”hello world” をくっつけるだけのものです。

プロジェクト一式のコードは、CodeReposに。 ライセンスは修正BSDで。 RubyCocoaがインストールされていれば、TigerでもLeopardでも動くと思います。

仕組み

RubyCocoaでQuartzComposer CustomPatchのときに書いたように、 CocoaアプリじゃなくてプラグインをRubyCocoaで書くには、RBBundleInit() という関数をプラグインの初期化の際に呼んであげればよいわけです。 ところが、Quicksilverプラグインの初期化ってどこなんだろうという。

QSActionProviderを継承したクラスで実際のプラグインの動作 (Action) を記述するので、このクラスのinit()で RBBundleInit() を呼べばいいかなーと考えてやってみたところ、Quicksilverをクラッシュさせてしまいます。こまった。

しかたないので、Actionを記述する performActionOnObject() の中で、RBBundleInit()を最初の一度だけ呼ぶようにしました。その中で、Objective-CからRubyクラスのインスタンスを参照できるようにしておきます。

あとは、RubyのクラスでActionを実装し、Objective-CからRubyのメソッドを呼んで移譲します。これでできあがり。 かなり強引で美しくないのですが目的は果たせるかな、というダーティハックです。

コード片

Objective-CのActionProvider:

 (QSObject *)performActionOnObject:(QSObject *)dObject{
  // initialize RubyCocoa
  static bool loaded = false;
  if (!loaded) {
    if (RBBundleInit("qs_action.rb", [self class], self)) {
      NSLog(@"[RubyCocoaPluginAction.performActionOnObject] RBBundleInit failed"
);
      abort();
    }
    loaded = true;
  }


// delegate actual action to Ruby class QSObject *ret = [QSObject objectWithString:[rb_ act:dObject]]; return ret; }

RubyCocoa側:

class Action
  def initialize(logger)
     = logger
  end


# write something great :) # - arg : QSObject def act(arg) val = arg.stringValue (val) 'Hello world, ' + val end end # Action
require 'osx/cocoa' OSX.init_for_bundle do |bdl, owner, log| # bdl - the bundle related with the 2nd argument of RBBundleInit # owner - the 3rd argument of RBBundleInit as optional data # log - logger for this block
act = Action.new(log) owner.setInstance act end

あと、やるとしたら

  • もうちょっときれいに初期化する (何らかのクラスのコンストラクタが望ましい)
  • QSActionProviderをRubyのクラスで継承する (よりRubyだけで書けるように)
  • ns_importとかつかってみる?

「RubyCocoaを使って」 よりも、「RubyCocoa」、スマートにプラグインを書けるようにしたいものです。 まぁ、まずは第一歩ということでひとつ。

まとめ

RubyCocoaを使って、Quicksilverプラグインをつくるためのとっかかりについて書きました。 RubyCocoaでバンドルを書くときに悩むのは初期化のタイミングだと思います。 今回はここを無理矢理解決しました。 Objective-Cを学んでる時間があったら、慣れ親しんでるRubyでちゃちゃっと コード書きたいよ! という方の参考になればと思います。

参考

  • RubyCocoaでQuartzComposer CustomPatch : QuartzComposerのCustomPatchもCocoaのバンドルなので、このときの経験が活かせました。
  • PyObjC Plug-ins : 本家による、PyObjCでQuicksilver pluginをつくるための情報。ただし、リンク先があちこちロストしてる ><
  • ひ日誌 : RubyCocoaで Quicksilver pluginは書けるのか? : ここが発端。

2008.02.03 追記

RubyCocoaのhisaさんにコメントいただき (!)、もっとよい方法を教えてもらいました。 こちらについても、まとめて別エントリにします。

Tags: , , ,