qcloud_cos 0.3.0 → 0.4.0.pre
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/.gitignore +2 -0
- data/README.md +2 -2
- data/bin/console +6 -6
- data/bin/qcloud-cos +120 -0
- data/lib/qcloud_cos.rb +15 -5
- data/lib/qcloud_cos/api.rb +11 -9
- data/lib/qcloud_cos/cli.rb +345 -0
- data/lib/qcloud_cos/configuration.rb +5 -0
- data/lib/qcloud_cos/convenient_api.rb +2 -1
- data/lib/qcloud_cos/error.rb +6 -0
- data/lib/qcloud_cos/version.rb +1 -1
- data/qcloud_cos.gemspec +4 -2
- data/wiki/get_started.md +387 -62
- metadata +37 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75ee730d319d95b7fca2482722203b7e326c03a0
|
4
|
+
data.tar.gz: 7d3f04b960205007488d35688c8cf40146c1e3e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3103a965be5176a4a7cb0346b748e6642d2b35dbb3b6aa9d7fb69be1ece65c4ee9e5b5e0bb222260931afd7a043d8ee06d5e11205a232c14b42f56ed9280c988
|
7
|
+
data.tar.gz: 3f00b1d37848247ac3a12fe521a131c39f4f37612c9600aaf1c8212d0cffcfef7807aa86252addbac7144e71f9c6c817f0be598ef99572a580c92e6d6e017676
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -49,12 +49,12 @@ More Example and Scenario, visit our [Document](#document)
|
|
49
49
|
|
50
50
|
Here is original Restful API, It has the most detailed and authoritative explanation for every API.
|
51
51
|
|
52
|
-
+ [COS RESTful API文档](http://www.qcloud.com/wiki/RESTful_API%E6%96%87%E6%A1%A3)
|
52
|
+
+ [COS RESTful API文档](http://www.qcloud.com/wiki/RESTful_API%E6%96%87%E6%A1%A3)
|
53
53
|
+ [COS 详细文档](http://www.qcloud.com/doc/product/227/%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D)
|
54
54
|
|
55
55
|
Here is our RDoc Document, It's well format to help you find more detail about methods.
|
56
56
|
|
57
|
-
+ [RDoc Document](http://www.rubydoc.info/gems/qcloud_cos/0.
|
57
|
+
+ [RDoc Document](http://www.rubydoc.info/gems/qcloud_cos/0.3.0)
|
58
58
|
|
59
59
|
|
60
60
|
Here are some more guides for help you. Welcome to advice.
|
data/bin/console
CHANGED
@@ -11,12 +11,12 @@ require 'qcloud_cos'
|
|
11
11
|
# Pry.start
|
12
12
|
|
13
13
|
QcloudCos.configure do |config|
|
14
|
-
config.app_id = ENV['
|
15
|
-
config.secret_id = ENV['
|
16
|
-
config.secret_key = ENV['
|
17
|
-
config.endpoint = ENV['
|
18
|
-
config.bucket = ENV['
|
19
|
-
config.ssl_ca_file = ENV['
|
14
|
+
config.app_id = ENV['QCLOUD_COS_APP_ID'] || 'app-id'
|
15
|
+
config.secret_id = ENV['QCLOUD_COS_SECRET_ID'] || 'secret_id'
|
16
|
+
config.secret_key = ENV['QCLOUD_COS_SECRET_KEY'] || 'secret_key'
|
17
|
+
config.endpoint = ENV['QCLOUD_COS_ENDPOINT'] || 'http://web.file.myqcloud.com/files/v1/'
|
18
|
+
config.bucket = ENV['QCLOUD_COS_BUCKET'] || 'privatesdkdemo'
|
19
|
+
config.ssl_ca_file = ENV['QCLOUD_COS_SSL_CA_FILE'] || 'path/to/ssl/ca/file'
|
20
20
|
end
|
21
21
|
|
22
22
|
require 'irb'
|
data/bin/qcloud-cos
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'commander/import'
|
4
|
+
require 'qcloud_cos/cli'
|
5
|
+
require 'awesome_print'
|
6
|
+
|
7
|
+
program :name, 'qcloud-cos'
|
8
|
+
program :version, QcloudCos::VERSION
|
9
|
+
program :description, 'command-line tool for Qcloud COS'
|
10
|
+
program :help, 'Author', 'Newell Zhu<zlx.star@gmail.com>'
|
11
|
+
default_command :help
|
12
|
+
|
13
|
+
command :config do |c|
|
14
|
+
c.syntax = 'qcloud-cos config'
|
15
|
+
c.description = 'Init config, eg: qcloud-cos config'
|
16
|
+
c.action do |args, options|
|
17
|
+
QcloudCos::Cli.config
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
command :info do |c|
|
22
|
+
c.syntax = 'qcloud-cos info [options] [dest_path]'
|
23
|
+
c.description = 'Obtain information'
|
24
|
+
c.example 'Obtain bucket information', '$ qcloud-cos info'
|
25
|
+
c.example 'Obtain information for /test/', '$ qcloud-cos info /test/'
|
26
|
+
c.example 'Obtain information for /production.log', '$ qcloud-cos info /production.log'
|
27
|
+
c.example 'Obtain information for /production.log from bucket2', '$ qcloud-cos info --bucket bucket2 /production.log'
|
28
|
+
c.option '--bucket Bucket Name', String, 'specify bucket name, it will override default bucket'
|
29
|
+
c.action do |args, options|
|
30
|
+
abort unless QcloudCos::Cli.environment_configed?
|
31
|
+
begin
|
32
|
+
cli = QcloudCos::Cli.init
|
33
|
+
ap cli.info(args, options), indent: -2
|
34
|
+
rescue => e
|
35
|
+
say_error e.message
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
command :list do |c|
|
41
|
+
c.syntax = 'qcloud-cos list [options] [dest_path]'
|
42
|
+
c.description = 'List objects under [dest_path]'
|
43
|
+
c.example 'List all objects under /', '$ qcloud-cos list'
|
44
|
+
c.example 'List all objects under /test/', '$ qcloud-cos list /test/'
|
45
|
+
c.example 'List first 10 objects under /test/', '$ qcloud-cos list --num 10 /test/'
|
46
|
+
c.example 'List all objects under / for bucket: bucket2', '$ qcloud-cos list --num 10 --bucket bucket2 /test/'
|
47
|
+
c.option '--bucket Bucket Name', String, 'specify bucket name, it will override default bucket'
|
48
|
+
c.option '--num Num', Integer, 'specify max objects, default is 100'
|
49
|
+
c.action do |args, options|
|
50
|
+
abort unless QcloudCos::Cli.environment_configed?
|
51
|
+
begin
|
52
|
+
cli = QcloudCos::Cli.init
|
53
|
+
cli.list(args, options).map{|path| puts path }
|
54
|
+
rescue => e
|
55
|
+
say_error e.message
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
command :upload do |c|
|
61
|
+
c.syntax = 'qcloud-cos upload [options] file [dest_path]'
|
62
|
+
c.description = 'Upload file or folder to COS'
|
63
|
+
c.example 'Upload production.log to /', '$ qcloud-cos upload production.log'
|
64
|
+
c.example 'Upload production.log to /data/', '$ qcloud-cos upload production.log /data/'
|
65
|
+
c.example 'Upload all files under ./test/ to /data/', '$ qcloud-cos upload test/ /data/'
|
66
|
+
c.example 'Upload all files under ./test/ to /data/ with other bucket: bucket2', '$ qcloud-cos upload --bucket bucket2 test/ /data/'
|
67
|
+
c.example 'Upload production.log to /data/ with slice_size and min', '$ qcloud-cos upload --size 10 --min 100 production.log /data/'
|
68
|
+
c.option '--bucket Bucket Name', String, 'specify bucket name, it will override default bucket'
|
69
|
+
c.option '--size Slice Size', Integer, "specify slice size for slice upload in Bytes, default: #{QcloudCos::DEFAULT_SLICE_SIZE}(#{QcloudCos::DEFAULT_SLICE_SIZE/1024/1024}M)"
|
70
|
+
c.option '--min Min Slice File Size', Integer, "specify min slice file size in Bytes, default: default: #{QcloudCos::MIN_SLICE_FILE_SIZE * 1024 * 1024}(#{QcloudCos::MIN_SLICE_FILE_SIZE}M)"
|
71
|
+
c.action do |args, options|
|
72
|
+
abort unless QcloudCos::Cli.environment_configed?
|
73
|
+
begin
|
74
|
+
cli = QcloudCos::Cli.init
|
75
|
+
cli.upload(args, options)
|
76
|
+
rescue => e
|
77
|
+
Commander::UI.say_error e.message
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
command :download do |c|
|
83
|
+
c.syntax = 'qcloud-cos download [options] dest_path [save_path]'
|
84
|
+
c.description = 'Download objects from COS'
|
85
|
+
c.example 'Download file from /data/production.log and save current path', '$ qcloud-cos download /data/production.log'
|
86
|
+
c.example 'Download file from /data/production.log and save under ./data/', '$ qcloud-cos download /data/production.log ./data'
|
87
|
+
c.example 'Download whole folder /data/test/ and save under ./data/', '$ qcloud-cos download /data/test/ ./data'
|
88
|
+
c.example 'Download whole folder /data/test/ from bucket2 and save under ./data/', '$ qcloud-cos download --bucket bucket2 /data/test/ ./data'
|
89
|
+
c.option '--bucket Bucket Name', String, 'specify bucket name, it will override default bucket'
|
90
|
+
c.action do |args, options|
|
91
|
+
abort unless QcloudCos::Cli.environment_configed?
|
92
|
+
begin
|
93
|
+
cli = QcloudCos::Cli.init
|
94
|
+
cli.download(args, options)
|
95
|
+
rescue => e
|
96
|
+
Commander::UI.say_error e.message
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
command :remove do |c|
|
102
|
+
c.syntax = 'qcloud-cos remove [options] dest_path'
|
103
|
+
c.description = 'Remove objects from COS'
|
104
|
+
c.example 'Remove file /data/production.log', '$ qcloud-cos remove /data/production.log'
|
105
|
+
c.example 'Remove folder /data/test/', '$ qcloud-cos remove /data/test/'
|
106
|
+
c.example 'Remove folder /data/test/ in recursive', '$ qcloud-cos remove --recursive /data/test/'
|
107
|
+
c.example 'Remove folder /data/test/ from bucket2', '$ qcloud-cos download --bucket bucket2 /data/test/'
|
108
|
+
c.option '--bucket Bucket Name', String, 'specify bucket name, it will override default bucket'
|
109
|
+
c.option '--[no-]recursive', 'specify recursive or not when remove folder'
|
110
|
+
c.action do |args, options|
|
111
|
+
abort unless QcloudCos::Cli.environment_configed?
|
112
|
+
begin
|
113
|
+
cli = QcloudCos::Cli.init
|
114
|
+
cli.remove(args, options)
|
115
|
+
Commander::UI.say_ok 'OK'
|
116
|
+
rescue => e
|
117
|
+
Commander::UI.say_error e.message
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
data/lib/qcloud_cos.rb
CHANGED
@@ -11,6 +11,8 @@ module QcloudCos
|
|
11
11
|
DEFAULT_SLICE_SIZE = 3_145_728 # 3M
|
12
12
|
MIN_SLICE_FILE_SIZE = 10 # 10M
|
13
13
|
MAX_RETRY_TIMES = 3
|
14
|
+
QCLOUD_COS_CONFIG = '.qcloud-cos.yml'
|
15
|
+
DEFAULT_ENDPOINT = 'http://web.file.myqcloud.com/files/v1/'
|
14
16
|
|
15
17
|
class << self
|
16
18
|
include Api
|
@@ -38,12 +40,10 @@ module QcloudCos
|
|
38
40
|
|
39
41
|
def validates(path, options, path_validate = :file_only)
|
40
42
|
Utils.stringify_keys!(options)
|
41
|
-
file_validates(path, path_validate)
|
42
|
-
|
43
|
-
bucket = options['bucket'] || config.bucket
|
44
|
-
fail MissingBucketError unless bucket
|
45
43
|
|
46
|
-
|
44
|
+
file_validates(path, path_validate)
|
45
|
+
num_validates(options['num'].to_i) if options['num']
|
46
|
+
bucket_validates(options['bucket'])
|
47
47
|
end
|
48
48
|
|
49
49
|
def fixed_path(path)
|
@@ -62,5 +62,15 @@ module QcloudCos
|
|
62
62
|
FolderObject.validate(path)
|
63
63
|
end
|
64
64
|
end
|
65
|
+
|
66
|
+
def num_validates(number)
|
67
|
+
fail InvalidNumError if (number > 199 || number < 1)
|
68
|
+
end
|
69
|
+
|
70
|
+
def bucket_validates(bucket_name)
|
71
|
+
bucket = bucket_name || config.bucket
|
72
|
+
fail MissingBucketError unless bucket
|
73
|
+
bucket
|
74
|
+
end
|
65
75
|
end
|
66
76
|
end
|
data/lib/qcloud_cos/api.rb
CHANGED
@@ -9,7 +9,7 @@ module QcloudCos
|
|
9
9
|
# @param path [String] 指定目标路径, 以 / 结尾, 则列出该目录下文件或者文件夹,不以 / 结尾,就搜索该前缀的文件或者文件夹
|
10
10
|
# @param options [Hash] 额外参数
|
11
11
|
# @option options [String] :bucket (config.bucket_name) 指定当前 bucket, 默认是配置里面的 bucket
|
12
|
-
# @option options [Integer] :num (100)
|
12
|
+
# @option options [Integer] :num (100) 指定需要拉取的条目, 可选范围: 1~199
|
13
13
|
# @option options [String] :pattern (eListBoth) 指定拉取的内容,可选值: eListBoth, eListDirOnly, eListFileOnly
|
14
14
|
# @option options [Integer] :order (0) 指定拉取文件的顺序, 默认为正序(=0), 可选值: 0, 1
|
15
15
|
# @option options [String] :context ("") 透传字段,查看第一页,则传空字符串。若需要翻页,需要将前一页返回值中的context透传到参数中。order用于指定翻页顺序。若order填0,则从当前页正序/往下翻页;若order填1,则从当前页倒序/往上翻页。
|
@@ -110,8 +110,15 @@ module QcloudCos
|
|
110
110
|
|
111
111
|
# 分片上传
|
112
112
|
#
|
113
|
+
# @example
|
114
|
+
#
|
115
|
+
# upload_slice('/data/test.log', 'test.log') do |pr|
|
116
|
+
# puts "uploaded #{pr * 100}%"
|
117
|
+
# end
|
118
|
+
#
|
113
119
|
# @param dst_path [String] 指定文件的目标路径
|
114
120
|
# @param src_path [String] 指定文件的本地路径
|
121
|
+
# @param block [Block] 指定 Block 来显示进度提示
|
115
122
|
# @param options [Hash] options
|
116
123
|
# @option options [String] :bucket (config.bucket_name) 指定当前 bucket, 默认是配置里面的 bucket
|
117
124
|
# @option options [Integer] :biz_attr 指定文件的 biz_attr 由业务端维护, 会在文件信息中返回
|
@@ -123,7 +130,7 @@ module QcloudCos
|
|
123
130
|
# @raise [InvalidFilePathError] 如果目标路径是非法文件路径
|
124
131
|
#
|
125
132
|
# @return [Hash]
|
126
|
-
def upload_slice(dst_path, src_path, options = {})
|
133
|
+
def upload_slice(dst_path, src_path, options = {}, &block)
|
127
134
|
dst_path = fixed_path(dst_path)
|
128
135
|
fail FileNotExistError unless File.exist?(src_path)
|
129
136
|
bucket = validates(dst_path, options)
|
@@ -133,7 +140,6 @@ module QcloudCos
|
|
133
140
|
sign = authorization.sign(bucket)
|
134
141
|
|
135
142
|
resp = init_slice_upload(dst_path, filesize, sha, options.merge('sign' => sign))
|
136
|
-
puts "init slice upload: #{resp}"
|
137
143
|
|
138
144
|
data = resp['data']
|
139
145
|
return data if data.key?('url') # 妙传命中
|
@@ -150,7 +156,8 @@ module QcloudCos
|
|
150
156
|
retry_times = 0
|
151
157
|
begin
|
152
158
|
result = upload_part(dst_path, session, offset, filecontent, options)
|
153
|
-
|
159
|
+
progress = [offset + slice_size, filesize].min
|
160
|
+
yield((progress.to_f/filesize).round(2)) if block_given?
|
154
161
|
|
155
162
|
if result.key?('data') && result['data'].key?('session')
|
156
163
|
session = result['data']['session']
|
@@ -159,7 +166,6 @@ module QcloudCos
|
|
159
166
|
end
|
160
167
|
rescue => e
|
161
168
|
retry_times += 1
|
162
|
-
puts "retry part upload request with offset:#{offset}, slice_size:#{slice_size} ..."
|
163
169
|
retry if retry_times <= config.max_retry_times
|
164
170
|
raise e
|
165
171
|
end
|
@@ -168,7 +174,6 @@ module QcloudCos
|
|
168
174
|
end
|
169
175
|
|
170
176
|
# 初始化分片上传
|
171
|
-
# @private
|
172
177
|
#
|
173
178
|
# @param path [String] 指定上传文件的路径
|
174
179
|
# @param filesize [Integer] 指定文件总大小
|
@@ -190,10 +195,8 @@ module QcloudCos
|
|
190
195
|
|
191
196
|
http.post(url, query: query, headers: { 'Authorization' => sign }).parsed_response
|
192
197
|
end
|
193
|
-
private :init_slice_upload
|
194
198
|
|
195
199
|
# 上传分片数据
|
196
|
-
# @private
|
197
200
|
#
|
198
201
|
# @param path [String] 指定上传文件的路径
|
199
202
|
# @param session [String] 指定分片上传的 session id
|
@@ -213,7 +216,6 @@ module QcloudCos
|
|
213
216
|
|
214
217
|
http.post(url, query: query, headers: { 'Authorization' => sign }).parsed_response
|
215
218
|
end
|
216
|
-
private :upload_part
|
217
219
|
|
218
220
|
# 更新文件或者目录信息
|
219
221
|
#
|
@@ -0,0 +1,345 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'rubygems'
|
3
|
+
require 'commander'
|
4
|
+
require 'awesome_print'
|
5
|
+
require 'qcloud_cos'
|
6
|
+
|
7
|
+
module QcloudCos
|
8
|
+
class Cli
|
9
|
+
include Commander::Methods
|
10
|
+
|
11
|
+
QCLOUD_COS_ENV_MAPPING = {
|
12
|
+
app_id: 'QCLOUD_COS_APP_ID',
|
13
|
+
secret_id: 'QCLOUD_COS_SECRET_ID',
|
14
|
+
secret_key: 'QCLOUD_COS_SECRET_KEY',
|
15
|
+
endpoint: 'QCLOUD_COS_ENDPOINT',
|
16
|
+
bucket: 'QCLOUD_COS_BUCKET',
|
17
|
+
ssl_ca_file: 'QCLOUD_COS_SSL_CA_FILE',
|
18
|
+
max_retry_times: 'QCLOUD_COS_MAX_RETRY_TIMES'
|
19
|
+
}
|
20
|
+
|
21
|
+
# 交互模式配置环境
|
22
|
+
# 命令: $ qcloud-cos config
|
23
|
+
def self.config(config_path = nil)
|
24
|
+
config_path = config_path || QcloudCos::QCLOUD_COS_CONFIG
|
25
|
+
return Commander::UI.say_error("#{config_path} already exist, remove it first or direct edit it!") if File.exist?(config_path)
|
26
|
+
|
27
|
+
app_id = Commander::UI.ask 'Qcloud COS APP ID: '
|
28
|
+
return Commander::UI.say_error("Missing Qcloud COS APP ID") if app_id.empty?
|
29
|
+
|
30
|
+
secret_id = Commander::UI.ask 'Qcloud COS Secret ID: '
|
31
|
+
return Commander::UI.say_error("Missing Qcloud COS Secret ID") if secret_id.empty?
|
32
|
+
|
33
|
+
secret_key = Commander::UI.ask 'Qcloud COS Secret Key: '
|
34
|
+
return Commander::UI.say_error("Missing Qcloud COS Secret Key") if secret_key.empty?
|
35
|
+
|
36
|
+
endpoint = Commander::UI.ask "Default Qcloud COS Endpoint [#{QcloudCos::DEFAULT_ENDPOINT}]: "
|
37
|
+
endpoint = QcloudCos::DEFAULT_ENDPOINT if endpoint.empty?
|
38
|
+
bucket = Commander::UI.ask 'Default Qcloud COS Bucket: '
|
39
|
+
|
40
|
+
write_config(
|
41
|
+
config_path,
|
42
|
+
app_id: app_id,
|
43
|
+
secret_id: secret_id,
|
44
|
+
secret_key: secret_key,
|
45
|
+
endpoint: endpoint,
|
46
|
+
bucket: bucket
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
# 检查环境是否配置
|
51
|
+
#
|
52
|
+
# @return [Boolean]
|
53
|
+
def self.environment_configed?
|
54
|
+
configed = File.exist?(QcloudCos::QCLOUD_COS_CONFIG) || !ENV['QCLOUD_COS_APP_ID'].to_s.empty?
|
55
|
+
Commander::UI.say_error("Use `qcloud-cos config` first or export your environments") unless configed
|
56
|
+
configed
|
57
|
+
end
|
58
|
+
|
59
|
+
# 检查环境,初始化 Cli
|
60
|
+
def self.init
|
61
|
+
QcloudCos.configure do |config|
|
62
|
+
load_config.each { |k, v| config.send("#{k}=", v) }
|
63
|
+
end
|
64
|
+
|
65
|
+
self.new
|
66
|
+
end
|
67
|
+
|
68
|
+
# 查看信息
|
69
|
+
# 命令: $ qcloud-cos info [options] [dest_path]
|
70
|
+
#
|
71
|
+
# @example
|
72
|
+
# # 查看 Bucket 信息
|
73
|
+
# qcloud-cos info
|
74
|
+
#
|
75
|
+
# # 查看 /production.log 信息
|
76
|
+
# qcloud-cos info /production.log
|
77
|
+
#
|
78
|
+
# # 查看 /test/ 信息
|
79
|
+
# qcloud-cos info /test/
|
80
|
+
#
|
81
|
+
# # 查看 bucket2 上的 /production.log 信息
|
82
|
+
# qcloud-cos info --bucket bucket2 /production.log
|
83
|
+
def info(args, options)
|
84
|
+
path = args.shift || '/'
|
85
|
+
opts = parse(options)
|
86
|
+
|
87
|
+
QcloudCos.stat(path, opts)['data']
|
88
|
+
end
|
89
|
+
|
90
|
+
# 列出文件或者文件夹
|
91
|
+
# 使用: $ qcloud-cos list [options] [dest_path]
|
92
|
+
#
|
93
|
+
# @example
|
94
|
+
#
|
95
|
+
# # 列出 / 下面的所有对象
|
96
|
+
# qcloud-cos list
|
97
|
+
#
|
98
|
+
# # 列出 /test/ 下面的所有对象
|
99
|
+
# qcloud-cos list /test/
|
100
|
+
#
|
101
|
+
# # 列出 /test/ 下面的前 10 个对象
|
102
|
+
# qcloud-cos list --num 10 /test/
|
103
|
+
#
|
104
|
+
# # 列出 bucket2 的 /test/ 下面的所有对象
|
105
|
+
# qcloud-cos list --bucket bucket2 /test/
|
106
|
+
#
|
107
|
+
def list(args, options)
|
108
|
+
path = args.shift || '/'
|
109
|
+
opts = parse(options)
|
110
|
+
opts[:num] = options.num || 100
|
111
|
+
|
112
|
+
objects = QcloudCos.list(path, opts)
|
113
|
+
objects.map do |object|
|
114
|
+
File.join(path, object.is_a?(QcloudCos::FolderObject) ? "#{object.name}/" : object.name)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# 上传文件或者目录到 COS
|
119
|
+
# 命令: qcloud-cos upload [options] file [dest_path]
|
120
|
+
#
|
121
|
+
# @example
|
122
|
+
#
|
123
|
+
# # 把 production.log 上传到 /
|
124
|
+
# qcloud-cos upload production.log
|
125
|
+
#
|
126
|
+
# # 把 production.log 上传到 /data/ 下面
|
127
|
+
# qcloud-cos upload production.log /data/
|
128
|
+
#
|
129
|
+
# # 把 ./test/ 整个文件夹上传到 /data/ 下面
|
130
|
+
# qcloud-cos upload test/ /data/
|
131
|
+
#
|
132
|
+
# # 把 ./test/ 整个文件夹上传到 bucket2 的 /data/ 下面
|
133
|
+
# qcloud-cos upload --bucket bucket2 test/ /data/
|
134
|
+
def upload(args, options)
|
135
|
+
path = args.shift
|
136
|
+
return Commander::UI.say_error("file missing, see example: $ qcloud-cos upload -h") unless path
|
137
|
+
return Commander::UI.say_error("file #{path} not exist") unless File.exist?(path)
|
138
|
+
|
139
|
+
dest_path = args.shift || '/'
|
140
|
+
return Commander::UI.say_error("dest_path must end with /, see example: $ qcloud-cos upload -h") unless dest_path.end_with?('/')
|
141
|
+
|
142
|
+
opts = parse(options)
|
143
|
+
opts[:slice_size] = options.size || QcloudCos::DEFAULT_SLICE_SIZE
|
144
|
+
opts[:min] = options.min || QcloudCos::MIN_SLICE_FILE_SIZE * 1024 * 1024
|
145
|
+
|
146
|
+
if path.end_with?('/')
|
147
|
+
upload_folder(path, dest_path, opts)
|
148
|
+
else
|
149
|
+
upload_file(path, dest_path, opts)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# 下载文件或者目录
|
154
|
+
# 命令: $ qcloud-cos download [options] dest_path [save_path]
|
155
|
+
#
|
156
|
+
# @example
|
157
|
+
#
|
158
|
+
# # 把 /data/production.log 下载到当前目录
|
159
|
+
# qcloud-cos download /data/production.log
|
160
|
+
#
|
161
|
+
# # 把 /data/production.log 下载到 ./data/ 下
|
162
|
+
# qcloud-cos download /data/production.log ./data
|
163
|
+
#
|
164
|
+
# # 把 /data/test/ 整个目录下载并保存到 ./data/ 目录下面
|
165
|
+
# qcloud-cos download /data/test/ ./data
|
166
|
+
#
|
167
|
+
# # 把 bucket2 下的 /data/test/ 整个目录下载并保存到 ./data/ 下面
|
168
|
+
# qcloud-cos download --bucket bucket2 /data/test/ ./data
|
169
|
+
#
|
170
|
+
def download(args, options)
|
171
|
+
path = args.shift
|
172
|
+
return Commander::UI.say_error("missing path, see example: $ qcloud-cos download -h") unless path
|
173
|
+
opts = parse(options)
|
174
|
+
opts[:save_path] = args.shift || '.'
|
175
|
+
|
176
|
+
if path.end_with?('/')
|
177
|
+
download_folder(path, opts)
|
178
|
+
else
|
179
|
+
download_file(path, opts)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
# 删除目录或者文件夹
|
184
|
+
# 命令: $ qcloud-cos remove [options] dest_path
|
185
|
+
#
|
186
|
+
# @example
|
187
|
+
#
|
188
|
+
# # 删除文件/data/production.log
|
189
|
+
# qcloud-cos remove /data/production.log
|
190
|
+
#
|
191
|
+
# # 删除目录 /data/test/, 目录非空会失败
|
192
|
+
# qcloud-cos remove /data/test/
|
193
|
+
#
|
194
|
+
# # 级联删除目录 /data/test/
|
195
|
+
# qcloud-cos remove --recursive /data/test/
|
196
|
+
#
|
197
|
+
# # 删除 bucket2 下面的目录 /data/test/
|
198
|
+
# qcloud-cos download --bucket bucket2 /data/test/
|
199
|
+
def remove(args, options)
|
200
|
+
path = args.shift
|
201
|
+
return Commander::UI.say_error("missing dest_path, see example: $ qcloud-cos remove -h") unless path
|
202
|
+
|
203
|
+
opts = parse(options)
|
204
|
+
|
205
|
+
if path.end_with?('/')
|
206
|
+
QcloudCos.delete_folder(path, opts.merge(recursive: !!options.recursive))
|
207
|
+
else
|
208
|
+
QcloudCos.delete_file(path, opts)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
private
|
213
|
+
|
214
|
+
def upload_file(path, dest_path, opts)
|
215
|
+
dest_path = File.join(dest_path, path.split('/').last)
|
216
|
+
file = File.new(path)
|
217
|
+
if file.size > opts[:min]
|
218
|
+
QcloudCos.upload_slice(dest_path, path, Utils.hash_slice(opts, :bucket).merge(slice_size: opts[:slice_size]))
|
219
|
+
else
|
220
|
+
QcloudCos.upload(dest_path, file, Utils.hash_slice(opts, :bucket))
|
221
|
+
end
|
222
|
+
Commander::UI.say_ok "#{path} uploaded to #{dest_path}..."
|
223
|
+
rescue => e
|
224
|
+
Commander::UI.say_error "Failed when uploaded #{path} ===> #{e.message}"
|
225
|
+
ensure
|
226
|
+
file && file.close
|
227
|
+
end
|
228
|
+
|
229
|
+
def upload_folder(path, dest_path, opts)
|
230
|
+
file_path_map = {}
|
231
|
+
Dir.glob("#{path}**/*") do |file_path|
|
232
|
+
split_path = file_path.sub(path, '').split('/')
|
233
|
+
new_path =
|
234
|
+
if File.file?(file_path)
|
235
|
+
split_path.size > 1 ? File.join(dest_path, *split_path[0..-2]) : dest_path
|
236
|
+
else
|
237
|
+
file_path = File.join(file_path, '')
|
238
|
+
File.join(dest_path, *split_path, '')
|
239
|
+
end
|
240
|
+
|
241
|
+
file_path_map[file_path] = new_path
|
242
|
+
end
|
243
|
+
remove_subdirectories(file_path_map)
|
244
|
+
|
245
|
+
file_path_map.each do |file_path, dest_path|
|
246
|
+
if file_path.end_with?('/')
|
247
|
+
QcloudCos.create_folder(dest_path, opts)
|
248
|
+
Commander::UI.say_ok "Create folder #{dest_path}"
|
249
|
+
else
|
250
|
+
upload_file(file_path, dest_path, opts)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def download_file(path, opts)
|
256
|
+
save_path = opts.delete(:save_path)
|
257
|
+
FileUtils.mkdir_p(save_path) unless File.exist?(save_path)
|
258
|
+
|
259
|
+
file_path = File.join(save_path, path.split('/').last)
|
260
|
+
signed_access_url = opts[:access_url] ? opts.delete(:access_url) : QcloudCos.public_url(path, opts)
|
261
|
+
save_to_file(signed_access_url, file_path)
|
262
|
+
Commander::UI.say_ok("Save #{path} to #{file_path}")
|
263
|
+
rescue => e
|
264
|
+
Commander::UI.say_error("Failed when Download #{path} ===> #{e.message}")
|
265
|
+
end
|
266
|
+
|
267
|
+
def download_folder(path, opts)
|
268
|
+
save_path = opts.delete(:save_path)
|
269
|
+
loop do
|
270
|
+
objects = QcloudCos.list(path, opts)
|
271
|
+
objects.each do |object|
|
272
|
+
if object.is_a?(QcloudCos::FolderObject)
|
273
|
+
new_path = File.join(save_path, object.name)
|
274
|
+
unless File.exist?(new_path)
|
275
|
+
FileUtils.mkdir_p(new_path) unless File.exist?(new_path)
|
276
|
+
Commander::UI.say_ok "Save #{path}#{object.name}/ to #{new_path}/"
|
277
|
+
end
|
278
|
+
download_folder("#{path}#{object.name}/", opts.merge(save_path: new_path))
|
279
|
+
elsif object.is_a?(QcloudCos::FileObject)
|
280
|
+
if object.access_url
|
281
|
+
download_file("#{path}#{object.name}", opts.merge(save_path: save_path, access_url: object.access_url))
|
282
|
+
else
|
283
|
+
download_file("#{path}#{object.name}", opts.merge(save_path: save_path))
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
break unless objects.has_more
|
288
|
+
opts['context'] = objects.context
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
def self.load_config
|
293
|
+
file_config = load_file_config
|
294
|
+
|
295
|
+
config = {}
|
296
|
+
QCLOUD_COS_ENV_MAPPING.each do |key, env_name|
|
297
|
+
config[key] = ENV[env_name] || file_config[key.to_s]
|
298
|
+
end
|
299
|
+
config
|
300
|
+
end
|
301
|
+
|
302
|
+
def self.load_file_config
|
303
|
+
return {} unless File.exist?(QcloudCos::QCLOUD_COS_CONFIG)
|
304
|
+
|
305
|
+
Hash[File.open(QcloudCos::QCLOUD_COS_CONFIG).map do |line|
|
306
|
+
key, value = line.split('=')
|
307
|
+
value.chomp!.empty? ? nil : [key, value]
|
308
|
+
end.compact]
|
309
|
+
end
|
310
|
+
|
311
|
+
def parse(options)
|
312
|
+
opts = {}
|
313
|
+
opts[:bucket] = options.bucket if options.bucket
|
314
|
+
opts
|
315
|
+
end
|
316
|
+
|
317
|
+
def remove_subdirectories(path_map)
|
318
|
+
new_map = path_map.dup
|
319
|
+
new_map.each do |_, dest_path|
|
320
|
+
path_map.reject! do |file_path, dest|
|
321
|
+
file_path.end_with?('/') && dest_path.start_with?(dest)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
def save_to_file(access_url, file_path)
|
327
|
+
File.open(file_path, "wb") do |f|
|
328
|
+
f.write HTTParty.get(access_url)
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
def self.write_config(config_path, options)
|
333
|
+
File.open(config_path, "w") do |file|
|
334
|
+
file.puts "app_id=#{options[:app_id]}"
|
335
|
+
file.puts "secret_id=#{options[:secret_id]}"
|
336
|
+
file.puts "secret_key=#{options[:secret_key]}"
|
337
|
+
file.puts "endpoint=#{options[:endpoint]}"
|
338
|
+
file.puts "bucket=#{options[:bucket]}"
|
339
|
+
file.puts "ssl_ca_file="
|
340
|
+
file.puts "max_retry_times="
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
end
|
345
|
+
end
|
@@ -6,7 +6,8 @@ module QcloudCos
|
|
6
6
|
# @param bucket_name [String] :bucket (config.bucket) 指定当前 bucket, 默认是配置里面的 bucket
|
7
7
|
#
|
8
8
|
# @return [Hash] 返回 Bucket 信息
|
9
|
-
def bucket_info(bucket_name =
|
9
|
+
def bucket_info(bucket_name = nil)
|
10
|
+
bucket_name = bucket_name || config.bucket
|
10
11
|
stat('/', bucket: bucket_name)['data']
|
11
12
|
rescue
|
12
13
|
{}
|
data/lib/qcloud_cos/error.rb
CHANGED
data/lib/qcloud_cos/version.rb
CHANGED
data/qcloud_cos.gemspec
CHANGED
@@ -14,13 +14,15 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.homepage = 'https://github.com/tencentyun'
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
-
spec.bindir = '
|
18
|
-
spec.executables =
|
17
|
+
spec.bindir = 'bin'
|
18
|
+
spec.executables = ['qcloud-cos']
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
21
|
spec.add_dependency 'httparty'
|
22
22
|
spec.add_dependency 'httmultiparty'
|
23
23
|
spec.add_dependency 'addressable'
|
24
|
+
spec.add_dependency 'commander'
|
25
|
+
spec.add_dependency 'awesome_print'
|
24
26
|
|
25
27
|
spec.add_development_dependency 'bundler'
|
26
28
|
spec.add_development_dependency 'rake'
|
data/wiki/get_started.md
CHANGED
@@ -21,7 +21,7 @@
|
|
21
21
|
10. [检查目录下是否有文件夹 (contains_folder?)](#判断目录是否为空)
|
22
22
|
3. [文件操作](#文件操作)
|
23
23
|
1. [上传文件 (create, upload)](#文件上传)
|
24
|
-
2. [分片上传文件,支持断点续传 (upload_slice)](
|
24
|
+
2. [分片上传文件,支持断点续传 (upload_slice)](#大文件分片上传)
|
25
25
|
3. [更新文件属性 (update)](#更新属性)
|
26
26
|
4. [查询文件信息 (stat)](#目录或者文件查询)
|
27
27
|
5. [列出文件 (list, list_files)](#列举目录下文件或目录)
|
@@ -30,8 +30,19 @@
|
|
30
30
|
8. [文件搜索 (list)](#列举目录下文件或目录)
|
31
31
|
9. [检查文件是否存在 (exists?, exist?)](#判断目录或者文件是否存在)
|
32
32
|
10. [查看目录下文件数量 (count)](#查看文件和文件夹数目)
|
33
|
-
11. [检查目录下是否有文件 (contains_folder?)](#判断目录是否为空)
|
34
|
-
|
33
|
+
11. [检查目录下是否有文件 (contains_folder?)](#判断目录是否为空)
|
34
|
+
4. [分片上传 (upload_slice)](#文件分片上传)
|
35
|
+
1. [分片上传大文件 (upload_slice)](#大文件分片上传)
|
36
|
+
2. [分片上传初始化 (init_slice_upload)](#分片上传初始化)
|
37
|
+
3. [分片上传数据 (upload_part)](#分片上传数据)
|
38
|
+
4. [命令行工具 (qcloud-cos)](#命令行工具)
|
39
|
+
1. [配置 (qcloud-cos config)](#命令行配置)
|
40
|
+
2. [查看信息 (qcloud-cos info)](#info)
|
41
|
+
3. [列出文件 (qcloud-cos list)](#list)
|
42
|
+
4. [上传文件或者目录 (qcloud-cos upload)](#upload)
|
43
|
+
5. [下载文件或者目录 (qcloud-cos download)](#download)
|
44
|
+
6. [删除文件或者目录 (qcloud-cos remove)](#remove)
|
45
|
+
3. [其它资源](#其它资源)
|
35
46
|
|
36
47
|
|
37
48
|
## 开发准备
|
@@ -539,63 +550,6 @@ path = "/myFolder/test.log";
|
|
539
550
|
result = QcloudCos.upload(path, file, biz_attr: 'attr')
|
540
551
|
```
|
541
552
|
|
542
|
-
#### 文件分片上传
|
543
|
-
|
544
|
-
1. 接口说明
|
545
|
-
|
546
|
-
用于较大文件(一般大于8MB)的上传,调用者可以通过此接口上传较大文件并获得文件的url和唯一标识resource_path(用于调用其他api)。
|
547
|
-
|
548
|
-
2. 方法
|
549
|
-
|
550
|
-
```ruby
|
551
|
-
QcloudCos.upload_slice(dst_path, src_path, options = {})
|
552
|
-
```
|
553
|
-
|
554
|
-
3. 参数和返回值
|
555
|
-
|
556
|
-
参数说明:
|
557
|
-
|
558
|
-
|
559
|
-
|参数名|类型 |必须 |默认值 |参数描述|
|
560
|
-
|-----|----|-----|------|-------|
|
561
|
-
| dst_path | String|是 |无 |文件在COS服务端的全路径,不包括/appid/bucketname|
|
562
|
-
| src_path | String |是 |无 |本地要上传文件的全路径|
|
563
|
-
| options | Hash | 否 | 无 | 额外参数
|
564
|
-
| options['bucket'] | String| 否 | 配置的默认 bucket | Bucket 名称|
|
565
|
-
| options['biz_attr'] | String| 否 | 无 | 文件属性,业务端自己维护 |
|
566
|
-
| options['slice_size'] |Integer |否 | 3M|分片大小,用户可以根据网络状况自行设置|
|
567
|
-
| options['session'] |String |否 |null |如果是断点续传, 则带上(唯一标识此文件传输过程的id, 由后台下发, 调用方透传)|
|
568
|
-
|
569
|
-
|
570
|
-
返回值, Hash:
|
571
|
-
|
572
|
-
|
573
|
-
|参数名 |类型 |必然返回 |参数描述 |
|
574
|
-
|------|----|--------|--------|
|
575
|
-
|code |Integer |是 |错误码,成功时为0|
|
576
|
-
|message |String |是 |错误信息|
|
577
|
-
|data |Array |是 |返回数据|
|
578
|
-
|data['access_url'] | String| 是 |生成的文件下载url|
|
579
|
-
|data['url'] |String |是 |操作文件的url|
|
580
|
-
|data['resource_path'] |String |是 |资源路径. 格式:/appid/bucket/xxx|
|
581
|
-
|
582
|
-
API 请求错误,则抛出 RequestError 异常
|
583
|
-
|
584
|
-
|
585
|
-
|参数名 |类型 |参数描述 |
|
586
|
-
|------|----|--------|
|
587
|
-
|code | Int| API 错误码|
|
588
|
-
|message | String| 错误信息|
|
589
|
-
|original_response | Response | 原始返回结果|
|
590
|
-
|
591
|
-
示例代码:
|
592
|
-
|
593
|
-
```ruby
|
594
|
-
src_path= "/data/test.mp4"
|
595
|
-
dst_path = "/myFolder/test.mp4"
|
596
|
-
result = QcloudCos.upload_slice(dst_path, src_path)
|
597
|
-
```
|
598
|
-
|
599
553
|
#### 查看文件和文件夹数目
|
600
554
|
|
601
555
|
1. 接口说明
|
@@ -753,9 +707,380 @@ API 请求错误,则抛出 RequestError 异常
|
|
753
707
|
```ruby
|
754
708
|
path = "/myFolder/test.mp4"
|
755
709
|
result = QcloudCos.public_url(path)
|
756
|
-
```
|
710
|
+
```
|
711
|
+
|
712
|
+
|
713
|
+
## 分片上传
|
714
|
+
|
715
|
+
分片上传在大文件上传和断点续传方面有很大的作用。我们主要提供了三个接口来帮助你完成上传。
|
716
|
+
|
717
|
+
### 大文件分片上传
|
718
|
+
|
719
|
+
1. 接口说明
|
720
|
+
|
721
|
+
用于较大文件的上传,调用者可以通过此接口上传较大文件并获得文件的url。
|
722
|
+
该接口还还支持断点续传,如果由于网络原因,导致了上传失败,只需要重试即可在自动在之前中断的位置继续上传。
|
723
|
+
|
724
|
+
如果你还需要更进一步的定制需求,可以使用更底层的接口:[init_slice_upload]() + [upload_part]()
|
725
|
+
|
726
|
+
2. 方法
|
727
|
+
|
728
|
+
```ruby
|
729
|
+
QcloudCos.upload_slice(dst_path, src_path, options = {}, &block)
|
730
|
+
```
|
731
|
+
|
732
|
+
3. 参数和返回值
|
733
|
+
|
734
|
+
参数说明:
|
735
|
+
|
736
|
+
|
737
|
+
|参数名|类型 |必须 |默认值 |参数描述|
|
738
|
+
|-----|----|-----|------|-------|
|
739
|
+
| dst_path | String|是 |无 |文件在COS服务端的全路径,不包括/appid/bucketname|
|
740
|
+
| src_path | String |是 |无 |本地要上传文件的全路径|
|
741
|
+
| block | Blockk |否 |无 |如果需要显示进度,可以传递一个 Block,Block 需要接受一个参数,是 0~1 的一个小数,表示当前进度|
|
742
|
+
| options | Hash | 否 | 无 | 额外参数
|
743
|
+
| options['bucket'] | String| 否 | 配置的默认 bucket | Bucket 名称|
|
744
|
+
| options['biz_attr'] | String| 否 | 无 | 文件属性,业务端自己维护 |
|
745
|
+
| options['slice_size'] |Integer |否 | 3M|分片大小,用户可以根据网络状况自行设置|
|
746
|
+
| options['session'] |String |否 |null |如果是断点续传, 则带上(唯一标识此文件传输过程的id, 由后台下发, 调用方透传)|
|
747
|
+
|
748
|
+
|
749
|
+
返回值, Hash:
|
750
|
+
|
751
|
+
|
752
|
+
|参数名 |类型 |必然返回 |参数描述 |
|
753
|
+
|------|----|--------|--------|
|
754
|
+
|code |Integer |是 |错误码,成功时为0|
|
755
|
+
|message |String |是 |错误信息|
|
756
|
+
|data |Array |是 |返回数据|
|
757
|
+
|data['access_url'] | String| 是 |生成的文件下载url|
|
758
|
+
|data['url'] |String |是 |操作文件的url|
|
759
|
+
|data['resource_path'] |String |是 |资源路径. 格式:/appid/bucket/xxx|
|
760
|
+
|
761
|
+
API 请求错误,则抛出 RequestError 异常
|
762
|
+
|
763
|
+
|
764
|
+
|参数名 |类型 |参数描述 |
|
765
|
+
|------|----|--------|
|
766
|
+
|code | Int| API 错误码|
|
767
|
+
|message | String| 错误信息|
|
768
|
+
|original_response | Response | 原始返回结果|
|
769
|
+
|
770
|
+
示例代码:
|
771
|
+
|
772
|
+
```ruby
|
773
|
+
src_path= "/data/test.mp4"
|
774
|
+
dst_path = "/myFolder/test.mp4"
|
775
|
+
result = QcloudCos.upload_slice(dst_path, src_path)
|
776
|
+
result = QcloudCos.upload_slice(dst_path, src_path) do |pr|
|
777
|
+
puts "uploaded #{pr * 100}%"
|
778
|
+
end
|
779
|
+
```
|
780
|
+
|
781
|
+
### 分片上传初始化
|
782
|
+
|
783
|
+
1. 接口说明
|
784
|
+
|
785
|
+
初始化分片上传,正常会返回分片上传 session ID。
|
786
|
+
|
787
|
+
注意:
|
788
|
+
|
789
|
+
+ 如果该文件 sha 值已存在,则直接返回成功,你可以根据结果中是否包含 data['url'] 判断。
|
790
|
+
+ 如果该文件上次分片上传没有成功,data['offset'] 表示了上次上传的位置,你可以从该位置开始上传。
|
791
|
+
+ 如果想断点续传,则需要传递上一次 session ID.
|
792
|
+
|
793
|
+
2. 方法
|
794
|
+
|
795
|
+
```ruby
|
796
|
+
QcloudCos.init_slice_upload(path, filesize, sha, options = {})
|
797
|
+
```
|
798
|
+
|
799
|
+
3. 参数和返回值
|
800
|
+
|
801
|
+
参数说明:
|
802
|
+
|
803
|
+
|
804
|
+
|参数名|类型 |必须 |默认值 |参数描述|
|
805
|
+
|-----|----|-----|------|-------|
|
806
|
+
| path | String|是 |无 |文件在COS服务端的全路径,不包括/appid/bucketname|
|
807
|
+
| filesize | Integer |是 |无 |本地要上传文件大小|
|
808
|
+
| sha | String |是 |无 |本地要上传文件 sha1 值 |
|
809
|
+
| options | Hash | 否 | 无 | 额外参数
|
810
|
+
| options['bucket'] | String| 否 | 配置的默认 bucket | Bucket 名称|
|
811
|
+
| options['biz_attr'] | String| 否 | 无 | 文件属性,业务端自己维护 |
|
812
|
+
| options['slice_size'] |Integer |否 | 3M|分片大小,用户可以根据网络状况自行设置|
|
813
|
+
| options['session'] |String |否 |null |如果是断点续传, 则带上(唯一标识此文件传输过程的id, 由后台下发, 调用方透传)|
|
814
|
+
|
815
|
+
|
816
|
+
返回值, Hash:
|
817
|
+
|
818
|
+
|
819
|
+
|参数名 |类型 |必然返回 |参数描述 |
|
820
|
+
|------|----|--------|--------|
|
821
|
+
|code |Integer |是 |错误码,成功时为0|
|
822
|
+
|message |String |是 |错误信息|
|
823
|
+
|data |Hash |是 |返回数据|
|
824
|
+
|data['access_url'] | String| 否 |生成的文件下载url|
|
825
|
+
|data['url'] |String |否 |操作文件的url|
|
826
|
+
|data['resource_path'] |String |否 |资源路径. 格式:/appid/bucket/xxx|
|
827
|
+
|
828
|
+
API 请求错误,则抛出 RequestError 异常
|
829
|
+
|
830
|
+
|
831
|
+
|参数名 |类型 |参数描述 |
|
832
|
+
|------|----|--------|
|
833
|
+
|code | Int| API 错误码|
|
834
|
+
|message | String| 错误信息|
|
835
|
+
|original_response | Response | 原始返回结果|
|
836
|
+
|
837
|
+
示例代码:
|
838
|
+
|
839
|
+
```ruby
|
840
|
+
file = File.new("/data/test.mp4")
|
841
|
+
filesize = file.size
|
842
|
+
sha = Digest::SHA1.file('/data/test.mp4').hexdigest
|
843
|
+
dst_path = "/myFolder/test.mp4"
|
844
|
+
result = QcloudCos.init_slice_upload(dst_path, filesize, sha) # { data: { session: 'dsfasfda' }
|
845
|
+
```
|
846
|
+
|
847
|
+
### 分片上传数据
|
848
|
+
|
849
|
+
1. 接口说明
|
850
|
+
|
851
|
+
分片上传数据,初始化之后可以分片上传数据,文件上传成功会返回文件的 url。
|
852
|
+
|
853
|
+
2. 方法
|
854
|
+
|
855
|
+
```ruby
|
856
|
+
QcloudCos.upload_part(path, session, offset, content, options = {})
|
857
|
+
```
|
858
|
+
|
859
|
+
3. 参数和返回值
|
860
|
+
|
861
|
+
参数说明:
|
862
|
+
|
863
|
+
|
864
|
+
|参数名|类型 |必须 |默认值 |参数描述|
|
865
|
+
|-----|----|-----|------|-------|
|
866
|
+
| path | String|是 |无 |文件在COS服务端的全路径,不包括/appid/bucketname|
|
867
|
+
| session | Integer |是 |无 |本次分片上传的 session ID, 初始化的时候会返回|
|
868
|
+
| offset | String |是 |无 |本地要上传的位移|
|
869
|
+
| content | String |是 |无 |本地要上传的内容 |
|
870
|
+
| options | Hash | 否 | 无 | 额外参数
|
871
|
+
| options['bucket'] | String| 否 | 配置的默认 bucket | Bucket 名称|
|
872
|
+
|
873
|
+
|
874
|
+
返回值, Hash:
|
875
|
+
|
876
|
+
|
877
|
+
|参数名 |类型 |必然返回 |参数描述 |
|
878
|
+
|------|----|--------|--------|
|
879
|
+
|code |Integer |是 |错误码,成功时为0|
|
880
|
+
|message |String |是 |错误信息|
|
881
|
+
|data |Hash |是 |返回数据|
|
882
|
+
|data['access_url'] | String| 否 |生成的文件下载url|
|
883
|
+
|data['url'] |String |否 |操作文件的url|
|
884
|
+
|data['resource_path'] |String |否 |资源路径. 格式:/appid/bucket/xxx|
|
885
|
+
|
886
|
+
API 请求错误,则抛出 RequestError 异常
|
887
|
+
|
888
|
+
|
889
|
+
|参数名 |类型 |参数描述 |
|
890
|
+
|------|----|--------|
|
891
|
+
|code | Int| API 错误码|
|
892
|
+
|message | String| 错误信息|
|
893
|
+
|original_response | Response | 原始返回结果|
|
894
|
+
|
895
|
+
示例代码:
|
896
|
+
|
897
|
+
```ruby
|
898
|
+
session = 'dsfasfda'
|
899
|
+
result = QcloudCos.upload_part(dst_path, session, 100, 'Hello')
|
900
|
+
```
|
901
|
+
|
902
|
+
## 命令行工具
|
903
|
+
|
904
|
+
为了更方便地管理你的 COS,我们提供了命令行工具。
|
905
|
+
|
906
|
+
我们主要提供了五个基本命令: info, list, upload, download, remove 来完成你的操作
|
907
|
+
|
908
|
+
```
|
909
|
+
$ qcloud-cos help
|
910
|
+
|
911
|
+
NAME:
|
912
|
+
|
913
|
+
qcloud-cos
|
914
|
+
|
915
|
+
DESCRIPTION:
|
916
|
+
|
917
|
+
command-line tool for Qcloud COS
|
918
|
+
|
919
|
+
COMMANDS:
|
920
|
+
|
921
|
+
config Init config, eg: qcloud-cos config
|
922
|
+
download Download objects from COS
|
923
|
+
help Display global or [command] help documentation
|
924
|
+
info Obtain information
|
925
|
+
list List objects under [dest_path]
|
926
|
+
remove Remove objects from COS
|
927
|
+
upload Upload file or folder to COS
|
928
|
+
|
929
|
+
GLOBAL OPTIONS:
|
930
|
+
|
931
|
+
-h, --help
|
932
|
+
Display help documentation
|
933
|
+
|
934
|
+
-v, --version
|
935
|
+
Display version information
|
936
|
+
|
937
|
+
-t, --trace
|
938
|
+
Display backtrace when an error occurs
|
939
|
+
```
|
940
|
+
|
941
|
+
### 命令行配置
|
942
|
+
|
943
|
+
在使用之前,你需要先做一些配置,最快速的方式是使用 `qcloud-cos config` 命令:
|
944
|
+
|
945
|
+
```
|
946
|
+
$ qcloud-cos config
|
947
|
+
Qcloud COS APP ID:
|
948
|
+
Qcloud COS Secret ID:
|
949
|
+
Qcloud COS Secret Key:
|
950
|
+
Default Qcloud COS Endpoint [http://web.file.myqcloud.com/files/v1/]:
|
951
|
+
Default Qcloud COS Bucket:
|
952
|
+
```
|
953
|
+
|
954
|
+
它会自动在当前目录下生成一个 `.qcloud-cos.yml` 配置文件。
|
955
|
+
|
956
|
+
如果不使用配置文件,你也可以使用环境变量:
|
957
|
+
|
958
|
+
```
|
959
|
+
export QCLOUD_COS_APP_ID='<your-app-id>'
|
960
|
+
export QCLOUD_COS_SECRET_ID='<your-secret-id>'
|
961
|
+
export QCLOUD_COS_SECRET_KEY='<your-secret-key>'
|
962
|
+
export QCLOUD_COS_ENDPOINT='http://web.file.myqcloud.com/files/v1/'
|
963
|
+
export QCLOUD_COS_BUCKET='<your-bucket-name>'
|
964
|
+
export QCLOUD_COS_SSL_CA_FILE='<your-ssl-ca-file-path>'
|
965
|
+
```
|
966
|
+
|
967
|
+
***注意:环境变量会覆盖配置文件中的设置***
|
968
|
+
|
969
|
+
|
970
|
+
### info
|
971
|
+
|
972
|
+
查看 Bucket,文件或者文件夹信息
|
973
|
+
|
974
|
+
基本用法: `qcloud-cos info [options] [dest_path]`
|
975
|
+
|
976
|
+
使用范例:
|
977
|
+
|
978
|
+
```
|
979
|
+
# 查看 Bucket 信息
|
980
|
+
$ qcloud-cos info
|
981
|
+
|
982
|
+
# 查看 /production.log 信息
|
983
|
+
$ qcloud-cos info /production.log
|
984
|
+
|
985
|
+
# 查看 /test/ 信息
|
986
|
+
$ qcloud-cos info /test/
|
987
|
+
|
988
|
+
# 查看 bucket2 上的 /production.log 信息
|
989
|
+
$ qcloud-cos info --bucket bucket2 /production.log
|
990
|
+
```
|
991
|
+
|
992
|
+
### list
|
993
|
+
|
994
|
+
列出文件或者文件夹
|
995
|
+
|
996
|
+
基本用法: `qcloud-cos list [options] [dest_path]`
|
997
|
+
|
998
|
+
使用范例:
|
999
|
+
|
1000
|
+
```
|
1001
|
+
# 列出 / 下面的所有对象
|
1002
|
+
$ qcloud-cos list
|
1003
|
+
|
1004
|
+
# 列出 /test/ 下面的所有对象
|
1005
|
+
$ qcloud-cos list /test/
|
1006
|
+
|
1007
|
+
# 列出 /test/ 下面的前 10 个对象
|
1008
|
+
$ qcloud-cos list --num 10 /test/
|
1009
|
+
|
1010
|
+
# 列出 bucket2 的 /test/ 下面的所有对象
|
1011
|
+
$ qcloud-cos list --bucket bucket2 /test/
|
1012
|
+
```
|
1013
|
+
|
1014
|
+
### upload
|
1015
|
+
|
1016
|
+
上传文件或者目录到 COS
|
1017
|
+
|
1018
|
+
基本用法: `qcloud-cos upload [options] file [dest_path]`
|
1019
|
+
|
1020
|
+
使用范例:
|
1021
|
+
|
1022
|
+
```
|
1023
|
+
# 把 production.log 上传到 /
|
1024
|
+
$ qcloud-cos upload production.log
|
1025
|
+
|
1026
|
+
# 把 production.log 上传到 /data/ 下面
|
1027
|
+
$ qcloud-cos upload production.log /data/
|
1028
|
+
|
1029
|
+
# 把 ./test/ 整个文件夹上传到 /data/ 下面
|
1030
|
+
$ qcloud-cos upload test/ /data/
|
1031
|
+
|
1032
|
+
# 把 ./test/ 整个文件夹上传到 bucket2 的 /data/ 下面
|
1033
|
+
$ qcloud-cos upload --bucket bucket2 test/ /data/
|
1034
|
+
```
|
1035
|
+
|
1036
|
+
### download
|
1037
|
+
|
1038
|
+
下载文件或者目录
|
1039
|
+
|
1040
|
+
基本用法: `qcloud-cos download [options] dest_path [save_path]`
|
1041
|
+
|
1042
|
+
使用范例:
|
1043
|
+
|
1044
|
+
```
|
1045
|
+
# 把 /data/production.log 下载到当前目录
|
1046
|
+
$ qcloud-cos download /data/production.log
|
1047
|
+
|
1048
|
+
# 把 /data/production.log 下载到 ./data/ 下
|
1049
|
+
$ qcloud-cos download /data/production.log ./data
|
1050
|
+
|
1051
|
+
# 把 /data/test/ 整个目录下载并保存到 ./data/ 目录下面
|
1052
|
+
$ qcloud-cos download /data/test/ ./data
|
1053
|
+
|
1054
|
+
# 把 bucket2 下的 /data/test/ 整个目录下载并保存到 ./data/ 下面
|
1055
|
+
$ qcloud-cos download --bucket bucket2 /data/test/ ./data
|
1056
|
+
```
|
1057
|
+
|
1058
|
+
|
1059
|
+
### remove
|
1060
|
+
|
1061
|
+
删除目录或者文件夹
|
1062
|
+
|
1063
|
+
基本用法: `qcloud-cos remove [options] dest_path`
|
1064
|
+
|
1065
|
+
使用范例:
|
1066
|
+
|
1067
|
+
```
|
1068
|
+
# 删除文件/data/production.log
|
1069
|
+
$ qcloud-cos remove /data/production.log
|
1070
|
+
|
1071
|
+
# 删除目录 /data/test/, 目录非空会失败
|
1072
|
+
$ qcloud-cos remove /data/test/
|
1073
|
+
|
1074
|
+
# 级联删除目录 /data/test/
|
1075
|
+
$ qcloud-cos remove --recursive /data/test/
|
1076
|
+
|
1077
|
+
# 删除 bucket2 下面的目录 /data/test/
|
1078
|
+
$ qcloud-cos download --bucket bucket2 /data/test/
|
1079
|
+
```
|
1080
|
+
|
1081
|
+
|
757
1082
|
|
758
1083
|
## 其它资源
|
759
1084
|
|
760
|
-
+ [RDoc 文档](http://www.rubydoc.info/gems/qcloud_cos/0.
|
1085
|
+
+ [RDoc 文档](http://www.rubydoc.info/gems/qcloud_cos/0.3.0)
|
761
1086
|
+ [腾讯 COS 详细文档](http://www.qcloud.com/doc/product/227/%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qcloud_cos
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Newell Zhu
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httparty
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: commander
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: awesome_print
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: bundler
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -153,7 +181,8 @@ dependencies:
|
|
153
181
|
description: Ruby SDK For QCloud COS, Enjoy it!
|
154
182
|
email:
|
155
183
|
- zlx.star@gmail.com
|
156
|
-
executables:
|
184
|
+
executables:
|
185
|
+
- qcloud-cos
|
157
186
|
extensions: []
|
158
187
|
extra_rdoc_files: []
|
159
188
|
files:
|
@@ -165,10 +194,12 @@ files:
|
|
165
194
|
- README.md
|
166
195
|
- Rakefile
|
167
196
|
- bin/console
|
197
|
+
- bin/qcloud-cos
|
168
198
|
- bin/setup
|
169
199
|
- lib/qcloud_cos.rb
|
170
200
|
- lib/qcloud_cos/api.rb
|
171
201
|
- lib/qcloud_cos/authorization.rb
|
202
|
+
- lib/qcloud_cos/cli.rb
|
172
203
|
- lib/qcloud_cos/configuration.rb
|
173
204
|
- lib/qcloud_cos/convenient_api.rb
|
174
205
|
- lib/qcloud_cos/error.rb
|
@@ -195,9 +226,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
195
226
|
version: '0'
|
196
227
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
197
228
|
requirements:
|
198
|
-
- - "
|
229
|
+
- - ">"
|
199
230
|
- !ruby/object:Gem::Version
|
200
|
-
version:
|
231
|
+
version: 1.3.1
|
201
232
|
requirements: []
|
202
233
|
rubyforge_project:
|
203
234
|
rubygems_version: 2.2.0
|