Bugzilla – Attachment 7146 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]
Bug 1633: [SIGNED-OFF] Add support for uploading images to Koha
Bug-1633-SIGNED-OFF-Add-support-for-uploading-imag.patch (text/plain), 30.35 KB, created by
Koustubha Kale
on 2012-01-14 08:49:19 UTC
(
hide
)
Description:
Bug 1633: [SIGNED-OFF] Add support for uploading images to Koha
Filename:
MIME Type:
Creator:
Koustubha Kale
Created:
2012-01-14 08:49:19 UTC
Size:
30.35 KB
patch
obsolete
>From 2ae4b206f38d314acef32dd5b7faa029993792b1 Mon Sep 17 00:00:00 2001 >From: Jared Camins-Esakov <jcamins@cpbibliography.com> >Date: Tue, 13 Dec 2011 08:20:41 -0500 >Subject: [PATCH] Bug 1633: [SIGNED-OFF] Add support for uploading images to > Koha >Content-Type: text/plain; charset="utf-8" > >A frequently-requested feature for Koha, especially by special libraries, is >the ability to upload local cover images into Koha. > >This patch adds a bibliocoverimage table, and image handling code in the >C4::Images module. Key features of the implementation include: >1. The ability to have multiple cover images for a biblio >2. Handling for "full size" (800x600) and thumbnail-size (200x140) images >3. Uploading images directly from the record view > >The image display functionality by Koustubha Kale of Anant Corporation will >follow in a second patch. > >Special thanks to Koustubha Kale and Anant Corporation for the initial >implementation of local cover images, and to Chris Nighswonger of Foundation >Bible College for his prior work on patron images. > >Signed-off-by: Jared Camins-Esakov <jcamins@cpbibliography.com> >Signed-off-by: Magnus Enger <magnus@enger.priv.no> >Will add comments on Bugzilla. > >Patch failed to apply because installer/data/mysql/sysprefs.sql had changed in master. >Corrected the same with this new patch. >--- > C4/Auth.pm | 5 +- > C4/Images.pm | 155 ++++++++++++++++++ > C4/UploadedFile.pm | 18 ++ > .../data/mysql/atomicupdate/local_cover_images.pl | 20 +++ > .../data/mysql/en/mandatory/userpermissions.sql | 1 + > installer/data/mysql/kohastructure.sql | 15 ++ > installer/data/mysql/sysprefs.sql | 3 + > .../intranet-tmpl/prog/en/includes/cat-toolbar.inc | 3 +- > .../intranet-tmpl/prog/en/includes/tools-menu.inc | 3 + > .../admin/preferences/enhanced_content.pref | 19 +++ > .../prog/en/modules/tools/tools-home.tt | 5 + > .../prog/en/modules/tools/upload-images.tt | 130 +++++++++++++++ > tools/upload-cover-image.pl | 169 ++++++++++++++++++++ > 13 files changed, 544 insertions(+), 2 deletions(-) > create mode 100644 C4/Images.pm > create mode 100755 installer/data/mysql/atomicupdate/local_cover_images.pl > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt > create mode 100755 tools/upload-cover-image.pl > >diff --git a/C4/Auth.pm b/C4/Auth.pm >index bbe472b..c7a27b5 100755 >--- a/C4/Auth.pm >+++ b/C4/Auth.pm >@@ -389,7 +389,9 @@ sub get_template_and_user { > virtualshelves => C4::Context->preference("virtualshelves"), > StaffSerialIssueDisplayCount => C4::Context->preference("StaffSerialIssueDisplayCount"), > NoZebra => C4::Context->preference('NoZebra'), >- EasyAnalyticalRecords => C4::Context->preference('EasyAnalyticalRecords'), >+ EasyAnalyticalRecords => C4::Context->preference('EasyAnalyticalRecords'), >+ LocalCoverImages => C4::Context->preference('LocalCoverImages'), >+ AllowMultipleCovers => C4::Context->preference('AllowMultipleCovers'), > ); > } > else { >@@ -494,6 +496,7 @@ sub get_template_and_user { > SyndeticsAwards => C4::Context->preference("SyndeticsAwards"), > SyndeticsSeries => C4::Context->preference("SyndeticsSeries"), > SyndeticsCoverImageSize => C4::Context->preference("SyndeticsCoverImageSize"), >+ OPACLocalCoverImages => C4::Context->preference("OPACLocalCoverImages"), > ); > > $template->param(OpacPublic => '1') if ($user || C4::Context->preference("OpacPublic")); >diff --git a/C4/Images.pm b/C4/Images.pm >new file mode 100644 >index 0000000..99d0198 >--- /dev/null >+++ b/C4/Images.pm >@@ -0,0 +1,155 @@ >+package C4::Images; >+use strict; >+use warnings; >+use 5.010; >+ >+use C4::Context; >+use GD; >+ >+use vars qw($debug $VERSION @ISA @EXPORT); >+ >+BEGIN { >+ # set the version for version checking >+ $VERSION = 3.03; >+ require Exporter; >+ @ISA = qw(Exporter); >+ @EXPORT = qw( >+ &PutImage >+ &RetrieveImage >+ &ListImagesForBiblio >+ &DelImage >+ ); >+ $debug = $ENV{KOHA_DEBUG} || $ENV{DEBUG} || 0; >+} >+ >+=head2 PutImage >+ >+ PutImage($biblionumber, $srcimage, $replace); >+ >+Stores binary image data and thumbnail in database, optionally replacing existing images for the given biblio. >+ >+=cut >+ >+sub PutImage { >+ my ($biblionumber, $srcimage, $replace) = @_; >+ >+ return -1 unless defined($srcimage); >+ >+ if ($replace) { >+ foreach (ListImagesForBiblio($biblionumber)) { >+ DelImage($_); >+ } >+ } >+ >+ my $dbh = C4::Context->dbh; >+ my $query = "INSERT INTO biblioimages (biblionumber, mimetype, imagefile, thumbnail) 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... >+# 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; >+} >+ >+=head2 RetrieveImage >+ my ($imagedata, $error) = RetrieveImage($imagenumber); >+ >+Retrieves the specified image. >+ >+=cut >+ >+sub RetrieveImage { >+ my ($imagenumber) = @_; >+ >+ my $dbh = C4::Context->dbh; >+ my $query = 'SELECT mimetype, imagefile, thumbnail FROM biblioimages WHERE imagenumber = ?'; >+ my $sth = $dbh->prepare($query); >+ $sth->execute($imagenumber); >+ my $imagedata = $sth->fetchrow_hashref; >+ if ($sth->err) { >+ warn "Database error!"; >+ return undef; >+ } else { >+ return $imagedata; >+ } >+} >+ >+=head2 ListImagesForBiblio >+ my (@images) = ListImagesForBiblio($biblionumber); >+ >+Gets a list of all images associated with a particular biblio. >+ >+=cut >+ >+ >+sub ListImagesForBiblio { >+ my ($biblionumber) = @_; >+ >+ my @imagenumbers; >+ my $dbh = C4::Context->dbh; >+ my $query = 'SELECT imagenumber FROM biblioimages WHERE biblionumber = ?'; >+ my $sth = $dbh->prepare($query); >+ $sth->execute($biblionumber); >+ warn "Database error!" if $sth->errstr; >+ if (!$sth->errstr && $sth->rows > 0) { >+ while (my $row = $sth->fetchrow_hashref) { >+ push @imagenumbers, $row->{'imagenumber'}; >+ } >+ return @imagenumbers; >+ } else { >+ return undef; >+ } >+} >+ >+=head2 DelImage >+ >+ my ($dberror) = DelImage($imagenumber); >+ >+Removes the image with the supplied imagenumber. >+ >+=cut >+ >+sub DelImage { >+ my ($imagenumber) = @_; >+ warn "Imagenumber passed to DelImage is $imagenumber" if $debug; >+ my $dbh = C4::Context->dbh; >+ my $query = "DELETE FROM biblioimages WHERE imagenumber = ?;"; >+ my $sth = $dbh->prepare($query); >+ $sth->execute($imagenumber); >+ my $dberror = $sth->errstr; >+ warn "Database error!" if $sth->errstr; >+ return $dberror; >+} >+ >+sub _scale_image { >+ my ($image, $maxwidth, $maxheight) = @_; >+ my ($width, $height) = $image->getBounds(); >+ $debug and warn "image is $width pix X $height pix."; >+ if ($width > $maxwidth || $height > $maxheight) { >+# $debug and warn "$filename exceeds the maximum pixel dimensions of $maxwidth X $maxheight. Resizing..."; >+ my $percent_reduce; # Percent we will reduce the image dimensions by... >+ if ($width > $maxwidth) { >+ $percent_reduce = sprintf("%.5f",($maxwidth/$width)); # If the width is oversize, scale based on width overage... >+ } else { >+ $percent_reduce = sprintf("%.5f",($maxheight/$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 image by " . ($percent_reduce * 100) . "\% or to $width_reduce pix X $height_reduce pix"; >+ my $newimage = GD::Image->new($width_reduce, $height_reduce, 1); #'1' creates true color image... >+ $newimage->copyResampled($image,0,0,0,0,$width_reduce,$height_reduce,$width,$height); >+ return $newimage; >+ } else { >+ return $image; >+ } >+} >+ >+1; >diff --git a/C4/UploadedFile.pm b/C4/UploadedFile.pm >index da29c1f..e8c9080 100644 >--- a/C4/UploadedFile.pm >+++ b/C4/UploadedFile.pm >@@ -159,6 +159,24 @@ sub name { > } > } > >+=head2 filename >+ >+ my $filename = $uploaded_file->filename(); >+ >+Accessor method for the name by which the file is to be known. >+ >+=cut >+ >+sub filename { >+ my $self = shift; >+ if (@_) { >+ $self->{'tmp_file_name'} = shift; >+ $self->_serialize(); >+ } else { >+ return $self->{'tmp_file_name'}; >+ } >+} >+ > =head2 max_size > > my $max_size = $uploaded_file->max_size(); >diff --git a/installer/data/mysql/atomicupdate/local_cover_images.pl b/installer/data/mysql/atomicupdate/local_cover_images.pl >new file mode 100755 >index 0000000..a698e7f >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/local_cover_images.pl >@@ -0,0 +1,20 @@ >+#! /usr/bin/perl >+use strict; >+use warnings; >+use C4::Context; >+my $dbh=C4::Context->dbh; >+ >+$dbh->do( q|CREATE TABLE `biblioimages` ( >+ `imagenumber` int(11) NOT NULL AUTO_INCREMENT, >+ `biblionumber` int(11) NOT NULL, >+ `mimetype` varchar(15) NOT NULL, >+ `imagefile` mediumblob NOT NULL, >+ `thumbnail` mediumblob NOT NULL, >+ PRIMARY KEY (`imagenumber`), >+ 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 images on OPAC search and details pages.','1','YesNo')|); >+$dbh->do( q|INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('LocalCoverImages','0','Display local cover images on intranet search and details pages.','1','YesNo')|); >+$dbh->do( q|INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('AllowMultipleCovers','0','Allow multiple cover images to be attached to each bibliographic record.','1','YesNo')|); >+$dbh->do( q|INSERT INTO permissions (module_bit, code, description) VALUES (13, 'upload_local_cover_images', 'Upload local cover images')|); >+print "Upgrade done (Added support for local cover images)\n"; >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 4fd4106..6be863a 100644 >--- a/installer/data/mysql/kohastructure.sql >+++ b/installer/data/mysql/kohastructure.sql >@@ -2668,6 +2668,21 @@ 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` ( >+ `imagenumber` int(11) NOT NULL AUTO_INCREMENT, >+ `biblionumber` int(11) NOT NULL, >+ `mimetype` varchar(15) NOT NULL, >+ `imagefile` mediumblob NOT NULL, >+ `thumbnail` mediumblob NOT NULL, >+ PRIMARY KEY (`imagenumber`), >+ 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 918df5c..2a59b47 100755 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -330,3 +330,6 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES > 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 ('CircAutoPrintQuickSlip', '1', 'Choose what should happen when an empty barcode field is submitted in circulation: Display a print quick slip window or Clear the screen.',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'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('LocalCoverImages','0','Display local cover images on intranet details pages.','1','YesNo'); >+INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('AllowMultipleCovers','0','Allow multiple cover images to be attached to each bibliographic record.','1','YesNo'); >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc >index 413d7f4..4276133 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc >@@ -101,7 +101,8 @@ function confirm_items_deletion() { > [% IF ( CAN_user_editcatalogue_edit_catalogue ) %]{ text: _("Edit Record"), url: "/cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=[% biblionumber %]&frameworkcode=&op=" },[% END %] > [% IF ( CAN_user_editcatalogue_edit_items ) %]{ text: _("Edit Items"), url: "/cgi-bin/koha/cataloguing/additem.pl?biblionumber=[% biblionumber %]" },[% END %] > [% IF ( CAN_user_editcatalogue_edit_items ) %]{ text: _("Attach Item"), url: "/cgi-bin/koha/cataloguing/moveitem.pl?biblionumber=[% biblionumber %]" },[% END %] >- [% IF ( EasyAnalyticalRecords ) %][% IF ( CAN_user_editcatalogue_edit_items ) %]{ text: _("Link to Host Item"), url: "/cgi-bin/koha/cataloguing/linkitem.pl?biblionumber=[% biblionumber %]" },[% END %][% END %] >+ [% IF ( EasyAnalyticalRecords ) %][% IF ( CAN_user_editcatalogue_edit_items ) %]{ text: _("Link to Host Item"), url: "/cgi-bin/koha/cataloguing/linkitem.pl?biblionumber=[% biblionumber %]" },[% END %][% END %] >+ [% IF ( LocalCoverImages ) %][% IF ( CAN_user_tools_upload_local_cover_images ) %]{ text: _("Upload Image"), url: "/cgi-bin/koha/tools/upload-cover-image.pl?biblionumber=[% biblionumber %]&filetype=image" },[% END %][% END %] > [% IF ( CAN_user_editcatalogue_edit_catalogue ) %]{ text: _("Edit as New (Duplicate)"), url: "/cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=[% biblionumber %]&frameworkcode=&op=duplicate" },[% END %] > [% IF ( CAN_user_editcatalogue_edit_catalogue ) %]{ text: _("Replace Record via Z39.50"), onclick: {fn: PopupZ3950 } },[% END %] > [% IF ( CAN_user_editcatalogue_edit_catalogue ) %]{ text: _("Delete Record"), onclick: {fn: confirm_deletion }[% IF ( count ) %],id:'disabled'[% END %] },[% END %] >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..f5828ae 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,22 @@ Enhanced Content: > - pref: TagsExternalDictionary > class: file > - on the server to be approved without moderation. >+ Local Cover Images: >+ - >+ - pref: LocalCoverImages >+ choices: >+ yes: Display >+ no: "Don't display" >+ - local cover images on intranet search and details pages. >+ - >+ - pref: OPACLocalCoverImages >+ choices: >+ yes: Display >+ no: "Don't display" >+ - local cover images on OPAC search and details pages. >+ - >+ - pref: AllowMultipleCovers >+ choices: >+ yes: Allow >+ no: "Don't allow" >+ - multiple images to be attached to each bibliographic record. >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 05bdb47..b71a1ee 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-images.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt >new file mode 100644 >index 0000000..36d6d37 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt >@@ -0,0 +1,130 @@ >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Tools › Upload Images</title> >+[% INCLUDE 'doc-head-close.inc' %] >+[% INCLUDE 'file-upload.inc' %] >+[% INCLUDE 'background-job.inc' %] >+<style type="text/css"> >+ #uploadpanel,#fileuploadstatus,#fileuploadfailed,#jobpanel,#jobstatus,#jobfailed { display : none; } >+ #fileuploadstatus,#jobstatus { margin:.4em; } >+ #fileuploadprogress,#jobprogress{ width:150px;height:10px;border:1px solid #666;background:url('/intranet-tmpl/prog/img/progress.png') -300px 0px no-repeat; }</style> >+<script type="text/javascript"> >+//<![CDATA[ >+$(document).ready(function(){ >+ $("#processfile").hide(); >+ $("#zipfile").click(function(){ >+ $("#bibnum").hide(); >+ }); >+ $("#image").click(function(){ >+ $("#bibnum").show(); >+ }); >+}); >+function CheckForm(f) { >+ if ($("#fileToUpload").value == '') { >+ alert(_('Please upload a file first.')); >+ } else { >+ return submitBackgroundJob(f); >+ } >+ return false; >+} >+ >+//]]> >+</script> >+</head> >+<body> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'cat-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> › [% IF ( uploadimage ) %]<a href="/cgi-bin/koha/tools/upload-cover-image.pl">Upload Local Cover Image</a> › Upload Results[% ELSE %]Upload Local Cover Image[% END %]</div> >+ >+<div id="doc3" class="yui-t2"> >+ >+ <div id="bd"> >+ <div id="yui-main"> >+ <div class="yui-b"> >+ >+<h1>Upload Local Cover Image</h1> >+[% IF ( uploadimage ) %] >+<p>Image upload results :</p> >+<ul> >+ <li>[% total %] images found</li> >+ [% IF ( error ) %] >+ <div class="dialog alert"> >+ [% IF ( error == 'UZIPFAIL' ) %]<p><b>Failed to unzip archive.<br />Please ensure you are uploading a valid zip file and try again.</b></p> >+ [% ELSIF ( error == 'OPNLINK' ) %]<p><b>Cannot open folder index (idlink.txt or datalink.txt) to read.<br />Please verify that it exists.</b></p> >+ [% ELSIF ( error == 'OPNIMG' ) %]<p><b>Cannot process file as an image.<br />Please ensure you only upload GIF, JPEG, PNG, or XPM images.</b></p> >+ [% ELSIF ( error == 'DELERR' ) %]<p><b>Unrecognized or missing field delimiter.<br />Please verify that you are using either a single quote or a tab.</b></p> >+ [% ELSIF ( error == 'DBERR' ) %]<p><b>Unable to save image to database.</b></p> >+ [% ELSE %]<p><b>An unknown error has occurred.<br />Please review the error log for more details.</b></p>[% END %] >+ </div> >+ </li> >+ [% END %] >+ <li><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblionumber %]">View final record</a></li> >+ <li><a href="/cgi-bin/koha/tools/tools-home.pl">Back</a></li> >+</ul> >+<hr /> >+[% END %] >+<ul> >+ <li>Select an image file or ZIP file to upload. The tool will accept images in GIF, JPEG, PNG, and XPM formats.</li> >+</ul> >+<form method="post" action="[% SCRIPT_NAME %]" id="uploadfile" enctype="multipart/form-data"> >+<fieldset class="rows" id="uploadform"> >+<legend>Upload images</legend> >+<ol> >+ <li> >+ <div id="fileuploadform"> >+ <label for="fileToUpload">Select the file to upload: </label> >+ <input type="file" id="fileToUpload" name="fileToUpload" /> >+ </div> </li> >+</ol> >+ <fieldset class="action"><button class="submit" onclick="return ajaxFileUpload();">Upload file</button></fieldset> >+</fieldset> >+ >+ <div id="uploadpanel"><div id="fileuploadstatus">Upload progress: <div id="fileuploadprogress"></div> <span id="fileuploadpercent">0</span>%</div> >+ <div id="fileuploadfailed"></div></div> >+</form> >+ >+ <form method="post" id="processfile" action="[% SCRIPT_NAME %]" enctype="multipart/form-data"> >+<fieldset class="rows"> >+ <input type="hidden" name="uploadedfileid" id="uploadedfileid" value="" /> >+ <input type="hidden" name="runinbackground" id="runinbackground" value="" /> >+ <input type="hidden" name="completedJobID" id="completedJobID" value="" /> >+ </fieldset> >+ <fieldset class="rows"> >+ <legend>File type</legend> >+ <ol> >+ <li class="radio"> >+ <input type="radio" id="zipfile" name="filetype" value="zip" [% IF (filetype != 'image' ) %]checked="checked"[% END %] /> >+ <label for="zipfile">ZIP file</label> >+ </li> >+ <li class="radio"> >+ <input type="radio" id="image" name="filetype" value="image" [% IF (filetype == 'image' ) %]checked="checked"[% END %] /> >+ <label for="imagefile">Image file</label> >+ </li> >+ <li class="radio"> >+ [% 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> >+ </fieldset> >+ <fieldset class="rows"> >+ <legend>Options</legend> >+ <ol> >+ <li class="checkbox"> >+ <input type="checkbox" id="replace" name="replace" [% IF AllowMultipleCovers == 0 %]checked="checked" disabled="disabled"[% END %] /> >+ <label for="replace">Replace existing covers</label> >+ </li> >+ </ol> >+ </fieldset> >+ <fieldset class="action"><input type="submit" value="Process images" /></fieldset> >+ >+ <div id="jobpanel"><div id="jobstatus">Job progress: <div id="jobprogress"></div> <span id="jobprogresspercent">0</span>%</div> >+ <div id="jobfailed"></div></div> >+ >+</form> >+ >+</div> >+</div> >+<div class="yui-b"> >+[% INCLUDE 'tools-menu.inc' %] >+</div> >+</div> >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/tools/upload-cover-image.pl b/tools/upload-cover-image.pl >new file mode 100755 >index 0000000..ac9661e >--- /dev/null >+++ b/tools/upload-cover-image.pl >@@ -0,0 +1,169 @@ >+#!/usr/bin/perl >+# >+# Copyright 2011 C & P Bibliography Services >+# >+# 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 >+# >+# >+# >+=head1 NAME >+ >+upload-cover-image.pl - Script for handling uploading of both single and bulk coverimages and importing them into the database. >+ >+=head1 SYNOPSIS >+ >+upload-cover-image.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. >+Images will be resized into thumbnails of 140x200 pixels and larger images of >+800x600 pixels. If the images that are uploaded are larger, they will be >+resized, maintaining aspect ratio. >+ >+=cut >+ >+ >+use strict; >+use warnings; >+ >+use File::Temp; >+use CGI; >+use GD; >+use C4::Context; >+use C4::Auth; >+use C4::Output; >+use C4::Images; >+use C4::UploadedFile; >+ >+my $debug = 1; >+ >+my $input = new CGI; >+ >+my $fileID=$input->param('uploadedfileid'); >+my ($template, $loggedinuser, $cookie) >+ = get_template_and_user({template_name => "tools/upload-images.tmpl", >+ query => $input, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { tools => 'upload_cover_images'}, >+ debug => 0, >+ }); >+ >+my $filetype = $input->param('filetype'); >+my $biblionumber = $input->param('biblionumber'); >+my $uploadfilename = $input->param('uploadfile'); >+my $replace = $input->param('replace'); >+my $op = $input->param('op'); >+my %cookies = parse CGI::Cookie($cookie); >+my $sessionID = $cookies{'CGISESSID'}->value; >+ >+my $error; >+ >+$template->{VARS}->{'filetype'} = $filetype; >+$template->{VARS}->{'biblionumber'} = $biblionumber; >+ >+my $total = 0; >+ >+if ($fileID) { >+ my $uploaded_file = C4::UploadedFile->fetch($sessionID, $fileID); >+ if ($filetype eq 'image') { >+ my $fh = $uploaded_file->fh(); >+ my $srcimage = GD::Image->new($fh); >+ if (defined $srcimage) { >+ my $dberror = PutImage($biblionumber, $srcimage, $replace); >+ if ($dberror) { >+ $error = 'DBERR'; >+ } else { >+ $total = 1; >+ } >+ } else { >+ $error = 'OPNIMG'; >+ } >+ undef $srcimage; >+ } else { >+ my $filename = $uploaded_file->filename(); >+ my $dirname = File::Temp::tempdir( CLEANUP => 1); >+ unless (system("unzip", $filename, '-d', $dirname) == 0) { >+ $error = 'UZIPFAIL'; >+ } else { >+ my @directories; >+ push @directories, "$dirname"; >+ foreach my $recursive_dir ( @directories ) { >+ my $dir; >+ opendir $dir, $recursive_dir; >+ while ( my $entry = readdir $dir ) { >+ push @directories, "$recursive_dir/$entry" if ( -d "$recursive_dir/$entry" and $entry !~ /^[._]/ ); >+ } >+ closedir $dir; >+ } >+ foreach my $dir ( @directories ) { >+ my $file; >+ if ( -e "$dir/idlink.txt" ) { >+ $file = "$dir/idlink.txt"; >+ } elsif ( -e "$dir/datalink.txt" ) { >+ $file = "$dir/datalink.txt"; >+ } else { >+ next; >+ } >+ if (open (FILE, $file)) { >+ while (my $line = <FILE>) { >+ 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'"; >+ $error = 'DELERR'; >+ } else { >+ ($biblionumber, $filename) = split $delim, $line; >+ $biblionumber =~ s/[\"\r\n]//g; # remove offensive characters >+ $filename =~ s/[\"\r\n\s]//g; >+ my $srcimage = GD::Image->new("$dir/$filename"); >+ if (defined $srcimage) { >+ $total++; >+ my $dberror = PutImage($biblionumber, $srcimage, $replace); >+ if ($dberror) { >+ $error = 'DBERR'; >+ } >+ } else { >+ $error = 'OPNIMG'; >+ } >+ undef $srcimage; >+ } >+ } >+ close(FILE); >+ } else { >+ $error = 'OPNLINK'; >+ } >+ } >+ } >+ } >+ $template->{VARS}->{'total'} = $total; >+ $template->{VARS}->{'uploadimage'} = 1; >+ $template->{VARS}->{'error'} = $error; >+ $template->{VARS}->{'biblionumber'} = $biblionumber; >+} >+ >+output_html_with_http_headers $input, $cookie, $template->output; >+ >+exit 0; >+ >+=head1 AUTHORS >+ >+Written by Jared Camins-Esakov of C & P Bibliography Services, in part based on >+code by Koustubha Kale of Anant Corporation and Chris Nighswonger of Foundation >+Bible College. >+ >+=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