Class: Jackal::Assets::Store

Inherits:
Object
  • Object
show all
Defined in:
lib/jackal-assets/store.rb

Overview

Object storage helper

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ Store

Create new instance

Parameters:

  • args (Hash) (defaults to: {})

Options Hash (args):

  • :bucket (String)

    bucket name

  • :provider (String)

    provider name



22
23
24
25
26
27
# File 'lib/jackal-assets/store.rb', line 22

def initialize(args={})
  @arguments = args.to_smash
  @connection_arguments = args[:connection]
  @bucket_name = args[:bucket]
  setup
end

Instance Attribute Details

#argumentsHash (readonly)

Returns initializer arguments.

Returns:

  • (Hash)

    initializer arguments



13
14
15
# File 'lib/jackal-assets/store.rb', line 13

def arguments
  @arguments
end

#bucketString

Returns bucket name.

Returns:

  • (String)

    bucket name



11
12
13
# File 'lib/jackal-assets/store.rb', line 11

def bucket
  @bucket
end

#connectionObject (readonly)

Returns remote connection if applicable.

Returns:

  • (Object)

    remote connection if applicable



15
16
17
# File 'lib/jackal-assets/store.rb', line 15

def connection
  @connection
end

Instance Method Details

#bucket_nameString

Returns name of bucket.

Returns:

  • (String)

    name of bucket



30
31
32
33
# File 'lib/jackal-assets/store.rb', line 30

def bucket_name
  @bucket_name ||
    Carnivore::Config.get(:jackal, :assets, :bucket)
end

#connection_argumentsSmash

Returns connection arguments.

Returns:

  • (Smash)

    connection arguments



36
37
38
39
40
# File 'lib/jackal-assets/store.rb', line 36

def connection_arguments
  (@connection_arguments ||
    Carnivore::Config.get(:jackal, :assets, :connection) ||
    Smash.new).to_smash
end

#delete(key) ⇒ TrueClass, FalseClass

Delete object

Parameters:

  • key (String)

Returns:

  • (TrueClass, FalseClass)


118
119
120
121
122
123
124
125
126
# File 'lib/jackal-assets/store.rb', line 118

def delete(key)
  remote_file = bucket.files.reload.get(key)
  if(remote_file)
    remote_file.destroy
    true
  else
    false
  end
end

#get(key) ⇒ File

Fetch object

Parameters:

  • key (String)

Returns:

  • (File)


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/jackal-assets/store.rb', line 62

def get(key)
  remote_file = bucket.files.filter(:prefix => key).detect do |item|
    item.name == key
  end
  if(remote_file)
    io = remote_file.body.io
    if(io.respond_to?(:path))
      io.rewind
      if(block_given?)
        begin
          while(data = io.readpartial(2048))
            yield data
          end
        rescue EOFError
        end
      end
      io.rewind
      io
    else
      e_file = Bogo::EphemeralFile.new('jackal-asset')
      e_file.binmode
      begin
        while(data = io.readpartial(2048))
          e_file.write data
          if(block_given?)
            yield data
          end
        end
      rescue EOFError
      end
      e_file.flush
      e_file.rewind
      e_file
    end
  else
    raise Error::NotFound.new "Remote file does not exist! (<#{bucket.name}>:#{key})"
  end
end

#pack(directory, name = nil) ⇒ File

Pack directory into compressed file

Parameters:

  • directory (String)
  • name (String) (defaults to: nil)

    tmp file base name

Returns:

  • (File)


147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/jackal-assets/store.rb', line 147

def pack(directory, name=nil)
  tmp_file = Tempfile.new(name || File.basename(directory))
  file_path = "#{tmp_file.path}.zip"
  tmp_file.delete
  entries = Hash[
    Dir.glob(File.join(directory, '**', '{*,.*}')).map do |path|
      next if path.end_with?('.')
      [path.sub(%r{#{Regexp.escape(directory)}/?}, ''), path]
    end
  ]
  Zip::File.open(file_path, Zip::File::CREATE) do |zipfile|
    entries.keys.sort.each do |entry|
      path = entries[entry]
      if(File.directory?(path))
        zipfile.mkdir(entry.dup)
      else
        zipfile.add(entry, path)
      end
    end
  end
  file = File.open(file_path, 'rb')
  file
end

#put(key, file) ⇒ TrueClass

Store object

Parameters:

  • key (String)
  • file (File)

Returns:

  • (TrueClass)


106
107
108
109
110
111
112
# File 'lib/jackal-assets/store.rb', line 106

def put(key, file)
  remote_file = bucket.files.reload.get(key) ||
    bucket.files.build(:name => key)
  remote_file.body = file
  remote_file.save
  true
end

#setupObject

Setup API connection and storage bucket



43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/jackal-assets/store.rb', line 43

def setup
  Carnivore.configure!(:verify)
  @connection = Miasma.api(
    connection_arguments.deep_merge(
      Smash.new(
        :type => :storage
      )
    )
  )
  @bucket = @connection.buckets.get(bucket_name)
  unless(@bucket)
    @bucket = @connection.buckets.build(:name => bucket_name).save
  end
end

#unpack(object, destination, *args) ⇒ String

Unpack object

Parameters:

  • object (File)
  • destination (String)
  • args (Symbol)

    argument list (:disable_overwrite)

Returns:

  • (String)

    destination



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/jackal-assets/store.rb', line 177

def unpack(object, destination, *args)
  if(File.exists?(destination) && args.include?(:disable_overwrite))
    destination
  else
    unless(File.directory?(destination))
      FileUtils.mkdir_p(destination)
    end
    if(object.respond_to?(:path))
      to_unpack = object.path
    elsif(object.respond_to?(:io))
      to_unpack = object.io
    else
      to_unpack = object
    end
    zfile = Zip::File.new(to_unpack)
    zfile.restore_permissions = true
    zfile.each do |entry|
      new_dest = File.join(destination, entry.name)
      if(File.exists?(new_dest))
        FileUtils.rm_rf(new_dest)
      end
      entry.restore_permissions = true
      entry.extract(new_dest)
    end
    destination
  end
end

#url(key, expires_in = nil) ⇒ String

URL for object

Parameters:

  • key (String)
  • expires_in (Numeric) (defaults to: nil)

    number of seconds url is valid

Returns:

  • (String)


133
134
135
136
137
138
139
140
# File 'lib/jackal-assets/store.rb', line 133

def url(key, expires_in=nil)
  remote_file = bucket.files.reload.get(key)
  if(remote_file)
    remote_file.url(expires_in)
  else
    raise Error::NotFound.new "Remote file does not exist! (<#{bucket}>:#{key})"
  end
end