activestorage-aliyun 1.0.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: []