diff --git a/bucket-tool b/bucket-tool index 8fa7d9f..f7ad61d 100644 --- a/bucket-tool +++ b/bucket-tool @@ -14,12 +14,11 @@ Description: search the filebucket and restore from it. Actions: - search : Search for bucket entries matching a portion of the filepath + search : Search for bucket entries matching a portion of the filepath list : List all Bucket entries list-files : List all files/paths that have been backed up to the bucket get : Get the content of a specific entry (by hash) - restore-hash : Restore previous state of file stored in bucket (by-hash) - restore-file : Restore previous state of file stored in bucket (by-filepath/filename) + restore : Restore previous state of file stored in bucket. Value can be hash or filename/filepath Global Flags: -d | --debug : Set debug flag @@ -79,6 +78,55 @@ def get_verification (prompt = "Do you want to continue?") end end +def get_selections (reference_array, prompt = "Which of the following do you want to select? ", options = { :multiple => false, }, &procedure) + ## Making clone of array since the selections were passed by reference + selections = reference_array.clone + + def put_prompt (selections, prompt) + puts prompt + selections.each_with_index do |value,index| + puts "#{index} : #{value}" + end + end + + def add_value(output_list, item, procedure) + value = + end + + if options[:multiple] == true + output = Array.new + else + output = "" + end + + put_prompt selections, prompt + + while true + choice = Integer(STDIN.gets.strip()) + if choice.is_a? Integer + if choice >= 0 and choice < selections.count + if options[:multiple] == true + output.push(selections[choice]) + selections.delete_at(choice) + if get_verification "Are you done selecting?" + break + end + put_prompt selections, prompt + else + output = selections[choice] + break + end + else + puts "#{choice} is not between the values of 0 and #{selections.count}. Please try again." + end + else + puts "#{choice} is not a valid option. Please try again." + end + end + output +end + + # END: Helper Functions @@ -164,6 +212,7 @@ case $CONFIG[:action] usage exit end + end ## END: Checks @@ -234,6 +283,18 @@ class Bucket end log "Bucket[#{@bucketdir}] was loaded" end + + def filenames + filenames = Array.new + @entries.each_value do |entry| + entry.filepaths.each do |path| + if not filenames.include? path + filenames.push(path) + end + end + end + filesnames + end end # END: Classes @@ -262,36 +323,76 @@ def list_all_entries (bucket) end def list_entry_files (bucket) - filenames = Array.new - bucket.entries.each_value do |entry| - entry.filepaths.each do |path| - if not filenames.include? path - filenames.push(path) - end - end + puts bucket.filenames.sort.join("\n") +end + +def get_entry_by_file (bucket, filenames) + filename = "" + if filenames.count == 1 + filename = filenames[0] + else + filename = get_selections filenames, "Your filename matched multiple files. Please select one to restore" + end + + entries = bucket.entries.each_value.select{|entry| entry.filepaths.include filename} + if entries.count == 1 + entry = entries[0] + else + while true { + entry_timestamp_selection = get_selections entries.map{|entry| entry.mtime}, "Which timestamp to you want to revert the file to?" {|entry| entry.hash} + entries.each_value.select + entry = + + if get_verification "Do you want to see the contents of #{filename} at this time?" + puts entry.content + + end + } + end + + if filename[0] != '/' + filename = "/#{filename}" + end + + +end + +def get_entry_by_hash (bucket) + if bucket.entries.has_key? $CONFIG[:search_term] + entry = bucket.entries[$CONFIG[:search_term]] + filepath = "" + if entry.filepaths.count == 1 + filepath = entry.filepaths[0] + else + filepath = get_selections entry.filepaths, "What filepath do you wish to restore to?" + end + + if filepath[0] != '/' + filepath = "/#{filepath}" + end + + return entry, filepath + + else + puts "There were no entries corresponding to #{$CONFIG[:search_term]}" end - puts filenames.sort.join("\n") end def restore_entry (bucket) - if bucket.entries.has_key? $CONFIG[:search_term] - entry = bucket.entries[$CONFIG[:search_term]] - if entry.filepaths.count == 1 - filepath = entry.filepaths[0] - if filepath[0] != '/' - filepath = "/#{filepath}" - end - if get_verification "Are you sure you want to overwrite #{filepath}?" - File.open(filepath,'w') do |file| - file.write(entry.content) - end - else - puts "Ok not overwriting." - end - else + entry = nil + if bucket.filenames.any{ |filename| filename.include? $CONFIG[:search_term] } + filenames = bucket.filenames.select {|filename| filename.include $CONFIG[:search_term]} + entry, filepath = get_entry_by_file bucket, filenames + else + entry, filepath = get_entry_by_hash bucket + end + + if get_verification "Are you sure you want to overwrite #{filepath}?" + File.open(filepath,'w') do |file| + file.write(entry.content) end else - puts "There were no entries corresponding to #{$CONFIG[:search_term]}" + puts "Ok not overwriting." end end