Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require "pathname"
- require "digest/sha1"
- require "yaml"
- require 'trollop'
- module DirScan
- class Scanner
- def initialize dir=Dir.pwd, options={:verbose => false}
- @dir = Pathname.new(dir).expand_path
- @file = Pathname.new('dirscan.yml').expand_path
- @verbose = options[:verbose]
- end
- def scan
- puts "Scanning '#{@dir}'..."
- @contents = {}.tap do |contents|
- @dir.find do |f|
- contents[f.to_s] = sha1 f if f.file?
- end
- end
- end
- def sha1 file
- Digest::SHA1.new.tap do |hash|
- File.open(file, 'r') do |fh|
- while buffer = fh.read(1024) do
- hash << buffer
- end
- end
- end.to_s
- end
- def save
- puts "Saving '#{@file}'..."
- File.open(@file, 'w+') do |f|
- h = {
- :directory => @dir,
- :timestamp => Time.now,
- :contents => @contents
- }
- f.write h.to_yaml
- end
- end
- def compare
- @snapshot = YAML.load_file @file
- a_hash = @snapshot[:contents]
- b_hash = scan
- a_hash.delete_if {|k, v| k =~ /[\/\\]dirscan.yml$/}
- b_hash.delete_if {|k, v| k =~ /[\/\\]dirscan.yml$/}
- @result = {:created => [], :updated => [], :deleted => [], :unchanged => []}
- a_hash.each do |a_key, a_value|
- b_value = b_hash.delete a_key
- case
- when !b_value then
- @result[:deleted] << a_key
- when b_value != a_value then
- @result[:updated] << a_key
- else
- @result[:unchanged] << a_key
- end
- end
- @result[:created] = b_hash.keys
- end
- def report
- total = @result.values.map{|v| v.size}.inject :'+'
- puts "="*50
- puts "Total files: #{total}"
- puts "- Unchanged: #{@result[:unchanged].size}"
- puts
- puts "Differences since #{@snapshot[:timestamp]}:"
- puts "- Updated: #{@result[:updated].size}"
- show_files :updated
- puts "- Deleted: #{@result[:deleted].size}"
- show_files :deleted
- puts "- Created: #{@result[:created].size}"
- show_files :created
- puts "="*50
- end
- protected
- def show_files key
- return unless @verbose
- @result[key].each do |file|
- puts "\t#{file.gsub /^#{Regexp.escape @dir.to_s}/, ''}"
- end
- end
- end
- end
- options = Trollop::options do
- opt :scan, "Scan directory", :default => Dir.pwd
- opt :compare, "Compare files", :default => false
- opt :write, "Save snapshot file", :default => false
- opt :verbose, "Display file names as well", :default => false
- end
- scanner = DirScan::Scanner.new(options[:scan], :verbose => options[:verbose])
- if options[:compare] then
- scanner.compare
- scanner.save if options[:write]
- scanner.report
- else
- scanner.scan
- scanner.save
- end
Add Comment
Please, Sign In to add comment