From 74b0aa12156c5876f1eadafa5e0a388dd5707427 Mon Sep 17 00:00:00 2001 From: Rodrigo Santellan Date: Thu, 17 Nov 2016 13:49:04 +0000 Subject: [PATCH] Bug 17650 - Create the option to save the cover with the uploaded files. Create the option to save the uploaded cover files with the rest of the files. Removing them from saving on the DB and save them on the koha uploads directory. Giving the implementation of creating cache miniatures for using them. Added an option on System Preferences to enable this new feature: SaveCoverOnDisk --- 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 diff --git a/C4/Images.pm b/C4/Images.pm index 37b24179aa..46327a0692 100644 --- a/C4/Images.pm +++ b/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); diff --git a/installer/data/mysql/atomicupdate/bug_17650_save_cover_to_hd.sql b/installer/data/mysql/atomicupdate/bug_17650_save_cover_to_hd.sql new file mode 100644 index 0000000000..c21878c4a3 --- /dev/null +++ b/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'); \ No newline at end of file diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref index 03fb7fc482..de6d7fc401 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref +++ b/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 diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/file-search.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/file-search.tt new file mode 100644 index 0000000000..1da95c7cf1 --- /dev/null +++ b/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 %] + +
\ No newline at end of file diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt index 817fee9217..b6a144f9a4 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt +++ b/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 %] diff --git a/tools/file-search.pl b/tools/file-search.pl new file mode 100755 index 0000000000..fa91c91624 --- /dev/null +++ b/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'; \ No newline at end of file diff --git a/tools/upload-cover-image.pl b/tools/upload-cover-image.pl index ff89afb1d6..2c9f1c3565 100755 --- a/tools/upload-cover-image.pl +++ b/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'; } diff --git a/tools/upload-file.pl b/tools/upload-file.pl index 86ef2c5dc2..1350609e22 100755 --- a/tools/upload-file.pl +++ b/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; } -- 2.11.0