class OpenURI::Cache

Attributes

cache_path[RW]

Public Class Methods

get(key) click to toggle source

Retrieve file content and meta data from cache @param [String] key @return [StringIO]

# File lib/open-uri/cached.rb, line 34
def get(key)
  filename = filename_from_url(key)
  # TODO: head request to determine last_modified vs file modtime

  # Read metadata, if it exists
  meta = YAML::load(File.read("#{filename}.meta")) if File.exists?("#{filename}.meta")

  f = File.exists?(filename) ? StringIO.new(File.open(filename, "rb") { |f| f.read }) : nil

  # Add meta accessors
  if meta && f
    f.instance_variable_set(:"@meta", meta)

    def f.meta
      @meta
    end
    def f.base_uri
      @meta[:base_uri]
    end
    def f.content_type
      @meta[:content_type]
    end
    def f.charset
      @meta[:charset]
    end
    def f.content_encoding
      @meta[:content_encoding]
    end
    def f.last_modified
      @meta[:last_modified]
    end
    def f.status
      @meta[:status]
    end
  end

  f
end
invalidate(key, time = Time.now) click to toggle source

Invalidate cache for a key, optionally if older than time givan @param [String] key

URL of content to be invalidated

@param [Time] time

(optional): the maximum age at which the cached value is still acceptable

@return

Returns 1 if a cached value was invalidated, false otherwise
# File lib/open-uri/cached.rb, line 107
def invalidate(key, time = Time.now)
  filename = filename_from_url(key)
  File.delete(filename) if File.stat(filename).mtime < time
rescue Errno::ENOENT
  false
end
set(key, value) click to toggle source

Cache file content and metadata @param [String] key

URL of content to be cached

@param [StringIO] value

value to be cached, typically StringIO returned from `original_open_uri`

@return [StringIO]

Returns value
# File lib/open-uri/cached.rb, line 80
def set(key, value)
  filename = filename_from_url(key)
  mkpath(filename)

  # Save metadata in a parallel file
  if value.respond_to?(:meta)
    filename_meta = "#{filename}.meta"
    meta = value.meta
    meta[:status] = value.status if value.respond_to?(:status)
    meta[:content_type] = value.content_type if value.respond_to?(:content_type)
    meta[:base_uri] = value.base_uri if value.respond_to?(:base_uri)
    File.open(filename_meta, 'wb') {|f| YAML::dump(meta, f)}
  end

  # Save file contents
  File.open(filename, 'wb'){|f| f.write value.read }
  value.rewind
  value
end

Protected Class Methods

filename_from_url(url) click to toggle source
# File lib/open-uri/cached.rb, line 115
def filename_from_url(url)
  uri = URI.parse(url) # TODO: rescue here?
  [ @cache_path, uri.host, Digest::SHA1.hexdigest(url) ].join('/')
end
mkpath(path) click to toggle source
# File lib/open-uri/cached.rb, line 120
def mkpath(path)
  full = []
  dirs = path.split('/'); dirs.pop
  dirs.each do |dir|
    full.push(dir)
    dir = full.join('/')
    next if dir.to_s == ''
    Dir.mkdir(dir) unless File.exists?(dir)
  end
end