Class: Refile::S3

Inherits:
Object
  • Object
show all
Extended by:
BackendMacros
Defined in:
lib/refile/s3.rb,
lib/refile/s3/version.rb

Overview

A refile backend which stores files in Amazon S3

Examples:

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"

Constant Summary collapse

VERSION =
"0.2.0"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(region:, bucket:, max_size: nil, prefix: nil, hasher: Refile::RandomHasher.new, **s3_options) ⇒ S3

Sets up an S3 backend

Parameters:

  • region (String)

    The AWS region to connect to

  • bucket (String)

    The name of the bucket where files will be stored

  • prefix (String) (defaults to: nil)

    A prefix to add to all files. Prefixes on S3 are kind of like folders.

  • max_size (Integer, nil) (defaults to: nil)

    The maximum size of an uploaded file

  • hasher (#hash) (defaults to: Refile::RandomHasher.new)

    A hasher which is used to generate ids from files

  • s3_options (Hash)

    Additional options to initialize S3 with

Raises:

See Also:



43
44
45
46
47
48
49
50
51
52
53
54
# 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

Instance Attribute Details

#access_key_idObject (readonly)

Returns the value of attribute access_key_id.



31
32
33
# File 'lib/refile/s3.rb', line 31

def access_key_id
  @access_key_id
end

#max_sizeObject (readonly)

Returns the value of attribute max_size.



31
32
33
# File 'lib/refile/s3.rb', line 31

def max_size
  @max_size
end

Instance Method Details

#clear!(confirm = nil) ⇒ void

This method returns an undefined value.

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

Examples:

backend.clear!(:confirm)

Parameters:

  • confirm (:confirm) (defaults to: nil)

    Pass the symbol ‘:confirm` to confirm deletion.

Raises:

  • (Refile::Confirm)

    Unless the ‘:confirm` symbol has been passed.



137
138
139
140
# File 'lib/refile/s3.rb', line 137

def clear!(confirm = nil)
  raise Refile::Confirm unless confirm == :confirm
  @bucket.objects(prefix: @prefix).delete
end

#deletevoid

This method returns an undefined value.

Delete a file from this backend

Parameters:

  • id (String)

    The id of the file



88
89
90
# File 'lib/refile/s3.rb', line 88

verify_id def delete(id)
  object(id).delete
end

#exists?Boolean

Return whether the file with the given id exists in this backend.

Parameters:

  • id (String)

    The id of the file

Returns:

  • (Boolean)


125
126
127
# File 'lib/refile/s3.rb', line 125

verify_id def exists?(id)
  object(id).exists?
end

#getRefile::File

Get a file from this backend.

Note that this method will always return a File object, even if a file with the given id does not exist in this backend. Use FileSystem#exists? to check if the file actually exists.

Parameters:

  • id (String)

    The id of the file

Returns:

  • (Refile::File)

    The retrieved file



80
81
82
# File 'lib/refile/s3.rb', line 80

verify_id def get(id)
  Refile::File.new(self, id)
end

#openIO

Return an IO object for the uploaded file which can be used to read its content.

Parameters:

  • id (String)

    The id of the file

Returns:

  • (IO)

    An IO object containing the file contents



97
98
99
# File 'lib/refile/s3.rb', line 97

verify_id def open(id)
  Kernel.open(object(id).presigned_url(:get))
end

#presignRefile::Signature

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

Returns:

  • (Refile::Signature)


146
147
148
149
150
151
# 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

#readString

Return the entire contents of the uploaded file as a String.

Parameters:

  • id (String)

    The id of the file

Returns:

  • (String)

    The file’s contents



105
106
107
108
109
# File 'lib/refile/s3.rb', line 105

verify_id def read(id)
  object(id).get.body.read
rescue Aws::S3::Errors::NoSuchKey
  nil
end

#sizeInteger

Return the size in bytes of the uploaded file.

Parameters:

  • id (String)

    The id of the file

Returns:

  • (Integer)

    The file’s size



115
116
117
118
119
# File 'lib/refile/s3.rb', line 115

verify_id def size(id)
  object(id).get.content_length
rescue Aws::S3::Errors::NoSuchKey
  nil
end

#uploadRefile::File

Upload a file into this backend

Parameters:

  • uploadable (IO)

    An uploadable IO-like object.

Returns:

  • (Refile::File)

    The uploaded file



60
61
62
63
64
65
66
67
68
69
70
# File 'lib/refile/s3.rb', line 60

verify_uploadable 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