Class: Service::VeTosService

Inherits:
Service
  • Object
show all
Defined in:
lib/active_storage/service/ve_tos_service.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(access_key_id:, secret_access_key:, region:, bucket:, endpoint: nil, security_token: nil, public: false, host: nil, upload_host: nil, prefix: nil) ⇒ VeTosService

Returns a new instance of VeTosService.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/active_storage/service/ve_tos_service.rb', line 10

def initialize(access_key_id:, secret_access_key:, region:, bucket:,
               endpoint: nil, security_token: nil, public: false,
               host: nil, upload_host: nil, prefix: nil, **)
  @client = TOS::Client.new(
    access_key_id: access_key_id,
    secret_access_key: secret_access_key,
    region: region,
    endpoint: endpoint,
    security_token: security_token,
  )
  @bucket_name = bucket
  @prefix = prefix
  @public = public
  @host = host
  @upload_host = upload_host
end

Instance Attribute Details

#bucket_nameObject (readonly)

Returns the value of attribute bucket_name.



8
9
10
# File 'lib/active_storage/service/ve_tos_service.rb', line 8

def bucket_name
  @bucket_name
end

#hostObject (readonly)

Returns the value of attribute host.



8
9
10
# File 'lib/active_storage/service/ve_tos_service.rb', line 8

def host
  @host
end

#prefixObject (readonly)

Returns the value of attribute prefix.



8
9
10
# File 'lib/active_storage/service/ve_tos_service.rb', line 8

def prefix
  @prefix
end

#publicObject (readonly)

Returns the value of attribute public.



8
9
10
# File 'lib/active_storage/service/ve_tos_service.rb', line 8

def public
  @public
end

#upload_hostObject (readonly)

Returns the value of attribute upload_host.



8
9
10
# File 'lib/active_storage/service/ve_tos_service.rb', line 8

def upload_host
  @upload_host
end

Instance Method Details

#compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {}) ⇒ Object

Server-side compose isn’t supported by this minimal SDK; download all source keys and re-upload as a single object. Fine for small previews (variants, thumbnails) but not for very large composites.



126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/active_storage/service/ve_tos_service.rb', line 126

def compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {})
  buffer = +""
  source_keys.each do |key|
    buffer << bucket.get_object(path_for(key)).body
  end

  bucket.put_object(
    path_for(destination_key),
    buffer,
    content_type: content_type,
    metadata: ,
  )
end

#delete(key) ⇒ Object



58
59
60
61
62
63
64
# File 'lib/active_storage/service/ve_tos_service.rb', line 58

def delete(key)
  instrument :delete, key: key do
    bucket.delete_object(path_for(key))
  end
rescue TOS::ServerError => e
  raise unless e.status == 404
end

#delete_prefixed(prefix_value) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/active_storage/service/ve_tos_service.rb', line 66

def delete_prefixed(prefix_value)
  instrument :delete_prefixed, prefix: prefix_value do
    loop do
      page = bucket.list_objects(prefix: path_for(prefix_value), max_keys: 1000)
      break if page[:keys].empty?

      bucket.delete_multiple_objects(page[:keys])
      break unless page[:is_truncated]
    end
  end
end

#download(key, &block) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/active_storage/service/ve_tos_service.rb', line 40

def download(key, &block)
  if block_given?
    instrument :streaming_download, key: key do
      bucket.get_object(path_for(key), &block)
    end
  else
    instrument :download, key: key do
      bucket.get_object(path_for(key)).body
    end
  end
end

#download_chunk(key, range) ⇒ Object



52
53
54
55
56
# File 'lib/active_storage/service/ve_tos_service.rb', line 52

def download_chunk(key, range)
  instrument :download_chunk, key: key, range: range do
    bucket.get_object(path_for(key), range: range).body
  end
end

#exist?(key) ⇒ Boolean

Returns:

  • (Boolean)


78
79
80
81
82
83
84
# File 'lib/active_storage/service/ve_tos_service.rb', line 78

def exist?(key)
  instrument :exist, key: key do |payload|
    answer = head?(path_for(key))
    payload[:exist] = answer
    answer
  end
end

#headers_for_direct_upload(_key, content_type:, checksum:, content_length:, custom_metadata: {}) ⇒ Object



113
114
115
116
117
118
119
120
121
# File 'lib/active_storage/service/ve_tos_service.rb', line 113

def headers_for_direct_upload(_key, content_type:, checksum:, content_length:, custom_metadata: {}, **)
  headers = {
    "Content-Type" => content_type,
    "Content-Length" => content_length.to_s,
  }
  headers["Content-MD5"] = checksum if checksum
  .each { |k, v| headers["x-tos-meta-#{k}"] = v.to_s }
  headers
end

#upload(key, io, checksum: nil, content_type: nil, disposition: nil, filename: nil, custom_metadata: {}) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/active_storage/service/ve_tos_service.rb', line 27

def upload(key, io, checksum: nil, content_type: nil, disposition: nil, filename: nil, custom_metadata: {}, **)
  instrument :upload, key: key, checksum: checksum do
    body = io.respond_to?(:read) ? io.read : io.to_s
    bucket.put_object(
      path_for(key),
      body,
      content_type: content_type,
      content_md5: checksum,
      metadata: ,
    )
  end
end

#url(key, expires_in:, filename:, content_type:, disposition:) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/active_storage/service/ve_tos_service.rb', line 86

def url(key, expires_in:, filename:, content_type:, disposition:, **)
  instrument :url, key: key do |payload|
    generated_url = if @public && @host
        public_url(key)
      else
        private_url(key, expires_in: expires_in, filename: filename,
                         content_type: content_type, disposition: disposition)
      end
    payload[:url] = generated_url
    generated_url
  end
end

#url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {}) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/active_storage/service/ve_tos_service.rb', line 99

def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {})
  instrument :url, key: key do |payload|
    url = @client.presign(
      method: "PUT",
      bucket: @bucket_name,
      key: path_for(key),
      expires_in: expires_in.to_i,
    )
    url = url.sub(/^https:\/\/[^\/]+/, "https://#{@upload_host}") if @upload_host
    payload[:url] = url
    url
  end
end