upyun 0.7.1 → 1.0.1
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 +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +14 -18
- data/.rspec +2 -0
- data/.travis.yml +11 -0
- data/Gemfile +2 -1
- data/{LICENSE → LICENSE.txt} +2 -2
- data/README.md +219 -14
- data/Rakefile +1 -1
- data/lib/upyun/form.rb +87 -0
- data/lib/upyun/rest.rb +132 -0
- data/lib/upyun/utils.rb +19 -0
- data/lib/upyun/version.rb +1 -1
- data/lib/upyun.rb +11 -12
- data/spec/spec_helper.rb +4 -0
- data/spec/upyun.jpg +0 -0
- data/spec/upyun_spec.rb +201 -0
- data/upyun.gemspec +25 -14
- metadata +100 -21
- data/lib/upyun/bucket.rb +0 -111
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3e728cd2f23654592cfaea37730c0ad780a31eea
|
4
|
+
data.tar.gz: 41572412bf3d5ea83525082d71851687605fc7bc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ec030a7fcc5ff6009b077d2408bfa945666bcbeebf49f0fc9fd33dfb2c8635c74e84baea60943bc23c6ba4fcef794d4b6e0aeae92b407be203fda37a32153b62
|
7
|
+
data.tar.gz: 8ad799d0272e685c803308c313bea67d75432331d9964416fba150b8802df9b6e3f8cc7b9b08d3bc97bbe45db111814f12509eabab79a8bd6599bbad7ab5ed83
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.gitignore
CHANGED
@@ -1,18 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
.
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
test/tmp
|
16
|
-
test/version_tmp
|
17
|
-
tmp
|
18
|
-
.DS_Store
|
1
|
+
/.bundle/
|
2
|
+
/.yardoc
|
3
|
+
/Gemfile.lock
|
4
|
+
/_yardoc/
|
5
|
+
/coverage/
|
6
|
+
/doc/
|
7
|
+
/pkg/
|
8
|
+
/spec/reports/
|
9
|
+
/tmp/
|
10
|
+
*.bundle
|
11
|
+
*.so
|
12
|
+
*.o
|
13
|
+
*.a
|
14
|
+
mkmf.log
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/{LICENSE → LICENSE.txt}
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c)
|
1
|
+
Copyright (c) 2014 jsvisa
|
2
2
|
|
3
3
|
MIT License
|
4
4
|
|
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
19
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
20
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
21
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,31 +1,236 @@
|
|
1
|
-
#
|
1
|
+
# UPYUN sdk for Ruby
|
2
|
+
[](https://rubygems.org/gems/upyun)
|
3
|
+
[](https://travis-ci.org/upyun/ruby-sdk)
|
4
|
+
[](https://coveralls.io/r/upyun/ruby-sdk)
|
2
5
|
|
3
|
-
|
6
|
+
[UPYUN](https://www.upyun.com) [Rest API](http://docs.upyun.com/api/rest_api/) 和 [Form API](http://docs.upyun.com/api/form_api/) 的 Ruby SDK !
|
4
7
|
|
5
|
-
## Installation
|
6
8
|
|
7
|
-
|
9
|
+
## 安装说明
|
8
10
|
|
9
|
-
|
11
|
+
*Gemfile* 中加入以下代码
|
10
12
|
|
11
|
-
|
13
|
+
```ruby
|
14
|
+
gem 'upyun'
|
15
|
+
```
|
16
|
+
|
17
|
+
然后执行:
|
12
18
|
|
13
19
|
$ bundle
|
14
20
|
|
15
|
-
|
21
|
+
或者可以手动安装:
|
16
22
|
|
17
23
|
$ gem install upyun
|
18
24
|
|
19
|
-
##
|
25
|
+
## 基本使用
|
26
|
+
|
27
|
+
### Rest API 使用
|
28
|
+
|
29
|
+
#### 初始化一个实例
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
require 'upyun'
|
33
|
+
|
34
|
+
upyun = Upyun::Rest.new('bucket', 'operator', 'password', 'endpoint')
|
35
|
+
```
|
36
|
+
|
37
|
+
其中,参数 `bucket` 为空间名称,`operator` 为授权操作员帐号, `password` 为授权操作员密码,必选。
|
38
|
+
|
39
|
+
参数 `endpoint` 为又拍云存储 API 接入点,根据国内的网络情况,又拍云存储 API 提供了电信、联通(网通)、移动(铁通)数个接入点,
|
40
|
+
在初始化时可由参数 `endpoint` 进行设置,详情查阅 [API 域名](http://docs.upyun.com/api/)。其可选的值有:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
Upyun::ED_AUTO # 自动判断最优线路
|
44
|
+
Upyun::ED_TELECOM # 电信接入点
|
45
|
+
Upyun::ED_UNION # 联通(网通)接入点
|
46
|
+
Upyun::ED_CMCC # 移动(铁通)接入点
|
47
|
+
```
|
48
|
+
|
49
|
+
默认设置为 `Upyun::ED_AUTO` ,但是我们推荐根据服务器网络状况,手动设置合理的接入点以获取最佳的访问速度。
|
50
|
+
同时,也可以在初始化一个实例之后通过:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
upyun.endpoint = Upyun::ED_CMCC
|
54
|
+
```
|
55
|
+
更改接入点。
|
56
|
+
|
57
|
+
#### 上传文件
|
58
|
+
|
59
|
+
默认使用 Upyun 基本 Header 头上传文件:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
upyun.put('/save/to/path', 'file or binary')
|
63
|
+
```
|
64
|
+
其中 `/save/to/path` 为文件保存路径, `file or binary` 为本机上文件路径或者文件内容。
|
65
|
+
**注:**
|
66
|
+
> 这里只指定了又拍云必选的 `Date`, `Content-Length` 两个 Header,其它 Header 信息均未指定
|
67
|
+
|
68
|
+
也可以使用 Upyun 定义的额外 Header 头上传文件,详情查阅 [Rest API](http://docs.upyun.com/api/rest_api/), 如:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
headers = {'Content-Type' => 'image/jpeg', 'x-gmkerl-type' => 'fix_width', 'x-gmkerl-value' => 1080}
|
72
|
+
upyun.put('/save/to/path', 'file or binary', headers)
|
73
|
+
```
|
74
|
+
|
75
|
+
上传成功返回 `true`,失败返回一个 `Hash` 结构: `{error: {code: code, message: message}}`,
|
76
|
+
其中 `code` 为又拍云返回的错误码, `message` 为错误信息。
|
77
|
+
|
78
|
+
|
79
|
+
#### 下载文件
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
file = upyun.get('/path/to/file')
|
83
|
+
```
|
84
|
+
|
85
|
+
下载成功返回文件信息,失败返回一个 `Hash`: `{error: {code: code, message: message}}`,
|
86
|
+
其中 `code` 为又拍云返回的错误码, `message` 为错误信息。
|
87
|
+
|
88
|
+
也可以指定保存路径,下载到的文件将写入到保存路径中:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
upyun.get('/path/to/file', 'saved/foo.png')
|
92
|
+
```
|
93
|
+
|
94
|
+
下载成功返回获取的文件长度。
|
95
|
+
|
96
|
+
|
97
|
+
#### 获取文件信息
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
upyun.getinfo('/path/to/file')
|
101
|
+
```
|
102
|
+
|
103
|
+
成功返回 `Hash` 结构:
|
104
|
+
|
105
|
+
```
|
106
|
+
{file_type: "file", file_size: 397190, file_date: 1415954066}
|
107
|
+
```
|
108
|
+
|
109
|
+
其中
|
110
|
+
|
111
|
+
* `:file_type` 说明是文件(`"file"`)还是目录(`"folder"`)
|
112
|
+
* `:file_size` 是文件的大小
|
113
|
+
* `:file_date` 是文件最后的更改时间。
|
114
|
+
|
115
|
+
失败返回一个 `Hash`: `{error: {code: code, message: message}}`。
|
116
|
+
|
117
|
+
|
118
|
+
#### 删除文件或者目录
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
upyun.delete('/path/to/file')
|
122
|
+
```
|
123
|
+
|
124
|
+
成功返回: `true`,
|
125
|
+
|
126
|
+
失败返回一个 `Hash`: `{error: {code: code, message: message}}`。
|
127
|
+
|
128
|
+
#### 创建目录
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
upyun.mkdir('/path/to/dir')
|
132
|
+
```
|
133
|
+
|
134
|
+
成功返回: `true`,
|
135
|
+
|
136
|
+
失败返回一个 `Hash`: `{error: {code: code, message: message}}`。
|
137
|
+
|
138
|
+
#### 获取目录文件列表
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
upyun.getlist('/path/to/dir')
|
142
|
+
```
|
143
|
+
|
144
|
+
成功返回一个数组,每个数组成员为一个文件/目录:
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
[{:name=>"foo", :type=>:folder, :length=>0, :last_modified=>1416193624},
|
148
|
+
{:name=>"bar.txt", :type=>:file, :length=>25, :last_modified=>1415261057}]
|
149
|
+
```
|
150
|
+
|
151
|
+
失败返回一个 `Hash`: `{error: {code: code, message: message}}`。
|
152
|
+
|
153
|
+
#### 获取空间使用情况
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
upyun.usage
|
157
|
+
```
|
158
|
+
|
159
|
+
成功返回空间使用量(单位为 `Byte`): `12400`,
|
160
|
+
|
161
|
+
失败返回一个 `Hash`: `{error: {code: code, message: message}}`。
|
162
|
+
|
163
|
+
### Form API 使用
|
164
|
+
|
165
|
+
#### 初始化一个实例
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
require 'upyun'
|
169
|
+
|
170
|
+
upyun = Upyun::Form.new('form-password', 'bucket')
|
171
|
+
```
|
172
|
+
|
173
|
+
其中,参数 `form-password` 为空间表单 API 密钥,可通过又拍云后台获取,`bucket` 为空间名称(必选)。
|
174
|
+
|
175
|
+
与 Rest API 相似, 表单 API 也有个实例变量 `endpoint` 代表又拍云基本域名,默认设置为 `Upyun::ED_AUTO` ,也可以在初始化一个实例之后通过:
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
upyun.endpoint = Upyun::ED_CMCC
|
179
|
+
```
|
180
|
+
更改接入点。
|
181
|
+
|
182
|
+
|
183
|
+
#### 上传文件
|
184
|
+
|
185
|
+
为了简化使用,又拍云文档必选的参数中:
|
186
|
+
>
|
187
|
+
`save-key` 默认设置为: `'/{year}/{mon}/{day}/{filename}{.suffix}'`
|
188
|
+
`expiration` 默认设置为10分钟: `Time.now.to_i + 600`
|
189
|
+
|
190
|
+
|
191
|
+
使用简化版本,不使用额外的策略参数:
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
upyun.upload('file')
|
195
|
+
```
|
196
|
+
上传结果返回一个 `Hash` 结构:
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
{
|
200
|
+
:code=>200,
|
201
|
+
:message=>"ok",
|
202
|
+
:url=>"/2014/11/17/upyun.jpg",
|
203
|
+
:time=>1416208715,
|
204
|
+
:sign=>"f5165b35df431065ca54490a34028635"
|
205
|
+
}
|
206
|
+
```
|
207
|
+
其中
|
208
|
+
1. `code`: 返回的状态码,`200` 为成功,其它为失败
|
209
|
+
2. `message`: 错误信息,具体查阅 [表单 API 状态代码表](http://docs.upyun.com/api/form_api/#api_2)
|
210
|
+
3. `url`: 上传文件保存路径
|
211
|
+
4. `time`: 请求的时间戳
|
212
|
+
5. `sign`: 签名参数,详情见 [sign与non-sign参数说明](http://docs.upyun.com/api/form_api/#note6)
|
213
|
+
6. 如果在请求中指定了 `ext-param`, 那么返回的结构中也会有 `ext-param` 字段,详情见 [ext-param](http://docs.upyun.com/api/form_api/#note5)
|
214
|
+
|
215
|
+
可以在上传的时候指定一些策略参数:
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
opts = {
|
219
|
+
'save_key' => '/foo/bar.jpg',
|
220
|
+
'content-type' => 'image/jpeg',
|
221
|
+
'image-width-range' => '0,1024',
|
222
|
+
'return-url' => 'http://www.example.com'
|
223
|
+
}
|
224
|
+
upyun.upload('file', opts)
|
225
|
+
```
|
226
|
+
特别地,如果指定了 `return-url`, 那么返回的是需要跳转的地址,
|
227
|
+
详情查阅 [通知规则](http://docs.upyun.com/api/form_api/#notify_return)
|
20
228
|
|
21
|
-
up_client = UpYun::Bucket.new("by-test-upload", "ichihuo", "********")
|
22
|
-
res = up_client.writeFile("/test.png", File.new("test.png"))
|
23
|
-
res['x-upyun-width']
|
24
229
|
|
25
230
|
## Contributing
|
26
231
|
|
27
|
-
1. Fork it
|
232
|
+
1. Fork it ( https://github.com/[my-github-username]/upyun/fork )
|
28
233
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
-
3. Commit your changes (`git commit -am '
|
234
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
235
|
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
-
5. Create new Pull Request
|
236
|
+
5. Create a new Pull Request
|
data/Rakefile
CHANGED
data/lib/upyun/form.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'restclient'
|
3
|
+
require 'base64'
|
4
|
+
require 'json'
|
5
|
+
require 'active_support/hash_with_indifferent_access'
|
6
|
+
|
7
|
+
module Upyun
|
8
|
+
class Form
|
9
|
+
include Utils
|
10
|
+
|
11
|
+
VALID_PARAMS = %w(
|
12
|
+
bucket
|
13
|
+
save-key
|
14
|
+
expiration
|
15
|
+
allow-file-type
|
16
|
+
content-length-range
|
17
|
+
content-md5
|
18
|
+
content-secret
|
19
|
+
content-type
|
20
|
+
image-width-range
|
21
|
+
image-height-range
|
22
|
+
notify-url
|
23
|
+
return-url
|
24
|
+
x-gmkerl-thumbnail
|
25
|
+
x-gmkerl-type
|
26
|
+
x-gmkerl-value
|
27
|
+
x-gmkerl-quality
|
28
|
+
x-gmkerl-unsharp
|
29
|
+
x-gmkerl-rotate
|
30
|
+
x-gmkerl-crop
|
31
|
+
x-gmkerl-exif-switch
|
32
|
+
ext-param
|
33
|
+
)
|
34
|
+
|
35
|
+
attr_accessor :bucket, :password
|
36
|
+
|
37
|
+
def initialize(password, bucket)
|
38
|
+
@password = password
|
39
|
+
@bucket = bucket
|
40
|
+
@endpoint = ED_AUTO
|
41
|
+
end
|
42
|
+
|
43
|
+
def upload(file, opts={})
|
44
|
+
base_opts = HashWithIndifferentAccess.new({
|
45
|
+
'bucket' => @bucket,
|
46
|
+
'save-key' => '/{year}/{mon}/{day}/{filename}{.suffix}',
|
47
|
+
'expiration' => Time.now.to_i + 600
|
48
|
+
})
|
49
|
+
|
50
|
+
payload = {
|
51
|
+
policy: policy(base_opts.merge(opts)),
|
52
|
+
signature: signature,
|
53
|
+
file: File.new(file, 'rb')
|
54
|
+
}
|
55
|
+
|
56
|
+
RestClient.post("http://#{@endpoint}/#{@bucket}", payload) do |res|
|
57
|
+
case res.code
|
58
|
+
when 302
|
59
|
+
res
|
60
|
+
else
|
61
|
+
body = JSON.parse(res.body, symbolize_names: true)
|
62
|
+
|
63
|
+
# TODO Upyun have a small bug for the `code`,
|
64
|
+
# we have to adjust it to integer
|
65
|
+
body[:code] = body[:code].to_i
|
66
|
+
body
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
def policy(opts)
|
73
|
+
@_policy = Base64.encode64(policy_json(opts))
|
74
|
+
end
|
75
|
+
|
76
|
+
def signature
|
77
|
+
md5("#{@_policy}&#{@password}")
|
78
|
+
end
|
79
|
+
|
80
|
+
def policy_json(opts)
|
81
|
+
policies = VALID_PARAMS.reduce({}) do |memo, e|
|
82
|
+
(v = opts[e]) ? memo.merge!({e => v}) : memo
|
83
|
+
end
|
84
|
+
policies.to_json
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
data/lib/upyun/rest.rb
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'restclient'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module Upyun
|
6
|
+
class Rest
|
7
|
+
include Utils
|
8
|
+
|
9
|
+
def initialize(bucket, operator, password, endpoint=Upyun::ED_AUTO)
|
10
|
+
@bucket = bucket
|
11
|
+
@operator = operator
|
12
|
+
@password = md5(password)
|
13
|
+
@endpoint = endpoint
|
14
|
+
end
|
15
|
+
|
16
|
+
def put(path, file, headers={})
|
17
|
+
raise ArgumentError, "'file' is not an instance of String" unless file.is_a?(String)
|
18
|
+
headers = headers.merge({"mkdir" => true}) unless headers.key?("mkdir")
|
19
|
+
options = if File.file?(file)
|
20
|
+
{body: File.read(file), length: File.size(file), headers: headers}
|
21
|
+
else
|
22
|
+
{body: file, length: file.length, headers: headers}
|
23
|
+
end
|
24
|
+
|
25
|
+
request(:put, path, options)
|
26
|
+
end
|
27
|
+
|
28
|
+
def get(path, savepath=nil)
|
29
|
+
res = request(:get, path)
|
30
|
+
return res if res.is_a?(Hash) || !savepath
|
31
|
+
|
32
|
+
dir = File.dirname(savepath)
|
33
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
34
|
+
File.write(savepath, res)
|
35
|
+
end
|
36
|
+
|
37
|
+
def getinfo(path)
|
38
|
+
hds = request(:head, path)
|
39
|
+
hds = hds.key?(:error) ? hds : format_info(hds)
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete(path)
|
43
|
+
request(:delete, path)
|
44
|
+
end
|
45
|
+
|
46
|
+
def mkdir(path)
|
47
|
+
request(:post, path, {headers: {folder: true, mkdir: true}})
|
48
|
+
end
|
49
|
+
|
50
|
+
def getlist(path="/")
|
51
|
+
res = request(:get, path)
|
52
|
+
return res if res.is_a?(Hash)
|
53
|
+
res.split("\n").map do |f|
|
54
|
+
attrs = f.split("\t")
|
55
|
+
{
|
56
|
+
name: attrs[0],
|
57
|
+
type: attrs[1] == "N" ? :file : :folder,
|
58
|
+
length: attrs[2].to_i,
|
59
|
+
last_modified: attrs[3].to_i
|
60
|
+
}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def usage(path="/")
|
65
|
+
res = request(:get, path, {params: "usage"})
|
66
|
+
return res if res.is_a?(Hash)
|
67
|
+
|
68
|
+
# RestClient has a bug, body.to_i returns the code instead of body,
|
69
|
+
# see more on https://github.com/rest-client/rest-client/pull/103
|
70
|
+
res.dup.to_i
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def format_info(hds)
|
76
|
+
selected = hds.select { |k| k.to_s.match(/^x_upyun/i) }
|
77
|
+
selected.reduce({}) do |memo, (k, v)|
|
78
|
+
memo.merge!({k[8..-1].to_sym => /^\d+$/.match(v) ? v.to_i : v})
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def fullpath(path)
|
83
|
+
"/#{@bucket}#{URI.encode(URI.decode(path[0] == '/' ? path : '/' + path))}"
|
84
|
+
end
|
85
|
+
|
86
|
+
def encode(fullpath, params)
|
87
|
+
URI.join("http://#{@endpoint}", fullpath, params.nil? ? '' : '?' + params).to_s
|
88
|
+
end
|
89
|
+
|
90
|
+
def request(method, path, options={})
|
91
|
+
fullpath = fullpath(path)
|
92
|
+
url = encode(fullpath, options[:params])
|
93
|
+
headers = options[:headers] || {}
|
94
|
+
date = gmdate
|
95
|
+
length = options[:length] || 0
|
96
|
+
headers.merge!({
|
97
|
+
'Date' => date,
|
98
|
+
'Authorization' => sign(method, date, fullpath, length)
|
99
|
+
})
|
100
|
+
|
101
|
+
if [:post, :patch, :put].include? method
|
102
|
+
RestClient.send(method, url, options[:body].nil? ? "" : options[:body], headers) do |res|
|
103
|
+
res.code == 200 ? true : {error: {code: res.code, message: res.body}}
|
104
|
+
end
|
105
|
+
else
|
106
|
+
RestClient.send(method, url, headers) do |res|
|
107
|
+
if res.code == 200
|
108
|
+
case method
|
109
|
+
when :get
|
110
|
+
res.body
|
111
|
+
when :head
|
112
|
+
res.headers
|
113
|
+
else
|
114
|
+
true
|
115
|
+
end
|
116
|
+
else
|
117
|
+
{error: {code: res.code, message: res.body}}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def gmdate
|
124
|
+
Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT')
|
125
|
+
end
|
126
|
+
|
127
|
+
def sign(method, date, path, length)
|
128
|
+
sign = "#{method.to_s.upcase}&#{path}&#{date}&#{length}&#{@password}"
|
129
|
+
"UpYun #{@operator}:#{md5(sign)}"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
data/lib/upyun/utils.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module Upyun
|
4
|
+
module Utils
|
5
|
+
def md5(str)
|
6
|
+
Digest::MD5.hexdigest(str)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.included(receiver)
|
10
|
+
receiver.send(:define_method, :endpoint) { @endpoint }
|
11
|
+
receiver.send(:define_method, :endpoint=) do |ep|
|
12
|
+
unless Upyun::ED_LIST.member?(ep)
|
13
|
+
raise ArgumentError, "Valid endpoints are: #{Upyun::ED_LIST}"
|
14
|
+
end
|
15
|
+
@endpoint = ep
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/upyun/version.rb
CHANGED
data/lib/upyun.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
|
1
|
+
require 'upyun/version'
|
2
|
+
require 'upyun/utils'
|
3
|
+
require 'upyun/rest'
|
4
|
+
require 'upyun/form'
|
4
5
|
|
5
6
|
module Upyun
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
14
|
-
end
|
7
|
+
DOMAIN = 'api.upyun.com'
|
8
|
+
ED_AUTO = "v0.#{DOMAIN}"
|
9
|
+
ED_TELECOM = "v1.#{DOMAIN}"
|
10
|
+
ED_UNION = "v2.#{DOMAIN}"
|
11
|
+
ED_CMCC = "v3.#{DOMAIN}"
|
12
|
+
ED_LIST = (0..3).map { |e| "v#{e}.#{DOMAIN}" }
|
13
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/upyun.jpg
ADDED
Binary file
|
data/spec/upyun_spec.rb
ADDED
@@ -0,0 +1,201 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "Upyun Restful API Basic testing" do
|
4
|
+
before :all do
|
5
|
+
@upyun = Upyun::Rest.new('sdkfile', 'tester', 'grjxv2mxELR3')
|
6
|
+
@file = File.expand_path('../upyun.jpg', __FILE__)
|
7
|
+
@str = 'This is a binary string, not a file'
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ".endpoint=" do
|
11
|
+
it "known ENDPOINT, should return ok" do
|
12
|
+
@upyun.endpoint = Upyun::ED_CMCC
|
13
|
+
expect(@upyun.endpoint).to eq 'v3.api.upyun.com'
|
14
|
+
end
|
15
|
+
|
16
|
+
it "unknown ENDPOINT, should raise ArgumentError" do
|
17
|
+
expect {@upyun.endpoint = 'v5.api.upyun.com'}.
|
18
|
+
to raise_error(ArgumentError, /Valid endpoints/)
|
19
|
+
end
|
20
|
+
|
21
|
+
after { @upyun.endpoint = Upyun::ED_AUTO }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe ".put" do
|
25
|
+
before { @path = '/ruby-sdk/foo/test.jpg' }
|
26
|
+
|
27
|
+
it "PUT a file" do
|
28
|
+
expect(@upyun.put(@path, @file)).to be true
|
29
|
+
end
|
30
|
+
|
31
|
+
it "PUT a binary string" do
|
32
|
+
expect(@upyun.put(@path, @str)).to be true
|
33
|
+
end
|
34
|
+
|
35
|
+
it "PUT with some extra process headers" do
|
36
|
+
headers = {
|
37
|
+
'Contetn-type' => 'image/jpeg',
|
38
|
+
'x-gmkerl-type' => 'fix_width',
|
39
|
+
'x-gmkerl-value' => 42,
|
40
|
+
'x-gmkerl-unsharp' => true
|
41
|
+
}
|
42
|
+
expect(@upyun.put(@path, @file, headers)).to be true
|
43
|
+
end
|
44
|
+
|
45
|
+
after { @upyun.delete(@path) }
|
46
|
+
end
|
47
|
+
|
48
|
+
describe ".get" do
|
49
|
+
before :all do
|
50
|
+
@path = '/ruby-sdk/foo/test.jpg'
|
51
|
+
@upyun.put(@path, @str, {'Content-Type' => 'text/plain'})
|
52
|
+
end
|
53
|
+
|
54
|
+
it "GET a file" do
|
55
|
+
expect(@upyun.get(@path)).to eq(@str)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "GET a file and save" do
|
59
|
+
expect(@upyun.get(@path, './save.jpg')).not_to eq(404)
|
60
|
+
expect(File.exists?('./save.jpg')).to be true
|
61
|
+
expect(File.read('./save.jpg')).to eq(@str)
|
62
|
+
File.delete('./save.jpg')
|
63
|
+
end
|
64
|
+
|
65
|
+
it "GET a not-exist file" do
|
66
|
+
res = @upyun.get('/ruby-sdk/foo/test-not-exist.jpg')
|
67
|
+
expect(res.is_a?(Hash) && res[:error][:code] == 404)
|
68
|
+
end
|
69
|
+
|
70
|
+
after(:all) { @upyun.delete(@path) }
|
71
|
+
end
|
72
|
+
|
73
|
+
describe ".getinfo" do
|
74
|
+
before :all do
|
75
|
+
@dir = '/ruby-sdk/foo'
|
76
|
+
@path = "#{@dir}/test.jpg"
|
77
|
+
@upyun.put(@path, @str, {'Content-Type' => 'text/plain'})
|
78
|
+
end
|
79
|
+
|
80
|
+
it "of file should success" do
|
81
|
+
res = @upyun.getinfo(@path)
|
82
|
+
expect(res[:file_type]).to eq('file')
|
83
|
+
end
|
84
|
+
|
85
|
+
it "of folder should success" do
|
86
|
+
res = @upyun.getinfo(@dir)
|
87
|
+
expect(res[:file_type]).to eq('folder')
|
88
|
+
end
|
89
|
+
|
90
|
+
after(:all) { @upyun.delete(@path) }
|
91
|
+
end
|
92
|
+
|
93
|
+
describe ".delete" do
|
94
|
+
before do
|
95
|
+
@path = '/ruby-sdk/foo/test.jpg'
|
96
|
+
@upyun.put(@path, @file)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "DELETE a file" do
|
100
|
+
expect(@upyun.delete(@path)).to be true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe ".mkdir" do
|
105
|
+
before(:all) { @path = '/ruby-skd/foo/dir' }
|
106
|
+
|
107
|
+
it "should success" do
|
108
|
+
expect(@upyun.mkdir(@path)).to be true
|
109
|
+
end
|
110
|
+
|
111
|
+
after(:all) { @upyun.delete(@path) }
|
112
|
+
end
|
113
|
+
|
114
|
+
describe ".getlist" do
|
115
|
+
it "should get a list of file record" do
|
116
|
+
expect(@upyun.getlist("/")).to be_instance_of(Array)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe ".usage" do
|
121
|
+
it "should be an Fixnum" do
|
122
|
+
expect(@upyun.usage).to be_instance_of(Fixnum)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "Form Upload" do
|
128
|
+
before :all do
|
129
|
+
@form = Upyun::Form.new('ESxWIoMmF39nSDY7CSFUsC7s50U=', 'sdkfile')
|
130
|
+
@file = File.expand_path('../upyun.jpg', __FILE__)
|
131
|
+
end
|
132
|
+
|
133
|
+
describe ".endpoint=" do
|
134
|
+
it "known ENDPOINT, should return ok" do
|
135
|
+
@form.endpoint = Upyun::ED_CMCC
|
136
|
+
expect(@form.endpoint).to eq 'v3.api.upyun.com'
|
137
|
+
end
|
138
|
+
|
139
|
+
it "unknown ENDPOINT, should raise ArgumentError" do
|
140
|
+
expect {@form.endpoint = 'v5.api.upyun.com'}.
|
141
|
+
to raise_error(ArgumentError, /Valid endpoints/)
|
142
|
+
end
|
143
|
+
|
144
|
+
after { @form.endpoint = Upyun::ED_AUTO }
|
145
|
+
end
|
146
|
+
|
147
|
+
describe ".upload" do
|
148
|
+
it "with default attributes should success" do
|
149
|
+
res = @form.upload(@file)
|
150
|
+
expect(res.keys).to include(:code, :message, :url, :time)
|
151
|
+
expect(res[:code]).to eq(200)
|
152
|
+
expect(res[:message]).to match(/ok/)
|
153
|
+
now = Time.now
|
154
|
+
expect(res[:url]).to eq("/#{now.year}/#{now.mon}/#{now.day}/upyun.jpg")
|
155
|
+
end
|
156
|
+
|
157
|
+
it "set 'save-key' should success" do
|
158
|
+
res = @form.upload(@file, {'save-key' => 'name-ed keypath'})
|
159
|
+
expect(res[:code]).to eq(200)
|
160
|
+
expect(res[:url]).to eq('name-ed keypath')
|
161
|
+
end
|
162
|
+
|
163
|
+
it "set not correct 'expiration' should return 403 with expired" do
|
164
|
+
res = @form.upload(@file, {'expiration' => 102400})
|
165
|
+
expect(res[:code]).to eq(403)
|
166
|
+
expect(res[:message]).to match(/Authorize has expired/)
|
167
|
+
end
|
168
|
+
|
169
|
+
it "set 'return-url' should return 302 with 'location' header" do
|
170
|
+
res = @form.upload(@file, {'return-url' => 'http://www.example.com'})
|
171
|
+
expect(res.code).to eq(302)
|
172
|
+
expect(res.headers.key?(:location)).to be true
|
173
|
+
end
|
174
|
+
|
175
|
+
it "set 'return-url' and handle failed, should also return 302 with 'location' header" do
|
176
|
+
opts = {
|
177
|
+
'image-width-range' => '0,10',
|
178
|
+
'return-url' => 'http://www.example.com'
|
179
|
+
}
|
180
|
+
res = @form.upload(@file, opts)
|
181
|
+
expect(res.code).to eq(302)
|
182
|
+
expect(res.headers.key?(:location)).to be true
|
183
|
+
end
|
184
|
+
|
185
|
+
it "set 'notify-url' should return 200 success" do
|
186
|
+
res = @form.upload(@file, {'notify-url' => 'http://www.example.com'})
|
187
|
+
expect(res).to be_instance_of(Hash)
|
188
|
+
expect(res[:code]).to eq(200)
|
189
|
+
end
|
190
|
+
|
191
|
+
it "set 'notify-url' and handle failed, should return 403 failed" do
|
192
|
+
opts = {
|
193
|
+
'image-width-range' => '0,10',
|
194
|
+
'notify-url' => 'http://www.example.com'
|
195
|
+
}
|
196
|
+
res = @form.upload(@file, opts)
|
197
|
+
expect(res).to be_instance_of(Hash)
|
198
|
+
expect(res[:code]).to eq(403)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
data/upyun.gemspec
CHANGED
@@ -1,17 +1,28 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'upyun/version'
|
3
5
|
|
4
|
-
Gem::Specification.new do |
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "upyun"
|
8
|
+
spec.version = Upyun::VERSION
|
9
|
+
spec.authors = ["jsvisa"]
|
10
|
+
spec.email = ["delweng@gmail.com"]
|
11
|
+
spec.summary = "UPYUN API SDK"
|
12
|
+
spec.description = "UPYUN Rest API and Form API SDK"
|
13
|
+
spec.homepage = "https://github.com/upyun/ruby-sdk"
|
14
|
+
spec.license = "MIT"
|
10
15
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "rest-client", ">= 1.6.7"
|
22
|
+
spec.add_dependency "activesupport", "~> 4.1.0"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.1.0"
|
17
27
|
end
|
28
|
+
|
metadata
CHANGED
@@ -1,55 +1,134 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: upyun
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
|
-
-
|
7
|
+
- jsvisa
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
14
|
-
|
11
|
+
date: 2014-11-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.6.7
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.6.7
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.1.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.1.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.7'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.7'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 3.1.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 3.1.0
|
83
|
+
description: UPYUN Rest API and Form API SDK
|
15
84
|
email:
|
16
|
-
-
|
85
|
+
- delweng@gmail.com
|
17
86
|
executables: []
|
18
87
|
extensions: []
|
19
88
|
extra_rdoc_files: []
|
20
89
|
files:
|
21
|
-
- .
|
90
|
+
- ".coveralls.yml"
|
91
|
+
- ".gitignore"
|
92
|
+
- ".rspec"
|
93
|
+
- ".travis.yml"
|
22
94
|
- Gemfile
|
23
|
-
- LICENSE
|
95
|
+
- LICENSE.txt
|
24
96
|
- README.md
|
25
97
|
- Rakefile
|
26
98
|
- lib/upyun.rb
|
27
|
-
- lib/upyun/
|
99
|
+
- lib/upyun/form.rb
|
100
|
+
- lib/upyun/rest.rb
|
101
|
+
- lib/upyun/utils.rb
|
28
102
|
- lib/upyun/version.rb
|
103
|
+
- spec/spec_helper.rb
|
104
|
+
- spec/upyun.jpg
|
105
|
+
- spec/upyun_spec.rb
|
29
106
|
- upyun.gemspec
|
30
|
-
homepage: https://github.com/
|
31
|
-
licenses:
|
107
|
+
homepage: https://github.com/upyun/ruby-sdk
|
108
|
+
licenses:
|
109
|
+
- MIT
|
110
|
+
metadata: {}
|
32
111
|
post_install_message:
|
33
112
|
rdoc_options: []
|
34
113
|
require_paths:
|
35
114
|
- lib
|
36
115
|
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
-
none: false
|
38
116
|
requirements:
|
39
|
-
- -
|
117
|
+
- - ">="
|
40
118
|
- !ruby/object:Gem::Version
|
41
119
|
version: '0'
|
42
120
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
-
none: false
|
44
121
|
requirements:
|
45
|
-
- -
|
122
|
+
- - ">="
|
46
123
|
- !ruby/object:Gem::Version
|
47
124
|
version: '0'
|
48
125
|
requirements: []
|
49
126
|
rubyforge_project:
|
50
|
-
rubygems_version:
|
127
|
+
rubygems_version: 2.4.4
|
51
128
|
signing_key:
|
52
|
-
specification_version:
|
53
|
-
summary:
|
54
|
-
test_files:
|
55
|
-
|
129
|
+
specification_version: 4
|
130
|
+
summary: UPYUN API SDK
|
131
|
+
test_files:
|
132
|
+
- spec/spec_helper.rb
|
133
|
+
- spec/upyun.jpg
|
134
|
+
- spec/upyun_spec.rb
|
data/lib/upyun/bucket.rb
DELETED
@@ -1,111 +0,0 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'uri'
|
3
|
-
require "base64"
|
4
|
-
require 'digest/md5'
|
5
|
-
|
6
|
-
module Upyun
|
7
|
-
class Bucket
|
8
|
-
attr_accessor :bucketname, :username, :password
|
9
|
-
attr_accessor :api_domain, :api_form_secret
|
10
|
-
|
11
|
-
def initialize(bucketname, username, password, options = {})
|
12
|
-
options = { :api_domain => "v0.api.upyun.com", :api_form_secret => "" }.merge(options)
|
13
|
-
@bucketname = bucketname
|
14
|
-
@username = username
|
15
|
-
@bpwd = password
|
16
|
-
@password = Digest::MD5.hexdigest(password)
|
17
|
-
@api_domain = options[:api_domain]
|
18
|
-
@api_form_secret = options[:api_form_secret]
|
19
|
-
end
|
20
|
-
|
21
|
-
def write_file(filepath, fd, mkdir='true')
|
22
|
-
url = "http://#{api_domain}/#{bucketname}#{filepath}"
|
23
|
-
uri = URI.parse(URI.encode(url))
|
24
|
-
|
25
|
-
response = Net::HTTP.start(uri.host, uri.port) do |http|
|
26
|
-
date = get_gmt_date
|
27
|
-
length = File.size(fd)
|
28
|
-
method = 'PUT'
|
29
|
-
headers = {
|
30
|
-
'Date' => date,
|
31
|
-
'Content-Length' => length.to_s,
|
32
|
-
'Authorization' => sign(method, get_gmt_date, "/#{@bucketname}#{filepath}", length),
|
33
|
-
'mkdir' => mkdir
|
34
|
-
}
|
35
|
-
|
36
|
-
http.send_request(method, uri.request_uri, fd.read, headers)
|
37
|
-
end
|
38
|
-
response.body
|
39
|
-
end
|
40
|
-
|
41
|
-
def check_space
|
42
|
-
url = "http://#{api_domain}/#{bucketname}/?usage"
|
43
|
-
uri = URI.parse(URI.encode(url))
|
44
|
-
req = Net::HTTP::Get.new(url)
|
45
|
-
req.basic_auth @username, @bpwd
|
46
|
-
response = Net::HTTP.start(uri.host, uri.port) do |http|
|
47
|
-
http.request(req)
|
48
|
-
end
|
49
|
-
response.body
|
50
|
-
end
|
51
|
-
|
52
|
-
def checkout(file)
|
53
|
-
url = "http://#{api_domain}/#{bucketname}/#{file}"
|
54
|
-
uri = URI.parse(URI.encode(url))
|
55
|
-
req = Net::HTTP::Get.new(url)
|
56
|
-
req.basic_auth @username, @bpwd
|
57
|
-
response = Net::HTTP.start(uri.host, uri.port) do |http|
|
58
|
-
http.request(req)
|
59
|
-
end
|
60
|
-
response.body
|
61
|
-
end
|
62
|
-
|
63
|
-
# 生成api使用的policy 以及 signature 可以是图片或者是文件附件 图片最大为1M 文件附件最大为5M
|
64
|
-
def api_form_params(file_type = "pic", notify_url = "", return_url = "", expire_date = 1.days)
|
65
|
-
policy_doc = {
|
66
|
-
"bucket" => bucketname,
|
67
|
-
"expiration" => (DateTime.now + expire_date).to_i,
|
68
|
-
"save-key" => "/{year}/{mon}/{random}{.suffix}",
|
69
|
-
"notify-url" => notify_url,
|
70
|
-
"return-url" => return_url
|
71
|
-
}
|
72
|
-
|
73
|
-
policy_doc = policy_doc.merge({"allow-file-type" => "jpg,jpeg,gif,png", "content-length-range" => "0,1048576"}) if file_type == "pic"
|
74
|
-
policy_doc = policy_doc.merge({"allow-file-type" => "doc docx xls xlsx ppt txt zip rar", "content-length-range" => "0,5242880"}) if file_type == "file"
|
75
|
-
|
76
|
-
policy = Base64.encode64(policy_doc.to_json).gsub("\n", "").strip
|
77
|
-
signature = Digest::MD5.hexdigest(policy + "&" + api_form_secret)
|
78
|
-
|
79
|
-
{:policy => policy, :signature => signature}
|
80
|
-
end
|
81
|
-
|
82
|
-
def parse_notify_params(params)
|
83
|
-
params = params.with_indifferent_access
|
84
|
-
if params[:code].to_s == "200" && (params[:sign] == Digest::MD5.hexdigest("#{params[:code]}&#{params[:message]}&#{params[:url]}&#{params[:time]}&#{api_form_secret}"))
|
85
|
-
url = "http://#{bucketname}.b0.upaiyun.com#{params[:url]}"
|
86
|
-
mid = Digest::MD5.hexdigest(url)
|
87
|
-
image_attributes = { :mid => mid, :url => url }
|
88
|
-
|
89
|
-
if params["image-width"] && params["image-height"] && params["image-frames"] && params["image-type"]
|
90
|
-
image_attributes[:width] = params["image-width"].to_i
|
91
|
-
image_attributes[:height] = params["image-height"].to_i
|
92
|
-
image_attributes[:frames] = params["image-frames"].to_i
|
93
|
-
image_attributes[:file_type] = params["image-type"]
|
94
|
-
end
|
95
|
-
image_attributes
|
96
|
-
else
|
97
|
-
nil
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
private
|
102
|
-
def get_gmt_date
|
103
|
-
DateTime.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT')
|
104
|
-
end
|
105
|
-
|
106
|
-
def sign(method, date, url, length)
|
107
|
-
sign = "#{method}&#{url}&#{date}&#{length}&#{password}"
|
108
|
-
"UpYun #{@username}:#{Digest::MD5.hexdigest(sign)}"
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|