class Miasma::Models::Storage::Local

Public Class Methods

new(args={}) click to toggle source

Create new instance

@param args [Hash] @return [self]

Calls superclass method
# File lib/miasma/contrib/local/storage.rb, line 18
def initialize(args={})
  super
  unless(::File.directory?(object_store_root))
    FileUtils.mkdir_p(object_store_root)
  end
end

Public Instance Methods

bucket_all() click to toggle source

Return all buckets

@return [Array<Models::Storage::Bucket>]

# File lib/miasma/contrib/local/storage.rb, line 70
def bucket_all
  Dir.new(object_store_root).map do |item|
    if(::File.directory?(::File.join(object_store_root, item)) && !item.start_with?('.'))
      Bucket.new(
        self,
        :id => ::File.basename(uri_unescape(item)),
        :name => ::File.basename(uri_unescape(item))
      ).valid_state
    end
  end.compact
end
bucket_destroy(bucket) click to toggle source

Destroy bucket

@param bucket [Models::Storage::Bucket] @return [TrueClass, FalseClass]

# File lib/miasma/contrib/local/storage.rb, line 42
def bucket_destroy(bucket)
  if(bucket.persisted?)
    FileUtils.rmdir(full_path(bucket))
    true
  else
    false
  end
end
bucket_path(bucket) click to toggle source

@return [String] escaped bucket name

# File lib/miasma/contrib/local/storage.rb, line 214
def bucket_path(bucket)
  ::File.join(object_store_root, uri_escape(bucket.name))
end
bucket_reload(bucket) click to toggle source

Reload the bucket

@param bucket [Models::Storage::Bucket] @return [Models::Storage::Bucket]

# File lib/miasma/contrib/local/storage.rb, line 55
def bucket_reload(bucket)
  if(bucket.persisted?)
    unless(::File.directory?(full_path(bucket)))
      bucket.data.clear
      bucket.dirty.clear
    else
      bucket.valid_state
    end
  end
  bucket
end
bucket_save(bucket) click to toggle source

Save bucket

@param bucket [Models::Storage::Bucket] @return [Models::Storage::Bucket]

# File lib/miasma/contrib/local/storage.rb, line 29
def bucket_save(bucket)
  unless(bucket.persisted?)
    FileUtils.mkdir_p(full_path(bucket))
    bucket.id = bucket.name
    bucket.valid_state
  end
  bucket
end
file_all(bucket) click to toggle source

Return all files within bucket

@param bucket [Bucket] @return [Array<File>] @todo pagination auto-follow

# File lib/miasma/contrib/local/storage.rb, line 107
def file_all(bucket)
  Dir.glob(::File.join(full_path(bucket), '*')).map do |item|
    if(::File.file?(item) && !item.start_with?('.'))
      item_name = item.sub("#{full_path(bucket)}/", '')
      item_name = uri_unescape(item_name)
      File.new(
        bucket,
        :id => ::File.join(bucket.name, item_name),
        :name => item_name,
        :updated => ::File.mtime(item),
        :size => ::File.size(item)
      ).valid_state
    end
  end.compact
end
file_body(file) click to toggle source

Fetch the contents of the file

@param file [Models::Storage::File] @return [IO, HTTP::Response::Body]

# File lib/miasma/contrib/local/storage.rb, line 201
def file_body(file)
  if(file.persisted?)
    tmp_file = Tempfile.new('miasma')
    tmp_path = tmp_file.path
    tmp_file.delete
    FileUtils.cp(full_path(file), tmp_path)
    File::Streamable.new(::File.open(tmp_path, 'rb'))
  else
    StringIO.new('')
  end
end
file_destroy(file) click to toggle source

Destroy file

@param file [Models::Storage::File] @return [TrueClass, FalseClass]

# File lib/miasma/contrib/local/storage.rb, line 153
def file_destroy(file)
  if(file.persisted?)
    FileUtils.rm(full_path(file))
    true
  else
    false
  end
end
file_filter(bucket, args) click to toggle source

