Created
September 11, 2011 19:06
-
-
Save h3rald/1209976 to your computer and use it in GitHub Desktop.
Directory Scanner based on SHA1 hash comparison
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment