qiniu_jxb 6.2.4

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.
Files changed (48) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +9 -0
  4. data/CHANGELOG.md +118 -0
  5. data/Gemfile +8 -0
  6. data/Gemfile.lock +37 -0
  7. data/LICENSE +22 -0
  8. data/README.md +47 -0
  9. data/Rakefile +21 -0
  10. data/docs/README.md +790 -0
  11. data/lib/qiniu-rs.rb +2 -0
  12. data/lib/qiniu.rb +209 -0
  13. data/lib/qiniu/abstract.rb +22 -0
  14. data/lib/qiniu/adt.rb +46 -0
  15. data/lib/qiniu/auth.rb +234 -0
  16. data/lib/qiniu/config.rb +58 -0
  17. data/lib/qiniu/exceptions.rb +120 -0
  18. data/lib/qiniu/fop.rb +4 -0
  19. data/lib/qiniu/http.rb +137 -0
  20. data/lib/qiniu/image.rb +38 -0
  21. data/lib/qiniu/log.rb +15 -0
  22. data/lib/qiniu/management.rb +128 -0
  23. data/lib/qiniu/misc.rb +33 -0
  24. data/lib/qiniu/pfop.rb +124 -0
  25. data/lib/qiniu/resumable_upload.rb +319 -0
  26. data/lib/qiniu/storage.rb +5 -0
  27. data/lib/qiniu/tokens/access_token.rb +21 -0
  28. data/lib/qiniu/tokens/download_token.rb +31 -0
  29. data/lib/qiniu/tokens/qbox_token.rb +38 -0
  30. data/lib/qiniu/tokens/upload_token.rb +47 -0
  31. data/lib/qiniu/upload.rb +138 -0
  32. data/lib/qiniu/utils.rb +109 -0
  33. data/lib/qiniu/version.rb +17 -0
  34. data/qiniu.gemspec +29 -0
  35. data/spec/qiniu/abstract_spec.rb +30 -0
  36. data/spec/qiniu/auth_spec.rb +81 -0
  37. data/spec/qiniu/image_logo_for_test.png +0 -0
  38. data/spec/qiniu/image_spec.rb +89 -0
  39. data/spec/qiniu/management_spec.rb +156 -0
  40. data/spec/qiniu/misc_spec.rb +59 -0
  41. data/spec/qiniu/pfop_spec.rb +89 -0
  42. data/spec/qiniu/qiniu_spec.rb +329 -0
  43. data/spec/qiniu/tokens/qbox_token_spec.rb +29 -0
  44. data/spec/qiniu/upload_spec.rb +308 -0
  45. data/spec/qiniu/utils_spec.rb +49 -0
  46. data/spec/qiniu/version_spec.rb +10 -0
  47. data/spec/spec_helper.rb +19 -0
  48. metadata +220 -0
