class Refile::S3

A refile backend which stores files in Amazon S3

@example

backend = Refile::Backend::S3.new(
  region: "sa-east-1",
  bucket: "my-bucket",
  prefix: "files"
)
file = backend.upload(StringIO.new("hello"))
backend.read(file.id) # => "hello"

Constants

VERSION

Attributes

access_key_id[R]
max_size[R]

Public Class Methods

new(region:, bucket:, max_size: nil, prefix: nil, hasher: Refile::RandomHasher.new, **s3_options) click to toggle source

Sets up an S3 backend

@param [String] region The AWS region to connect to @param [String] bucket The name of the bucket where files will be stored @param [String] prefix A prefix to add to all files. Prefixes on S3 are kind of like folders. @param [Integer, nil] max_size The maximum size of an uploaded file @param [#hash] hasher A hasher which is used to generate ids from files @param [Hash] s3_options Additional options to initialize S3 with @see docs.aws.amazon.com/AWSRubySDK/latest/AWS/Core/Configuration.html @see docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3.html

# File lib/refile/s3.rb, line 43
def initialize(region:, bucket:, max_size: nil, prefix: nil, hasher: Refile::RandomHasher.new, **s3_options)
  @s3_options = { region: region }.merge s3_options
  @s3 = Aws::S3::Resource.new @s3_options
  credentials = @s3.client.config.credentials
  raise S3CredentialsError unless credentials
  @access_key_id = credentials.access_key_id
  @bucket_name = bucket
  @bucket = @s3.bucket @bucket_name
  @hasher = hasher
  @prefix = prefix
  @max_size = max_size
end

Public Instance Methods

clear!(confirm = nil) click to toggle source

Remove all files in this backend. You must confirm the deletion by passing the symbol `:confirm` as an argument to this method.

@example

backend.clear!(:confirm)

@raise [Refile::Confirm] Unless the `:confirm` symbol has been passed. @param [:confirm] confirm Pass the symbol `:confirm` to confirm deletion. @return [void]

# File lib/refile/s3.rb, line 137
def clear!(confirm = nil)
  raise Refile::Confirm unless confirm == :confirm
  @bucket.objects(prefix: @prefix).delete
end
delete(id) click to toggle source
# File lib/refile/s3.rb, line 88
          def delete(id)
  object(id).delete
end
exists?(id) click to toggle source
# File lib/refile/s3.rb, line 125
          def exists?(id)
  object(id).exists?
end
get(id) click to toggle source
# File lib/refile/s3.rb, line 80
          def get(id)
  Refile::File.new(self, id)
end
object(id) click to toggle source
# File lib/refile/s3.rb, line 153
          def object(id)
  @bucket.object([*@prefix, id].join("/"))
end
open(id) click to toggle source
# File lib/refile/s3.rb, line 97
          def open(id)
  Kernel.open(object(id).presigned_url(:get))
end
presign() click to toggle source

Return a presign signature which can be used to upload a file into this backend directly.

@return [Refile::Signature]

# File lib/refile/s3.rb, line 146
def presign
  id = RandomHasher.new.hash
  signature = @bucket.presigned_post(key: [*@prefix, id].join("/"))
  signature.content_length_range(0..@max_size) if @max_size
  Signature.new(as: "file", id: id, url: signature.url.to_s, fields: signature.fields)
end
read(id) click to toggle source
# File lib/refile/s3.rb, line 105
          def read(id)
  object(id).get.body.read
rescue Aws::S3::Errors::NoSuchKey
  nil
end
size(id) click to toggle source
# File lib/refile/s3.rb, line 115
          def size(id)
  object(id).get.content_length
rescue Aws::S3::Errors::NoSuchKey
  nil
end
upload(uploadable) click to toggle source
# File lib/refile/s3.rb, line 60
                  def upload(uploadable)
  id = @hasher.hash(uploadable)

  if uploadable.is_a?(Refile::File) and uploadable.backend.is_a?(S3) and uploadable.backend.access_key_id == access_key_id
    object(id).copy_from(copy_source: [@bucket_name, uploadable.backend.object(uploadable.id).key].join("/"))
  else
    object(id).put(body: uploadable, content_length: uploadable.size)
  end

  Refile::File.new(self, id)
end