--- layout: old_post title: Firefoxを自動リロードして快適開発生活 - Ruby>DRb>MozLab>Firefox permalink: /tatsuya/show/337-firefox-ruby-drb-mozlab-firefox ---

いまさらながら、ファイル更新を検知してMozLab経由telnetでFirefoxのページ更新をするRubyスクリプトを書いてみた
激しく車輪の再発明くさいけど、気にしない方向で。
自宅MacはローカルのみでOKだけど、どうせなのでサーバ + クライアントと分かれていても使えるように、DRbで通信してみた。

ローカルPC (reload-firefox.rb)

#!/usr/local/bin/ruby
require 'drb/drb'
require 'net/telnet'

DRB_PORT = 7575
MOZLAB_PORT = 4242

class ReloadFirefox
  def initialize(stream=$stdout)
    @stream = stream
    @telnet = Net::Telnet.new({
      "Host" => "localhost",
      "Port" => MOZLAB_PORT
    })
  end
  def reload
    @stream.puts "reload Firefox"
    @telnet.puts "content.location.reload(true)"
  end
end

uri = "druby://#{ARGV.shift}:#{DRB_PORT}"
DRb.start_service(uri, ReloadFirefox.new)
puts "start DRb server #{uri}"
sleep

サーバ側 (reload-checker.rb)

#!/usr/bin/ruby
require 'drb/drb'

WAIT_TIME = 3
RELOAD_TIME = 0.5
DRB_PORT = 7575

uri = ARGV.shift
firefox = DRbObject.new_with_uri("druby://#{uri}:#{DRB_PORT}")

check = []
while(name = ARGV.shift)
  check << Dir::pwd + "/" + name
end

last_time = Time.now
while true
  check.each do |name|
    file_time = File::mtime(name)
    if (last_time + WAIT_TIME) < file_time then
      p "file #{name} updated now..."
      firefox.reload
      last_time = file_time
    end
  end
  sleep(RELOAD_TIME)
end

サーバ側でファイルの更新を検知したらDRbでローカルPCへ通知、ローカルPCのプロセスがtelnetでFirefoxへページ更新命令を投げる。

実行手順 (ローカルPCIP 192.168.1.2 とする)

1) サーバ側でfoo.cssとbar.cssを監視する場合 ruby reload-checker.rb 192.168.1.2 foo.css bar.css
2) 以下ローカルPCで、FirefoxへMozLab拡張を入れて再起動 http://dev.hyperstruct.net/mozlab
3) Firefoxのメニューから Tools > MozLab > start repl でtelnet待ち受け開始
4) ローカルPC待ち受け開始 ruby reload-server.rb 192.168.1.2

でサーバ情報ファイルを変更してみる > ローカルPCのFirefoxが自動でページリロードする筈。cssとかviewの作業がかなり快適生活:)
クライアント&サーバ 共にローカルで完結するならこれで

#!/usr/local/bin/ruby
#reload-local.rb
require 'net/telnet'

WAIT_TIME = 3
RELOAD_TIME = 0.5

def reload_firefox(name)
  p "reload #{name}"
  @telnet.puts "content.location.reload(true)"
end

@telnet = Net::Telnet.new({
  "Host" => "localhost",
  "Port" => 4242
})
check = []
while(name = ARGV.shift)
  check << Dir::pwd + "/" + name
end

last_time = Time.now
while true
  check.each do |name|
    file_time = File::mtime(name)
    if (last_time + WAIT_TIME) < file_time then
      reload_firefox(name)
      last_time = file_time
    end
  end
  sleep(RELOAD_TIME)
end

ruby reload-local.rb hoge.txt とかで