Skip to content

Instantly share code, notes, and snippets.

@Zrubi
Created July 29, 2020 12:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Zrubi/60ec60eb857cf754311fbd7a2d5fcad6 to your computer and use it in GitHub Desktop.
Save Zrubi/60ec60eb857cf754311fbd7a2d5fcad6 to your computer and use it in GitHub Desktop.
My very basic Photo pre-processing script
work_dir = /home/user/tmp/import
<model>
<default>
prefix = OOO_00
author = Z
</default>
<D70>
orig = "dsc_\d{4}\.jpg"
author = Zrubi
prefix = D70_04
convert = -quality 95
# convert = -quality 95 -scale 1000x1000
</D70>
<D7100>
orig = "dsc_\d{4}\.jpg"
author = Zrubi
prefix = D7100_01
# convert = -quality 95
convert = -quality 95 -scale 1920x1920
</D7100>
<D40>
orig = "dsc_\d{4}\.jpg"
author = Zr
prefix = D40_00
convert = -quality 95
</D40>
</model>
#!/usr/bin/perl -w
use strict;
use Getopt::Long;
Getopt::Long::Configure ("bundling", "no_auto_abbrev");
use Config::General qw(ParseConfig);
use File::Basename;
use File::Copy;
use File::Find;
use File::Path;
#use File::stat;
#use Digest::MD5;
use Image::ExifTool;
use POSIX qw(strftime);
use Date::Parse;
#use Pod::Usage;
use Data::Dumper;
# kapcsolok
my ($help, $man, $ver);
my ($purge, $author, $prefix, $date, $dateshift, $rename, $convert, $assign, $stat);
my $loglevel = 1;
my $debug_level = 5;
my $target=0;
# konfig
my %conf;
my $temp_dir;
my %originals;
my %reworks;
my %skipped;
my %new_models;
srand;
sub myprint
{
my $string = shift;
my $level = shift;
if ($loglevel >= $level)
{
#print STDOUT strftime("%Y-%m-%d %T",localtime()), " $string\n";
print STDOUT "$string\n";
}
}
sub process_file {
assign($_);
print "$_\n";
}
sub get_originals {
my $file = $_;
my $know_model;
my $original;
my %f = () ;
if (-f $file) {
my $exifTool = new Image::ExifTool;
my $info = $exifTool->ImageInfo($file);
myprint(Data::Dumper->Dump([\$info], ['*exifdata']), $debug_level);
#$f{$file}{'file'} = $file;
$f{$file}{'path'} = $File::Find::name;
#$f{$file}{'name'} = fileparse($File::Find::name, qr/.(jpg)/i);;
my ($name,$path,$suffix) = fileparse($File::Find::name, qr/.(jpg|jpeg)/i);
$f{$file}{'name'} = $name;
if (!$suffix) {
$skipped{$file} = $f{$file};
return 1;
}
# van-e ilyen exif mezo egyatalan?
if ( $exifTool->GetValue('Model') ){
$f{$file}{'model'} = $exifTool->GetValue('Model');
while ( my($model, $value) = each %{$conf{'model'}}) {
# matchel-e a configban felvettek kozul valamelyikkel
#print "MATCH? '" .$exifTool->GetValue('Model') ."' =~ '$model'\n";
if ($exifTool->GetValue('Model') =~ $model){
$know_model = $model;
#print "MATCHED!: '$model'\n";
# illeszkedik-e a file neve a model alatt megadott mintara
if ($conf{'model'}{$model}{'orig'} and lc($file) =~ $conf{'model'}{$model}{'orig'}){
#print "MATCH: '$file' =~ '$conf{'model'}{$model}{'orig'}'\n";
$original = 1;
}
}
elsif(!$know_model){
# tehat van 'Model' exif tag, de nincs felveve a konfigba:
# ezeket eredetinek kezeljuk
$original = 1;
}
}
# globalisan megadott author eseten:
if ($author){
$f{$file}{'author'} = $author;
}
# model szekcioban megadott author eseten:
elsif($know_model){
$f{$file}{'author'} = $conf{'model'}{$know_model}{'author'};
}
# default szekcioban megadott author eseten:
elsif ($conf{'model'}{'default'}{'author'}){
$f{$file}{'author'} = $conf{'model'}{'default'}{'author'};
}
# globalisan megadott prefix eseten:
if ($prefix){
$f{$file}{'prefix'} = $prefix;
}
# model szekcioban megadott prefix eseten:
elsif($know_model){
$f{$file}{'prefix'} = $conf{'model'}{$know_model}{'prefix'};
}
# default szekcioban megadott prefix eseten:
elsif ($conf{'model'}{'default'}{'prefix'}){
$f{$file}{'prefix'} = $conf{'model'}{'default'}{'prefix'};
}
# globalisan megadott convert eseten:
if ($convert){
$f{$file}{'convert'} = $convert;
}
# model szekcioban megadott convert eseten:
elsif($know_model){
$f{$file}{'convert'} = $conf{'model'}{$know_model}{'convert'};
}
# default szekcioban megadott convert eseten:
elsif ($conf{'model'}{'default'}{'convert'}){
$f{$file}{'convert'} = $conf{'model'}{'default'}{'convert'};
}
$f{$file}{'date'} = $exifTool->GetValue('DateTimeOriginal') if $exifTool->GetValue('DateTimeOriginal');
# begyujtjuk az eredetinek minositett kepeket:
$originals{$file} = $f{$file} if $original;
# es gyujtjuk az ismeretlen model-re vonatkozo exif adatokat is:
$new_models{$exifTool->GetValue('Model')} = $exifTool->GetValue('Make') if !$know_model;
}
if (!$original){
#$f{$file}{'modif'} = "BW" if $exifTool->GetValue('ColorComponents') == 1;
$reworks{$file} = $f{$file};
}
}
}
sub assign_files{
my $action = shift;
my ($orig_filename, $rev_filename, $d, $serial, $rev, $ext);
myprint(Data::Dumper->Dump([\%originals], ['*originals']), 4) if $action eq "print";
myprint(Data::Dumper->Dump([\%reworks], ['*Reworks']), 4) if $action eq "print";
foreach my $orig_key (sort keys %originals){
my $f = $orig_key;
my $i = $f =~ /(\d{4,6})/;
$serial = $1;
$rev = 0;
$d = strftime("%Y%m%d", localtime(str2time($originals{$orig_key}{'date'})));
$ext = ".jpg";
#$orig_filename = $d ."-" .$originals{$orig_key}{'prefix'} .$serial ."-r" .sprintf("%02d",$rev) .$ext;
$orig_filename = $d ."-" .$originals{$orig_key}{'prefix'} .$serial .$ext;
print "\t$orig_key\t$originals{$orig_key}{'date'}\t$originals{$orig_key}{'model'} \n" if $action eq "print";
if ($action eq "rename"){
myprint("\tRenaming file: '$orig_key' -> $orig_filename",3);
rename("$temp_dir/$orig_key","$temp_dir/$orig_filename");
}
foreach my $rev_key (keys %reworks){
if ($reworks{$rev_key}{'name'} =~ $serial){
#if ($reworks{$rev_key}{'name'} =~ $originals{$orig_key}{'name'}){
$rev++;
if ($action eq "print"){
print "\t\t-> $rev_key\n";
}
elsif ($action eq "rename"){
#$rev_filename = $d ."-" .$originals{$orig_key}{'prefix'} .$serial ."-r" .sprintf("%02d",$rev) .$ext;
$rev_filename = $d ."-" .$originals{$orig_key}{'prefix'} .$serial ."-$rev" .$ext;
myprint("\tRenaming file: '$rev_key' -> $rev_filename",3);
rename("$temp_dir/$rev_key","$temp_dir/$rev_filename");
system("exiftool -q -overwrite_original -TagsFromFile $temp_dir/$orig_filename -exif:all $temp_dir/$rev_filename")
and "File: '$temp_dir/$rev_filename' cannot be modify: $!";
}
else{
system("exiftool -q -overwrite_original -TagsFromFile $originals{$orig_key}{path} -exif:all $reworks{$rev_key}{path}")
and "File: '$reworks{$rev_key}{path}' cannot be modify: $!";
}
}
}
print "\n" if $action eq "print";
}
print "\n";
}
sub print_stat{
assign_files('print');
}
sub copy_files{
foreach (keys %reworks){
myprint ("copy $reworks{$_}{'path'} $temp_dir/$_",$debug_level);
copy("$reworks{$_}{'path'}", "$temp_dir/$_") or die "File: '$reworks{$_}{'path'}' cannot be copied: $!";
}
foreach (keys %originals){
if ($originals{$_}{'convert'}){
myprint ("convert $originals{$_}{'path'} $originals{$_}{'convert'} $temp_dir/$_",$debug_level);
system("convert $originals{$_}{'path'} $originals{$_}{'convert'} $temp_dir/$_") and die "File: '$originals{$_}{'path'}' cannot be convert: $!";
}
else{
myprint ("copy $originals{$_}{'path'} $temp_dir/$_",$debug_level);
copy("$originals{$_}{'path'}", "$temp_dir/$_") or die "File: '$reworks{$_}{'path'}' cannot be copied: $!";
}
}
}
sub exif_rewrite {
my $file;
foreach (keys %originals){
$file = $originals{$_}{'path'};
if (-f $file) {
my $exifTool = new Image::ExifTool;
my $info = $exifTool->ImageInfo($file);
if ($originals{$_}{'author'}){
$exifTool->SetNewValue(Author => $originals{$_}{'author'});
}
if ($purge){
$exifTool->SetNewValue(PreviewImage => '');
$exifTool->SetNewValue('ThumbnailImage');
}
my $w_result = $exifTool->WriteInfo($file);
myprint ("WriteInfo: $w_result\n", $debug_level) if $w_result;
print "ERROR:" .$exifTool->GetValue('Error') ."\n" if $exifTool->GetValue('Error');
print "Warning:" .$exifTool->GetValue('Warning') ."\n" if $exifTool->GetValue('Warning');
}
}
}
GetOptions ('help' => \$help, 'man' => \$man, 'version|V' => \$ver,
'loglevel=i' => \$loglevel,
'author=s' => \$author,
'prefix=s' => \$prefix,
'date=s' => \$date,
'dateshift=s' => \$dateshift,
'purge' => \$purge,
'rename' => \$rename,
'convert' => \$convert,
'assign' => \$assign,
'stat' => \$stat,
) || pod2usage(1);
pod2usage(1) if $help;
pod2usage(-verbose => 2) if $man;
print_version() if $ver;
# konfig beolvasasa:
%conf = ParseConfig(
-ConfigFile => ".preprocess.conf",
-ConfigPath => "$ENV{HOME}/");
myprint(Data::Dumper->Dump([\%conf], ['*conf']), $debug_level);
if (!$stat){
$temp_dir = "$conf{work_dir}/" .time();
myprint("Creating temporary directory: '$temp_dir'", 3);
mkpath("$temp_dir", 0, 0750) or die("Couldn't make temporary directory: '$temp_dir': $!");
}
foreach $target (@ARGV){
$target =~ s/\/*$//;
myprint("Processing directory: '$target'", 1);
find(\&get_originals, $target);
myprint(Data::Dumper->Dump([\%originals], ['*originals']), 4);
myprint(Data::Dumper->Dump([\%reworks], ['*reworks']), 4);
myprint(Data::Dumper->Dump([\%skipped], ['*skipped']), 2);
myprint(Data::Dumper->Dump([\%new_models], ['*new_models']), 2);
if ($stat){
print_stat();
}
else{
myprint("Copying files from directory: '$target'", 1);
copy_files();
%originals = ();
%reworks = ();
find(\&get_originals, $temp_dir);
myprint(Data::Dumper->Dump([\%originals], ['*Originals']), 5);
myprint(Data::Dumper->Dump([\%reworks], ['*Reworks']), 5);
myprint(Data::Dumper->Dump([\%skipped], ['*Skipped']), 5);
myprint("Modifying EXIF data in files", 2);
exif_rewrite();
if ($assign){
if ($rename){
assign_files('rename');
}
else{
assign_files('rewrite');
}
}
myprint("You can find the processed files in: $temp_dir",1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment