123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- # Copyright (C) 2004, 2012 Alex Schroeder <alex@gnu.org>
- # Copyright (C) 2005 Rob Neild
- #
- # This program is free software: you can redistribute it and/or modify it under
- # the terms of the GNU General Public License as published by the Free Software
- # Foundation, either version 3 of the License, or (at your option) any later
- # version.
- #
- # This program is distributed in the hope that it will be useful, but WITHOUT
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License along with
- # this program. If not, see <http://www.gnu.org/licenses/>.
- # Thumbnail (and improved image handling) module for OddMuse wiki
- # Conflicts with the "Image extension module"
- use strict;
- use v5.10;
- require MIME::Base64;
- use File::Path;
- AddModuleDescription('thumbs.pl', 'Image Thumbnails');
- our ($q, $OpenPageName, %IndexHash, @UploadTypes, @MyRules, $FreeLinkPattern);
- # Tempoary directory to create thumbnails in
- our $ThumbnailTempDir = '/tmp';
- # Path and name of external program to use to create thumbnails. Only
- # ImageMagick 'convert' can be used. You may have to set the MAGICK_HOME
- # environment variable in your config file if you set it to
- # /usr/local/bin/convert and get the following error:
- # convert: no decode delegate for this image format
- # For your config file:
- # $ENV{MAGICK_HOME} = '/usr/local';
- our $ThumbnailConvert = '/usr/bin/convert';
- # Max size for a thumbnail. If larger size is specified just shows
- # regular image
- our $ThumbnailMaxSize = 500;
- # Default thumbnail size if non is specified
- our $ThumbnailDefaultSize = 100;
- # MIME types to create thumbnail for, all allowed if empty list
- our @ThumbnailTypes = @UploadTypes;
- # As well as using ALT, use TITLE. This enables comments to popup when
- # hovering mouse over thumbnail
- our $ThumbnailImageUseTitle = 0;
- our $ThumbnailCacheDir = "oddmuse_thumbnail_cache";
- our $ThumbnailCacheUrl = "/oddmuse_thumbnail_cache";
- # Define new formatting rule "thumb" that inserts an auto generated thumbnail
- # Syntax is [[thumb:page name | etc. ]]
- push(@MyRules, \&ThumbNailSupportRule);
- sub ThumbNailSupportRule {
- my $result;
- my $RawMatch;
- if (m!\G(\[\[thumb:$FreeLinkPattern(\|.*?)?\]\])!cg)
- {
- $RawMatch = $1;
- # Try and extract out all the options. They can be in any order, apart from comment at end
- my $name = $2;
- my $size="$ThumbnailDefaultSize"; # default size for thumbnail
- my $frame;
- my $comment; # default alignment for a non framed picture
- my $alignment_framed = 'tright'; # default alignment for a framed picture
- my $alignment;
- my $params = $3 . '|';
- if($params =~ s/\|([0-9]+)px\|/\|/) { $size = $1; }
- if($params =~ s/\|thumb\|/\|/) { $frame = 'yes' ;}
- if($params =~ s/\|frame\|/\|/) { $frame = 'yes'; }
- if ($params =~ s/\|none\|/\|/) { $alignment_framed= 'tnone'; }
- if ($params =~ s/\|right\|/\|/) { $alignment_framed= 'tright'; $alignment='floatright';}
- if ($params =~ s/\|left\|/\|/) { $alignment_framed= 'tleft'; $alignment='floatleft'; }
- if ($params =~ m/\|(.+)\|$/) { $comment = $1; }
- my $id = FreeToNormal($name);
- AllPagesList();
- # if the page does exists
- if ($IndexHash{$id})
- {
- if (!IsFile("$ThumbnailCacheDir/$id/$size"))
- {
- GenerateThumbNail ($id, $size);
- }
- my %img_attribs;
- my $action = "$ThumbnailCacheUrl/" . UrlEncode($id) . "/$size";
- $img_attribs{'-src'} = $action;
- if (defined $comment) {
- $img_attribs{'-alt'} ="$comment";
- $img_attribs{'-title'} = "$comment" if $ThumbnailImageUseTitle==1;
- }
- else { $img_attribs{'-alt'} = "$name"; }
- $img_attribs{'-class'} = 'upload';
- $result = $q->img(\%img_attribs);
- $result = ScriptLink(UrlEncode($id) , $result, 'image');
- if (defined $frame) {
- if (defined $comment) { $result = $result . $q->div({-class=>'thumbcaption'}, "$comment"); }
- if ($size>0) {
- $result = $q->div({-style=>"width:" . ($size+2) . "px"}, $result);
- $result = $q->div({-class=>"thumb " . $alignment_framed}, $result);
- }
- }
- else
- {
- if (defined $alignment) { $result = $q->div({-class=>"$alignment" }, $result); }
- }
- }
- else
- {
- # if the image does not exist
- $result = '[' . T('thumb') . ':' . $name . GetEditLink($id, '?', 1) . ']';
- }
- }
- if (defined $result)
- {
- Dirty($RawMatch);
- print $result;
- $result = '';
- }
- return $result;
- }
- # define new action "thumbnail" that actually does the on fly generation of the image
- # thumbnails are put into the file so they only need be generated once
- # we also store the size of thumbnail so that can be used in the markup
- # if we get passed a size of zero then all we need to do is check whether we have the image size stored in thumbnail_0
- # this enbles markup for non-thumbnail images better
- sub GenerateThumbNail {
- my ($id, $size) = (@_);
- ValidIdOrDie($id);
- AllPagesList();
- if (not $IndexHash{$id}) { ReportError(Ts('Error creating thumbnail from nonexisting page %s.' , $id), '500 INTERNAL SERVER ERROR'); } # Page Doesn't exist,
- my $openpage = $OpenPageName; # remember the current page we are on
- RequestLockOrError();
- OpenPage($id);
- # Parse out some data
- # Check MIME type supported
- # Check is a file
- my $text = GetTextRevision(GetParam('revision', ''))->{text}; # maybe revision reset!
- my ($type) = TextIsFile($text); # MIME type if an uploaded file
- my $data = substr($text, index($text, "\n") + 1);
- if ($type)
- {
- my $regexp = quotemeta($type);
- if (@ThumbnailTypes and not grep(/^$regexp$/, @ThumbnailTypes)) {
- ReportError(Ts('Can not create thumbnail for file type %s.' , $type), '415 UNSUPPORTED MEDIA TYPE');
- }
- }
- else
- {
- ReportError(T('Can not create thumbnail for a text document'), '500 INTERNAL SERVER ERROR');
- }
- my $filename = $ThumbnailTempDir . "/odd" . $id . "_" . $size;
- # Decode the original image to a temp file
- open(my $FD, '>', encode_utf8($filename)) or ReportError(Ts("Could not open %s for writing whilst trying to save image before creating thumbnail. Check write permissions.",$filename), '500 INTERNAL SERVER ERROR');
- binmode($FD);
- print $FD MIME::Base64::decode($data);
- close($FD);
- eval { mkpath("$ThumbnailCacheDir/$id") };
- if ($@) {
- ReportError(Ts('Can not create path for thumbnail - %s', $@), '500 INTERNAL SERVER ERROR');
- }
- # create the thumbnail
- my $command = "$ThumbnailConvert '$filename' -verbose -resize ${size}x '$ThumbnailCacheDir/$id/$size' 2>&1";
- open (my $MESSAGE, '-|', $command)
- or ReportError(Tss("Failed to run %1 to create thumbnail: %2", $ThumbnailConvert, $!),
- '500 INTERNAL SERVER ERROR');
- my $convert = <$MESSAGE>;
- close($MESSAGE);
- my $scaled_size_x;
- my $scaled_size_y;
- my $thumbnail_data= '';
- if($?) {
- ReportError(Ts("%s ran into an error", $ThumbnailConvert), '500 INTERNAL SERVER ERROR', undef,
- $q->pre($command . "\n" . $convert));
- } elsif($convert =~ m/=>(\d+)x(\d+)/) {
- $scaled_size_x = $1;
- $scaled_size_y = $2;
- } elsif (!$convert) {
- ReportError(Ts("%s produced no output", $ThumbnailConvert), '500 INTERNAL SERVER ERROR');
- } else {
- ReportError(Ts("Failed to parse %s.", $convert), '500 INTERNAL SERVER ERROR');
- }
- Unlink($filename);
- # save tag to page
- #$Page{'thumbnail_' . $size} = '#FILE ' . $type . ' created=' . $Now . ' revision=' . $Page{'revision'} . ' size=' . $scaled_size_x . 'x' . $scaled_size_y . "\n" . $thumbnail_data;
- #SavePage();
- ReleaseLock();
- OpenPage($openpage); # restore original open page
- }
|