NAME

import-pictures - copy/move pictures from a directory


SYNOPSIS

import-pictures [options]


DESCRIPTION

import-pictures copies or moves pictures from one directory (for example from a mounted camera) to another directory. You can choose date ranges from within to copy the images. For example you can just choose the pictures from one day of the event in one directory and after that you can move the other day into another directory.


OPTIONS

-h, --help

Prints out a brief help

-d, --debug

Enable additional debug informations

-m, --move

Move pictures instead of copying

-x, --exif

Use exif metadata as data instead of creation date of the file

-f, --filetypes "filetypes" (default: jpg,nef)

Comma separated list of file extensions to work on (default jpg and nef)

-o, --origin "origindir"

From which directory pictures should be copied.

-t, --to "targetdir"

Where to copy the pictures to. If targetdir does not exist it will be created.

-s, --start-date "date"

From which date images should get copied. You can use relative dates as used in the date command.

-e, --end-date "date"

Until which date images should get copied. You can use relative dates as used in the date command.

-i, --start-num "startnumber"

Starting number for the _COUNTER_ template

-r, --rotate

Use exifautotran to rotate the pictures automatically

--simulate

Don't do anything, just print out what would happen.

-T, --template "templatestring"

You can rename files according to a simple template string. Currently the following template strings are supported:

_COUNTER_

This is a counter which gets incremented for every picture

_DAY_, _MONTH_, _YEAR, _HOUR_, _MINUTE_, _SEC_

Will be replaced by the according date strings.

NOTE: Don't add a file extension the templat or you will end with doubled extensions.

For example 'foobar-_YEAR__MONTH__DAY_-_COUNTER_' results in filenames like foobar-20060916-44.nef


EXAMPLES

Copy the pictures from the last week up to now based on their exif tag and rename them to last_week-YearMonthDay-Counter.suffix

  % import-pictures --exif --start-date 'one week ago' --origin /mnt/cam/DCIM/
    --to Bilder/Last_Week --template 'last_week-_YEAR__MONTH__DAY_-_COUNTER_'


AUTHOR

Alexander Wirt <formorer@formorer.de>


COPYRIGHT

 Copyright 2006 Alexander Wirt <formorer@formorer.de>
 This program is licensed under the GNU General Public License v2.
 You may fold, spindle, and mutilate this software under the terms of the GPL.
 
=cut

use strict; use English; use Pod::Usage; use Getopt::Long; use File::Path qw(mkpath); use Data::Dumper; use Image::ExifTool 'ImageInfo'; use Date::Format; use Time::ParseDate; use File::Copy; use File::Basename;

Getopt::Long::Configure ("bundling");

my $filetypes = ''; my ($debug,$help, $exif, $move, $simulate, $rotate) = 0; my ($rename,$to, $start_date) = ''; my $start_date = "1970/1/2"; #if you have soooo old files you have a problem... my $end_date = localtime (time); my $startnum = 1; my (@from, @files);

GetOptions('help|h' => \$help, #Help function
'debug|d' => \$debug, #print more details
'move|m' => \$move, #move the pictures instead of copying
'exif|x' => \$exif, #use exifdate for date selection
'filetypes|f=s' => \$filetypes, #which filetypes to select
'to|t=s' => \$to, #where to copy the images
'origin|o=s' => \@from, #from where to opy the images
'start-date|s=s' => \$start_date, #from when to copy images
'end-date|e=s' => \$end_date, #until when to copy images
'template|T=s' => \$rename,
'start-num|n=i' => \$startnum,
'simulate' => \$simulate,
'rotate|r' => \$rotate,
);

pod2usage(1) if $help;

die "Need target directory" unless $to; die "Need source directory" unless @from;

if (! $filetypes) { $filetypes = 'jpg|nef'; } else { $filetypes = join('|', split(/,/,$filetypes)); }

foreach my $dir (@from) { warn "$dir"; scan_dir($dir); }

#check the target directory

if (-d "$to" && -w "$to") { print "Target '$to' already exists\n"; } else { eval { mkpath($to) }; if ($@) { print "Couldn't create target directory '$to': $@"; } }

