开发者

Is there a unified way to get content at a file:// or http:// URI scheme in Ruby?

It appears the Net::HTTP library doesn't 开发者_运维知识库support loading of local file via file:// . I'd like to configure loading of content from a file or remotely, depending on environment.

Is there a standard Ruby way to access either type the same way, or barring that some succinct code that branches?


Do you know about open-uri?

require 'open-uri'

open("/home/me/file.txt") { |f| ... }
open("http://www.google.com") { |f| ... }

So to support either "http://" or "file://" in one statement, simply remove the "file://" from the beginning of the uri if it is present (and no need to do any processing for "http://"), like so:

uri = ...
open(uri.sub(%r{^file://}, ''))


Here's some experimental code that teaches "open-uri" to handle "file:" URIs:

require 'open-uri'
require 'uri'

module URI

  class File < Generic
    def open(*args, &block)
      ::File.open(self.path, &block)
    end
  end

  @@schemes['FILE'] = File

end


As Ben Lee pointed out, open-uri is the way to go here. I've also used it in combination with paperclip for storing resources associated with models, which makes everything brilliantly simple.

require 'open-uri'
class SomeModel < ActiveRecord::Base
  attr_accessor :remote_url

  has_attached_file :resource # etc, etc.

  before_validation :get_remote_resource, :if => :remote_url_provided?

  validates_presence_of :remote_url, :if => :remote_url_provided?,
                                     :message => 'is invalid or missing'

  def get_remote_resource
    self.resource = SomeModel.download_remote_resource(self.remote_url)
  end

  def self.download_remote_resource (uri)
    io = open(URI.parse(uri))
    def io.original_filename; base_uri.path.split('/').last; end
    io.original_filename.blank? ? nil : io
    rescue 
  end
end

# SomeModel.new(:remote_url => 'http://www.google.com/').save
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