Return filtered files

@param args [Hash] filter options @return [Array<Models::Storage::File>]

# File lib/miasma/contrib/local/storage.rb, line 86
def file_filter(bucket, args)
  Dir.glob(::File.join(full_path(bucket), "#{uri_escape(args[:prefix])}*")).map do |item|
    if(::File.file?(item) && !item.start_with?('.'))
      item_name = item.sub("#{full_path(bucket)}/", '')
      item_name = uri_unescape(item_name)
      File.new(
        bucket,
        :id => ::File.join(bucket.name, item_name),
        :name => item_name,
        :updated => ::File.mtime(item),
        :size => ::File.size(item)
      ).valid_state
    end
  end.compact
end
file_path(file) click to toggle source

@return [String] escaped file path

# File lib/miasma/contrib/local/storage.rb, line 219
def file_path(file)
  uri_escape(file.name)
end
file_reload(file) click to toggle source

Reload the file

@param file [Models::Storage::File] @return [Models::Storage::File]

# File lib/miasma/contrib/local/storage.rb, line 166
def file_reload(file)
  if(file.persisted?)
    new_info = Smash.new.tap do |data|
      data[:updated] = ::File.mtime(full_path(file))
      data[:size] = ::File.size(full_path(file))
      data[:etag] = Digest::MD5.hexdigest(::File.read(full_path(file))) # @todo Update for block building
      mime = MIME::Types.of(full_path(file)).first
      if(mime)
        data[:content_type] = mime.content_type
      end
    end
    file.load_data(file.attributes.deep_merge(new_info))
    file.valid_state
  end
  file
end
file_save(file) click to toggle source

Save file

@param file [Models::Storage::File] @return [Models::Storage::File]

# File lib/miasma/contrib/local/storage.rb, line 127
def file_save(file)
  if(file.dirty?)
    file.load_data(file.attributes)
    if(file.attributes[:body].respond_to?(:readpartial))
      file.body.rewind
      tmp_file = Tempfile.new('miasma')
      begin
        while(content = file.body.read(Storage::READ_BODY_CHUNK_SIZE))
          tmp_file.write content
        end
      rescue EOFError
      end
      tmp_file.flush
      tmp_file.close
      FileUtils.mv(tmp_file.path, full_path(file))
    end
    file.id = ::File.join(file.bucket.name, file.name)
    file.reload
  end
  file
end
file_url(file, timeout_secs) click to toggle source

Create publicly accessible URL

@param timeout_secs [Integer] seconds available @return [String] URL @todo where is this in swift?

# File lib/miasma/contrib/local/storage.rb, line 188
def file_url(file, timeout_secs)
  if(file.persisted?)
    "file://#{full_path(file)}"
    full_path(file)
  else
    raise Error::ModelPersistError.new "#{file} has not been saved!"
  end
end
full_path(file_or_bucket) click to toggle source

Provide full path for object

@param file_or_bucket [File, Bucket] @return [String]

# File lib/miasma/contrib/local/storage.rb, line 227
def full_path(file_or_bucket)
  if(file_or_bucket.is_a?(Bucket))
    bucket_path(file_or_bucket)
  else
    ::File.join(
      bucket_path(file_or_bucket.bucket),
      file_path(file_or_bucket)
    )
  end
end
uri_escape(string) click to toggle source

URL string escape

@param string [String] string to escape @return [String] escaped string @todo move this to common module

# File lib/miasma/contrib/local/storage.rb, line 243
def uri_escape(string)
  string.to_s.gsub(/([^a-zA-Z0-9_.\-~])/) do
    '%' << $1.unpack('H2' * $1.bytesize).join('%').upcase
  end
end
uri_unescape(string) click to toggle source

Un-escape URL escaped string

@param string [String] @return [String]

# File lib/miasma/contrib/local/storage.rb, line 253
def uri_unescape(string)
  string.to_s.gsub(/%([^%]{2})/) do
    [$1].pack('H2')
  end
end