#!/usr/local/bin/perl -w use strict; use warnings FATAL => 'all'; use Data::Dumper; use Image::ExifTool qw(:Public); use DB_File; my $androidversion_to_model = { '6.0.1' => 'SM-N910C', '9' => 'SM-N950F', '10' => 'SM-N960F', }; my $verbose; my $args = join ' ', @ARGV; $verbose = 1 if $args =~ /v/; chdir '/home/ketas/files/symlink-img-archive' || die $!; tie my %db, 'DB_File', '.exif-symlinks.db' || die $!; $SIG{$_} = \&clean_exit foreach qw(INT TERM); sub clean_exit { untie %db; exit; } while (my $file = ) { $file =~ s/^\s+//; $file =~ s/\s+$//; printf "\n\n[%s]\n\n", $file if $verbose; if ($db{$file}) { print "in db, skip\n" if $verbose; next; } my $tags_file = $file; if ($file =~ /^(.+\.)AVI$/) { $tags_file = sprintf "%sTHM", $1; unless (-e $tags_file) { printf "no tags file '%s'\n", $tags_file; next; } } my $exif = ImageInfo $tags_file; my $error = $exif->{Error}; my $model = $exif->{Model} || 'UNKNOWN'; my $datetime = $exif->{DateTimeOriginal} || $exif->{MediaCreateDate}; my $androidversion = $exif->{AndroidVersion}; if ($error) { next if $error eq 'File is empty' && !$verbose; my $extra = ''; $extra = sprintf " in '%s'", $file unless $verbose; printf "error '%s'%s\n", $error, $extra; next; } $model = $androidversion_to_model->{$androidversion} if $model eq 'UNKNOWN' && $androidversion && $androidversion_to_model->{$androidversion}; unless ($model) { my $extra = ''; $extra = sprintf " in '%s'", $file unless $verbose; printf "no model%s\n", $extra; next; } unless ($datetime) { my $extra = ''; $extra = sprintf " in '%s'", $file unless $verbose; printf "no datetime%s\n", $extra; next; } my $safe_model = $model; $safe_model =~ s/[^a-zA-Z0-9_-]+/_/g; if ($datetime =~ /^(\d{4}):(\d{2}):(\d{2})\s+\d{2}:\d{2}:\d{2}$/) { my $year = $1; my $month = $2; my $day = $3; my $iso_date = sprintf "%s-%s-%s", $year, $month, $day; my $file_basename = $file; $file_basename =~ s|^.*/||; my $dir_camera = $safe_model; my $dir_year = sprintf "%s/%s", $dir_camera, $year; my $dir_month = sprintf "%s/%s-%s", $dir_year, $year, $month; my $dir_day = sprintf "%s/%s", $dir_month, $iso_date; my $symlink_file = sprintf "%s/%s", $dir_day, $file_basename; foreach my $dir ($dir_camera, $dir_year, $dir_month, $dir_day) { unless (-e $dir) { printf "mkdir '%s'\n", $dir; mkdir $dir || die $!; } } unless (-e $symlink_file) { printf "symlink '%s'\n", $symlink_file; symlink $file, $symlink_file || die $!; $db{$file} = 1; } } else { printf "invalid datetime '%s'\n", $datetime; next; } } clean_exit;