リハビリ開始
休み中に Rails アプリを作りたいのですが、まずは Ruby のリハビリから。
問題:Web 上からコンテンツを取得する。ただし更新されていない場合はムダなので持ってこない
回答:
#!/usr/local/bin/ruby -Ke # # $Id$ # require 'time' require 'net/http' require 'uri' require 'fileutils' require 'tempfile' Net::HTTP.version_1_2 class HTTPFile def initialize(url, path) @uri = URI.parse(url) @path = path @lastupdate = begin File.ctime(@path) rescue nil end end def update? return true unless @lastupdate Net::HTTP.start(@uri.host, @uri.port) do |http| case http.head(@uri.path, {"If-Modified-Since" => @lastupdate.httpdate}) when Net::HTTPSuccess true when Net::HTTPNotModified false else raise "unknown HTTP status" end end end def get Net::HTTP.start(@uri.host, @uri.port) do |http| tempfile = Tempfile.open("tmp-" + File.basename(@path), File.dirname(@path)) open(tempfile.path, "wb") do |f| http.get(@uri.path) do |data| f.write data end end FileUtils.install(tempfile.path, @path, {:mode => 0755}) tempfile.close end end end if __FILE__ == $0 [{:url => 'http://drweb.jp/download/programs/cureit/cureit.exe', :path => 'c:/temp/cureit.exe'}, {:url => 'http://drweb.jp/feeds/vbase.xml', :path => 'c:/temp/vbase.xml'}].each do |data| print data[:url] + " ... " httpfile = HTTPFile.new(data[:url], data[:path]) if httpfile.update? puts "modified, so get" httpfile.get else puts "not modified" end end puts "complete." end感想
- これで簡単な処理なら wget 呼ばなくて済みます。
- 更新されていないコンテンツを毎回ダウンロードしてしまうムダもなくなります。
- 恥ずかしながら If-Modified-Since ヘッダの使い方を初めて学びました。