]> mj.ucw.cz Git - gallery.git/blob - gal/UCW/Gallery.pm
Added caching of image hashes (optional)
[gallery.git] / gal / UCW / Gallery.pm
1 # Simple Photo Gallery
2 # (c) 2003--2014 Martin Mares <mj@ucw.cz>
3
4 package UCW::Gallery;
5
6 use strict;
7 use warnings;
8
9 use File::Spec;
10 use Storable;
11
12 ### Class methods ###
13
14 sub new($) {
15         my ($class) = @_;
16         my $self = { };
17         $self->{cfg} = {
18                 # Directories
19                 OrigDir => '.',                 # Original images
20                 PhotoDir => 'photo',            # Scaled-down photos for web
21                 CacheDir => 'cache',            # Cache with meta-data and thumbnails
22
23                 # URL prefixes
24                 PhotoUrlPrefix => 'photo/',
25                 ThumbUrlPrefix => 'thumb/',
26                 ThemeUrlPrefix => 'gal/',
27
28                 # Processing machinery settings
29                 ScanDefaultTransform => 's',
30                 PhotoMaxWidth => 1024,
31                 PhotoMaxHeight => 1024,
32                 ThumbFormats => [ "114x94" ],   # Built-in themes use the first size,
33                                                 # but more can be generated
34                 CacheExif => 0,                 # Cache selected EXIF meta-data
35                 CacheHashes => 1,               # Let gal-scan cache file hashes
36
37                 # Titles and navigation
38                 Title => 'An Unnamed Gallery',
39                 SubTitle => "",
40                 ParentURL => '../',
41                 BackURL => "",
42                 FwdURL => "",
43
44                 # Hacks
45                 GeoHack => 0,
46         };
47         return bless $self, $class;
48 }
49
50 sub load_config($) {
51         my $cfg = "./gallery.cf";
52         my $self = do $cfg;
53         unless (defined $self) {
54                 if ($@) {
55                         die "Error parsing $cfg: $@";
56                 } elsif ($!) {
57                         die "Cannot load $cfg: $!\n";
58                 } else {
59                         die "Cannot load $cfg, check that it returns true\n";
60                 }
61         }
62         return $self;
63 }
64
65 ### Object methods ###
66
67 sub get($$) {
68         my ($self, $key) = @_;
69         if (exists $self->{cfg}->{$key}) {
70                 my $val = $self->{cfg}->{$key};
71                 defined $val or warn "Gallery: Config item $key is not set\n";
72                 return $val;
73         } else {
74                 warn "Gallery: Config item $key does not exist\n";
75                 return;
76         }
77 }
78
79 sub try_get($$) {
80         my ($self, $key) = @_;
81         return $self->{cfg}->{$key};
82 }
83
84 sub def($@) {
85         my $self = shift;
86         while (my $key = shift @_) {
87                 my $val = shift @_;
88                 $self->{cfg}->{$key} //= $val;
89         }
90 }
91
92 sub set($@) {
93         my $self = shift;
94         while (my $key = shift @_) {
95                 $self->{cfg}->{$key} = shift @_;
96         }
97 }
98
99 sub get_config_keys($) {
100         my ($self) = @_;
101         return keys %{$self->{cfg}};
102 }
103
104 sub write_list($$$) {
105         my ($self, $file, $images) = @_;
106         open my $fh, '>:utf8', "$file.new" or die "Cannot create $file.new: $!\n";
107         for my $i (@$images) {
108                 print $fh join("\t",
109                         $i->{file},
110                         $i->{id},
111                         $i->{orientation},
112                         $i->{xfrm},
113                         ($i->{title} eq '' ? '-' : $i->{title}),
114                 ), "\n";
115         }
116         close $fh;
117         rename "$file.new", $file or die "Cannot rename $file.new to $file: $!\n";
118 }
119
120 sub read_list($$) {
121         my ($self, $file) = @_;
122         my @images = ();
123         open my $fh, '<:utf8', $file or return;
124         while (<$fh>) {
125                 chomp;
126                 /^$/ and next;
127                 /^#/ and next;
128                 my $i = {};
129                 ($i->{file}, $i->{id}, $i->{orientation}, $i->{xfrm}, $i->{title}) = split /\t/;
130                 if ($i->{title} eq '-') { $i->{title} = ""; }
131                 push @images, $i;
132         }
133         close $fh;
134         return \@images;
135 }
136
137 sub write_meta($$) {
138         my ($self, $file, $meta) = @_;
139         open my $fh, '>', "$file.new" or die "Cannot create $file.new: $!\n";
140         Storable::nstore_fd($meta, $fh);
141         close $fh;
142         rename "$file.new", $file or die "Cannot rename $file.new to $file: $!\n";
143 }
144
145 sub read_meta($) {
146         my ($self, $file) = @_;
147         open my $fh, '<', $file or die "Cannot read $file: $!\n";
148         my $meta = Storable::fd_retrieve($fh) or die "Cannot parse $file\n";
149         close $fh;
150         return $meta;
151 }
152
153 sub photo_meta_name($) {
154         my ($self) = @_;
155         return File::Spec->catfile($self->get('PhotoDir'), 'gallery.meta');
156 }
157
158 sub cache_meta_name($) {
159         my ($self) = @_;
160         return File::Spec->catfile($self->get('CacheDir'), 'cache.meta');
161 }
162
163 sub thumb_fmt_to_size($$) {
164         my ($self, $fmt) = @_;
165         my ($tw, $th) = ($fmt =~ m{^(\d+)x(\d+)$}) or die "Cannot parse thumbnail format $fmt\n";
166         return ($tw, $th);
167 }
168
169 sub photo_file_name($$$) {
170         my ($self, $photo_meta, $id) = @_;
171         return $id . '.' . ($photo_meta->{fmt} // 'jpg');
172 }
173
174 sub photo_name($$$) {
175         my ($self, $photo_meta, $id) = @_;
176         return File::Spec->catfile($self->get('PhotoDir'), $self->photo_file_name($photo_meta, $id));
177 }
178
179
180 1;