| @Mac/iPhone

youpyさん作のiTunesで聞いてる曲のレートが5だったらLast.fmに "Love" を送信してくれるやつを試してみようとした。cronで2分間隔とかで回して使うやつ。

なんで二年近く前のやつを今頃使ってみようとしたのかというと、二年前はRubyとかUnixのことが全然分かんなくてブックマークしただけだったから。いまは多少はRuby分かるし、crontabの使い方も分かるので、いましかないと思ったわけです。

git clone git://gist.github.com/58251.git
cd 58251
ruby love.rb

初回起動時にはLast.fmのAPIキーやTokenを入力するようにコンソールにメッセージが表示される。その後こういうエラーが出てしまった。

/Library/Ruby/Gems/1.8/gems/rubyosa-0.4.0/lib/osa.bundle: dlopen(/Library/Ruby/Gems/1.8/gems/rubyosa-0.4.0/lib/osa.bundle, 9): no suitable image found.  Did find: (LoadError)
  /Library/Ruby/Gems/1.8/gems/rubyosa-0.4.0/lib/osa.bundle: no matching architecture in universal wrapper - /Library/Ruby/Gems/1.8/gems/rubyosa-0.4.0/lib/osa.bundle
  from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:29:in `require'
  from /Library/Ruby/Gems/1.8/gems/rubyosa-0.4.0/lib/rbosa.rb:29
  from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:34:in `gem_original_require'
  from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:34:in `require'
  from love.rb:71:in `initialize'
  from love.rb:61:in `new'
  from love.rb:61:in `get_instance'
  from love.rb:34:in `main'
  from love.rb:206

なんかアーキテクチャが違うとかそれ系のエラーメッセージが出ている模様。そもそもRubyOSAって何なんだろうと思って調べてみたら、以下にたどり着いた。

なるほど、Appleが用意してるRubyからMac OS Xのイベントとかを管理できるようにするやつか。RubyをAppleScript的な使い方が出来るようにするらしい。Snow Leopard発売前の2007年に出たVersion 0.4.0で開発止まってるみたいだし、64bit化したSnow Leopardでは使えないってことなんだろうか。いや、64bit化する前のMacBook黒からTimeMachineでデータを引き継いでるから、アーキテクチャに合わないRubyOSAが入ったままになってるのかもしんない。「10.6 Snow Leopard と RubyOSA のインストール - Numata Designed Factory」 という記事を参考に、RubyOSAを入れ直してみることにした。

svn checkout svn://rubyforge.org/var/svn/rubyosa
cd rubyosa/trunk
cat src/rbosa.c | (rm src/rbosa.c; sed "s/c ID/c RB_ID/g" > src/rbosa.c)
ruby extconf.rb
make
sudo make install
sudo make install-extras

インストール後、再度 ruby love.rb を実行してみた。しかし今度は以下のようなエラーが出る。

/Library/Ruby/Site/1.8/rbosa.rb:470: warning: Passing no parameters to XML::Parser.new is deprecated.  Pass an instance of XML::Parser::Context instead.
XML::Parser#string is deprecated.  Use XML::Parser.string instead
/Library/Ruby/Site/1.8/rbosa.rb:558:in `__send_event__': Cannot send Apple Event 'coregetd' : procNotFound (-600) (RuntimeError)
  from /Library/Ruby/Site/1.8/rbosa.rb:558:in `player_state'
  from love.rb:77:in `playing?'
  from love.rb:36:in `main'
  from love.rb:206

どうも古いバージョンの libxml を使わないとエラーが出るらしい。今度は「RubyOSA 0.4.0を使おうとしたのですが、Bus Errorが発生 - Watsonのメモ」という記事を参考に以下のようにした。

diff /Library/Ruby/Site/1.8/rbosa.rb /Library/Ruby/Site/1.8/rbosa.rb.org
39c39
<   gem 'xml/libxml', '= 0.3.8.4'
---
>   require 'xml/libxml'

とりあえず、irbでrbosaをrequireしてもエラーは出なくなった。

irb -r rbosa
>> itunes = OSA.app('iTunes')
=> <OSA::ITunes::Application:0x10173bb38 desc="'sign'($6B6F6F68$)">

iTunesでレートは★★★★★だけどLast.fmで "Love" マークが付いてない曲を再生しながら、もう一度 ruby love.rb してみたところ、 {"status"=>"ok"} が返ってきた。ちゃんとLast.fmで "Love" されてた。iTunesで音楽を聴いてるときにcronで回してあげれば常にレート5の曲をLast.fmで "Love" してくれるようになる。Launch Daemon化とかはやり方が分からないのでそのうち調べる。

| @ブログ

ポータルシットをリニューアルしようかと思ってます。ブログプラットフォームは2003年の時点で完成されてて、P_BLOGの提供する機能に不満なところはないんだけど、コメント欄を含むP_BLOGのMySQLのデータをうまい具合に移行して作り直したらいろいろ勉強になるだろうなと思って。目指してるのはRESTfulであることと、シンプルであること、Ruby製であること。RubyベースのCMSかRailsで置き換えようと思います。納期は未定。

| @技術/プログラミング

ポータルシットのコメント一覧ページで、マウスオーバーして全文を取得するやつをかっこよくした。

これまではjQueryでスクレイピングして、記事のパーマリンクからコメントを取得していた。しかしこれは無駄なクエリが発生する。記事本文を取得するクエリとコメントを取得するクエリだ。

これはださいと思っていたので、Rubyでコメントを取得してJSONで返すCGIを書いた。

#! /usr/bin/env ruby
#-*- coding: utf-8 -*-
start_time = Time.now

require "rubygems"
require "active_record"
require "mysql"
require "kconv"
require "cgi"

ActiveRecord::Base.establish_connection(
  :adapter  => "mysql",
  :database => "database_name",
  :host     => "mysql.host.name",
  :username => "mysql_username",
  :password => "mysql_password",
  :socket   => "/path/to/mysqld.sock",
  :encoding => "utf8"
)

class Comment < ActiveRecord::Base
  set_table_name 'p_forum'
  
  def self.some_comment(n)
    find(n)
  rescue ActiveRecord::RecordNotFound
    return false
  end
end

cgi = CGI.new
comment_id = cgi.params['id'][0]
@comment = Comment.some_comment(comment_id)
redirect_url = '/var/index.php?id=error404'
print cgi.header({ 'status' => 'REDIRECT', 'Location' => redirect_url }) unless @comment
cgi.out("application/json") {
  {:title => @comment.title, :user_name => @comment.user_name, :user_uri => @comment.user_uri, :date => @comment.date, :mod => @comment.mod, :comment => @comment.comment, :generation => Time.now - start_time}.to_json
}

ActiveRecordのおかげでさくっとできる。このCGIにjQueryで $.getJSON() してJSONをページ内に読み込む。各コメントはMarkdownに似た形式で記述されているので、Showdown.js を使って Markdown->HTML して表示している。参考までにコードはこんな感じ。

// load entire comment by JSON
$(document).ready(function() {
  $("#recent-comment-list a.taggedlink").one("mouseover", function() {
    var targetUrl = $(this).attr("href");
    targetUrl.match(/#c(d+)$/);
    var commentId = RegExp.$1;
    var commentLoadDiv = 'div#c' + commentId;
    var commentAuthorParagraph = 'div#c' + commentId + ' + p.auth';
    $.getJSON(
      'comments.cgi',
      { "id": commentId },
      function(data) {
        var converter = new Showdown.converter();
        var comment = converter.makeHtml(data.comment);
        $(commentAuthorParagraph).css("clear", "both");
        $(commentLoadDiv).html(comment).slideDown("slow");
        $(commentLoadDiv).wrap('<div class="comment-content"></div>');
      }
    );
  });
});

問い合わせのクエリはコメントを持ってる p_forum というテーブルへの一回だけになったが、RubyをCGIとして動かすと遅い。パフォーマンスは逆に落ちてるかも知れないけど、所詮自己満足なので問題なし。

追記: なんか脆弱性ありそうな気がしてきた…

| @Mac/iPhone

Alfred

Quicksilverのかわりに入れた。インターフェイスはお洒落。

PowerPack(£12)を購入すればディレクトリの閲覧やアクションの選択など、Quicksilver的な機能が使えるようにはなるけど、やはりQuicksilverに比べたら機能は少ない。特にQuicksilverのTriggersに相当する機能(ホットキー)がないのが移行してすぐは不便だった(iTunesの操作はすべてQuicksilverのTriggers経由で行っていたので)。

Alfredは日本語が通る

日本語が通るのは便利だ。例えばAddress Bookの人名検索をするとき。いちいちAddress Bookを開かず、Alfredの入力画面を呼び出して人名を入れるだけで検索できる。こんな感じ。

ただ、日本語が通るためTerminal.appなど、日本語環境で起動したときアプリケーション名がカタカナになってるソフトの起動時に日本語で呼び出さなきゃいけないのが地味に面倒くさい。Quicksilverでは「terminal」と入れれば良いものを、Alfredでは「ta-minaru」と入力した後、スペースキーでカタカナに変換し、さらにリターンキーで確定しないといけない。Terminal一つ起動するのになんでここまで苦労しなければならないのかと泣けてくる。

なんかネガティブな感想が多くなってしまったけど、事実上Quicksilverは開発止まってるし、Mac OS Xのアップデートである日いきなり使えなくなることも考えられるので、Quicksilverに依存しきりの人はランチャーの「次の選択肢」を考えておいた方がいいかも。

Divvy

最初はBreezeというソフトの方をmacZOTで知ってこういうウィンドウサイズ管理ソフトの導入を検討してた。Breeze買おうかなと思ってたんだけど、たまたまDivvyの存在を知ってこっちを使ってみたら、HUDっぽいUIで画面サイズを簡単に変更できるところが素晴らしくて、BreezeやめてDivvyを買った。

RubyKaigiで近くに座ってる人のMacBookの使い方を見てたらやたらSpacesでたくさん画面を作って切り替えながら作業してる人が多かった。

Spacesはメモリの量が少ないMacでやると重いので自分は使ってない。そもそもSpacesで複数の画面を切り替えて使っても、例えばブラウザーを見ながらテキストエディターに何かを入力するみたいな作業が必要なときには頻繁にスペースを切り替えなければならず、大変うざい。

一発でアプリケーションウィンドウサイズを変更して左にブラウザー、右にエディターみたいな使い方が出来たら便利だ。DivvyやBreezeならこういうことが出来る。Breezeの場合はウィンドウサイズと位置をあらかじめ登録しておかなければいけないけど、DivvyはHUDポップアップウィンドウを呼び出して、ドラッグで好きなようにウィンドウサイズ・位置を変更できる。こんな感じ。

13インチのMacBook Proは1280×800という解像度のため、データを参照しながらのテキスト入力などでは生産性がいまいちだけど、Divvyなどを使うことでセカンドディスプレイがなくてもデータを参照しながら効率的に入力作業を行うことが出来る。大変素晴らしい。

職場が変わって仕事ではWindows漬けだけど、Windowsにはこの辺の作業を快適にしてくれるソフトが少なくて、改めてMac良いと思う。Terminal内での操作感は基本的にUNIXやLinuxと同じだし。Macで仕事できてる人たちが本当にうらやましい。

| @雑談

毎晩泣きながらRubyKaigi 2010で買った『情熱プログラマー』を読んで寝てる。ちなみに250円の弁当はまだ一度も買ったことない。

| @技術/プログラミング

Ruby 1.9、Rails 3、RSpec 2で開発してる。いままでRubyとRailsになれるのに一杯一杯でテスト駆動開発できてなかったので、きちんとテストファーストでやることにした。

そんで環境を整えてたんだけど、RSpecはRails 3に合わせてVersion 2が出てるみたい。しかも結構変わってる。

$ spec -c spec/*

とかやってもエラーが出る。 which spec すると /usr/bin/spec と出ちゃう。どうやら spec で発動されるのはRSpec 1.3のものみたい。

RSpec 2からはコマンド名が変更されており、テストコードを実行したいときは以下のように書くみたい。

$ rspec -c spec/*

これできちんとテストコードが実行された。かと思いきやFailureが。

Ruby 1.9で動かしてるから、コードの中に日本語を書くときは一行目に

# -*- coding: utf-8 -*-

と書いてテキストエンコーディングを明示してあげないといけない。

| @技術/プログラミング

動かしてるサイトのCakePHPのバージョンを最新版の1.3.4に上げようと思って、Media PluginもCakePHP 1.3対応バージョンの1.3alphaにアップデートしようとした。

とりあえず本体を git clone http://github.com/cakephp/cakephp.git し、Media Pluginを git clone http://github.com/davidpersson/media.git してみた。

Media Plugin 1.3での設定方法とか調べてみようと思って、GitHub上のWikiのページを探すんだけど見つからない。なんと、作者サマはVer 1.3からWikiを消しちゃったみたい! そんまま動かしてみたところではMedia Plugin動いてないみたい。Mediumヘルパーがないというエラーが出る。プロジェクトの中の docs ディレクトリにドキュメントが格納されていたのを発見したので(docs at 1.3 from davidpersson's media - GitHub)そこを参考にしながらMedia Plugin 0.6から1.3へのMigration作業をやったんだけど、とうとうできなかった。

まず第一に、クラス名が変わってる。Media.Medium だったのが Media.Media になってる。Viewファイル内での変数も $medium ではなく、 $media になってる。そしてメソッドとかもHTML5対応とかで結構変わってるみたい。

さらに、media processing 関連のクラスが分割されて別のライブラリとしてMedia Pluginの中に含まれてる(davidpersson's mm at master - GitHub)。これが結構わかりにくい。なんかImagick必要ぽくて、本番環境じゃインストール権限ないので使えないし、結局ここで諦めてしまった。

Media PluginはVer 0.6のWikiがあった頃もなんかドキュメンが見づらかったし、1.3になってドキュメントはただのテキストファイルになり、しかもメソッドについての解説がないので結局本体のコードを読むしかない。

RubyのライブラリはたいていRdocとかついててドキュメントが充実してるので、あれに慣れるとドキュメントがわかりにくいライブラリやプラグインは億劫に感じてしまう。