activestorage-aliyun 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49de212acae6a9c8e99b3ca01602eca84414955eafc1f965b6e1a35fcdbc3241
4
- data.tar.gz: 8923a8b87a36f28d34ccac03369a13d1cb18c9db9da94843437c1ef8d281cb46
3
+ metadata.gz: 8e1d0cce28e49848d648e656a281dd9a0848b2e3f601fcce2813977501e9f321
4
+ data.tar.gz: ce8902fe4003bc87ebe1ae6a7f7f1b55af136a05fbabc44856eaaf0e9116d0c8
5
5
  SHA512:
6
- metadata.gz: cf61f0de45f6c8e7ea1e8b495beeab96ef523cb3984075b1b4727adb6dfc3fd8f3b97e8712825640482f8f34f2dc3b5142a9d384bba4d4fec7940f10bf623c98
7
- data.tar.gz: c35ecb00a20b765844b241fd8eda14a9eafab64de1894ba7ec5d4a885b1a188cb985590c5b7460ebe8794dca7ecd4b9df802fa0616f401d4afa3133b51bcad62
6
+ metadata.gz: 1d55c0ac4bfbe3dcf9ad29a37990cc843e3d3352a3b978c8ec2ca702e30d2207be7d3edad2e6f2b44f56c87bf330a79a00f5eb0a40b291fe24fa940d2d976b61
7
+ data.tar.gz: 11e6a67d777d4c07f2cd9edcfef2886d47ccc6f5561cebc43e9df95722bee051a7e19ee8986dec9ae05d3010756a06964be9a0aa7d40908c7ff518823f741c67
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ https://github.com/huacnlee/activestorage-aliyun/releases
2
+
3
+ ## 1.1.0
4
+
5
+ - Add custo_metadata args in service method for Rails 7 supports.
6
+
1
7
  ## 1.0.0
2
8
 
3
9
  - Update for support Rals 6.1 permanent URL, and compatiable with Rails 6.0.
data/README.md CHANGED
@@ -2,16 +2,14 @@
2
2
 
