Class: CarrierWave::Storage::Fog::File

Inherits:
Object
  • Object
show all
Includes:
Utilities::Uri
Defined in:
lib/carrierwave/storage/fog.rb

Constant Summary

Constants included from Utilities::Uri

Utilities::Uri::SAFE_STRING, Utilities::Uri::UNSAFE

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uploader, base, path) ⇒ File

Returns a new instance of File.



285
286
287
# File 'lib/carrierwave/storage/fog.rb', line 285

def initialize(uploader, base, path)
  @uploader, @base, @path, @content_type = uploader, base, path, nil
end

Instance Attribute Details

#pathObject (readonly)

Current local path to file

Returns

String

a path to file



173
174
175
# File 'lib/carrierwave/storage/fog.rb', line 173

def path
  @path
end

Instance Method Details

#attributesObject

Return all attributes from file

Returns

Hash

attributes from file



182
183
184
# File 'lib/carrierwave/storage/fog.rb', line 182

def attributes
  file.attributes
end

#authenticated_url(options = {}) ⇒ Object

Return a temporary authenticated url to a private file, if available Only supported for AWS, Rackspace, Google, AzureRM and Aliyun providers

Returns

String

temporary authenticated url

or
NilClass

no authenticated url available



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/carrierwave/storage/fog.rb', line 196

def authenticated_url(options = {})
  if ['AWS', 'Google', 'Rackspace', 'OpenStack', 'AzureRM', 'Aliyun'].include?(@uploader.fog_credentials[:provider])
    # avoid a get by using local references
    local_directory = connection.directories.new(:key => @uploader.fog_directory)
    local_file = local_directory.files.new(:key => path)
    expire_at = options[:expire_at] || ::Fog::Time.now + @uploader.fog_authenticated_url_expiration
    case @uploader.fog_credentials[:provider]
      when 'AWS', 'Google'
        # Older versions of fog-google do not support options as a parameter
        if url_options_supported?(local_file)
          local_file.url(expire_at, options)
        else
          warn "Options hash not supported in #{local_file.class}. You may need to upgrade your Fog provider."
          local_file.url(expire_at)
        end
      when 'Rackspace', 'OpenStack'
        connection.get_object_https_url(@uploader.fog_directory, path, expire_at, options)
      when 'Aliyun'
        expire_at = expire_at - Time.now
        local_file.url(expire_at)
      else
        local_file.url(expire_at)
    end
  end
end

#content_typeObject

Lookup value for file content-type header

Returns

String

value of content-type



229
230
231
# File 'lib/carrierwave/storage/fog.rb', line 229

def content_type
  @content_type || file.try(:content_type)
end

#content_type=(new_content_type) ⇒ Object

Set non-default content-type header (default is file.content_type)

Returns

String

returns new content type value



240
241
242
# File 'lib/carrierwave/storage/fog.rb', line 240

def content_type=(new_content_type)
  @content_type = new_content_type
end

#copy_to(new_path) ⇒ CarrierWave::Storage::Fog::File

Creates a copy of this file and returns it.

Parameters

new_path (String)

The path where the file should be copied to.

Returns

Returns:



444
445
446
447
# File 'lib/carrierwave/storage/fog.rb', line 444

def copy_to(new_path)
  connection.copy_object(@uploader.fog_directory, file.key, @uploader.fog_directory, new_path, acl_header)
  CarrierWave::Storage::Fog::File.new(@uploader, @base, new_path)
end

#deleteObject

Remove the file from service

Returns

Boolean

true for success or raises error



251
252
253
254
255
256
# File 'lib/carrierwave/storage/fog.rb', line 251

def delete
  # avoid a get by just using local reference
  directory.files.new(:key => path).destroy.tap do |result|
    @file = nil if result
  end
end

#exists?Boolean

Check if the file exists on the remote service

Returns

Boolean

true if file exists or false

Returns:

  • (Boolean)


326
327
328
# File 'lib/carrierwave/storage/fog.rb', line 326

def exists?
  !!file
end

#extensionObject

Return extension of file

Returns

String

extension of file or nil if the file has no extension



265
266
267
268
# File 'lib/carrierwave/storage/fog.rb', line 265

def extension
  path_elements = path.split('.')
  path_elements.last if path_elements.size > 1
end

#filename(options = {}) ⇒ Object

Return file name, if available

Returns

String

file name

or
NilClass

no file name available



