@@ -, +, @@ uploaded files. --- C4/Images.pm | 83 ++++++++++++++++++---- .../atomicupdate/bug_17650_save_cover_to_hd.sql | 16 +++++ .../admin/preferences/enhanced_content.pref | 6 ++ .../prog/en/modules/tools/file-search.tt | 29 ++++++++ .../prog/en/modules/tools/upload-images.tt | 56 ++++++++++++++- tools/file-search.pl | 67 +++++++++++++++++ tools/upload-cover-image.pl | 5 +- tools/upload-file.pl | 2 + 8 files changed, 247 insertions(+), 17 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_17650_save_cover_to_hd.sql create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/tools/file-search.tt create mode 100755 tools/file-search.pl --- a/C4/Images.pm +++ a/C4/Images.pm @@ -24,6 +24,9 @@ use 5.010; use C4::Context; use GD; +use Koha::Upload; + +use File::Path qw(make_path); use vars qw($debug $noimage @ISA @EXPORT); @@ -54,7 +57,7 @@ Stores binary image data and thumbnail in database, optionally replacing existin =cut sub PutImage { - my ( $biblionumber, $srcimage, $replace ) = @_; + my ( $biblionumber, $srcimage, $replace, $uploadedfileid ) = @_; return -1 unless defined($srcimage); @@ -66,25 +69,29 @@ sub PutImage { my $dbh = C4::Context->dbh; my $query = -"INSERT INTO biblioimages (biblionumber, mimetype, imagefile, thumbnail) VALUES (?,?,?,?);"; +"INSERT INTO biblioimages (biblionumber, mimetype, imagefile, thumbnail, uploadedfileid) VALUES (?,?,?,?,?);"; my $sth = $dbh->prepare($query); my $mimetype = 'image/png' ; # GD autodetects three basic image formats: PNG, JPEG, XPM; we will convert all to PNG which is lossless... + if( defined $uploadedfileid){ + $sth->execute( $biblionumber, $mimetype, undef, undef, $uploadedfileid ); + }else{ + # Check the pixel size of the image we are about to import... + my $thumbnail = _scale_image( $srcimage, 140, 200 ) + ; # MAX pixel dims are 140 X 200 for thumbnail... + my $fullsize = _scale_image( $srcimage, 600, 800 ) + ; # MAX pixel dims are 600 X 800 for full-size image... + $debug and warn "thumbnail is " . length($thumbnail) . " bytes."; + + $sth->execute( $biblionumber, $mimetype, $fullsize->png(), + $thumbnail->png(), $uploadedfileid ); + undef $thumbnail; + undef $fullsize; + } - # Check the pixel size of the image we are about to import... - my $thumbnail = _scale_image( $srcimage, 140, 200 ) - ; # MAX pixel dims are 140 X 200 for thumbnail... - my $fullsize = _scale_image( $srcimage, 600, 800 ) - ; # MAX pixel dims are 600 X 800 for full-size image... - $debug and warn "thumbnail is " . length($thumbnail) . " bytes."; - - $sth->execute( $biblionumber, $mimetype, $fullsize->png(), - $thumbnail->png() ); my $dberror = $sth->errstr; warn "Error returned inserting $biblionumber.$mimetype." if $sth->errstr; - undef $thumbnail; - undef $fullsize; return $dberror; } @@ -100,20 +107,68 @@ sub RetrieveImage { my $dbh = C4::Context->dbh; my $query = -'SELECT imagenumber, mimetype, imagefile, thumbnail FROM biblioimages WHERE imagenumber = ?'; +'SELECT imagenumber, mimetype, imagefile, thumbnail, uploadedfileid FROM biblioimages WHERE imagenumber = ?'; my $sth = $dbh->prepare($query); $sth->execute($imagenumber); my $imagedata = $sth->fetchrow_hashref; if ( !$imagedata ) { $imagedata->{'thumbnail'} = $noimage; $imagedata->{'imagefile'} = $noimage; + }else{ + if (defined $imagedata->{'uploadedfileid'}){ + my ($thumbnail, $imagefile) = _retrieve_thumbs_images($imagedata->{'uploadedfileid'}); + $imagedata->{'thumbnail'} = $thumbnail; # MAX pixel dims are 140 X 200 for thumbnail... + $imagedata->{'imagefile'} = $imagefile; + + } } + if ( $sth->err ) { warn "Database error!" if $debug; } return $imagedata; } +sub _retrieve_thumbs_images { + my ($uploadedfileid) = @_; + my $thumbnail_name = '140_200.png'; + my $imagefile_name = '600_800.png'; + my $temp_directory = "/tmp/koha_thumbs_$uploadedfileid"; + my $files_exists = 0; + #Check if the uploaded file id exists on the temp directory. + #Check if a temp dir exists. + if ( -d $temp_directory){ + if ( -e "$temp_directory/$thumbnail_name" && -e "$temp_directory/$imagefile_name"){ + $files_exists = 1; + } + }else{ + make_path("/tmp/koha_thumbs_$uploadedfileid"); + } + my $thumbnail; + my $imagefile; + if($files_exists){ + $thumbnail = GD::Image->new("$temp_directory/$thumbnail_name")->png(); + $imagefile = GD::Image->new("$temp_directory/$imagefile_name")->png(); + }else{ + # There is none temp files, create them. + my $upload = Koha::Upload->new->get({ id => $uploadedfileid, filehandle => 1 }); + my $srcimage = GD::Image->new($upload->{fh}); + $thumbnail = _scale_image( $srcimage, 140, 200 )->png(); + $imagefile = _scale_image( $srcimage, 600, 800 )->png(); + warn "$temp_directory/$thumbnail_name"; + open( IMAGE, ">$temp_directory/$thumbnail_name"); + binmode( IMAGE ); + print IMAGE $thumbnail; + close IMAGE; + warn "$temp_directory/$imagefile_name"; + open( IMAGE2, ">$temp_directory/$imagefile_name"); + binmode( IMAGE2 ); + print IMAGE2 $imagefile; + close IMAGE2; + } + return ($thumbnail, $imagefile); +} + =head2 ListImagesForBiblio my (@images) = ListImagesForBiblio($biblionumber); --- a/installer/data/mysql/atomicupdate/bug_17650_save_cover_to_hd.sql +++ a/installer/data/mysql/atomicupdate/bug_17650_save_cover_to_hd.sql @@ -0,0 +1,16 @@ +ALTER TABLE `biblioimages` +DROP FOREIGN KEY `bibliocoverimage_fk1`; +ALTER TABLE `biblioimages` +CHANGE COLUMN `imagefile` `imagefile` MEDIUMBLOB NULL DEFAULT NULL , +CHANGE COLUMN `thumbnail` `thumbnail` MEDIUMBLOB NULL DEFAULT NULL , +ADD COLUMN `uploadedfileid` INT(11) NULL DEFAULT NULL AFTER `thumbnail`, +ADD INDEX `bibliocoverimage_fk2_idx` (`uploadedfileid` ASC); +ALTER TABLE `biblioimages` +ADD CONSTRAINT `bibliocoverimage_fk2` + FOREIGN KEY (`uploadedfileid`) + REFERENCES `uploaded_files` (`id`) + ON DELETE CASCADE + ON UPDATE CASCADE; + + +INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES ('SaveCoverOnDisk','0','','Save the covers on the the hard disk instead of the database.','YesNo'); --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref @@ -316,6 +316,12 @@ Enhanced Content: yes: Allow no: "Don't allow" - multiple images to be attached to each bibliographic record. + - + - pref: SaveCoverOnDisk + choices: + yes: "Yes" + no: "No" + - Save the covers on the the hard disk instead of the database. HTML5 Media: - - Show a tab with a HTML5 media player for files catalogued in field 856 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/file-search.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/file-search.tt @@ -0,0 +1,29 @@ +[% USE Koha %] + + + + + + + + + + + + + + [% FOREACH record IN uploads %] + + + + + + + + + + [% END %] + +
FilenameSizeHashvalueCategoryPublicTemporaryActions
[% record.name %][% record.filesize %][% record.hashvalue %][% record.uploadcategorycode %][% IF record.public %]Yes[% ELSE %]No[% END %][% IF record.permanent %]No[% ELSE %]Yes[% END %] + +
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt @@ -68,7 +68,26 @@
+[% IF SaveCoverOnDisk %] +
+ + +
+ Search uploads by name or hashvalue +
    +
  1. + + +
  2. +
+
+ +
+
+
+
+[% END %]
@@ -120,7 +139,7 @@ $('#uploadform button.submit').prop('disabled',true); $("#fileuploadstatus").show(); $("#uploadedfileid").val(''); - xhr= AjaxUpload( $('#fileToUpload'), $('#fileuploadprogress'), 'temp=1', cbUpload ); + xhr= AjaxUpload( $('#fileToUpload'), $('#fileuploadprogress'), 'temp=[% IF SaveCoverOnDisk %]0&category=covers[% ELSE %]1[% END %]', cbUpload ); } function cbUpload( status, fileid, errors ) { if( status=='done' ) { @@ -139,8 +158,33 @@ $("#processfile").hide(); } } + [% IF SaveCoverOnDisk %] + function searchFile(form){ + $.ajax({ + url: $(form).attr('action'), + data: $(form).serialize(), + type: 'post', + success: function(html){ + $("#searchfilepanel").html(html); + } + , + complete: function() + { + } + }); + return false; + } + + function selectFileToAssociate(fileid){ + $("#uploadedfileid").val( fileid ); + $('#fileToUpload').prop('disabled',true); + $("#processfile").show(); + } + [% END %] + $(document).ready(function(){ $("#processfile").hide(); + $("#zipfile").click(function(){ $("#bibnum").hide(); }); @@ -153,6 +197,16 @@ return false; } }); + [% IF SaveCoverOnDisk %] + $("#searchbutton").on("click",function(e){ + e.preventDefault(); + searchFile($('#searchfile')); + }); + $(".choose_entry").on("click",function(e){ + e.preventDefault(); + selectFileToAssociate($(this).data("record-id")); + }); + [% END %] }); [% END %] --- a/tools/file-search.pl +++ a/tools/file-search.pl @@ -0,0 +1,67 @@ +#!/usr/bin/perl + +# Converted to new plugin style (Bug 13437) + +# Copyright 2000-2002 Katipo Communications +# +# This file is part of Koha. +# +# Koha 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. +# +# Koha 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 Koha; if not, see . + +use Modern::Perl; +use CGI qw ( -utf8 ); +use JSON; + +use warnings; +no warnings 'redefine'; # otherwise loading up multiple plugins fills the log with subroutine redefine warnings + +use C4::Auth; +use C4::Context; +use C4::Output; + +use Koha::Upload; + +use Data::Dumper; + +use vars qw($debug); + +BEGIN { + $debug = $ENV{DEBUG} || 0; +} + +my $dbh = C4::Context->dbh; +my $input = CGI->new; +$debug or $debug = $input->param('debug') || 0; +my $content_type = 'json'; + +my $term = $input->param('term'); + +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { template_name => "tools/file-search.tt", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => { editcatalogue => '*' }, + debug => 1, + } +); + +my $upar = {}; +my $h = { term => $term, uploadcategorycode => 'covers' }; +my @uploads = Koha::Upload->new($upar)->get($h); +$template->param( + uploads => \@uploads, +); + +output_with_http_headers $input, $cookie, $template->output, 'html'; --- a/tools/upload-cover-image.pl +++ a/tools/upload-cover-image.pl @@ -48,6 +48,7 @@ use C4::Output; use C4::Images; use Koha::UploadedFiles; use C4::Log; +use Data::Dumper; my $debug = 1; @@ -78,9 +79,9 @@ my $error; $template->{VARS}->{'filetype'} = $filetype; $template->{VARS}->{'biblionumber'} = $biblionumber; +$template->{VARS}->{'SaveCoverOnDisk'} = C4::Context->preference("SaveCoverOnDisk"); my $total = 0; - if ($fileID) { my $upload = Koha::UploadedFiles->find( $fileID ); if ( $filetype eq 'image' ) { @@ -88,7 +89,7 @@ if ($fileID) { my $srcimage = GD::Image->new($fh); $fh->close if $fh; if ( defined $srcimage ) { - my $dberror = PutImage( $biblionumber, $srcimage, $replace ); + my $dberror = PutImage( $biblionumber, $srcimage, $replace, $fileID ); if ($dberror) { $error = 'DBERR'; } --- a/tools/upload-file.pl +++ a/tools/upload-file.pl @@ -28,6 +28,7 @@ use URI::Escape; use C4::Context; use C4::Auth qw/check_cookie_auth haspermission/; use Koha::Uploader; +use Data::Dumper; # upload-file.pl must authenticate the user # before processing the POST request, @@ -80,5 +81,6 @@ sub upload_pars { # this sub parses QUERY_STRING in order to build the $rv->{$p} = $2; } } + warn Dumper($rv); return $rv; } --