# coding: utf-8 module COS class Resource attr_reader :bucket, :path, :dir_count, :file_count # 实例化COS资源迭代器 def initialize(bucket, path, options = {}) @bucket = bucket @path = path @more = options @results = Array.new @dir_count = 0 @file_count = 0 end # 实现迭代器 def next loop do # 从接口获取下一页结果 fetch_more if @results.empty? # 取出结果 r = @results.shift break unless r yield r end end # 返回迭代器 def to_enum self.enum_for(:next) end # 获取列表 def fetch client = bucket.client resp = client.api.list(path, @more.merge({bucket: bucket.bucket_name})) # 遍历结果转换为对应的对象 @results = resp[:infos].map do |r| if r[:filesize].nil? # 目录 COSDir.new(r.merge({ bucket: bucket, path: Util.get_list_path(path, r[:name]) })) else # 文件 COSFile.new(r.merge({ bucket: bucket, path: Util.get_list_path(path, r[:name], true) })) end end || [] @dir_count = resp[:dir_count] @file_count = resp[:file_count] @more[:context] = resp[:context] @more[:has_more] = resp[:has_more] end private # 如果有更多页继续获取下一页 def fetch_more return if @more[:has_more] == false fetch end end # COS资源,文件与目录的共有操作 class ResourceOperator < Struct::Base required_attrs :bucket, :path, :name, :ctime, :mtime optional_attrs :biz_attr, :filesize, :filelen, :sha, :access_url, # 根目录(bucket)参数 :authority, :bucket_type, :migrate_source_domain, :need_preview, :refers, :blackrefers, :brower_exec, :cnames, :nugc_flag, :SKIP_EXTRA # 资源类型 attr_reader :type alias :file_size :filesize alias :file_len :filelen def initialize(attrs) super(attrs) end # 创建时间Time类型 # # @return [Time] def created_at Time.at(ctime.to_i) end # 更新时间Time类型 # # @return [Time] def updated_at Time.at(mtime.to_i) end # 参数转化为Hash类型 # # @return [Hash] def to_hash hash = { type: type, bucket: bucket.bucket_name, path: path, name: name, ctime: ctime, mtime: mtime, } optional_attrs.each do |key| hash[key] = send(key.to_s) if respond_to?(key) and send(key.to_s) != nil end hash end # 判断当前资源是否存在 # # @raise [ServerError] 服务端异常返回 # # @return [Boolean] 是否存在 # # @example # puts resource.exist? def exist? bucket.exist?(path) end alias :exists? :exist? # 获取(刷新)当前资源的状态 # # @note 如查询根目录('/', '')可以获取到bucket信息, 返回COSDir # # @raise [ServerError] 服务端异常返回 # # @return [COSFile|COSDir] 如果是目录则返回COSDir资源对象,是文件则返回COSFile资源对象 # # @example # puts resource.stat.name def stat bucket.stat(path) end # 更新当前资源的属性 # # @note 根目录('/') 不可更新, 否则会抛出异常 # # @param biz_attr [String] 目录/文件属性,业务端维护 # # @raise [ServerError] 服务端异常返回 # # @example # resource.update('i am the attr') def update(biz_attr) bucket.update(path, biz_attr) @mtime = Time.now.to_i.to_s @biz_attr = biz_attr self end # 删除当前资源 # # @note 非空目录及根目录不可删除,会抛出异常 # # @raise [ServerError] 服务端异常返回 # # @example # resource.delete def delete bucket.delete(path) self end # 删除当前资源, 不会抛出异常而是返回布尔值 # # @note 非空目录及根目录不可删除, 返回false # # @example # puts resource.delete! def delete! bucket.delete!(path) end end end