examples/search_cache.rb in dropbox-sdk-1.6.4 vs examples/search_cache.rb in dropbox-sdk-1.6.5
- old
+ new
@@ -29,294 +29,294 @@
APP_SECRET = ''
STATE_FILE = 'search_cache.json'
def main()
- if APP_KEY == '' or APP_SECRET == ''
- warn "ERROR: Set your APP_KEY and APP_SECRET at the top of search_cache.rb"
- exit
- end
- prog_name = __FILE__
- args = ARGV
- if args.size == 0
- warn("Usage:\n")
- warn(" #{prog_name} link Link to a user's account.")
- warn(" #{prog_name} update Update cache to the latest on Dropbox.")
- warn(" #{prog_name} update <num> Update cache, limit to <num> pages of /delta.")
- warn(" #{prog_name} find <term> Search cache for <term>.")
- warn(" #{prog_name} find Display entire cache contents")
- warn(" #{prog_name} reset Delete the cache.")
- exit
- end
+ if APP_KEY == '' or APP_SECRET == ''
+ warn "ERROR: Set your APP_KEY and APP_SECRET at the top of search_cache.rb"
+ exit
+ end
+ prog_name = __FILE__
+ args = ARGV
+ if args.size == 0
+ warn("Usage:\n")
+ warn(" #{prog_name} link Link to a user's account.")
+ warn(" #{prog_name} update Update cache to the latest on Dropbox.")
+ warn(" #{prog_name} update <num> Update cache, limit to <num> pages of /delta.")
+ warn(" #{prog_name} find <term> Search cache for <term>.")
+ warn(" #{prog_name} find Display entire cache contents")
+ warn(" #{prog_name} reset Delete the cache.")
+ exit
+ end
- command = args[0]
- if command == 'link'
- command_link(args)
- elsif command == 'update'
- command_update(args)
- elsif command == 'find'
- command_find(args)
- elsif command == 'reset'
- command_reset(args)
- else
- warn "ERROR: Unknown command: #{command}"
- warn "Run with no arguments for help."
- exit(1)
- end
+ command = args[0]
+ if command == 'link'
+ command_link(args)
+ elsif command == 'update'
+ command_update(args)
+ elsif command == 'find'
+ command_find(args)
+ elsif command == 'reset'
+ command_reset(args)
+ else
+ warn "ERROR: Unknown command: #{command}"
+ warn "Run with no arguments for help."
+ exit(1)
+ end
end
def command_link(args)
- if args.size != 1
- warn "ERROR: \"link\" doesn't take any arguments"
- exit
- end
+ if args.size != 1
+ warn "ERROR: \"link\" doesn't take any arguments"
+ exit
+ end
- web_auth = DropboxOAuth2FlowNoRedirect.new(APP_KEY, APP_SECRET)
- authorize_url = web_auth.start()
- puts "1. Go to: #{authorize_url}"
- puts "2. Click \"Allow\" (you might have to log in first)."
- puts "3. Copy the authorization code."
+ web_auth = DropboxOAuth2FlowNoRedirect.new(APP_KEY, APP_SECRET)
+ authorize_url = web_auth.start()
+ puts "1. Go to: #{authorize_url}"
+ puts "2. Click \"Allow\" (you might have to log in first)."
+ puts "3. Copy the authorization code."
- print "Enter the authorization code here: "
- STDOUT.flush
- auth_code = STDIN.gets.strip
+ print "Enter the authorization code here: "
+ STDOUT.flush
+ auth_code = STDIN.gets.strip
- access_token, user_id = web_auth.finish(auth_code)
- puts "Link successful."
+ access_token, user_id = web_auth.finish(auth_code)
+ puts "Link successful."
- save_state({
- 'access_token' => access_token,
- 'tree' => {}
- })
+ save_state({
+ 'access_token' => access_token,
+ 'tree' => {}
+ })
end
def command_update(args)
- if args.size == 1
- page_limit = nil
- elsif args.size == 2
- page_limit = Integer(args[1])
- else
- warn "ERROR: \"update\" takes either zero or one argument."
- exit
- end
+ if args.size == 1
+ page_limit = nil
+ elsif args.size == 2
+ page_limit = Integer(args[1])
+ else
+ warn "ERROR: \"update\" takes either zero or one argument."
+ exit
+ end
- # Load state
- state = load_state()
- access_token = state['access_token']
- cursor = state['cursor']
- tree = state['tree']
+ # Load state
+ state = load_state()
+ access_token = state['access_token']
+ cursor = state['cursor']
+ tree = state['tree']
- # Connect to Dropbox
- c = DropboxClient.new(access_token)
+ # Connect to Dropbox
+ c = DropboxClient.new(access_token)
- page = 0
- changed = false
- while (page_limit == nil) or (page < page_limit)
- # Get /delta results from Dropbox
- result = c.delta(cursor)
- page += 1
- if result['reset'] == true
- puts 'reset'
- changed = true
- tree = {}
- end
- cursor = result['cursor']
- # Apply the entries one by one to our cached tree.
- for delta_entry in result['entries']
- changed = true
- apply_delta(tree, delta_entry)
- end
- cursor = result['cursor']
- if not result['has_more']
- break
- end
+ page = 0
+ changed = false
+ while (page_limit == nil) or (page < page_limit)
+ # Get /delta results from Dropbox
+ result = c.delta(cursor)
+ page += 1
+ if result['reset'] == true
+ puts 'reset'
+ changed = true
+ tree = {}
end
-
- # Save state
- if changed
- state['cursor'] = cursor
- state['tree'] = tree
- save_state(state)
- else
- puts "No updates."
+ cursor = result['cursor']
+ # Apply the entries one by one to our cached tree.
+ for delta_entry in result['entries']
+ changed = true
+ apply_delta(tree, delta_entry)
end
+ cursor = result['cursor']
+ if not result['has_more']
+ break
+ end
+ end
+ # Save state
+ if changed
+ state['cursor'] = cursor
+ state['tree'] = tree
+ save_state(state)
+ else
+ puts "No updates."
+ end
+
end
# We track folder state as a tree of Node objects.
class Node
- attr_accessor :path, :content
- def initialize(path, content)
- # The "original" page (i.e. not the lower-case path)
- @path = path
- # For files, content is a pair (size, modified)
- # For folders, content is a hash of children Nodes, keyed by lower-case file names.
- @content = content
+ attr_accessor :path, :content
+ def initialize(path, content)
+ # The "original" page (i.e. not the lower-case path)
+ @path = path
+ # For files, content is a pair (size, modified)
+ # For folders, content is a hash of children Nodes, keyed by lower-case file names.
+ @content = content
+ end
+ def folder?()
+ @content.is_a? Hash
+ end
+ def to_json()
+ [@path, Node.to_json_content(@content)]
+ end
+ def self.from_json(jnode)
+ path, jcontent = jnode
+ Node.new(path, Node.from_json_content(jcontent))
+ end
+ def self.to_json_content(content)
+ if content.is_a? Hash
+ map_hash_values(content) { |child| child.to_json }
+ else
+ content
end
- def folder?()
- @content.is_a? Hash
+ end
+ def self.from_json_content(jcontent)
+ if jcontent.is_a? Hash
+ map_hash_values(jcontent) { |jchild| Node.from_json jchild }
+ else
+ jcontent
end
- def to_json()
- [@path, Node.to_json_content(@content)]
- end
- def self.from_json(jnode)
- path, jcontent = jnode
- Node.new(path, Node.from_json_content(jcontent))
- end
- def self.to_json_content(content)
- if content.is_a? Hash
- map_hash_values(content) { |child| child.to_json }
- else
- content
- end
- end
- def self.from_json_content(jcontent)
- if jcontent.is_a? Hash
- map_hash_values(jcontent) { |jchild| Node.from_json jchild }
- else
- jcontent
- end
- end
+ end
end
# Run a mapping function over every value in a Hash, returning a new Hash.
def map_hash_values(h)
- new = {}
- h.each { |k,v| new[k] = yield v }
- new
+ new = {}
+ h.each { |k,v| new[k] = yield v }
+ new
end
def apply_delta(root, e)
- path, metadata = e
- branch, leaf = split_path(path)
+ path, metadata = e
+ branch, leaf = split_path(path)
- if metadata != nil
- puts "+ #{path}"
- # Traverse down the tree until we find the parent folder of the entry
- # we want to add. Create any missing folders along the way.
- children = root
- branch.each do |part|
- node = get_or_create_child(children, part)
- # If there's no folder here, make an empty one.
- if not node.folder?
- node.content = {}
- end
- children = node.content
- end
+ if metadata != nil
+ puts "+ #{path}"
+ # Traverse down the tree until we find the parent folder of the entry
+ # we want to add. Create any missing folders along the way.
+ children = root
+ branch.each do |part|
+ node = get_or_create_child(children, part)
+ # If there's no folder here, make an empty one.
+ if not node.folder?
+ node.content = {}
+ end
+ children = node.content
+ end
- # Create the file/folder.
- node = get_or_create_child(children, leaf)
- node.path = metadata['path'] # Save the un-lower-cased path.
- if metadata['is_dir']
- # Only create a folder if there isn't one there already.
- node.content = {} if not node.folder?
- else
- node.content = metadata['size'], metadata['modified']
- end
+ # Create the file/folder.
+ node = get_or_create_child(children, leaf)
+ node.path = metadata['path'] # Save the un-lower-cased path.
+ if metadata['is_dir']
+ # Only create a folder if there isn't one there already.
+ node.content = {} if not node.folder?
else
- puts "- #{path}"
- # Traverse down the tree until we find the parent of the entry we
- # want to delete.
- children = root
- missing_parent = false
- branch.each do |part|
- node = children[part]
- # If one of the parent folders is missing, then we're done.
- if node == nil or not node.folder?
- missing_parent = true
- break
- end
- children = node.content
- end
- # If we made it all the way, delete the file/folder.
- if not missing_parent
- children.delete(leaf)
- end
+ node.content = metadata['size'], metadata['modified']
end
+ else
+ puts "- #{path}"
+ # Traverse down the tree until we find the parent of the entry we
+ # want to delete.
+ children = root
+ missing_parent = false
+ branch.each do |part|
+ node = children[part]
+ # If one of the parent folders is missing, then we're done.
+ if node == nil or not node.folder?
+ missing_parent = true
+ break
+ end
+ children = node.content
+ end
+ # If we made it all the way, delete the file/folder.
+ if not missing_parent
+ children.delete(leaf)
+ end
+ end
end
def get_or_create_child(children, name)
- child = children[name]
- if child == nil
- children[name] = child = Node.new(nil, nil)
- end
- child
+ child = children[name]
+ if child == nil
+ children[name] = child = Node.new(nil, nil)
+ end
+ child
end
def split_path(path)
- bad, *parts = path.split '/'
- [parts, parts.pop]
+ bad, *parts = path.split '/'
+ [parts, parts.pop]
end
def command_find(args)
- if args.size == 1
- term = ''
- elsif args.size == 2
- term = args[1]
- else
- warn("ERROR: \"find\" takes either zero or one arguments.")
- exit
- end
+ if args.size == 1
+ term = ''
+ elsif args.size == 2
+ term = args[1]
+ else
+ warn("ERROR: \"find\" takes either zero or one arguments.")
+ exit
+ end
- state = load_state()
- results = []
- search_tree(results, state['tree'], term)
- for r in results
- puts("#{r}")
- end
- puts("[Matches: #{results.size}]")
+ state = load_state()
+ results = []
+ search_tree(results, state['tree'], term)
+ for r in results
+ puts("#{r}")
+ end
+ puts("[Matches: #{results.size}]")
end
def command_reset(args)
- if args.size != 1
- warn("ERROR: \"reset\" takes no arguments.")
- exit
- end
+ if args.size != 1
+ warn("ERROR: \"reset\" takes no arguments.")
+ exit
+ end
- # Delete cursor, empty tree.
- state = load_state()
- if state.has_key?('cursor')
- state.delete('cursor')
- end
- state['tree'] = {}
- save_state(state)
+ # Delete cursor, empty tree.
+ state = load_state()
+ if state.has_key?('cursor')
+ state.delete('cursor')
+ end
+ state['tree'] = {}
+ save_state(state)
end
# Recursively search 'tree' for files that contain the string in 'term'.
# Print out any matches.
def search_tree(results, tree, term)
- tree.each do |name_lc, node|
- path = node.path
- if (path != nil) and path.include?(term)
- if node.folder?
- results.push("#{path}")
- else
- size, modified = node.content
- results.push("#{path} (#{size}, #{modified})")
- end
- end
- if node.folder?
- search_tree(results, node.content, term)
- end
+ tree.each do |name_lc, node|
+ path = node.path
+ if (path != nil) and path.include?(term)
+ if node.folder?
+ results.push("#{path}")
+ else
+ size, modified = node.content
+ results.push("#{path} (#{size}, #{modified})")
+ end
end
+ if node.folder?
+ search_tree(results, node.content, term)
+ end
+ end
end
def save_state(state)
- state['tree'] = Node.to_json_content(state['tree'])
- File.open(STATE_FILE,"w") do |f|
- f.write(JSON.pretty_generate(state, :max_nesting => false))
- end
+ state['tree'] = Node.to_json_content(state['tree'])
+ File.open(STATE_FILE,"w") do |f|
+ f.write(JSON.pretty_generate(state, :max_nesting => false))
+ end
end
def load_state()
- state = JSON.parse(File.read(STATE_FILE), :max_nesting => false)
- state['tree'] = Node.from_json_content(state['tree'])
- state
+ state = JSON.parse(File.read(STATE_FILE), :max_nesting => false)
+ state['tree'] = Node.from_json_content(state['tree'])
+ state
end
main()