AP4R で Parallels の壁を越える
Mac にようやく慣れてきたこのごろ、ストレスの非常に少い環境で、いままでとの快適さの違いを実感中。
そこで、ストレスが減ってきたために、ひとつ気になる点が目立ちはじめた。メーラーに Outlook を使う都合上、Parallels Desktop で Windows を動かしてる。そこで、メールの中にある URL をポチッと押したときに、Windows 上の Firefox でページが開くのがとても気になる。そこで Mac 側の Firefox が開いてほしいんよね。というわけで、なんとかして http(s) を Mac の Firefox でひらくようにしてみる。
たぶん、それなりに簡単に出来るんじゃ、、、というのは無視して、AP4R を使ってやる。あくまでも最小構成は目指しません。というわけで、使うものは、以下。
- MozRepl (Firefox extenstion): telnet で Firefox をいじれる
- Ruby: telnet クライアント, AP4R, Rails を動かす、Windows 側でもスクリプトとして使用、感謝
- AP4R: 永続化付き非同期メッセージング、あきらかに牛刀
- Rails: なんとなく
- あとは、とうぜん Firefox と、レジストリエディタくらいか
MozRepl の練習
一番わからないところから入る。MozLab という拡張。はっきりいってこれが一番大事で、あとはどうでもよかったりする。
参考はここ、Ruby スクリプトも参考にさせていただきました。
最速インターフェース研究会 :: Firefoxの拡張MozLabの中に含まれるMozReplがヤバすぎる件について
開始するには、[ツール]-[MozLab]-[Start Repl] で、ローカルホストで listen する telnet サーバが起動。あとはコマンドラインででもなんでも繋ぐだけ。ポートは 4242。日本では微妙か?
コマンドラインでひとしきり試し打ちしたあと、Ruby スクリプトを書いてみる。のだけど、ここはワザワザ Rails アプリにする。これも牛刀だなぁ。
require 'net/telnet' class FirefoxController < ApplicationController def open if request.post? telnet = nil begin prompt = /^repl> / telnet = Net::Telnet.new("Host" => "localhost", "Port" => 4242, "Timeout" => 10, "Prompt" => prompt) telnet.waitfor(prompt) telnet.cmd <<-JS_SCRIPT do |c| (function(){ window.top.getBrowser().selectedTab = window.top.getBrowser().addTab(\"#{params[:url]}\"); return true; })(); JS_SCRIPT logger.info("Opened URL in Firefox: #{params[:url]}") end ensure telnet.close if telnet end end end end
ビュー
<% form_tag :action => "open" do -%> <%= hidden_field_tag 'for_ap4r', "true" %> <%= text_field_tag 'url', params[:url] || "http://ap4r.rubyforge.org/wiki/wiki.pl", :size => 40 %> <%= submit_tag 'open' %> <% end -%>
これで、 http://localhost:3000/firefox/open をひらいて、URL いれて open とやると別タブで開くところまで OK。hidden は、AP4R のレスポンスに(今のところ)必要なちょっといけてない仕様。見えなければ、スタイルででも良い。見えても気にしないならテキストでも良い。
AP4R 設定、起動
AP4R をインストールしてあれば、ap4r_setup でワークスペースを生成。今回は、設定ファイルと起動スクリプトとをそれぞれ一つしか要らないので、RAILS_ROOT/config/queues_disk.cfg, RAILS_ROOT/script/mongrel_ap4r にコピー、生成したワークスペースは削除。ローカルホストの外側からアクセスしたいので、reliable-msg にちょっと変更。修正箇所は、id:kiwamu さんとこに書いてあるとおり。
kiwamu日記 - ap4r-0.3.0 リリース
reliable-msg へのパッチをあてる
http://d.hatena.ne.jp/kiwamu/20070406/1175859018
加えて、queue-manager.rb については、修正した行の、localhost を、#{drb['host']||'localhost'} にしておく。
queues_disk.cfg で、drb: の設定を少々変更。
- listen する NIC を設定。ぼくは単純に全部で。セキュリティに気をつかう環境では絞ったほうがよいかもね。(Rails も注意、ローカルホストだけで良い)
- ACL をいじって、Windows 側の IP を ALLOW に入れておく
修正後
drb: host: 0.0.0.0 port: 6438 acl: allow 127.0.0.1 allow ::1 allow [ここに Windows の IP]
起動は、ふつうに。
% mongrel_ap4r start -d -A config/queues_disk.cfg
動作確認を IRB で。キューの名前は、queue. で始まれば(ここでは)何でも良い。
>> require 'reliable-msg' => ["ReliableMsg"] >> q = ReliableMsg::Queue.new 'queue.firefox.open' => #<ReliableMsg::Queue:0x264b980 @queue="queue.firefox.open"> >> q.put 'url=http://www.google.co.jp', {:dispatch_mode => :HTTP, :target_url => "http://localhost:3000/firefox/open"}
Windows の HTTP を処理するスクリプトを書いて設定
URL を貰ったら、それをパラメータとしてメッセージを一つ、キューにいれるスクリプト post_url.rb。Windows 側に、RubyGems とか reliable-msg を入れるのが面倒だったら、DRb のみでもいける。そのときは、reliable-msg の ReliableMsg::Queue とか、ReliableMsg::QueueManager を見て、パラメータの渡し方を見れば OK。
url = ARGV[0] require 'rubygems' require 'reliable-msg' q = ReliableMsg::Queue.new "queue.firefox.open", :drb_uri => "druby://[ここには Mac の IP を入れる]:6438" q.put "url=#{url}", {:dispatch_mode => :HTTP, :target_url => "http://localhost:3000/firefox/open"}
同じフォルダに、post_url.cmd 作成。
ruby %~dp0post_url.rb %*
あとは、このファイルを、HTTP プロトコルで呼ばれるプログラムに関連付ける。HKCU\Software\Classes\HTTP 以下に値を書き込む。Microsoft のサポート情報はこのへん http://support.microsoft.com/default.aspx/kb/256986/ja 。あとは、HKEY_CURRENT_USER\Software\Classes\HTTP でググッたらいくらか出てくるので。http://www.codingforums.com/showthread.php?t=36323 は丁寧に書いてある。
ここまで出来たら、Outlook を開いて、なんか URL をクリックすると、Mac の Firefox が新しいタブで開いてくれました。プロセス経由しすぎ。