diff --git a/examples/aliyun/oss/bucket.rb b/examples/aliyun/oss/bucket.rb index 5d17923..eea6c48 100644 --- a/examples/aliyun/oss/bucket.rb +++ b/examples/aliyun/oss/bucket.rb @@ -4,7 +4,7 @@ require 'yaml' require 'aliyun/oss' -# 初始化OSS client +# Initialize OSS client Aliyun::Common::Logging.set_log_level(Logger::DEBUG) conf_file = '~/.oss.yml' conf = YAML.load(File.read(File.expand_path(conf_file))) @@ -15,7 +15,7 @@ :access_key_secret => conf['access_key_secret']) bucket = client.get_bucket(conf['bucket']) -# 辅助打印函数 +# print helper function def demo(msg) puts "######### #{msg} ########" puts @@ -24,13 +24,13 @@ def demo(msg) puts end -# 列出当前所有的bucket +# list all buckets demo "List all buckets" do buckets = client.list_buckets buckets.each{ |b| puts "Bucket: #{b.name}"} end -# 创建bucket,如果同名的bucket已经存在,则创建会失败 +# create bucket. If the bucket already exists, the creation will fail demo "Create bucket" do begin bucket_name = 't-foo-bar' @@ -41,7 +41,7 @@ def demo(msg) end end -# 向bucket中添加5个空的object: +# add 5 empty objects into bucket: # foo/obj1, foo/bar/obj1, foo/bar/obj2, foo/xxx/obj1 demo "Put objects before list" do @@ -52,7 +52,7 @@ def demo(msg) bucket.put_object('中国の') end -# list bucket下所有objects +# list bucket's all objects demo "List first 10 objects" do objects = bucket.list_objects @@ -61,7 +61,7 @@ def demo(msg) end end -# list bucket下所有前缀为foo/bar/的object +# list bucket's all object whose name has the prefix foo/bar/ demo "List first 10 objects with prefix 'foo/bar/'" do objects = bucket.list_objects(:prefix => 'foo/bar/') @@ -70,18 +70,17 @@ def demo(msg) end end -# 获取object的common prefix,common prefix是指bucket下所有object(也可 -# 以指定特定的前缀)的公共前缀,这在object数量巨多的时候很有用,例如有 -# 如下的object: +# get common prefix of the object. Common prefix object is the object whose name is the common prefix of some other objects in the bucket. +# Essentially it's a 'folder' in the bucket. +# For example, if we have the following objects: # /foo/bar/obj1 # /foo/bar/obj2 # ... # /foo/bar/obj9999999 # /foo/xx/ -# 指定foo/为prefix,/为delimiter,则返回的common prefix为 -# /foo/bar/, /foo/xxx/ -# 这可以表示/foo/目录下的子目录。如果没有common prefix,你可能要遍历所 -# 有的object来找公共的前缀 +# Specify the prefix as foo/ and delimiter as '/', then the retirned common prefix is +# /foo/bar/ and /foo/xxx/ +# They could represent the subfolder of '/foo' folder. It's a efficient way to enumerate all files under a folder by specifying the common prefix. demo "List first 10 objects/common prefixes" do objects = bucket.list_objects(:prefix => 'foo/', :delimiter => '/') @@ -95,7 +94,7 @@ def demo(msg) end end -# 获取/设置Bucket属性: ACL, Logging, Referer, Website, LifeCycle, CORS +# get/set Bucket attributes: ACL, Logging, Referer, Website, LifeCycle, CORS demo "Get/Set bucket properties: ACL/Logging/Referer/Website/Lifecycle/CORS" do puts "Bucket acl before: #{bucket.acl}" bucket.acl = Aliyun::OSS::ACL::PUBLIC_READ diff --git a/examples/aliyun/oss/callback.rb b/examples/aliyun/oss/callback.rb index b35338b..0b5c105 100644 --- a/examples/aliyun/oss/callback.rb +++ b/examples/aliyun/oss/callback.rb @@ -6,14 +6,13 @@ require 'aliyun/oss' ## -# 用户在上传文件时可以指定“上传回调”,这样在文件上传成功后OSS会向用户 -# 提供的服务器地址发起一个HTTP POST请求,相当于一个通知机制。用户可以 -# 在收到回调的时候做相应的动作。 -# 1. 如何接受OSS的回调可以参考代码目录下的 +# User could specify callback when uploading a file so that OSS will issue a POST request to that callback url upon a successful file upload. +# This is one way of notification and user could do proper action on that callback request. +# 1. Check out the following file to know more about how to handle OSS's callback request. # rails/aliyun_oss_callback_server.rb -# 2. 只有put_object和resumable_upload支持上传回调 +# 2. Only put_object and resumable_upload support upload callback. -# 初始化OSS client +# Initialize OSS client Aliyun::Common::Logging.set_log_level(Logger::DEBUG) conf_file = '~/.oss.yml' conf = YAML.load(File.read(File.expand_path(conf_file))) @@ -23,7 +22,7 @@ :access_key_id => conf['access_key_id'], :access_key_secret => conf['access_key_secret']).get_bucket(conf['bucket']) -# 辅助打印函数 +# print helper function def demo(msg) puts "######### #{msg} ########" puts diff --git a/examples/aliyun/oss/object.rb b/examples/aliyun/oss/object.rb index a299ff3..790342d 100644 --- a/examples/aliyun/oss/object.rb +++ b/examples/aliyun/oss/object.rb @@ -4,7 +4,7 @@ require 'yaml' require 'aliyun/oss' -# 初始化OSS client +# Initialize OSS client Aliyun::Common::Logging.set_log_level(Logger::DEBUG) conf_file = '~/.oss.yml' conf = YAML.load(File.read(File.expand_path(conf_file))) @@ -14,7 +14,7 @@ :access_key_id => conf['access_key_id'], :access_key_secret => conf['access_key_secret']).get_bucket(conf['bucket']) -# 辅助打印函数 +# print helper function def demo(msg) puts "######### #{msg} ########" puts @@ -23,8 +23,8 @@ def demo(msg) puts end -# 上传一个object -# 流式上传请参考:examples/streaming.rb +# upload an object +# Check out examples/streaming.rb for streaming upload example. demo "Put object from input" do bucket.put_object('files/hello') do |content| content << 'hello world.' @@ -32,15 +32,15 @@ def demo(msg) puts "Put object: files/hello" end -# 上传一个文件 -# 断点续传请参考:examples/resumable_upload.rb +# upload an object +# Check out examples/resumable_upload.rb for resumable upload example. demo "Put object from local file" do File.open('/tmp/x', 'w'){ |f| f.write("hello world\n") } bucket.put_object('files/world', :file => '/tmp/x') puts "Put object: files/world" end -# 创建一个Appendable object +# Create an Appendable object demo "Create appendable object" do size = bucket.get_object('files/appendable').size rescue 0 bucket.append_object('files/appendable', size) do |content| @@ -49,8 +49,8 @@ def demo(msg) puts "Append object: files/appendable" end -# 向files/appendable中追加内容 -# 首先要获取object当前的长度 +# append content into files/appendable. +# Get the object's current length. demo "Append to object" do size = bucket.get_object('files/appendable').size bucket.append_object('files/appendable', size) do |content| @@ -59,7 +59,7 @@ def demo(msg) puts "Append object: files/appendable" end -# 使用错误的position进行追加会失败 +# Append will fail if using wrong position demo "Append with wrong pos" do begin bucket.append_object('files/appendable', 0) do |content| @@ -70,7 +70,7 @@ def demo(msg) end end -# 向一个normal object中追加内容会失败 +# Appending to normal object will fail demo "Append to normal object(fail)" do begin bucket.append_object('files/hello', 0) do |content| @@ -81,13 +81,13 @@ def demo(msg) end end -# 拷贝一个object +# copy an object demo "Copy object" do bucket.copy_object('files/hello', 'files/copy') puts "Copy object files/hello => files/copy" end -# 拷贝一个appendable object会失败 +# copying an appendable object will fail demo "Copy appendable object(fail)" do begin bucket.copy_object('files/appendable', 'files/copy') @@ -96,8 +96,8 @@ def demo(msg) end end -# 下载一个object:流式处理 -# 流式下载请参考:examples/streaming.rb +# download an OSS object into memory +# Check out examples/streaming.rb for streaming download examples. demo "Get object: handle content" do total_size = 0 bucket.get_object('files/hello') do |chunk| @@ -106,27 +106,27 @@ def demo(msg) puts "Total size: #{total_size}" end -# 下载一个object:下载到文件中 +# download an OSS object into local file demo "Get object to local file" do bucket.get_object('files/hello', :file => '/tmp/hello') puts "Get object: files/hello => /tmp/hello" end -# 删除一个object +# delete an object demo "Delete object" do bucket.delete_object('files/world') puts "Delete object: files/world" end -# 删除一个不存在的object返回OK -# 这意味着delete_object是幂等的,在删除失败的时候可以不断重试,直到成 -# 功,成功意味着object已经不存在 +# Delete an non-existing object and it should return OK. +# So delete_object is idempotent and you can retry delete_object until success if it fails. +# It means the object does not exist if delete_object return OK. demo "Delete a non-existent object(OK)" do bucket.delete_object('non-existent-object') puts "Delete object: non-existent-object" end -# 设置Object metas +# Set Object metas demo "Put objec with metas" do bucket.put_object( 'files/hello', @@ -139,7 +139,7 @@ def demo(msg) puts "Object metas: #{o.metas}" end -# 修改Object metas +# Modify Object metas demo "Update object metas" do bucket.update_object_metas( 'files/hello', {'year' => '2016', 'people' => 'jack'}) @@ -147,7 +147,7 @@ def demo(msg) puts "Meta changed: #{o.metas}" end -# 设置Object的ACL +# Set Object的ACL demo "Set object ACL" do puts "Object acl before: #{bucket.get_object_acl('files/hello')}" @@ -155,7 +155,7 @@ def demo(msg) puts "Object acl now: #{bucket.get_object_acl('files/hello')}" end -# 指定条件get_object +# get_object with conditions demo "Get object with conditions" do o = bucket.get_object('files/hello') diff --git a/examples/aliyun/oss/resumable_download.rb b/examples/aliyun/oss/resumable_download.rb index fac4b12..92b3f30 100644 --- a/examples/aliyun/oss/resumable_download.rb +++ b/examples/aliyun/oss/resumable_download.rb @@ -4,7 +4,7 @@ require 'yaml' require 'aliyun/oss' -# 初始化OSS Bucket +# Initialize OSS Bucket Aliyun::Common::Logging.set_log_level(Logger::DEBUG) conf_file = '~/.oss.yml' conf = YAML.load(File.read(File.expand_path(conf_file))) @@ -14,7 +14,7 @@ :access_key_id => conf['access_key_id'], :access_key_secret => conf['access_key_secret']).get_bucket(conf['bucket']) -# 辅助打印函数 +# print helper function def demo(msg) puts "######### #{msg} ########" puts @@ -24,7 +24,7 @@ def demo(msg) end demo "Resumable download" do - # 下载一个100M的文件 + # Download a 100M file cpt_file = '/tmp/y.cpt' File.delete(cpt_file) if File.exist?(cpt_file) start = Time.now @@ -35,8 +35,8 @@ def demo(msg) end puts "Download complete. Cost: #{Time.now - start} seconds." - # 测试方法: + # test method: # 1. ruby examples/resumable_download.rb - # 2. 过几秒后用Ctrl-C中断下载 - # 3. ruby examples/resumable_download.rb恢复下载 + # 2. after a few seconds, type Ctrl-C to disrupt the download. + # 3. ruby examples/resumable_download.rb to recover the download end diff --git a/examples/aliyun/oss/resumable_upload.rb b/examples/aliyun/oss/resumable_upload.rb index ae53a9e..a455ff2 100644 --- a/examples/aliyun/oss/resumable_upload.rb +++ b/examples/aliyun/oss/resumable_upload.rb @@ -4,7 +4,7 @@ require 'yaml' require 'aliyun/oss' -# 初始化OSS Bucket +# Initialize OSS Bucket Aliyun::Common::Logging.set_log_level(Logger::DEBUG) conf_file = '~/.oss.yml' conf = YAML.load(File.read(File.expand_path(conf_file))) @@ -14,7 +14,7 @@ :access_key_id => conf['access_key_id'], :access_key_secret => conf['access_key_secret']).get_bucket(conf['bucket']) -# 辅助打印函数 +# print helper function def demo(msg) puts "######### #{msg} ########" puts @@ -25,7 +25,7 @@ def demo(msg) demo "Resumable upload" do puts "Generate file: /tmp/x, size: 100MB" - # 生成一个100M的文件 + # Create a 100M file File.open('/tmp/x', 'w') do |f| (1..1024*1024).each{ |i| f.puts i.to_s.rjust(99, '0') } end @@ -33,7 +33,7 @@ def demo(msg) cpt_file = '/tmp/x.cpt' File.delete(cpt_file) if File.exist?(cpt_file) - # 上传一个100M的文件 + # Upload a 100M file start = Time.now puts "Start upload: /tmp/x => resumable" bucket.resumable_upload( @@ -42,8 +42,8 @@ def demo(msg) end puts "Upload complete. Cost: #{Time.now - start} seconds." - # 测试方法: + # Test steps: # 1. ruby examples/resumable_upload.rb - # 2. 过几秒后用Ctrl-C中断上传 - # 3. ruby examples/resumable_upload.rb恢复上传 + # 2. Type Ctrl-C to distrupt the upload after a few seconds + # 3. run ruby examples/resumable_upload.rb to recover the upload end diff --git a/examples/aliyun/oss/streaming.rb b/examples/aliyun/oss/streaming.rb index a7450ac..dc108ee 100644 --- a/examples/aliyun/oss/streaming.rb +++ b/examples/aliyun/oss/streaming.rb @@ -5,24 +5,20 @@ require 'aliyun/oss' ## -# 一般来说用户在上传object和下载object时只需要指定文件名就可以满足需要: -# - 在上传的时候client会从指定的文件中读取数据上传到OSS -# - 在下载的时候client会把从OSS下载的数据写入到指定的文件中 +# Generally speaking, when a user uploads or downloads objects with specifying a file: +# - In upload, client will upload the data of the file to OSS. +# - In download, client will download the data from OSS to the file locally. # -# 在某些情况下用户可能会需要流式地上传和下载: -# - 用户要写入到object中的数据不能立即得到全部,而是从网络中流式获取, -# 然后再一段一段地写入到OSS中 -# - 用户要写入到object的数据是经过运算得出,每次得到一部分,用户不希望 -# 保留所有的数据然后一次性写入到OSS -# - 用户下载的object很大,用户不希望一次性把它们下载到内存中,而是希望 -# 获取一部分就处理一部分;用户也不希望把它先下载到文件中,然后再从文 -# 件中读出来处理,这样会让数据经历不必要的拷贝 +# However in some scenarios, users may want to download or upload data in streaming: +# - Users cannot get the whole data for uploading, instead each time they get the partial data from up streaming and write it into OSS. +# - The data users want to write is computed and each compute just returns partial data. Typically Users dont want to compute all data and then write them as the whole +# to OSS. Instead they wantt o compute some data and write the result to OSS immediately. +# - The object users want to download is too big to hold in memory. They want to download some data and then processs them without saving to local file. # -# 当然,对于流式上传的需求,我们可以使用OSS的appendable object来满足。 -# 但是即使是normal object,利用sdk的streaming功能,也可以实现流式上传 -# 和下载。 +# Of course, for streaming upload scenario, we can leverage appendable object to solve. +# However, even for normal object, by using SDK's streaming APIs, you can also achieve the streaming upload or download. -# 初始化OSS client +# Initialize OSS client Aliyun::Common::Logging.set_log_level(Logger::DEBUG) conf_file = '~/.oss.yml' conf = YAML.load(File.read(File.expand_path(conf_file))) @@ -32,7 +28,7 @@ :access_key_id => conf['access_key_id'], :access_key_secret => conf['access_key_secret']).get_bucket(conf['bucket']) -# 辅助打印函数 +# print helper function def demo(msg) puts "######### #{msg} ########" puts @@ -41,9 +37,9 @@ def demo(msg) puts end -# 例子1: 归并排序 -# 有两个文件sort.1, sort.2,它们分别存了一些从小到大排列的整数,每个整 -# 数1行,现在要将它们做归并排序的结果上传到OSS中,命名为sort.all +# Example1: merge sort +# There're two files sort.1 and sort.2 which have the sorted int. Every int occupies one line. +# Now you need to merge sort the two files into one file and uploaded it to OSS. local_1, local_2 = 'sort.1', 'sort.2' result_object = 'sort.all' @@ -83,29 +79,29 @@ def demo(msg) puts "Put object: #{result_object}" - # 将文件下载下来查看 + # download the file and print the content bucket.get_object(result_object, :file => result_object) puts "Get object: #{result_object}" puts "Content: #{File.read(result_object)}" end -# 例子2: 下载进度条 -# 下载一个大文件(10M),在下载的过程中打印下载进度 +# Example 2: download progress bar +# Download a 10M file and print the download progress large_file = 'large_file' demo "Streaming download" do puts "Begin put object: #{large_file}" - # 利用streaming上传 + # Leverage streaming upload bucket.put_object(large_file) do |stream| 10.times { stream << "x" * (1024 * 1024) } end - # 查看object大小 + # check object size object_size = bucket.get_object(large_file).size puts "Put object: #{large_file}, size: #{object_size}" - # 流式下载文件,仅打印进度,不保存文件 + # streaming download file, print the progress, but not save the file def to_percentile(v) "#{(v * 100.0).round(2)} %" end @@ -114,7 +110,7 @@ def to_percentile(v) last_got, got = 0, 0 bucket.get_object(large_file) do |chunk| got += chunk.size - # 仅在下载进度大于10%的时候打印 + # only print the progress when the progress is more than 10%. if (got - last_got).to_f / object_size > 0.1 puts "Progress: #{to_percentile(got.to_f / object_size)}" last_got = got diff --git a/examples/aliyun/oss/using_sts.rb b/examples/aliyun/oss/using_sts.rb index 29ede9e..a750ae1 100644 --- a/examples/aliyun/oss/using_sts.rb +++ b/examples/aliyun/oss/using_sts.rb @@ -5,12 +5,12 @@ require 'aliyun/sts' require 'aliyun/oss' -# 初始化OSS client +# Initialize OSS client Aliyun::Common::Logging.set_log_level(Logger::DEBUG) conf_file = '~/.sts.yml' conf = YAML.load(File.read(File.expand_path(conf_file))) -# 辅助打印函数 +# print helper function def demo(msg) puts "######### #{msg} ########" puts diff --git a/examples/aliyun/sts/assume_role.rb b/examples/aliyun/sts/assume_role.rb index 3728995..238cd1e 100644 --- a/examples/aliyun/sts/assume_role.rb +++ b/examples/aliyun/sts/assume_role.rb @@ -11,7 +11,7 @@ :access_key_id => conf['access_key_id'], :access_key_secret => conf['access_key_secret']) -# 辅助打印函数 +# print helper function def demo(msg) puts "######### #{msg} ########" puts diff --git a/lib/aliyun/common/logging.rb b/lib/aliyun/common/logging.rb index 46e339c..14b5325 100644 --- a/lib/aliyun/common/logging.rb +++ b/lib/aliyun/common/logging.rb @@ -20,12 +20,12 @@ def self.set_log_level(level) Logging.logger.level = level end - # 设置日志输出的文件 + # set logger output file def self.set_log_file(file) @log_file = file end - # 获取logger + # get logger def logger Logging.logger end diff --git a/lib/aliyun/oss/bucket.rb b/lib/aliyun/oss/bucket.rb index 2b775e1..d79cc82 100644 --- a/lib/aliyun/oss/bucket.rb +++ b/lib/aliyun/oss/bucket.rb @@ -3,11 +3,11 @@ module Aliyun module OSS ## - # Bucket是用户的Object相关的操作的client,主要包括三部分功能: - # 1. bucket相关:获取/设置bucket的属性(acl, logging, referer, - # website, lifecycle, cors) - # 2. object相关:上传、下载、追加、拷贝object等 - # 3. multipart相关:断点续传、断点续载 + # Bucket is the class for object related operations. It consists of three major functions: + # 1. bucket related:Gets/Sets bucket settings (e.g. acl, logging, referer, + # website, lifecycle, cors, etc) + # 2. object related:Upload, download, append, copy object, etc + # 3. multipart related:upload with checkpoint, download with checkpoint. class Bucket < Common::Struct::Base attrs :name, :location, :creation_time @@ -17,28 +17,28 @@ def initialize(opts = {}, protocol = nil) @protocol = protocol end - ### Bucket相关的API ### + ### Bucket related API ### - # 获取Bucket的ACL + # Gets Bucket ACL # @return [String] Bucket的{OSS::ACL ACL} def acl @protocol.get_bucket_acl(name) end - # 设置Bucket的ACL + # Sets Bucket ACL # @param acl [String] Bucket的{OSS::ACL ACL} def acl=(acl) @protocol.put_bucket_acl(name, acl) end - # 获取Bucket的logging配置 - # @return [BucketLogging] Bucket的logging配置 + # Gets Bucket logging config + # @return [BucketLogging] Bucket logging config def logging @protocol.get_bucket_logging(name) end - # 设置Bucket的logging配置 - # @param logging [BucketLogging] logging配置 + # Sets Bucket logging config + # @param logging [BucketLogging] logging config def logging=(logging) if logging.enabled? @protocol.put_bucket_logging(name, logging) @@ -47,8 +47,8 @@ def logging=(logging) end end - # 获取Bucket的website配置 - # @return [BucketWebsite] Bucket的website配置 + # Gets Bucket website config + # @return [BucketWebsite] Bucket website config def website begin w = @protocol.get_bucket_website(name) @@ -59,8 +59,8 @@ def website w || BucketWebsite.new end - # 设置Bucket的website配置 - # @param website [BucketWebsite] website配置 + # Sets Bucket website config + # @param website [BucketWebsite] website config def website=(website) if website.enabled? @protocol.put_bucket_website(name, website) @@ -69,21 +69,20 @@ def website=(website) end end - # 获取Bucket的Referer配置 - # @return [BucketReferer] Bucket的Referer配置 + # Gets Bucket referer config + # @return [BucketReferer] Bucket referer config def referer @protocol.get_bucket_referer(name) end - # 设置Bucket的Referer配置 - # @param referer [BucketReferer] Referer配置 + # Sets Bucket referer config + # @param referer [BucketReferer] Referer config def referer=(referer) @protocol.put_bucket_referer(name, referer) end - # 获取Bucket的生命周期配置 - # @return [Array] Bucket的生命周期规则,如果 - # 当前Bucket未设置lifecycle,则返回[] + # GETS Bucket's lifecycle config + # @return [Array] Bucket's lifecycle config, if it's not set, return []. def lifecycle begin r = @protocol.get_bucket_lifecycle(name) @@ -94,11 +93,10 @@ def lifecycle r || [] end - # 设置Bucket的生命周期配置 - # @param rules [Array] 生命 - # 周期配置规则 - # @see OSS::LifeCycleRule 查看如何设置生命周期规则 - # @note 如果rules为空,则会删除这个bucket上的lifecycle配置 + # Sets Bucket's lifecycle config + # @param rules [Array] lifecycle rule config. + # @see OSS::LifeCycleRule for how to set lifecycle rules. + # @note if rules is empty, the existing lifecycle config will be deleted. def lifecycle=(rules) if rules.empty? @protocol.delete_bucket_lifecycle(name) @@ -107,9 +105,8 @@ def lifecycle=(rules) end end - # 获取Bucket的跨域资源共享(CORS)的规则 - # @return [Array] Bucket的CORS规则,如果当前 - # Bucket未设置CORS规则,则返回[] + # Gets Bucket's CORS rules + # @return [Array] Bucket's CORS rules. If it's not set, returns []. def cors begin r = @protocol.get_bucket_cors(name) @@ -120,9 +117,9 @@ def cors r || [] end - # 设置Bucket的跨域资源共享(CORS)的规则 - # @param rules [Array] CORS规则 - # @note 如果rules为空,则会删除这个bucket上的CORS配置 + # Sets Bucket CORS rules + # @param rules [Array] CORS rules + # @note If rules are empty, it will delete the existing CORS config. def cors=(rules) if rules.empty? @protocol.delete_bucket_cors(name) @@ -131,30 +128,27 @@ def cors=(rules) end end - ### Object相关的API ### + ### Object related API ### - # 列出bucket中的object - # @param opts [Hash] 查询选项 - # @option opts [String] :prefix 返回的object的前缀,如果设置则只 - # 返回那些名字以它为前缀的object - # @option opts [String] :marker 如果设置,则只返回名字在它之后 - # (字典序,不包含marker)的object - # @option opts [String] :delimiter 用于获取公共前缀的分隔符,从 - # 前缀后面开始到第一个分隔符出现的位置之前的字符,作为公共前缀。 + # Lists objects in the bucket + # @param opts [Hash] options for the list operation + # @option opts [String] :prefix object prefix. If set, it will only return objects whose key has the prefix. + # @option opts [String] :marker object marker. If set, it will only return objects whose key is greater than the marker. + # @option opts [String] :delimiter the separator for getting common prefix. The common prefixes are the objects + # whose key starting with prefix and ending with the delimiter. # @example - # 假设我们有如下objects: + # If we have the following objects: # /foo/bar/obj1 # /foo/bar/obj2 # ... # /foo/bar/obj9999999 # /foo/xxx/ - # 用'foo/'作为前缀, '/'作为分隔符, 则得到的公共前缀是: - # '/foo/bar/', '/foo/xxx/'。它们恰好就是目录'/foo/'下的所有子目 - # 录。用delimiter获取公共前缀的方法避免了查询当前bucket下的所有 - # object(可能数量巨大),是用于模拟目录结构的常用做法。 - # @return [Enumerator] 其中Object可能是{OSS::Object},也 - # 可能是{String},此时它是一个公共前缀 + # Use 'foo/' as prefix and '/' as delimiter, then the common prefixes are: + # '/foo/bar/', '/foo/xxx/'. They're the subdirectories of directory '/foo/'. + # Use prefix and delimiter for getting common prefix could avoid querying all the objects under the bucket. + # This is the common practise for iterating the directory structures. + # @return [Enumerator] the object could be {OSS::Object} or {String}. In latter case it's the common prefix. # @example # all = bucket.list_objects # all.each do |i| @@ -169,31 +163,29 @@ def list_objects(opts = {}) @protocol, name, opts.merge(encoding: KeyEncoding::URL)).to_enum end - # 向Bucket中上传一个object - # @param key [String] Object的名字 - # @param opts [Hash] 上传object时的选项(可选) - # @option opts [String] :file 设置所上传的文件 - # @option opts [String] :content_type 设置所上传的内容的 - # Content-Type,默认是application/octet-stream - # @option opts [Hash] :metas 设置object的meta,这是一些用户自定 - # 义的属性,它们会和object一起存储,在{#get_object}的时候会 - # 返回这些meta。属性的key不区分大小写。例如:{ 'year' => '2015' } - # @option opts [Callback] :callback 指定操作成功后OSS的 - # 上传回调,上传成功后OSS会向用户的应用服务器发一个HTTP POST请 - # 求,`:callback`参数指定这个请求的相关参数 - # @option opts [Hash] :headers 指定请求的HTTP Header,不区分大小 - # 写。这里指定的值会覆盖通过`:content_type`和`:metas`设置的值。 - # @yield [HTTP::StreamWriter] 如果调用的时候传递了block,则写入 - # 到object的数据由block指定 - # @example 流式上传数据 + # Uploads an object to the bucket + # @param key [String] Object key + # @param opts [Hash] options for uploading + # @option opts [String] :file local file to upload + # @option opts [String] :content_type content to upload + # Content-Type,default is application/octet-stream + # @option opts [Hash] :metas object's custom meta,which will be stored with object. + # They're returned when {#get_object} are called. The custom metadata's key are not case sensitive. + # For example :{ 'year' => '2015' } is same as {'YEAR' => '2015'} + # @option opts [Callback] :callback specifies the callback after the operation succeeds. + # After the upload succeeds, OSS could send a HTTP POST to user's application--the callback parameter specifies parameters of this post request. + # @option opts [Hash] :headers specifies the HTTP headers, the headers are case insensitive. + # Its values could overwrite the the value set by `:content_type` and `:metas`. + # @yield [HTTP::StreamWriter] if the block is specified, then the object content is specified by thsi block. + # @example upload streaming data # put_object('x'){ |stream| 100.times { |i| stream << i.to_s } } # put_object('x'){ |stream| stream << get_data } - # @example 上传文件 + # @example upload file # put_object('x', :file => '/tmp/x') - # @example 指定Content-Type和metas + # @example specifies Content-Type and metas # put_object('x', :file => '/tmp/x', :content_type => 'text/html', # :metas => {'year' => '2015', 'people' => 'mary'}) - # @example 指定Callback + # @example specifies Callback # callback = Aliyun::OSS::Callback.new( # url: 'http://10.101.168.94:1234/callback', # query: {user: 'put_object'}, @@ -201,12 +193,10 @@ def list_objects(opts = {}) # ) # # bucket.put_object('files/hello', callback: callback) - # @raise [CallbackError] 如果文件上传成功而Callback调用失败,抛 - # 出此错误 - # @note 如果opts中指定了`:file`,则block会被忽略 - # @note 如果指定了`:callback`,则可能文件上传成功,但是callback - # 执行失败,此时会抛出{OSS::CallbackError},用户可以选择接住这 - # 个异常,以忽略Callback调用错误 + # @raise [CallbackError] If file upload succeeds but callback failed, it will throw this error. + # @note If `:file` is specified in opts, then block parameter is ignored. + # @note If `:callback` is specified, then it's possibel that file upload succeeds but callback fails, in which case + # the {OSS::CallbackError} is thrown. The call could opt to catch this exception and ignore the callback failure. def put_object(key, opts = {}, &block) args = opts.dup @@ -225,39 +215,38 @@ def put_object(key, opts = {}, &block) end end - # 从Bucket中下载一个object - # @param key [String] Object的名字 - # @param opts [Hash] 下载Object的选项(可选) - # @option opts [Array] :range 指定下载object的部分数据, - # range应只包含两个数字,表示一个*左开右闭*的bytes range - # @option opts [String] :file 指定将下载的object写入到文件中 - # @option opts [Hash] :condition 指定下载object需要满足的条件 - # * :if_modified_since (Time) 指定如果object的修改时间晚于这个值,则下载 - # * :if_unmodified_since (Time) 指定如果object从这个时间后再无修改,则下载 - # * :if_match_etag (String) 指定如果object的etag等于这个值,则下载 - # * :if_unmatch_etag (String) 指定如果object的etag不等于这个值,则下载 - # @option opts [Hash] :headers 指定请求的HTTP Header,不区分大小 - # 写。这里指定的值会覆盖通过`:range`和`:condition`设置的值。 - # @option opts [Hash] :rewrite 指定下载object时Server端返回的响应头部字段的值 - # * :content_type (String) 指定返回的响应中Content-Type的值 - # * :content_language (String) 指定返回的响应中Content-Language的值 - # * :expires (Time) 指定返回的响应中Expires的值 - # * :cache_control (String) 指定返回的响应中Cache-Control的值 - # * :content_disposition (String) 指定返回的响应中Content-Disposition的值 - # * :content_encoding (String) 指定返回的响应中Content-Encoding的值 - # @return [OSS::Object] 返回Object对象 - # @yield [String] 如果调用的时候传递了block,则获取到的object的数据交由block处理 - # @example 流式下载文件 + # Download an object from the bucket + # @param key [String] Object key. + # @param opts [Hash] options for downloading objects + # @option opts [Array] :range specifies the exact offset of the object to download. + # The range should follow the HTTP Range specification (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range). + # @option opts [String] :file specifies the local file path for store the object to download. + # @option opts [Hash] :condition specifies the condition to download the file. + # * :if_modified_since (Time) if the object's last modified time is later than this value, download the object. + # * :if_unmodified_since (Time) if the object's last modified time is earlier than this value, download the object. + # * :if_match_etag (String) if the object's ETag matches this value, download the object. + # * :if_unmatch_etag (String) if the object's ETag does not match this value, download the object. + # @option opts [Hash] :headers specifies HTTP headers, they're case insensitive. + # The headers' values could overwrite the values set by `:range` and `:condition`. + # @option opts [Hash] :rewrite specifies the headers the OSS server response should contain for the download request. + # * :content_type (String) specifies the response to return Content-Type value + # * :content_language (String) specifies the response to return Content-Language value + # * :expires (Time) specifies the response to return Expires value. + # * :cache_control (String) specifies the response to return Cache-Control value. + # * :content_disposition (String) specifies the response to return Content-Disposition value. + # * :content_encoding (String) specifies the response to return Content-Encoding value. + # @return [OSS::Object] returns Object + # @yield [String] if the block is specified, then the data will be stored in block. + # @example stremaing data download # get_object('x'){ |chunk| handle_chunk_data(chunk) } - # @example 下载到本地文件 + # @example download object to local file # get_object('x', :file => '/tmp/x') - # @example 指定检查条件 + # @example specifies condition # get_object('x', :file => '/tmp/x', :condition => {:if_match_etag => 'etag'}) - # @example 指定重写响应的header信息 + # @example specifies rewrite header information. # get_object('x', :file => '/tmp/x', :rewrite => {:content_type => 'text/html'}) - # @note 如果opts中指定了`:file`,则block会被忽略 - # @note 如果既没有指定`:file`也没有指定block,则只获取Object - # meta而不下载Object内容 + # @note If opts contains `:file`,then block is ignored. + # @note If neither `:file` nor block is specified, then only object meta is returned (no content) def get_object(key, opts = {}, &block) obj = nil file = opts[:file] @@ -276,14 +265,14 @@ def get_object(key, opts = {}, &block) obj end - # 更新Object的metas - # @param key [String] Object的名字 - # @param metas [Hash] Object的meta - # @param conditions [Hash] 指定更新Object meta需要满足的条件, - # 同{#get_object} - # @return [Hash] 更新后文件的信息 - # * :etag [String] 更新后文件的ETag - # * :last_modified [Time] 更新后文件的最后修改时间 + # Updates Object's metas + # @param key [String] Object's name + # @param metas [Hash] Object's meta + # @param conditions [Hash] Specifies the condition to update Object meta. + # It's same as the one in {#get_object} + # @return [Hash] updated file metadatas + # * :etag [String] new ETag + # * :last_modified [Time] updated last modified time def update_object_metas(key, metas, conditions = {}) @protocol.copy_object( name, key, key, @@ -292,9 +281,9 @@ def update_object_metas(key, metas, conditions = {}) :condition => conditions) end - # 判断一个object是否存在 - # @param key [String] Object的名字 - # @return [Boolean] 如果Object存在返回true,否则返回false + # checks if an object exists or not. + # @param key [String] Object key. + # @return [Boolean] If object exists, returns true; otherwise returns false. def object_exists?(key) begin get_object(key) @@ -309,28 +298,28 @@ def object_exists?(key) alias :object_exist? :object_exists? - # 向Bucket中的object追加内容。如果object不存在,则创建一个 - # Appendable Object。 - # @param key [String] Object的名字 - # @param opts [Hash] 上传object时的选项(可选) - # @option opts [String] :file 指定追加的内容从文件中读取 - # @option opts [String] :content_type 设置所上传的内容的 - # Content-Type,默认是application/octet-stream - # @option opts [Hash] :metas 设置object的meta,这是一些用户自定 - # 义的属性,它们会和object一起存储,在{#get_object}的时候会 - # 返回这些meta。属性的key不区分大小写。例如:{ 'year' => '2015' } - # @option opts [Hash] :headers 指定请求的HTTP Header,不区分大小 - # 写。这里指定的值会覆盖通过`:content_type`和`:metas`设置的值。 - # @example 流式上传数据 + # Appends content to the object in a bucket. If the object does not exist, create a new one. + # Appendable Object. + # @param key [String] Object key + # @param opts [Hash] opts for appending the object (optional) + # @option opts [String] :file specifies the local file to read from for the appending. + # @option opts [String] :content_type sets the content-type for the upload + # Content-Type,default is application/octet-stream + # @option opts [Hash] :metas Sets object meta. These user custom metadata will be stored with object. + # And {#get_object} would return these meta. + # metas' key are case insensitive. For example:{ 'year' => '2015' } + # @option opts [Hash] :headers specifies HTTP header, it's case insenstive. + # The values would overwrite the one set by `:content_type` and `:metas`. + # @example append streaming data. # pos = append_object('x', 0){ |stream| 100.times { |i| stream << i.to_s } } # append_object('x', pos){ |stream| stream << get_data } - # @example 上传文件 + # @example append a file # append_object('x', 0, :file => '/tmp/x') - # @example 指定Content-Type和metas + # @example specifies Content-Type and metas # append_object('x', 0, :file => '/tmp/x', :content_type => 'text/html', # :metas => {'year' => '2015', 'people' => 'mary'}) - # @return [Integer] 返回下次append的位置 - # @yield [HTTP::StreamWriter] 同 {#put_object} + # @return [Integer] return the offset for next append. + # @yield [HTTP::StreamWriter] same as {#put_object} def append_object(key, pos, opts = {}, &block) args = opts.dup @@ -351,26 +340,24 @@ def append_object(key, pos, opts = {}, &block) next_pos end - # 将Bucket中的一个object拷贝成另外一个object - # @param source [String] 源object名字 - # @param dest [String] 目标object名字 - # @param opts [Hash] 拷贝object时的选项(可选) - # @option opts [String] :src_bucket 源object所属的Bucket,默认与 - # 目标文件为同一个Bucket。源Bucket与目标Bucket必须属于同一个Region。 - # @option opts [String] :acl 目标文件的acl属性,默认为private - # @option opts [String] :meta_directive 指定是否拷贝源object的 - # meta信息,默认为{OSS::MetaDirective::COPY}:即拷贝object的时 - # 候也拷贝meta信息。 - # @option opts [Hash] :metas 设置object的meta,这是一些用户自定 - # 义的属性,它们会和object一起存储,在{#get_object}的时候会 - # 返回这些meta。属性的key不区分大小写。例如:{ 'year' => '2015' - # }。如果:meta_directive为{OSS::MetaDirective::COPY},则:metas - # 会被忽略。 - # @option opts [Hash] :condition 指定拷贝object需要满足的条件, - # 同 {#get_object} - # @return [Hash] 目标文件的信息 - # * :etag [String] 目标文件的ETag - # * :last_modified [Time] 目标文件的最后修改时间 + # copy an object in the bucket to another one. + # @param source [String] source object name + # @param dest [String] target object name + # @param opts [Hash] options + # @option opts [String] :src_bucket source object's bucket. By default it's same as the target object's bucket + # Source Bucket and target bucket must belong to the same region. + # @option opts [String] :acl target object's ACL property. Default is private. + # @option opts [String] :meta_directive specifies if copying the metadata from source object as well. + # Default is {OSS::MetaDirective::COPY}:means it copies the metadata. + # @option opts [Hash] :metas Sets object's meta,which is stored with the object content. + # {#get_object} could return these metadata. + # Its key is case insensitive. For example: { 'year' => '2015'}. + # if meta_directive is {OSS::MetaDirective::COPY}, then this opt will be ignored. + # @option opts [Hash] :condition specifies conditions to copy the object. + # It's same as {#get_object}. + # @return [Hash] target object's information. + # * :etag [String] Target object's ETag + # * :last_modified [Time] Target object last modified time. def copy_object(source, dest, opts = {}) args = opts.dup @@ -378,89 +365,80 @@ def copy_object(source, dest, opts = {}) @protocol.copy_object(name, source, dest, args) end - # 删除一个object - # @param key [String] Object的名字 + # Deletes an object + # @param key [String] Object name def delete_object(key) @protocol.delete_object(name, key) end - # 批量删除object - # @param keys [Array] Object的名字集合 - # @param opts [Hash] 删除object的选项(可选) - # @option opts [Boolean] :quiet 指定是否允许Server返回成功删除的 - # object,默认为false,即返回删除结果 - # @return [Array] 成功删除的object的名字,如果指定 - # 了:quiet参数,则返回[] + # deletes multiple objects + # @param keys [Array] Object names' set + # @param opts [Hash] options for deleting objects + # @option opts [Boolean] :quiet specifies if prevent server returning objects status. + # Default is false which means returns all the objects' deletion status. + # @return [Array] return deleted objects list. If quiet is specified, return []. def batch_delete_objects(keys, opts = {}) @protocol.batch_delete_objects( name, keys, opts.merge(encoding: KeyEncoding::URL)) end - # 设置object的ACL - # @param key [String] Object的名字 - # @param acl [String] Object的{OSS::ACL ACL} + # Sets object ACL + # @param key [String] Object name + # @param acl [String] Object's {OSS::ACL ACL} def set_object_acl(key, acl) @protocol.put_object_acl(name, key, acl) end - # 获取object的ACL - # @param key [String] Object的名字 + # Gets object ACL + # @param key [String] Object name # @return [String] object的{OSS::ACL ACL} def get_object_acl(key) @protocol.get_object_acl(name, key) end - # 获取object的CORS规则 - # @param key [String] Object的名字 + # Gets object's CORS rule + # @param key [String] Object name # @return [OSS::CORSRule] def get_object_cors(key) @protocol.get_object_cors(name, key) end ## - # 断点续传相关的API + # APIs about upload with checkpoint (a.k. resumable upload) # - # 上传一个本地文件到bucket中的一个object,支持断点续传。指定的文 - # 件会被分成多个分片进行上传,只有所有分片都上传成功整个文件才 - # 上传成功。 - # @param key [String] Object的名字 - # @param file [String] 本地文件的路径 - # @param opts [Hash] 上传文件的可选项 - # @option opts [String] :content_type 设置所上传的内容的 - # Content-Type,默认是application/octet-stream - # @option opts [Hash] :metas 设置object的meta,这是一些用户自定 - # 义的属性,它们会和object一起存储,在{#get_object}的时候会 - # 返回这些meta。属性的key不区分大小写。例如:{ 'year' => '2015' } - # @option opts [Integer] :part_size 设置分片上传时每个分片的大小, - # 默认为10 MB。断点上传最多允许10000个分片,如果文件大于10000个 - # 分片的大小,则每个分片的大小会大于10MB。 - # @option opts [String] :cpt_file 断点续传的checkpoint文件,如果 - # 指定的cpt文件不存在,则会在file所在目录创建一个默认的cpt文件, - # 命名方式为:file.cpt,其中file是用户要上传的文件。在上传的过 - # 程中会不断更新此文件,成功完成上传后会删除此文件;如果指定的 - # cpt文件已存在,则从cpt文件中记录的点继续上传。 - # @option opts [Boolean] :disable_cpt 是否禁用checkpoint功能,如 - # 果设置为true,则在上传的过程中不会写checkpoint文件,这意味着 - # 上传失败后不能断点续传,而只能重新上传整个文件。如果这个值为 - # true,则:cpt_file会被忽略。 - # @option opts [Callback] :callback 指定文件上传成功后OSS的 - # 上传回调,上传成功后OSS会向用户的应用服务器发一个HTTP POST请 - # 求,`:callback`参数指定这个请求的相关参数 - # @option opts [Hash] :headers 指定请求的HTTP Header,不区分大小 - # 写。这里指定的值会覆盖通过`:content_type`和`:metas`设置的值。 - # @yield [Float] 如果调用的时候传递了block,则会将上传进度交由 - # block处理,进度值是一个0-1之间的小数 - # @raise [CheckpointBrokenError] 如果cpt文件被损坏,则抛出此错误 - # @raise [FileInconsistentError] 如果指定的文件与cpt中记录的不一 - # 致,则抛出此错误 - # @raise [CallbackError] 如果文件上传成功而Callback调用失败,抛 - # 出此错误 + # Uploads a local file to the bucket with checkpoint support. + # The file will be upload in parts and only after all parts upload succeed, the file upload is complete and available for access. + # + # @param key [String] Object key + # @param file [String] the local file path + # @param opts [Hash] options for upload file + # @option opts [String] :content_type content-type + # Content-Type,default is application/octet-stream + # @option opts [Hash] :metas Sets object meta which is user's custom attributes. They're stored with the object content. + # The meta information is returned in {#get_object}'s response. + # The keys in meta are case insensitive. For example:{ 'year' => '2015' } + # @option opts [Integer] :part_size Part size + # Default is 10 MB. The max part count is 10,000. + # @option opts [String] :cpt_file the checkpoint file path (local) If the cpt_file does not exist, it will create a + # default cpt file (named as $file.cpt, $file is the file name to upload) of the current file's folder. + # The cpt file has the upload progress information and thus if the upload failed, the next upload would resume + # the upload according to the checkpoint. + # @option opts [Boolean] :disable_cpt flag of disabling checkpoint function. If true, the checkpoint function is disabled and cpt_file is ignored. + # @option opts [Callback] :callback specifies the callback information after a successful upload. + # After the file is uploaded, OSS could send a POST request to the specified URL and other information in the callback parameter. + # @option opts [Hash] :headers specifies the HTTP headers in the request, it's case insensitive. + # The values could overwrite the one set by `:content_type` and `:metas`. + # @yield [Float] If the block is specified, the upload progress will be stored in the block. + # The progress is the number between 0 to 1. + # @raise [CheckpointBrokenError] If the cp file is corrupted, the CheckpointBrokenError is thrown. + # @raise [FileInconsistentErro] If the specified file does not match the one in cpt, the eFileInconsistentError is thrown. + # @raise [CallbackError] If the file is uploaded but the callback call fails, CallbackError is thrown # @example # bucket.resumable_upload('my-object', '/tmp/x') do |p| # puts "Progress: #{(p * 100).round(2)} %" # end - # @example 指定Callback + # @example specifies Callback # callback = Aliyun::OSS::Callback.new( # url: 'http://10.101.168.94:1234/callback', # query: {user: 'put_object'}, @@ -468,9 +446,8 @@ def get_object_cors(key) # ) # # bucket.resumable_upload('files/hello', '/tmp/x', callback: callback) - # @note 如果指定了`:callback`,则可能文件上传成功,但是callback - # 执行失败,此时会抛出{OSS::CallbackError},用户可以选择接住这 - # 个异常,以忽略Callback调用错误 + # @note If `:callback` is specified, then it's possible that file upload succeeds but callback fails. + # Then in this case the {OSS::CallbackError} is thrown. User could opt to catch this exception to ignore the callback failure. def resumable_upload(key, file, opts = {}, &block) args = opts.dup @@ -486,43 +463,27 @@ def resumable_upload(key, file, opts = {}, &block) ).run end - # 下载bucket中的一个object到本地文件,支持断点续传。指定的object - # 会被分成多个分片进行下载,只有所有的分片都下载成功整个object才 - # 下载成功。对于每个下载的分片,会在file所在目录建立一个临时文件 - # file.part.N,下载成功后这些part文件会被合并成最后的file然后删 - # 除。 - # @param key [String] Object的名字 - # @param file [String] 本地文件的路径 - # @param opts [Hash] 下载文件的可选项 - # @option opts [Integer] :part_size 设置分片上传时每个分片的大小, - # 默认为10 MB。断点下载最多允许100个分片,如果文件大于100个分片, - # 则每个分片的大小会大于10 MB - # @option opts [String] :cpt_file 断点续传的checkpoint文件,如果 - # 指定的cpt文件不存在,则会在file所在目录创建一个默认的cpt文件, - # 命名方式为:file.cpt,其中file是用户要下载的文件名。在下载的过 - # 程中会不断更新此文件,成功完成下载后会删除此文件;如果指定的 - # cpt文件已存在,则从cpt文件中记录的点继续下载。 - # @option opts [Boolean] :disable_cpt 是否禁用checkpoint功能,如 - # 果设置为true,则在下载的过程中不会写checkpoint文件,这意味着 - # 下载失败后不能断点续传,而只能重新下载整个文件。如果这个值为true, - # 则:cpt_file会被忽略。 - # @option opts [Hash] :condition 指定下载object需要满足的条件, - # 同 {#get_object} - # @option opts [Hash] :headers 指定请求的HTTP Header,不区分大小 - # 写。这里指定的值会覆盖通过`:condition`设置的值。 - # @option opts [Hash] :rewrite 指定下载object时Server端返回的响 - # 应头部字段的值,同 {#get_object} - # @yield [Float] 如果调用的时候传递了block,则会将下载进度交由 - # block处理,进度值是一个0-1之间的小数 - # @raise [CheckpointBrokenError] 如果cpt文件被损坏,则抛出此错误 - # @raise [ObjectInconsistentError] 如果指定的object的etag与cpt文 - # 件中记录的不一致,则抛出错误 - # @raise [PartMissingError] 如果已下载的部分(.part文件)找不到, - # 则抛出此错误 - # @raise [PartInconsistentError] 如果已下载的部分(.part文件)的 - # MD5值与cpt文件记录的不一致,则抛出此错误 - # @note 已经下载的部分会在file所在的目录创建.part文件,命名方式 - # 为file.part.N + # Download bucket to the local file, with checkpoint supported. The specified object could be downloaded in parts. + # And only after all the parts are downloaded, the whole object download is complete. + # For every downloaded part, it will be stored in the file's folder with name pattern file.part.N. + # Once the download succceeds, all these parts will be merged to the final file and then get deleted. + # @param key [String] Object key + # @param file [String] the local file path + # @param opts [Hash] options for downloading the file. + # @option opts [Integer] :part_size part size. Default is 10MB. Max part count is 100 and thus the part size could be + # bigger if the file is more than 1GB. + # @option opts [String] :cpt_file checkpoint file. If the cpt file does not exist, it will create one named as $file.cpt----$file is the target file name. + # If the cpt file exists, then the download will resume from the last download according to the checkpoint. + # @option opts [Boolean] :disable_cpt flag of disabling checkpoint. If true, then it's disabled and cpt_file is ignored. + # @option opts [Hash] :condition the conditions to download the object, same as {#get_object}. + # @option opts [Hash] :headers specifies the http headers (case insensitive). They may overwrite the values set by 'condition'. + # @option opts [Hash] :rewrite specifies the headers to ask OSS return them in the response. Check out {#get_object} for the detail. + # @yield [Float] If the block is specified, the download progress is stored in block, which is the number between 0 to 1. + # @raise [CheckpointBrokenError] If the cpt file is corrupted, the error is thrown. + # @raise [ObjectInconsistentError] If the object's ETag does not match the cpt file's one, the error is thrown. + # @raise [PartMissingError] If the download parts file do not exist, the error is thrown. + # @raise [PartInconsistentError] If the downloaded parts file's MD5 does not match with the CPT file, the error is thrown. + # @note The downloaded parts will be stored in the same folder of the target fiel with name as file.part.N. # @example # bucket.resumable_download('my-object', '/tmp/x') do |p| # puts "Progress: #{(p * 100).round(2)} %" @@ -542,24 +503,15 @@ def resumable_download(key, file, opts = {}, &block) ).run end - # 列出此Bucket中正在进行的multipart上传请求,不包括已经完成或者 - # 被取消的。 - # @param [Hash] opts 可选项 - # @option opts [String] :key_marker object key的标记,根据有没有 - # 设置:id_marker,:key_marker的含义不同: - # 1. 如果未设置:id_marker,则只返回object key在:key_marker之后 - # (字典序,不包含marker)的upload请求 - # 2. 如果设置了:id_marker,则返回object key在:key_marker之后 - # (字典序,不包含marker)的uplaod请求*和*Object - # key与:key_marker相等,*且*upload id在:id_marker之后(字母 - # 表顺序排序,不包含marker)的upload请求 - # @option opts [String] :id_marker upload id的标记,如 - # 果:key_marker没有设置,则此参数会被忽略;否则与:key_marker一起 - # 决定返回的结果(见上) - # @option opts [String] :prefix 如果指定,则只返回object key中符 - # 合指定前缀的upload请求 - # @return [Enumerator] 其中每一个元素表 - # 示一个upload请求 + # Lists all ongoing multipart upload requests, not includes completed or aborted one. + # @param [Hash] opts options + # @option opts [String] :key_marker object key marker. Its behavior depends on if id_marker is set: + # 1. If :id_marker is not specifeid,then returned objects' key are all larger than :key_marker in lexicrographic order. + # 2. If :id_marker is specified, then the returned objects' key are larger than :key_marker or same as the :key_marker but the upload id is + # bigger thant he :id_marker. + # @option opts [String] :id_marker upload id marker. See the detail in :key_marker. + # @option opts [String] :prefix if the prefix is specified, only return the uploads whose target object key has the specified prefix. + # @return [Enumerator] Every element represents an upload request. # @example # key_marker = 1, id_marker = null # # return <2, 0>, <2, 1>, <3, 0> ... @@ -570,26 +522,25 @@ def list_uploads(opts = {}) @protocol, name, opts.merge(encoding: KeyEncoding::URL)).to_enum end - # 取消一个multipart上传请求,一般用于清除Bucket下因断点上传而产 - # 生的文件碎片。成功取消后属于这个上传请求的分片都会被清除。 - # @param [String] upload_id 上传请求的id,可通过{#list_uploads} - # 获得 - # @param [String] key Object的名字 + # Cancels the multipart upload request, to clear all parts data uploaded. + # A successful cancel will clear all uploaded parts data of the upload. + # @param [String] upload_id uplaod request Id. It could be retrieved from {#list_uploads} + # @param [String] key Object key. def abort_upload(upload_id, key) @protocol.abort_multipart_upload(name, key, upload_id) end - # 获取Bucket的URL - # @return [String] Bucket的URL + # Gets bucket's URL + # @return [String] Bucket URL def bucket_url @protocol.get_request_url(name) end - # 获取Object的URL - # @param [String] key Object的key - # @param [Boolean] sign 是否对URL进行签名,默认为是 - # @param [Fixnum] expiry URL的有效时间,单位为秒,默认为60s - # @return [String] 用于直接访问Object的URL + # Gets object's URL + # @param [String] key Object key + # @param [Boolean] sign flag of signing the url. Default is true + # @param [Fixnum] expiry URL's expiration time in seconds. Default is 60 seconds. + # @return [String] return the object's URL which could be used for accessing the object directly. def object_url(key, sign = true, expiry = 60) url = @protocol.get_request_url(name, key) return url unless sign @@ -626,15 +577,15 @@ def object_url(key, sign = true, expiry = 60) [url, query_string].join('?') end - # 获取用户所设置的ACCESS_KEY_ID - # @return [String] 用户的ACCESS_KEY_ID + # gets the user's ACCESS_KEY_ID + # @return [String] gets the user's ACCESS_KEY_ID def access_key_id @protocol.get_access_key_id end - # 用ACCESS_KEY_SECRET对内容进行签名 - # @param [String] string_to_sign 要进行签名的内容 - # @return [String] 生成的签名 + # Sign the content with ACCESS_KEY_SECRET + # @param [String] string_to_sign the content to sign + # @return [String] the signature def sign(string_to_sign) @protocol.sign(string_to_sign) end diff --git a/lib/aliyun/oss/client.rb b/lib/aliyun/oss/client.rb index 59aaf26..89ca3a6 100644 --- a/lib/aliyun/oss/client.rb +++ b/lib/aliyun/oss/client.rb @@ -4,9 +4,9 @@ module Aliyun module OSS ## - # OSS服务的客户端,用于获取bucket列表,创建/删除bucket。Object相关 - # 的操作请使用{OSS::Bucket}。 - # @example 创建Client + # OSS service's client class, which is for getting bucket list, creating or deleting bucket. For {OSS:Object} related operations, + # please use {OSS::Bucket}. + # @example creates a Client object # endpoint = 'oss-cn-hangzhou.aliyuncs.com' # client = Client.new( # :endpoint => endpoint, @@ -18,30 +18,24 @@ module OSS # bucket = client.get_bucket('my-bucket') class Client - # 构造OSS client,用于操作buckets。 - # @param opts [Hash] 构造Client时的参数选项 - # @option opts [String] :endpoint [必填]OSS服务的地址,可以是以 - # oss-cn-hangzhou.aliyuncs.com的标准域名,也可以是用户绑定的域名 - # @option opts [String] :access_key_id [可选]用户的ACCESS KEY ID, - # 如果不填则会尝试匿名访问 - # @option opts [String] :access_key_secret [可选]用户的ACCESS - # KEY SECRET,如果不填则会尝试匿名访问 - # @option opts [Boolean] :cname [可选] 指定endpoint是否是用户绑 - # 定的域名 - # @option opts [Boolean] :upload_crc_enable [可选]指定上传处理 - # 是否开启CRC校验,默认为开启(true) - # @option opts [Boolean] :download_crc_enable [可选]指定下载处理 - # 是否开启CRC校验,默认为不开启(false) - # @option opts [String] :sts_token [可选] 指定STS的 - # SecurityToken,如果指定,则使用STS授权访问 - # @option opts [Fixnum] :open_timeout [可选] 指定建立连接的超时 - # 时间,默认为10秒 - # @option opts [Fixnum] :read_timeout [可选] 指定等待响应的超时 - # 时间,默认为120秒 - # @example 标准endpoint + # creates OSS client for buckets operations. + # @param opts [Hash] options for creating the Client object + # @option opts [String] :endpoint [required] OSS endpoint. It could be standard endpoint such as + # oss-cn-hangzhou.aliyuncs.com or user domain binded with the bucket + # @option opts [String] :access_key_id [optional] user's ACCESS KEY ID, + # if not specified, then the request is anonymous. + # @option opts [String] :access_key_secret [optional] user's ACCESS + # KEY SECRET,if not specified, then the request is anonymous. + # @option opts [Boolean] :cname [optional] flag indicates if the endpoint is CNamed. + # @option opts [Boolean] :upload_crc_enable [optional] specifies if the upload enabled with CRC. Default is true. + # @option opts [Boolean] :download_crc_enable [optional] specifies if the download enabled with CRC. Default is false. + # @option opts [String] :sts_token [optional] specifies STS's SecurityToken. If it's specified, then use STS for authorization. + # @option opts [Fixnum] :open_timeout [optional] the connection timeout in seconds. By default it's 10s. + # @option opts [Fixnum] :read_timeout [optional] the response's timeout in seconds. By default it's 120s. + # @example standard endpoint # oss-cn-hangzhou.aliyuncs.com # oss-cn-beijing.aliyuncs.com - # @example 用户绑定的域名 + # @example cname binded endpoint # my-domain.com # foo.bar.com def initialize(opts) @@ -51,12 +45,11 @@ def initialize(opts) @protocol = Protocol.new(@config) end - # 列出当前所有的bucket - # @param opts [Hash] 查询选项 - # @option opts [String] :prefix 如果设置,则只返回以它为前缀的bucket - # @option opts [String] :marker 如果设置,则只返回名字在它之后 - # (字典序,不包含marker)的bucket - # @return [Enumerator] Bucket的迭代器 + # Lists all buckets of the account + # @param opts [Hash] options for the list + # @option opts [String] :prefix if it's specified, only buckets prefixed with it will be returned + # @option opts [String] :marker if it's specified, only buckets whose key is larger than :marker will be returned. + # @return [Enumerator] Bucket's iterator def list_buckets(opts = {}) if @config.cname fail ClientError, "Cannot list buckets for a CNAME endpoint." @@ -65,24 +58,24 @@ def list_buckets(opts = {}) Iterator::Buckets.new(@protocol, opts).to_enum end - # 创建一个bucket - # @param name [String] Bucket名字 - # @param opts [Hash] 创建Bucket的属性(可选) - # @option opts [:location] [String] 指定bucket所在的区域,默认为oss-cn-hangzhou + # Creates a bucket + # @param name [String] Bucket name + # @param opts [Hash] options for creating the bucket(optional) + # @option opts [:location] [String] the region for the new bucket. By default is oss-cn-hangzhou def create_bucket(name, opts = {}) @protocol.create_bucket(name, opts) end - # 删除一个bucket - # @param name [String] Bucket名字 - # @note 如果要删除的Bucket不为空(包含有object),则删除会失败 + # Deletes a bucket + # @param name [String] Bucket name + # @note If the bucket is not empty (has objects), then the deletion will fail. def delete_bucket(name) @protocol.delete_bucket(name) end - # 判断一个bucket是否存在 - # @param name [String] Bucket名字 - # @return [Boolean] 如果Bucket存在则返回true,否则返回false + # Checks if the bucket exists + # @param name [String] Bucket name + # @return [Boolean] If Bucket exists returns true; otherwise returns false. def bucket_exists?(name) exist = false @@ -98,9 +91,9 @@ def bucket_exists?(name) alias :bucket_exist? :bucket_exists? - # 获取一个Bucket对象,用于操作bucket中的objects。 - # @param name [String] Bucket名字 - # @return [Bucket] Bucket对象 + # Gets the bucket object for objects level operations + # @param name [String] Bucket name + # @return [Bucket] Bucket object def get_bucket(name) Bucket.new({:name => name}, @protocol) end diff --git a/lib/aliyun/oss/object.rb b/lib/aliyun/oss/object.rb index fe52ba0..e07c174 100644 --- a/lib/aliyun/oss/object.rb +++ b/lib/aliyun/oss/object.rb @@ -4,7 +4,7 @@ module Aliyun module OSS ## - # Object表示OSS存储的一个对象 + # Object represents an object in OSS # class Object < Common::Struct::Base diff --git a/lib/aliyun/sts/client.rb b/lib/aliyun/sts/client.rb index f263e94..7192331 100644 --- a/lib/aliyun/sts/client.rb +++ b/lib/aliyun/sts/client.rb @@ -3,8 +3,8 @@ module Aliyun module STS - # STS服务的客户端,用于向STS申请临时token。 - # @example 创建Client + # The client for STS service, for requesting temporary token. + # @example creates Client # client = Client.new( # :access_key_id => 'access_key_id', # :access_key_secret => 'access_key_secret') diff --git a/rails/aliyun_oss_callback_server.rb b/rails/aliyun_oss_callback_server.rb index e134fab..e8736ca 100644 --- a/rails/aliyun_oss_callback_server.rb +++ b/rails/aliyun_oss_callback_server.rb @@ -7,8 +7,8 @@ require 'openssl' require 'json' -# 接受OSS上传回调的server示例,利用RSA公钥验证请求来自OSS,而非其 -# 他恶意请求。具体签名/验证过程请参考: +# Examples of callback server for OSS callback calls. It checks the request signature by using the public key of OSS. +# Checks out the following link for exact process of signing/verification: # https://help.aliyun.com/document_detail/oss/api-reference/object/Callback.html def get_header(name) diff --git a/spec/aliyun/oss/service_spec.rb b/spec/aliyun/oss/service_spec.rb index ce2c557..4302dcc 100644 --- a/spec/aliyun/oss/service_spec.rb +++ b/spec/aliyun/oss/service_spec.rb @@ -24,7 +24,7 @@ module OSS end end - # 生成list_buckets返回的响应,包含bucket列表和more信息 + # Generates the response of list_buckets, which contains the bucket list and more information. def mock_response(buckets, more) builder = Nokogiri::XML::Builder.new do |xml| xml.ListAllMyBucketsResult { @@ -56,7 +56,7 @@ def mock_response(buckets, more) end context "List all buckets" do - # 测试list_buckets正确地发送了HTTP请求 + # tests list_buckets send HTTP request correctly it "should send correct request" do stub_request(:get, @endpoint) @@ -66,7 +66,7 @@ def mock_response(buckets, more) with(:body => nil, :query => {}) end - # 测试list_buckets正确地解析了list_buckets的返回 + # tests list_buckets parse the response correctly. it "should correctly parse response" do stub_request(:get, @endpoint).to_return( {:body => mock_response(@all_buckets, {})}) @@ -82,7 +82,7 @@ def mock_response(buckets, more) end context "Paging buckets" do - # 测试list_buckets的请求中包含prefix/marker/maxkeys等信息 + # tests list_buckets request has the information like prefix/marker/maskeys it "should set prefix/max-keys param" do prefix = 'rubysdk-bucket-00' marker = 'rubysdk-bucket-002' @@ -101,7 +101,7 @@ def mock_response(buckets, more) 'max-keys' => limit}) end - # 测试list_buckets正确地解析了HTTP响应,包含more信息 + # test list_buckets parse the response correctly, which has the more information. it "should parse next marker" do prefix = 'rubysdk-bucket-00' marker = 'rubysdk-bucket-002' diff --git a/spec/aliyun/oss/util_spec.rb b/spec/aliyun/oss/util_spec.rb index d27b498..514a045 100644 --- a/spec/aliyun/oss/util_spec.rb +++ b/spec/aliyun/oss/util_spec.rb @@ -6,7 +6,7 @@ module Aliyun module OSS describe Util do - # 测试对body content的md5编码是否正确 + # test if the MD5 of the body content is correct. it "should get correct content md5" do content = "" @@ -18,7 +18,7 @@ module OSS expect(md5).to eq("XrY7u+Ae7tCTyyK7j1rNww==") end - # 测试签名是否正确 + # test if the signature is correct. it "should get correct signature" do key = 'helloworld' date = 'Fri, 30 Oct 2015 07:21:00 GMT' @@ -44,7 +44,7 @@ module OSS expect(signature).to eq("7Oh2wobzeg6dw/cWYbF/2m6s6qc=") end - # 测试CRC计算是否正确 + # test if the CRC calculation is correct. it "should calculate a correct data crc" do content = "" crc = Util.crc(content) @@ -59,7 +59,7 @@ module OSS expect(crc).to eq(6745424696046691431) end - # 测试CRC Combine计算是否正确 + # Test CRC combine calculation is correct or not. it "should calculate a correct crc that crc_a combine with crc_b" do content_a = "test\0hello\1world\2!\3" crc_a = Util.crc(content_a) @@ -79,7 +79,7 @@ module OSS expect(crc_ab).to eq(crc_c) end - # 测试CRC校验和异常处理是否正确 + # test CRC checksum and exception handler is correct or not. it "should check inconsistent crc" do expect { Util.crc_check(6745424696046691431, 6745424696046691431, 'put')