class Object

Public Instance Methods

build_paths(dest, file, date) click to toggle source
# File lib/methods/build_paths.rb, line 3
def build_paths(dest, file, date)
  date = get_dates(file)
  destpath = "#{dest}/#{date}"
  destpath = destpath.gsub('//', '/')
  outfile =  "#{destpath}/#{File.basename(file)}"
  [outfile, destpath]
end
copy_pic(file, outfile, destpath, dryrun = nil, file_op = 'cp') click to toggle source
# File lib/methods/copy_pic.rb, line 13
def copy_pic(file, outfile, destpath, dryrun = nil, file_op = 'cp')
  if File.exist?(outfile)
    puts "\"#{outfile}\" #{"already exists. Skipping...".colorize(:light_blue)}."
  else
    unless dryrun
      unless File.exist?(destpath)
        puts "creating folder \"#{destpath}\""
        FileUtils.mkdir_p(destpath)
      end
    end
    process_file(file, outfile, dryrun, file_op)
  end
end
display_help(err=nil,color=nil) click to toggle source
# File lib/methods/display_help.rb, line 1
def display_help(err=nil,color=nil)
  print <<~HELPFILE
    ===== ImageBackup =====

    Keep your photos and videos organized by date.

    A simple terminal app to crawl a folder (usually a camera card's DCIM folder) for pictures and videos, and pop them in dated folders to your destination folder of choice. Uses exif data when available, creation_time, or the file's own creation date if nothing better is present.

    Will also copy over any xmp sidecar files found, not overwriting.

    Options:

    -n, --dry-run                            Run without actually doing anything. Good for making sure
                                             things are working properly. This will also give you console
                                             output which helps identify unreadable files.

    -a, --add-filetype <extension> <type>    This will add a custom file type to the list of files it's
                                             looking for. If you have an arcane digital camera (we
                                             currently support canon, sony, pentax but new stuff comes out
                                             all the time), this will allow you to add your raw files.
                                             You can also access *filetypes.csv* and add them manually,
                                             but ensure there's a blank line at the end or this program
                                             may behave badly.

    -m, --move                               Will move (deleting the original), which is probably not a
                                             good idea in most cases but still useful at times.
    -l, --link                               Create symbolic links instead of copying or moving
                                             actual files. Useful for large videos.

    Usage:

    - To backup a camera card:

    $ cd /media/username/EOS_DIGITAL/DCIM
    $ imagebackup.rb ~/Photos/raw

    This will search all files within the DCIM folder, check them with either exiv2 (for stills) or ffprobe (for videos) and retrieve their creation dates.
    It will then copy them to a folder of the form ~/Photos/raw/<yyyy>-<mm>-<dd>
    If it's unable to find metadata in a file it will look at the file's creation time attribute, which is less reliable but usually ok.

    - To register a new file type:

    $ imagebackup.rb --add-filetype orf pic
    or
    $ imagebackup.rb -a orf pic

    This will work with *.ORF, orf, ".orf" as it will strip off any unnecessary characters. It is case-insensitive.

    - To do a dry run, checking each file and destination but not actually copying:

    $ imagebackup.rb -n ~/Photos/raw
    or
    $ imagebackup.rb ~/Photos/raw --dry-run

    - To move files instead of copying them (careful!):

    $ imagebackup.rb -m ~/Photos/raw
    or
    $ imagebackup.rb --move ~/Photos/raw

    - To make symbolic links instead of copying files:

    $ imagebackup.rb -l ~/Photos/raw
    or
    $ imagebackup.rb --link ~/Photos/raw

    This mode can be useful if you want to operate on the files in one place but keep them on their media. Particularly useful for large movie files.
  HELPFILE
  puts err.to_s.colorize(color)
  exit(0)
end
get_dates(file) click to toggle source
# File lib/methods/get_dates.rb, line 1
def get_dates(file)
  begin
    image = Exiv2::ImageFactory.open(file)
    image.read_metadata
    date = image.exif_data.find { |v| v[0] == 'Exif.Image.DateTime' }
    date = date[1].split[0].gsub(':', '-')
  rescue StandardError
    begin
      probe = Ffprober::Parser.from_file(file)
      date = probe.format.tags[:creation_time].split(/[T ]/)[0]
    rescue StandardError
      fileobj = File.new(file)
      date = "#{"%04d" % fileobj.stat.ctime.year}-#{"%02d" % fileobj.stat.ctime.month}-#{"%02d" % fileobj.stat.ctime.day}"
    end
  end
  date
end
main_loop(dest, dryrun = true, file_op = 'copy') click to toggle source
# File lib/imagebackup.rb, line 17
def main_loop(dest, dryrun = true, file_op = 'copy')
  file_types = FileTypes.list
  Dir.glob(file_types).reverse_each do |f|
    file = "#{Dir.pwd}/#{f}"

    parms = build_paths(dest, file, get_dates(file))
    outfile = parms[0]
    destpath = parms[1]

    copy_pic(file, outfile, destpath, dryrun, file_op)
  end
  puts "\nFinished!\n".colorize(:light_green)
end
process_file(file, outfile, dryrun = nil, file_op = 'cp') click to toggle source
# File lib/methods/copy_pic.rb, line 1
def process_file(file, outfile, dryrun = nil, file_op = 'cp')
  if dryrun
    puts "#{"pretending to ".colorize(:light_green)}#{file_op} \"#{file}\"#{" to ".colorize(:light_green)}\"#{outfile}\""
  else
    puts "#{file_op}-ing \"#{file} to #{outfile}\"..."
    FileUtils.public_send(file_op, file, outfile)
    if File.exist?("#{file}.xmp")
      FileUtils.public_send(file_op, "#{file}.xmp", "#{outfile}.xmp")
    end
  end
end