require('md5') class FileCache cattr_accessor :config @@config = { :default_dir => RAILS_ROOT + "/public/images/cache/", :default_extension => "" } def self.get(options = {}, &block) get_or_create(options, &block) end def self.get_filename(options = {}, &block) get_or_create(options.merge(:get => :filename), &block) end def self.file_exists?(options = {}) File.exist?(filename(options.dup)) end def self.put(options = {}, &block) get_or_create(options.merge(:recreate => true), &block) end protected def self.filename(opts) options = opts.sort {|a,b| a[0].to_s<=>b[0].to_s} # dump(options) prefix = options.delete(:prefix) || "" dir = options.delete(:dir) || @@config[:default_dir] extension = options.delete(:extension) || @@config[:default_extension] filename = options.delete(:filename) || (MD5.new(options.to_s).to_s + extension) filename = "#{prefix}#{filename}" if prefix filename = "#{dir}/#{filename}" end def self.get_or_create(opts = {}, &block) options = opts.dup get = options.delete(:get) recreate = options.delete(:recreate) filename = filename(options) obj = nil if recreate || !File.exist?(filename) FileUtils.mkdir_p(filename.slice(%r{.+/})) obj = block.call(options) File.open(filename, "wb") {|f| obj.is_a?(String) ? f.write(obj) : Marshal.dump(obj, f)} end return filename if (get == :filename) return obj unless obj.nil? File.open(filename, "rb") do |f| if (f.getc == Marshal::MAJOR_VERSION && f.getc == Marshal::MINOR_VERSION) f.rewind obj = Marshal.load(f) else f.rewind obj = f.read end end obj end end