qiniu 6.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.
@@ -0,0 +1,2 @@
1
+ # More logical way to require 'qiniu-rs'
2
+ require File.join(File.dirname(__FILE__), 'qiniu', 'qiniu')
@@ -0,0 +1,229 @@
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 put_file opts = {}
58
+ code, data = Storage.put_file(opts[:file],
59
+ opts[:bucket],
60
+ opts[:key],
61
+ opts[:mime_type],
62
+ opts[:note],
63
+ opts[:enable_crc32_check])
64
+ code == StatusOK
65
+ end
66
+
67
+ def upload_file opts = {}
68
+ uncontained_opts = [:uptoken, :file, :bucket, :key] - opts.keys
69
+ raise MissingArgsError, uncontained_opts unless uncontained_opts.empty?
70
+
71
+ source_file = opts[:file]
72
+ raise NoSuchFileError, source_file unless File.exist?(source_file)
73
+
74
+ opts[:enable_resumable_upload] = true unless opts.has_key?(:enable_resumable_upload)
75
+
76
+ if opts[:enable_resumable_upload] && File::size(source_file) > Config.settings[:block_size]
77
+ code, data = Storage.upload_with_token(opts[:uptoken],
78
+ opts[:file],
79
+ opts[:bucket],
80
+ opts[:key],
81
+ opts[:mime_type],
82
+ opts[:note],
83
+ opts[:customer],
84
+ opts[:callback_params],
85
+ opts[:rotate])
86
+ else
87
+ code, data = Storage.upload_with_token(opts[:uptoken],
88
+ opts[:file],
89
+ opts[:bucket],
90
+ opts[:key],
91
+ opts[:mime_type],
92
+ opts[:note],
93
+ opts[:callback_params],
94
+ opts[:enable_crc32_check],
95
+ opts[:rotate])
96
+ end
97
+ raise UploadFailedError.new(code, data) if code != StatusOK
98
+ return data
99
+ end
100
+
101
+ def stat(bucket, key)
102
+ code, data = Storage.stat(bucket, key)
103
+ code == StatusOK ? data : false
104
+ end
105
+
106
+ def get(bucket, key, save_as = nil, expires_in = nil, version = nil)
107
+ code, data = Storage.get(bucket, key, save_as, expires_in, version)
108
+ code == StatusOK ? data : false
109
+ end
110
+
111
+ def download(bucket, key, save_as = nil, expires_in = nil, version = nil)
112
+ code, data = Storage.get(bucket, key, save_as, expires_in, version)
113
+ code == StatusOK ? data["url"] : false
114
+ end
115
+
116
+ def copy(source_bucket, source_key, target_bucket, target_key)
117
+ code, data = Storage.copy(source_bucket, source_key, target_bucket, target_key)
118
+ code == StatusOK
119
+ end
120
+
121
+ def move(source_bucket, source_key, target_bucket, target_key)
122
+ code, data = Storage.move(source_bucket, source_key, target_bucket, target_key)
123
+ code == StatusOK
124
+ end
125
+
126
+ def delete(bucket, key)
127
+ code, data = Storage.delete(bucket, key)
128
+ code == StatusOK
129
+ end
130
+
131
+ def batch(command, bucket, keys)
132
+ code, data = Storage.batch(command, bucket, keys)
133
+ code == StatusOK ? data : false
134
+ end
135
+
136
+ def batch_stat(bucket, keys)
137
+ code, data = Storage.batch_stat(bucket, keys)
138
+ code == StatusOK ? data : false
139
+ end
140
+
141
+ def batch_get(bucket, keys)
142
+ code, data = Storage.batch_get(bucket, keys)
143
+ code == StatusOK ? data : false
144
+ end
145
+
146
+ def batch_copy(*args)
147
+ code, data = Storage.batch_copy(args)
148
+ code == StatusOK
149
+ end
150
+
151
+ def batch_move(*args)
152
+ code, data = Storage.batch_move(args)
153
+ code == StatusOK
154
+ end
155
+
156
+ def batch_download(bucket, keys)
157
+ code, data = Storage.batch_get(bucket, keys)
158
+ return false unless code == StatusOK
159
+ links = []
160
+ data.each { |e| links << e["data"]["url"] }
161
+ links
162
+ end
163
+
164
+ def batch_delete(bucket, keys)
165
+ code, data = Storage.batch_delete(bucket, keys)
166
+ code == StatusOK ? data : false
167
+ end
168
+
169
+ def publish(domain, bucket)
170
+ code, data = Storage.publish(domain, bucket)
171
+ code == StatusOK
172
+ end
173
+
174
+ def unpublish(domain)
175
+ code, data = Storage.unpublish(domain)
176
+ code == StatusOK
177
+ end
178
+
179
+ def drop(bucket)
180
+ code, data = Storage.drop(bucket)
181
+ code == StatusOK
182
+ end
183
+
184
+ def image_info(url)
185
+ code, data = Fop::Image.info(url)
186
+ code == StatusOK ? data : false
187
+ end
188
+
189
+ def image_exif(url)
190
+ code, data = Fop::Image.exif(url)
191
+ code == StatusOK ? data : false
192
+ end
193
+
194
+ def image_mogrify_preview_url(source_image_url, options)
195
+ Fop::Image.mogrify_preview_url(source_image_url, options)
196
+ end
197
+
198
+ def image_mogrify_save_as(bucket, key, source_image_url, options)
199
+ code, data = Storage.image_mogrify_save_as(bucket, key, source_image_url, options)
200
+ code == StatusOK ? data : false
201
+ end
202
+
203
+ def generate_upload_token(opts = {})
204
+ token_obj = UploadToken.new(opts)
205
+ token_obj.access_key = Config.settings[:access_key]
206
+ token_obj.secret_key = Config.settings[:secret_key]
207
+ #token_obj.scope = opts[:scope]
208
+ #token_obj.expires_in = opts[:expires_in]
209
+ #token_obj.callback_url = opts[:callback_url]
210
+ #token_obj.callback_body_type = opts[:callback_body_type]
211
+ #token_obj.customer = opts[:customer]
212
+ #token_obj.escape = opts[:escape]
213
+ #token_obj.async_options = opts[:async_options]
214
+ #token_obj.return_body = opts[:return_body]
215
+ token_obj.generate_token
216
+ end
217
+
218
+ def generate_download_token(opts = {})
219
+ token_obj = DownloadToken.new(opts)
220
+ token_obj.access_key = Config.settings[:access_key]
221
+ token_obj.secret_key = Config.settings[:secret_key]
222
+ #token_obj.expires_in = opts[:expires_in]
223
+ #token_obj.pattern = opts[:pattern]
224
+ token_obj.generate_token
225
+ end
226
+
227
+ end
228
+
229
+ 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
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'qiniu/exceptions'
4
+
5
+ module Qiniu
6
+ module Auth
7
+
8
+ class << self
9
+
10
+ include Utils
11
+
12
+ def call_with_signature(url, data, retry_times = 0, options = {})
13
+ code, data = http_request url, data, options.merge({:qbox_signature_token => generate_qbox_signature(url, data, options[:mime])})
14
+ [code, data]
15
+ end
16
+
17
+ def request(url, data = nil, options = {})
18
+ code, data = Auth.call_with_signature(url, data, 0, options)
19
+ [code, data]
20
+ end
21
+
22
+ end
23
+
24
+ end # module Auth
25
+ end # module Qiniu
@@ -0,0 +1,61 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ # USAGE WAY 1:
4
+ # Qbox::Config.initialize_connect :client_id => "<ClientID>",
5
+ # :client_secret => "<ClientSecret>"
6
+ #
7
+ # USAGE WAY 2:
8
+ # Qbox::Config.load "path/to/your_project/config/qiniu.yml"
9
+ #
10
+
11
+ require 'tmpdir'
12
+
13
+ module Qiniu
14
+ module Config
15
+ class << self
16
+
17
+ DEFAULT_OPTIONS = {
18
+ :user_agent => 'Qiniu-RS-Ruby-SDK-' + Version.to_s + '()',
19
+ :method => :post,
20
+ :content_type => 'application/x-www-form-urlencoded',
21
+ :auth_url => "https://acc.qbox.me/oauth2/token",
22
+ :rs_host => "http://rs.qiniu.com",
23
+ :io_host => "http://iovip.qbox.me",
24
+ :up_host => "http://up.qiniu.com",
25
+ :pub_host => "http://pu.qbox.me:10200",
26
+ :eu_host => "http://eu.qbox.me",
27
+ :client_id => "a75604760c4da4caaa456c0c5895c061c3065c5a",
28
+ :client_secret => "75df554a39f58accb7eb293b550fa59618674b7d",
29
+ :access_key => "",
30
+ :secret_key => "",
31
+ :auto_reconnect => true,
32
+ :max_retry_times => 3,
33
+ :block_size => 1024*1024*4,
34
+ :chunk_size => 1024*256,
35
+ :enable_debug => true,
36
+ :tmpdir => Dir.tmpdir + File::SEPARATOR + 'Qiniu-RS-Ruby-SDK'
37
+ }
38
+
39
+ REQUIRED_OPTION_KEYS = [:access_key, :secret_key]
40
+
41
+ attr_reader :settings, :default_params
42
+
43
+ def load config_file
44
+ if File.exist?(config_file)
45
+ config_options = YAML.load_file(config_file)
46
+ initialize_connect(config_options)
47
+ else
48
+ raise MissingConfError, config_file
49
+ end
50
+ end
51
+
52
+ def initialize_connect options = {}
53
+ @settings = DEFAULT_OPTIONS.merge(options)
54
+ REQUIRED_OPTION_KEYS.each do |opt|
55
+ raise MissingArgsError, [opt] unless @settings.has_key?(opt)
56
+ end
57
+ end
58
+
59
+ end
60
+ end # module Config
61
+ end # module Qiniu
@@ -0,0 +1,120 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ module Qiniu
4
+
5
+ class Exception < RuntimeError
6
+ end
7
+
8
+ class ResponseError < Exception
9
+ attr_reader :response
10
+
11
+ def initialize(message, response = nil)
12
+ @response = response
13
+ super(message)
14
+ end
15
+
16
+ def http_code
17
+ @response.code.to_i if @response
18
+ end
19
+
20
+ def http_body
21
+ @response.body if @response
22
+ end
23
+
24
+ def inspect
25
+ "#{message}: #{http_body}"
26
+ end
27
+ end
28
+
29
+ class RequestFailed < ResponseError
30
+ def message
31
+ "HTTP status code: #{http_code}. Response body: #{http_body}"
32
+ end
33
+
34
+ def to_s
35
+ message
36
+ end
37
+ end
38
+
39
+ class UploadFailedError < Exception
40
+ def initialize(status_code, response_data)
41
+ data_string = response_data.map { |key, value| %Q(:#{key.to_s} => #{value.to_s}) }
42
+ msg = %Q(Uploading Failed. HTTP Status Code: #{status_code}. HTTP response body: #{data_string.join(', ')}.)
43
+ super(msg)
44
+ end
45
+ end
46
+
47
+ class FileSeekReadError < Exception
48
+ def initialize(fpath, block_index, seek_pos, read_length, result_length)
49
+ msg = "Reading file: #{fpath}, "
50
+ msg += "at block index: #{block_index}. "
51
+ msg += "Expected seek_pos:#{seek_pos} and read_length:#{read_length}, "
52
+ msg += "but got result_length: #{result_length}."
53
+ super(msg)
54
+ end
55
+ end
56
+
57
+ class BlockSizeNotMathchError < Exception
58
+ def initialize(fpath, block_index, offset, restsize, block_size)
59
+ msg = "Reading file: #{fpath}, "
60
+ msg += "at block index: #{block_index}. "
61
+ msg += "Expected offset: #{offset}, restsize: #{restsize} and block_size: #{block_size}, "
62
+ msg += "but got offset+restsize=#{offset+restsize}."
63
+ super(msg)
64
+ end
65
+ end
66
+
67
+ class BlockCountNotMathchError < Exception
68
+ def initialize(fpath, block_count, checksum_count, progress_count)
69
+ msg = "Reading file: #{fpath}, "
70
+ msg += "Expected block_count, checksum_count, progress_count is: #{block_count}, "
71
+ msg += "but got checksum_count: #{checksum_count}, progress_count: #{progress_count}."
72
+ super(msg)
73
+ end
74
+ end
75
+
76
+ class MissingArgsError < Exception
77
+ def initialize(missing_keys)
78
+ key_list = missing_keys.map {|key| key.to_s}.join(' and the ')
79
+ super("You did not provide both required args. Please provide the #{key_list}.")
80
+ end
81
+ end
82
+
83
+ class MissingAccessToken < MissingArgsError
84
+ def initialize
85
+ super([:access_token])
86
+ end
87
+ end
88
+
89
+ class MissingRefreshToken < MissingArgsError
90
+ def initialize
91
+ super([:refresh_token])
92
+ end
93
+ end
94
+
95
+ class MissingUsernameOrPassword < MissingArgsError
96
+ def initialize
97
+ super([:username, :password])
98
+ end
99
+ end
100
+
101
+ class InvalidArgsError < Exception
102
+ def initialize(invalid_keys)
103
+ key_list = invalid_keys.map {|key| key.to_s}.join(' and the ')
104
+ super("#{key_list} should not be empty.")
105
+ end
106
+ end
107
+
108
+ class MissingConfError < Exception
109
+ def initialize(missing_conf_file)
110
+ super("Error, missing #{missing_conf_file}. You must have #{missing_conf_file} to configure your client id and secret.")
111
+ end
112
+ end
113
+
114
+ class NoSuchFileError < Exception
115
+ def initialize(missing_file)
116
+ super("Error, no such file #{missing_file}.")
117
+ end
118
+ end
119
+
120
+ end # module Qiniu