└── canon_import.rb /canon_import.rb: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/ruby 2 | 3 | require 'optparse' 4 | require 'fileutils' 5 | 6 | require 'optparse' 7 | require 'ostruct' 8 | 9 | 10 | 11 | def main 12 | @@options = OpenStruct.new 13 | 14 | OptionParser.new do |opts| 15 | opts.banner = "Usage: image_grab.rb [options]" 16 | opts.on("-d", "--disk DISK", String, "disk location") do |d| 17 | @@options.disk = d 18 | end 19 | opts.on("-c", "--camera CAMERA", String, "use CAMERA as camera name prefix") do |c| 20 | @@options.camera = c 21 | end 22 | end.parse! 23 | 24 | 25 | disk = @@options.disk || guess_disk 26 | 27 | $stderr.puts "looking for images in #{disk}" 28 | begin 29 | dirs = Dir.open("#{disk}/DCIM").visible_entries 30 | rescue Errno::ENOENT 31 | $stderr.puts "#{disk} doesn't seem to be a Canon flash drive" 32 | exit 1 33 | end 34 | 35 | dirs.each do |dname| 36 | d = Dir.open("#{disk}/DCIM/#{dname}") 37 | process_dir(d) 38 | end 39 | 40 | end 41 | 42 | 43 | class Dir 44 | def visible_entries 45 | self.entries.collect do |e| 46 | if e.match(/^\./) 47 | nil 48 | else 49 | e 50 | end 51 | end.compact 52 | end 53 | end 54 | 55 | 56 | 57 | 58 | def process_dir(d) 59 | path = d.path 60 | 61 | if md = d.path.match(/(\d+)(\D.+)$/) 62 | dirnum = md[1] 63 | camera = @@options.camera || md[2] 64 | d.visible_entries.each do |filename| 65 | num = filenum(filename) 66 | ext = fileext(filename) 67 | file = File.open("#{path}/#{filename}") 68 | dirname = sprintf("%04d-%02d-%02d", file.mtime.year, file.mtime.month, file.mtime.day) 69 | FileUtils.mkdir_p(dirname) 70 | new_name = "#{dirname}/#{camera}-#{dirnum}-#{num}.#{ext}" 71 | FileUtils.cp(file.path, new_name, :preserve => true) 72 | puts new_name 73 | end 74 | end 75 | end 76 | 77 | def filenum(filename) 78 | md = filename.match(/\D+(\d+)/) 79 | return md[1] 80 | end 81 | 82 | def fileext(filename) 83 | md = filename.match(/\.([^\.]+)$/) 84 | return md[1] 85 | end 86 | 87 | 88 | 89 | def guess_disk 90 | volumes = Dir.open("/Volumes") 91 | volumes.visible_entries.each do |d| 92 | if d.match(/CANON/) 93 | return "/Volumes/#{d}" 94 | end 95 | end 96 | end 97 | 98 | 99 | 100 | main() 101 | --------------------------------------------------------------------------------