dropbox-sdk 1.6.3 → 1.6.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.
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.