so no requirements at all exist in regard to type
and functionality of HTTP daemon.
+
Installation
-------------------------
The shipped config lists all configuration options,
along with their default values (used if no config present).
+
Execution / Use
-------------------------
--htmlonly
Add this option to only generate HTML files
No image operations will be performed with this option
+ --noexif
+ Forces EXIF data block not to be written to HTML output
--config=/path/to/config
Overrides default config file location.
Default is to look for ./plsgen.cfg, then ../plsgen.cfg
--help
Displays a list of available commandline options
+
+File overrides: comments, title, index image.
+------------------------------------------------------
+plsgen supports static gallery- and image comments. To get descriptive
+text or author comments on a gallery, add a file with the name 'comment.txt'
+to the directory before generating the album. The file is read, and injected
+verbatim, into all index* files generated, pre- and post-padded with the
+content of the comment-{pre,post} configuration variables.
+
+To add an image comment, create a text file named identically to the image
+filename, plus the suffix .txt. So, if an image is named 'AnImage.JPG', the
+corresponding comment file should be named 'AnImage.JPG.txt'
+
+If you wish to pre-seed the gallery title, you may do so by putting the
+gallery title on a single line in a file named '.title'. The title is read
+from this file if no title is given on the command line, and it is present.
+Note that if a title is given on the command line, that title will be used,
+and also will overwrite any content in the .title file.
+
+A reference to an "index image", simply the first image in the set,
+is saved in the file '.indeximage', if this file does not previously exist.
+To override the chosen index image, simply put the filename you would
+rather have used in this file. The index image is used bu the included
+example index.php and rss.php
+
+
+Index front-end and RSS support
+-------------------------
+Included is a sample front-end index, and an accompanying RSS
+generator written using PHP. To use these, take a look at the PHP
+source, make personal adaptation (at least change references to my site
+to your own), and place both php files, plus indexstyle.css in a
+directory where you keep your albums as sub-directories.
+
+E.g.:
+ Web Root
+ |-- galleryset1
+ | |-- image1.jpg
+ | |-- image1.jpg.txt
+ | |-- image2.jpg
+ | |-- comment.txt
+ | `- .title
+ |-- galleryset2
+ . ...
+ |-- nav.js
+ |-- style.css
+ |-- index.php
+ |-- indexstyle.css
+ `- rss.php
+
+
Todo-list
-------------------------
-# TODO: filename.txt for file comments
# TODO: Templating of EXIF
# TODO: Priority/sorting of EXIF tags
# TODO: Possibility for hide/show EXIF
-# TODO: RSS support? Delegate that to frontend?
-# TODO: Save reference to main-index thumbnail.
# TODO: Clear old generated files and meta on regen
# TODO: Use perlmagick et. al instead of convert/jhead..
</a>
</div>
+%{comment}
+
<div id="exifinfo">
%{exif}
</div>
+<div id="copyright">
+Copyright EDIT_FULL_TPL, all rights reserved.<br/>
+
<div id="timestamp">
Generated %{gallery_timestamp}
+</div>
+
</div>
<div id="footer">%{footer_tag}</div>
--- /dev/null
+<html>
+<head><title>plsgen-generated photoalbum.</title>
+
+<link rel='stylesheet' href='indexstyle.css' type='text/css' />
+
+</head>
+<body>
+<div id="wrapper">
+<div id="head">
+<h1>Photo albums!</h1>
+<a style="display: block; float: right;" href="rss.php"><img src="images/rss_icon.png" alt="RSS" border="0" /></a>
+<div id="head-link"><a href="http://example.com">Update index.php!</a>
+</div>
+</div>
+<div id="content">
+
+<?php
+
+//define the path as relative
+$path = "./";
+
+//using the opendir function
+$dir_handle = @opendir($path) or die("Unable to open $path");
+
+//running the while loop
+while ($file = readdir($dir_handle)) {
+ $target = $path . $file;
+ if (($file != "images") && ($file != "generate") && ($file != ".") && ($file != "..")) {
+ if(file_exists($target)) {
+ if (!is_file($target)) {
+ if (is_file($target . "/.title")) {
+ $fd = fopen($target . "/.title", "r");
+ $buf = "";
+ $buf = fgets($fd, 4096);
+ fclose($fd);
+ $album[$file] = "<span class='strong'>" . $buf . "</span>";
+ }
+
+ if (is_file($target . "/.indeximage")) {
+ $fd = fopen($target . "/.indeximage", "r");
+ $buf = $file . "/thumb/";
+ $buf .= fgets($fd, 4096);
+ chop ($buf);
+ fclose($fd);
+ $idximage[$file] = "<img src='" . $buf . "' alt='Thumb' />";
+ }
+
+ } else {
+
+ }
+ }
+ }
+}
+//closing the directory
+closedir($dir_handle);
+
+krsort($album);
+
+foreach ( $album as $key => $value ) {
+ echo "<div class='album'>";
+ echo "<div class='idxthumb'>";
+ echo "<a target=_blank href='" . $key . "'>";
+ echo $idximage[$key];
+ echo "</a>";
+ echo "</div>";
+ echo "<div class='idxlink'>";
+ echo "<a target=_blank href='" . $key . "'>" . $key . "</a>\n";
+ echo "</div>";
+ echo "<div class='title'>$value</div>";
+ echo "</div>";
+}
+?>
+</div>
+</div>
+<div style="font-family: sans; font-size: 7pt; color: #444; margin-top: 20px;">
+Photo gallery index by Jon Langseth, generated using <a href="index.phps">index.php</a>
+</div>
+</body>
+</html>
%{thumbnails}
+%{comment}
+
Album generated %{gallery_timestamp}
<div id="footer">%{footer_tag}</div>
--- /dev/null
+body {
+ font-family : Arial, Verdana, Geneva, Helvetica, sans-serif;
+ font-size: 12px;
+ background-color: black;
+ text-align: center
+}
+#wrapper {
+ margin-left: auto;
+ margin-right: auto;
+ width: 950px;
+}
+#head {
+ width: 925px;
+ background-color: #444;
+ border: 2px solid #2c2c29;
+ padding: 10px;
+ text-align: center;
+ color: wheat;
+}
+#head h1 {
+ font-size: 18px;
+ font-weight: bold;
+ margin: 0px;
+}
+#head-link {
+ font-size: 10px;
+ font-weight: italic;
+ margin-top: 10px;
+}
+a, a:visited {
+ color: white;
+}
+
+#content {
+ margin-top: 10px;
+ width: 100%;
+ background-color: black;
+ color: white;
+ clear: both;
+ display: block;
+ text-align: center;
+}
+.title {
+ font-size: 11pt;
+ margin-top: 5px;
+ font-weight: bold;
+}
+.album {
+ width: 220px;
+ height: 225px;
+ margin: 5px;
+ padding: 0px;
+ display: -moz-inline-stack;
+ display: inline-block;
+ /* zoom: 1;*/
+ *display: inline;
+ _height: 225px;
+
+ vertical-align: top;
+ text-align: center;
+}
+.title {}
+.idxthumb {
+ width: 170px;
+ height: 135px;
+ margin: 5px;
+ padding: 0px;
+ display: -moz-inline-stack;
+ display: inline-block;
+ /* zoom: 1;*/
+ *display: inline;
+ _height: 135px;
+
+ background-color: #2c2c29;
+ vertical-align: top;
+ text-align: center;
+
+}
+.idxthumb img
+{
+ background-color: #2c2c29;
+ margin: 0px;
+ margin-top: 5px;
+ padding: 0px;
+}
+.idxthumb a img
+{
+ border:1px solid #2c2c29;
+}
+.idxthumb a:hover img
+{
+ border:1px solid #black;
+}
+
+
+.idxlink {}
+
use Getopt::Long;
use strict;
-# TODO: filename.txt for file comments
# TODO: Templating of EXIF
-# TODO: Priority/sorting of EXFI tags
+# TODO: Priority/sorting of EXIF tags
# TODO: Possibility for hide/show EXIF
# TODO: RSS support? Delegate that to frontend?
-# TODO: Save reference to main-index thumbnail.
# TODO: Clear old generated files and meta on regen
# TODO: Use perlmagick et. al instead of convert/jhead..
my $htmlonly = 0;
my $configfile = undef;
my $halp = undef;
+my $album_comment = undef;
+my $doexif = 1;
GetOptions (
"title=s" => \$title,
"htmlonly!" => \$htmlonly,
+ "exif!" => \$doexif,
"config=s" => \$configfile,
"help" => \$halp
);
print " --htmlonly\n";
print " Add this option to only generate HTML files\n";
print " No image operations will be performed with this option\n";
+ print " --noexif\n";
+ print " Forces EXIF data block not to be written to HTML output\n";
print " --config=/path/to/config\n";
print " Overrides default config file location.\n";
print " Default is to look for ./plsgen.cfg, then ../plsgen.cfg\n";
my $rows = $config->rows;
my $thumb_pre = $config->thumb_pre;
my $thumb_post = $config->thumb_post;
+my $comment_pre = $config->comment_pre;
+my $comment_post = $config->comment_post;
my $idx_prev_text = $config->idx_prev_text;
my $idx_next_text = $config->idx_next_text;
my $idx_ret_text = $config->idx_ret_text;
close TF;
}
+# Get the album comment, if available
+if ( -f "comment.txt" )
+{
+ open CF, "<comment.txt";
+ while (<CF>) { $album_comment .= $_; }
+ close CF;
+}
+
mkdir "thumb";
mkdir "view";
# Glob file names to an array
my @images = glob("*png *.jpg *.JPG *.gif *.GIF");
# Keep count of total number of images
-my $imagecount = $#images;
+my $imagecount = $#images+1;
my ($current, $previous, $next);
my $indexcount = 1;
my $cur_index_text = "<a href='". $indexfile ."'>" . $idx_ret_text . "</a>";
my $current_display = "view/" . $current;
+ # Check for, and load comment from FILENAME.txt here..
+ my $comment = undef;
+ if ( -f $current . ".txt" )
+ {
+ open CF, "<" . $current . ".txt";
+ while (<CF>) { $comment .= $_; }
+ close CF;
+ }
+ if ( $comment )
+ {
+ $comment = $comment_pre . $comment . $comment_post;
+ }
+
printf ("Processing image %s: %s\n", $position, $current);
# - - If rotated according to EXIF, do rotation
{
system("jhead -autorot " . $current . ">/dev/null") unless $htmlonly;
}
- my $exif_text = get_exifblock($exif);
+ my $exif_text = get_exifblock($exif) if $doexif;
# - - Create thumbnail image (resize to new image)
system("convert " . $current . " -geometry '160x120>' thumb/" . $current) unless $htmlonly;
# - - Create normal display image (resize to new image)
system("convert " . $current . " -geometry '800x600>' view/" . $current) unless $htmlonly;
+# - - Save a reference to the "primary image"
+ if ( not -f ".indeximage" )
+ {
+ open IM, ">.indeximage";
+ print IM $current;
+ close IM;
+ }
# - - Create full view HTML file
my $cur_html;
open TEMPLATE, "<" . $full_tpl_file or die "UNABLE TO LOAD TEMPLATE $full_tpl_file\n";
$_ =~ s/%\{position\}/$position/;
$_ =~ s/%\{current\}/$current/;
$_ =~ s/%\{current_display\}/$current_display/;
+ $_ =~ s/%\{comment\}/$comment/;
$_ =~ s/%\{exif\}/$exif_text/;
$_ =~ s/%\{gallery_timestamp\}/$gentime/;
$_ =~ s/%\{navscript\}/$navscript/;
{
$thumbs .= "</div>";
# - - On each Y, terminate index file/group:
- make_index( $index_tpl_file, $indexcount, $indexes, $thumbs);
+ make_index( $index_tpl_file, $indexcount, $indexes, $thumbs, $album_comment );
$thumbs = "<div class='thumbnails'>";
$indexcount++;
}
}
}
$thumbs .= "</div>";
-make_index( $index_tpl_file, $indexcount, $indexes, $thumbs);
+make_index( $index_tpl_file, $indexcount, $indexes, $thumbs, $album_comment );
# Done.
my $idxcount = shift;
my $lastidx = shift;
my $thumbs = shift;
+ my $comment = shift;
my $gentime = localtime;
my $html;
$next_text = "<a href='" . $next_file . "'>" . $idx_next_text . "</a>";
}
+ if ( $comment )
+ {
+ $comment = $comment_pre . $comment . $comment_post;
+ }
+
my $position = $indexcount . " of " . $lastidx;
my $navscript = gen_navscript( $prev_file, $next_file );
$_ =~ s/%\{previous\}/$prev_text/;
$_ =~ s/%\{next\}/$next_text/;
$_ =~ s/%\{title\}/$title/;
+ $_ =~ s/%\{comment\}/$comment/;
$_ =~ s/%\{position\}/$position/;
$_ =~ s/%\{main_meta\}/$main_meta/;
$_ =~ s/%\{navigation_script\}/$navigation_header/;
my $info = $exifTool->ImageInfo($image);
$exif->{'Make'} = $info->{'Make'};
$exif->{'Model'} = $info->{'Model'};
- #$exif->{'Orientation'} = $info->{'Orientation'};
+ $exif->{'Orientation'} = $info->{'Orientation'};
$exif->{'ExposureTime'} = $info->{'ExposureTime'};
$exif->{'FNumber'} = $info->{'FNumber'};
$exif->{'ISO'} = $info->{'ISO'};
my $flipflop = 0;
foreach my $tag ( keys %$exif )
{
+ next if $tag =~ m/Orientation/;
my $val = $exif->{$tag};
next unless $val;
$block .= "<tr class='exiflight'>" if $flipflop;
$cfg->thumb_pre("<div class='thumb'>");
$cfg->define('thumb_post');
$cfg->thumb_post("</div>");
+ $cfg->define('comment_pre');
+ $cfg->comment_pre("<div id='comment'>");
+ $cfg->define('comment_post');
+ $cfg->thumb_post("</div>");
$cfg->define('idx_prev_text');
$cfg->idx_prev_text("← Back");
$cfg->define('idx_next_text');
# The layout of the thumbnails in the index. Each row will be wrapped
# in a <div class='thumnails'>
-rows = 3
-columns = 4
+rows = 4
+columns = 5
# HTML code to wrap each thumbnail with. The default allows simple
# styling. If you wish to span this over multiple lines, use the
thumb_pre = <div class='thumb'>
thumb_post = </div>
+# HTML code to wrap comments with, for both index and image
+# display. The default allows simple styling. If you wish to span
+# this over multiple lines, use the end-of-line continuation mark \
+comment_pre = <div id='comment'>
+comment_post = </div>
+
+
# Text-strings that can easily be replaced with more complex HTML.
idx_prev_text = ← Back
idx_next_text = Next →
--- /dev/null
+<?php
+
+$site_url = "http://photos.defcon.no";
+$stream_title = "photos.defcon.no gallerystream";
+$stream_description = "The latest entries in the photo galleries at defcon.no";
+$contact_address = "jon.langseth@lilug.no";
+
+$maxcount = 50;
+
+$ctimes = array();
+$album = array();
+$title = array();
+$idximage = array();
+
+//define the path as relative
+$basepath = "./";
+
+//using the opendir function
+$dir_handle = @opendir($basepath) or die("Unable to open $basepath");
+
+//running the while loop
+while ($dir = readdir($dir_handle)) {
+ $target = $basepath . $dir;
+
+
+ if ((!is_file($target)) &&
+ (file_exists($target)) &&
+ ($dir != "images") &&
+ ($dir != ".") &&
+ ($dir != ".."))
+ {
+ if (is_file($target . "/.title"))
+ {
+ $ctime = filectime($target . "/.title");
+ $key = date("Y-m-d-His", $ctime);
+ $album[$key] = $dir;
+ $ctimes[$key] = $ctime;
+
+ $fd = fopen($target . "/.title", "r");
+ $buf = chop(fgets($fd, 4096));
+ fclose($fd);
+ $title[$key] = $buf;
+
+ if (is_file($target . "/.indeximage")) {
+ $fd = fopen($target . "/.indeximage", "r");
+ $buf = "thumb/";
+ $buf .= chop(fgets($fd, 4096));
+ chop ($buf);
+ fclose($fd);
+ $idximage[$key] = $buf;
+ }
+
+ }
+ }
+}
+//closing the directory
+closedir($dir_handle);
+
+krsort($album);
+header("Content-type: application/xml;\n\n");
+print ("<rss version='2.0' xmlns:dc='http://purl.org/dc/elements/1.1/'
+xmlns:content='http://purl.org/rss/1.0/modules/content/'>\n");
+print ("<!-- rss version='2.0' xmlns:dc='http://purl.org/dc/elements/1.1/' -->\n");
+print (" <channel>\n");
+print (" <title>" . $stream_title . "</title>\n");
+print (" <link>" . $site_url . "</link>\n");
+print (" <description>" . $stream_description . "</description>\n");
+print (" <docs>http://blogs.law.harvard.edu/tech/rss</docs>\n");
+print (" <managingEditor>" . $contact_address . "</managingEditor>\n");
+print (" <webMaster>" . $contact_address . "</webMaster>\n");
+
+/* // disse må fixxes
+ <pubDate> <pubDate>
+ </lastBuildDate> </lastBuildDate> */
+
+foreach ( $album as $key => $value ) {
+ print ("<item>\n");
+ print ("<title>");
+ $i_title = html_entity_decode($title[$key]);
+ $url = $site_url . "/" . $value;
+ print ($i_title);
+ print ("</title>\n");
+ print (" <pubDate>" . date("D, j M Y H:i:s +0100", $ctimes[$key]) . "</pubDate>\n");
+ print (" <link>" . $url . "</link>\n");
+ print (" <guid>$key$value</guid>\n");
+ print (" <description>\n");
+ printf ("The photo gallery '%s' at <a href='%s'>%s</a> was updated/published at %s", $i_title,$url,$url,date("D, j M Y H:i:s +0100", $ctimes[$key]));
+ print (" </description>\n");
+ print ("<content:encoded><![CDATA[ ");
+ printf("<center><img src='%s/%s' /></center>", $url, $idximage[$key]);
+ printf ("The photo gallery '%s' at <a href='%s'>%s</a> was updated/published at %s", $i_title,$url,$url,date("D, j M Y H:i:s +0100", $ctimes[$key]));
+ print (" ]]></content:encoded>");
+ print ("</item>\n");
+
+ $maxcount--;
+ if ($maxcount < 1) break;
+}
+print (" </channel>\n");
+print ("</rss>");
+?>
+
+
padding: 2px 0 2px 10px;
}
+#timestamp {
+ margin-top: 15px;
+ font-size: 10pt;
+ font-family: sans;
+}
+
+#copyright {
+ margin-top: 5px;
+ font-size: 10pt;
+ font-family: sans;
+}
+
#footer {
font-family: serif;
font-size: 7pt;
color: #444;
- margin-top: 20px;
+ margin-top: 10px;
}