data/lib/qiniu-rs.rb ADDED
@@ -0,0 +1,2 @@
1
+ # More logical way to require 'qiniu-rs'
2
+ require File.join(File.dirname(__FILE__), 'qiniu', 'qiniu')
data/lib/qiniu.rb ADDED
@@ -0,0 +1,209 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Qiniu
4
+ autoload :Version, 'qiniu/version'
5
+ autoload :Utils, 'qiniu/utils'
6
+ autoload :Auth, 'qiniu/auth'
7
+ autoload :Config, 'qiniu/config'
8
+ autoload :Log, 'qiniu/log'
9
+ autoload :Exception, 'qiniu/exceptions'
10
+ autoload :AccessToken, 'qiniu/tokens/access_token'
11
+ autoload :QboxToken, 'qiniu/tokens/qbox_token'
12
+ autoload :UploadToken, 'qiniu/tokens/upload_token'
13
+ autoload :DownloadToken, 'qiniu/tokens/download_token'
14
+ autoload :Abstract, 'qiniu/abstract'
15
+ autoload :Storage, 'qiniu/storage'
16
+ autoload :Fop, 'qiniu/fop'
17
+ autoload :Misc, 'qiniu/misc'
18
+
19
+ class << self
20
+
21
+ StatusOK = 200
22
+
23
+ def establish_connection!(opts = {})
24
+ Config.initialize_connect opts
25
+ end
26
+
27
+ def mkbucket(bucket_name)
28
+ code, data = Storage.mkbucket(bucket_name)
29
+ code == StatusOK
30
+ end
31
+
32
+ def buckets
33
+ code, data = Storage.buckets
34
+ code == StatusOK ? data : false
35
+ end
36
+
37
+ def set_protected(bucket, protected_mode)
38
+ code, data = Misc.set_protected(bucket, protected_mode)
39
+ code == StatusOK
40
+ end
41
+
42
+ def set_separator(bucket, separator)
43
+ code, data = Misc.set_separator(bucket, separator)
44
+ code == StatusOK
45
+ end
46
+
47
+ def set_style(bucket, name, style)
48
+ code, data = Misc.set_style(bucket, name, style)
49
+ code == StatusOK
50
+ end
51
+
52
+ def unset_style(bucket, name)
53
+ code, data = Misc.unset_style(bucket, name)
54
+ code == StatusOK
55
+ end
56
+
57
+ def upload_file opts = {}
58
+ uncontained_opts = [:uptoken, :file, :bucket, :key] - opts.keys
59
+ raise MissingArgsError, uncontained_opts unless uncontained_opts.empty?
60
+
61
+ source_file = opts[:file]
62
+ raise NoSuchFileError, source_file unless File.exist?(source_file)
63
+
64
+ opts[:enable_resumable_upload] = true unless opts.has_key?(:enable_resumable_upload)
65
+
66
+ if opts[:enable_resumable_upload] && File::size(source_file) > Config.settings[:block_size]
67
+ code, data, raw_headers = Storage.upload_with_token(opts[:uptoken],
68
+ opts[:file],
69
+ opts[:bucket],
70
+ opts[:key],
71
+ opts[:mime_type],
72
+ opts[:note],
73
+ opts[:customer],
74
+ opts[:callback_params],
75
+ opts[:rotate])
76
+ else
77
+ code, data, raw_headers = Storage.upload_with_token(opts[:uptoken],
78
+ opts[:file],
79
+ opts[:bucket],
80
+ opts[:key],
81
+ opts[:mime_type],
82
+ opts[:note],
83
+ opts[:callback_params],
84
+ opts[:enable_crc32_check],
85
+ opts[:rotate])
86
+ end
87
+ raise UploadFailedError.new(code, data) if code != StatusOK
88
+ return data
89
+ end
90
+
91
+ def stat(bucket, key)
92
+ code, data = Storage.stat(bucket, key)
93
+ code == StatusOK ? data : false
94
+ end
95
+
96
+ def get(bucket, key, save_as = nil, expires_in = nil, version = nil)
97
+ code, data = Storage.get(bucket, key, save_as, expires_in, version)
98
+ code == StatusOK ? data : false
99
+ end
100
+
101
+ def download(bucket, key, save_as = nil, expires_in = nil, version = nil)
102
+ code, data = Storage.get(bucket, key, save_as, expires_in, version)
103
+ code == StatusOK ? data["url"] : false
104
+ end
105
+
106
+ def copy(source_bucket, source_key, target_bucket, target_key)
107
+ code, data = Storage.copy(source_bucket, source_key, target_bucket, target_key)
108
+ code == StatusOK
109
+ end
110
+
111
+ def move(source_bucket, source_key, target_bucket, target_key)
112
+ code, data = Storage.move(source_bucket, source_key, target_bucket, target_key)
113
+ code == StatusOK
114
+ end
115
+
116
+ def delete(bucket, key)
117
+ code, data = Storage.delete(bucket, key)
118
+ code == StatusOK
119
+ end
120
+
121
+ def batch(command, bucket, keys)
122
+ code, data = Storage.batch(command, bucket, keys)
123
+ code == StatusOK ? data : false
124
+ end
125
+
126
+ def batch_stat(bucket, keys)
127
+ code, data = Storage.batch_stat(bucket, keys)
128
+ code == StatusOK ? data : false
129
+ end
130
+
131
+ def batch_get(bucket, keys)
132
+ code, data = Storage.batch_get(bucket, keys)
133
+ code == StatusOK ? data : false
134
+ end
135
+
136
+ def batch_copy(*args)
137
+ code, data = Storage.batch_copy(args)
138
+ code == StatusOK
139
+ end
140
+
141
+ def batch_move(*args)
142
+ code, data = Storage.batch_move(args)
143
+ code == StatusOK
144
+ end
145
+
146
+ def batch_download(bucket, keys)
147
+ code, data = Storage.batch_get(bucket, keys)
148
+ return false unless code == StatusOK
149
+ links = []
150
+ data.each { |e| links << e["data"]["url"] }
151
+ links
152
+ end
153
+
154
+ def batch_delete(bucket, keys)
155
+ code, data = Storage.batch_delete(bucket, keys)
156
+ code == StatusOK ? data : false
157
+ end
158
+
159
+ def drop(bucket)
160
+ code, data = Storage.drop(bucket)
161
+ code == StatusOK
162
+ end
163
+
164
+ def image_info(url)
165
+ code, data = Fop::Image.info(url)
166
+ code == StatusOK ? data : false
167
+ end
168
+
169
+ def image_exif(url)
170
+ code, data = Fop::Image.exif(url)
171
+ code == StatusOK ? data : false
172
+ end
173
+
174
+ def image_mogrify_preview_url(source_image_url, options)
175
+ Fop::Image.mogrify_preview_url(source_image_url, options)
176
+ end
177
+
178
+ def image_mogrify_save_as(bucket, key, source_image_url, options)
179
+ code, data = Storage.image_mogrify_save_as(bucket, key, source_image_url, options)
180
+ code == StatusOK ? data : false
181
+ end
182
+
183
+ def generate_upload_token(opts = {})
184
+ token_obj = UploadToken.new(opts)
185
+ token_obj.access_key = Config.settings[:access_key]
186
+ token_obj.secret_key = Config.settings[:secret_key]
187
+ #token_obj.scope = opts[:scope]
188
+ #token_obj.expires_in = opts[:expires_in]
189
+ #token_obj.callback_url = opts[:callback_url]
190
+ #token_obj.callback_body_type = opts[:callback_body_type]
191
+ #token_obj.customer = opts[:customer]
192
+ #token_obj.escape = opts[:escape]
193
+ #token_obj.async_options = opts[:async_options]
194
+ #token_obj.return_body = opts[:return_body]
195
+ token_obj.generate_token
196
+ end
197
+
198
+ def generate_download_token(opts = {})
199
+ token_obj = DownloadToken.new(opts)
200
+ token_obj.access_key = Config.settings[:access_key]
201
+ token_obj.secret_key = Config.settings[:secret_key]
202
+ #token_obj.expires_in = opts[:expires_in]
203
+ #token_obj.pattern = opts[:pattern]
204
+ token_obj.generate_token
205
+ end
206
+
207
+ end
208
+
209
+ end # module Qiniu
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Qiniu
4
+ module Abstract
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def abstract_methods(*args)
11
+ args.each do |name|
12
+ class_eval <<-END
13
+ def #{name}(*args)
14
+ errmsg = %Q(class \#{self.class.name} must implement abstract method #{self.name}##{name}().)
15
+ raise NotImplementedError.new(errmsg)
16
+ end
17
+ END
18
+ end
19
+ end
20
+ end
21
+ end # module Abstract
22
+ end # module Qiniu
data/lib/qiniu/adt.rb ADDED
@@ -0,0 +1,46 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # vim: sw=2 ts=2
3
+
4
+ require 'uri'
5
+
6
+ module Qiniu
7
+ module ADT
8
+
9
+ class ApiSpecification
10
+ public
11
+ def to_str; return ""; end
12
+ end # class ApiSpecification
13
+
14
+ module Policy
15
+ public
16
+ def to_json
17
+ args = {}
18
+
19
+ self.params.each_pair do |key, fld|
20
+ val = self.__send__(key)
21
+ if !val.nil? then
22
+ args[fld] = val
23
+ end
24
+ end
25
+
26
+ return args.to_json
27
+ end # to_json
28
+
29
+ def to_query_string
30
+ args = []
31
+
32
+ self.params.each_pair do |key, fld|
33
+ val = self.__send__(key)
34
+ if !val.nil? then
35
+ new_fld = CGI.escape(fld.to_s)
36
+ new_val = CGI.escape(val.to_s).gsub('+', '%20')
37
+ args.push("#{new_fld}=#{new_val}")
38
+ end
39
+ end
40
+
41
+ return args.join("&")
42
+ end # to_query_string
43
+ end # module Policy
44
+
45
+ end # module ADT
46
+ end # module Qiniu
data/lib/qiniu/auth.rb ADDED
@@ -0,0 +1,234 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # vim: sw=2 ts=2
3
+
4
+ require 'hmac-sha1'
5
+ require 'uri'
6
+
7
+ require 'qiniu/exceptions'
8
+
9
+ module Qiniu
10
+ module Auth
11
+ DEFAULT_AUTH_SECONDS = 3600
12
+
13
+ class << self
14
+ def calculate_deadline(expires_in, deadline = nil)
15
+ ### 授权期计算
16
+ if expires_in.is_a?(Integer) && expires_in > 0 then
17
+ # 指定相对时间,单位:秒
18
+ return Time.now.to_i + expires_in
19
+ elsif deadline.is_a?(Integer) then
20
+ # 指定绝对时间,常用于调试和单元测试
21
+ return deadline
22
+ end
23
+
24
+ # 默认授权期1小时
25
+ return Time.now.to_i + DEFAULT_AUTH_SECONDS
26
+ end # calculate_deadline
27
+ end # class << self
28
+
29
+ class PutPolicy
30
+ private
31
+ def initialize(bucket,
32
+ key = nil,
33
+ expires_in = DEFAULT_AUTH_SECONDS,
34
+ deadline = nil)
35
+ ### 设定scope参数(必填项目)
36
+ self.scope!(bucket, key)
37
+
38
+ ### 设定deadline参数(必填项目)
39
+ @expires_in = expires_in
40
+ @deadline = Auth.calculate_deadline(expires_in, deadline)
41
+ end # initialize
42
+
43
+ PARAMS = {
44
+ # 字符串类型参数
45
+ :scope => "scope" ,
46
+ :save_key => "saveKey" ,
47
+ :end_user => "endUser" ,
48
+ :return_url => "returnUrl" ,
49
+ :return_body => "returnBody" ,
50
+ :callback_url => "callbackUrl" ,
51
+ :callback_body => "callbackBody" ,
52
+ :persistent_ops => "persistentOps" ,
53
+ :persistent_notify_url => "persistentNotifyUrl" ,
54
+ :persistent_pipeline => "persistentPipeline" ,
55
+
56
+ # 数值类型参数
57
+ :deadline => "deadline" ,
58
+ :insert_only => "insertOnly" ,
59
+ :fsize_limit => "fsizeLimit" ,
60
+ :detect_mime => "detectMime" ,
61
+ :mime_limit => "mimeLimit"
62
+ } # PARAMS
63
+
64
+ public
65
+ attr_reader :bucket, :key
66
+
67
+ def scope!(bucket, key = nil)
68
+ @bucket = bucket
69
+ @key = key
70
+
71
+ if key.nil? then
72
+ # 新增语义,文件已存在则失败
73
+ @scope = bucket
74
+ else
75
+ # 覆盖语义,文件已存在则直接覆盖
76
+ @scope = "#{bucket}:#{key}"
77
+ end
78
+ end # scope!
79
+
80
+ def expires_in!(seconds)
81
+ if !seconds.nil? then
82
+ return @expires_in
83
+ end
84
+
85
+ @epires_in = seconds
86
+ @deadline = Auth.calculate_deadline(seconds)
87
+
88
+ return @expires_in
89
+ end # expires_in!
90
+
91
+ def expires_in=(seconds)
92
+ return expires_in!(seconds)
93
+ end # expires_in=
94
+
95
+ def expires_in
96
+ return @expires_in
97
+ end # expires_in
98
+
99
+ def allow_mime_list! (list)
100
+ @mime_limit = list
101
+ end # allow_mime_list!
102
+
103
+ def deny_mime_list! (list)
104
+ @mime_limit = "!#{list}"
105
+ end # deny_mime_list!
106
+
107
+ def insert_only!
108
+ @insert_only = 1
109
+ end # insert_only!
110
+
111
+ def detect_mime!
112
+ @detect_mime = 1
113
+ end # detect_mime!
114
+
115
+ def to_json
116
+ args = {}
117
+
118
+ PARAMS.each_pair do |key, fld|
119
+ val = self.__send__(key)
120
+ if !val.nil? then
121
+ args[fld] = val
122
+ end
123
+ end
124
+
125
+ return args.to_json
126
+ end # to_json
127
+
128
+ PARAMS.each_pair do |key, fld|
129
+ attr_accessor key
130
+ end
131
+ end # class PutPolicy
132
+
133
+ class << self
134
+ EMPTY_ARGS = {}
135
+
136
+ ### 生成下载授权URL
137
+ def authorize_download_url(url, args = EMPTY_ARGS)
138
+ ### 提取AK/SK信息
139
+ access_key = Config.settings[:access_key]
140
+ secret_key = Config.settings[:secret_key]
141
+
142
+ download_url = url
143
+
144
+ ### URL变换:追加FOP指令
145
+ if args[:fop].is_a?(String) && args[:fop] != '' then
146
+ if download_url.index('?').is_a?(Fixnum) then
147
+ # 已有参数
148
+ download_url = "#{download_url}&#{args[:fop]}"
149
+ else
150
+ # 尚无参数
151
+ download_url = "#{download_url}?#{args[:fop]}"
152
+ end
153
+ end
154
+
155
+ ### 授权期计算
156
+ e = Auth.calculate_deadline(args[:expires_in], args[:deadline])
157
+
158
+ ### URL变换:追加授权期参数
159
+ if download_url.index('?').is_a?(Fixnum) then
160
+ # 已有参数
161
+ download_url = "#{download_url}&e=#{e}"
162
+ else
163
+ # 尚无参数
164
+ download_url = "#{download_url}?e=#{e}"
165
+ end
166
+
167
+ ### 生成数字签名
168
+ sign = HMAC::SHA1.new(secret_key).update(download_url).digest
169
+ encoded_sign = Utils.urlsafe_base64_encode(sign)
170
+
171
+ ### 生成下载授权凭证
172
+ dntoken = "#{access_key}:#{encoded_sign}"
173
+
174
+ ### 返回下载授权URL
175
+ return "#{download_url}&token=#{dntoken}"
176
+ end # authorize_download_url
177
+
178
+ def generate_acctoken(url, body = '')
179
+ ### 提取AK/SK信息
180
+ access_key = Config.settings[:access_key]
181
+ secret_key = Config.settings[:secret_key]
182
+
183
+ ### 解析URL,生成待签名字符串
184
+ uri = URI.parse(url)
185
+ signing_str = uri.path
186
+
187
+ # 如有QueryString部分,则需要加上
188
+ query_string = uri.query
189
+ if query_string.is_a?(String) && !query_string.empty?
190
+ signing_str += '?' + query_string
191
+ end
192
+
193
+ # 追加换行符
194
+ signing_str += "\n"
195
+
196
+ # 如果有Body,则也加上
197
+ # (仅限于mime == "application/x-www-form-urlencoded"的情况)
198
+ if body.is_a?(String) && !body.empty?
199
+ signing_str += body
200
+ end
201
+
202
+ ### 生成数字签名
203
+ sign = HMAC::SHA1.new(secret_key).update(signing_str).digest
204
+ encoded_sign = Utils.urlsafe_base64_encode(sign)
205
+
206
+ ### 生成管理授权凭证
207
+ acctoken = "#{access_key}:#{encoded_sign}"
208
+
209
+ ### 返回管理授权凭证
210
+ return acctoken
211
+ end # generate_acctoken
212
+
213
+ def generate_uptoken(put_policy)
214
+ ### 提取AK/SK信息
215
+ access_key = Config.settings[:access_key]
216
+ secret_key = Config.settings[:secret_key]
217
+
218
+ ### 生成待签名字符串
219
+ encoded_put_policy = Utils.urlsafe_base64_encode(put_policy.to_json)
220
+
221
+ ### 生成数字签名
222
+ sign = HMAC::SHA1.new(secret_key).update(encoded_put_policy).digest
223
+ encoded_sign = Utils.urlsafe_base64_encode(sign)
224
+
225
+ ### 生成上传授权凭证
226
+ uptoken = "#{access_key}:#{encoded_sign}:#{encoded_put_policy}"
227
+
228
+ ### 返回上传授权凭证
229
+ return uptoken
230
+ end # generate_uptoken
231
+ end # class << self
232
+
233
+ end # module Auth
234
+ end # module Qiniu