my $i = $startnum; foreach my $file (@files) { my $picture_date; #Receive the creation date of the file if ($exif) { my $info = ImageInfo("$file"); $picture_date = $info->{'CreateDate'} || $info->{'DateTimeOriginal'}; if (! $picture_date ) { print "Could not read exif data of $file - ignored\n"; next; }


        if ($picture_date =~ /^([\d:]+)\s+(.*)$/) {
                my $time = $2; 
                my $day = $1; 
                $day =~ s/:/\//g;
                $picture_date = "$day $time"; 
        }
    } else {
        $picture_date = time2str("%a %b %e %T %Y", (stat($file))[10]);
    }
    my $targetfile;
    if ($rename) { 
            $targetfile = evaluate_template($file, $picture_date, $i); 
            print basename($file) . " evaluates to $targetfile\n" if $debug;
            $i++;
        } else { 
            $targetfile = basename($file);
    }
    #check if the file fits into the date
    if (check_date({ start_date => $start_date, end_date => $end_date,
                picture_date=> $picture_date})) {
        #create directories first
        if ($targetfile =~ /\//) {
                my $directory = dirname($targetfile); 
                eval { mkpath("$to/$directory") };
                if ($@) {
                        print "Couldn't create target directory '$to/$directory': $@";
                }
        }
        if ($move) {
            
            print "Move file from $file to $to/$targetfile\n";
            move("$file", "$to/$targetfile") unless $simulate;
        } else {
            print "Copy file from $file to $to/$targetfile\n";
            copy("$file", "$to/$targetfile") unless $simulate;
        }
        
        if ($rotate) {
            print "Rotate $to/$targetfile\n";
            my @args = ("exifautotran", "$to/$targetfile");
            system(@args) unless $simulate; 
        }
    } else {
        print "$file does not match criteria\n" if $debug;
    }
}

sub check_date ($) { my $date = shift; my $start_date = parsedate($date->{start_date}); my $end_date = parsedate($date->{end_date}); my $picture_date = parsedate($date->{picture_date}); print "Start: " . time2str("%a %b %e %T %Y\n", $start_date) if $debug; print "End: " . time2str("%a %b %e %T %Y\n", $end_date) if $debug; print "File: " . time2str("%a %b %e %T %Y\n", $picture_date) if $debug; return 1 if ( $picture_date >= $start_date && $picture_date <= $end_date ); return 0; }

sub evaluate_template($) { my ($filename,$picture_date, $i) = @_; my($filename, $directories, $suffix) = fileparse($filename, qr/\.[^.]*/); my $fname = $rename; $suffix = lc($suffix);

    my $seconds = parsedate("$picture_date"); 
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = 
        localtime($seconds);
    $year += 1900;
    $mon += 1; 
    $mon = sprintf("%02d", $mon);
    
    $mday = sprintf("%02d", $mday);
    $hour = sprintf("%02d", $hour); 
    $min = sprintf("%02d", $min); 
    $sec = sprintf("%02d", $sec);
    print "Template: $fname\n" if $debug; 
    $fname =~ s/_DAY_/$mday/g;
    $fname =~ s/_MONTH_/$mon/g;
    $fname =~ s/_YEAR_/$year/g;
    $fname =~ s/_HOUR_/$hour/g;
    $fname =~ s/_MINUTE_/$min/g;
    $fname =~ s/_SEC_/$sec/g;
    $fname =~ s/_COUNTER_/$i/g;
    $fname .= "$suffix";
    return $fname;
}

sub scan_dir ($) { my $dir = shift; local *DIR; print "Reading: $dir\n" if $debug; opendir (DIR, "$dir") || die "Can't open $dir: $!"; while (my $entry = readdir(DIR)) { next if $entry =~ /^\.{1,2}$/; if (-d "$dir/$entry") { scan_dir("$dir/$entry"); } push @files, "$dir/$entry" if $entry =~ /^[^.].*\.($filetypes)$/i } closedir DIR; }

#!/usr/bin/perl # $Id: import-pictures 14 2007-05-22 20:00:19Z formorer $

