dropbox-sdk 1.6.3 → 1.6.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ 1.6.4 (2014-4-12)
2
+ * Bugfixes
3
+ * Update gemspec to include all examples
4
+ * Release tests and other internal scripts
5
+
1
6
  1.6.3 (2013-12-11)
2
7
  * Stricter SSL: Update certs, use only approved ciphersuites, work around
3
8
  Ruby SSL bugs.
data/README CHANGED
@@ -7,9 +7,9 @@ A Ruby library that for Dropbox's HTTP-based Core API.
7
7
  ----------------------------------
8
8
  Setup
9
9
 
10
- You can install this package using 'pip':
10
+ You can install this package using 'gem':
11
11
 
12
- # pip install dropbox
12
+ # gem install dropbox-sdk
13
13
 
14
14
  ----------------------------------
15
15
  Getting a Dropbox API key
@@ -0,0 +1,71 @@
1
+ # An example use of the /chunked_upload API call.
2
+
3
+ require File.expand_path('../../lib/dropbox_sdk', __FILE__)
4
+
5
+ # You must use your Dropbox App key and secret to use the API.
6
+ # Find this at https://www.dropbox.com/developers
7
+ APP_KEY = ''
8
+ APP_SECRET = ''
9
+
10
+ STATE_FILE = 'search_cache.json'
11
+
12
+ def main()
13
+ if APP_KEY == '' or APP_SECRET == ''
14
+ warn "ERROR: Set your APP_KEY and APP_SECRET at the top of search_cache.rb"
15
+ exit
16
+ end
17
+ prog_name = __FILE__
18
+ args = ARGV
19
+ if args.size == 0
20
+ warn("Usage:\n")
21
+ warn(" #{prog_name} <local-file-path> <dropbox-target-path> <chunk-size-in-bytes>")
22
+ exit
23
+ end
24
+
25
+ if args.size != 3
26
+ warn "ERROR: expecting exactly three arguments. Run with no arguments for help."
27
+ exit(1)
28
+ end
29
+
30
+ web_auth = DropboxOAuth2FlowNoRedirect.new(APP_KEY, APP_SECRET)
31
+ authorize_url = web_auth.start()
32
+ puts "1. Go to: #{authorize_url}"
33
+ puts "2. Click \"Allow\" (you might have to log in first)."
34
+ puts "3. Copy the authorization code."
35
+
36
+ print "Enter the authorization code here: "
37
+ STDOUT.flush
38
+ auth_code = STDIN.gets.strip
39
+
40
+ access_token, user_id = web_auth.finish(auth_code)
41
+
42
+ c = DropboxClient.new(access_token)
43
+
44
+ local_file_path = args[0]
45
+ dropbox_target_path = args[1]
46
+ chunk_size = args[2].to_i
47
+
48
+ # Upload the file
49
+ local_file_size = File.size(local_file_path)
50
+ uploader = c.get_chunked_uploader(File.new(local_file_path, "r"), local_file_size)
51
+ retries = 0
52
+ puts "Uploading..."
53
+ while uploader.offset < uploader.total_size
54
+ begin
55
+ uploader.upload(chunk_size)
56
+ rescue DropboxError => e
57
+ if retries > 10
58
+ puts "- Error uploading, giving up."
59
+ break
60
+ end
61
+ puts "- Error uploading, trying again..."
62
+ retries += 1
63
+ end
64
+ end
65
+ puts "Finishing upload..."
66
+ uploader.finish(dropbox_target_path)
67
+ puts "Done."
68
+
69
+ end
70
+
71
+ main()
@@ -1,5 +1,6 @@
1
- require './lib/dropbox_sdk'
1
+ require File.expand_path('../../lib/dropbox_sdk', __FILE__)
2
2
  require 'pp'
3
+ require 'shellwords'
3
4
 
4
5
  ####
5
6
  # An example app using the Dropbox API Ruby Client
@@ -65,7 +66,7 @@ class DropboxCLI
65
66
  end
66
67
 
67
68
  def execute_dropbox_command(cmd_line)
68
- command = cmd_line.split
69
+ command = Shellwords.shellwords cmd_line
69
70
  method = command.first
70
71
  if LOGIN_REQUIRED.include? method
