Class: Saviour::S3Storage

Inherits:
Object
  • Object
show all
Defined in:
lib/saviour/s3_storage.rb

Constant Summary collapse

MissingPublicUrlPrefix =
Class.new(StandardError)
KeyTooLarge =
Class.new(StandardError)

Instance Method Summary collapse

Constructor Details

#initialize(conf = {}) ⇒ S3Storage

Returns a new instance of S3Storage.



11
12
13
14
15
16
17
18
19
# File 'lib/saviour/s3_storage.rb', line 11

def initialize(conf = {})
  @bucket = conf.delete(:bucket)
  @public_url_prefix = conf.delete(:public_url_prefix)
  @conf = conf
  @create_options = conf.delete(:create_options) { {} }
  conf.fetch(:aws_access_key_id) { raise(ArgumentError, "aws_access_key_id is required") }
  conf.fetch(:aws_secret_access_key) { raise(ArgumentError, "aws_secret_access_key is required") }
  @region = conf[:region] || raise(ArgumentError, "region is required")
end

Instance Method Details

#cp(source_path, destination_path) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/saviour/s3_storage.rb', line 82

def cp(source_path, destination_path)
  source_path = sanitize_leading_slash(source_path)
  destination_path = sanitize_leading_slash(destination_path)

  client.copy_object(
    @create_options.merge(
      copy_source: "/#{@bucket}/#{source_path}",
      bucket: @bucket,
      key: destination_path
    )
  )
rescue Aws::S3::Errors::NoSuchKey
  raise FileNotPresent, "Trying to cp an unexisting path: #{source_path}"
end

#delete(path) ⇒ Object



55
56
57
58
59
60
61
62
# File 'lib/saviour/s3_storage.rb', line 55

def delete(path)
  path = sanitize_leading_slash(path)

  client.delete_object(
    bucket: @bucket,
    key: path,
  )
end

#exists?(path) ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
67
68
69
70
71
72
73
# File 'lib/saviour/s3_storage.rb', line 64

def exists?(path)
  path = sanitize_leading_slash(path)

  !!client.head_object(
    bucket: @bucket,
    key: path
  )
rescue Aws::S3::Errors::NotFound
  false
end

#mv(source_path, destination_path) ⇒ Object



97
98
99
100
# File 'lib/saviour/s3_storage.rb', line 97

def mv(source_path, destination_path)
  cp(source_path, destination_path)
  delete(source_path)
end

#public_url(path) ⇒ Object



75
76
77
78
79
80
# File 'lib/saviour/s3_storage.rb', line 75

def public_url(path)
  raise(MissingPublicUrlPrefix, "You must provide a `public_url_prefix`") unless public_url_prefix

  path = sanitize_leading_slash(path)
  ::File.join(public_url_prefix, path)
end

#read(path) ⇒ Object



51
52
53
# File 'lib/saviour/s3_storage.rb', line 51

def read(path)
  get_file_stringio(path).read
end

#read_to_file(path, dest_file) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/saviour/s3_storage.rb', line 38

def read_to_file(path, dest_file)
  dest_file.binmode
  dest_file.rewind
  dest_file.truncate(0)

  io = get_file_stringio(path)
  while data = io.read(1024 * 1024)
    dest_file.write(data)
  end

  dest_file.flush
end

#write(file_or_contents, path) ⇒ Object



21
22
23
24
25
26
27
28
29
30
# File 'lib/saviour/s3_storage.rb', line 21

def write(file_or_contents, path)
  path = sanitize_leading_slash(path)

  # http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html
  if path.bytesize > 1024
    raise(KeyTooLarge, "The key in S3 must be at max 1024 bytes, this key is too big: #{path}")
  end

  client.put_object(@create_options.merge(body: file_or_contents, bucket: @bucket, key: path))
end

#write_from_file(file, path) ⇒ Object



32
33
34
35
36
# File 'lib/saviour/s3_storage.rb', line 32

def write_from_file(file, path)
  file.rewind

  write(file, path)
end