carrierwave-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 +4 -4
- data/CHANGELOG.md +22 -0
- data/lib/carrierwave/aliyun/bucket.rb +46 -41
- data/lib/carrierwave/aliyun/version.rb +1 -1
- data/lib/carrierwave/storage/aliyun.rb +39 -3
- data/lib/carrierwave/storage/aliyun_file.rb +51 -15
- metadata +7 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54c88d264e49631dd46a637080fc79b10cb73d487910a1608afd4ac67cf65561
|
4
|
+
data.tar.gz: 7362e2b9d48547d369994443b105af5f4d57f7a34b64a7c78b51b9ecf940aa8e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6589f76ad4cc466e3bd1acb690a0759786cb7ec2517fe2e51c2aeb0ad044053ff1b6d373bc04b51c75db6cb34551f0fe1a9d22c688bb66579a1d8f8303af37c7
|
7
|
+
data.tar.gz: '00487944ad9d21be007c4f1148ce676e376c621f9d1de6207347d1f621351fda81c48b2f8100801cb6cff18965923447ae1034a396406da93b012280bb34590e'
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
## 1.2.0
|
2
|
+
|
3
|
+
- 整理修复 OSS 文件访问 URL 的生成方式,去掉 img host,保持和最新 OSS API 一样的逻辑。
|
4
|
+
- 生成 URL 的时候,不再强制替换为 https,保持 `aliyun_host` 的配置;
|
5
|
+
|
6
|
+
## 1.1.2
|
7
|
+
|
8
|
+
- 修正 aliyun-sdk 0.7.0 以上 Thumb URL 生成的支持;
|
9
|
+
- Requirement aliyun-sdk >= 0.7.0;
|
10
|
+
|
11
|
+
## 1.1.2
|
12
|
+
|
13
|
+
- 修正废弃调用方式,避免在 Ruby 2.7 里面出现 warning.
|
14
|
+
|
15
|
+
## 1.1.1
|
16
|
+
|
17
|
+
- 对于 CarrierWave 的 cache 机制正确支持;
|
18
|
+
|
19
|
+
## 1.1.0
|
20
|
+
|
21
|
+
- 支持 CarrierWave 2.0;
|
22
|
+
|
1
23
|
## 1.0.0
|
2
24
|
|
3
25
|
- 采用 Aliyun 官方的 SDK 来访问 OSS;
|
@@ -3,12 +3,12 @@
|
|
3
3
|
module CarrierWave
|
4
4
|
module Aliyun
|
5
5
|
class Bucket
|
6
|
-
PATH_PREFIX = %r{^/}
|
6
|
+
PATH_PREFIX = %r{^/}.freeze
|
7
7
|
CHUNK_SIZE = 1024 * 1024
|
8
8
|
|
9
9
|
attr_reader :access_key_id, :access_key_secret, :bucket, :region, :mode, :host
|
10
10
|
|
11
|
-
attr_reader :endpoint, :
|
11
|
+
attr_reader :endpoint, :upload_endpoint, :get_endpoint
|
12
12
|
|
13
13
|
def initialize(uploader)
|
14
14
|
if uploader.aliyun_area.present?
|
@@ -16,7 +16,7 @@ module CarrierWave
|
|
16
16
|
uploader.aliyun_region ||= uploader.aliyun_area
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
unless uploader.aliyun_private_read.nil?
|
20
20
|
ActiveSupport::Deprecation.warn(%(config.aliyun_private_read will deprecation in carrierwave-aliyun 1.1.0, please use `aliyun_mode = :private` instead.))
|
21
21
|
uploader.aliyun_mode ||= uploader.aliyun_private_read ? :private : :public
|
22
22
|
end
|
@@ -38,15 +38,15 @@ module CarrierWave
|
|
38
38
|
@mode = (uploader.aliyun_mode || :public).to_sym
|
39
39
|
|
40
40
|
# Host for get request
|
41
|
-
@
|
41
|
+
@endpoint = "https://#{bucket}.oss-#{region}.aliyuncs.com"
|
42
|
+
@host = uploader.aliyun_host || @endpoint
|
42
43
|
|
43
44
|
unless @host.include?("//")
|
44
|
-
raise "config.aliyun_host requirement include // http:// or https://, but you give: #{
|
45
|
+
raise "config.aliyun_host requirement include // http:// or https://, but you give: #{host}"
|
45
46
|
end
|
46
47
|
|
47
|
-
@
|
48
|
-
@upload_endpoint = uploader.aliyun_internal == true ? "https://oss-#{
|
49
|
-
@img_endpoint = "https://img-#{self.region}.aliyuncs.com"
|
48
|
+
@get_endpoint = "https://oss-#{region}.aliyuncs.com"
|
49
|
+
@upload_endpoint = uploader.aliyun_internal == true ? "https://oss-#{region}-internal.aliyuncs.com" : "https://oss-#{region}.aliyuncs.com"
|
50
50
|
end
|
51
51
|
|
52
52
|
# 上传文件
|
@@ -70,11 +70,18 @@ module CarrierWave
|
|
70
70
|
stream << file.read(CHUNK_SIZE) until file.eof?
|
71
71
|
end
|
72
72
|
path_to_url(path)
|
73
|
-
rescue => e
|
73
|
+
rescue StandardError => e
|
74
74
|
raise "Put file failed: #{e}"
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
+
def copy_object(source, dest)
|
79
|
+
source = source.sub(PATH_PREFIX, "")
|
80
|
+
dest = dest.sub(PATH_PREFIX, "")
|
81
|
+
|
82
|
+
oss_upload_client.copy_object(source, dest)
|
83
|
+
end
|
84
|
+
|
78
85
|
# 读取文件
|
79
86
|
# params:
|
80
87
|
# - path - remote 存储路径
|
@@ -88,7 +95,7 @@ module CarrierWave
|
|
88
95
|
end
|
89
96
|
|
90
97
|
[obj, chunk_buff.join("")]
|
91
|
-
rescue => e
|
98
|
+
rescue StandardError => e
|
92
99
|
raise "Get content faild: #{e}"
|
93
100
|
end
|
94
101
|
|
@@ -103,62 +110,60 @@ module CarrierWave
|
|
103
110
|
path = path.sub(PATH_PREFIX, "")
|
104
111
|
oss_upload_client.delete_object(path)
|
105
112
|
path_to_url(path)
|
106
|
-
rescue => e
|
113
|
+
rescue StandardError => e
|
107
114
|
raise "Delete failed: #{e}"
|
108
115
|
end
|
109
116
|
|
110
117
|
##
|
111
118
|
# 根据配置返回完整的上传文件的访问地址
|
112
119
|
def path_to_url(path, thumb: nil)
|
113
|
-
path
|
114
|
-
|
115
|
-
if thumb
|
116
|
-
[self.host, [path, thumb].join("")].join("/")
|
117
|
-
else
|
118
|
-
[self.host, path].join("/")
|
119
|
-
end
|
120
|
+
get_url(path, thumb: thumb)
|
120
121
|
end
|
121
122
|
|
122
123
|
# 私有空间访问地址,会带上实时算出的 token 信息
|
123
124
|
# 有效期 15 minutes
|
124
125
|
def private_get_url(path, thumb: nil)
|
126
|
+
get_url(path, private: true, thumb: thumb)
|
127
|
+
end
|
128
|
+
|
129
|
+
def get_url(path, private: false, thumb: nil)
|
125
130
|
path = path.sub(PATH_PREFIX, "")
|
126
131
|
|
127
|
-
url = if thumb
|
128
|
-
|
132
|
+
url = if thumb&.start_with?("?")
|
133
|
+
# foo.jpg?x-oss-process=image/resize,h_100
|
134
|
+
parameters = { "x-oss-process" => thumb.split("=").last }
|
135
|
+
oss_client.object_url(path, private, 15.minutes, parameters)
|
129
136
|
else
|
130
|
-
oss_client.object_url(path,
|
137
|
+
oss_client.object_url(path, private, 15.minutes)
|
131
138
|
end
|
132
139
|
|
133
|
-
|
140
|
+
unless private
|
141
|
+
url = [url, thumb].join("") unless thumb&.start_with?("?")
|
142
|
+
end
|
143
|
+
|
144
|
+
url.sub(endpoint, host)
|
134
145
|
end
|
135
146
|
|
136
147
|
def head(path)
|
137
|
-
|
148
|
+
path = path.sub(PATH_PREFIX, "")
|
149
|
+
oss_upload_client.get_object(path)
|
138
150
|
end
|
139
151
|
|
140
152
|
private
|
141
153
|
|
142
|
-
|
143
|
-
|
144
|
-
client = ::Aliyun::OSS::Client.new(endpoint: self.endpoint,
|
145
|
-
access_key_id: self.access_key_id, access_key_secret: self.access_key_secret)
|
146
|
-
@oss_client = client.get_bucket(self.bucket)
|
147
|
-
end
|
154
|
+
def oss_client
|
155
|
+
return @oss_client if defined?(@oss_client)
|
148
156
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
access_key_id: self.access_key_id, access_key_secret: self.access_key_secret)
|
153
|
-
@img_client = client.get_bucket(self.bucket)
|
154
|
-
end
|
157
|
+
client = ::Aliyun::OSS::Client.new(endpoint: get_endpoint, access_key_id: access_key_id, access_key_secret: access_key_secret)
|
158
|
+
@oss_client = client.get_bucket(bucket)
|
159
|
+
end
|
155
160
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
161
|
+
def oss_upload_client
|
162
|
+
return @oss_upload_client if defined?(@oss_upload_client)
|
163
|
+
|
164
|
+
client = ::Aliyun::OSS::Client.new(endpoint: upload_endpoint, access_key_id: access_key_id, access_key_secret: access_key_secret)
|
165
|
+
@oss_upload_client = client.get_bucket(bucket)
|
166
|
+
end
|
162
167
|
end
|
163
168
|
end
|
164
169
|
end
|
@@ -3,20 +3,56 @@
|
|
3
3
|
module CarrierWave
|
4
4
|
module Storage
|
5
5
|
class Aliyun < Abstract
|
6
|
-
def store!(
|
6
|
+
def store!(new_file)
|
7
7
|
f = AliyunFile.new(uploader, self, uploader.store_path)
|
8
8
|
headers = {
|
9
|
-
content_type:
|
9
|
+
content_type: new_file.content_type,
|
10
10
|
content_disposition: uploader.try(:content_disposition)
|
11
11
|
}
|
12
12
|
|
13
|
-
f.store(
|
13
|
+
f.store(new_file, headers)
|
14
14
|
f
|
15
15
|
end
|
16
16
|
|
17
17
|
def retrieve!(identifier)
|
18
18
|
AliyunFile.new(uploader, self, uploader.store_path(identifier))
|
19
19
|
end
|
20
|
+
|
21
|
+
def cache!(new_file)
|
22
|
+
f = AliyunFile.new(uploader, self, uploader.cache_path)
|
23
|
+
headers = {
|
24
|
+
content_type: new_file.content_type,
|
25
|
+
content_disposition: uploader.try(:content_disposition)
|
26
|
+
}
|
27
|
+
|
28
|
+
f.store(new_file, headers)
|
29
|
+
f
|
30
|
+
end
|
31
|
+
|
32
|
+
def retrieve_from_cache!(identifier)
|
33
|
+
AliyunFile.new(uploader, self, uploader.cache_path(identifier))
|
34
|
+
end
|
35
|
+
|
36
|
+
def delete_dir!(path)
|
37
|
+
# do nothing, because there's no such things as 'empty directory'
|
38
|
+
end
|
39
|
+
|
40
|
+
def clean_cache!(_seconds)
|
41
|
+
will_remove_keys = []
|
42
|
+
bucket.list_objects(prefix: uploader.cache_path).each do |file|
|
43
|
+
next unless file.is_a?(Object)
|
44
|
+
time = file.key.scan(/(\d+)-\d+-\d+(?:-\d+)?/).first.map { |t| t.to_i }
|
45
|
+
time = Time.at(*time)
|
46
|
+
will_remove_keys << item.key if time < (Time.now.utc - seconds)
|
47
|
+
end
|
48
|
+
bucket.batch_delete_objects(will_remove_keys)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def bucket
|
54
|
+
@bucket ||= CarrierWave::Aliyun::Bucket.new(uploader)
|
55
|
+
end
|
20
56
|
end
|
21
57
|
end
|
22
58
|
end
|
@@ -2,23 +2,28 @@
|
|
2
2
|
|
3
3
|
module CarrierWave
|
4
4
|
module Storage
|
5
|
-
class AliyunFile
|
6
|
-
attr_reader :path
|
5
|
+
class AliyunFile
|
6
|
+
attr_reader :uploader, :path
|
7
|
+
|
8
|
+
alias_method :filename, :path
|
9
|
+
alias_method :identifier, :filename
|
7
10
|
|
8
11
|
def initialize(uploader, base, path)
|
9
|
-
@uploader = uploader
|
10
|
-
|
11
|
-
|
12
|
+
@uploader, @path, @base = uploader, escape(path), base
|
13
|
+
end
|
14
|
+
|
15
|
+
def escape(path)
|
16
|
+
CGI.escape(path).gsub("%2F", "/")
|
12
17
|
end
|
13
18
|
|
14
19
|
def read
|
15
|
-
object, body = bucket.get(
|
20
|
+
object, body = bucket.get(path)
|
16
21
|
@headers = object.headers
|
17
22
|
body
|
18
23
|
end
|
19
24
|
|
20
25
|
def delete
|
21
|
-
bucket.delete(
|
26
|
+
bucket.delete(path)
|
22
27
|
true
|
23
28
|
rescue => e
|
24
29
|
# If the file's not there, don't panic
|
@@ -33,9 +38,9 @@ module CarrierWave
|
|
33
38
|
#
|
34
39
|
def url(opts = {})
|
35
40
|
if bucket.mode == :private
|
36
|
-
bucket.private_get_url(
|
41
|
+
bucket.private_get_url(path, **opts)
|
37
42
|
else
|
38
|
-
bucket.path_to_url(
|
43
|
+
bucket.path_to_url(path, **opts)
|
39
44
|
end
|
40
45
|
end
|
41
46
|
|
@@ -47,20 +52,51 @@ module CarrierWave
|
|
47
52
|
headers[:content_type] = new_content_type
|
48
53
|
end
|
49
54
|
|
50
|
-
def store(
|
51
|
-
|
55
|
+
def store(new_file, headers = {})
|
56
|
+
if new_file.is_a?(self.class)
|
57
|
+
new_file.copy_to(path)
|
58
|
+
else
|
59
|
+
fog_file = new_file.to_file
|
60
|
+
bucket.put(path, fog_file, **headers)
|
61
|
+
fog_file.close if fog_file && !fog_file.closed?
|
62
|
+
end
|
63
|
+
true
|
52
64
|
end
|
53
65
|
|
54
66
|
def headers
|
55
|
-
@headers ||=
|
67
|
+
@headers ||= begin
|
68
|
+
obj = bucket.head(path)
|
69
|
+
obj.headers
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def exists?
|
74
|
+
!!headers
|
75
|
+
end
|
76
|
+
|
77
|
+
def copy_to(new_path)
|
78
|
+
bucket.copy_object(path, new_path)
|
79
|
+
self.class.new(uploader, @base, new_path)
|
80
|
+
end
|
81
|
+
|
82
|
+
def extension
|
83
|
+
path_elements = path.split(".")
|
84
|
+
path_elements.last if path_elements.size > 1
|
85
|
+
end
|
86
|
+
|
87
|
+
def original_filename
|
88
|
+
return @original_filename if @original_filename
|
89
|
+
if @file && @file.respond_to?(:original_filename)
|
90
|
+
@file.original_filename
|
91
|
+
elsif path
|
92
|
+
::File.basename(path)
|
93
|
+
end
|
56
94
|
end
|
57
95
|
|
58
96
|
private
|
59
97
|
|
60
98
|
def bucket
|
61
|
-
|
62
|
-
|
63
|
-
@bucket = CarrierWave::Aliyun::Bucket.new(@uploader)
|
99
|
+
@bucket ||= CarrierWave::Aliyun::Bucket.new(uploader)
|
64
100
|
end
|
65
101
|
end
|
66
102
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carrierwave-aliyun
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jason Lee
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: carrierwave
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '1'
|
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:
|
26
|
+
version: '1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: aliyun-sdk
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.7.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.
|
40
|
+
version: 0.7.0
|
41
41
|
description: Aliyun OSS support for Carrierwave
|
42
42
|
email:
|
43
43
|
- huacnlee@gmail.com
|
@@ -72,8 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
72
|
- !ruby/object:Gem::Version
|
73
73
|
version: '0'
|
74
74
|
requirements: []
|
75
|
-
|
76
|
-
rubygems_version: 2.7.9
|
75
|
+
rubygems_version: 3.0.3
|
77
76
|
signing_key:
|
78
77
|
specification_version: 4
|
79
78
|
summary: Aliyun OSS support for Carrierwave
|