lib/carrierwave/aliyun/bucket.rb in carrierwave-aliyun-0.9.0 vs lib/carrierwave/aliyun/bucket.rb in carrierwave-aliyun-1.0.0

- old
+ new

@@ -1,24 +1,54 @@ +# frozen_string_literal: true + module CarrierWave module Aliyun class Bucket PATH_PREFIX = %r{^/} + CHUNK_SIZE = 1024 * 1024 + attr_reader :access_key_id, :access_key_secret, :bucket, :region, :mode, :host + + attr_reader :endpoint, :img_endpoint, :upload_endpoint + def initialize(uploader) - @aliyun_access_id = uploader.aliyun_access_id - @aliyun_access_key = uploader.aliyun_access_key - @aliyun_bucket = uploader.aliyun_bucket - @aliyun_area = uploader.aliyun_area || 'cn-hangzhou' - @aliyun_private_read = uploader.aliyun_private_read - @aliyun_internal = uploader.aliyun_internal + if uploader.aliyun_area.present? + ActiveSupport::Deprecation.warn("config.aliyun_area will deprecation in carrierwave-aliyun 1.1.0, please use `aliyun_region` instead.") + uploader.aliyun_region ||= uploader.aliyun_area + end + if uploader.aliyun_private_read != nil + ActiveSupport::Deprecation.warn(%(config.aliyun_private_read will deprecation in carrierwave-aliyun 1.1.0, please use `aliyun_mode = :private` instead.)) + uploader.aliyun_mode ||= uploader.aliyun_private_read ? :private : :public + end + + if uploader.aliyun_access_id.present? + ActiveSupport::Deprecation.warn(%(config.aliyun_access_id will deprecation in carrierwave-aliyun 1.1.0, please use `aliyun_access_key_id` instead.)) + uploader.aliyun_access_key_id ||= uploader.aliyun_access_id + end + + if uploader.aliyun_access_key.present? + ActiveSupport::Deprecation.warn(%(config.aliyun_access_key will deprecation in carrierwave-aliyun 1.1.0, please use `aliyun_access_key_secret` instead.)) + uploader.aliyun_access_key_secret ||= uploader.aliyun_access_key + end + + @access_key_id = uploader.aliyun_access_key_id + @access_key_secret = uploader.aliyun_access_key_secret + @bucket = uploader.aliyun_bucket + @region = uploader.aliyun_region || "cn-hangzhou" + @mode = (uploader.aliyun_mode || :public).to_sym + # Host for get request - @aliyun_host = uploader.aliyun_host || "https://#{@aliyun_bucket}.oss-#{@aliyun_area}.aliyuncs.com" + @host = uploader.aliyun_host || "https://#{self.bucket}.oss-#{self.region}.aliyuncs.com" - unless @aliyun_host.include?('//') - raise "config.aliyun_host requirement include // http:// or https://, but you give: #{@aliyun_host}" + unless @host.include?("//") + raise "config.aliyun_host requirement include // http:// or https://, but you give: #{self.host}" end + + @endpoint = "https://oss-#{self.region}.aliyuncs.com" + @upload_endpoint = uploader.aliyun_internal == true ? "https://oss-#{self.region}-internal.aliyuncs.com" : @endpoint + @img_endpoint = "https://img-#{self.region}.aliyuncs.com" end # 上传文件 # params: # - path - remote 存储路径 @@ -26,123 +56,109 @@ # - opts: # - content_type - 上传文件的 MimeType,默认 `image/jpg` # - content_disposition - Content-Disposition # returns: # 图片的下载地址 - def put(path, file, opts = {}) - path.sub!(PATH_PREFIX, '') + def put(path, file, content_type: "image/jpg", content_disposition: nil) + path = path.sub(PATH_PREFIX, "") headers = {} - headers['Content-Type'] = opts[:content_type] || 'image/jpg' - content_disposition = opts[:content_disposition] - if content_disposition - headers['Content-Disposition'] = content_disposition - end + headers["Content-Type"] = content_type + headers["Content-Disposition"] = content_disposition if content_disposition - res = oss_upload_client.bucket_create_object(path, file, headers) - if res.success? + begin + oss_upload_client.put_object(path, headers: headers) do |stream| + stream << file.read(CHUNK_SIZE) until file.eof? + end path_to_url(path) - else - raise 'Put file failed' + rescue => e + raise "Put file failed: #{e}" end end # 读取文件 # params: # - path - remote 存储路径 # returns: # file data def get(path) - path.sub!(PATH_PREFIX, '') - res = oss_upload_client.bucket_get_object(path) - if res.success? - return res - else - raise 'Get content faild' + path = path.sub(PATH_PREFIX, "") + chunk_buff = [] + obj = oss_upload_client.get_object(path) do |chunk| + chunk_buff << chunk end + + [obj, chunk_buff.join("")] + rescue => e + raise "Get content faild: #{e}" end # 删除 Remote 的文件 # # params: # - path - remote 存储路径 # # returns: # 图片的下载地址 def delete(path) - path.sub!(PATH_PREFIX, '') - res = oss_upload_client.bucket_delete_object(path) - if res.success? - return path_to_url(path) - else - raise 'Delete failed' - end + path = path.sub(PATH_PREFIX, "") + oss_upload_client.delete_object(path) + path_to_url(path) + rescue => e + raise "Delete failed: #{e}" end ## # 根据配置返回完整的上传文件的访问地址 - def path_to_url(path, opts = {}) - if opts[:thumb] - thumb_path = [path, opts[:thumb]].join('') - [@aliyun_host, thumb_path].join('/') + def path_to_url(path, thumb: nil) + path = path.sub(PATH_PREFIX, "") + + if thumb + [self.host, [path, thumb].join("")].join("/") else - [@aliyun_host, path].join('/') + [self.host, path].join("/") end end # 私有空间访问地址,会带上实时算出的 token 信息 - # 有效期 3600s - def private_get_url(path, opts = {}) - path.sub!(PATH_PREFIX, '') - url = '' - if opts[:thumb] - thumb_path = [path, opts[:thumb]].join('') - url = img_client.bucket_get_object_share_link(thumb_path, 3600) - else - url = oss_client.bucket_get_object_share_link(path, 3600) - end - url.gsub('http://', 'https://') + # 有效期 15 minutes + def private_get_url(path, thumb: nil) + path = path.sub(PATH_PREFIX, "") + + url = if thumb + img_client.object_url([path, thumb].join(""), expiry: 15.minutes) + else + oss_client.object_url(path, expiry: 15.minutes) + end + + url.sub("http://", "https://") end def head(path) - oss_client.bucket_get_meta_object(path) + oss_client.get_object_meta(path) end private - def oss_client - return @oss_client if defined?(@oss_client) - opts = { - host: "oss-#{@aliyun_area}.aliyuncs.com", - bucket: @aliyun_bucket - } - @oss_client = ::Aliyun::Oss::Client.new(@aliyun_access_id, @aliyun_access_key, opts) - end + def oss_client + return @oss_client if defined?(@oss_client) + client = ::Aliyun::OSS::Client.new(endpoint: self.endpoint, + access_key_id: self.access_key_id, access_key_secret: self.access_key_secret) + @oss_client = client.get_bucket(self.bucket) + end - def img_client - return @img_client if defined?(@img_client) - opts = { - host: "img-#{@aliyun_area}.aliyuncs.com", - bucket: @aliyun_bucket - } - @img_client = ::Aliyun::Oss::Client.new(@aliyun_access_id, @aliyun_access_key, opts) - end + def img_client + return @img_client if defined?(@img_client) + client = ::Aliyun::OSS::Client.new(endpoint: self.img_endpoint, + access_key_id: self.access_key_id, access_key_secret: self.access_key_secret) + @img_client = client.get_bucket(self.bucket) + end - def oss_upload_client - return @oss_upload_client if defined?(@oss_upload_client) - - host = if @aliyun_internal - "oss-#{@aliyun_area}-internal.aliyuncs.com" - else - "oss-#{@aliyun_area}.aliyuncs.com" - end - - opts = { - host: host, - bucket: @aliyun_bucket - } - - @oss_upload_client = ::Aliyun::Oss::Client.new(@aliyun_access_id, @aliyun_access_key, opts) - end + def oss_upload_client + return @oss_upload_client if defined?(@oss_upload_client) + client = ::Aliyun::OSS::Client.new(endpoint: self.upload_endpoint, + access_key_id: self.access_key_id, access_key_secret: self.access_key_secret) + @oss_upload_client = client.get_bucket(self.bucket) + end end end end