Lines starting with "#" are ignored.
+Lines starting with a tab add further attributes to the previous photo.
+The following attributes are recognized:
+
+ lat geographic latitude in degrees north of equator
+ lon geographic longitude in degrees east of Greenwich
+ alt geographic altitude in meters
+ t time when the photo was taken (2014-01-25 09:40:12)
+
+
+Importing meta-data from other sources
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Occasionally, you want to add photos from a source which already provides
+some meta-data. In this case, you can construct a gallery.list with a subset
+of fields, or feed the stdin of "gal scan" with such a list.
+
+For convenience, orientation, transformation and title can be also given
+as named attributes. They are called "orientation", "xf", and "title".
+
Photo meta-data (PhotoDir/gallery.meta or CacheDir/cache.meta)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Simple Photo Gallery
-# (c) 2003--2014 Martin Mares <mj@ucw.cz>
+# (c) 2003--2015 Martin Mares <mj@ucw.cz>
package UCW::Gallery;
return keys %{$self->{cfg}};
}
+our %list_attrs = (
+ 'file' => 0, # 0 = not permitted as extended attribute
+ 'id' => 0,
+ 'orientation' => 1, # 1 = aliases for normal attributes
+ 'title' => 1,
+ 'xf' => 2, # 2 = ... and propagated to gal-gen
+ 'lat' => 3, # 3 = normal extended attributes, propagated to gal-gen
+ 'lon' => 3,
+ 'alt' => 3,
+ 't' => 3,
+);
+
sub write_list($$$) {
my ($self, $file, $images) = @_;
open my $fh, '>:utf8', "$file.new" or die "Cannot create $file.new: $!\n";
$i->{file},
$i->{id},
$i->{orientation},
- $i->{xfrm},
+ $i->{xf},
($i->{title} eq '' ? '-' : $i->{title}),
), "\n";
+ for my $k (keys %$i) {
+ print $fh "\t$k=", $i->{$k}, "\n" if $list_attrs{$k} >= 3;
+ }
}
close $fh;
rename "$file.new", $file or die "Cannot rename $file.new to $file: $!\n";
}
-sub read_list($$) {
- my ($self, $file) = @_;
+sub read_list_fh($$) {
+ my ($self, $fh) = @_;
my @images = ();
- open my $fh, '<:utf8', $file or return;
while (<$fh>) {
chomp;
/^$/ and next;
/^#/ and next;
- my $i = {};
- ($i->{file}, $i->{id}, $i->{orientation}, $i->{xfrm}, $i->{title}) = split /\t/;
- if ($i->{title} eq '-') { $i->{title} = ""; }
- push @images, $i;
+ if (/^\t/) {
+ @images or die "Misplaced continuation line before first image\n";
+ if (my ($k, $v) = /^\t+(.*?)=(.*)/) {
+ # Continutation of previous line
+ my $i = $images[-1];
+ if ($list_attrs{$k}) {
+ $i->{$k} = $v;
+ } else {
+ print STDERR "Ignoring unknown attribute $k for ", $i->{file}, "\n";
+ }
+ } else {
+ die "Invalid continuation line. Expecting 'key=value'.\n";
+ }
+ } else {
+ my $i = {};
+ ($i->{file}, $i->{id}, $i->{orientation}, $i->{xf}, $i->{title}) = split /\t/;
+ if (!defined $i->{title} || $i->{title} eq '-') { $i->{title} = ""; }
+ push @images, $i;
+ }
}
- close $fh;
return \@images;
}
+sub read_list($$) {
+ my ($self, $file) = @_;
+ open my $fh, '<:utf8', $file or return;
+ my $list = $self->read_list_fh($fh);
+ close $fh;
+ return $list;
+}
+
sub write_meta($$) {
my ($self, $file, $meta) = @_;
open my $fh, '>', "$file.new" or die "Cannot create $file.new: $!\n";
#!/usr/bin/perl
# UCW Gallery: Generate published photos
-# (c) 2004--2014 Martin Mares <mj@ucw.cz>
+# (c) 2004--2015 Martin Mares <mj@ucw.cz>
use strict;
use warnings;
$h = int($h + .5);
$m->{o} = $rotate;
- $m->{xf} = $f->{xfrm};
+ for my $k (keys %UCW::Gallery::list_attrs) {
+ next if $UCW::Gallery::list_attrs{$k} < 2;
+ $m->{$k} = $f->{$k} if defined $f->{$k};
+ }
$m->{w0} = $w0;
$m->{h0} = $h0;
$m->{w} = $w;
# printf "[GEO: lat=%s lon=%s alt=%s] ", $lat // '?', $lon // '?', $alt // '?';
if ($lat && $lon) {
- $m->{lat} = $lat;
- $m->{lon} = $lon;
+ $m->{lat} //= $lat;
+ $m->{lon} //= $lon;
}
- $m->{alt} = $alt if $alt;
+ $m->{alt} //= $alt if $alt;
my $time = $i->{image}->{'Image Created'};
if ($time) {
if ($time =~ m{^(\d{4}):(\d{2}):(\d{2}) (\d{2}:\d{2}:\d{2})$}) {
- $m->{t} = "$1-$2-$3 $4";
+ $m->{t} //= "$1-$2-$3 $4";
# print "[TIME: ", $m->{t}, "] ";
} else {
print "[EXIF: unable to parse time $time] ";
if (@ARGV && $ARGV[0] eq '--help') {
die <<AMEN ;
-Usage: cat list | gal scan
- or: gal scan <files and directories>
- or: gal scan --update
+Usage: cat list | gal scan <options>
+ or: gal scan <options> <files and directories>
+ or: gal scan <options> --update
+
+Options:
+--add Keep existing images and add new ones
AMEN
}
+my $add;
my $update;
GetOptions(
+ 'add!' => \$add,
'update!' => \$update,
) or die "Try gal scan --help\n";
}
}
} else {
- while (<STDIN>) {
- chomp;
- push @source, { file => $_ };
- }
+ binmode STDIN, ':utf8';
+ @source = @{$gal->read_list_fh(\*STDIN)};
}
my $hashes = UCW::Gallery::Hashes->new($gal);
}
print " ori=", $src->{orientation};
- defined $src->{xfrm} or $src->{xfrm} = $gal->get('ScanDefaultTransform');
- print " xfrm=", $src->{xfrm};
+ defined $src->{xf} or $src->{xf} = $gal->get('ScanDefaultTransform');
+ print " xfrm=", $src->{xf};
$src->{title} //= '';
push @images, $src;
my $id = $o->{id};
my $i = $new_by_id{$id};
if (!$i) {
- print "\t$id: removed\n";
- next;
+ if ($add) {
+ print "\t$id: kept\n";
+ push @result, $o;
+ } else {
+ print "\t$id: removed\n";
+ }
+ } else {
+ print "\t$id: kept\n";
+ push @result, $o;
+ delete $new_by_id{$id};
}
- print "\t$id: updated\n";
- push @result, $o;
- delete $new_by_id{$id};
}
for my $i (@images) {
my $id = $i->{id};