baidu-sdk 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +15 -0
- data/.yardopts +1 -0
- data/Gemfile +17 -0
- data/Guardfile +6 -0
- data/HISTORY.md +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +161 -0
- data/Rakefile +4 -0
- data/baidu-pcs.gemspec +24 -0
- data/lib/baidu/configure.rb +27 -0
- data/lib/baidu/core.rb +19 -0
- data/lib/baidu/errors/error.rb +22 -0
- data/lib/baidu/oauth.rb +11 -0
- data/lib/baidu/oauth/client.rb +66 -0
- data/lib/baidu/oauth/flow/base.rb +44 -0
- data/lib/baidu/oauth/flow/code.rb +69 -0
- data/lib/baidu/oauth/flow/device.rb +75 -0
- data/lib/baidu/pcs.rb +19 -0
- data/lib/baidu/pcs/client.rb +1090 -0
- data/lib/baidu/session.rb +36 -0
- data/lib/baidu/support/cacert.pem +37 -0
- data/lib/baidu/support/request.rb +127 -0
- data/lib/baidu/support/util.rb +67 -0
- data/lib/baidu/version.rb +5 -0
- data/spec/baidu/core_spec.rb +20 -0
- data/spec/baidu/oauth/client_spec.rb +199 -0
- data/spec/baidu/pcs/client_spec.rb +878 -0
- data/spec/baidu/session_spec.rb +27 -0
- data/spec/baidu/support/request_spec.rb +58 -0
- data/spec/baidu/support/util_spec.rb +48 -0
- data/spec/fixtures/add_task.json +1 -0
- data/spec/fixtures/cancel_task.json +3 -0
- data/spec/fixtures/copy.json +7 -0
- data/spec/fixtures/delete.json +3 -0
- data/spec/fixtures/diff.json +17 -0
- data/spec/fixtures/empty.json +1 -0
- data/spec/fixtures/get_token_code.json +8 -0
- data/spec/fixtures/get_token_device.json +8 -0
- data/spec/fixtures/list.json +11 -0
- data/spec/fixtures/list_task_0.json +1 -0
- data/spec/fixtures/list_task_1.json +1 -0
- data/spec/fixtures/listrecycle.json +23 -0
- data/spec/fixtures/logo.png +0 -0
- data/spec/fixtures/meta.json +11 -0
- data/spec/fixtures/mkdir.json +7 -0
- data/spec/fixtures/move.json +8 -0
- data/spec/fixtures/query_task_0.json +24 -0
- data/spec/fixtures/query_task_1.json +22 -0
- data/spec/fixtures/quota.json +5 -0
- data/spec/fixtures/rapidupload.json +10 -0
- data/spec/fixtures/refresh_token.json +8 -0
- data/spec/fixtures/restore.json +1 -0
- data/spec/fixtures/search.json +11 -0
- data/spec/fixtures/stream_list.json +16 -0
- data/spec/fixtures/streaming.m3u8 +5 -0
- data/spec/fixtures/upload.json +9 -0
- data/spec/fixtures/upload_block.json +4 -0
- data/spec/fixtures/user_and_device_code.json +8 -0
- data/spec/spec_helper.rb +66 -0
- metadata +169 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Baidu
|
4
|
+
module OAuth
|
5
|
+
module Flow
|
6
|
+
module Base
|
7
|
+
include Baidu::Support
|
8
|
+
|
9
|
+
# 此授权流程对应的 OAuth Client 实例
|
10
|
+
attr_reader :client
|
11
|
+
|
12
|
+
def initialize(client)
|
13
|
+
@client = client
|
14
|
+
end
|
15
|
+
|
16
|
+
def authorize_url(redirect_uri, params={})
|
17
|
+
query = authorize_query.update params
|
18
|
+
query.update({ client_id: self.client.client_id, redirect_uri: redirect_uri })
|
19
|
+
Util.clean_params query
|
20
|
+
uri = URI(self.client.site)
|
21
|
+
uri.path = authorize_endpoint
|
22
|
+
uri.query = Util.encode_params(query) unless Util.blank? query
|
23
|
+
uri.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_token(code, redirect_uri=nil, params={})
|
27
|
+
body = token_body.update params
|
28
|
+
body.update({ client_id: self.client.client_id,
|
29
|
+
client_secret: self.client.client_secret,
|
30
|
+
redirect_uri: redirect_uri, code: code})
|
31
|
+
rest = self.client.post Baidu::OAuth::TOKEN_ENDPOINT, nil, body
|
32
|
+
return nil if rest.nil?
|
33
|
+
Baidu::Session.from rest
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def authorize_endpoint
|
39
|
+
Baidu::OAuth::AUTHORIZATION_ENDPOINT
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'baidu/oauth/flow/base'
|
4
|
+
|
5
|
+
module Baidu
|
6
|
+
module OAuth
|
7
|
+
module Flow
|
8
|
+
|
9
|
+
# 采用Authorization Code获取Access Token的授权验证流程又被称为Web Server Flow,
|
10
|
+
# 适用于所有有Server端的应用,如Web/Wap站点、有Server端的手机/桌面客户端应用等。
|
11
|
+
#
|
12
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/authorization Authorization Code授权
|
13
|
+
class Code
|
14
|
+
include Base
|
15
|
+
|
16
|
+
# 通过 Device Code 来获取 Access Token
|
17
|
+
#
|
18
|
+
# @note 每一个 Authorization Code 的有效期为10分钟,并且只能使用一次,再次使用将无效。
|
19
|
+
#
|
20
|
+
# 如果用户在此页面同意授权,授权服务则将重定向用户浏览器到应用所指定的“redirect_uri”,
|
21
|
+
# 并附带上表示授权服务所分配的 Authorization Code 的 +code+ 参数,以及 state 参数(如果请求authorization code时带了这个参数)。
|
22
|
+
#
|
23
|
+
# @param [String] code 所获得的 Authorization Code (redirect_uri 附带的 {code} 参数)
|
24
|
+
# @return [Baidu::Session]
|
25
|
+
# @see #user_and_device_code
|
26
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/device 通过Device Code获取Access Token
|
27
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/overview Access Token生命周期
|
28
|
+
def get_token(code, redirect_uri); super end
|
29
|
+
|
30
|
+
# 获取 Authorization URL
|
31
|
+
# @param [String] redirect_uri 授权后要回调的URI,即接收Authorization Code的URI。
|
32
|
+
# 如果用户在授权过程中取消授权,会回调该URI,并在URI末尾附上error=access_denied参数。
|
33
|
+
# 对于无Web Server的应用,其值可以是“oob”,此时用户同意授权后,
|
34
|
+
# 授权服务会将Authorization Code直接显示在响应页面的页面中及页面title中。
|
35
|
+
# 非“oob”值的redirect_uri按照如下规则进行匹配:
|
36
|
+
# (1)如果开发者在“授权安全设置”中配置了“授权回调地址”,
|
37
|
+
# 则redirect_uri必须与“授权回调地址”中的某一个相匹配;
|
38
|
+
# (2)如果未配置“授权回调地址”,redirect_uri所在域名必须与开发者注册应用时
|
39
|
+
# 所提供的网站根域名列表或应用的站点地址(如果根域名列表没填写)的域名相匹配。
|
40
|
+
# @option params [String] :scope 以空格分隔的权限列表,若不传递此参数,代表请求用户的默认权限
|
41
|
+
# @option params [String] :state 用于保持请求和回调的状态,授权服务器在回调时(重定向用户浏览器到“redirect_uri”时),
|
42
|
+
# 会在Query Parameter中原样回传该参数。OAuth2.0标准协议建议,利用state参数来防止CSRF攻击
|
43
|
+
# @option params [String] :display 登录和授权页面的展现样式,默认为“page”
|
44
|
+
# @option params [Boolean] :force_login +true+ 表示加载登录页时强制用户输入用户名和口令,不会从cookie中读取百度用户的登陆状态
|
45
|
+
# @option params [Boolean] :confirm_login +true+ 表示且百度用户已处于登陆状态,会提示是否使用已当前登陆用户对应用授权
|
46
|
+
# @return [String]
|
47
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/list 权限列表
|
48
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/set 页面设置
|
49
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/redirect 授权回调地址
|
50
|
+
def authorize_url(redirect_uri, params={})
|
51
|
+
opts = {}.update(params)
|
52
|
+
opts.update({ force_login: 1 }) if params[:force_login]
|
53
|
+
opts.update({ confirm_login: 1 }) if params[:confirm_login]
|
54
|
+
super redirect_uri, opts
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def authorize_query
|
60
|
+
{ response_type: 'code', display: 'page' }
|
61
|
+
end
|
62
|
+
|
63
|
+
def token_body
|
64
|
+
{ grant_type: 'authorization_code' }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'baidu/oauth/flow/base'
|
4
|
+
|
5
|
+
module Baidu
|
6
|
+
module OAuth
|
7
|
+
module Flow
|
8
|
+
|
9
|
+
# 对设备应用而言,其流程由获取User Code和Device Code、引导用户去百度
|
10
|
+
# 填写User Code并授权、以及通过Device Code获取Access Token这3步组成。
|
11
|
+
#
|
12
|
+
# @note 使用此授权流程,对于终端类型的应用也非常方便,同时还可以获取 Refresh Token
|
13
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/device Device授权
|
14
|
+
class Device
|
15
|
+
include Base
|
16
|
+
|
17
|
+
# 获取 User Code 和 Device Code
|
18
|
+
# @example 返回的原始 JSON
|
19
|
+
# {
|
20
|
+
# "device_code": "a82hjs723h72h3a82hjs723h72h3vb",
|
21
|
+
# "user_code": "8sjiae3p",
|
22
|
+
# "verification_url": "https://openapi.baidu.com/oauth/2.0/device",
|
23
|
+
# "qrcode_url": "http://openapi.baidu.com/device/qrcode/6c6a8afee394f99e55eb25858/2c885vjk",
|
24
|
+
# "expires_in": 1800,
|
25
|
+
# "interval": 5
|
26
|
+
# }
|
27
|
+
#
|
28
|
+
# :device_code Device Code,设备需要保存,供下一步使用
|
29
|
+
# :user_code User Code,设备需要展示给用户
|
30
|
+
# :verification_url 用户填写User Code并进行授权的url,设备需要展示给用户
|
31
|
+
# :qrcode_url 用于二维码登陆的Qr Code图片url,用户用智能终端扫描该二维码之后,
|
32
|
+
# 可直接进入步骤2的登陆授权页面
|
33
|
+
# :expires_in Device Code/ Use Code的过期时间,单位为秒
|
34
|
+
# :interval 设备尝试获取Access Token的时间间隔,单位为秒,设备下一步会使用
|
35
|
+
#
|
36
|
+
# @param [String] scope 非必须参数,以空格分隔的权限列表
|
37
|
+
# @return [Hash]
|
38
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/list 权限列表
|
39
|
+
def user_and_device_code(scope=nil)
|
40
|
+
query = authorize_query.update({ client_id: self.client.client_id })
|
41
|
+
query[:scope] = scope unless scope.nil?
|
42
|
+
self.client.get(authorize_endpoint, query)
|
43
|
+
end
|
44
|
+
|
45
|
+
# 通过 Device Code 来获取 Access Token
|
46
|
+
#
|
47
|
+
# @param [String] code {#user_and_device_code} 所获得的 Device Code
|
48
|
+
# @return [Baidu::Session]
|
49
|
+
# @see #user_and_device_code
|
50
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/device 通过Device Code获取Access Token
|
51
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/oauth/overview Access Token生命周期
|
52
|
+
def get_token(code); super end
|
53
|
+
|
54
|
+
# @private
|
55
|
+
def authorize_url
|
56
|
+
raise NoMethodError, 'no such method in device flow'
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def authorize_query
|
62
|
+
{ response_type: 'device_code', display: nil }
|
63
|
+
end
|
64
|
+
|
65
|
+
def token_body
|
66
|
+
{ grant_type: 'device_token' }
|
67
|
+
end
|
68
|
+
|
69
|
+
def authorize_endpoint
|
70
|
+
Baidu::OAuth::DEVICE_ENDPOINT
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/baidu/pcs.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'baidu/core'
|
2
|
+
require 'baidu/pcs/client'
|
3
|
+
|
4
|
+
module Baidu
|
5
|
+
|
6
|
+
module PCS
|
7
|
+
SITE = 'https://pcs.baidu.com'
|
8
|
+
UPLOAD_SITE = 'https://c.pcs.baidu.com'
|
9
|
+
DOWNLOAD_SITE = 'https://d.pcs.baidu.com'
|
10
|
+
BASE_PATH = '/rest/2.0/pcs'
|
11
|
+
APPS_PATH_PREFIX = '/apps'
|
12
|
+
end
|
13
|
+
|
14
|
+
module Configure
|
15
|
+
# 全局配置 PCS 的文件目录
|
16
|
+
# @return [String]
|
17
|
+
attr_accessor :pcs_dir_name
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,1090 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Baidu
|
4
|
+
module PCS
|
5
|
+
|
6
|
+
# Client 类封装实现了 Baidu PCS 的文件API,主要包括文件上传、下载、拷贝、删除、搜索、断点续传及缩略图等功能。
|
7
|
+
#
|
8
|
+
# 本文档多数内容取自 {http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list 文件API列表},
|
9
|
+
# 使用本 API 之前请先参考 Baidu PCS {http://developer.baidu.com/wiki/index.php?title=docs/pcs/guide/overview 开发指南},
|
10
|
+
# 准备好相应环境。
|
11
|
+
# @example
|
12
|
+
# require 'baidu/pcs'
|
13
|
+
#
|
14
|
+
# #全局配置,如已在其他地方配置过,可以忽略
|
15
|
+
# Baidu.config do |c|
|
16
|
+
# # ...
|
17
|
+
# c.pcs_dir_name = 'notes' # 可选,如此处未做配置,那么实例化 Client 时必须指定 dir_name
|
18
|
+
# # ...
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# # 用户授权完成之后获取的 access token
|
22
|
+
# access_token = 'xxxxxxxxxxxxxxxxxxxxxxxxx'
|
23
|
+
# # 使用全局配置 pcs_dir_name 作为文件目录
|
24
|
+
# client = Baidu::PCS::Client.new(access_token)
|
25
|
+
# # 不使用全局配置 pcs_dir_name
|
26
|
+
# # client = Baidu::PCS::Client.new(access_token, 'notes')
|
27
|
+
#
|
28
|
+
# File.open('/opt/ubuntu-12.04.3-server-amd64.iso', 'r') do |f|
|
29
|
+
# result = client.upload(f)
|
30
|
+
# # result 为 Hash 实例,是直接根据 Baidu REST API 返回的 JSON 转换而来
|
31
|
+
# # 具体键值及意义可参看各方法中 “返回的原始 JSON” 部分
|
32
|
+
# puts result[:path] # 输出上传后文件的保存路径
|
33
|
+
# puts result[:size] # 输出上传的文件大小
|
34
|
+
# puts result[:md5] # 输出上传的文件 md5 签名
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
class Client
|
38
|
+
include Baidu::Support::Request
|
39
|
+
|
40
|
+
# 创建一个 +Baidu::PCS::Client+ 文件API 实例,通过此实例可以执行 文件API 调用
|
41
|
+
# @overload initialize(access_token, dir_name=Baidu.pcs_dir_name)
|
42
|
+
# @param access_token [String] 通过 Baidu OAuth API 获得的 Access Token
|
43
|
+
# @param dir_name [String] 开通 PCS API 权限时,填写的文件目录。如果未设置此参数,则使用全局配置
|
44
|
+
#
|
45
|
+
# @overload initialize(session, dir_name=Baidu.pcs_dir_name)
|
46
|
+
# @param session [Baidu::Session] 通过 Baidu OAuth API 获得的 Session
|
47
|
+
# @param dir_name [String] 开通 PCS API 权限时,填写的文件目录。如果未设置此参数,则使用全局配置
|
48
|
+
#
|
49
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/guide/api_approve 开通PCS API权限
|
50
|
+
def initialize(access_token_or_session, dir_name=Baidu.pcs_dir_name)
|
51
|
+
@dir_name = dir_name
|
52
|
+
@access_token = case access_token_or_session
|
53
|
+
when String then access_token_or_session
|
54
|
+
when Baidu::Session then access_token_or_session.access_token
|
55
|
+
end
|
56
|
+
raise ArgumentError, 'dir_name must not be blank' if Util.blank? @dir_name
|
57
|
+
raise ArgumentError, 'access_token must not be blank' if Util.blank? @access_token
|
58
|
+
@site = Baidu::PCS::SITE
|
59
|
+
@dir_path = "#{APPS_PATH_PREFIX}/#{@dir_name}"
|
60
|
+
end
|
61
|
+
|
62
|
+
# @!group 1 基本功能
|
63
|
+
|
64
|
+
# 空间配额信息
|
65
|
+
#
|
66
|
+
# 获取当前用户空间配额信息
|
67
|
+
#
|
68
|
+
# @example 返回的原始 JSON
|
69
|
+
# {"quota":15000000000,"used":5221166,"request_id":4043312634}
|
70
|
+
#
|
71
|
+
# :quota 空间配额,单位为字节
|
72
|
+
# :used 已使用空间大小,单位为字节
|
73
|
+
#
|
74
|
+
# @return [Hash]
|
75
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E7.A9.BA.E9.97.B4.E9.85.8D.E9.A2.9D.E4.BF.A1.E6.81.AF 空间配额信息
|
76
|
+
def quota
|
77
|
+
get "#{BASE_PATH}/quota", base_query('info')
|
78
|
+
end
|
79
|
+
|
80
|
+
# 上传单个文件
|
81
|
+
#
|
82
|
+
# @note 百度PCS服务目前支持最大2G的单个文件上传
|
83
|
+
# @note 文件大小超过 128MB 时,自动启用文件分块上传;
|
84
|
+
# 如果不想启用文件分块上传,可以通过 +block_upload: false+ 来关闭
|
85
|
+
#
|
86
|
+
# @example
|
87
|
+
# File.open('/opt/ubuntu-12.04.3-server-amd64.iso', 'r') do |f|
|
88
|
+
# c.upload(f, block_upload: true)
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# @example 返回的原始 JSON
|
92
|
+
# {
|
93
|
+
# "fs_id": 3916799999,
|
94
|
+
# "path": "/apps/album/1.png",
|
95
|
+
# "ctime": 1384493574,
|
96
|
+
# "mtime": 1384493574,
|
97
|
+
# "md5": "6c37219ba0d3dfdfa95ff6912e2c42b9",
|
98
|
+
# "size": 4914,
|
99
|
+
# "request_id": 3036629135
|
100
|
+
# }
|
101
|
+
#
|
102
|
+
# :fs_id 文件在PCS的临时唯一标识ID
|
103
|
+
# :path 该文件的绝对路径
|
104
|
+
# :ctime 文件创建时间
|
105
|
+
# :mtime 文件修改时间
|
106
|
+
# :md5 文件的md5签名
|
107
|
+
# :size 文件字节大小
|
108
|
+
#
|
109
|
+
# @param file [File] 待上传的文件
|
110
|
+
# @option options [String] :path 上传文件路径,含上传的文件名称(相对于应用根目录),默认为 +file+ 的文件名
|
111
|
+
# @option options [Boolean] :overwrite
|
112
|
+
# +true+: 表示覆盖同名文件,
|
113
|
+
# +false+: 表示生成文件副本并进行重命名,命名规则为“文件名_日期.后缀”,
|
114
|
+
# 默认为 +false+
|
115
|
+
# @option options [Boolean] :block_upload 对文件分块上传,仅当 +file+ 大小超过 8MB 时,此设置有效;
|
116
|
+
# 分块大小取决于文件大小,4GB 以下文件分块大小为 4MB
|
117
|
+
# @option options [Fixnum] :retry_times <b>分块上传时</b>,出错自动重试次数,默认 5
|
118
|
+
# @option options [Fixnum] :retry_waitsec <b>分块上传时</b>,出错自动重试暂停秒数,默认 30
|
119
|
+
# @return [Hash]
|
120
|
+
# @see #upload_block
|
121
|
+
# @see #create_super_file
|
122
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E4.B8.8A.E4.BC.A0.E5.8D.95.E4.B8.AA.E6.96.87.E4.BB.B6 上传单个文件
|
123
|
+
def upload(file, options={})
|
124
|
+
raise ArgumentError, 'file must be an instance of File' unless file.instance_of? File
|
125
|
+
path = options[:path] || File.basename(file)
|
126
|
+
size = file.size
|
127
|
+
if (options[:block_upload] && size >= 4*1024*1024*2) || # at least 2 blocks
|
128
|
+
(options[:block_upload].nil? && size >= 128*1024*1024)
|
129
|
+
block_size = 4*1024*1024
|
130
|
+
while block_size * 1024 < size # at most 1024 blocks1
|
131
|
+
block_size *= 2
|
132
|
+
end
|
133
|
+
offset, block_list = 0, []
|
134
|
+
max_retry_times = options[:retry_times] || 5
|
135
|
+
retry_waitsec = options[:retry_waitsec] || 30
|
136
|
+
loop do
|
137
|
+
with_retries(max_retry_times, retry_waitsec) do
|
138
|
+
rest = upload_block IO.binread(file, block_size, offset)
|
139
|
+
block_list << rest[:md5]
|
140
|
+
end
|
141
|
+
offset += block_size
|
142
|
+
break if offset >= size
|
143
|
+
end
|
144
|
+
with_retries(max_retry_times, retry_waitsec) do
|
145
|
+
create_super_file block_list, path, options[:overwrite]
|
146
|
+
end
|
147
|
+
else
|
148
|
+
raise IOError, 'file is too large (larger than 2G)' if size > 2*1024*1024*1024
|
149
|
+
query = build_upload_query 'upload', path, options[:overwrite]
|
150
|
+
post "#{BASE_PATH}/file", query, { file: file }, site: Baidu::PCS::UPLOAD_SITE
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# 上传分片文件
|
155
|
+
#
|
156
|
+
# @note 百度PCS服务支持每次直接上传最大2G的单个文件。
|
157
|
+
# 如需支持上传超大文件(>2G),则可以通过组合调用分片文件上传方法和合并分片文件方法实现:
|
158
|
+
# 首先,将超大文件分割为2G以内的单文件,并调用 {#upload_block} 将分片文件依次上传;
|
159
|
+
# 其次,调用 {#create_super_file} ,完成分片文件的重组。
|
160
|
+
# 除此之外,如果应用中需要支持断点续传的功能,也可以通过分片上传文件并调用 {#create_super_file} 的方式实现。
|
161
|
+
#
|
162
|
+
# @example 返回的原始 JSON
|
163
|
+
# {"md5":"a7619410bca74850f985e488c9a0d51e","request_id":3238563823}
|
164
|
+
#
|
165
|
+
# :md5 上传内容的md5签名
|
166
|
+
#
|
167
|
+
# @param data [String] 上传的内容
|
168
|
+
# @return [Hash]
|
169
|
+
# @see #create_super_file
|
170
|
+
# @see #upload
|
171
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E5.88.86.E7.89.87.E4.B8.8A.E4.BC.A0.E2.80.94.E6.96.87.E4.BB.B6.E5.88.86.E7.89.87.E5.8F.8A.E4.B8.8A.E4.BC.A0 文件分片及上传
|
172
|
+
def upload_block(data)
|
173
|
+
query = build_upload_query 'upload', nil, nil, true
|
174
|
+
post "#{BASE_PATH}/file", query, { file: StringIO.new(data) }, site: Baidu::PCS::UPLOAD_SITE
|
175
|
+
end
|
176
|
+
|
177
|
+
# 合并分片文件
|
178
|
+
#
|
179
|
+
# 与分片文件上传 {#upload_block} 方法配合使用,可实现超大文件(>2G)上传,同时也可用于断点续传的场景
|
180
|
+
#
|
181
|
+
# @example 返回的原始 JSON
|
182
|
+
# {
|
183
|
+
# "path": "/apps/album/1.png",
|
184
|
+
# "size": 6844,
|
185
|
+
# "ctime": 1331197101,
|
186
|
+
# "mtime": 1331197101,
|
187
|
+
# "md5": "baa7c379639b74e9bf98c807498e1b64",
|
188
|
+
# "fs_id": 1548308694,
|
189
|
+
# "request_id": 4043313276
|
190
|
+
# }
|
191
|
+
#
|
192
|
+
# :path 该文件的绝对路径
|
193
|
+
# :size 文件字节大小
|
194
|
+
# :ctime 文件创建时间
|
195
|
+
# :mtime 文件修改时间
|
196
|
+
# :md5 文件的md5签名
|
197
|
+
# :fs_id 文件在PCS的临时唯一标识ID
|
198
|
+
#
|
199
|
+
# @param block_list [Array<String>] 数组,数组的取值为子文件内容的MD5;子文件至少2个,最多1024个
|
200
|
+
# @param path [String] 上传文件路径(含上传的文件名称)
|
201
|
+
# @param overwrite [Boolean]
|
202
|
+
# +true+: 表示覆盖同名文件
|
203
|
+
# +false+: 表示生成文件副本并进行重命名,命名规则为“文件名_日期.后缀”
|
204
|
+
# @return [Hash]
|
205
|
+
# @see #upload_block
|
206
|
+
# @see #upload
|
207
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E5.88.86.E7.89.87.E4.B8.8A.E4.BC.A0.E2.80.94.E5.90.88.E5.B9.B6.E5.88.86.E7.89.87.E6.96.87.E4.BB.B6 合并分片文件
|
208
|
+
def create_super_file(block_list, path, overwrite=false)
|
209
|
+
raise ArgumentError, 'block_list must be Array' unless block_list.instance_of? Array
|
210
|
+
raise ArgumentError, 'block_list size must be in 2..1024' unless block_list.length.between? 2, 1024
|
211
|
+
query = build_upload_query 'createsuperfile', path, overwrite
|
212
|
+
param = { block_list: block_list }
|
213
|
+
post "#{BASE_PATH}/file", query, param: JSON.dump(param)
|
214
|
+
end
|
215
|
+
|
216
|
+
# 下载单个文件
|
217
|
+
#
|
218
|
+
# Download 接口支持 HTTP 协议标准 range 定义,通过指定 range 的取值可以实现断点下载功能。
|
219
|
+
#
|
220
|
+
# @example 下载文件第 101 - 200 字节之间的内容
|
221
|
+
# File.open('logo.part2.png', 'w') do |f|
|
222
|
+
# f.write client.download('logo.png', begin: 100, end: 199)
|
223
|
+
# end
|
224
|
+
#
|
225
|
+
# @overload download(path, options={})
|
226
|
+
# 适合下载小文件,简单直接
|
227
|
+
# @note 下载大文件会占用过多的内存, 请使用 block 方法 #download(path, &block)
|
228
|
+
# @example
|
229
|
+
# File.open('logo.png', 'w') do |f|
|
230
|
+
# f.write client.download('logo.png')
|
231
|
+
# end
|
232
|
+
#
|
233
|
+
# @param path [String] 下载文件路径,路径相对于应用目录,从应用根目录起计算
|
234
|
+
# @option options [Fixnum] :begin 断点下载的开始字节索引
|
235
|
+
# @option options [Fixnum] :end 断点下载的结束字节索引
|
236
|
+
# @return [String] 直接返回文件内容
|
237
|
+
#
|
238
|
+
# @overload download(path, options={}, &block)
|
239
|
+
# 针对下载大文件优化的方法
|
240
|
+
# @example
|
241
|
+
# File.open('ubuntu.iso', 'w') do |f|
|
242
|
+
# client.download('ubuntu-12.04.3-server-amd64.iso') do |segment|
|
243
|
+
# f.write segment
|
244
|
+
# end
|
245
|
+
# end
|
246
|
+
#
|
247
|
+
# @param path [String] 下载文件路径,路径相对于应用目录,从应用根目录起计算
|
248
|
+
# @option options [Fixnum] :begin 断点下载的开始字节索引
|
249
|
+
# @option options [Fixnum] :end 断点下载的结束字节索引
|
250
|
+
# @yield [segment] 下载内容将以片段的方式提供
|
251
|
+
# @return [void]
|
252
|
+
#
|
253
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E4.B8.8B.E8.BD.BD.E5.8D.95.E4.B8.AA.E6.96.87.E4.BB.B6 下载单个文件
|
254
|
+
def download(path, options={}, &block)
|
255
|
+
site = Baidu::PCS::DOWNLOAD_SITE
|
256
|
+
query = { path: build_path(path) }.update(base_query 'download')
|
257
|
+
headers = if options[:begin] || options[:end]
|
258
|
+
range = "#{options[:begin] || 0}-#{options[:end]}"
|
259
|
+
{ Range: "bytes=#{range}" }
|
260
|
+
end
|
261
|
+
if block_given?
|
262
|
+
get "#{BASE_PATH}/file", query, site: site, headers: headers, &block
|
263
|
+
else
|
264
|
+
get "#{BASE_PATH}/file", query, site: site, headers: headers, raw: true
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
# 创建目录
|
269
|
+
#
|
270
|
+
# 为当前用户创建一个目录
|
271
|
+
#
|
272
|
+
# @example 返回的原始 JSON
|
273
|
+
# {
|
274
|
+
# "fs_id": 1636599174,
|
275
|
+
# "path": "/apps/yunfom/music",
|
276
|
+
# "ctime": 1331183814,
|
277
|
+
# "mtime": 1331183814,
|
278
|
+
# "request_id": 4043312656
|
279
|
+
# }
|
280
|
+
#
|
281
|
+
# :fs_id 目录在PCS的临时唯一标识id
|
282
|
+
# :path 该目录的绝对路径
|
283
|
+
# :ctime 目录创建时间
|
284
|
+
# :mtime 目录修改时间
|
285
|
+
#
|
286
|
+
# @param path [String] 需要创建的目录,相对于应用根目录
|
287
|
+
# @return [Hash]
|
288
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E5.88.9B.E5.BB.BA.E7.9B.AE.E5.BD.95 创建目录
|
289
|
+
def mkdir(path)
|
290
|
+
query = { path: build_path(path, true) }
|
291
|
+
post "#{BASE_PATH}/file", query.update(base_query 'mkdir')
|
292
|
+
end
|
293
|
+
|
294
|
+
# 单个或批量获取文件/目录的元信息
|
295
|
+
#
|
296
|
+
# @example 返回的原始 JSON
|
297
|
+
# {
|
298
|
+
# "list": [
|
299
|
+
# {
|
300
|
+
# "fs_id": 3528850315,
|
301
|
+
# "path": "/apps/album/music/hello",
|
302
|
+
# "ctime": 1331184269,
|
303
|
+
# "mtime": 1331184269,
|
304
|
+
# "block_list": [
|
305
|
+
# "59ca0efa9f5633cb0371bbc0355478d8"
|
306
|
+
# ],
|
307
|
+
# "size": 13,
|
308
|
+
# "isdir": 1
|
309
|
+
# }
|
310
|
+
# ],
|
311
|
+
# "request_id": 4043312678
|
312
|
+
# }
|
313
|
+
#
|
314
|
+
# :fs_id 文件或目录在PCS的临时唯一标识ID
|
315
|
+
# :path 文件或目录的绝对路径
|
316
|
+
# :ctime 文件或目录的创建时间
|
317
|
+
# :mtime 文件或目录的最后修改时间
|
318
|
+
# :block_list 文件所有分片的md5数组JSON字符串
|
319
|
+
# :size 文件大小(byte)
|
320
|
+
# :isdir 是否是目录的标识符:“0”为文件,“1”为目录
|
321
|
+
# :ifhassubdir 是否含有子目录的标识符:“0”表示没有子目录,“1”表示有子目录
|
322
|
+
#
|
323
|
+
# @overload meta(path)
|
324
|
+
# 获取单个文件或目录的元信息
|
325
|
+
# @param path [String] 文件或目录路径,相对于应用根目录
|
326
|
+
# @return [Hash]
|
327
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E8.8E.B7.E5.8F.96.E5.8D.95.E4.B8.AA.E6.96.87.E4.BB.B6.2F.E7.9B.AE.E5.BD.95.E7.9A.84.E5.85.83.E4.BF.A1.E6.81.AF 获取单个文件/目录的元信息
|
328
|
+
#
|
329
|
+
# @overload meta(paths)
|
330
|
+
# 批量获取文件或目录的元信息
|
331
|
+
# @param paths [Array<String>] 文件或目录路径,相对于应用根目录
|
332
|
+
# @return [Hash]
|
333
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E6.89.B9.E9.87.8F.E8.8E.B7.E5.8F.96.E6.96.87.E4.BB.B6.2F.E7.9B.AE.E5.BD.95.E7.9A.84.E5.85.83.E4.BF.A1.E6.81.AF 批量获取文件/目录的元信息
|
334
|
+
#
|
335
|
+
# @return [Hash]
|
336
|
+
def meta(path)
|
337
|
+
meta_or_delete :meta, path
|
338
|
+
end
|
339
|
+
|
340
|
+
# 获取目录下的文件列表
|
341
|
+
#
|
342
|
+
# @example 调用示例
|
343
|
+
# client.list('apitest/movies', order: 'asc', by: 'time', limit: '2-10')
|
344
|
+
#
|
345
|
+
# @example 返回的原始 JSON
|
346
|
+
# {
|
347
|
+
# "list": [
|
348
|
+
# {
|
349
|
+
# "fs_id": 703525418,
|
350
|
+
# "path": "/apps/Backups/apitest/movies/1.mkv",
|
351
|
+
# "ctime": 1377136220,
|
352
|
+
# "mtime": 1384493344,
|
353
|
+
# "md5": "6366d2a234e8139c63dab707ec4569c3",
|
354
|
+
# "size": 74818037,
|
355
|
+
# "isdir": 0
|
356
|
+
# }
|
357
|
+
# ],
|
358
|
+
# "request_id": 4043312670
|
359
|
+
# }
|
360
|
+
#
|
361
|
+
# :fs_id 文件或目录在PCS的临时唯一标识id
|
362
|
+
# :path 文件或目录的绝对路径
|
363
|
+
# :ctime 文件或目录的创建时间
|
364
|
+
# :mtime 文件或目录的最后修改时间
|
365
|
+
# :md5 文件的md5值
|
366
|
+
# :size 文件大小(byte)
|
367
|
+
# :isdir 是否是目录的标识符:“0”为文件,“1”为目录
|
368
|
+
#
|
369
|
+
# @param path [String] 需要list的目录(相对于应用的根目录)
|
370
|
+
#
|
371
|
+
# @option options [String] :by 排序字段,缺省根据文件名排序:
|
372
|
+
# +time+(修改时间),
|
373
|
+
# +name+(文件名),
|
374
|
+
# +size+(大小,注意目录无大小)
|
375
|
+
# @option options [String] :order “+asc+”或“+desc+”,缺省采用降序排序:
|
376
|
+
# +asc+(升序),
|
377
|
+
# +desc+(降序)
|
378
|
+
# @option options [String] :limit 返回条目控制,参数格式为:n1-n2。
|
379
|
+
# 返回结果集的[n1, n2)之间的条目,缺省返回所有条目;n1从0开始
|
380
|
+
# @return [Hash]
|
381
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E8.8E.B7.E5.8F.96.E7.9B.AE.E5.BD.95.E4.B8.8B.E7.9A.84.E6.96.87.E4.BB.B6.E5.88.97.E8.A1.A8 获取目录下的文件列表
|
382
|
+
def list(path, options={})
|
383
|
+
query = { path: build_path(path) }
|
384
|
+
query[:by] = options[:by] || 'name'
|
385
|
+
query[:order] = options[:order] || 'desc'
|
386
|
+
query[:limit] = options[:limit]
|
387
|
+
get "#{BASE_PATH}/file", query.update(base_query 'list')
|
388
|
+
end
|
389
|
+
|
390
|
+
# 单个或批量移动文件/目录
|
391
|
+
#
|
392
|
+
# @example 返回的原始 JSON
|
393
|
+
# {
|
394
|
+
# "extra": {
|
395
|
+
# "list": [
|
396
|
+
# {
|
397
|
+
# "to": "/apps/album/test2/2.jpg",
|
398
|
+
# "from": "/apps/album/test1/1.jpg"
|
399
|
+
# }
|
400
|
+
# ]
|
401
|
+
# },
|
402
|
+
# "request_id": 2298812844
|
403
|
+
# }
|
404
|
+
#
|
405
|
+
# :from 执行move操作成功的源文件地址
|
406
|
+
# :to 执行move操作成功的目标文件地址
|
407
|
+
#
|
408
|
+
# @overload move(from, to)
|
409
|
+
# 移动单个文件/目录
|
410
|
+
# @note 调用move接口时,目标文件的名称如果和源文件不相同,将会在move操作时对文件进行重命名
|
411
|
+
# @param from [String] 源文件地址(包括文件名,相对于应用根目录)
|
412
|
+
# @param to [String] 目标文件地址(包括文件名,相对于应用根目录)
|
413
|
+
# @return [Hash] 如果move操作执行成功,那么response会返回执行成功的from/to列表
|
414
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E7.A7.BB.E5.8A.A8.E5.8D.95.E4.B8.AA.E6.96.87.E4.BB.B6.2F.E7.9B.AE.E5.BD.95 移动单个文件/目录
|
415
|
+
#
|
416
|
+
# @overload move(froms, tos)
|
417
|
+
# 批量移动文件/目录
|
418
|
+
# @note 批量执行move操作时,move接口一次对请求参数中的每个from/to进行操作;执行失败就会退出,成功就继续,返回执行成功的from/to列表
|
419
|
+
# @param froms [Array<String>] 源文件地址(包括文件名,相对于应用根目录)
|
420
|
+
# @param tos [Array<String>] 目标文件地址(包括文件名,相对于应用根目录)
|
421
|
+
# @return [Hash] 返回参数extra由list数组组成,list数组的两个元素分别是“from”和“to”,代表move操作的源地址和目的地址
|
422
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E6.89.B9.E9.87.8F.E7.A7.BB.E5.8A.A8.E6.96.87.E4.BB.B6.2F.E7.9B.AE.E5.BD.95 批量移动文件/目录
|
423
|
+
#
|
424
|
+
# @return [Hash]
|
425
|
+
def move(from, to)
|
426
|
+
move_or_copy :move, from, to
|
427
|
+
end
|
428
|
+
|
429
|
+
# 单个或批量拷贝文件/目录
|
430
|
+
#
|
431
|
+
# @example 返回的原始 JSON
|
432
|
+
# {
|
433
|
+
# "extra": {
|
434
|
+
# "list": [
|
435
|
+
# {
|
436
|
+
# "to": "/apps/album/test2/6.jpg",
|
437
|
+
# "from": "/apps/album/test1/6.jpg"
|
438
|
+
# }
|
439
|
+
# ]
|
440
|
+
# },
|
441
|
+
# "request_id": 2298812844
|
442
|
+
# }
|
443
|
+
#
|
444
|
+
# :from 执行copy操作成功的源文件地址
|
445
|
+
# :to 执行copy操作成功的目标文件地址
|
446
|
+
#
|
447
|
+
# @overload copy(from, to)
|
448
|
+
# 拷贝单个文件/目录
|
449
|
+
# @note move操作后,源文件被移动至目标地址;copy操作则会保留原文件
|
450
|
+
# @param from [String] 源文件地址(包括文件名,相对于应用根目录)
|
451
|
+
# @param to [String] 目标文件地址(包括文件名,相对于应用根目录)
|
452
|
+
# @return [Hash] 如果copy操作执行成功,那么response会返回执行成功的from/to列表
|
453
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E6.8B.B7.E8.B4.9D.E5.8D.95.E4.B8.AA.E6.96.87.E4.BB.B6.2F.E7.9B.AE.E5.BD.95 拷贝单个文件/目录
|
454
|
+
#
|
455
|
+
# @overload copy(froms, tos)
|
456
|
+
# 批量拷贝文件/目录
|
457
|
+
# @note 批量执行copy操作时,copy接口一次对请求参数中的每个from/to进行操作;执行失败就会退出,成功就继续,返回执行成功的from/to列表
|
458
|
+
# @param froms [Array<String>] 源文件地址(相对于应用根目录)
|
459
|
+
# @param tos [Array<String>] 目标文件地址(相对于应用根目录)
|
460
|
+
# @return [Hash] 返回参数extra由list数组组成,list数组的两个元素分别是“from”和“to”,代表copy操作的源地址和目的地址
|
461
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E6.89.B9.E9.87.8F.E6.8B.B7.E8.B4.9D.E6.96.87.E4.BB.B6.2F.E7.9B.AE.E5.BD.95 批量拷贝文件/目录
|
462
|
+
#
|
463
|
+
# @return [Hash]
|
464
|
+
def copy(from, to)
|
465
|
+
move_or_copy :copy, from, to
|
466
|
+
end
|
467
|
+
|
468
|
+
# 单个或批量删除文件/目录
|
469
|
+
# @note 文件/目录删除后默认临时存放在回收站内,删除文件或目录的临时存放不占用用户的空间配额;
|
470
|
+
# 存放有效期为10天,10天内可还原回原路径下,10天后则永久删除
|
471
|
+
#
|
472
|
+
# @example 返回的原始 JSON
|
473
|
+
# {"request_id":4043312866}
|
474
|
+
#
|
475
|
+
# @overload delete(path)
|
476
|
+
# 删除单个文件/目录
|
477
|
+
# @param path [String] 需要删除的文件或者目录路径
|
478
|
+
# @return [Hash]
|
479
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E5.88.A0.E9.99.A4.E5.8D.95.E4.B8.AA.E6.96.87.E4.BB.B6.2F.E7.9B.AE.E5.BD.95 删除单个文件/目录
|
480
|
+
#
|
481
|
+
# @overload delete(paths)
|
482
|
+
# 批量删除文件/目录
|
483
|
+
# @param paths [Array<String>] 需要删除的文件或者目录路径
|
484
|
+
# @return [Hash]
|
485
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E6.89.B9.E9.87.8F.E5.88.A0.E9.99.A4.E6.96.87.E4.BB.B6.2F.E7.9B.AE.E5.BD.95 批量删除文件/目录
|
486
|
+
#
|
487
|
+
# @return [Hash]
|
488
|
+
def delete(path)
|
489
|
+
meta_or_delete :delete, path
|
490
|
+
end
|
491
|
+
|
492
|
+
# 按文件名搜索文件
|
493
|
+
# @note 不支持查找目录
|
494
|
+
#
|
495
|
+
# @example 返回的原始 JSON
|
496
|
+
# {
|
497
|
+
# "list": [
|
498
|
+
# {
|
499
|
+
# "fs_id": 3528850315,
|
500
|
+
# "path": "/apps/album/music/hello",
|
501
|
+
# "ctime": 1331184269,
|
502
|
+
# "mtime": 1331184269,
|
503
|
+
# "block_list": [
|
504
|
+
# "59ca0efa9f5633cb0371bbc0355478d8"
|
505
|
+
# ],
|
506
|
+
# "size": 13,
|
507
|
+
# "isdir": 0
|
508
|
+
# }
|
509
|
+
# ],
|
510
|
+
# "request_id": 4043312670
|
511
|
+
# }
|
512
|
+
#
|
513
|
+
# :fs_id 目录在PCS的临时唯一标识ID。
|
514
|
+
# :path 该目录的绝对路径。
|
515
|
+
# :ctime 文件服务器创建时间。
|
516
|
+
# :mtime 文件服务器修改时间。
|
517
|
+
# :md5 文件的md5值。
|
518
|
+
# :size 文件大小(byte)。
|
519
|
+
# :isdir 是否是目录的标识符:“0”为文件,“1”为目录
|
520
|
+
#
|
521
|
+
# @param path [String] 需要检索的目录(相对于应用根目录)
|
522
|
+
# @param wd [String] 关键词
|
523
|
+
# @param re [Boolean] 是否递归:+true+ 表示递归,+false+ 表示不递归
|
524
|
+
# @return [Hash]
|
525
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E6.90.9C.E7.B4.A2 搜索
|
526
|
+
def search(path, wd, re=false)
|
527
|
+
path = build_path path
|
528
|
+
query = { path: path, wd: wd, re: (re ? 1 : 0) }
|
529
|
+
get "#{BASE_PATH}/file", query.update(base_query 'search')
|
530
|
+
end
|
531
|
+
|
532
|
+
# @!endgroup
|
533
|
+
|
534
|
+
# @!group 2 高级功能
|
535
|
+
|
536
|
+
# 获取指定图片文件的缩略图
|
537
|
+
# @note 限制条件:
|
538
|
+
# 原图大小(0, 10M];
|
539
|
+
# 原图类型: jpg、jpeg、bmp、gif、png;
|
540
|
+
# 目标图类型和原图的类型有关;例如:原图是gif图片,则缩略后也为gif图片
|
541
|
+
# @param path [String] 源图片的路径(相对于应用根目录)
|
542
|
+
# @param width [Fixnum] 指定缩略图的宽度,取值范围为(0,1600]
|
543
|
+
# @param height [Fixnum] 指定缩略图的高度,取值范围为(0,1600]
|
544
|
+
# @param quality [Fixnum] 缩略图的质量,默认为“100”,取值范围(0,100]
|
545
|
+
#
|
546
|
+
# @overload thumbnail(path, width, height, quality=100)
|
547
|
+
# @example
|
548
|
+
# File.open('logo_120.png', 'w') do |f|
|
549
|
+
# f.write client.thumbnail('logo.png', 120, 120)
|
550
|
+
# end
|
551
|
+
# @return [String] 缩略图文件内容
|
552
|
+
#
|
553
|
+
# @overload thumbnail(path, width, height, quality=100, &block)
|
554
|
+
# 使用 block 方式,减少内存占用率
|
555
|
+
# @example
|
556
|
+
# File.open('logo_1600.png', 'w') do |f|
|
557
|
+
# client.thumbnail('logo.png', 1600, 1600) do |segment|
|
558
|
+
# f.write segment
|
559
|
+
# end
|
560
|
+
# end
|
561
|
+
# @yield [segment] 内容将以片段的方式提供
|
562
|
+
# @return [void]
|
563
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E7.BC.A9.E7.95.A5.E5.9B.BE 缩略图
|
564
|
+
# @see #download
|
565
|
+
def thumbnail(path, width, height, quality=100, &block)
|
566
|
+
path = build_path path
|
567
|
+
query = { path: path, width: width, height: height, quality: quality }.update base_query('generate')
|
568
|
+
if block_given?
|
569
|
+
get "#{BASE_PATH}/thumbnail", query, &block
|
570
|
+
else
|
571
|
+
get "#{BASE_PATH}/thumbnail", query, raw: true
|
572
|
+
end
|
573
|
+
end
|
574
|
+
|
575
|
+
# 文件增量更新操作查询
|
576
|
+
# @note 本接口有数秒延迟,但保证返回结果为最终一致
|
577
|
+
#
|
578
|
+
# @example 返回的原始 JSON
|
579
|
+
# {
|
580
|
+
# "entries": {
|
581
|
+
# "/apps/album/6.png": {
|
582
|
+
# "fs_id": 3858723392,
|
583
|
+
# "path": "/apps/album/6.png",
|
584
|
+
# "size": 4914,
|
585
|
+
# "isdir": 0,
|
586
|
+
# "isdelete": 0,
|
587
|
+
# "revision": 0,
|
588
|
+
# "md5": "6c37219ba0d3dfdfa95ff6912e2c42b9",
|
589
|
+
# "mtime": 1384526979,
|
590
|
+
# "ctime": 1384526979
|
591
|
+
# },
|
592
|
+
# "/apps/ablum/logo.png": {
|
593
|
+
# "fs_id": 3866920660,
|
594
|
+
# "path": "/apps/album/logo.png",
|
595
|
+
# "size": 4914,
|
596
|
+
# "isdir": 0,
|
597
|
+
# "isdelete": 0,
|
598
|
+
# "revision": 0,
|
599
|
+
# "md5": "6c37219ba0d3dfdfa95ff6912e2c42b9",
|
600
|
+
# "mtime": 1384486230,
|
601
|
+
# "ctime": 1384021638
|
602
|
+
# }
|
603
|
+
# },
|
604
|
+
# "has_more": true,
|
605
|
+
# "reset": true,
|
606
|
+
# "cursor": "MxKx6UPie%2F9WzBkwALPrVWQlyxlmK0LgHG8zutwXp8oyC%2F2BQ%3D%3D...",
|
607
|
+
# "request_id": 3355443548
|
608
|
+
# }
|
609
|
+
#
|
610
|
+
# :entries k-v形式的列表,分为以下两种形式:
|
611
|
+
# 1. key为path,value为path对应的meta值,meta中isdelete=0为更新操作
|
612
|
+
# 如果path为文件,则更新path对应的文件;
|
613
|
+
# 如果path为目录,则更新path对应的目录信息,但不更新path下的文件。
|
614
|
+
# 2. key为path,value为path删除的meta信息,meta中“isdelete!=0”为删除操作
|
615
|
+
# isdelete=1 该文件被永久删除;
|
616
|
+
# isdelete=-1 该文件被放置进回收站;
|
617
|
+
# 如果path为文件,则删除该path对应的文件;
|
618
|
+
# 如果path为目录,则删除该path对应的目录和目录下的所有子目录和文件;
|
619
|
+
# 如果path在本地没有任何记录,则跳过本删除操作。
|
620
|
+
# :has_more True: 本次调用diff接口,增量更新结果服务器端无法一次性返回,客户端可以立刻再调用一次diff接口获取剩余结果;
|
621
|
+
# False: 截止当前的增量更新结果已经全部返回,客户端可以等待一段时间(1-2分钟)之后再diff一次查看是否有更新。
|
622
|
+
# :reset True: 服务器通知客户端,服务器端将按时间排序从第一条开始向客户端返回一份完整的数据列表;
|
623
|
+
# False:返回上次请求返回cursor之后的增量更新结果。
|
624
|
+
# :cursor 用于下一次调用diff接口时传入的断点参数。
|
625
|
+
#
|
626
|
+
# @param cursor [String] 用于标记更新断点:
|
627
|
+
# 首次调用cursor=null;
|
628
|
+
# 非首次调用,使用最后一次调用diff接口的返回结果中的cursor
|
629
|
+
# @return [Hash]
|
630
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E5.A2.9E.E9.87.8F.E6.9B.B4.E6.96.B0.E6.9F.A5.E8.AF.A2 增量更新查询
|
631
|
+
def diff(cursor='null')
|
632
|
+
query = { cursor: cursor }
|
633
|
+
get "#{BASE_PATH}/file", query.update(base_query 'diff')
|
634
|
+
end
|
635
|
+
|
636
|
+
# 视频转码
|
637
|
+
#
|
638
|
+
# 对视频文件进行转码,实现实时观看视频功能。可下载支持HLS/M3U8的媒体云播放器SDK配合使用。
|
639
|
+
# @note 目前这个接口支持的源文件格式如下:m3u8/m3u/asf/avi/flv/gif/mkv/mov/mp4/m4a/3gp/3g2/mj2/mpeg/ts/rm/rmvb/webm
|
640
|
+
# @param path [String] 需要下载的视频文件路径,需含源文件的文件名(相对于应用根目录)
|
641
|
+
# @param type [String] 目前支持以下格式:M3U8_320_240、M3U8_480_224、M3U8_480_360、M3U8_640_480和M3U8_854_480
|
642
|
+
# @return [String] 直接返回文件内容(在线播放的 URL 地址清单)
|
643
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E8.A7.86.E9.A2.91.E8.BD.AC.E7.A0.81 视频转码
|
644
|
+
def streaming(path, type, &block)
|
645
|
+
path = build_path path
|
646
|
+
query = { path: path, type: type }.update base_query('streaming')
|
647
|
+
if block_given?
|
648
|
+
get "#{BASE_PATH}/file", query, &block
|
649
|
+
else
|
650
|
+
get "#{BASE_PATH}/file", query, raw: true
|
651
|
+
end
|
652
|
+
end
|
653
|
+
|
654
|
+
# 获取流式文件列表
|
655
|
+
#
|
656
|
+
# 以视频、音频、图片及文档四种类型的视图获取所创建应用程序下的文件列表。
|
657
|
+
#
|
658
|
+
# @example 返回的原始 JSON
|
659
|
+
# {
|
660
|
+
# "total": 13,
|
661
|
+
# "start": 0,
|
662
|
+
# "limit": 1,
|
663
|
+
# "list": [
|
664
|
+
# {
|
665
|
+
# "path": "/apps/album/1.jpg",
|
666
|
+
# "size": 372121,
|
667
|
+
# "ctime": 1234567890,
|
668
|
+
# "mtime": 1234567890,
|
669
|
+
# "md5": "cb123afcc12453543ef",
|
670
|
+
# "fs_id": 12345,
|
671
|
+
# "isdir": 0
|
672
|
+
# }
|
673
|
+
# ]
|
674
|
+
# }
|
675
|
+
#
|
676
|
+
# :total 文件总数
|
677
|
+
# :start 起始数
|
678
|
+
# :limit 获取数
|
679
|
+
# :path 获取流式文件的绝对路径
|
680
|
+
# :block_list 分片MD5列表
|
681
|
+
# :size 流式文件的文件大小(byte)
|
682
|
+
# :mtime 流式文件在服务器上的修改时间
|
683
|
+
# :ctime 流式文件在服务器上的创建时间
|
684
|
+
# :fs_id 流式文件在PCS中的唯一标识ID
|
685
|
+
# :isdir “0”文件,“1”目录
|
686
|
+
#
|
687
|
+
# @param type [String] 类型分为video、audio、image及doc四种
|
688
|
+
# @option options [Fixnum] :start 返回条目控制起始值,默认为0
|
689
|
+
# @option options [Fixnum] :limit 返回条目控制长度,默认为1000
|
690
|
+
# @option options [String] :filter_path 需要过滤的前缀路径,如:/apps/album
|
691
|
+
# @return [Hash]
|
692
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E8.8E.B7.E5.8F.96.E6.B5.81.E5.BC.8F.E6.96.87.E4.BB.B6.E5.88.97.E8.A1.A8 获取流式文件列表
|
693
|
+
def stream_list(type, options={})
|
694
|
+
query = { type: type }.update options
|
695
|
+
get "#{BASE_PATH}/stream", query.update(base_query 'list')
|
696
|
+
end
|
697
|
+
|
698
|
+
# 秒传文件
|
699
|
+
# @note 被秒传文件必须大于256KB(即 256*1024 B);校验段为文件的前256KB,秒传接口需要提供校验段的MD5。
|
700
|
+
# @note 非强一致接口,上传后请等待1秒后再读取
|
701
|
+
#
|
702
|
+
# @example 返回的原始 JSON
|
703
|
+
# {
|
704
|
+
# "path": "/apps/album/1.jpg",
|
705
|
+
# "size": 372121,
|
706
|
+
# "ctime": 1234567890,
|
707
|
+
# "mtime": 1234567890,
|
708
|
+
# "md5": "cb123afcc12453543ef",
|
709
|
+
# "fs_id": 12345,
|
710
|
+
# "isdir": 0,
|
711
|
+
# "request_id": 12314124
|
712
|
+
# }
|
713
|
+
# :path 秒传文件的绝对路径
|
714
|
+
# :size 秒传文件的字节大小
|
715
|
+
# :ctime 秒传文件的创建时间。
|
716
|
+
# :mtime 秒传文件的修改时间
|
717
|
+
# :md5 秒传文件的md5签名
|
718
|
+
# :fs_id 秒传文件在PCS的唯一标识ID
|
719
|
+
# :isdir “0”文件 “1”目录
|
720
|
+
#
|
721
|
+
# @param path [String] 上传文件的全路径名(相对于应用根目录)
|
722
|
+
# @param content_length [Fixnum] 待秒传的文件长度
|
723
|
+
# @param content_md5 [String] 待秒传的文件的MD5
|
724
|
+
# @param slice_md5 [String] 待秒传文件校验段的MD5
|
725
|
+
# @param content_crc32 [String] 待秒传文件校验段的MD5
|
726
|
+
# @param overwrite [Boolean] +true+: 表示覆盖同名文件,+false+:表示生成文件副本并进行重命名,命名规则为“文件名_日期.后缀”
|
727
|
+
# @return [Hash]
|
728
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E7.A7.92.E4.BC.A0.E6.96.87.E4.BB.B6a 秒传文件
|
729
|
+
def rapid_upload(path, content_length, content_md5, slice_md5, content_crc32, overwrite=false)
|
730
|
+
path = build_path path, true
|
731
|
+
query = { :path => path,
|
732
|
+
:'content-length' => content_length,
|
733
|
+
:'content-md5' => content_md5,
|
734
|
+
:'slice-md5' => slice_md5,
|
735
|
+
:'content-crc32' => content_crc32 }
|
736
|
+
query[:ondup] = overwrite ? 'overwrite' : 'newcopy'
|
737
|
+
post "#{BASE_PATH}/file", query.update(base_query 'rapidupload')
|
738
|
+
end
|
739
|
+
|
740
|
+
# 添加离线下载任务,实现单个文件离线下载
|
741
|
+
#
|
742
|
+
# @example 返回的原始 JSON
|
743
|
+
# {"task_id":432432432432432,"request_id":3372220525}
|
744
|
+
#
|
745
|
+
# :task_id 任务ID号
|
746
|
+
#
|
747
|
+
# @param source_url [String] 源文件的URL
|
748
|
+
# @option options :save_path [String] 下载后的文件保存路径(相对于应用根目录)
|
749
|
+
# 如果未指定则获取源文件的URL名称,如果获取失败则使用当前时间
|
750
|
+
# @option options :timeout [Fixnum] 下载超时时间
|
751
|
+
# @option options :expires [Fixnum] 请求失效时间,如果有,则会校验
|
752
|
+
# @option options :rate_limit [Fixnum] 下载限速,默认不限速
|
753
|
+
# @option options :callback [String] 下载完毕后的回调
|
754
|
+
# @return [Hash]
|
755
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E6.B7.BB.E5.8A.A0.E7.A6.BB.E7.BA.BF.E4.B8.8B.E8.BD.BD.E4.BB.BB.E5.8A.A1 添加离线下载任务
|
756
|
+
def add_task(source_url, options={})
|
757
|
+
query = { source_url: source_url }
|
758
|
+
query[:timeout] = options.delete(:timeout) || 3600
|
759
|
+
save_path = options.delete(:save_path)
|
760
|
+
unless save_path
|
761
|
+
save_path = URI(source_url).path.split('/').last || Time.now.localtime.to_s
|
762
|
+
end
|
763
|
+
save_path = build_path save_path, true
|
764
|
+
query[:save_path] = save_path
|
765
|
+
query.update options
|
766
|
+
post "#{BASE_PATH}/services/cloud_dl", query.update(base_query 'add_task')
|
767
|
+
end
|
768
|
+
|
769
|
+
# 精确查询离线下载任务
|
770
|
+
#
|
771
|
+
# 根据任务ID号,查询离线下载任务信息及进度信息
|
772
|
+
#
|
773
|
+
# @example 查询进度信息,返回的原始 JSON
|
774
|
+
# {
|
775
|
+
# "task_info": {
|
776
|
+
# "23998044": {
|
777
|
+
# "create_time": "1384703711",
|
778
|
+
# "start_time": "1384703711",
|
779
|
+
# "finish_time": "1384703717",
|
780
|
+
# "file_size": "0",
|
781
|
+
# "finished_size": "0",
|
782
|
+
# "task_name": "1.dmg",
|
783
|
+
# "save_path": "/apps/album/1.dmg",
|
784
|
+
# "source_url": "https://example.com/1.dmg",
|
785
|
+
# "status": "1",
|
786
|
+
# "result": 0
|
787
|
+
# }
|
788
|
+
# },
|
789
|
+
# "request_id": 631260401
|
790
|
+
# }
|
791
|
+
#
|
792
|
+
# :result 0查询成功,结果有效,1要查询的task_id不存在
|
793
|
+
# :status 0下载成功,1下载进行中 2系统错误,3资源不存在,4下载超时,
|
794
|
+
# 5资源存在但下载失败 6存储空间不足 7任务取消
|
795
|
+
# :status status为0、1时,其余字段有效
|
796
|
+
#
|
797
|
+
# @example 查询任务信息,返回的原始 JSON
|
798
|
+
# {
|
799
|
+
# "task_info": {
|
800
|
+
# "23654044": {
|
801
|
+
# "source_url": "https://example.com/1.dmg",
|
802
|
+
# "finished_size": "0",
|
803
|
+
# "save_path": "/apps/album/1.dmg",
|
804
|
+
# "rate_limit": "0",
|
805
|
+
# "timeout": "3600",
|
806
|
+
# "callback": "",
|
807
|
+
# "status": "7",
|
808
|
+
# "create_time": "1384703711",
|
809
|
+
# "task_name": "1.dmg",
|
810
|
+
# "od_type": "0",
|
811
|
+
# "result": 0
|
812
|
+
# }
|
813
|
+
# },
|
814
|
+
# "request_id": 689959608
|
815
|
+
# }
|
816
|
+
#
|
817
|
+
# :result 0查询成功,结果有效,1要查询的task_id不存在
|
818
|
+
# :source_url 下载数据源地址
|
819
|
+
# :save_path 下载完成后的存放地址
|
820
|
+
# :status 0下载成功,1下载进行中 2系统错误,3资源不存在,4下载超时,
|
821
|
+
# 5资源存在但下载失败 6存储空间不足 7目标地址数据已存在 8任务取消
|
822
|
+
# :create_time 任务创建时间
|
823
|
+
#
|
824
|
+
# @overload query_task(task_id, options={})
|
825
|
+
# @param task_id [String] 要查询的任务ID
|
826
|
+
# @return [Hash]
|
827
|
+
#
|
828
|
+
# @overload query_task(task_ids, options={})
|
829
|
+
# @param task_ids [Array<String>] 要查询的任务ID
|
830
|
+
# @return [Hash]
|
831
|
+
#
|
832
|
+
# @option options [Fixnum] :op_type 0:查任务信息;1:查进度信息;默认为1
|
833
|
+
# @option options [Fixnum] :expires 请求失效时间,如果有,则会校验
|
834
|
+
# @return [Hash]
|
835
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E7.B2.BE.E7.A1.AE.E6.9F.A5.E8.AF.A2.E7.A6.BB.E7.BA.BF.E4.B8.8B.E8.BD.BD.E4.BB.BB.E5.8A.A1 精确查询离线下载任务
|
836
|
+
def query_task(task_ids, options={})
|
837
|
+
task_ids = task_ids.join(',') if task_ids.is_a? Array
|
838
|
+
query = { task_ids: task_ids }.update options
|
839
|
+
post "#{BASE_PATH}/services/cloud_dl", query.update(base_query 'query_task')
|
840
|
+
end
|
841
|
+
|
842
|
+
# 查询离线下载任务列表
|
843
|
+
#
|
844
|
+
# 查询离线下载任务ID列表及任务信息
|
845
|
+
#
|
846
|
+
# @example 不包含任务信息,返回的原始 JSON
|
847
|
+
# {"task_info":[{"task_id":"26"}, {"task_id":"27"}],"total":"2","request_id":1283164486}
|
848
|
+
#
|
849
|
+
# @example 包含任务信息,返回的原始 JSON
|
850
|
+
# {
|
851
|
+
# "task_info": [
|
852
|
+
# {
|
853
|
+
# "task_id": "26",
|
854
|
+
# "source_url": "https://example.com/1.dmg",
|
855
|
+
# "save_path": "/apps/album/1.dmg",
|
856
|
+
# "rate_limit": "100",
|
857
|
+
# "timeout": "10000",
|
858
|
+
# "callback": "",
|
859
|
+
# "status": "1",
|
860
|
+
# "create_time": "1347449048"
|
861
|
+
# }
|
862
|
+
# ],
|
863
|
+
# "total": "1",
|
864
|
+
# "request_id": 1285732167
|
865
|
+
# }
|
866
|
+
#
|
867
|
+
# @param [Hash] options 皆为可选参数
|
868
|
+
# @option options [Fixnum] :start 查询任务起始位置,默认为0
|
869
|
+
# @option options [Fixnum] :limit 设定返回任务数量,默认为10
|
870
|
+
# @option options [Fixnum] :asc 0:降序;1:升序;默认为0
|
871
|
+
# @option options [Fixnum] :need_task_info 是否需要返回任务信息:0:不需要;1:需要;默认为1
|
872
|
+
# @option options [Fixnum] :status 任务状态
|
873
|
+
# @option options [Fixnum] :create_time 任务创建时间,note:此参数似乎无效
|
874
|
+
# @option options [String] :source_url 源地址URL
|
875
|
+
# @option options [String] :save_path 文件保存路径(相对于应用根目录)
|
876
|
+
# @option options [Fixnum] :expires 请求失效时间,如果有,则会校验
|
877
|
+
# @return [Hash]
|
878
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E6.9F.A5.E8.AF.A2.E7.A6.BB.E7.BA.BF.E4.B8.8B.E8.BD.BD.E4.BB.BB.E5.8A.A1.E5.88.97.E8.A1.A8 查询离线下载任务列表
|
879
|
+
def list_task(options={})
|
880
|
+
query = options.dup
|
881
|
+
post "#{BASE_PATH}/services/cloud_dl", query.update(base_query 'list_task')
|
882
|
+
end
|
883
|
+
|
884
|
+
# 取消离线下载任务
|
885
|
+
#
|
886
|
+
# @example 返回的原始 JSON
|
887
|
+
# {"request_id":12394838223}
|
888
|
+
#
|
889
|
+
# @param task_id [String] 要取消的任务ID号
|
890
|
+
# @param expires [Fixnum] 请求失效时间,如果有,则会校验
|
891
|
+
# @return [Hash]
|
892
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E5.8F.96.E6.B6.88.E7.A6.BB.E7.BA.BF.E4.B8.8B.E8.BD.BD.E4.BB.BB.E5.8A.A1 取消离线下载任务
|
893
|
+
def cancel_task(task_id, expires=nil)
|
894
|
+
query = { task_id: task_id, expires: expires }
|
895
|
+
post "#{BASE_PATH}/services/cloud_dl", query.update(base_query 'cancel_task')
|
896
|
+
end
|
897
|
+
|
898
|
+
# @!endgroup
|
899
|
+
|
900
|
+
# @!group 3 回收站
|
901
|
+
|
902
|
+
# 查询回收站文件
|
903
|
+
#
|
904
|
+
# 获取回收站中的文件及目录列表
|
905
|
+
#
|
906
|
+
# @example 返回的原始 JSON
|
907
|
+
# {
|
908
|
+
# "list": [
|
909
|
+
# {
|
910
|
+
# "fs_id": 1579174,
|
911
|
+
# "path": "/apps/album/2.7z",
|
912
|
+
# "ctime": 1361934614,
|
913
|
+
# "mtime": 1361934625,
|
914
|
+
# "md5": "1131170ac11cfbec411a5e8d4e111769",
|
915
|
+
# "size": 10730431,
|
916
|
+
# "isdir": 0
|
917
|
+
# },
|
918
|
+
# {
|
919
|
+
# "fs_id": 304521061,
|
920
|
+
# "path": "/apps/album/3.7z",
|
921
|
+
# "ctime": 1361934605,
|
922
|
+
# "mtime": 1361934625,
|
923
|
+
# "md5": "9552bf5e5abdf962e2de94be243bec7c",
|
924
|
+
# "size": 4287611,
|
925
|
+
# "isdir": 0
|
926
|
+
# }
|
927
|
+
# ],
|
928
|
+
# "request_id": 3779302504
|
929
|
+
# }
|
930
|
+
#
|
931
|
+
# :fs_id 目录在PCS上的临时唯一标识
|
932
|
+
# :path 该目录的绝对路径
|
933
|
+
# :ctime 文件在服务器上的创建时间
|
934
|
+
# :mtime 文件在服务器上的修改时间
|
935
|
+
# :md5 分片MD5
|
936
|
+
# :size 文件大小(byte)
|
937
|
+
# :isdir 是否是目录的标识符:
|
938
|
+
#
|
939
|
+
# @param start [Fixnum] 返回条目的起始值
|
940
|
+
# @param limit [Fixnum] 返回条目的长度
|
941
|
+
# @return [Hash]
|
942
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E6.9F.A5.E8.AF.A2.E5.9B.9E.E6.94.B6.E7.AB.99.E6.96.87.E4.BB.B6 查询回收站文件
|
943
|
+
def listrecycle(start=0, limit=1000)
|
944
|
+
query = { start:start, limit: limit }
|
945
|
+
get "#{BASE_PATH}/file", query.update(base_query 'listrecycle')
|
946
|
+
end
|
947
|
+
|
948
|
+
# 单个或批量还原文件/目录
|
949
|
+
# @note 非强一致接口,调用后请sleep 1秒读取
|
950
|
+
# @overload restore(fs_id)
|
951
|
+
# 还原单个文件或目录
|
952
|
+
#
|
953
|
+
# @example 还原成功返回的原始 JSON
|
954
|
+
# {"extra":{"list":[{"fs_id":"1356099017"}]},"request_id":3775323016}
|
955
|
+
#
|
956
|
+
# @param [String] fs_id 所还原的文件或目录在PCS的临时唯一标识ID
|
957
|
+
# @return [Hash]
|
958
|
+
#
|
959
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E8.BF.98.E5.8E.9F.E5.8D.95.E4.B8.AA.E6.96.87.E4.BB.B6.E6.88.96.E7.9B.AE.E5.BD.95 还原单个文件或目录
|
960
|
+
#
|
961
|
+
# @overload restore(fs_ids)
|
962
|
+
# 批量还原文件或目录
|
963
|
+
#
|
964
|
+
# @example 全部还原成功返回的原始 JSON
|
965
|
+
# {"extra":{"list":[{"fs_id":"3275514389"}]},"request_id":3859098573}
|
966
|
+
# @example 部分还原成功返回的原始 JSON
|
967
|
+
# {"error_code":31078,"error_msg":"invalid fs id","extra":{"list":[{"fs_id":"706533300"}]},"request_id":3825218191}
|
968
|
+
# @example 全部还原失败返回的原始 JSON
|
969
|
+
# {"error_code":31078,"error_msg":"invalid fs id","extra":{"list":[]},"request_id":805400333}
|
970
|
+
#
|
971
|
+
# @param [Array<String>] fs_ids 所还原的文件或目录在PCS的临时唯一标识ID的数组
|
972
|
+
# @return [Hash]
|
973
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E6.89.B9.E9.87.8F.E8.BF.98.E5.8E.9F.E6.96.87.E4.BB.B6.E6.88.96.E7.9B.AE.E5.BD.95 批量还原文件或目录
|
974
|
+
#
|
975
|
+
# @return [Hash]
|
976
|
+
def restore(fs_ids)
|
977
|
+
query = case fs_ids
|
978
|
+
when String
|
979
|
+
{ fs_id: fs_ids }
|
980
|
+
when Array
|
981
|
+
fs_ids = fs_ids.map { |id| { fs_id: id } }
|
982
|
+
{ param: JSON.dump({ list: fs_ids }) }
|
983
|
+
else
|
984
|
+
raise ArgumentError, 'fs_id(s) must be kind of String or Array'
|
985
|
+
end
|
986
|
+
post "#{BASE_PATH}/file", query.update(base_query 'restore')
|
987
|
+
end
|
988
|
+
|
989
|
+
# 清空回收站
|
990
|
+
#
|
991
|
+
# @example 返回的原始 JSON
|
992
|
+
# {"request_id":2307473052}
|
993
|
+
#
|
994
|
+
# @return [Hash]
|
995
|
+
# @see http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list#.E6.B8.85.E7.A9.BA.E5.9B.9E.E6.94.B6.E7.AB.99 清空回收站
|
996
|
+
def empty
|
997
|
+
query = { type: 'recycle' }
|
998
|
+
post "#{BASE_PATH}/file", query.update(base_query 'delete')
|
999
|
+
end
|
1000
|
+
|
1001
|
+
# @!endgroup
|
1002
|
+
|
1003
|
+
private
|
1004
|
+
|
1005
|
+
def base_query(method)
|
1006
|
+
{ method: method, access_token: @access_token }
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
# 构建上传 query hash
|
1010
|
+
# 如果 +path+ 中包含 +"\\ ? | " > < : *"+, 则被替换为 +"_"+
|
1011
|
+
# 如果 +path+ 开头结尾包含 +"."+ 或 空白符, 则将被删除
|
1012
|
+
#
|
1013
|
+
# [method] api 中 method 的固定值
|
1014
|
+
# [path] 上传文件路径(含上传的文件名称)
|
1015
|
+
# [overwrite] +true+: 表示覆盖同名文件
|
1016
|
+
# +false+: 表示生成文件副本并进行重命名,命名规则为“文件名_日期.后缀”
|
1017
|
+
# [tmpfile] +true+: 表示使用分块上传,此时将忽略上述四个参数
|
1018
|
+
# +false+: 表示正常上传,不使用分块上传
|
1019
|
+
def build_upload_query(method, path, overwrite=false, tmpfile=false)
|
1020
|
+
if tmpfile
|
1021
|
+
query = { type: 'tmpfile' }
|
1022
|
+
else
|
1023
|
+
path = build_path path, true
|
1024
|
+
ondup = overwrite ? 'overwrite' : 'newcopy'
|
1025
|
+
query = { path: path, ondup: ondup }
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
#文档提醒:file需通过POST表单进行传递,其他参数则需通过query_string进行传递。
|
1029
|
+
query.update base_query(method)
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
def build_path(path, edit=false)
|
1033
|
+
if Util.blank? path
|
1034
|
+
raise ArgumentError, 'path must not be blank'
|
1035
|
+
end
|
1036
|
+
if path.bytesize > 1000
|
1037
|
+
raise ArgumentError, 'path length must not be greater than 1000'
|
1038
|
+
end
|
1039
|
+
path = Util.edit_path path if edit # edit path to meet api rule
|
1040
|
+
File.join @dir_path, path # add app path
|
1041
|
+
end
|
1042
|
+
|
1043
|
+
def with_retries(max_retry_times, waitsec)
|
1044
|
+
retry_times = 0
|
1045
|
+
begin
|
1046
|
+
yield
|
1047
|
+
rescue
|
1048
|
+
raise if (retry_times += 1) > max_retry_times
|
1049
|
+
sleep waitsec
|
1050
|
+
retry
|
1051
|
+
end
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
def move_or_copy(method, from, to)
|
1055
|
+
body = case from
|
1056
|
+
when String
|
1057
|
+
raise ArgumentError, 'from and to must have the same type' unless to.is_a? String
|
1058
|
+
from = build_path from
|
1059
|
+
to = build_path to, true
|
1060
|
+
{ from: from, to: to }
|
1061
|
+
when Array
|
1062
|
+
raise ArgumentError, 'from and to must have the same type' unless to.is_a? Array
|
1063
|
+
raise ArgumentError, 'from or to must not be empty' if from.empty? || to.empty?
|
1064
|
+
raise ArgumentError, 'from and to must have the same size' unless from.size == to.size
|
1065
|
+
list = []
|
1066
|
+
from.zip(to) { |arr| list << { from: build_path(arr[0]), to: build_path(arr[1], true) } }
|
1067
|
+
{ param: JSON.dump({ list: list }) }
|
1068
|
+
else
|
1069
|
+
raise ArgumentError, 'from and to must be kind of String or Array'
|
1070
|
+
end
|
1071
|
+
post "#{BASE_PATH}/file", base_query(method.to_s), body
|
1072
|
+
end
|
1073
|
+
|
1074
|
+
def meta_or_delete(method, path)
|
1075
|
+
query = case path
|
1076
|
+
when String
|
1077
|
+
path = build_path path
|
1078
|
+
{ path: path }
|
1079
|
+
when Array
|
1080
|
+
raise ArgumentError, 'path(s) must not be empty' if path.empty?
|
1081
|
+
paths = path.map { |p| { path: build_path(p) } }
|
1082
|
+
{ param: JSON.dump({ list: paths }) }
|
1083
|
+
else
|
1084
|
+
raise ArgumentError, 'path must be kind of String or Array'
|
1085
|
+
end
|
1086
|
+
get "#{BASE_PATH}/file", query.update(base_query method.to_s)
|
1087
|
+
end
|
1088
|
+
end
|
1089
|
+
end
|
1090
|
+
end
|