2 # UCW Gallery: Symlink photos according to their EXIF timestamps
3 # (c) 2013 Martin Mares <mj@ucw.cz>
11 if (@ARGV && $ARGV[0] eq '--help') {
13 Usage: cat list | gal date [<options>]
14 or: gal date [<options>] <files>
17 -d, --destdir=<dir> Create symlinks in specified directory (default: current dir)
18 -n, --dry-run Perform a trial run with no changes made
19 -o, --offset=<offset> Adjust timestamps by a given offset (<h>[:<m>[:<s>]])
20 --suffix=<s> Add suffix to all names
21 -s, --symbolic Create symbolic links (default: hardlinks)
30 Getopt::Long::Configure('bundling');
32 'destdir|d=s' => \$destdir,
33 'dry-run|n!' => \$dry_run,
34 'offset|o=s' => \$offset,
35 'suffix=s' => \$suffix,
36 'symbolic|s!' => \$symbolic,
37 ) or die "Try gal date --help\n";
47 if ($offset =~ m{^([+-])?(\d)+(:(\d+)(:(\d+))?)?$}) {
48 $offset = $2 * 3600 + ($4 // 0) * 60 + ($6 // 0);
49 if ($1 eq '-') { $offset = -$offset; }
51 die "Invalid offset: $offset\n";
54 foreach my $f (@src) {
55 my $e = new Image::EXIF($f);
56 my $i = $e->get_all_info();
58 print STDERR "EXIF error on $f: ", $e->error, "\n";
61 # print STDERR Dumper($i), "\n";
63 my $d = $i->{'image'}->{'Image Created'};
65 print STDERR "No date for $f\n";
68 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";
69 my $t = 3600*$tH + 60*$tM + $tS;
70 $t = int($t + $offset);
72 $tM = int(($t % 3600) / 60);
78 $dest = sprintf("%s/%04d-%02d-%02d-%02d:%02d:%02d%s%s.jpg",
83 $retry ? sprintf("-%d", $retry) : "");
91 symlink $f, $dest or die "Cannot symlink $f to $dest: $!\n";
93 link $f, $dest or die "Cannot hardlink $f to $dest: $!\n";