Bugzilla – Attachment 6242 Details for
Bug 1633
Add ability to take book cover images from local img db
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to enable local cover images
0001-Bug-1633-Patch-to-add-local-cover-images-support-for.patch (text/plain), 37.83 KB, created by
Koustubha Kale
on 2011-11-06 09:37:14 UTC
(
hide
)
Description:
Patch to enable local cover images
Filename:
MIME Type:
Creator:
Koustubha Kale
Created:
2011-11-06 09:37:14 UTC
Size:
37.83 KB
patch
obsolete
>From a7f974bda619d9cea868249316273fc4efb2477d Mon Sep 17 00:00:00 2001 >From: Koustubha Kale <kmkale@anantcorp.com> >Date: Sun, 6 Nov 2011 11:13:23 +0530 >Subject: [PATCH] [Bug 1633] Patch to add local cover images support for > display in OPAC. >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit >Content-Type: text/plain; charset="utf-8" > >This patch adds support for local cover images for display in OPAC. > >How to use/test : >Assign user permission to the user Tools > (upload_local_cover_images Upload local cover images. >In order to upload local images, login to the staff client. Go to Home ⺠Tools ⺠Upload Cover Images. >Here you can upload cover images either singly or in bulk in the form of a zip file. >If uploading singly, click on image file, browse the image from your local disk, type in the biblio number of the catalouge entry and press upload. >If uploading in bulk as a zip file, the zip file must contain ( in addition to cover images ) one text file named either datalink.txt OR >idlink.txt. This file should have mapping of biblionumber to image file name in the zip one per line with comma or tab as delimiters. For example > >1, scanned_cover_image_of_bib_no_1.jpg >2, scanned_cover_image_of_bib_no_1.jpg > >Cover Image Files greater than 100K will be refused. Images should be 140x200 pixels. If they are larger they will be auto-resized to comply. >If a cover image file is uploaded with a biblionumber which already has matching image in the database it will be overwritten. >1. The patch adds a menu link in Tools from where you can upload local cover images >2. It adds a user permission to enable access control to this menu item under Tools >3. It adds a system preference OPACLocalCoverImages under Enhanced Content. This needs to be turned on to show local cover images in OPAC. > >Once you have uploaded local images, if you search for the biblio, the local cover should show up in search as well as search detail pages. > >I am working on another patch which will allow us to set a cover image source priority in system preferences, >and which will then gracefully fail over to the next source if image is not available from the first choice source. >--- > .../data/mysql/en/mandatory/userpermissions.sql | 1 + > installer/data/mysql/kohastructure.sql | 13 + > installer/data/mysql/sysprefs.sql | 2 +- > installer/data/mysql/updatedatabase.pl | 16 + > .../intranet-tmpl/prog/en/includes/tools-menu.inc | 3 + > .../admin/preferences/enhanced_content.pref | 7 + > .../prog/en/modules/tools/tools-home.tt | 5 + > .../prog/en/modules/tools/upload-cover-image.tt | 126 +++++++ > koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 1 + > .../opac-tmpl/prog/en/modules/opac-results.tt | 1 + > opac/opac-coverimage.pl | 105 ++++++ > opac/opac-detail.pl | 5 + > opac/opac-search.pl | 4 + > tools/upload-cover-image.pl | 341 ++++++++++++++++++++ > 14 files changed, 629 insertions(+), 1 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-cover-image.tt > create mode 100755 opac/opac-coverimage.pl > create mode 100755 tools/upload-cover-image.pl > >diff --git a/installer/data/mysql/en/mandatory/userpermissions.sql b/installer/data/mysql/en/mandatory/userpermissions.sql >index ec61ea0..873089a 100644 >--- a/installer/data/mysql/en/mandatory/userpermissions.sql >+++ b/installer/data/mysql/en/mandatory/userpermissions.sql >@@ -36,6 +36,7 @@ INSERT INTO permissions (module_bit, code, description) VALUES > (13, 'manage_csv_profiles', 'Manage CSV export profiles'), > (13, 'moderate_tags', 'Moderate patron tags'), > (13, 'rotating_collections', 'Manage rotating collections'), >+ (13, 'upload_local_cover_images', 'Upload local cover images'), > (15, 'check_expiration', 'Check the expiration of a serial'), > (15, 'claim_serials', 'Claim missing serials'), > (15, 'create_subscription', 'Create a new subscription'), >diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql >index e4388a4..97bd04e 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -2665,6 +2665,19 @@ CREATE TABLE `fieldmapping` ( -- koha to keyword mapping > PRIMARY KEY (`id`) > ) ENGINE=InnoDB DEFAULT CHARSET=utf8; > >+-- >+-- Table structure for table `bibliocoverimage` >+-- >+ >+DROP TABLE IF EXISTS `bibliocoverimage`; >+ >+CREATE TABLE `bibliocoverimage` ( >+ `biblionumber` int(11) NOT NULL, >+ `mimetype` varchar(15) NOT NULL, >+ `imagefile` mediumblob NOT NULL, >+ PRIMARY KEY (`biblionumber`), >+ CONSTRAINT `bibliocoverimage_fk1` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE >+) ENGINE=InnoDB DEFAULT CHARSET=utf8 > > /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; > /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; >diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >index ae2c1cb..254fcc8 100755 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -328,4 +328,4 @@ INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES(' > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OpacKohaUrl','1',"Show 'Powered by Koha' text on OPAC footer.",NULL,NULL); > INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES('EasyAnalyticalRecords','0','If on, display in the catalogue screens tools to easily setup analytical record relationships','','YesNo'); > INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacShowRecentComments',0,'If ON a link to recent comments will appear in the OPAC masthead',NULL,'YesNo'); >- >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OPACLocalCoverImages','0','Display local cover images on OPAC search and details pages.','1','YesNo'); >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index a8cd166..b796f26 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -4550,6 +4550,22 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { > SetVersion ($DBversion); > } > >+$DBversion = '3.06.00.XXX'; >+if (C4::Context->preference("Version") < TransformToNum($DBversion)) { >+ $dbh->do( q|CREATE TABLE `bibliocoverimage` ( >+ `biblionumber` int(11) NOT NULL, >+ `mimetype` varchar(15) NOT NULL, >+ `imagefile` mediumblob NOT NULL, >+ PRIMARY KEY (`biblionumber`), >+ CONSTRAINT `bibliocoverimage_fk1` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE >+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8|); >+ $dbh->do( q|INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OPACLocalCoverImages','0','Display local cover mages on OPAC search and details pages.','1','YesNo')|); >+ $dbh->do( q|INSERT INTO permissions (module_bit, code, description) VALUES (13, 'upload_local_cover_images', 'Upload local cover images')|); >+ print "Upgrade to $DBversion done (Added bibliocoverimage table to stover local cover images)\n"; >+ SetVersion ($DBversion); >+} >+ >+ > =head1 FUNCTIONS > > =head2 DropAllForeignKeys($table) >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc >index e3896cc..8a739d5 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc >@@ -70,6 +70,9 @@ > [% IF ( CAN_user_tools_manage_staged_marc ) %] > <li><a href="/cgi-bin/koha/tools/manage-marc-import.pl">Staged MARC management</a></li> > [% END %] >+ [% IF ( CAN_user_tools_upload_local_cover_images ) %] >+ <li><a href="/cgi-bin/koha/tools/upload-cover-image.pl">Upload Local Cover Image</a></li> >+ [% END %] > </ul> > <h5>Additional Tools</h5> > <ul> >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 171b5f4..1db76a2 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 >@@ -311,3 +311,10 @@ Enhanced Content: > - pref: TagsExternalDictionary > class: file > - on the server to be approved without moderation. >+ Local Cover Images: >+ - >+ - pref: OPACLocalCoverImages >+ choices: >+ yes: Display >+ no: "Don't display" >+ - local cover images on OPAC search and details pages. >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt >index 10f1d6d..0c3077a 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt >@@ -140,6 +140,11 @@ > <dd>Managed staged MARC records, including completing and reversing imports</dd> > [% END %] > >+ [% IF ( CAN_user_tools_upload_local_cover_images ) %] >+ <dt><a href="/cgi-bin/koha/tools/upload-cover-image.pl">Upload Local Cover Image</a></dt> >+ <dd>Utility to upload scanned cover images for display in OPAC</dd> >+ [% END %] >+ > </dl> > </div> > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-cover-image.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-cover-image.tt >new file mode 100644 >index 0000000..2f1642d >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-cover-image.tt >@@ -0,0 +1,126 @@ >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Tools › Upload Cover Images</title> >+[% INCLUDE 'doc-head-close.inc' %] >+<script type="text/javascript"> >+ $(document).ready(function() { >+ $("#zipfile").click(function(){ >+ $("#bibnum").hide(); >+ }); >+ $("#image").click(function(){ >+ $("#bibnum").show(); >+ }); >+}); >+</script> >+</head> >+<body> >+ >+[% INCLUDE 'header.inc' %] >+[%# [% INCLUDE 'cover-search.inc' %] %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> › Upload Cover Images </div> >+ >+<div id="doc3" class="yui-t2"> >+ <div id="bd"> >+ <div id="yui-main"> >+[% IF ( TOTAL ) %] >+ <div class="yui-b"> >+ <div class="yui-g"> >+ <div class="yui-u first"> >+ [% IF ( ERRORS ) %] >+ [% IF ( TCOUNTS ) %] >+ <div class="dialog alert"> >+ <h3>Cover Image(s) Uploaded With Some Errors</h3> >+ [% ELSE %] >+ <div class="dialog alert"> >+ <h3>Cover Image Failed to Upload</h3> >+ [% END %] >+ [% ELSE %] >+ <div class="dialog message"> >+ <h3>Cover Image(s) Successfully Uploaded</h3> >+ [% END %] >+ <ul class="data"> >+ <li>Unpacking completed</li> >+ <li>[% TOTAL %] directorie(s) scanned.</li> >+ <li>[% HANDLED %] directorie(s) processed.</li> >+ </ul> >+ [% FOREACH COUNT IN COUNTS %] >+ <ul class="data"> >+ [% IF ( COUNT.TCOUNTS ) %]<li>[% COUNT.TCOUNTS %] image(s) moved into the database:</li>[% END %] >+ [% FOREACH filename IN COUNT.filenames %] >+ <li>[% filename.source %] - Biblionumber: [% filename.biblionumber %] >+ [% IF ( filename.filerrors ) %]<br /> <b>WARNING:</b> This image <i>not</i> imported because >+ [% FOREACH filerror IN filename.filerrors %] >+ [% IF ( filerror.DBERR ) %]the database returned an error. Please refer to the error log for more details.</li> >+ [% ELSIF ( filerror.IMGEXISTS ) %]this cover does not exist in the database.</li> >+ [% ELSIF ( filerror.MIMERR ) %]the image format is unrecognized.</li> >+ [% ELSIF ( filerror.CORERR ) %]the image file is corrupted.</li> >+ [% ELSIF ( filerror.OPNERR ) %]Koha was unable to open the image for reading.</li> >+ [% ELSIF ( filerror.OVRSIZ ) %]the image file is too big.</li> >+ [% ELSIF ( filerror.CRDFIL ) %]the [% filerror.CRDFIL %] is missing.</li> >+ [% ELSE %]of an unknown error. Please refer to the error log for more details.</li>[% END %] >+ [% END %] >+ [% ELSE %] imported successfully.</li> >+ [% END %] >+ [% END %] >+ </ul> >+ [% END %] >+ >+ </div> >+ >+ <a id="uploadmore" href="/cgi-bin/koha/tools/upload-cover-image.pl">Upload More Images</a> >+ <a id="doneupload" href="/cgi-bin/koha/tools/tools-home.pl">Return to Tools</a> >+ </div> >+[% ELSE %] >+ <div class="yui-b"> >+ <div class="yui-g"> >+ <div class="yui-u first"> >+ <h1>Upload Cover Images</h1> >+ [% IF ( ERRORS ) %] >+ <div class="dialog alert"> >+ [% FOREACH ERROR IN ERRORS %] >+ [% IF ( ERROR.NOTZIP ) %]<li><b>The upload file does not appear to be a zip file. The extension is not '.zip'.</b></li> >+ [% ELSIF ( ERROR.NOWRITETEMP ) %]<li><b>This script is not able to create/write to the necessary temporary directory.</b></li> >+ [% ELSIF ( ERROR.EMPTYUPLOAD ) %]<li><b>The upload file appears to be empty.</b></li> >+ [% ELSIF ( ERROR.OPNLINK ) %]<li><b>Cannot open [% ERROR.OPNLINK %] to read.<br />Please verify that it exists.</b></li> >+ [% ELSIF ( ERROR.OPNIMG ) %]<li><b>Cannot open [% ERROR.OPNIMG %] to read.<br />Please verify that it exists.</b></li> >+ [% ELSIF ( ERROR.DELERR ) %]<li><b>Unrecognized or missing field delimiter.<br />Please verify that you are using either a single quote or a tab.</b></li> >+ [% ELSIF ( ERROR.UZIPFAIL ) %]<li><b>[% ERROR.UZIPFAIL %] failed to unpack.<br />Please verify the integrity of the zip file and retry.</b></li> >+ [% ELSE %]<li><b>[% ERROR.CORERR %] An unknown error has occurred.<br />Please review the error log for more details.</b></li>[% END %] >+ [% END %] >+ </div> >+ [% END %] >+ <form method="post" action="/cgi-bin/koha/tools/upload-cover-image.pl" enctype="multipart/form-data"> >+ <fieldset class="brief"> >+ <div class="hint"><b>NOTE:</b> Only PNG, GIF, JPEG, XPM formats are supported.</div> >+ <ol class="radio"> >+ <li class="radio"> >+ <label for="zipfile"><input type="radio" id="zipfile" name="filetype" value="zip" checked="checked" /> zip file</label></li> >+ <li> >+ <label for="image"> >+ [% IF ( filetype == 'image' ) %]<input type="radio" id="image" name="filetype" value="image" checked="checked" />[% ELSE %]<input type="radio" id="image" name="filetype" value="image" />[% END %] >+ image file</label> >+ <ol> >+ <li> >+ <label for="uploadfile">Select the file to upload: </label><input type="file" id="uploadfile" name="uploadfile" /> >+ [% IF ( filetype == 'image' ) %]<span id="bibnum">[% ELSE %]<span id="bibnum" style="display: none">[% END %]<label for="biblionumber">Enter cover biblionumber: </label><input type="text" id="biblionumber" name="biblionumber" value="[% biblionumber %]" size="15" /></span> >+ </li> >+ </ol> >+ </li></ol> >+ </fieldset> >+ <fieldset class="action"> >+ <input type="hidden" name="op" value="Upload" /> >+ <input type="submit" value="Upload" class="submit" /> >+ <a href="/cgi-bin/koha/tools/tools-home.pl" class="cancel">Cancel</a> >+ </fieldset> >+ </form> >+ >+ </div> >+[% END %] >+ </div> >+ </div> >+</div> >+<div class="yui-b noprint"> >+ [% INCLUDE 'tools-menu.inc' %] >+</div> >+</div> >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt >index 8cba98b..13a9102 100755 >--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt >+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt >@@ -224,6 +224,7 @@ YAHOO.util.Event.onContentReady("furtherm", function () { > <div id="catalogue_detail_biblio"> > > <div id="bookcover"> >+ [% IF ( OPACLocalCoverImages ) %] <img src="/cgi-bin/koha/opac-coverimage.pl?bibnum=[% biblionumber %]" alt="No Local Cover Image" class="thumbnail" />[% ELSE %]<span class="no-image">No Local cover image available</span>[% END %] > [% IF ( OPACAmazonEnabled ) %][% IF ( OPACAmazonCoverImages ) %][% IF ( OPACurlOpenInNewWindow ) %]<a href="http://www.amazon[% AmazonTld %]/gp/reader/[% normalized_isbn %]/ref=sib_dp_pt/002-7879865-0184864#reader-link" target="_blank"><img border="0" src="http://images.amazon.com/images/P/[% normalized_isbn %].01.MZZZZZZZ.jpg" alt="Cover Image" /></a>[% ELSE %]<a href="http://www.amazon[% AmazonTld %]/gp/reader/[% normalized_isbn %]/ref=sib_dp_pt/002-7879865-0184864#reader-link"><img border="0" src="http://images.amazon.com/images/P/[% normalized_isbn %].01.MZZZZZZZ.jpg" alt="Cover Image" /></a>[% END %][% END %][% END %] > > [% IF ( SyndeticsEnabled ) %][% IF ( SyndeticsCoverImages ) %][% IF ( content_identifier_exists ) %][% IF ( using_https ) %] >diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt >index b7fbcb3..7a22884 100755 >--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt >+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt >@@ -528,6 +528,7 @@ $(document).ready(function(){ > </span> > </td><td> > <a class="p1" href="/cgi-bin/koha/opac-detail.pl?biblionumber=[% SEARCH_RESULT.biblionumber %]"> >+ [% IF ( OPACLocalCoverImages ) %] <img src="/cgi-bin/koha/opac-coverimage.pl?bibnum=[% SEARCH_RESULT.biblionumber %] alt="No Local Cover Image" class="thumbnail" />[% ELSE %]<span class="no-image">No Local cover image available</span>[% END %] > [% IF ( OPACAmazonEnabled ) %][% IF ( OPACAmazonCoverImages ) %][% IF ( SEARCH_RESULT.normalized_isbn ) %]<img src="http://images.amazon.com/images/P/[% SEARCH_RESULT.normalized_isbn %].01.TZZZZZZZ.jpg" alt="" class="thumbnail" />[% ELSE %]<span class="no-image">No cover image available</span>[% END %][% END %][% END %] > > [% IF ( SyndeticsEnabled ) %][% IF ( SyndeticsCoverImages ) %][% IF ( using_https ) %] >diff --git a/opac/opac-coverimage.pl b/opac/opac-coverimage.pl >new file mode 100755 >index 0000000..5ce86f0 >--- /dev/null >+++ b/opac/opac-coverimage.pl >@@ -0,0 +1,105 @@ >+#!/usr/bin/perl >+# >+# based on patronimage.pl >+# >+# 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 2 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, write to the Free Software Foundation, Inc., >+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. >+# >+# >+# >+ >+use strict; >+use warnings; >+ >+use CGI; #qw(:standard escapeHTML); >+use C4::Context; >+ >+$|=1; >+ >+my $DEBUG = 0; >+my $data = new CGI; >+my $biblionumber; >+ >+=head1 NAME >+ >+opac-coverimage.pl - Script for retrieving and formatting local cover images for display >+ >+=head1 SYNOPSIS >+ >+<img src="opac-coverimage.pl?bibnum= /> >+ >+=head1 DESCRIPTION >+ >+This script, when called from within HTML and passed a valid biblionumber, will retrieve the image data associated with that biblionumber if one exists, format it in proper HTML format and pass it back to be displayed. >+ >+=cut >+ >+if ($data->param('bibnum')) { >+ $biblionumber = $data->param('bibnum'); >+} else { >+ $biblionumber = shift; >+} >+ >+ >+warn "biblionumber passed in: $biblionumber" if $DEBUG; >+ >+my ($imagedata, $dberror) = GetCoverImage($biblionumber); >+ >+if ($dberror) { >+ warn "Database Error!"; >+ exit; >+} >+ >+# NOTE: Never dump the contents of $imagedata->{'patronimage'} via a warn to a log or nasty >+# things will result... you have been warned! >+ >+if ($imagedata) { >+ print $data->header (-type => $imagedata->{'mimetype'}, -'Cache-Control' => 'no-store', -Content_Length => length ($imagedata->{'imagefile'})), $imagedata->{'imagefile'}; >+ exit; >+} else { >+ warn "No image exists for $biblionumber"; >+ exit; >+} >+ >+=head2 GetCoverImage >+ >+ my ($imagedata, $dberror) = GetCoverImage($biblionumber); >+ >+Returns the mimetype and binary image data of the local cover image for the biblio with the supplied biblionumber. >+ >+=cut >+ >+sub GetCoverImage { >+ my ($biblionumber) = @_; >+ warn "Biblionumber passed to GetCoverImage is $biblionumber" if $DEBUG; >+ my $dbh = C4::Context->dbh; >+ my $query = 'SELECT mimetype, imagefile FROM bibliocoverimage WHERE biblionumber = ?'; >+ my $sth = $dbh->prepare($query); >+ $sth->execute($biblionumber); >+ my $imagedata = $sth->fetchrow_hashref; >+ warn "Database error!" if $sth->errstr; >+ return $imagedata, $sth->errstr; >+} >+ >+ >+exit; >+ >+=head1 AUTHOR >+ >+Chris Nighswonger cnighswonger <at> foundations <dot> edu >+ >+modified for local cover images by Koustubha Kale kmkale <at> anantcorp <dot> com >+ >+=cut >diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl >index d3c7e2a..8be033e 100755 >--- a/opac/opac-detail.pl >+++ b/opac/opac-detail.pl >@@ -681,6 +681,11 @@ if (scalar(@serialcollections) > 0) { > serialcollections => \@serialcollections); > } > >+# Local cover Images stuff >+if (C4::Context->preference("OPACLocalCoverImages")){ >+ $template->param(OPACLocalCoverImages => 1); >+} >+ > # Amazon.com Stuff > if ( C4::Context->preference("OPACAmazonEnabled") ) { > $template->param( AmazonTld => get_amazon_tld() ); >diff --git a/opac/opac-search.pl b/opac/opac-search.pl >index 716b164..83d0613 100755 >--- a/opac/opac-search.pl >+++ b/opac/opac-search.pl >@@ -611,6 +611,10 @@ for (my $i=0;$i<@servers;$i++) { > $template->param(SEARCH_RESULTS => \@newresults, > OPACItemsResultsDisplay => (C4::Context->preference("OPACItemsResultsDisplay") eq "itemdetails"?1:0), > ); >+ if (C4::Context->preference("OPACLocalCoverImages")){ >+ $template->param(OPACLocalCoverImages => 1); >+ $template->param(OPACLocalCoverImagesPriority => C4::Context->preference("OPACLocalCoverImagesPriority")); >+ } > ## Build the page numbers on the bottom of the page > my @page_numbers; > # total number of pages there will be >diff --git a/tools/upload-cover-image.pl b/tools/upload-cover-image.pl >new file mode 100755 >index 0000000..75eefa4 >--- /dev/null >+++ b/tools/upload-cover-image.pl >@@ -0,0 +1,341 @@ >+#!/usr/bin/perl >+# >+# >+# 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, >+# Suite 330, Boston, MA 02111-1307 USA >+# >+# >+# >+ >+#use strict; >+#use warnings; FIXME - Bug 2505 >+ >+use File::Temp; >+use File::Copy; >+use CGI; >+use GD; >+use C4::Context; >+use C4::Auth; >+use C4::Output; >+use C4::Debug; >+ >+my $input = new CGI; >+ >+my ($template, $loggedinuser, $cookie) >+ = get_template_and_user({template_name => "tools/upload-cover-image.tmpl", >+ query => $input, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { tools => '*'}, >+ debug => 0, >+ }); >+ >+my $filetype = $input->param('filetype'); >+my $biblionumber = $input->param('biblionumber'); >+my $uploadfilename = $input->param('uploadfile'); >+my $uploadfile = $input->upload('uploadfile'); >+my $op = $input->param('op'); >+ >+#FIXME: This code is really in the rough. The variables need to be re-scoped as the two subs depend on global vars to operate. >+# Other parts of this code could be optimized as well, I think. Perhaps the file upload could be done with YUI's upload >+# coded. -fbcit >+ >+$debug and warn "Params are: filetype=$filetype, biblionumber=$biblionumber, uploadfile=$uploadfilename"; >+ >+=head1 NAME >+ >+upload-cover-image.pl - Script for handling uploading of both single and bulk coverimages and importing them into the database. >+ >+=head1 SYNOPSIS >+ >+Copied from picture-upload.pl >+ >+=head1 DESCRIPTION >+ >+This script is called and presents the user with an interface allowing him/her to upload a single cover image or bulk cover images via a zip file. >+Files greater than 100K will be refused. Images should be 140x200 pixels. If they are larger they will be auto-resized to comply. >+ >+=cut >+ >+$debug and warn "Operation requested: $op"; >+ >+my ( $total, $handled, @counts, $tempfile, $tfh ); >+ >+if ( ($op eq 'Upload') && $uploadfile ) { # Case is important in these operational values as the template must use case to be visually pleasing! >+ my $dirname = File::Temp::tempdir( CLEANUP => 1); >+ $debug and warn "dirname = $dirname"; >+ my $filesuffix = $1 if $uploadfilename =~ m/(\..+)$/i; >+ ( $tfh, $tempfile ) = File::Temp::tempfile( SUFFIX => $filesuffix, UNLINK => 1 ); >+ $debug and warn "tempfile = $tempfile"; >+ my ( @directories, $errors ); >+ >+ $errors{'NOTZIP'} = 1 if ( $uploadfilename !~ /\.zip$/i && $filetype =~ m/zip/i ); >+ $errors{'NOWRITETEMP'} = 1 unless ( -w $dirname ); >+ $errors{'EMPTYUPLOAD'} = 1 unless ( length( $uploadfile ) > 0 ); >+ >+ if ( %errors ) { >+ $template->param( ERRORS => [ \%errors ] ); >+ } else { >+ while ( <$uploadfile> ) { >+ print $tfh $_; >+ } >+ close $tfh; >+ if ( $filetype eq 'zip' ) { >+ unless (system("unzip", $tempfile, '-d', $dirname) == 0) { >+ $errors{'UZIPFAIL'} = $uploadfilename; >+ $template->param( ERRORS => [ \%errors ] ); >+ output_html_with_http_headers $input, $cookie, $template->output; # This error is fatal to the import, so bail out here >+ exit; >+ } >+ push @directories, "$dirname"; >+ foreach $recursive_dir ( @directories ) { >+ opendir $dir, $recursive_dir; >+ while ( my $entry = readdir $dir ) { >+ push @directories, "$recursive_dir/$entry" if ( -d "$recursive_dir/$entry" and $entry !~ /^\./ ); >+ $debug and warn "$recursive_dir/$entry"; >+ } >+ closedir $dir; >+ } >+ my $results; >+ foreach my $dir ( @directories ) { >+ $results = handle_dir( $dir, $filesuffix ); >+ $handled++ if $results == 1; >+ } >+ $total = scalar @directories; >+ } else { #if ($filetype eq 'zip' ) >+ $results = handle_dir( $dirname, $filesuffix ); >+ $handled = 1; >+ $total = 1; >+ } >+ >+ if ( %$results || %errors ) { >+ $template->param( ERRORS => [ \%$results ] ); >+ } else { >+ my $filecount; >+ map {$filecount += $_->{count}} @counts; >+ $debug and warn "Total directories processed: $total"; >+ $debug and warn "Total files processed: $filecount"; >+ $template->param( >+ TOTAL => $total, >+ HANDLED => $handled, >+ COUNTS => \@counts, >+ TCOUNTS => ($filecount > 0 ? $filecount : undef), >+ ); >+ $template->param( biblionumber => $biblionumber ) if $biblionumber; >+ } >+ } >+} elsif ( ($op eq 'Upload') && !$uploadfile ) { >+ warn "Problem uploading file or no file uploaded."; >+ $template->param(biblionumber => $biblionumber); >+ $template->param(filetype => $filetype); >+} elsif ( $op eq 'Delete' ) { >+ my $dberror = RmBiblioImage($biblionumber); >+ $debug and warn "Cover image deleted for $biblionumber"; >+ warn "Database returned $dberror" if $dberror; >+} >+ >+output_html_with_http_headers $input, $cookie, $template->output; >+ >+ >+sub handle_dir { >+ my ( $dir, $suffix ) = @_; >+ my $source; >+ $debug and warn "Entering sub handle_dir; passed \$dir=$dir, \$suffix=$suffix"; >+ if ($suffix =~ m/zip/i) { # If we were sent a zip file, process any included data/idlink.txt files >+ my ( $file, $filename, $biblionumber ); >+ $debug and warn "Passed a zip file."; >+ opendir my $dirhandle, $dir; >+ while ( my $filename = readdir $dirhandle ) { >+ $file = "$dir/$filename" if ($filename =~ m/datalink\.txt/i || $filename =~ m/idlink\.txt/i); >+ } >+ unless (open (FILE, $file)) { >+ warn "Opening $dir/$file failed!"; >+ $errors{'OPNLINK'} = $file; >+ return $errors; # This error is fatal to the import of this directory contents, so bail and return the error to the caller >+ }; >+ >+ while (my $line = <FILE>) { >+ $debug and warn "Reading contents of $file"; >+ chomp $line; >+ $debug and warn "Examining line: $line"; >+ my $delim = ($line =~ /\t/) ? "\t" : ($line =~ /,/) ? "," : ""; >+ $debug and warn "Delimeter is \'$delim\'"; >+ unless ( $delim eq "," || $delim eq "\t" ) { >+ warn "Unrecognized or missing field delimeter. Please verify that you are using either a ',' or a 'tab'"; >+ $errors{'DELERR'} = 1; # This error is fatal to the import of this directory contents, so bail and return the error to the caller >+ return $errors; >+ } >+ ($biblionumber, $filename) = split $delim, $line; >+ $biblionumber =~ s/[\"\r\n]//g; # remove offensive characters >+ $filename =~ s/[\"\r\n\s]//g; >+ $debug and warn "Biblionumber: $biblionumber Filename: $filename"; >+ $source = "$dir/$filename"; >+ %counts = handle_file($biblionumber, $source, %counts); >+ } >+ close FILE; >+ closedir ($dirhandle); >+ } else { >+ $source = $tempfile; >+ %counts = handle_file($biblionumber, $source, %counts); >+ } >+push @counts, \%counts; >+return 1; >+} >+ >+sub handle_file { >+ my ($biblionumber, $source, %count) = @_; >+ $debug and warn "Entering sub handle_file; passed \$biblionumber=$biblionumber, \$source=$source"; >+ $count{filenames} = () if !$count{filenames}; >+ $count{source} = $source if !$count{source}; >+ if ($biblionumber && $source) { # Now process any imagefiles >+ my %filerrors; >+ my $filename; >+ if ($filetype eq 'image') { >+ $filename = $uploadfilename; >+ } else { >+ $filename = $1 if ($source =~ /\/([^\/]+)$/); >+ } >+ $debug and warn "Source: $source"; >+ my $size = (stat($source))[7]; >+ if ($size > 550000) { # This check is necessary even with image resizing to avoid possible security/performance issues... >+ $filerrors{'OVRSIZ'} = 1; >+ push my @filerrors, \%filerrors; >+ push @{ $count{filenames} }, { filerrors => \@filerrors, source => $filename, biblionumber => $biblionumber }; >+ $template->param( ERRORS => 1 ); >+ return %count; # this one is fatal so bail here... >+ } >+ my ($srcimage, $image); >+ if (open (IMG, "$source")) { >+ $srcimage = GD::Image->new(*IMG); >+ close (IMG); >+ if (defined $srcimage) { >+ my $mimetype = 'image/png'; # GD autodetects three basic image formats: PNG, JPEG, XPM; we will convert all to PNG which is lossless... >+ # Check the pixel size of the image we are about to import... >+ my ($width, $height) = $srcimage->getBounds(); >+ $debug and warn "$filename is $width pix X $height pix."; >+ if ($width > 200 || $height > 300) { # MAX pixel dims are 200 X 300... >+ $debug and warn "$filename exceeds the maximum pixel dimensions of 200 X 300. Resizing..."; >+ my $percent_reduce; # Percent we will reduce the image dimensions by... >+ if ($width > 200) { >+ $percent_reduce = sprintf("%.5f",(140/$width)); # If the width is oversize, scale based on width overage... >+ } else { >+ $percent_reduce = sprintf("%.5f",(200/$height)); # otherwise scale based on height overage. >+ } >+ my $width_reduce = sprintf("%.0f", ($width * $percent_reduce)); >+ my $height_reduce = sprintf("%.0f", ($height * $percent_reduce)); >+ $debug and warn "Reducing $filename by " . ($percent_reduce * 100) . "\% or to $width_reduce pix X $height_reduce pix"; >+ $image = GD::Image->new($width_reduce, $height_reduce, 1); #'1' creates true color image... >+ $image->copyResampled($srcimage,0,0,0,0,$width_reduce,$height_reduce,$width,$height); >+ $imgfile = $image->png(); >+ $debug and warn "$filename is " . length($imgfile) . " bytes after resizing."; >+ undef $image; >+ undef $srcimage; # This object can get big... >+ } else { >+ $image = $srcimage; >+ $imgfile = $image->png(); >+ $debug and warn "$filename is " . length($imgfile) . " bytes."; >+ undef $image; >+ undef $srcimage; # This object can get big... >+ } >+ $debug and warn "Image is of mimetype $mimetype"; >+ my $dberror = PutCoverImage($biblionumber,$mimetype, $imgfile) if $mimetype; >+ if ( !$dberror && $mimetype ) { # Errors from here on are fatal only to the import of a particular image, so don't bail, just note the error and keep going >+ $count{count}++; >+ push @{ $count{filenames} }, { source => $filename, biblionumber => $biblionumber }; >+ } elsif ( $dberror ) { >+ warn "Database returned error: $dberror"; >+ ($dberror =~ /coverimage_fk1/) ? $filerrors{'IMGEXISTS'} = 1 : $filerrors{'DBERR'} = 1; >+ push my @filerrors, \%filerrors; >+ push @{ $count{filenames} }, { filerrors => \@filerrors, source => $filename, biblionumber => $biblionumber }; >+ $template->param( ERRORS => 1 ); >+ } elsif ( !$mimetype ) { >+ warn "Unable to determine mime type of $filename. Please verify mimetype."; >+ $filerrors{'MIMERR'} = 1; >+ push my @filerrors, \%filerrors; >+ push @{ $count{filenames} }, { filerrors => \@filerrors, source => $filename, biblionumber => $biblionumber }; >+ $template->param( ERRORS => 1 ); >+ } >+ } else { >+ warn "Contents of $filename corrupted!"; >+ # $count{count}--; >+ $filerrors{'CORERR'} = 1; >+ push my @filerrors, \%filerrors; >+ push @{ $count{filenames} }, { filerrors => \@filerrors, source => $filename, biblionumber => $biblionumber }; >+ $template->param( ERRORS => 1 ); >+ } >+ } else { >+ warn "Opening $dir/$filename failed!"; >+ $filerrors{'OPNERR'} = 1; >+ push my @filerrors, \%filerrors; >+ push @{ $count{filenames} }, { filerrors => \@filerrors, source => $filename, biblionumber => $biblionumber }; >+ $template->param( ERRORS => 1 ); >+ } >+ } else { # The need for this seems a bit unlikely, however, to maximize error trapping it is included >+ warn "Missing " . ($biblionumber ? "filename" : ($filename ? "biblionumber" : "biblionumber and filename")); >+ $filerrors{'CRDFIL'} = ($biblionumber ? "filename" : ($filename ? "biblionumber" : "biblionumber and filename")); >+ push my @filerrors, \%filerrors; >+ push @{ $count{filenames} }, { filerrors => \@filerrors, source => $filename, biblionumber => $biblionumber }; >+ $template->param( ERRORS => 1 ); >+ } >+ return (%count); >+} >+=head2 PutCoverImage >+ >+ PutCoverImage($biblionumber, $mimetype, $imgfile); >+ >+Stores cover binary image data and mimetype in database. >+NOTE: This function is good for updating images as well as inserting new images in the database. >+ >+=cut >+ >+sub PutCoverImage { >+ my ($biblionumber, $mimetype, $imgfile) = @_; >+ warn "Parameters passed in: Biblionumber=$biblionumber, Mimetype=$mimetype, " . ($imgfile ? "Imagefile" : "No Imagefile") if $debug; >+ my $dbh = C4::Context->dbh; >+ my $query = "INSERT INTO bibliocoverimage (biblionumber, mimetype, imagefile) VALUES (?,?,?) ON DUPLICATE KEY UPDATE imagefile = ?;"; >+ my $sth = $dbh->prepare($query); >+ $sth->execute($biblionumber,$mimetype,$imgfile,$imgfile); >+ warn "Error returned inserting $biblionumber.$mimetype." if $sth->errstr; >+ return $sth->errstr; >+} >+ >+=head2 RmCoverImage >+ >+ my ($dberror) = RmCoverImage($biblionumber); >+ >+Removes the image for the cover with the supplied biblionumber. >+ >+=cut >+ >+sub RmCoverImage { >+ my ($biblionumber) = @_; >+ warn "Biblionumber passed to RmBiblioImage is $biblionumber" if $debug; >+ my $dbh = C4::Context->dbh; >+ my $query = "DELETE FROM bibliocoverimage WHERE biblionumber = ?;"; >+ my $sth = $dbh->prepare($query); >+ $sth->execute($biblionumber); >+ my $dberror = $sth->errstr; >+ warn "Database error!" if $sth->errstr; >+ return $dberror; >+} >+ >+=head1 AUTHORS >+ >+Copied from picture-upload.pl >+ >+Database storage, single coverimage upload option, and extensive error trapping contributed by Chris Nighswonger cnighswonger <at> foundations <dot> edu >+Image scaling/resizing contributed by the same. >+ >+=cut >-- >1.7.5.4 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 1633
:
6242
|
6699
|
6706
|
6712
|
6745
|
6746
|
6747
|
6748
|
6749
|
6750
|
6755
|
6756
|
6758
|
6759
|
6764
|
6765
|
6766
|
6785
|
6786
|
6787
|
6788
|
6791
|
6823
|
6973
|
6974
|
6975
|
6976
|
6977
|
6978
|
6979
|
6980
|
6981
|
6982
|
6983
|
7146
|
7147
|
7148
|
7149
|
7150
|
7151
|
7152
|
7153
|
7156
|
7219
|
7267
|
7268
|
7270
|
7271
|
7272
|
7273
|
7274
|
7275
|
7312
|
7315
|
7320
|
7324
|
7325
|
7334