dropbox-sdk 1.6.4 → 1.6.5

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.
@@ -31,292 +31,292 @@ APP_SECRET = ''
31
31
  STATE_FILE = 'search_cache.json'
32
32
 
33
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
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
65
  end
66
66
 
67
67
 
68
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
- })
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
91
  end
92
92
 
93
93
 
94
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
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 = {}
102
123
  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
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)
134
129
  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."
130
+ cursor = result['cursor']
131
+ if not result['has_more']
132
+ break
143
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
144
 
145
145
  end
146
146
 
147
147
  # We track folder state as a tree of Node objects.
148
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
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
173
172
  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
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
180
179
  end
180
+ end
181
181
  end
182
182
 
183
183
  # Run a mapping function over every value in a Hash, returning a new Hash.
184
184
  def map_hash_values(h)
185
- new = {}
186
- h.each { |k,v| new[k] = yield v }
187
- new
185
+ new = {}
186
+ h.each { |k,v| new[k] = yield v }
187
+ new
188
188
  end
189
189
 
190
190
 
191
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
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?
218
215
  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
216
+ node.content = metadata['size'], metadata['modified']
237
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
238
  end
239
239
 
240
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
241
+ child = children[name]
242
+ if child == nil
243
+ children[name] = child = Node.new(nil, nil)
244
+ end
245
+ child
246
246
  end
247
247
 
248
248
  def split_path(path)
249
- bad, *parts = path.split '/'
250
- [parts, parts.pop]
249
+ bad, *parts = path.split '/'
250
+ [parts, parts.pop]
251
251
  end
252
252
 
253
253
 
254
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}]")
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
271
  end
272
272
 
273
273
 
274
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)
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
287
  end
288
288
 
289
289
 
290
290
  # Recursively search 'tree' for files that contain the string in 'term'.
291
291
  # Print out any matches.
292
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
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
306
302
  end
303
+ if node.folder?
304
+ search_tree(results, node.content, term)
305
+ end
306
+ end
307
307
  end
308
308
 
309
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
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
314
  end
315
315
 
316
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
317
+ state = JSON.parse(File.read(STATE_FILE), :max_nesting => false)
318
+ state['tree'] = Node.from_json_content(state['tree'])
319
+ state
320
320
  end
321
321
 
322
322
  main()