dropbox-sdk 1.0.beta → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -0
- data/cli_example.rb +5 -5
- data/lib/dropbox_sdk.rb +198 -115
- metadata +10 -27
data/CHANGELOG
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
1.1 (2011-10-17)
|
2
|
+
* Various bug fixes found during beta period
|
3
|
+
* Improved documentation
|
4
|
+
* Improved module structure
|
5
|
+
* Removed dependency on the oauth module, using plaintext authentication over https
|
6
|
+
|
1
7
|
1.0 (2011-8-16)
|
2
8
|
* Backwards compatibility broken
|
3
9
|
- Changed interface
|
data/cli_example.rb
CHANGED
@@ -10,8 +10,8 @@ require 'pp'
|
|
10
10
|
|
11
11
|
# You must use your Dropbox App key and secret to use the API.
|
12
12
|
# Find this at https://www.dropbox.com/developers
|
13
|
-
APP_KEY =
|
14
|
-
APP_SECRET =
|
13
|
+
APP_KEY = ''
|
14
|
+
APP_SECRET = ''
|
15
15
|
ACCESS_TYPE = :app_folder #The two valid values here are :app_folder and :dropbox
|
16
16
|
#The default is :app_folder, but your application might be
|
17
17
|
#set to have full :dropbox access. Check your app at
|
@@ -46,7 +46,7 @@ class DropboxCLI
|
|
46
46
|
@session.get_request_token
|
47
47
|
|
48
48
|
authorize_url = @session.get_authorize_url
|
49
|
-
puts "Got a request token. Your request token key is #{@session.
|
49
|
+
puts "Got a request token. Your request token key is #{@session.request_token.key} and your token secret is #{@session.request_token.secret}"
|
50
50
|
|
51
51
|
# make the user log in and authorize this token
|
52
52
|
puts "AUTHORIZING", authorize_url, "Please visit that web page and hit 'Allow', then hit Enter here."
|
@@ -56,7 +56,7 @@ class DropboxCLI
|
|
56
56
|
@session.get_access_token
|
57
57
|
|
58
58
|
end
|
59
|
-
puts "You are logged in. Your access token key is #{@session.
|
59
|
+
puts "You are logged in. Your access token key is #{@session.access_token.key} your secret is #{@session.access_token.secret}"
|
60
60
|
@client = DropboxClient.new(@session, ACCESS_TYPE)
|
61
61
|
end
|
62
62
|
|
@@ -95,7 +95,7 @@ class DropboxCLI
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
-
def logout
|
98
|
+
def logout(command)
|
99
99
|
@session.clear_access_token
|
100
100
|
puts "You are logged out."
|
101
101
|
@client = nil
|
data/lib/dropbox_sdk.rb
CHANGED
@@ -1,56 +1,142 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require 'oauth'
|
3
|
-
require 'json'
|
4
2
|
require 'uri'
|
3
|
+
require 'net/https'
|
4
|
+
require 'cgi'
|
5
|
+
require 'json'
|
5
6
|
require 'yaml'
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
module Dropbox
|
9
|
+
API_SERVER = "api.dropbox.com"
|
10
|
+
API_CONTENT_SERVER = "api-content.dropbox.com"
|
11
|
+
WEB_SERVER = "www.dropbox.com"
|
9
12
|
|
10
|
-
API_VERSION = 1
|
13
|
+
API_VERSION = 1
|
14
|
+
SDK_VERSION = "1.1"
|
15
|
+
end
|
11
16
|
|
12
17
|
# DropboxSession is responsible for holding OAuth information. It knows how to take your consumer key and secret
|
13
18
|
# and request an access token, an authorize url, and get an access token. You just need to pass it to
|
14
19
|
# DropboxClient after its been authorized.
|
15
20
|
class DropboxSession
|
16
|
-
def initialize(key, secret)
|
17
|
-
@consumer_key = key
|
18
|
-
@consumer_secret = secret
|
19
|
-
@oauth_conf = {
|
20
|
-
:site => "https://" + DROPBOX_API_SERVER,
|
21
|
-
:scheme => :header,
|
22
|
-
:http_method => :post,
|
23
|
-
:request_token_url => "/#{API_VERSION}/oauth/request_token",
|
24
|
-
:access_token_url => "/#{API_VERSION}/oauth/access_token",
|
25
|
-
:authorize_url => "/#{API_VERSION}/oauth/authorize",
|
26
|
-
}
|
27
21
|
|
28
|
-
|
29
|
-
@
|
22
|
+
def initialize(consumer_key, consumer_secret)
|
23
|
+
@consumer_key = consumer_key
|
24
|
+
@consumer_secret = consumer_secret
|
30
25
|
@request_token = nil
|
26
|
+
@access_token = nil
|
31
27
|
end
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
def
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
29
|
+
private
|
30
|
+
|
31
|
+
def do_http(uri, auth_token, request) # :nodoc:
|
32
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
33
|
+
http.use_ssl = true
|
34
|
+
|
35
|
+
request.add_field('Authorization', build_auth_header(auth_token))
|
36
|
+
|
37
|
+
#We use this to better understand how developers are using our SDKs.
|
38
|
+
request['User-Agent'] = "OfficialDropboxRubySDK/#{Dropbox::SDK_VERSION}"
|
39
|
+
|
40
|
+
http.request(request)
|
41
|
+
end
|
42
|
+
|
43
|
+
def build_auth_header(token) # :nodoc:
|
44
|
+
header = "OAuth oauth_version=\"1.0\", oauth_signature_method=\"PLAINTEXT\", " +
|
45
|
+
"oauth_consumer_key=\"#{URI.escape(@consumer_key)}\", "
|
46
|
+
if token
|
47
|
+
key = URI.escape(token.key)
|
48
|
+
secret = URI.escape(token.secret)
|
49
|
+
header += "oauth_token=\"#{key}\", oauth_signature=\"#{URI.escape(@consumer_secret)}&#{secret}\""
|
50
|
+
else
|
51
|
+
header += "oauth_signature=\"#{URI.escape(@consumer_secret)}&\""
|
52
|
+
end
|
53
|
+
header
|
54
|
+
end
|
55
|
+
|
56
|
+
def do_get_with_token(url, token, headers=nil) # :nodoc:
|
57
|
+
uri = URI.parse(url)
|
58
|
+
do_http(uri, token, Net::HTTP::Get.new(uri.request_uri))
|
59
|
+
end
|
60
|
+
|
61
|
+
public
|
62
|
+
|
63
|
+
def do_get(url, headers=nil) # :nodoc:
|
64
|
+
assert_authorized
|
65
|
+
do_get_with_token(url, @access_token)
|
66
|
+
end
|
67
|
+
|
68
|
+
def do_http_with_body(uri, request, body)
|
69
|
+
if body != nil
|
70
|
+
if body.is_a?(Hash)
|
71
|
+
form_data = {}
|
72
|
+
body.each {|k,v| form_data[k.to_s] = v if !v.nil?}
|
73
|
+
request.set_form_data(form_data)
|
74
|
+
elsif body.respond_to?(:read)
|
75
|
+
if body.respond_to?(:length)
|
76
|
+
request["Content-Length"] = body.length.to_s
|
77
|
+
elsif body.respond_to?(:stat) && body.stat.respond_to?(:size)
|
78
|
+
request["Content-Length"] = body.stat.size.to_s
|
79
|
+
else
|
80
|
+
raise ArgumentError, "Don't know how to handle 'body' (responds to 'read' but not to 'length' or 'stat.size')."
|
81
|
+
end
|
82
|
+
request.body_stream = body
|
83
|
+
else
|
84
|
+
s = body.to_s
|
85
|
+
request["Content-Length"] = s.length
|
86
|
+
request.body = s
|
87
|
+
end
|
88
|
+
end
|
89
|
+
do_http(uri, @access_token, request)
|
90
|
+
end
|
91
|
+
|
92
|
+
def do_post(url, headers=nil, body=nil) # :nodoc:
|
93
|
+
assert_authorized
|
94
|
+
uri = URI.parse(url)
|
95
|
+
do_http_with_body(uri, Net::HTTP::Post.new(uri.request_uri, headers), body)
|
96
|
+
end
|
97
|
+
|
98
|
+
def do_put(url, headers=nil, body=nil) # :nodoc:
|
99
|
+
assert_authorized
|
100
|
+
uri = URI.parse(url)
|
101
|
+
do_http_with_body(uri, Net::HTTP::Put.new(uri.request_uri, headers), body)
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
def get_token(url_end, input_token, error_message_prefix) #: nodoc:
|
106
|
+
response = do_get_with_token("https://#{Dropbox::API_SERVER}:443/#{Dropbox::API_VERSION}/oauth#{url_end}", input_token)
|
107
|
+
if not response.kind_of?(Net::HTTPSuccess) # it must be a 200
|
108
|
+
raise DropboxAuthError.new("#{error_message_prefix} Server returned #{response.code}: #{response.message}.", response)
|
109
|
+
end
|
110
|
+
parts = CGI.parse(response.body)
|
111
|
+
if !parts.has_key? "oauth_token" and parts["oauth_token"].length != 1
|
112
|
+
raise DropboxAuthError.new("Invalid response from #{url_end}: missing \"oauth_token\" parameter: #{response.body}", response)
|
40
113
|
end
|
114
|
+
if !parts.has_key? "oauth_token_secret" and parts["oauth_token_secret"].length != 1
|
115
|
+
raise DropboxAuthError.new("Invalid response from #{url_end}: missing \"oauth_token\" parameter: #{response.body}", response)
|
116
|
+
end
|
117
|
+
|
118
|
+
OAuthToken.new(parts["oauth_token"][0], parts["oauth_token_secret"][0])
|
119
|
+
end
|
120
|
+
|
121
|
+
# This returns a request token. Requests one from the dropbox server using the provided application key and secret if nessecary.
|
122
|
+
def get_request_token()
|
123
|
+
@request_token ||= get_token("/request_token", nil, "Error getting request token. Is your app key and secret correctly set?")
|
41
124
|
end
|
42
125
|
|
43
126
|
# This returns a URL that your user must visit to grant
|
44
127
|
# permissions to this application.
|
45
|
-
def get_authorize_url(callback=nil
|
46
|
-
get_request_token(
|
128
|
+
def get_authorize_url(callback=nil)
|
129
|
+
get_request_token()
|
47
130
|
|
48
|
-
url = @request_token.
|
131
|
+
url = "/#{Dropbox::API_VERSION}/oauth/authorize?oauth_token=#{URI.escape(@request_token.key)}"
|
49
132
|
if callback
|
50
|
-
url +=
|
133
|
+
url += "&oauth_callback=#{URI.escape(callback)}"
|
134
|
+
end
|
135
|
+
if @locale
|
136
|
+
url += "&locale=#{URI.escape(@locale)}"
|
51
137
|
end
|
52
138
|
|
53
|
-
"https
|
139
|
+
"https://#{Dropbox::WEB_SERVER}#{url}"
|
54
140
|
end
|
55
141
|
|
56
142
|
# Clears the access_token
|
@@ -58,51 +144,48 @@ class DropboxSession
|
|
58
144
|
@access_token = nil
|
59
145
|
end
|
60
146
|
|
147
|
+
# Returns the request token, or nil if one hasn't been acquired yet.
|
148
|
+
def request_token
|
149
|
+
@request_token
|
150
|
+
end
|
151
|
+
|
152
|
+
# Returns the access token, or nil if one hasn't been acquired yet.
|
153
|
+
def access_token
|
154
|
+
@access_token
|
155
|
+
end
|
156
|
+
|
61
157
|
# Given a saved request token and secret, set this location's token and secret
|
62
158
|
# * token - this is the request token
|
63
159
|
# * secret - this is the request token secret
|
64
160
|
def set_request_token(key, secret)
|
65
|
-
@request_token =
|
161
|
+
@request_token = OAuthToken.new(key, secret)
|
66
162
|
end
|
67
163
|
|
68
164
|
# Given a saved access token and secret, you set this Session to use that token and secret
|
69
165
|
# * token - this is the access token
|
70
166
|
# * secret - this is the access token secret
|
71
167
|
def set_access_token(key, secret)
|
72
|
-
@access_token =
|
73
|
-
end
|
74
|
-
|
75
|
-
def check_authorized
|
76
|
-
##this check is applied before the token and secret methods
|
77
|
-
raise DropboxError.new('Session does not yet have a request token') unless authorized?
|
78
|
-
end
|
79
|
-
|
80
|
-
# Returns the current oauth access or request token.
|
81
|
-
def token
|
82
|
-
(@access_token || @request_token).token
|
83
|
-
end
|
84
|
-
|
85
|
-
# Returns the current oauth access or request token secret.
|
86
|
-
def secret
|
87
|
-
(@access_token || @request_token).secret
|
168
|
+
@access_token = OAuthToken.new(key, secret)
|
88
169
|
end
|
89
170
|
|
90
171
|
# Returns the access token. If this DropboxSession doesn't yet have an access_token, it requests one
|
91
172
|
# using the request_token generate from your app's token and secret. This request will fail unless
|
92
|
-
# your user has
|
173
|
+
# your user has gone to the authorize_url and approved your request
|
93
174
|
def get_access_token
|
94
|
-
|
95
|
-
if @request_token.nil?
|
96
|
-
raise DropboxAuthError.new("No request token. You must set this or get an authorize url first.")
|
97
|
-
end
|
175
|
+
return @access_token if authorized?
|
98
176
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
177
|
+
if @request_token.nil?
|
178
|
+
raise DropboxAuthError.new("No request token. You must set this or get an authorize url first.")
|
179
|
+
end
|
180
|
+
|
181
|
+
@access_token = get_token("/access_token", @request_token, "Couldn't get access token.")
|
182
|
+
end
|
183
|
+
|
184
|
+
# If we have an access token, then do nothing. If not, throw a RuntimeError.
|
185
|
+
def assert_authorized
|
186
|
+
unless authorized?
|
187
|
+
raise RuntimeError.new('Session does not yet have a request token')
|
104
188
|
end
|
105
|
-
@access_token
|
106
189
|
end
|
107
190
|
|
108
191
|
# Returns true if this Session has been authorized and has an access_token.
|
@@ -112,24 +195,24 @@ class DropboxSession
|
|
112
195
|
|
113
196
|
# serialize the DropboxSession.
|
114
197
|
# At DropboxSession's state is capture in three key/secret pairs. Consumer, request, and access.
|
115
|
-
#
|
198
|
+
# Serialize returns these in a YAML string, generated from a converted array of the form:
|
116
199
|
# [consumer_key, consumer_secret, request_token.token, request_token.secret, access_token.token, access_token.secret]
|
117
200
|
# access_token is only included if it already exists in the DropboxSesssion
|
118
201
|
def serialize
|
119
202
|
toreturn = []
|
120
203
|
if @access_token
|
121
|
-
toreturn.push @access_token.secret, @access_token.
|
204
|
+
toreturn.push @access_token.secret, @access_token.key
|
122
205
|
end
|
123
206
|
|
124
|
-
get_request_token
|
207
|
+
get_request_token
|
125
208
|
|
126
|
-
toreturn.push @request_token.secret, @request_token.
|
209
|
+
toreturn.push @request_token.secret, @request_token.key
|
127
210
|
toreturn.push @consumer_secret, @consumer_key
|
128
211
|
|
129
212
|
toreturn.to_yaml
|
130
213
|
end
|
131
214
|
|
132
|
-
# Takes a serialized DropboxSession and returns a new DropboxSession object
|
215
|
+
# Takes a serialized DropboxSession YAML String and returns a new DropboxSession object
|
133
216
|
def self.deserialize(ser)
|
134
217
|
ser = YAML::load(ser)
|
135
218
|
session = DropboxSession.new(ser.pop, ser.pop)
|
@@ -143,6 +226,22 @@ class DropboxSession
|
|
143
226
|
end
|
144
227
|
|
145
228
|
|
229
|
+
# A class that represents either an OAuth request token or an OAuth access token.
|
230
|
+
class OAuthToken
|
231
|
+
def initialize(key, secret)
|
232
|
+
@key = key
|
233
|
+
@secret = secret
|
234
|
+
end
|
235
|
+
|
236
|
+
def key
|
237
|
+
@key
|
238
|
+
end
|
239
|
+
|
240
|
+
def secret
|
241
|
+
@secret
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
146
245
|
|
147
246
|
# This is the usual error raised on any Dropbox related Errors
|
148
247
|
class DropboxError < RuntimeError
|
@@ -179,15 +278,7 @@ class DropboxClient
|
|
179
278
|
# Initialize a new DropboxClient. You need to get it a session which either has been authorized. See
|
180
279
|
# documentation on DropboxSession for how to authorize it.
|
181
280
|
def initialize(session, root="app_folder", locale=nil)
|
182
|
-
|
183
|
-
begin
|
184
|
-
## attempt to get an access token and authorize the session
|
185
|
-
session.get_access_token
|
186
|
-
rescue OAuth::Unauthorized => e
|
187
|
-
raise DropboxAuthError.new("Could not initialize. Failed to get access token from Session. Error was: #{ e.message }")
|
188
|
-
# If this was raised, the user probably didn't go to auth.get_authorize_url
|
189
|
-
end
|
190
|
-
end
|
281
|
+
session.get_access_token
|
191
282
|
|
192
283
|
@root = root.to_s # If they passed in a symbol, make it a string
|
193
284
|
|
@@ -196,15 +287,12 @@ class DropboxClient
|
|
196
287
|
end
|
197
288
|
if @root == "app_folder"
|
198
289
|
#App Folder is the name of the access type, but for historical reasons
|
199
|
-
#sandbox is the URL root
|
290
|
+
#sandbox is the URL root component that indicates this
|
200
291
|
@root = "sandbox"
|
201
292
|
end
|
202
293
|
|
203
294
|
@locale = locale
|
204
295
|
@session = session
|
205
|
-
@token = session.get_access_token
|
206
|
-
|
207
|
-
#There's no gurantee that @token is still valid, so be sure to handle any DropboxAuthErrors that can be raised
|
208
296
|
end
|
209
297
|
|
210
298
|
# Parse response. You probably shouldn't be calling this directly. This takes responses from the server
|
@@ -236,7 +324,6 @@ class DropboxClient
|
|
236
324
|
rescue JSON::ParserError
|
237
325
|
raise DropboxError.new("Unable to parse JSON response", response)
|
238
326
|
end
|
239
|
-
|
240
327
|
end
|
241
328
|
|
242
329
|
|
@@ -245,7 +332,7 @@ class DropboxClient
|
|
245
332
|
# For a detailed description of what this call returns, visit:
|
246
333
|
# https://www.dropbox.com/developers/docs#account-info
|
247
334
|
def account_info()
|
248
|
-
response = @
|
335
|
+
response = @session.do_get build_url("/account/info")
|
249
336
|
parse_response(response)
|
250
337
|
end
|
251
338
|
|
@@ -254,7 +341,7 @@ class DropboxClient
|
|
254
341
|
# Arguments:
|
255
342
|
# * to_path: The directory path to upload the file to. If the destination
|
256
343
|
# directory does not yet exist, it will be created.
|
257
|
-
# * file_obj: A file-like object to upload. If you would like, you can
|
344
|
+
# * file_obj: A file-like object to upload. If you would like, you can
|
258
345
|
# pass a string as file_obj.
|
259
346
|
# * overwrite: Whether to overwrite an existing file at the given path. [default is False]
|
260
347
|
# If overwrite is False and a file already exists there, Dropbox
|
@@ -275,14 +362,13 @@ class DropboxClient
|
|
275
362
|
# * a Hash containing the metadata of the newly uploaded file. The file may have a different name if it conflicted.
|
276
363
|
#
|
277
364
|
# Simple Example
|
278
|
-
# client = DropboxClient(session,
|
365
|
+
# client = DropboxClient(session, :app_folder)
|
279
366
|
# #session is a DropboxSession I've already authorized
|
280
367
|
# client.put_file('/test_file_on_dropbox', open('/tmp/test_file'))
|
281
368
|
# This will upload the "/tmp/test_file" from my computer into the root of my App's app folder
|
282
369
|
# and call it "test_file_on_dropbox".
|
283
370
|
# The file will not overwrite any pre-existing file.
|
284
371
|
def put_file(to_path, file_obj, overwrite=false, parent_rev=nil)
|
285
|
-
|
286
372
|
path = "/files_put/#{@root}#{format_path(to_path)}"
|
287
373
|
|
288
374
|
params = {
|
@@ -291,9 +377,9 @@ class DropboxClient
|
|
291
377
|
|
292
378
|
params['parent_rev'] = parent_rev unless parent_rev.nil?
|
293
379
|
|
294
|
-
response = @
|
295
|
-
|
296
|
-
|
380
|
+
response = @session.do_put(build_url(path, params, content_server=true),
|
381
|
+
{"Content-Type" => "application/octet-stream"},
|
382
|
+
file_obj)
|
297
383
|
|
298
384
|
parse_response(response)
|
299
385
|
end
|
@@ -311,7 +397,7 @@ class DropboxClient
|
|
311
397
|
params['rev'] = rev.to_s if rev
|
312
398
|
|
313
399
|
path = "/files/#{@root}#{format_path(from_path)}"
|
314
|
-
response = @
|
400
|
+
response = @session.do_get build_url(path, params, content_server=true)
|
315
401
|
|
316
402
|
parse_response(response, raw=true)
|
317
403
|
end
|
@@ -336,7 +422,7 @@ class DropboxClient
|
|
336
422
|
"from_path" => format_path(from_path, false),
|
337
423
|
"to_path" => format_path(to_path, false),
|
338
424
|
}
|
339
|
-
response = @
|
425
|
+
response = @session.do_post build_url("/fileops/copy", params)
|
340
426
|
parse_response(response)
|
341
427
|
end
|
342
428
|
|
@@ -352,9 +438,9 @@ class DropboxClient
|
|
352
438
|
def file_create_folder(path)
|
353
439
|
params = {
|
354
440
|
"root" => @root,
|
355
|
-
"path" => format_path(
|
441
|
+
"path" => format_path(path, false),
|
356
442
|
}
|
357
|
-
response = @
|
443
|
+
response = @session.do_post build_url("/fileops/create_folder", params)
|
358
444
|
|
359
445
|
parse_response(response)
|
360
446
|
end
|
@@ -371,9 +457,9 @@ class DropboxClient
|
|
371
457
|
def file_delete(path)
|
372
458
|
params = {
|
373
459
|
"root" => @root,
|
374
|
-
"path" => format_path(
|
460
|
+
"path" => format_path(path, false),
|
375
461
|
}
|
376
|
-
response = @
|
462
|
+
response = @session.do_post build_url("/fileops/delete", params)
|
377
463
|
parse_response(response)
|
378
464
|
end
|
379
465
|
|
@@ -394,7 +480,7 @@ class DropboxClient
|
|
394
480
|
"from_path" => format_path(from_path, false),
|
395
481
|
"to_path" => format_path(to_path, false),
|
396
482
|
}
|
397
|
-
response = @
|
483
|
+
response = @session.do_post build_url("/fileops/move", params)
|
398
484
|
parse_response(response)
|
399
485
|
end
|
400
486
|
|
@@ -425,7 +511,7 @@ class DropboxClient
|
|
425
511
|
|
426
512
|
params["hash"] = hash if hash
|
427
513
|
|
428
|
-
response = @
|
514
|
+
response = @session.do_get build_url("/metadata/#{@root}#{format_path(path)}", params=params)
|
429
515
|
if response.kind_of? Net::HTTPRedirection
|
430
516
|
raise DropboxNotModified.new("metadata not modified")
|
431
517
|
end
|
@@ -447,16 +533,14 @@ class DropboxClient
|
|
447
533
|
# inside path. For a detailed description of what this call returns, visit:
|
448
534
|
# https://www.dropbox.com/developers/docs#search
|
449
535
|
def search(path, query, file_limit=10000, include_deleted=false)
|
450
|
-
|
451
536
|
params = {
|
452
537
|
'query' => query,
|
453
538
|
'file_limit' => file_limit.to_s,
|
454
539
|
'include_deleted' => include_deleted.to_s
|
455
540
|
}
|
456
541
|
|
457
|
-
response = @
|
542
|
+
response = @session.do_get build_url("/search/#{@root}#{format_path(path)}", params)
|
458
543
|
parse_response(response)
|
459
|
-
|
460
544
|
end
|
461
545
|
|
462
546
|
# Retrive revisions of a file
|
@@ -478,7 +562,7 @@ class DropboxClient
|
|
478
562
|
'rev_limit' => rev_limit.to_s
|
479
563
|
}
|
480
564
|
|
481
|
-
response = @
|
565
|
+
response = @session.do_get build_url("/revisions/#{@root}#{format_path(path)}", params)
|
482
566
|
parse_response(response)
|
483
567
|
|
484
568
|
end
|
@@ -498,7 +582,7 @@ class DropboxClient
|
|
498
582
|
'rev' => rev.to_s
|
499
583
|
}
|
500
584
|
|
501
|
-
response = @
|
585
|
+
response = @session.do_post build_url("/restore/#{@root}#{format_path(path)}", params)
|
502
586
|
parse_response(response)
|
503
587
|
end
|
504
588
|
|
@@ -515,7 +599,7 @@ class DropboxClient
|
|
515
599
|
# * A Hash object that looks like the following:
|
516
600
|
# {'url': 'https://dl.dropbox.com/0/view/wvxv1fw6on24qw7/file.mov', 'expires': 'Thu, 16 Sep 2011 01:01:25 +0000'}
|
517
601
|
def media(path)
|
518
|
-
response = @
|
602
|
+
response = @session.do_get build_url("/media/#{@root}#{format_path(path)}")
|
519
603
|
parse_response(response)
|
520
604
|
end
|
521
605
|
|
@@ -534,7 +618,7 @@ class DropboxClient
|
|
534
618
|
# For a detailed description of what this call returns, visit:
|
535
619
|
# https://www.dropbox.com/developers/docs#share
|
536
620
|
def shares(path)
|
537
|
-
response = @
|
621
|
+
response = @session.do_get build_url("/shares/#{@root}#{format_path(path)}")
|
538
622
|
parse_response(response)
|
539
623
|
end
|
540
624
|
|
@@ -560,14 +644,14 @@ class DropboxClient
|
|
560
644
|
|
561
645
|
url = build_url("/thumbnails/#{@root}#{from_path}", params, content_server=true)
|
562
646
|
|
563
|
-
response = @
|
647
|
+
response = @session.do_get url
|
564
648
|
parse_response(response, raw=true)
|
565
649
|
end
|
566
650
|
|
567
651
|
def build_url(url, params=nil, content_server=false) # :nodoc:
|
568
652
|
port = 443
|
569
|
-
host = content_server ?
|
570
|
-
versioned_url = "/#{API_VERSION}#{url}"
|
653
|
+
host = content_server ? Dropbox::API_CONTENT_SERVER : Dropbox::API_SERVER
|
654
|
+
versioned_url = "/#{Dropbox::API_VERSION}#{url}"
|
571
655
|
|
572
656
|
target = URI::Generic.new("https", nil, host, port, nil, versioned_url, nil, nil, nil)
|
573
657
|
|
@@ -585,23 +669,22 @@ class DropboxClient
|
|
585
669
|
|
586
670
|
target.to_s
|
587
671
|
end
|
588
|
-
end
|
589
672
|
|
673
|
+
#From the oauth spec plus "/". Slash should not be ecsaped
|
674
|
+
RESERVED_CHARACTERS = /[^a-zA-Z0-9\-\.\_\~\/]/
|
590
675
|
|
591
|
-
|
592
|
-
|
676
|
+
def format_path(path, escape=true) # :nodoc:
|
677
|
+
path = path.gsub(/\/+/,"/")
|
678
|
+
# replace multiple slashes with a single one
|
593
679
|
|
594
|
-
|
595
|
-
|
596
|
-
# replace multiple slashes with a single one
|
680
|
+
path = path.gsub(/^\/?/,"/")
|
681
|
+
# ensure the path starts with a slash
|
597
682
|
|
598
|
-
|
599
|
-
|
683
|
+
path.gsub(/\/?$/,"")
|
684
|
+
# ensure the path doesn't end with a slash
|
600
685
|
|
601
|
-
|
602
|
-
|
686
|
+
return URI.escape(path, RESERVED_CHARACTERS) if escape
|
687
|
+
path
|
688
|
+
end
|
603
689
|
|
604
|
-
return URI.escape(path, RESERVED_CHARACTERS) if escape
|
605
|
-
path
|
606
690
|
end
|
607
|
-
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dropbox-sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 13
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
|
10
|
-
version: 1.0.beta
|
8
|
+
- 1
|
9
|
+
version: "1.1"
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Dropbox, Inc.
|
@@ -15,10 +14,10 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2011-
|
17
|
+
date: 2011-10-28 00:00:00 Z
|
19
18
|
dependencies:
|
20
19
|
- !ruby/object:Gem::Dependency
|
21
|
-
name:
|
20
|
+
name: json
|
22
21
|
prerelease: false
|
23
22
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
23
|
none: false
|
@@ -31,20 +30,6 @@ dependencies:
|
|
31
30
|
version: "0"
|
32
31
|
type: :runtime
|
33
32
|
version_requirements: *id001
|
34
|
-
- !ruby/object:Gem::Dependency
|
35
|
-
name: json
|
36
|
-
prerelease: false
|
37
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
-
none: false
|
39
|
-
requirements:
|
40
|
-
- - ">="
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
hash: 3
|
43
|
-
segments:
|
44
|
-
- 0
|
45
|
-
version: "0"
|
46
|
-
type: :runtime
|
47
|
-
version_requirements: *id002
|
48
33
|
description: " A library that provides a plain function-call interface to the\n Dropbox API web endpoints.\n"
|
49
34
|
email:
|
50
35
|
- support-api@dropbox.com
|
@@ -82,14 +67,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
82
67
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
68
|
none: false
|
84
69
|
requirements:
|
85
|
-
- - "
|
70
|
+
- - ">="
|
86
71
|
- !ruby/object:Gem::Version
|
87
|
-
hash:
|
72
|
+
hash: 3
|
88
73
|
segments:
|
89
|
-
-
|
90
|
-
|
91
|
-
- 1
|
92
|
-
version: 1.3.1
|
74
|
+
- 0
|
75
|
+
version: "0"
|
93
76
|
requirements: []
|
94
77
|
|
95
78
|
rubyforge_project:
|