AxKit2
view release on metacpan or search on metacpan
plugins/demo/gallery view on Meta::CPAN
our $DEFAULT_SIZE = '133 640 800 1024';
sub hook_xmlresponse {
my ($self, $input) = @_;
$self->log(LOGINFO, "running");
my $client = $self->client;
my $file = $client->headers_in->filename;
if (-d $file) {
return $self->serve_dir($input);
}
$self->log(LOGINFO, "checking content type and format");
my $mm = File::MMagic->new;
my $ct = $mm->checktype_filename($file);
# we're only interested in images
return DECLINED unless $ct =~ /^image\//i;
my $format = $client->param('format') || 'html';
if ($format eq 'html') {
return $self->serve_image_page($input, $ct);
}
# Now we just serve the raw image, possibly resized
$self->log(LOGINFO, "serving raw image");
# Make sure the specified size is one we're configured to
# support. If it isn't then use the default size
my $sizelist = $self->get_cfg('GallerySizes') || $DEFAULT_SIZE;
my @sizes = split(/\s+/, $sizelist);
my $size = $client->param('size') || '';
# If the size is 'full' then we're sending back the full size
# image. There's no work to do, so just return DECLINED
if ($size eq 'full') {
open(my $fh, $file) || die "open($file): $!";
$client->headers_out->header('Content-Length', -s $file);
$client->headers_out->header('Content-Type', $ct);
$client->send_http_headers;
local $/;
my $out = <$fh>;
$client->write(\$out);
return OK;
}
if ($size eq 'thumb') {
$size = $sizes[0];
}
else {
$size = $sizes[1] unless grep { $_ eq $size } @sizes;
}
my $cache = $self->cache;
if (my $cache_obj = $cache->get_object("$file+$size")) {
if ($cache_obj->get_created_at() >= (stat($file))[9]) {
my $out = $cache->get("$file+$size");
$self->log(LOGINFO, "Serving cached image");
$client->headers_out->header('Content-Length', bytelength($out));
$client->headers_out->header('Content-Type', $ct);
$client->send_http_headers;
# using ->get here makes sure Cache::Cache expires stuff
$client->write(\$out);
return OK;
}
}
$self->log(LOGINFO, "Resizing image $file to size $size");
my ($type) = $ct =~ /\/(.*)$/;
my $out;
$self->resize_image($size, $file, $type, \$out);
$cache->set("$file+$size", $out);
$client->headers_out->header('Content-Length', bytelength($out));
$client->headers_out->header('Content-Type', $ct);
$client->send_http_headers;
# using ->get here makes sure Cache::Cache expires stuff
$client->write(\$out);
return OK;
}
sub resize_image {
my ($self, $size, $file, $type, $out) = @_;
my $image = Imager->new;
$image->open(file => $file)
or die $image->errstr();
my($w, $h) = ($image->getwidth(), $image->getheight());
$self->log(LOGINFO, "Original width x height: $w x $h");
my $quality = $self->get_cfg('GalleryThumbQuality') || 'preview';
$quality = 'normal' if $quality ne 'preview';
$quality = 'normal' if $self->client->param('size') ne 'thumb';
$self->log(LOGINFO, "Scaling to $size with quality: $quality");
my $doublesize = $size < (($w > $h ? $w : $h)/2);
if ($quality eq 'normal' && $doublesize) {
$self->log(LOGINFO, "Doing an initial shrinkage in preview mode");
my $thumb = $image->scale(qtype => "preview",
$w > $h ? (xpixels => $w/2)
: (ypixels => $h/2)
);
$image = $thumb;
}
my $thumb = $image->scale(qtype => $quality,
$w > $h ?
(xpixels => $size)
: (ypixels => $size)
);
if ($doublesize) {
$self->log(LOGINFO, "sharpening $thumb");
# Sharpen a bit with a convolve filter
$thumb->filter(
type=>'conv',
coef => [-0.2, 1, -0.2]
) if $quality eq 'normal';
}
$thumb->write(data => $out, type => $type)
or die "Cannot write to scalar: ", $thumb->errstr;
}
sub serve_image_page {
my ($self, $input, $ct) = @_;
$self->log(LOGINFO, "Serving Imagesheet");
my $file = $self->client->headers_in->filename;
my $filesize = (stat($file))[7];
my $mod = (stat(_))[9];
my $path;
($path, $file) = $file =~ /(.*)\/(.*)/; # Extract the path/file info
my $mm = File::MMagic->new;
opendir(DIR, $path);
my ($prev, $next);
my $found = 0;
for my $entry (sort readdir(DIR)) {
next if $entry =~ /^\./;
next if -d $entry;
if ($entry eq $file) {
$found++;
next;
}
my $type = $mm->checktype_filename("$path/$entry");
next unless $type =~ /^image\//;
if ($found) {
$next = $entry;
last;
}
else {
$prev = $entry;
}
}
my $uri = $self->client->headers_in->request_uri;
$uri =~ s/\?.*//;
# generate path and config data.
my ($uri_path) = $uri =~ /(.*)\//;
$uri =~ s/^\///; # Trim the leading '/'
$uri = "<full><e>$uri</e><u>" . uri_decode($uri) . "</u></full>\n" .
"<path><e>$uri_path</e><u>" . uri_decode($uri_path) . "</u></path>\n" .
join("\n",
map { "<component><e>$_</e><u>" . uri_decode($_) . "</u></component>" } split(/\//, $uri));
my $xml = <<EOXML;
<?xml version="1.0"?>
<imagesheet>
<config>
<perl-vars>
EOXML
foreach my $var (qw(ProofsheetColumns ImagesPerProofsheet
GalleryCache GalleryThumbQuality))
{
no warnings 'uninitialized';
$xml .= "<var name='$var'>" . $self->get_cfg($var) . "</var>\n";
}
my $size = $self->client->param('size') || '';
# Make sure the specified size is one we're configured to
# support. If it isn't then use the default size
my $sizelist = $self->get_cfg('GallerySizes');
$sizelist = $DEFAULT_SIZE unless defined $sizelist;
my @sizes = split(/\s+/, $sizelist);
( run in 0.982 second using v1.01-cache-2.11-cpan-39bf76dae61 )