+my $album = $ARGV[0] // die "Usage: gal mj-upgrade <album>\n";
+print "### $album ###\n";
+
+### Scan photos.map ###
+
+my $year = $album;
+$year =~ s{/.*}{};
+if ($album eq '2009/Fireworks') { $year = 2008; }
+print "Loading map for $year\n";
+open M, "$photos_root/photos.map" or die "No map file found\n";
+my %map = ();
+while (<M>) {
+ chomp;
+ m{^$year} or next;
+ my ($path, $hash) = split /\t/;
+ my $name = $path;
+ $name =~ s{.*/}{};
+ if (defined $map{$name}) {
+ my $prev = $map{$name};
+ if ($prev->{hash} ne $hash) {
+ print STDERR "Collision for $name: ", $prev->{path}, " vs. ", $path, "\n";
+ } else {
+ # print STDERR "Harmless collision for $name: ", $prev->{path}, " vs. ", $path, "\n";
+ }
+ } else {
+ $map{$name} = { path => $path, hash => $hash };
+ }
+}
+close M;
+
+### Scan static list (if any) ###
+
+my @src = ();
+if (open S, "../static/photos/$album/x") {
+ print "Found static list\n";
+ while (<S>) {
+ chomp;
+ my @fields = split /\t/;
+ if (@fields == 4) {
+ push @src, { name => $fields[0], rotate => $fields[2], xform => $fields[3] };
+ } elsif (@fields == 2) {
+ push @src, { name => $fields[0], rotate => $fields[1], xform => '.' };
+ } else {
+ die "Error parsing gallery list: $_\n";
+ }
+ }
+ close S;