]> mj.ucw.cz Git - gallery.git/commitdiff
Extended attributes and import of meta-data
authorMartin Mares <mj@ucw.cz>
Sun, 8 Feb 2015 19:12:11 +0000 (20:12 +0100)
committerMartin Mares <mj@ucw.cz>
Sun, 8 Feb 2015 20:14:18 +0000 (21:14 +0100)
The format of gallery.list has been extended to allow multi-line
entries containing further attributes of photos. This can be used
to provide extra pieces of meta-data like geographical coordinates,
which are further propagated to cache files via gal-gen.

Also, gal-scan can be fed partial gallery.list entries on its stdin,
which makes it easier to import photos from external programs
including selected meta-data.

Finally, "gal-scan --add" can be used to add more photos to an existing
gallery.

gal/FORMAT
gal/UCW/Gallery.pm
gal/bin/gal-gen
gal/bin/gal-scan

index a7a4463e37e157a13fe496a48103c5cf3455a95a..059f2af5761989e2bb813969a33a9a199a538a6d 100644 (file)
@@ -13,6 +13,24 @@ One photo per line, tab-separated columns:
 
 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)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 1e7bba320a733b566b255dedf6a67f501e96b3e8..748fe3cddff99db81f2ef9f2241bdb991f77a041 100644 (file)
@@ -1,5 +1,5 @@
 # Simple Photo Gallery
-# (c) 2003--2014 Martin Mares <mj@ucw.cz>
+# (c) 2003--2015 Martin Mares <mj@ucw.cz>
 
 package UCW::Gallery;
 
@@ -101,6 +101,18 @@ sub get_config_keys($) {
        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";
@@ -109,31 +121,55 @@ sub write_list($$$) {
                        $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";
index dfd434f9ef8568e707eae76a83026c7115ce85ae..1ee10b04749fd47b09b7e4cd31a885edded68d18 100755 (executable)
@@ -1,6 +1,6 @@
 #!/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;
@@ -58,7 +58,10 @@ sub get_meta_basic($$$) {
        $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;
@@ -108,15 +111,15 @@ sub get_meta_exif($$) {
 
        # 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] ";
index 4424cc3732b78a987b610ab776876e8be9913f87..a976d5d9ce4e33b480359d968ab665bcd2c76627 100755 (executable)
@@ -13,14 +13,19 @@ use Getopt::Long;
 
 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";
 
@@ -54,10 +59,8 @@ if ($update) {
                }
        }
 } else {
-       while (<STDIN>) {
-               chomp;
-               push @source, { file => $_ };
-       }
+       binmode STDIN, ':utf8';
+       @source = @{$gal->read_list_fh(\*STDIN)};
 }
 
 my $hashes = UCW::Gallery::Hashes->new($gal);
@@ -102,8 +105,8 @@ foreach my $src (@source) {
        }
        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;
@@ -120,12 +123,17 @@ if (!$update) {
                        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};