Class: Refile::Backend::S3

Inherits:
Object
  • Object
show all
Defined in:
lib/refile/backend/s3.rb

Overview

A refile backend which stores files in Amazon S3

Examples:

backend = Refile::Backend::S3.new(
  access_key_id: "xyz",
  secret_access_key: "abcd1234",
  bucket: "my-bucket",
  prefix: "files"
)
file = backend.upload(StringIO.new("hello"))
backend.read(file.id) # => "hello"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Sets up an S3 backend with the given credentials.

Parameters:

  • access_key_id (String)
  • secret_access_key (String)
  • 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

See Also:



31
32
33
34
35
36
37
38
39
40
41
# File 'lib/refile/backend/s3.rb', line 31

def initialize(access_key_id:, secret_access_key:, bucket:, max_size: nil, prefix: nil, hasher: Refile::RandomHasher.new, **s3_options)
  @access_key_id = access_key_id
  @secret_access_key = secret_access_key
  @s3_options = { access_key_id: access_key_id, secret_access_key: secret_access_key }.merge s3_options
  @s3 = AWS::S3.new @s3_options
  @bucket_name = bucket
  @bucket = @s3.buckets[@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.



18
19
20
# File 'lib/refile/backend/s3.rb', line 18

def access_key_id
  @access_key_id
end

#max_sizeObject (readonly)

Returns the value of attribute max_size.



18
19
20
# File 'lib/refile/backend/s3.rb', line 18

def max_size
  @max_size
end

Instance Method Details

#clear!(confirm = nil)

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.



126
127
128
129
# File 'lib/refile/backend/s3.rb', line 126

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

#delete(id)

This method returns an undefined value.

Delete a file from this backend

Parameters:

  • id (Sring)

    The id of the file



77
78
79
# File 'lib/refile/backend/s3.rb', line 77

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

#exists?(id) ⇒ Boolean

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

Parameters:

  • id (Sring)

    The id of the file

Returns:

  • (Boolean)


114
115
116
# File 'lib/refile/backend/s3.rb', line 114

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

#get(id) ⇒ Refile::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 (Sring)

    The id of the file

Returns:



69
70
71
# File 'lib/refile/backend/s3.rb', line 69

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

#object(id) ⇒ Object



142
143
144
# File 'lib/refile/backend/s3.rb', line 142

def object(id)
  @bucket.objects[[*@prefix, id].join("/")]
end

#open(id) ⇒ IO

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

Parameters:

  • id (Sring)

    The id of the file

Returns:

  • (IO)

    An IO object containing the file contents



86
87
88
# File 'lib/refile/backend/s3.rb', line 86

def open(id)
  Kernel.open(object(id).url_for(:read))
end

#presignRefile::Signature

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

Returns:



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

def presign
  id = RandomHasher.new.hash
  signature = @bucket.presigned_post(key: [*@prefix, id].join("/"))
  signature.where(content_length: @max_size) if @max_size
  Signature.new(as: "file", id: id, url: signature.url.to_s, fields: signature.fields)
end

#read(id) ⇒ String

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



94
95
96
97
98
# File 'lib/refile/backend/s3.rb', line 94

def read(id)
  object(id).read
rescue AWS::S3::Errors::NoSuchKey
  nil
end

#size(id) ⇒ Integer

Return the size in bytes of the uploaded file.

Parameters:

  • id (Sring)

    The id of the file

Returns:

  • (Integer)

    The file's size



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

def size(id)
  object(id).content_length
rescue AWS::S3::Errors::NoSuchKey
  nil
end

#upload(uploadable) ⇒ Refile::File

Upload a file into this backend

Parameters:

  • uploadable (IO)

    An uploadable IO-like object.

Returns:



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/refile/backend/s3.rb', line 47

def upload(uploadable)
  Refile.verify_uploadable(uploadable, @max_size)

  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
    uploadable.backend.object(uploadable.id).copy_to(object(id))
  else
    object(id).write(uploadable, content_length: uploadable.size)
  end

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