# Copyright (C) 2007 Alexander Wirt <formorer@formorer.de> # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA #


NAME

import-pictures - copy/move pictures from a directory


SYNOPSIS

import-pictures [options]


DESCRIPTION

import-pictures copies or moves pictures from one directory (for example from a mounted camera) to another directory. You can choose date ranges from within to copy the images. For example you can just choose the pictures from one day of the event in one directory and after that you can move the other day into another directory.


OPTIONS

-h, --help

Prints out a brief help

-d, --debug

Enable additional debug informations

-m, --move

Move pictures instead of copying

-x, --exif

Use exif metadata as data instead of creation date of the file

-f, --filetypes "filetypes" (default: jpg,nef)

Comma separated list of file extensions to work on (default jpg and nef)

-o, --origin "origindir"

From which directory pictures should be copied.

-t, --to "targetdir"

Where to copy the pictures to. If targetdir does not exist it will be created.

-s, --start-date "date"

From which date images should get copied. You can use relative dates as used in the date command.

-e, --end-date "date"

Until which date images should get copied. You can use relative dates as used in the date command.

-i, --start-num "startnumber"

Starting number for the _COUNTER_ template

-r, --rotate

Use exifautotran to rotate the pictures automatically

--simulate

Don't do anything, just print out what would happen.

-T, --template "templatestring"

You can rename files according to a simple template string. Currently the following template strings are supported:

_COUNTER_

This is a counter which gets incremented for every picture

_DAY_, _MONTH_, _YEAR, _HOUR_, _MINUTE_, _SEC_

Will be replaced by the according date strings.

NOTE: Don't add a file extension the templat or you will end with doubled extensions.

For example 'foobar-_YEAR__MONTH__DAY_-_COUNTER_' results in filenames like foobar-20060916-44.nef


EXAMPLES

Copy the pictures from the last week up to now based on their exif tag and rename them to last_week-YearMonthDay-Counter.suffix

  % import-pictures --exif --start-date 'one week ago' --origin /mnt/cam/DCIM/
    --to Bilder/Last_Week --template 'last_week-_YEAR__MONTH__DAY_-_COUNTER_'


AUTHOR

Alexander Wirt <formorer@formorer.de>


COPYRIGHT

 Copyright 2006 Alexander Wirt <formorer@formorer.de>
 This program is licensed under the GNU General Public License v2.
 You may fold, spindle, and mutilate this software under the terms of the GPL.
 
=cut

use strict; use English; use Pod::Usage; use Getopt::Long; use File::Path qw(mkpath); use Data::Dumper; use Image::ExifTool 'ImageInfo'; use Date::Format; use Time::ParseDate; use File::Copy; use File::Basename;

Getopt::Long::Configure ("bundling");

my $filetypes = ''; my ($debug,$help, $exif, $move, $simulate, $rotate) = 0; my ($rename,$to, $start_date) = ''; my $start_date = "1970/1/2"; #if you have soooo old files you have a problem... my $end_date = localtime (time); my $startnum = 1; my (@from, @files);

GetOptions('help|h' => \$help, #Help function
'debug|d' => \$debug, #print more details
'move|m' => \$move, #move the pictures instead of copying
'exif|x' => \$exif, #use exifdate for date selection
'filetypes|f=s' => \$filetypes, #which filetypes to select
'to|t=s' => \$to, #where to copy the images
'origin|o=s' => \@from, #from where to opy the images
'start-date|s=s' => \$start_date, #from when to copy images
'end-date|e=s' => \$end_date, #until when to copy images
'template|T=s' => \$rename,
'start-num|n=i' => \$startnum,
'simulate' => \$simulate,
'rotate|r' => \$rotate,
);

pod2usage(1) if $help;

die "Need target directory" unless $to; die "Need source directory" unless @from;

if (! $filetypes) { $filetypes = 'jpg|nef'; } else { $filetypes = join('|', split(/,/,$filetypes)); }

foreach my $dir (@from) { warn "$dir"; scan_dir($dir); }

#check the target directory

