2 # UCW Gallery: Symlink photos according to their EXIF timestamps
3 # (c) 2013 Martin Mares <mj@ucw.cz>
10 if (@ARGV && $ARGV[0] eq '--help') {
12 Usage: cat list | gal date [<options>]
13 or: gal date [<options>] <files>
16 -d, --destdir=<dir> Create symlinks in specified directory (default: current dir)
17 -n, --dry-run Perform a trial run with no changes made
18 -o, --offset=<offset> Adjust timestamps by a given offset (<h>[:<m>[:<s>]])
19 --suffix=<s> Add suffix to all names
20 -s, --symbolic Create symbolic links (default: hardlinks)
29 Getopt::Long::Configure('bundling');
31 'destdir|d=s' => \$destdir,
32 'dry-run|n!' => \$dry_run,
33 'offset|o=s' => \$offset,
34 'suffix=s' => \$suffix,
35 'symbolic|s!' => \$symbolic,
36 ) or die "Try gal date --help\n";
46 if ($offset =~ m{^([+-])?(\d)+(:(\d+)(:(\d+))?)?$}) {
47 $offset = $2 * 3600 + ($4 // 0) * 60 + ($6 // 0);
48 if ($1 eq '-') { $offset = -$offset; }
50 die "Invalid offset: $offset\n";
53 foreach my $f (@src) {
54 my $e = new Image::EXIF($f);
55 my $i = $e->get_all_info();
57 print STDERR "EXIF error on $f: ", $e->error, "\n";
60 # print STDERR Dumper($i), "\n";
62 my $d = $i->{'image'}->{'Image Created'};
64 print STDERR "No date for $f\n";
67 my ($ty, $tm, $td, $tH, $tM, $tS) = ($d =~ m{^(\d{4}):(\d{2}):(\d{2}) (\d{2}):(\d{2}):(\d{2})$}) or die "EXIF date parse error: $d\n";
68 my $t = 3600*$tH + 60*$tM + $tS;
69 $t = int($t + $offset);
71 $tM = int(($t % 3600) / 60);
77 $dest = sprintf("%s/%04d-%02d-%02d-%02d:%02d:%02d%s%s.jpg",
82 $retry ? sprintf("-%d", $retry) : "");
90 symlink $f, $dest or die "Cannot symlink $f to $dest: $!\n";
92 link $f, $dest or die "Cannot hardlink $f to $dest: $!\n";