2 # (c) 2003--2015 Martin Mares <mj@ucw.cz>
18 OrigDir => '.', # Original images
19 PhotoDir => 'photo', # Scaled-down photos for web
20 CacheDir => 'cache', # Cache with meta-data and thumbnails
23 PhotoUrlPrefix => 'photo/',
24 ThumbUrlPrefix => 'thumb/',
25 ThemeUrlPrefix => 'gal/',
27 # Processing machinery settings
28 ScanDefaultTransform => 's',
29 PhotoMaxWidth => 1024,
30 PhotoMaxHeight => 1024,
31 ThumbFormats => [ "114x94" ], # Built-in themes use the first size,
32 # but more can be generated
33 CacheExif => 0, # Cache selected EXIF meta-data
34 CacheHashes => 1, # Let gal-scan cache file hashes
36 # Titles and navigation (may contain HTML tags and entities)
37 Title => 'An Unnamed Gallery',
46 return bless $self, $class;
50 my $cfg = "./gallery.cf";
52 unless (defined $self) {
54 die "Error parsing $cfg: $@";
56 die "Cannot load $cfg: $!\n";
58 die "Cannot load $cfg, check that it returns true\n";
64 ### Object methods ###
67 my ($self, $key) = @_;
68 if (exists $self->{cfg}->{$key}) {
69 my $val = $self->{cfg}->{$key};
70 defined $val or warn "Gallery: Config item $key is not set\n";
73 warn "Gallery: Config item $key does not exist\n";
79 my ($self, $key) = @_;
80 return $self->{cfg}->{$key};
85 while (my $key = shift @_) {
87 $self->{cfg}->{$key} //= $val;
93 while (my $key = shift @_) {
94 $self->{cfg}->{$key} = shift @_;
98 sub get_config_keys($) {
100 return keys %{$self->{cfg}};
104 'file' => 0, # 0 = not permitted as extended attribute
106 'orientation' => 1, # 1 = aliases for normal attributes
108 'xf' => 2, # 2 = ... and propagated to gal-gen
109 'lat' => 3, # 3 = normal extended attributes, propagated to gal-gen
115 sub write_list($$$) {
116 my ($self, $file, $images) = @_;
117 open my $fh, '>:utf8', "$file.new" or die "Cannot create $file.new: $!\n";
118 for my $i (@$images) {
124 ($i->{title} eq '' ? '-' : $i->{title}),
126 for my $k (keys %$i) {
127 print $fh "\t$k=", $i->{$k}, "\n" if $list_attrs{$k} >= 3;
131 rename "$file.new", $file or die "Cannot rename $file.new to $file: $!\n";
134 sub read_list_fh($$) {
135 my ($self, $fh) = @_;
142 @images or die "Misplaced continuation line before first image\n";
143 if (my ($k, $v) = /^\t+(.*?)=(.*)/) {
144 # Continutation of previous line
146 if ($list_attrs{$k}) {
149 print STDERR "Ignoring unknown attribute $k for ", $i->{file}, "\n";
152 die "Invalid continuation line. Expecting 'key=value'.\n";
156 ($i->{file}, $i->{id}, $i->{orientation}, $i->{xf}, $i->{title}) = split /\t/;
157 if (!defined $i->{title} || $i->{title} eq '-') { $i->{title} = ""; }
165 my ($self, $file) = @_;
166 open my $fh, '<:utf8', $file or return;
167 my $list = $self->read_list_fh($fh);
173 my ($self, $file, $meta) = @_;
174 open my $fh, '>', "$file.new" or die "Cannot create $file.new: $!\n";
175 Storable::nstore_fd($meta, $fh);
177 rename "$file.new", $file or die "Cannot rename $file.new to $file: $!\n";
181 my ($self, $file) = @_;
182 open my $fh, '<', $file or die "Cannot read $file: $!\n";
183 my $meta = Storable::fd_retrieve($fh) or die "Cannot parse $file\n";
188 sub photo_meta_name($) {
190 return File::Spec->catfile($self->get('PhotoDir'), 'gallery.meta');
193 sub cache_meta_name($) {
195 return File::Spec->catfile($self->get('CacheDir'), 'cache.meta');
198 sub thumb_fmt_to_size($$) {
199 my ($self, $fmt) = @_;
200 my ($tw, $th) = ($fmt =~ m{^(\d+)x(\d+)$}) or die "Cannot parse thumbnail format $fmt\n";
204 sub photo_file_name($$$) {
205 my ($self, $photo_meta, $id) = @_;
206 return $id . '.' . ($photo_meta->{fmt} // 'jpg');
209 sub photo_name($$$) {
210 my ($self, $photo_meta, $id) = @_;
211 return File::Spec->catfile($self->get('PhotoDir'), $self->photo_file_name($photo_meta, $id));