Created
May 4, 2010 16:18
-
-
Save thekindofme/389604 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
This file contains hidden or 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 'find' | |
require 'exifr' | |
require "fileutils" | |
class PhotoOrganizer | |
SOURCE_DIRS = ["/media/truecrypt1/nick_picks"] | |
EXCLUDES = ["CVS"] | |
DEST_DIR = "/media/truecrypt1/dow_jones" | |
DEST_DIR_OTHER = "/media/truecrypt1/dow_jones/other" | |
DUPLICATES = "duplicates" | |
IMAGE_FILE_EXTS = [".jpg", ".jpeg"] | |
STATS_LOG_FILE = "stats.log" | |
DUPLICATES_LOG_FILE = "duplicate_files.log" | |
def run | |
FileUtils.mkdir_p "#{DEST_DIR}#{File::SEPARATOR}#{DUPLICATES}" | |
FileUtils.mkdir_p DEST_DIR_OTHER | |
@files_with_valid_exif_data = [] | |
@files_with_invalid_exif_data = [] | |
@files_with_invalid_ext = [] | |
@duplicate_files = [] | |
@files_with_same_timestamp = [] | |
@unique_files = [] | |
walk_the_source_dir | |
write_log_file | |
end | |
def write_log_file | |
log = <<EOS | |
Files with valid EXIF data = #{@files_with_valid_exif_data.size} | |
Files with invalid EXIF data = #{@files_with_invalid_exif_data.size} | |
Files with invalid_ext = #{@files_with_invalid_ext.size} | |
Duplicate files = #{@duplicate_files.size} | |
Files with same timestamp = #{@files_with_same_timestamp.size} | |
Unique files = #{@unique_files.size} | |
EOS | |
File.open("#{DEST_DIR}#{File::SEPARATOR}#{STATS_LOG_FILE}", 'w') {|f| f.write(log) } | |
File.open("#{DEST_DIR}#{File::SEPARATOR}#{DUPLICATES_LOG_FILE}", 'w') {|f| | |
@duplicate_files.each { |entry| | |
f.puts "duplicate of #{entry[:original]} found in #{entry[:duplicate]}" | |
} | |
} | |
end | |
def walk_the_source_dir | |
SOURCE_DIRS.each do |dir| | |
Find.find(dir) do |path| | |
if FileTest.directory?(path) | |
if EXCLUDES.include?(File.basename(path)) | |
Find.prune # Don't look any further into this directory. | |
else | |
next | |
end | |
else | |
#p "processing #{path}..." | |
process_file path | |
end | |
end | |
end | |
end | |
def process_file source_path | |
file_ext = File.extname(source_path.downcase) | |
if IMAGE_FILE_EXTS.include? file_ext | |
exif_file = EXIFR::JPEG.new(source_path) | |
if exif_file.exif? && exif_file.date_time | |
@files_with_valid_exif_data << source_path | |
copy_file(source_path, exif_file.date_time) | |
else | |
p "#{source_path}: doesn't contain valid EXIF data, hence using ctime" | |
@files_with_invalid_exif_data << source_path | |
copy_file(source_path, File.new(source_path).ctime) | |
end | |
else | |
p "#{source_path}:doesn't have a valid file ext. Coping to Other" | |
@files_with_invalid_ext << source_path | |
FileUtils.cp source_path, "#{DEST_DIR_OTHER}#{File::SEPARATOR}#{File.basename(source_path)}" | |
end | |
end | |
def copy_file source_path, timestamp | |
dest_dir = "#{DEST_DIR}#{File::SEPARATOR}#{timestamp.year}#{File::SEPARATOR}#{timestamp.strftime("%b")}#{File::SEPARATOR}#{timestamp.strftime("%d - %a")}" | |
dest_file_path = "#{dest_dir}#{File::SEPARATOR}#{timestamp.strftime("%p %I:%M:%S")}" | |
FileUtils.mkdir_p dest_dir | |
if File.exists?(dest_file_path) | |
if FileUtils.compare_file(source_path, dest_file_path) | |
@count = 0 | |
@duplicate_files << {:duplicate => source_path, :original => dest_file_path} | |
FileUtils.cp source_path, "#{DEST_DIR}#{File::SEPARATOR}#{DUPLICATES}#{File::SEPARATOR}#{File.basename(source_path)}-#{rand(51252)}" | |
else #two or more uniuqe files with the same timestamp | |
@count = @count + 1 | |
@files_with_same_timestamp << source_path | |
FileUtils.cp source_path,"#{dest_file_path} - #{@count}" | |
end | |
else | |
@unique_files << source_path | |
@count = 0 | |
FileUtils.cp source_path, dest_file_path | |
end | |
p "copied #{source_path} to #{dest_file_path}" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment