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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d76d49aaf688f569f6ad24269872e9ff3a773590d63533c472e5fe570bc673ab
4
- data.tar.gz: 4a6d40ae6c492edb56fd5804ee7b69ff89cddbc88143f95dc7b2aa5bd8a6a898
3
+ metadata.gz: 54c88d264e49631dd46a637080fc79b10cb73d487910a1608afd4ac67cf65561
4
+ data.tar.gz: 7362e2b9d48547d369994443b105af5f4d57f7a34b64a7c78b51b9ecf940aa8e
5
5
  SHA512:
6
- metadata.gz: 478a675dbb9dd3eaea1049c6a33dd892c5ff1458c615c1dff4d0eb6c4eb6a61cb8227bb7fb8d327679fed4cc29c24890ee1fb59399e431b2d845d2afa9960170
7
- data.tar.gz: 935fc2b025cb985d5133b198d7aa82e3baec7e7328bea7b33152b2dd90efc753df3c94a407fa102f9bb88465b41cd35e0b953728b49f0956ed24f8ab15ac1e0e
6
+ metadata.gz: 6589f76ad4cc466e3bd1acb690a0759786cb7ec2517fe2e51c2aeb0ad044053ff1b6d373bc04b51c75db6cb34551f0fe1a9d22c688bb66579a1d8f8303af37c7
7
+ data.tar.gz: '00487944ad9d21be007c4f1148ce676e376c621f9d1de6207347d1f621351fda81c48b2f8100801cb6cff18965923447ae1034a396406da93b012280bb34590e'
@@ -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, :img_endpoint, :upload_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
- if uploader.aliyun_private_read != nil
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
- @host = uploader.aliyun_host || "https://#{self.bucket}.oss-#{self.region}.aliyuncs.com"
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: #{self.host}"
45
+ raise "config.aliyun_host requirement include // http:// or https://, but you give: #{host}"
45
46
  end
46
47
 
47
- @endpoint = "https://oss-#{self.region}.aliyuncs.com"
48
- @upload_endpoint = uploader.aliyun_internal == true ? "https://oss-#{self.region}-internal.aliyuncs.com" : @endpoint
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 = path.sub(PATH_PREFIX, "")
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
- img_client.object_url([path, thumb].join(""), expiry: 15.minutes)
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, expiry: 15.minutes)
137
+ oss_client.object_url(path, private, 15.minutes)
131
138
  end
132
139
 
133
- url.sub("http://", "https://")
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
- oss_client.get_object_meta(path)
148
+ path = path.sub(PATH_PREFIX, "")
149
+ oss_upload_client.get_object(path)
138
150
  end
139
151
 
140
152
  private
141
153
 
142
- def oss_client
143
- return @oss_client if defined?(@oss_client)
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
- def img_client
150
- return @img_client if defined?(@img_client)
151
- client = ::Aliyun::OSS::Client.new(endpoint: self.img_endpoint,
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
- def oss_upload_client
157
- return @oss_upload_client if defined?(@oss_upload_client)
158
- client = ::Aliyun::OSS::Client.new(endpoint: self.upload_endpoint,
159
- access_key_id: self.access_key_id, access_key_secret: self.access_key_secret)
160
- @oss_upload_client = client.get_bucket(self.bucket)
161
- end
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module CarrierWave
4
4
  module Aliyun
5
- VERSION = "1.0.0"
5
+ VERSION = "1.2.0"
6
6
  end
7
7
  end
@@ -3,20 +3,56 @@
3
3
  module CarrierWave
4
4
  module Storage
5
5
  class Aliyun < Abstract
6
- def store!(file)
6
+ def store!(new_file)
7
7
  f = AliyunFile.new(uploader, self, uploader.store_path)
8
8
  headers = {
9
- content_type: file.content_type,
9
+ content_type: new_file.content_type,
10
10
  content_disposition: uploader.try(:content_disposition)
11
11
  }
12
12
 
13
- f.store(::File.open(file.file), headers)
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 < CarrierWave::SanitizedFile
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
- @path = URI.encode(path)
11
- @base = base
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(@path)
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(@path)
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(@path, opts)
41
+ bucket.private_get_url(path, **opts)
37
42
  else
38
- bucket.path_to_url(@path, opts)
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(file, headers = {})
51
- bucket.put(@path, file, headers)
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
- return @bucket if defined? @bucket
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.0.0
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: 2019-07-23 00:00:00.000000000 Z
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: 0.5.7
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: 0.5.7
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.6.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.6.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
- rubyforge_project:
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