71
72
  if @client
@@ -0,0 +1,148 @@
1
+ require File.expand_path('../../lib/dropbox_sdk', __FILE__)
2
+ require 'json'
3
+
4
+ # You must use your Dropbox App key and secret to use the API.
5
+ # Find this at https://www.dropbox.com/developers
6
+ APP_KEY = ''
7
+ APP_SECRET = ''
8
+
9
+ STATE_FILE = 'copy_between_accounts.json'
10
+
11
+ def main()
12
+ prog_name = __FILE__
13
+ if APP_KEY == '' or APP_SECRET == ''
14
+ warn "ERROR: Set your APP_KEY and APP_SECRET at the top of #{prog_name}"
15
+ exit
16
+ end
17
+ args = ARGV
18
+ if args.size == 0
19
+ warn("Usage:\n")
20
+ warn(" #{prog_name} link Link to a user's account. Also displays UID.")
21
+ warn(" #{prog_name} list List linked users including UID.")
22
+ warn(" #{prog_name} copy '<uid>:<path>' '<uid>:<path>' Copies a file from the first user's path, to the second user's path.")
23
+ warn("\n\n <uid> is the account UID shown when linked. <path> is a path to a file on that user's dropbox.")
24
+ exit
25
+ end
26
+
27
+ command = args[0]
28
+ if command == 'link'
29
+ command_link(args)
30
+ elsif command == 'list'
31
+ command_list(args)
32
+ elsif command == 'copy'
33
+ command_copy(args)
34
+ else
35
+ warn "ERROR: Unknown command: #{command}"
36
+ warn "Run with no arguments for help."
37
+ exit(1)
38
+ end
39
+ end
40
+
41
+ def command_link(args)
42
+ if args.size != 1
43
+ warn "ERROR: \"link\" doesn't take any arguments"
44
+ exit
45
+ end
46
+
47
+ web_auth = DropboxOAuth2FlowNoRedirect.new(APP_KEY, APP_SECRET)
48
+ authorize_url = web_auth.start()
49
+ puts "1. Go to: #{authorize_url}"
50
+ puts "2. Click \"Allow\" (you might have to log in first)."
51
+ puts "3. Copy the authorization code."
52
+
53
+ print "Enter the authorization code here: "
54
+ STDOUT.flush
55
+ auth_code = STDIN.gets.strip
56
+
57
+ access_token, user_id = web_auth.finish(auth_code)
58
+
59
+ c = DropboxClient.new(access_token)
60
+ account_info = c.account_info()
61
+ puts "Link successful. #{account_info['display_name']} is uid #{account_info['uid']} "
62
+
63
+ state = load_state()
64
+ state[account_info['uid']] = {
65
+ 'access_token' => access_token,
66
+ 'display_name' => account_info['display_name'],
67
+ }
68
+
69
+ if account_info['team']
70
+ state[account_info['uid']]['team_name'] = account_info['team']['name']
71
+ end
72
+
73
+ save_state(state)
74
+ end
75
+
76
+ def command_list(args)
77
+ if args.size != 1
78
+ warn "ERROR: \"list\" doesn't take any arguments"
79
+ exit
80
+ end
81
+
82
+ state = load_state()
83
+ for e in state.keys()
84
+ if state[e]['team_name']
85
+ puts "#{state[e]['display_name']} (#{state[e]['team_name']}) is uid #{e}"
86
+ else
87
+ puts "#{state[e]['display_name']} is uid #{e}"
88
+ end
89
+ end
90
+ end
91
+
92
+ def command_copy(args)
93
+ if args.size != 3
94
+ warn "ERROR: \"copy\" takes exactly two arguments"
95
+ exit
96
+ end
97
+
98
+ state = load_state()
99
+
100
+ if state.keys().length < 2
101
+ warn "ERROR: You can't use the copy command until at least two users have linked"
102
+ exit
103
+ end
104
+
105
+ from = args[1].gsub(/['"]/,'')
106
+ to = args[2].gsub(/['"]/,'')
107
+
108
+ if not to.index(':') or not from.index(':')
109
+ warn "ERROR: Ill-formated paths. Run #{prog_name} without arugments to see documentation."
110
+ exit
111
+ end
112
+
113
+ from_uid, from_path = from.split ":"
114
+ to_uid, to_path = to.split ":"
115
+
116
+ if not state.has_key?(to_uid) or not state.has_key?(from_uid)
117
+ warn "ERROR: Those UIDs have not linked. Run #{prog_name} list to see linked UIDs."
118
+ exit
119
+ end
120
+
121
+ from_client = DropboxClient.new(state[from_uid]['access_token'])
122
+ to_client = DropboxClient.new(state[to_uid]['access_token'])
123
+
124
+ #Create a copy ref under the identity of the from user
125
+ copy_ref = from_client.create_copy_ref(from_path)['copy_ref']
126
+
127
+ metadata = to_client.add_copy_ref(to_path, copy_ref)
128
+
129
+ puts "File successly copied from #{state[from_uid]['display_name']} to #{state[to_uid]['display_name']}!"
130
+ puts "The file now exists at #{metadata['path']}"
131
+
132
+ end
133
+
134
+ def save_state(state)
135
+ File.open(STATE_FILE,"w") do |f|
136
+ f.write(JSON.pretty_generate(state))
137
+ end
138
+ end
139
+
140
+ def load_state()
141
+ if not FileTest.exists?(STATE_FILE)
142
+ return {}
143
+ end
144
+ JSON.parse(File.read(STATE_FILE))
145
+ end
146
+
147
+
148
+ main()
@@ -3,18 +3,24 @@
3
3
  # - Runs the through Dropbox's OAuth 2 flow, yielding a Dropbox API access token.
4
4
  # - Makes a Dropbox API call to upload a file.
5
5
  #
6
+ # To set up:
7
+ # 1. Create a Dropbox App key and secret to use the API. https://www.dropbox.com/developers
8
+ # 2. Add http://localhost:3000/dropbox/auth_finish as a Redirect URI for your Dropbox app.
9
+ # 3. Copy your App key and App secret into APP_KEY and APP_SECRET below.
10
+ #
6
11
  # To run:
7
12
  # 1. You need a Rails 3 project (to create one, run: rails new <folder-name>)
8
- # 2. Copy this file into <folder-name>/app/controllers/
9
- # 3. Add the following lines to <folder-name>/config/routes.rb
13
+ # 2. Copy dropbox_sdk.rb into <folder-name>/vendor
14
+ # 3. Copy this file into <folder-name>/app/controllers/
15
+ # 4. Add the following lines to <folder-name>/config/routes.rb
10
16
  # get "dropbox/main"
11
17
  # post "dropbox/upload"
12
18
  # get "dropbox/auth_start"
13
19
  # get "dropbox/auth_finish"
14
- # 4. Run: rails server
15
- # 5. Point your browser at: https://localhost:3000/dropbox/main
20
+ # 5. Run: rails server
21
+ # 6. Point your browser at: https://localhost:3000/dropbox/main
16
22
 
17
- require '../lib/dropbox_sdk'
23
+ require 'dropbox_sdk'
18
24
  require 'securerandom'
19
25
 
20
26
  APP_KEY = ""
@@ -0,0 +1,40 @@
1
+ require File.expand_path('../../lib/dropbox_sdk', __FILE__)
2
+ require 'pp'
3
+
4
+ # You must use your Dropbox App key and secret to use the API.
5
+ # Find this at https://www.dropbox.com/developers
6
+ APP_KEY = ''
7
+ APP_SECRET = ''
8
+
9
+ def main
10
+ if APP_KEY == '' or APP_SECRET == ''
11
+ warn "ERROR: Set your APP_KEY and APP_SECRET at the top of search_cache.rb"
12
+ exit
13
+ end
14
+
15
+ prog_name = __FILE__
16
+ args = ARGV
17
+ if args.size != 2
18
+ warn "Usage: #{prog_name} <oauth1-access-token-key> <oauth1-access-token-secret>"
19
+ exit 1
20
+ end
21
+
22
+ access_token_key = args[0]
23
+ access_token_secret = args[1]
24
+
25
+ sess = DropboxSession.new(APP_KEY, APP_SECRET)
26
+ sess.set_access_token(access_token_key, access_token_secret)
27
+ c = DropboxClient.new(sess)
28
+
29
+ print "Creating OAuth 2 access token...\n"
30
+ oauth2_access_token = c.create_oauth2_access_token
31
+
32
+ print "Using OAuth 2 access token to get account info...\n"
33
+ c2 = DropboxClient.new(oauth2_access_token)
34
+ pp c2.account_info
35
+
36
+ print "Disabling OAuth 1 access token...\n"
37
+ c.disable_access_token
38
+ end
39
+
40
+ main()
@@ -0,0 +1,322 @@
1
+ # An example use of the /delta API call. Maintains a local cache of
2
+ # the App Folder's contents. Use the 'update' sub-command to update
3
+ # the local cache. Use the 'find' sub-command to search the local
4
+ # cache.
5
+ #
6
+ # Example usage:
7
+ #
8
+ # 1. Link to your Dropbox account
9
+ # > ruby search_cache.rb link
10
+ #
11
+ # 2. Go to Dropbox and make changes to the contents.
12
+ #
13
+ # 3. Update the local cache to match what's on Dropbox.
14
+ # > ruby search_cache.rb update
15
+ #
16
+ # 4. Search the local cache.
17
+ # > ruby search_cache.rb find 'txt'
18
+
19
+ # Repeat steps 2-4 any number of times.
20
+
21
+
22
+
23
+ require File.expand_path('../../lib/dropbox_sdk', __FILE__)
24
+ require 'json'
25
+
26
+ # You must use your Dropbox App key and secret to use the API.
27
+ # Find this at https://www.dropbox.com/developers
28
+ APP_KEY = ''
29
+ APP_SECRET = ''
30
+
31
+ STATE_FILE = 'search_cache.json'
32
+
33
+ def main()
34
+ if APP_KEY == '' or APP_SECRET == ''
35
+ warn "ERROR: Set your APP_KEY and APP_SECRET at the top of search_cache.rb"
36
+ exit
37
+ end
38
+ prog_name = __FILE__
39
+ args = ARGV
40
+ if args.size == 0
41
+ warn("Usage:\n")
42
+ warn(" #{prog_name} link Link to a user's account.")
43
+ warn(" #{prog_name} update Update cache to the latest on Dropbox.")
44
+ warn(" #{prog_name} update <num> Update cache, limit to <num> pages of /delta.")
45
+ warn(" #{prog_name} find <term> Search cache for <term>.")
46
+ warn(" #{prog_name} find Display entire cache contents")
47
+ warn(" #{prog_name} reset Delete the cache.")
48
+ exit
49
+ end
50
+
51
+ command = args[0]
52
+ if command == 'link'
53
+ command_link(args)
54
+ elsif command == 'update'
55
+ command_update(args)
56
+ elsif command == 'find'
57
+ command_find(args)
58
+ elsif command == 'reset'
59
+ command_reset(args)
60
+ else
61
+ warn "ERROR: Unknown command: #{command}"
62
+ warn "Run with no arguments for help."
63
+ exit(1)
64
+ end
65
+ end
66
+
67
+
68
+ def command_link(args)
69
+ if args.size != 1
70
+ warn "ERROR: \"link\" doesn't take any arguments"
71
+ exit
72
+ end
73
+
74
+ web_auth = DropboxOAuth2FlowNoRedirect.new(APP_KEY, APP_SECRET)
75
+ authorize_url = web_auth.start()
76
+ puts "1. Go to: #{authorize_url}"
77
+ puts "2. Click \"Allow\" (you might have to log in first)."
78
+ puts "3. Copy the authorization code."
79
+
80
+ print "Enter the authorization code here: "
81
+ STDOUT.flush
82
+ auth_code = STDIN.gets.strip
83
+
84
+ access_token, user_id = web_auth.finish(auth_code)
85
+ puts "Link successful."
86
+
87
+ save_state({
88
+ 'access_token' => access_token,
89
+ 'tree' => {}
90
+ })
91
+ end
92
+
93
+
94
+ def command_update(args)
95
+ if args.size == 1
96
+ page_limit = nil
97
+ elsif args.size == 2
98
+ page_limit = Integer(args[1])
99
+ else
100
+ warn "ERROR: \"update\" takes either zero or one argument."
101
+ exit
102
+ end
103
+
104
+ # Load state
105
+ state = load_state()
106
+ access_token = state['access_token']
107
+ cursor = state['cursor']
108
+ tree = state['tree']
109
+
110
+ # Connect to Dropbox
111
+ c = DropboxClient.new(access_token)
112
+
113
+ page = 0
114
+ changed = false
115
+ while (page_limit == nil) or (page < page_limit)
116
+ # Get /delta results from Dropbox
117
+ result = c.delta(cursor)
118
+ page += 1
119
+ if result['reset'] == true
120
+ puts 'reset'
121
+ changed = true
122
+ tree = {}
123
+ end
124
+ cursor = result['cursor']
125
+ # Apply the entries one by one to our cached tree.
126
+ for delta_entry in result['entries']
127
+ changed = true
128
+ apply_delta(tree, delta_entry)
129
+ end
130
+ cursor = result['cursor']
131
+ if not result['has_more']
132
+ break
133
+ end
134
+ end
135
+
136
+ # Save state
137
+ if changed
138
+ state['cursor'] = cursor
139
+ state['tree'] = tree
140
+ save_state(state)
141
+ else
142
+ puts "No updates."
143
+ end
144
+
145
+ end
146
+
147
+ # We track folder state as a tree of Node objects.
148
+ class Node
149
+ attr_accessor :path, :content
150
+ def initialize(path, content)
151
+ # The "original" page (i.e. not the lower-case path)
152
+ @path = path
153
+ # For files, content is a pair (size, modified)
154
+ # For folders, content is a hash of children Nodes, keyed by lower-case file names.
155
+ @content = content
156
+ end
157
+ def folder?()
158
+ @content.is_a? Hash
159
+ end
160
+ def to_json()
161
+ [@path, Node.to_json_content(@content)]
162
+ end
163
+ def self.from_json(jnode)
164
+ path, jcontent = jnode
165
+ Node.new(path, Node.from_json_content(jcontent))
166
+ end
167
+ def self.to_json_content(content)
168
+ if content.is_a? Hash
169
+ map_hash_values(content) { |child| child.to_json }
170
+ else
171
+ content
172
+ end
173
+ end
174
+ def self.from_json_content(jcontent)
175
+ if jcontent.is_a? Hash
176
+ map_hash_values(jcontent) { |jchild| Node.from_json jchild }
177
+ else
178
+ jcontent
179
+ end
180
+ end
181
+ end
182
+
183
+ # Run a mapping function over every value in a Hash, returning a new Hash.
184
+ def map_hash_values(h)
185
+ new = {}
186
+ h.each { |k,v| new[k] = yield v }
187
+ new
188
+ end
189
+
190
+
191
+ def apply_delta(root, e)
192
+ path, metadata = e
193
+ branch, leaf = split_path(path)
194
+
195
+ if metadata != nil
196
+ puts "+ #{path}"
197
+ # Traverse down the tree until we find the parent folder of the entry
198
+ # we want to add. Create any missing folders along the way.
199
+ children = root
200
+ branch.each do |part|
201
+ node = get_or_create_child(children, part)
202
+ # If there's no folder here, make an empty one.
203
+ if not node.folder?
204
+ node.content = {}
205
+ end
206
+ children = node.content
207
+ end
208
+
209
+ # Create the file/folder.
210
+ node = get_or_create_child(children, leaf)
211
+ node.path = metadata['path'] # Save the un-lower-cased path.
212
+ if metadata['is_dir']
213
+ # Only create a folder if there isn't one there already.
214
+ node.content = {} if not node.folder?
215
+ else
216
+ node.content = metadata['size'], metadata['modified']
217
+ end
218
+ else
219
+ puts "- #{path}"
220
+ # Traverse down the tree until we find the parent of the entry we
221
+ # want to delete.
222
+ children = root
223
+ missing_parent = false
224
+ branch.each do |part|
225
+ node = children[part]
226
+ # If one of the parent folders is missing, then we're done.
227
+ if node == nil or not node.folder?
228
+ missing_parent = true
229
+ break
230
+ end
231
+ children = node.content
232
+ end
233
+ # If we made it all the way, delete the file/folder.
234
+ if not missing_parent
235
+ children.delete(leaf)
236
+ end
237
+ end
238
+ end
239
+
240
+ def get_or_create_child(children, name)
241
+ child = children[name]
242
+ if child == nil
243
+ children[name] = child = Node.new(nil, nil)
244
+ end
245
+ child
246
+ end
247
+
248
+ def split_path(path)
249
+ bad, *parts = path.split '/'
250
+ [parts, parts.pop]
251
+ end
252
+
253
+
254
+ def command_find(args)
255
+ if args.size == 1
256
+ term = ''
257
+ elsif args.size == 2
258
+ term = args[1]
259
+ else
260
+ warn("ERROR: \"find\" takes either zero or one arguments.")
261
+ exit
262
+ end
263
+
264
+ state = load_state()
265
+ results = []
266
+ search_tree(results, state['tree'], term)
267
+ for r in results
268
+ puts("#{r}")
269
+ end
270
+ puts("[Matches: #{results.size}]")
271
+ end
272
+
273
+
274
+ def command_reset(args)
275
+ if args.size != 1
276
+ warn("ERROR: \"reset\" takes no arguments.")
277
+ exit
278
+ end
279
+
280
+ # Delete cursor, empty tree.
281
+ state = load_state()
282
+ if state.has_key?('cursor')
283
+ state.delete('cursor')
284
+ end
285
+ state['tree'] = {}
286
+ save_state(state)
287
+ end
288
+
289
+
290
+ # Recursively search 'tree' for files that contain the string in 'term'.
291
+ # Print out any matches.
292
+ def search_tree(results, tree, term)
293
+ tree.each do |name_lc, node|
294
+ path = node.path
295
+ if (path != nil) and path.include?(term)
296
+ if node.folder?
297
+ results.push("#{path}")
298
+ else
299
+ size, modified = node.content
300
+ results.push("#{path} (#{size}, #{modified})")
301
+ end
302
+ end
303
+ if node.folder?
304
+ search_tree(results, node.content, term)
305
+ end
306
+ end
307
+ end
308
+
309
+ def save_state(state)
310
+ state['tree'] = Node.to_json_content(state['tree'])
311
+ File.open(STATE_FILE,"w") do |f|
312
+ f.write(JSON.pretty_generate(state, :max_nesting => false))
313
+ end
314
+ end
315
+
316
+ def load_state()
317
+ state = JSON.parse(File.read(STATE_FILE), :max_nesting => false)
318
+ state['tree'] = Node.from_json_content(state['tree'])
319
+ state
320
+ end
321
+
322
+ main()
@@ -4,6 +4,11 @@
4
4
  # - The webapp OAuth process.
5
5
  # - The metadata() and put_file() calls.
6
6
  #
7
+ # To set up:
8
+ # 1. Create a Dropbox App key and secret to use the API. https://www.dropbox.com/developers
9
+ # 2. Add http://localhost:4567/dropbox-auth-finish as a Redirect URI for your Dropbox app.
10
+ # 3. Copy your App key and App secret into APP_KEY and APP_SECRET below.
11
+ #
7
12
  # To run:
8
13
  # 1. Install Sinatra $ gem install sinatra
9
14
  # 2. Launch server $ ruby web_file_browser.rb
@@ -14,7 +19,7 @@ require 'rubygems'
14
19
  require 'sinatra'
15
20
  require 'pp'
16
21
  require 'securerandom'
17
- require './lib/dropbox_sdk'
22
+ require File.expand_path('../../lib/dropbox_sdk', __FILE__)
18
23
 
19
24
  # Get your app's key and secret from https://www.dropbox.com/developers/
20
25
  APP_KEY = ''
@@ -1,4 +1,3 @@
1
- require 'rubygems'
2
1
  require 'uri'
3
2
  require 'net/https'
4
3
  require 'cgi'
@@ -14,7 +13,7 @@ module Dropbox # :nodoc:
14
13
  WEB_SERVER = "www.dropbox.com"
15
14
 
16
15
  API_VERSION = 1
17
- SDK_VERSION = "1.6.3"
16
+ SDK_VERSION = "1.6.4"
18
17
 
19
18
  TRUSTED_CERT_FILE = File.join(File.dirname(__FILE__), 'trusted-certs.crt')
20
19
 
@@ -88,7 +87,7 @@ module Dropbox # :nodoc:
88
87
  http.request(request)
89
88
  rescue OpenSSL::SSL::SSLError => e
90
89
  raise DropboxError.new("SSL error connecting to Dropbox. " +
91
- "There may be a problem with the set of certificates in \"#{Dropbox::TRUSTED_CERT_FILE}\". #{e}")
90
+ "There may be a problem with the set of certificates in \"#{Dropbox::TRUSTED_CERT_FILE}\". #{e.message}")
92
91
  end
93
92
  end
94
93
 
@@ -861,9 +860,18 @@ class DropboxClient
861
860
  begin
862
861
  resp = Dropbox::parse_response(@client.partial_chunked_upload(last_chunk, @upload_id, @offset))
863
862
  last_chunk = nil
863
+ rescue SocketError => e
864
+ raise e
865
+ rescue SystemCallError => e
866
+ raise e
864
867
  rescue DropboxError => e
865
- resp = JSON.parse(e.http_response.body)
866
- raise unless resp.has_key? 'offset'
868
+ raise e if e.http_response.nil? or e.http_response.code[0] == '5'
869
+ begin
870
+ resp = JSON.parse(e.http_response.body)
871
+ raise DropboxError.new('server response does not have offset key') unless resp.has_key? 'offset'
872
+ rescue JSON::ParserError
873
+ raise DropboxError.new("Unable to parse JSON response: #{e.http_response.body}")
874
+ end
867
875
  end
868
876
 
869
877
  if resp.has_key? 'offset' and resp['offset'] > @offset
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: 9
5
- prerelease:
4
+ prerelease: false
6
5
  segments:
7
6
  - 1
8
7
  - 6
9
- - 3
10
- version: 1.6.3
8
+ - 4
9
+ version: 1.6.4
11
10
  platform: ruby
12
11
  authors:
13
12
  - Dropbox, Inc.
@@ -15,17 +14,16 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2013-12-11 00:00:00 Z
17
+ date: 2014-04-24 00:00:00 -07:00
18
+ default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: json
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
- none: false
25
24
  requirements:
26
25
  - - ">="
27
26
  - !ruby/object:Gem::Version
28
- hash: 3
29
27
  segments:
30
28
  - 0
31
29
  version: "0"
@@ -44,11 +42,16 @@ files:
44
42
  - CHANGELOG
45
43
  - LICENSE
46
44
  - README
47
- - cli_example.rb
48
- - dropbox_controller.rb
49
- - web_file_browser.rb
45
+ - examples/cli_example.rb
46
+ - examples/dropbox_controller.rb
47
+ - examples/web_file_browser.rb
48
+ - examples/copy_between_accounts.rb
49
+ - examples/chunked_upload.rb
50
+ - examples/oauth1_upgrade.rb
51
+ - examples/search_cache.rb
50
52
  - lib/dropbox_sdk.rb
51
53
  - lib/trusted-certs.crt
54
+ has_rdoc: true
52
55
  homepage: http://www.dropbox.com/developers/
53
56
  licenses:
54
57
  - MIT
@@ -58,27 +61,23 @@ rdoc_options: []
58
61
  require_paths:
59
62
  - lib
60
63
  required_ruby_version: !ruby/object:Gem::Requirement
61
- none: false
62
64
  requirements:
63
65
  - - ">="
64
66
  - !ruby/object:Gem::Version
65
- hash: 3
66
67
  segments:
67
68
  - 0
68
69
  version: "0"
69
70
  required_rubygems_version: !ruby/object:Gem::Requirement
70
- none: false
71
71
  requirements:
72
72
  - - ">="
73
73
  - !ruby/object:Gem::Version
74
- hash: 3
75
74
  segments:
76
75
  - 0
77
76
  version: "0"
78
77
  requirements: []
79
78
 
80
79
  rubyforge_project:
81
- rubygems_version: 1.8.25
80
+ rubygems_version: 1.3.6
82
81
  signing_key:
83
82
  specification_version: 3
84
83
  summary: Dropbox REST API Client.