428
429
430
431
# File 'lib/carrierwave/storage/fog.rb', line 428

def filename(options = {})
  return unless file_url = url(options)
  CGI.unescape(file_url.split('?').first).gsub(/.*\/(.*?$)/, '\1')
end

#headersObject

deprecated: All attributes from file (includes headers)

Returns

Hash

attributes from file



277
278
279
280
281
282
283
# File 'lib/carrierwave/storage/fog.rb', line 277

def headers
  location = caller.first
  warning = "[yellow][WARN] headers is deprecated, use attributes instead[/]"
  warning << " [light_black](#{location})[/]"
  Formatador.display_line(warning)
  attributes
end

#public_urlObject

Return a url to a public file, if available

Returns

String

public url

or
NilClass

no public url available



362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
# File 'lib/carrierwave/storage/fog.rb', line 362

def public_url
  encoded_path = encode_path(path)
  if host = @uploader.asset_host
    if host.respond_to? :call
      "#{host.call(self)}/#{encoded_path}"
    else
      "#{host}/#{encoded_path}"
    end
  else
    # AWS/Google optimized for speed over correctness
    case fog_provider
    when 'AWS'
      # check if some endpoint is set in fog_credentials
      if @uploader.fog_credentials.has_key?(:endpoint)
        "#{@uploader.fog_credentials[:endpoint]}/#{@uploader.fog_directory}/#{encoded_path}"
      else
        protocol = @uploader.fog_use_ssl_for_aws ? "https" : "http"

        subdomain_regex = /^(?:[a-z]|\d(?!\d{0,2}(?:\d{1,3}){3}$))(?:[a-z0-9\.]|(?![\-])|\-(?![\.])){1,61}[a-z0-9]$/
        valid_subdomain = @uploader.fog_directory.to_s =~ subdomain_regex && !(protocol == 'https' && @uploader.fog_directory =~ /\./)

        # if directory is a valid subdomain, use that style for access
        if valid_subdomain
          s3_subdomain = @uploader.fog_aws_accelerate ? "s3-accelerate" : "s3"
          "#{protocol}://#{@uploader.fog_directory}.#{s3_subdomain}.amazonaws.com/#{encoded_path}"
        else
          # directory is not a valid subdomain, so use path style for access
          "#{protocol}://s3.amazonaws.com/#{@uploader.fog_directory}/#{encoded_path}"
        end
      end
    when 'Google'
      # https://cloud.google.com/storage/docs/access-public-data
      "https://storage.googleapis.com/#{@uploader.fog_directory}/#{encoded_path}"
    else
      # avoid a get by just using local reference
      directory.files.new(:key => path).public_url
    end
  end
end

#readObject

Read content of file from service

Returns

String

contents of file



295
296
297
298
299
300
301
302
303
304
305
306
307
# File 'lib/carrierwave/storage/fog.rb', line 295

def read
  file_body = file.body

  return if file_body.nil?
  return file_body unless file_body.is_a?(::File)

  # Fog::Storage::XXX::File#body could return the source file which was upoloaded to the remote server.
  read_source_file(file_body) if ::File.exist?(file_body.path)

  # If the source file doesn't exist, the remote content is read
  @file = nil # rubocop:disable Gitlab/ModuleWithInstanceVariables
  file.body
end

#sizeObject

Return size of file body

Returns

Integer

size of file body



316
317
318
# File 'lib/carrierwave/storage/fog.rb', line 316

def size
  file.nil? ? 0 : file.content_length
end

#store(new_file) ⇒ Object

Write file to service

Returns

Boolean

true on success or raises error



336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'lib/carrierwave/storage/fog.rb', line 336

def store(new_file)
  if new_file.is_a?(self.class)
    new_file.copy_to(path)
  else
    fog_file = new_file.to_file
    @content_type ||= new_file.content_type
    @file = directory.files.create({
      :body         => fog_file ? fog_file : new_file.read,
      :content_type => @content_type,
      :key          => path,
      :public       => @uploader.fog_public
    }.merge(@uploader.fog_attributes))
    fog_file.close if fog_file && !fog_file.closed?
  end
  true
end

#url(options = {}) ⇒ Object

Return url to file, if avaliable

Returns

String

url

or
NilClass

no url available



411
412
413
414
415
416
417
# File 'lib/carrierwave/storage/fog.rb', line 411

def url(options = {})
  if !@uploader.fog_public
    authenticated_url(options)
  else
    public_url
  end
end