Module: Studio::S3
- Defined in:
- lib/studio/s3.rb
Defined Under Namespace
Classes: Error, NotConfigured
Class Method Summary
collapse
Class Method Details
.bucket ⇒ Object
46
47
48
49
50
|
# File 'lib/studio/s3.rb', line 46
def bucket
prefix = Studio.s3_bucket_prefix
raise NotConfigured, "Studio.s3_bucket_prefix not set in config/initializers/studio.rb" if prefix.nil? || prefix.empty?
"#{prefix}-#{environment}"
end
|
.client ⇒ Object
90
91
92
93
94
95
|
# File 'lib/studio/s3.rb', line 90
def client
@client ||= begin
require "aws-sdk-s3"
Aws::S3::Client.new(region: region)
end
end
|
Whether this app can touch object storage at all. Callers that must
degrade rather than 500 (the /admin/emails uploader on an app whose
bucket was never provisioned) ask this instead of rescuing NotConfigured.
55
56
57
58
59
60
|
# File 'lib/studio/s3.rb', line 55
def configured?
bucket
true
rescue NotConfigured
false
end
|
.delete(key:) ⇒ Object
35
36
37
|
# File 'lib/studio/s3.rb', line 35
def delete(key:)
client.delete_object(bucket: bucket, key: full_key(key))
end
|
.download(key:) ⇒ Object
15
16
17
|
# File 'lib/studio/s3.rb', line 15
def download(key:)
client.get_object(bucket: bucket, key: full_key(key)).body.read
end
|
.exists?(key:) ⇒ Boolean
28
29
30
31
32
33
|
# File 'lib/studio/s3.rb', line 28
def exists?(key:)
client.head_object(bucket: bucket, key: full_key(key))
true
rescue Aws::S3::Errors::NotFound, Aws::S3::Errors::NoSuchKey
false
end
|
.full_key(key) ⇒ Object
Logical key -> the real object key in the bucket.
72
73
74
75
76
|
# File 'lib/studio/s3.rb', line 72
def full_key(key)
return key if key.nil?
"#{key_prefix}#{key}"
end
|
.key_prefix ⇒ Object
Studio.s3_key_prefix, normalized to "" or "something/". The namespace a
satellite app lives under when it shares another app's bucket.
64
65
66
67
68
69
|
# File 'lib/studio/s3.rb', line 64
def key_prefix
prefix = Studio.s3_key_prefix.to_s
return "" if prefix.empty?
prefix.end_with?("/") ? prefix : "#{prefix}/"
end
|
.list(prefix: nil, max: 1000) ⇒ Object
Returns LOGICAL keys (the app's key namespace stripped back off), so a
caller can feed any result straight back into download/delete/url.
41
42
43
44
|
# File 'lib/studio/s3.rb', line 41
def list(prefix: nil, max: 1000)
resp = client.list_objects_v2(bucket: bucket, prefix: full_key(prefix), max_keys: max)
resp.contents.map { |object| logical_key(object.key) }
end
|
.logical_key(key) ⇒ Object
The real object key -> logical key (inverse of full_key).
79
80
81
82
83
84
|
# File 'lib/studio/s3.rb', line 79
def logical_key(key)
prefix = key_prefix
return key if prefix.empty? || !key.to_s.start_with?(prefix)
key.to_s.delete_prefix(prefix)
end
|
.region ⇒ Object
86
87
88
|
# File 'lib/studio/s3.rb', line 86
def region
Studio.s3_region
end
|
.reset! ⇒ Object
97
98
99
|
# File 'lib/studio/s3.rb', line 97
def reset!
@client = nil
end
|
.signed_url(key:, expires_in: 3600) ⇒ Object
23
24
25
26
|
# File 'lib/studio/s3.rb', line 23
def signed_url(key:, expires_in: 3600)
require "aws-sdk-s3"
Aws::S3::Presigner.new(client: client).presigned_url(:get_object, bucket: bucket, key: full_key(key), expires_in: expires_in)
end
|
.upload(key:, body:, content_type: nil, cache_control: nil) ⇒ Object
7
8
9
10
11
12
13
|
# File 'lib/studio/s3.rb', line 7
def upload(key:, body:, content_type: nil, cache_control: nil)
opts = { bucket: bucket, key: full_key(key), body: body }
opts[:content_type] = content_type if content_type
opts[:cache_control] = cache_control if cache_control
client.put_object(**opts)
url(key: key)
end
|
.url(key:) ⇒ Object
19
20
21
|
# File 'lib/studio/s3.rb', line 19
def url(key:)
"https://#{bucket}.s3.#{region}.amazonaws.com/#{full_key(key)}"
end
|