dropbox-sdk 1.6.4 → 1.6.5

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