qiniu 6.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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