3
3
  Wraps the Aliyun OSS as an Active Storage service, use [Aliyun official Ruby SDK](https://github.com/aliyun/aliyun-oss-ruby-sdk) for upload.
4
4
 
5
-
6
- [![Gem Version](https://badge.fury.io/rb/activestorage-aliyun.svg)](https://badge.fury.io/rb/activestorage-aliyun) [![Build Status](https://travis-ci.org/huacnlee/activestorage-aliyun.svg)](https://travis-ci.org/huacnlee/activestorage-aliyun) [![Code Climate](https://codeclimate.com/github/huacnlee/activestorage-aliyun/badges/gpa.svg)](https://codeclimate.com/github/huacnlee/activestorage-aliyun) [![codecov.io](https://codecov.io/github/huacnlee/activestorage-aliyun/coverage.svg?branch=master)](https://codecov.io/github/huacnlee/activestorage-aliyun?branch=master)
7
-
5
+ [![Gem Version](https://badge.fury.io/rb/activestorage-aliyun.svg)](https://badge.fury.io/rb/activestorage-aliyun) [![build](https://github.com/huacnlee/activestorage-aliyun/workflows/build/badge.svg)](https://github.com/huacnlee/activestorage-aliyun/actions?query=workflow%3Abuild)
8
6
 
9
7
  ## Installation
10
8
 
11
9
  Add this line to your application's Gemfile:
12
10
 
13
11
  ```ruby
14
- gem 'activestorage-aliyun'
12
+ gem "activestorage-aliyun"
15
13
  ```
16
14
 
17
15
  And then execute:
@@ -22,17 +20,20 @@ $ bundle
22
20
 
23
21
  ## Usage
24
22
 
23
+ > NOTE! Current document work for Rails 6.1, if you are using Rails 6.0, please visit: https://github.com/huacnlee/activestorage-aliyun/tree/v0.6.4
24
+ > You can also to use activestorage-aliyun 1.0.0 in Rails 6.0
25
+
25
26
  config/storage.yml
26
27
 
27
28
  ```yml
28
29
  aliyun:
29
30
  service: Aliyun
30
- access_key_id: "your-oss-access-key-id"
31
- access_key_secret: "your-oss-access-key-secret"
32
- bucket: "bucket-name"
33
- endpoint: "https://oss-cn-beijing.aliyuncs.com"
31
+ access_key_id: 'your-oss-access-key-id'
32
+ access_key_secret: 'your-oss-access-key-secret'
33
+ bucket: 'bucket-name'
34
+ endpoint: 'https://oss-cn-beijing.aliyuncs.com'
34
35
  # path prefix, default: /
35
- path: "my-app-files"
36
+ path: 'my-app-files'
36
37
  # Bucket public: true/false, default: true, for generate public/private URL.
37
38
  public: true
38
39
  ```
@@ -42,13 +43,13 @@ aliyun:
42
43
  ```yml
43
44
  aliyun:
44
45
  service: Aliyun
45
- access_key_id: "your-oss-access-key-id"
46
- access_key_secret: "your-oss-access-key-secret"
47
- bucket: "bucket-name"
48
- endpoint: "https://file.myhost.com"
46
+ access_key_id: 'your-oss-access-key-id'
47
+ access_key_secret: 'your-oss-access-key-secret'
48
+ bucket: 'bucket-name'
49
+ endpoint: 'https://oss-cn-beijing.aliyuncs.com'
49
50
  public: false
50
- # Enable cname to use custom domain
51
- cname: true
51
+ # Custom host for get file url, if this present, upload still use `endpoint`, but download url will use this.
52
+ host: 'https://file.myhost.com'
52
53
  ```
53
54
 
54
55
  ### Use for image url
@@ -56,7 +57,7 @@ aliyun:
56
57
  ```erb
57
58
  Original File URL:
58
59
 
59
- <%= image_tag @photo.image.service_url %>
60
+ <%= image_tag @photo.image.url %>
60
61
  ```
61
62
 
62
63
  Thumb with OSS image service:
@@ -64,7 +65,7 @@ Thumb with OSS image service:
64
65
  ```rb
65
66
  class Photo < ApplicationRecord
66
67
  def image_thumb_url(process)
67
- self.image.service_url(params: { "x-oss-process" => process })
68
+ self.image.url(params: { "x-oss-process" => process })
68
69
  end
69
70
  end
70
71
  ```
@@ -72,7 +73,7 @@ end
72
73
  And then:
73
74
 
74
75
  ```erb
75
- <%= image_tag @photo.image.image_thumb_url("image/resize,h_100,w_100") %>
76
+ <%= image_tag @photo.image_thumb_url("image/resize,h_100,w_100") %>
76
77
  ```
77
78
 
78
79
  ### Use for file download
@@ -81,7 +82,7 @@ If you want to get original filename (Include Chinese and other UTF-8 chars), fo
81
82
 
82
83
  ```erb
83
84
  #
84
- <%= image_tag @photo.image.service_url(disposition: :attachment) %>
85
+ <%= image_tag @photo.image.url(disposition: :attachment) %>
85
86
  ```
86
87
 
87
88
  ## Contributing
@@ -19,17 +19,17 @@ module ActiveStorage
19
19
 
20
20
  CHUNK_SIZE = 1024 * 1024
21
21
 
22
- def upload(key, io, checksum: nil, content_type: nil, disposition: nil, filename: nil)
22
+ def upload(key, io, checksum: nil, content_type: nil, disposition: nil, filename: nil, custom_metadata: {}, **)
23
23
  instrument :upload, key: key, checksum: checksum do
24
24
  content_type ||= Marcel::MimeType.for(io)
25
- bucket.put_object(path_for(key), content_type: content_type) do |stream|
25
+ bucket.put_object(path_for(key), content_type: content_type, metas: custom_metadata) do |stream|
26
26
  stream << io.read(CHUNK_SIZE) until io.eof?
27
27
  end
28
28
  end
29
29
  end
30
30
 
31
31
  def download(key, &block)
32
- if block_given?
32
+ if block
33
33
  instrument :streaming_download, key: key do
34
34
  bucket.get_object(path_for(key), &block)
35
35
  end
@@ -39,7 +39,7 @@ module ActiveStorage
39
39
  bucket.get_object(path_for(key)) do |chunk|
40
40
  chunk_buff << chunk
41
41
  end
42
- chunk_buff.join("")
42
+ chunk_buff.join
43
43
  end
44
44
  end
45
45
  end
@@ -51,7 +51,7 @@ module ActiveStorage
51
51
  bucket.get_object(path_for(key), range: [range.begin, range_end]) do |chunk|
52
52
  chunk_buff << chunk
53
53
  end
54
- chunk_buff.join("")
54
+ chunk_buff.join
55
55
  end
56
56
  end
57
57
 
@@ -65,14 +65,16 @@ module ActiveStorage
65
65
  instrument :delete_prefixed, prefix: prefix do
66
66
  files = bucket.list_objects(prefix: path_for(prefix))
67
67
  return if files.blank?
68
+
68
69
  keys = files.map(&:key)
69
70
  return if keys.blank?
71
+
70
72
  bucket.batch_delete_objects(keys, quiet: true)
71
73
  end
72
74
  end
73
75
 
74
76
  def exist?(key)
75
- instrument :exist, key: key do |payload|
77
+ instrument :exist, key: key do |_payload|
76
78
  bucket.object_exists?(path_for(key))
77
79
  end
78
80
  end
@@ -83,7 +85,7 @@ module ActiveStorage
83
85
  # Source: *.your.host.com
84
86
  # Allowed Methods: POST, PUT, HEAD
85
87
  # Allowed Headers: *
86
- def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
88
+ def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {})
87
89
  instrument :url, key: key do |payload|
88
90
  generated_url = bucket.object_url(path_for(key), false)
89
91
  payload[:url] = generated_url
@@ -94,16 +96,21 @@ module ActiveStorage
94
96
  # Headers for Direct Upload
95
97
  # https://help.aliyun.com/document_detail/31951.html
96
98
  # headers["Date"] is required use x-oss-date instead
97
- def headers_for_direct_upload(key, content_type:, checksum:, **)
99
+ def headers_for_direct_upload(key, content_type:, checksum:, custom_metadata: {}, **)
98
100
  date = Time.now.httpdate
99
101
  {
100
102
  "Content-Type" => content_type,
101
103
  "Content-MD5" => checksum,
102
104
  "Authorization" => authorization(key, content_type, checksum, date),
103
105
  "x-oss-date" => date,
106
+ **custom_metadata_headers(custom_metadata)
104
107
  }
105
108
  end
106
109
 
110
+ def custom_metadata_headers(metadata)
111
+ metadata.transform_keys { |key| "x-oss-meta-#{key}" }
112
+ end
113
+
107
114
  # Remove this in Rails 6.1, compatiable with Rails 6.0.0
108
115
  def url(key, **options)
109
116
  instrument :url, key: key do |payload|
@@ -121,91 +128,113 @@ module ActiveStorage
121
128
  end
122
129
 
123
130
  private
124
- attr_reader :config
125
131
 
126
- def private_url(key, expires_in: 60, filename: nil, content_type: nil, disposition: nil, params: {}, **)
127
- filekey = path_for(key)
132
+ attr_reader :config
128
133
 
129
- params["response-content-type"] = content_type unless content_type.blank?
134
+ def private_url(key, expires_in: 60, filename: nil, content_type: nil, disposition: nil, params: {}, **)
135
+ filekey = path_for(key)
130
136
 
131
- if filename
132
- filename = ActiveStorage::Filename.wrap(filename)
133
- params["response-content-disposition"] = content_disposition_with(type: disposition, filename: filename)
134
- end
137
+ params["response-content-type"] = content_type unless content_type.blank?
135
138
 
136
- object_url(filekey, sign: true, expires_in: expires_in, params: params)
139
+ if filename
140
+ filename = ActiveStorage::Filename.wrap(filename)
141
+ params["response-content-disposition"] = content_disposition_with(type: disposition, filename: filename)
137
142
  end
138
143
 
139
- def public_url(key, params: {}, **)
140
- object_url(path_for(key), sign: false, params: params)
141
- end
144
+ object_url(filekey, sign: true, expires_in: expires_in, params: params)
145
+ end
146
+
147
+ def public_url(key, params: {}, **)
148
+ object_url(path_for(key), sign: false, params: params)
149
+ end
142
150
 
143
- # Remove this in Rails 6.1, compatiable with Rails 6.0.0
144
- def public?
145
- @public == true
151
+ # Remove this in Rails 6.1, compatiable with Rails 6.0.0
152
+ def public?
153
+ @public == true
154
+ end
155
+
156
+ def path_for(key)
157
+ root_path = config.fetch(:path, nil)
158
+ full_path = if root_path.blank? || root_path == "/"
159
+ key
160
+ else
161
+ File.join(root_path, key)
146
162
  end
147
163
 
148
- def path_for(key)
149
- root_path = config.fetch(:path, nil)
150
- if root_path.blank? || root_path == "/"
151
- full_path = key
152
- else
153
- full_path = File.join(root_path, key)
154
- end
164
+ full_path.gsub(%r{^/}, "").squeeze("/")
165
+ end
166
+
167
+ def object_url(key, sign: false, expires_in: 60, params: {})
168
+ url = host_bucket.object_url(key, false)
169
+ unless sign
170
+ return url if params.blank?
155
171
 
156
- full_path.gsub(/^\//, "").gsub(/[\/]+/, "/")
172
+ return "#{url}?#{params.to_query}"
157
173
  end
158
174
 
159
- def object_url(key, sign: false, expires_in: 60, params: {})
160
- url = bucket.object_url(key, false)
161
- unless sign
162
- return url if params.blank?
163
- return url + "?" + params.to_query
164
- end
175
+ resource = "/#{host_bucket.name}/#{key}"
176
+ expires = Time.now.to_i + expires_in
177
+ query = {
178
+ "Expires" => expires,
179
+ "OSSAccessKeyId" => config.fetch(:access_key_id)
180
+ }
181
+ query.merge!(params)
165
182
 
166
- resource = "/#{bucket.name}/#{key}"
167
- expires = Time.now.to_i + expires_in
168
- query = {
169
- "Expires" => expires,
170
- "OSSAccessKeyId" => config.fetch(:access_key_id)
171
- }
172
- query.merge!(params)
183
+ resource += "?" + params.map { |k, v| "#{k}=#{v}" }.sort.join("&") if params.present?
173
184
 
174
- if params.present?
175
- resource += "?" + params.map { |k, v| "#{k}=#{v}" }.sort.join("&")
176
- end
185
+ string_to_sign = ["GET", "", "", expires, resource].join("\n")
186
+ query["Signature"] = host_bucket.sign(string_to_sign)
177
187
 
178
- string_to_sign = ["GET", "", "", expires, resource].join("\n")
179
- query["Signature"] = bucket.sign(string_to_sign)
188
+ [url, query.to_query].join("?")
189
+ end
180
190
 
181
- [url, query.to_query].join("?")
182
- end
191
+ def bucket
192
+ return @bucket if defined? @bucket
183
193
 
184
- def bucket
185
- return @bucket if defined? @bucket
186
- @bucket = client.get_bucket(config.fetch(:bucket))
187
- @bucket
188
- end
194
+ @bucket = client.get_bucket(config.fetch(:bucket))
195
+ @bucket
196
+ end
189
197
 
190
- def authorization(key, content_type, checksum, date)
191
- filename = File.expand_path("/#{bucket.name}/#{path_for(key)}")
192
- addition_headers = "x-oss-date:#{date}"
193
- sign = ["PUT", checksum, content_type, date, addition_headers, filename].join("\n")
194
- signature = bucket.sign(sign)
195
- "OSS " + config.fetch(:access_key_id) + ":" + signature
196
- end
198
+ def host_bucket
199
+ return @host_bucket if defined? @host_bucket
197
200
 
198
- def endpoint
199
- config.fetch(:endpoint, "https://oss-cn-hangzhou.aliyuncs.com")
200
- end
201
+ host_bucket_client = host ? host_client : client
202
+ @host_bucket = host_bucket_client.get_bucket(config.fetch(:bucket))
203
+ @host_bucket
204
+ end
201
205
 
202
- def client
203
- @client ||= Aliyun::OSS::Client.new(
204
- endpoint: endpoint,
205
- access_key_id: config.fetch(:access_key_id),
206
- access_key_secret: config.fetch(:access_key_secret),
207
- cname: config.fetch(:cname, false)
208
- )
209
- end
206
+ def authorization(key, content_type, checksum, date)
207
+ filename = File.expand_path("/#{bucket.name}/#{path_for(key)}")
208
+ addition_headers = "x-oss-date:#{date}"
209
+ sign = ["PUT", checksum, content_type, date, addition_headers, filename].join("\n")
210
+ signature = bucket.sign(sign)
211
+ "OSS #{config.fetch(:access_key_id)}:#{signature}"
212
+ end
213
+
214
+ def endpoint
215
+ config.fetch(:endpoint, "https://oss-cn-hangzhou.aliyuncs.com")
216
+ end
217
+
218
+ def host
219
+ config.fetch(:host, nil)
220
+ end
221
+
222
+ def client
223
+ @client ||= Aliyun::OSS::Client.new(
224
+ endpoint: endpoint,
225
+ access_key_id: config.fetch(:access_key_id),
226
+ access_key_secret: config.fetch(:access_key_secret),
227
+ cname: config.fetch(:cname, false)
228
+ )
229
+ end
230
+
231
+ def host_client
232
+ @host_client ||= Aliyun::OSS::Client.new(
233
+ endpoint: host,
234
+ access_key_id: config.fetch(:access_key_id),
235
+ access_key_secret: config.fetch(:access_key_secret),
236
+ cname: config.fetch(:cname, false)
237
+ )
238
+ end
210
239
  end
211
240
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveStorageAliyun
2
4
  class Railtie < ::Rails::Railtie
3
5
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveStorageAliyun
4
- VERSION = "1.0.0"
4
+ VERSION = "1.2.0"
5
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # require "active_storage_aliyun/railtie"
2
4
 
3
5
  module ActiveStorageAliyun
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activestorage-aliyun
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Lee
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-01 00:00:00.000000000 Z
11
+ date: 2023-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: aliyun-sdk
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 6.0.0
19
+ version: 0.6.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 6.0.0
26
+ version: 0.6.0
27
27
  - !ruby/object:Gem::Dependency
28
- name: aliyun-sdk
28
+ name: rails
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.6.0
33
+ version: 6.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 0.6.0
40
+ version: 6.0.0
41
41
  description: Wraps the Aliyun OSS as an Active Storage service.
42
42
  email: huacnlee@gmail.com
43
43
  executables: []
@@ -54,7 +54,7 @@ homepage: https://github.com/huacnlee/activestorage-aliyun
54
54
  licenses:
55
55
  - MIT
56
56
  metadata: {}
57
- post_install_message:
57
+ post_install_message:
58
58
  rdoc_options: []
59
59
  require_paths:
60
60
  - lib
@@ -62,15 +62,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
62
62
  requirements:
63
63
  - - ">="
64
64
  - !ruby/object:Gem::Version
65
- version: '0'
65
+ version: 2.5.0
66
66
  required_rubygems_version: !ruby/object:Gem::Requirement
67
67
  requirements:
68
68
  - - ">="
69
69
  - !ruby/object:Gem::Version
70
70
  version: '0'
71
71
  requirements: []
72
- rubygems_version: 3.0.3
73
- signing_key:
72
+ rubygems_version: 3.4.19
73
+ signing_key:
74
74
  specification_version: 4
75
75
  summary: Wraps the Aliyun OSS as an Active Storage service
76
76
  test_files: []