]> mj.ucw.cz Git - gallery.git/blob - bin/gal-scan
gal-mj-digikam: Use image title
[gallery.git] / bin / gal-scan
1 #!/usr/bin/perl
2 # UCW Gallery: Scan images and generate image list
3 # (c) 2004--2015 Martin Mares <mj@ucw.cz>
4
5 use common::sense;
6
7 use UCW::Gallery;
8 use UCW::Gallery::Hashes;
9 use Encode;
10 use File::Spec;
11 use Image::EXIF;
12 use Getopt::Long;
13
14 if (@ARGV && $ARGV[0] eq '--help') {
15         die <<AMEN ;
16 Usage:  cat list | gal scan <options>
17    or:  gal scan <options> <files and directories>
18    or:  gal scan <options> --update
19
20 Options:
21 --add           Keep existing images and add new ones
22 AMEN
23 }
24
25 my $add;
26 my $update;
27 GetOptions(
28         'add!' => \$add,
29         'update!' => \$update,
30 ) or die "Try gal scan --help\n";
31
32 STDOUT->autoflush(1);
33 my $gal = UCW::Gallery->load_config;
34 my $orig_prefix = $gal->get('OrigDir');
35 $orig_prefix =~ m{/$} or $orig_prefix .= '/';
36
37 my @source = ();
38 if ($update) {
39         print "Loading previous gallery.list\n";
40         my $pg = $gal->read_list('gallery.list') or die "Unable to load gallery.list\n";
41         @source = @{$pg};
42 } elsif (@ARGV) {
43         for my $in (@ARGV) {
44                 if (-f $in) {
45                         push @source, { file => $in };
46                 } elsif (-d $in) {
47                         opendir D, $in or die "Cannot scan directory $in: $!\n";
48                         my @p = ();
49                         while (my $e = readdir D) {
50                                 $e = Encode::decode('utf-8', $e);
51                                 my $f = File::Spec->canonpath(File::Spec->catfile($in, $e));
52                                 if ($f =~ m{\.(jpe?g|png)$}i) {
53                                         push @p, $f;
54                                 }
55                         }
56                         closedir D;
57                         push @source, map { { file => $_ } } sort @p;
58                 } else {
59                         die "$in is neither file nor directory\n";
60                 }
61         }
62 } else {
63         binmode STDIN, ':utf8';
64         @source = @{$gal->read_list_fh(\*STDIN)};
65 }
66
67 my $hashes = UCW::Gallery::Hashes->new($gal);
68
69 print "Scanning photos\n";
70 my @images = ();
71 foreach my $src (@source) {
72         my $name = $src->{file};
73         if ($name =~ m{^/}) {
74                 # Try to relativize to OrigDir
75                 if (substr($name, 0, length $orig_prefix) eq $orig_prefix) {
76                         $src->{file} = $name = substr($name, length $orig_prefix);
77                 }
78         }
79         print "\t$name:";
80
81         my $path = File::Spec->rel2abs($name, $gal->get('OrigDir'));
82         -f $path or die "Cannot find $path\n";
83
84         $src->{id} = $hashes->hash_image($path);
85         print " id=", $src->{id};
86
87         if (!defined $src->{orientation} || $src->{orientation} eq '-') {
88                 my $e = new Image::EXIF($path);
89                 my $i = $e->get_all_info();
90                 if ($e->error) {
91                         print "EXIF error: ", $e->error, "\n";
92                         $src->{orientation} = '.';
93                 } else {
94                         # print STDERR Dumper($i), "\n";
95                         my $o = $i->{'image'}->{'Image Orientation'} || "Top, Left-Hand";
96                         if ($o eq "Top, Left-Hand") { $o = "."; }
97                         elsif ($o eq "Right-Hand, Top") { $o = "r"; }
98                         elsif ($o eq "Left-Hand, Bottom") { $o = "l"; }
99                         elsif ($o eq "Bottom, Right-Hand") { $o = "u"; }
100                         else {
101                                 print "Unrecognized orientation: $o\n";
102                                 $o = ".";
103                         }
104                         $src->{orientation} = $o;
105                 }
106         }
107         print " ori=", $src->{orientation};
108
109         if (!defined $src->{xf} || $src->{xf} eq '-') {
110                 $src->{xf} = $gal->get('ScanDefaultTransform');
111         }
112         print " xfrm=", $src->{xf};
113
114         $src->{title} //= '';
115         push @images, $src;
116         print "\n";
117 }
118
119 if (!$update) {
120         my $old = $gal->read_list('gallery.list');
121         if ($old) {
122                 print "Updating gallery.list\n";
123                 my %new_by_id = map { $_->{id} => $_ } @images;
124                 my @result = ();
125                 for my $o (@$old) {
126                         my $id = $o->{id};
127                         my $i = $new_by_id{$id};
128                         if (!$i) {
129                                 if ($add) {
130                                         print "\t$id: kept\n";
131                                         push @result, $o;
132                                 } else {
133                                         print "\t$id: removed\n";
134                                 }
135                         } else {
136                                 print "\t$id: kept\n";
137                                 push @result, $o;
138                                 delete $new_by_id{$id};
139                         }
140                 }
141                 for my $i (@images) {
142                         my $id = $i->{id};
143                         $new_by_id{$id} or next;
144                         print "\t$id: new\n";
145                         push @result, $i;
146                 }
147                 @images = @result;
148         }
149 }
150
151 $gal->write_list('gallery.list', \@images);
152 print "Written gallery.list (", (scalar @images), " items)\n";
153 $hashes->write;