]>
git.defcon.no Git - plsgen/blob - plsgen
10 # DONE: Removed some default values in config, allowing empty options
11 # TODO: Stripping of image suffix for HTML file w/config option?
12 # TODO: Templating of EXIF
13 # TODO: Priority/sorting of EXIF tags
14 # TODO: Possibility for hide/show EXIF
15 # TODO: Clear old generated files and meta on regen
16 # TODO: Use perlmagick et. al instead of convert/jhead..
17 # BUG: The naive handling of filenames breaks on special characters
24 my $configfile = undef;
26 my $album_comment = undef;
28 my $threadcounter = 0;
29 share
( $threadcounter );
33 "htmlonly!" => \
$htmlonly,
35 "config=s" => \
$configfile,
40 print "\nplsgen version " . $version . "\n";
41 print "Copyright Jon Langseth, BSD lisence\n\n";
42 print " --title='Your album title'\n";
43 print " Sets the album title. Title will be stored in .title\n";
44 print " If no title is given, it will be read from .title, if present\n";
45 print " --htmlonly\n";
46 print " Add this option to only generate HTML files\n";
47 print " No image operations will be performed with this option\n";
49 print " Forces EXIF data block not to be written to HTML output\n";
50 print " --config=/path/to/config\n";
51 print " Overrides default config file location.\n";
52 print " Default is to look for ./plsgen.cfg, then ../plsgen.cfg\n";
53 print " and finally /etc/plsgen.cfg.\n";
59 my $config = get_config
( $configfile );
60 my $full_tpl_file = $config->full_tpl_file;
61 my $index_tpl_file = $config->index_tpl_file;
62 my $css_file = $config->css_file;
63 my $navigation_script = $config->navigation_script;
64 my $up_arrow_navigate = $config->up_arrow_navigate;
65 my $disable_rescale = $config->disable_rescale;
66 my $columns = $config->columns;
67 my $rows = $config->rows;
68 my $thumb_pre = $config->thumb_pre;
69 my $thumb_post = $config->thumb_post;
70 my $thumb_maxwidth = $config->thumb_maxwidth;
71 my $thumb_maxheight = $config->thumb_maxheight;
72 my $view_maxwidth = $config->view_maxwidth;
73 my $view_maxheight = $config->view_maxheight;
74 my $comment_pre = $config->comment_pre;
75 my $comment_post = $config->comment_post;
76 my $idx_prev_text = $config->idx_prev_text;
77 my $idx_next_text = $config->idx_next_text;
78 my $idx_ret_text = $config->idx_ret_text;
79 my $footer_tag = $config->footer_tag;
80 my $concurrent = $config->concurrent_threads;
82 # Get or save the title, depending..
83 if ( (not $title) && ( -f
".title" ) )
93 print TF
$title . "\n";
97 # Get the album comment, if available
98 if ( -f
"comment.txt" )
100 open CF
, "<comment.txt";
101 while (<CF
>) { $album_comment .= $_; }
108 # Glob file names to an array
109 my @images = glob("*png *.jpg *.JPG *.gif *.GIF");
110 # Keep count of total number of images
111 my $imagecount = $#images+1;
113 my ($current, $previous, $next);
117 my $main_meta = "<link rel='stylesheet' href='" . $css_file . "' type='text/css' />";
118 my $navigation_header = "<script type='text/javascript' src='" . $navigation_script . "'></script>";
120 my $thumbs = "<div class='thumbnails'>";
122 my $indexes = ceil
( $imagecount/($rows*$columns) );
123 my $gentime = localtime;
125 # In groups of N ( X rows x Y colums of index):
126 # - Step through image array:
127 for ( my $i = 1; $i <= $imagecount; $i++)
129 $current = $images[$i-1];
130 # - - Previous image is previous location in array, unless cur=first
131 $previous = $images[$i-2] if $i > 1;
132 $previous = undef if $i == 1;
133 # - - Next image is next location in array, unless cur=last.
134 $next = $images[$i] if $i < ( $imagecount);
135 $next = undef if $i >= ( $imagecount);
137 #Set up text-strings for template replacement
138 if ( $indexcount == 1 ) { $indexfile = "index.html"; }
139 else { $indexfile = "index" . $indexcount . ".html"; }
140 my $navscript = gen_navscript
( $previous, $next, $indexfile );
141 my $position = $i . " of " . $imagecount;
142 my $prev_text = "<a href='" . $previous . ".html'><img src='thumb/" . $previous . "' alt='Previous image' /></a>";
143 my $next_text = "<a href='" . $next . ".html'><img src='thumb/" . $next . "' alt='Next image' /></a>";
144 my $cur_index_text = "<a href='". $indexfile ."'>" . $idx_ret_text . "</a>";
145 my $current_display = $current;
146 $current_display = "view/" . $current unless $disable_rescale;
148 # Check for, and load comment from FILENAME.txt here..
150 if ( -f
$current . ".txt" )
152 open CF
, "<" . $current . ".txt";
153 while (<CF
>) { $comment .= $_; }
158 $comment = $comment_pre . $comment . $comment_post;
161 printf ("Processing image %s: %s\n", $position, $current);
163 # - - If rotated according to EXIF, do rotation
164 my $exif = get_exifdata
( $current );
165 if ( $exif->{'Orientation'} =~ m/rotate/i )
167 system("jhead -autorot " . $current . ">/dev/null") unless $htmlonly;
169 my $exif_text = get_exifblock
($exif) if $doexif;
171 ## - - Create thumbnail and normal view images, support threading
175 my $thread = threads
->create (
177 $current, $thumb_maxwidth, $thumb_maxheight,
178 $view_maxwidth, $view_maxheight, $disable_rescale);
180 if ( $threadcounter >= $concurrent )
182 foreach my $thr ( threads
->list() ) { $thr->join(); }
185 # - - Save a reference to the "primary image"
186 if ( not -f
".indeximage" )
188 open IM
, ">.indeximage";
192 # - - Create full view HTML file
194 open TEMPLATE
, "<" . $full_tpl_file or die "UNABLE TO LOAD TEMPLATE $full_tpl_file\n";
197 if ( $previous ) { $_ =~ s/%\{previous\}/$prev_text/; }
198 else { $_ =~ s/%\{previous\}//; }
199 if ( $next ) { $_ =~ s/%\{next\}/$next_text/; }
200 else { $_ =~ s/%\{next\}//; }
201 $_ =~ s/%\{index\}/$cur_index_text/;
202 $_ =~ s/%\{title\}/$title/;
203 $_ =~ s/%\{main_meta\}/$main_meta/;
204 $_ =~ s/%\{navigation_script\}/$navigation_header/;
205 $_ =~ s/%\{position\}/$position/;
206 $_ =~ s/%\{current\}/$current/;
207 $_ =~ s/%\{current_display\}/$current_display/;
208 $_ =~ s/%\{comment\}/$comment/;
209 $_ =~ s/%\{exif\}/$exif_text/;
210 $_ =~ s/%\{gallery_timestamp\}/$gentime/;
211 $_ =~ s/%\{navscript\}/$navscript/;
212 $_ =~ s/%\{footer_tag\}/$footer_tag/;
216 open HTML
, ">" . $current . ".html" or die "UNABLE TO WRITE\n";
217 print HTML
$cur_html;
220 # - - Append image thumbnail code to current index content
221 $thumbs .= $thumb_pre . "<a href='" . $current . ".html'><img src='thumb/" . $current . "' alt='View " . $current . "' /></a>" . $thumb_post;
222 if ( $i % ($rows*$columns) == 0 )
225 # - - On each Y, terminate index file/group:
226 make_index
( $index_tpl_file, $indexcount, $indexes, $thumbs, $album_comment );
227 $thumbs = "<div class='thumbnails'>";
230 elsif ( $i % ($columns) == 0 )
232 # - - On each X, terminate index content row
233 $thumbs .= "\n</div>\n<div class='thumbnails'>";
237 make_index
( $index_tpl_file, $indexcount, $indexes, $thumbs, $album_comment );
239 printf ("Waiting for %d threads to finish\n", $threadcounter) if $threadcounter;
240 foreach my $thr ( threads
->list() ) { $thr->join(); }
244 # -------------- Functions supporting above code -----------------------
248 my $idxcount = shift;
253 my $gentime = localtime;
262 # If index counter is 1, filename is index.html
263 $indexfile = ( $indexcount ==1 ) ?
"index.html" : "index" . $idxcount . ".html";
265 # If index counter is > 1, add previous index link.
268 $prev_file = "index" . ($idxcount-1) . ".html";
269 $prev_file = "index.html" if ( $idxcount == 2 );
270 $prev_text = "<a href='$prev_file'>" . $idx_prev_text . "</a>";
273 # If current image is last in array, do not add nex-index link
274 if ( $idxcount < $lastidx )
276 $next_file = "index" . ($idxcount+1) . ".html";
277 $next_text = "<a href='" . $next_file . "'>" . $idx_next_text . "</a>";
282 $comment = $comment_pre . $comment . $comment_post;
285 my $position = $indexcount . " of " . $lastidx;
286 my $navscript = gen_navscript
( $prev_file, $next_file );
288 open TEMPLATE
, "<" . $tpl or die "UNABLE TO LOAD TEMPLATE\n";
291 $_ =~ s/%\{previous\}/$prev_text/;
292 $_ =~ s/%\{next\}/$next_text/;
293 $_ =~ s/%\{title\}/$title/;
294 $_ =~ s/%\{comment\}/$comment/;
295 $_ =~ s/%\{position\}/$position/;
296 $_ =~ s/%\{main_meta\}/$main_meta/;
297 $_ =~ s/%\{navigation_script\}/$navigation_header/;
298 $_ =~ s/%\{thumbnails\}/$thumbs/;
299 $_ =~ s/%\{gallery_timestamp\}/$gentime/;
300 $_ =~ s/%\{navscript\}/$navscript/;
301 $_ =~ s/%\{footer_tag\}/$footer_tag/;
305 open HTML
, ">" . $indexfile or die "UNABLE TO WRITE\n";
314 my $exifTool = new Image
::ExifTool
;
315 $exifTool->Options(Unknown
=> 1);
318 my $info = $exifTool->ImageInfo($image);
319 $exif->{'Make'} = $info->{'Make'};
320 $exif->{'Model'} = $info->{'Model'};
321 $exif->{'Orientation'} = $info->{'Orientation'};
322 $exif->{'ExposureTime'} = $info->{'ExposureTime'};
323 $exif->{'FNumber'} = $info->{'FNumber'};
324 $exif->{'ISO'} = $info->{'ISO'};
325 $exif->{'CreateDate'} = $info->{'CreateDate'};
326 $exif->{'ExposureCompensation'} = $info->{'ExposureCompensation'};
327 $exif->{'Flash'} = $info->{'Flash'};
328 $exif->{'FocalLength'} = $info->{'FocalLength'};
329 $exif->{'ExposureMode'} = $info->{'ExposureMode'};
330 $exif->{'Macro'} = $info->{'Macro'};
331 $exif->{'LensType'} = $info->{'LensType'};
338 my $exifTool = new Image
::ExifTool
;
339 my $block = "<table id='exifdata' cellspacing='0'>\n";
340 $block .= "<tr class='exifhead'><td>EXIF Parameter</td><td>Value</td></tr>\n";
343 foreach my $tag ( keys %$exif )
345 next if $tag =~ m/Orientation/;
346 my $val = $exif->{$tag};
348 $block .= "<tr class='exiflight'>" if $flipflop;
349 $block .= "<tr class='exifdark'>" if not $flipflop;
351 $block .= $exifTool->GetDescription($tag);
357 $flipflop = not $flipflop;
360 $block .= "</table>";
361 $block = undef if not $tagcount;
374 my $scriptbuffer = "<script type='text/javascript'>\n";
375 $scriptbuffer .= "\tnav_reg_prev('" . $prev . "');\n" if $prev;
376 $scriptbuffer .= "\tnav_reg_next('" . $next . "');\n" if $next;
377 if ( $up_arrow_navigate == 1 )
379 $scriptbuffer .= "\tnav_reg_index('" . $index . "');\n" if $index;
381 $scriptbuffer .= "\tnav_reg_onkeypress();\n";
382 $scriptbuffer .= "</script>\n";
383 return $scriptbuffer;
389 my $thumb_maxwidth = shift;
390 my $thumb_maxheight = shift;
391 my $view_maxwidth = shift;
392 my $view_maxheight = shift;
393 my $disable_rescale = shift;
395 my $tgeom = $thumb_maxwidth . "x" . $thumb_maxheight;
396 my $vgeom = $view_maxwidth . "x" . $view_maxheight;
397 # - - Create thumbnail image (resize to new image)
398 system("convert " . $current . " -geometry '" . $tgeom . ">' thumb/" . $current);
399 # - - Create normal display image (resize to new image)
400 system("convert " . $current . " -geometry '" . $vgeom . ">' view/" . $current) unless $disable_rescale;
407 # My standard way of implementing AppConfig use ...
408 my $filename = shift;
411 my @files = ( "./plsgen.cfg", "../plsgen.cfg", "/etc/plsgen.cfg" );
412 foreach my $file ( @files ) {
414 last if ( -f
$filename );
418 my $cfg = AppConfig
->new(
421 ERROR
=> \
&cfg_error
,
423 DEFAULT
=> "<undef>",
424 ARGCOUNT
=> AppConfig
::ARGCOUNT_ONE
429 $cfg->define('full_tpl_file');
430 $cfg->full_tpl_file("/usr/local/share/plsgen/full.tpl");
431 $cfg->define('index_tpl_file');
432 $cfg->index_tpl_file("/usr/local/share/plsgen/index.tpl");
434 $cfg->define('css_file');
435 $cfg->css_file("../style.css");
436 $cfg->define('navigation_script');
437 $cfg->navigation_script("../nav.js");
439 $cfg->define('up_arrow_navigate');
440 $cfg->up_arrow_navigate(1);
442 $cfg->define('columns');
444 $cfg->define('rows');
447 $cfg->define('concurrent_threads');
448 $cfg->concurrent_threads(1);
450 $cfg->define('thumb_maxwidth');
451 $cfg->thumb_maxwidth(160);
452 $cfg->define('thumb_maxheight');
453 $cfg->thumb_maxheight(120);
454 $cfg->define('view_maxwidth');
455 $cfg->view_maxwidth(800);
456 $cfg->define('view_maxheight');
457 $cfg->view_maxwidth(600);
458 $cfg->define('disable_rescale');
459 $cfg->disable_rescale(0);
461 $cfg->define('thumb_pre');
462 $cfg->define('thumb_post');
464 $cfg->define('comment_pre');
465 $cfg->define('comment_post');
467 $cfg->define('idx_prev_text');
468 $cfg->define('idx_next_text');
469 $cfg->define('idx_ret_text');
471 $cfg->define('footer_tag');
472 $cfg->footer_tag('plsgen : Perl Simple Gallery Generator ' . $version);
474 $cfg->file($filename) if -f
$filename;
479 die "Error occured in config-handling: $_\n";