if (-d "$to" && -w "$to") { print "Target '$to' already exists\n"; } else { eval { mkpath($to) }; if ($@) { print "Couldn't create target directory '$to': $@"; } }

my $i = $startnum; foreach my $file (@files) { my $picture_date; #Receive the creation date of the file if ($exif) { my $info = ImageInfo("$file"); $picture_date = $info->{'CreateDate'} || $info->{'DateTimeOriginal'}; if (! $picture_date ) { print "Could not read exif data of $file - ignored\n"; next; }


        if ($picture_date =~ /^([\d:]+)\s+(.*)$/) {
                my $time = $2; 
                my $day = $1; 
                $day =~ s/:/\//g;
                $picture_date = "$day $time"; 
        }
    } else {
        $picture_date = time2str("%a %b %e %T %Y", (stat($file))[10]);
    }
    my $targetfile;
    if ($rename) { 
            $targetfile = evaluate_template($file, $picture_date, $i); 
            print basename($file) . " evaluates to $targetfile\n" if $debug;
            $i++;
        } else { 
            $targetfile = basename($file);
    }
    #check if the file fits into the date
    if (check_date({ start_date => $start_date, end_date => $end_date,
                picture_date=> $picture_date})) {
        #create directories first
        if ($targetfile =~ /\//) {
                my $directory = dirname($targetfile); 
                eval { mkpath("$to/$directory") };
                if ($@) {
                        print "Couldn't create target directory '$to/$directory': $@";
                }
        }
        if ($move) {
            
            print "Move file from $file to $to/$targetfile\n";
            move("$file", "$to/$targetfile") unless $simulate;
        } else {
            print "Copy file from $file to $to/$targetfile\n";
            copy("$file", "$to/$targetfile") unless $simulate;
        }
        
        if ($rotate) {
            print "Rotate $to/$targetfile\n";
            my @args = ("exifautotran", "$to/$targetfile");
            system(@args) unless $simulate; 
        }
    } else {
        print "$file does not match criteria\n" if $debug;
    }
}

sub check_date ($) { my $date = shift; my $start_date = parsedate($date->{start_date}); my $end_date = parsedate($date->{end_date}); my $picture_date = parsedate($date->{picture_date}); print "Start: " . time2str("%a %b %e %T %Y\n", $start_date) if $debug; print "End: " . time2str("%a %b %e %T %Y\n", $end_date) if $debug; print "File: " . time2str("%a %b %e %T %Y\n", $picture_date) if $debug; return 1 if ( $picture_date >= $start_date && $picture_date <= $end_date ); return 0; }

sub evaluate_template($) { my ($filename,$picture_date, $i) = @_; my($filename, $directories, $suffix) = fileparse($filename, qr/\.[^.]*/); my $fname = $rename; $suffix = lc($suffix);

    my $seconds = parsedate("$picture_date"); 
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = 
        localtime($seconds);
    $year += 1900;
    $mon += 1; 
    $mon = sprintf("%02d", $mon);
    
    $mday = sprintf("%02d", $mday);
    $hour = sprintf("%02d", $hour); 
    $min = sprintf("%02d", $min); 
    $sec = sprintf("%02d", $sec);
    print "Template: $fname\n" if $debug; 
    $fname =~ s/_DAY_/$mday/g;
    $fname =~ s/_MONTH_/$mon/g;
    $fname =~ s/_YEAR_/$year/g;
    $fname =~ s/_HOUR_/$hour/g;
    $fname =~ s/_MINUTE_/$min/g;
    $fname =~ s/_SEC_/$sec/g;
    $fname =~ s/_COUNTER_/$i/g;
    $fname .= "$suffix";
    return $fname;
}

sub scan_dir ($) { my $dir = shift; local *DIR; print "Reading: $dir\n" if $debug; opendir (DIR, "$dir") || die "Can't open $dir: $!"; while (my $entry = readdir(DIR)) { next if $entry =~ /^\.{1,2}$/; if (-d "$dir/$entry") { scan_dir("$dir/$entry"); } push @files, "$dir/$entry" if $entry =~ /^[^.].*\.($filetypes)$/i } closedir DIR; }