Archive for 4月, 2011

Rackで静的サイトを公開する(DirectoryIndex対応版)

Time to Read

1分

Rackライブラリ自身に Rack::Static が添付されていますが、これ、ディレクトリを見に行った場合に自動的に「index.html」を見てくれるとか(Apacheで言うDirectoryIndex設定のこと)、そういう気を回してくれないんですね。

あと、普通にWEBrickを使えばいいんという話もあるでしょうけど、Rackアプリケーションとして実装する意味って結構あって、例えば Rack::URLMap なんかと組み合わせたりできたりします。

ということで、 Rack::Directory を少しだけ変更することで実装可能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env ruby
require 'rack'
require 'rack/contrib'
 
class Rack::StaticSite < Rack::Directory
  def initialize(root, options={})
    super(root, options[:app])
    @index_filenames = (
      case
      when options[:index]
        [options[:index]]
      when options[:indexes] && !options[:indexes].empty?
        options[:indexes]
      else
        ["index.html"]
      end
    )
  end
 
  def list_directory
    @index_filenames.each do |index|
      @stat = F.stat(File.join(@path, index))
      if @stat.file?
        return @app.call(@env.tap{|e| e['PATH_INFO'] = File.join(e['PATH_INFO'], index) })
      end
    end
    Rack::NotFound.new.call(@env)
  end
end
 
if __FILE__ == $0
  Signal.trap(:INT) { exit! }
  app = Rack::Builder.new { run Rack::StaticSite.new(ARGV[0] || ".") }
  Rack::Handler::WEBrick.run app, :Port => 9292
end

Gistはこちら。オプション等はソースから類推してください。コード自体は、微妙に添削可能かもしれません……。

Rack::NotFound は、 rack-contrib gemに含まれています。index.htmlが無いときはディレクトリを見せるようにしたければ、ただ一言 super と唱えればよろしい。

ワンライナーでも試せるよ!

1
wget https://gist.github.com/raw/909366/fa511a3716a83de433ca5c153fa3554476e8ced1/rack-static_site.rb -O- | ruby - public

 

Ruby – DateTimeオブジェクトの時差を変更する

Time to Read

30秒

DateTime#new_offset を用いて、引数に「何日」ずれるか(時差を24で割った値)を突っ込めば良い。日本なら、Rational(9, 24)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require 'date'
d = DateTime.parse("Tue, 22 Mar 2011 03:30:45 +0000")
#=> #<DateTime: 4714833881/1920,0,2299161>
d.to_s
#=> "2011-03-22T03:30:45+00:00"
d.offset
#=> Rational(0, 1)
d = d.new_offset(9)
#=> #<DateTime: 4714833881/1920,9,2299161>
d.to_s
#=> "2011-03-31T03:30:45+216:00"
d = d.new_offset(Rational(9, 24))
#=> #<DateTime: 4714833881/1920,3/8,2299161>
d.to_s
#=> "2011-03-22T12:30:45+09:00"

 

Grailsで、起動時のポートを指定

Time to Read

30秒

よくある設定なんですが、ふつうはGrailsの起動時に

1
grails -Dserver.port=9999 run-app

ってやると思います。でも、ローカルで常に別のプロセスが8080番をふさいでる……とかで、毎回指定するのが面倒な場合。

起動時のデフォルトポート指定は、grails-app/conf/Config.groovyじゃなくてgrails-app/conf/BuildConfig.groovyに以下の一行を追加します。

1
grails.server.port.http = 9999

これで、-Dserver.port指定が要らなくなります。

参考