View | Details | Raw Unified | Return to bug 1633
Collapse All | Expand All

(-)a/C4/Auth.pm (-1 / +4 lines)
Lines 389-395 sub get_template_and_user { Link Here
389
            virtualshelves              => C4::Context->preference("virtualshelves"),
389
            virtualshelves              => C4::Context->preference("virtualshelves"),
390
            StaffSerialIssueDisplayCount => C4::Context->preference("StaffSerialIssueDisplayCount"),
390
            StaffSerialIssueDisplayCount => C4::Context->preference("StaffSerialIssueDisplayCount"),
391
            NoZebra                     => C4::Context->preference('NoZebra'),
391
            NoZebra                     => C4::Context->preference('NoZebra'),
392
		EasyAnalyticalRecords => C4::Context->preference('EasyAnalyticalRecords'),
392
            EasyAnalyticalRecords       => C4::Context->preference('EasyAnalyticalRecords'),
393
            LocalCoverImages            => C4::Context->preference('LocalCoverImages'),
394
            AllowMultipleCovers         => C4::Context->preference('AllowMultipleCovers'),
393
        );
395
        );
394
    }
396
    }
395
    else {
397
    else {
Lines 494-499 sub get_template_and_user { Link Here
494
            SyndeticsAwards              => C4::Context->preference("SyndeticsAwards"),
496
            SyndeticsAwards              => C4::Context->preference("SyndeticsAwards"),
495
            SyndeticsSeries              => C4::Context->preference("SyndeticsSeries"),
497
            SyndeticsSeries              => C4::Context->preference("SyndeticsSeries"),
496
            SyndeticsCoverImageSize      => C4::Context->preference("SyndeticsCoverImageSize"),
498
            SyndeticsCoverImageSize      => C4::Context->preference("SyndeticsCoverImageSize"),
499
            OPACLocalCoverImages         => C4::Context->preference("OPACLocalCoverImages"),
497
        );
500
        );
498
501
499
        $template->param(OpacPublic => '1') if ($user || C4::Context->preference("OpacPublic"));
502
        $template->param(OpacPublic => '1') if ($user || C4::Context->preference("OpacPublic"));
(-)a/C4/Images.pm (+155 lines)
Line 0 Link Here
1
package C4::Images;
2
use strict;
3
use warnings;
4
use 5.010;
5
6
use C4::Context;
7
use GD;
8
9
use vars qw($debug $VERSION @ISA @EXPORT);
10
11
BEGIN {
12
	# set the version for version checking
13
	$VERSION = 3.03;
14
	require Exporter;
15
	@ISA    = qw(Exporter);
16
	@EXPORT = qw(
17
        &PutImage
18
        &RetrieveImage
19
        &ListImagesForBiblio
20
        &DelImage
21
    );
22
	$debug = $ENV{KOHA_DEBUG} || $ENV{DEBUG} || 0;
23
}
24
25
=head2 PutImage
26
27
    PutImage($biblionumber, $srcimage, $replace);
28
29
Stores binary image data and thumbnail in database, optionally replacing existing images for the given biblio.
30
31
=cut
32
33
sub PutImage {
34
    my ($biblionumber, $srcimage, $replace) = @_;
35
36
    return -1 unless defined($srcimage);
37
38
    if ($replace) {
39
        foreach (ListImagesForBiblio($biblionumber)) {
40
            DelImage($_);
41
        }
42
    }
43
44
    my $dbh = C4::Context->dbh;
45
    my $query = "INSERT INTO biblioimages (biblionumber, mimetype, imagefile, thumbnail) VALUES (?,?,?,?);";
46
    my $sth = $dbh->prepare($query);
47
48
    my $mimetype = 'image/png';	# GD autodetects three basic image formats: PNG, JPEG, XPM; we will convert all to PNG which is lossless...
49
# Check the pixel size of the image we are about to import...
50
    my $thumbnail = _scale_image($srcimage, 140, 200);    # MAX pixel dims are 140 X 200 for thumbnail...
51
    my $fullsize = _scale_image($srcimage, 600, 800);   # MAX pixel dims are 600 X 800 for full-size image...
52
    $debug and warn "thumbnail is " . length($thumbnail) . " bytes.";
53
54
    $sth->execute($biblionumber,$mimetype,$fullsize->png(),$thumbnail->png());
55
    my $dberror = $sth->errstr;
56
    warn "Error returned inserting $biblionumber.$mimetype." if $sth->errstr;
57
    undef $thumbnail;
58
    undef $fullsize;
59
    return $dberror;
60
}
61
62
=head2 RetrieveImage
63
    my ($imagedata, $error) = RetrieveImage($imagenumber);
64
65
Retrieves the specified image.
66
67
=cut
68
69
sub RetrieveImage {
70
    my ($imagenumber) = @_;
71
72
    my $dbh = C4::Context->dbh;
73
    my $query = 'SELECT mimetype, imagefile, thumbnail FROM biblioimages WHERE imagenumber = ?';
74
    my $sth = $dbh->prepare($query);
75
    $sth->execute($imagenumber);
76
    my $imagedata = $sth->fetchrow_hashref;
77
    if ($sth->err) {
78
        warn "Database error!";
79
        return undef;
80
    } else {
81
        return $imagedata;
82
    }
83
}
84
85
=head2 ListImagesForBiblio
86
    my (@images) = ListImagesForBiblio($biblionumber);
87
88
Gets a list of all images associated with a particular biblio.
89
90
=cut
91
92
93
sub ListImagesForBiblio {
94
    my ($biblionumber) = @_;
95
96
    my @imagenumbers;
97
    my $dbh = C4::Context->dbh;
98
    my $query = 'SELECT imagenumber FROM biblioimages WHERE biblionumber = ?';
99
    my $sth = $dbh->prepare($query);
100
    $sth->execute($biblionumber);
101
    warn "Database error!" if $sth->errstr;
102
    if (!$sth->errstr && $sth->rows > 0) {
103
        while (my $row = $sth->fetchrow_hashref) {
104
            push @imagenumbers, $row->{'imagenumber'};
105
        }
106
        return @imagenumbers;
107
    } else {
108
        return undef;
109
    }
110
}
111
112
=head2 DelImage
113
114
    my ($dberror) = DelImage($imagenumber);
115
116
Removes the image with the supplied imagenumber.
117
118
=cut
119
120
sub DelImage {
121
    my ($imagenumber) = @_;
122
    warn "Imagenumber passed to DelImage is $imagenumber" if $debug;
123
    my $dbh = C4::Context->dbh;
124
    my $query = "DELETE FROM biblioimages WHERE imagenumber = ?;";
125
    my $sth = $dbh->prepare($query);
126
    $sth->execute($imagenumber);
127
    my $dberror = $sth->errstr;
128
    warn "Database error!" if $sth->errstr;
129
    return $dberror;
130
}
131
132
sub _scale_image {
133
    my ($image, $maxwidth, $maxheight) = @_;
134
    my ($width, $height) = $image->getBounds();
135
    $debug and warn "image is $width pix X $height pix.";
136
    if ($width > $maxwidth || $height > $maxheight) {
137
#        $debug and warn "$filename exceeds the maximum pixel dimensions of $maxwidth X $maxheight. Resizing...";
138
        my $percent_reduce;    # Percent we will reduce the image dimensions by...
139
            if ($width > $maxwidth) {
140
                $percent_reduce = sprintf("%.5f",($maxwidth/$width));    # If the width is oversize, scale based on width overage...
141
            } else {
142
                $percent_reduce = sprintf("%.5f",($maxheight/$height));    # otherwise scale based on height overage.
143
            }
144
        my $width_reduce = sprintf("%.0f", ($width * $percent_reduce));
145
        my $height_reduce = sprintf("%.0f", ($height * $percent_reduce));
146
        $debug and warn "Reducing image by " . ($percent_reduce * 100) . "\% or to $width_reduce pix X $height_reduce pix";
147
        my $newimage = GD::Image->new($width_reduce, $height_reduce, 1); #'1' creates true color image...
148
        $newimage->copyResampled($image,0,0,0,0,$width_reduce,$height_reduce,$width,$height);
149
        return $newimage;
150
    } else {
151
        return $image;
152
    }
153
}
154
155
1;
(-)a/C4/UploadedFile.pm (+18 lines)
Lines 159-164 sub name { Link Here
159
    }
159
    }
160
}
160
}
161
161
162
=head2 filename
163
164
  my $filename = $uploaded_file->filename();
165
166
Accessor method for the name by which the file is to be known.
167
168
=cut
169
170
sub filename {
171
    my $self = shift;
172
    if (@_) {
173
        $self->{'tmp_file_name'} = shift;
174
        $self->_serialize();
175
    } else {
176
        return $self->{'tmp_file_name'};
177
    }
178
}
179
162
=head2 max_size
180
=head2 max_size
163
181
164
  my $max_size = $uploaded_file->max_size();
182
  my $max_size = $uploaded_file->max_size();
(-)a/installer/data/mysql/atomicupdate/local_cover_images.pl (+20 lines)
Line 0 Link Here
1
#! /usr/bin/perl
2
use strict;
3
use warnings;
4
use C4::Context;
5
my $dbh=C4::Context->dbh;
6
7
$dbh->do( q|CREATE TABLE `biblioimages` (
8
      `imagenumber` int(11) NOT NULL AUTO_INCREMENT,
9
      `biblionumber` int(11) NOT NULL,
10
      `mimetype` varchar(15) NOT NULL,
11
      `imagefile` mediumblob NOT NULL,
12
      `thumbnail` mediumblob NOT NULL,
13
      PRIMARY KEY (`imagenumber`),
14
      CONSTRAINT `bibliocoverimage_fk1` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE
15
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8|);
16
$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')|);
17
$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')|);
18
$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')|);
19
$dbh->do( q|INSERT INTO permissions (module_bit, code, description) VALUES (13, 'upload_local_cover_images', 'Upload local cover images')|);
20
print "Upgrade done (Added support for local cover images)\n";
(-)a/installer/data/mysql/en/mandatory/userpermissions.sql (+1 lines)
Lines 36-41 INSERT INTO permissions (module_bit, code, description) VALUES Link Here
36
   (13, 'manage_csv_profiles', 'Manage CSV export profiles'),
36
   (13, 'manage_csv_profiles', 'Manage CSV export profiles'),
37
   (13, 'moderate_tags', 'Moderate patron tags'),
37
   (13, 'moderate_tags', 'Moderate patron tags'),
38
   (13, 'rotating_collections', 'Manage rotating collections'),
38
   (13, 'rotating_collections', 'Manage rotating collections'),
39
   (13, 'upload_local_cover_images', 'Upload local cover images'),
39
   (15, 'check_expiration', 'Check the expiration of a serial'),
40
   (15, 'check_expiration', 'Check the expiration of a serial'),
40
   (15, 'claim_serials', 'Claim missing serials'),
41
   (15, 'claim_serials', 'Claim missing serials'),
41
   (15, 'create_subscription', 'Create a new subscription'),
42
   (15, 'create_subscription', 'Create a new subscription'),
(-)a/installer/data/mysql/kohastructure.sql (+15 lines)
Lines 2668-2673 CREATE TABLE `fieldmapping` ( -- koha to keyword mapping Link Here
2668
  PRIMARY KEY  (`id`)
2668
  PRIMARY KEY  (`id`)
2669
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2669
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2670
2670
2671
--
2672
-- Table structure for table `bibliocoverimage`
2673
--
2674
2675
DROP TABLE IF EXISTS `bibliocoverimage`;
2676
2677
CREATE TABLE `bibliocoverimage` (
2678
 `imagenumber` int(11) NOT NULL AUTO_INCREMENT,
2679
 `biblionumber` int(11) NOT NULL,
2680
 `mimetype` varchar(15) NOT NULL,
2681
 `imagefile` mediumblob NOT NULL,
2682
 `thumbnail` mediumblob NOT NULL,
2683
 PRIMARY KEY (`imagenumber`),
2684
 CONSTRAINT `bibliocoverimage_fk1` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE
2685
) ENGINE=InnoDB DEFAULT CHARSET=utf8
2671
2686
2672
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
2687
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
2673
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
2688
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
(-)a/installer/data/mysql/sysprefs.sql (+3 lines)
Lines 330-332 INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES Link Here
330
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');
330
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');
331
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');
331
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');
332
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');
332
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');
333
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OPACLocalCoverImages','0','Display local cover images on OPAC search and details pages.','1','YesNo');
334
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('LocalCoverImages','0','Display local cover images on intranet details pages.','1','YesNo');
335
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('AllowMultipleCovers','0','Allow multiple cover images to be attached to each bibliographic record.','1','YesNo');
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc (-1 / +2 lines)
Lines 101-107 function confirm_items_deletion() { Link Here
101
	        [% IF ( CAN_user_editcatalogue_edit_catalogue ) %]{ text: _("Edit Record"), url: "/cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=[% biblionumber %]&frameworkcode=&op=" },[% END %]
101
	        [% IF ( CAN_user_editcatalogue_edit_catalogue ) %]{ text: _("Edit Record"), url: "/cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=[% biblionumber %]&frameworkcode=&op=" },[% END %]
102
	        [% IF ( CAN_user_editcatalogue_edit_items ) %]{ text: _("Edit Items"), url: "/cgi-bin/koha/cataloguing/additem.pl?biblionumber=[% biblionumber %]" },[% END %]
102
	        [% IF ( CAN_user_editcatalogue_edit_items ) %]{ text: _("Edit Items"), url: "/cgi-bin/koha/cataloguing/additem.pl?biblionumber=[% biblionumber %]" },[% END %]
103
	        [% IF ( CAN_user_editcatalogue_edit_items ) %]{ text: _("Attach Item"), url: "/cgi-bin/koha/cataloguing/moveitem.pl?biblionumber=[% biblionumber %]" },[% END %]
103
	        [% IF ( CAN_user_editcatalogue_edit_items ) %]{ text: _("Attach Item"), url: "/cgi-bin/koha/cataloguing/moveitem.pl?biblionumber=[% biblionumber %]" },[% END %]
104
                [% IF ( EasyAnalyticalRecords ) %][% IF ( CAN_user_editcatalogue_edit_items ) %]{ text: _("Link to Host Item"), url: "/cgi-bin/koha/cataloguing/linkitem.pl?biblionumber=[% biblionumber %]" },[% END %][% END %]
104
            [% IF ( EasyAnalyticalRecords ) %][% IF ( CAN_user_editcatalogue_edit_items ) %]{ text: _("Link to Host Item"), url: "/cgi-bin/koha/cataloguing/linkitem.pl?biblionumber=[% biblionumber %]" },[% END %][% END %]
105
            [% 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 %]
105
	        [% IF ( CAN_user_editcatalogue_edit_catalogue ) %]{ text: _("Edit as New (Duplicate)"), url: "/cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=[% biblionumber %]&frameworkcode=&op=duplicate" },[% END %]
106
	        [% IF ( CAN_user_editcatalogue_edit_catalogue ) %]{ text: _("Edit as New (Duplicate)"), url: "/cgi-bin/koha/cataloguing/addbiblio.pl?biblionumber=[% biblionumber %]&frameworkcode=&op=duplicate" },[% END %]
106
			[% IF ( CAN_user_editcatalogue_edit_catalogue ) %]{ text: _("Replace Record via Z39.50"), onclick: {fn: PopupZ3950 } },[% END %]
107
			[% IF ( CAN_user_editcatalogue_edit_catalogue ) %]{ text: _("Replace Record via Z39.50"), onclick: {fn: PopupZ3950 } },[% END %]
107
			[% IF ( CAN_user_editcatalogue_edit_catalogue ) %]{ text: _("Delete Record"), onclick: {fn: confirm_deletion }[% IF ( count ) %],id:'disabled'[% END %] },[% END %]
108
			[% IF ( CAN_user_editcatalogue_edit_catalogue ) %]{ text: _("Delete Record"), onclick: {fn: confirm_deletion }[% IF ( count ) %],id:'disabled'[% END %] },[% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc (+3 lines)
Lines 70-75 Link Here
70
    [% IF ( CAN_user_tools_manage_staged_marc ) %]
70
    [% IF ( CAN_user_tools_manage_staged_marc ) %]
71
	<li><a href="/cgi-bin/koha/tools/manage-marc-import.pl">Staged MARC management</a></li>
71
	<li><a href="/cgi-bin/koha/tools/manage-marc-import.pl">Staged MARC management</a></li>
72
    [% END %]
72
    [% END %]
73
    [% IF ( CAN_user_tools_upload_local_cover_images ) %]
74
	<li><a href="/cgi-bin/koha/tools/upload-cover-image.pl">Upload Local Cover Image</a></li>
75
    [% END %]
73
</ul>
76
</ul>
74
<h5>Additional Tools</h5>
77
<h5>Additional Tools</h5>
75
<ul>
78
<ul>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref (+19 lines)
Lines 311-313 Enhanced Content: Link Here
311
            - pref: TagsExternalDictionary
311
            - pref: TagsExternalDictionary
312
              class: file
312
              class: file
313
            - on the server to be approved without moderation.
313
            - on the server to be approved without moderation.
314
    Local Cover Images:
315
        -
316
            - pref: LocalCoverImages
317
              choices:
318
                  yes: Display
319
                  no: "Don't display"
320
            - local cover images on intranet search and details pages.
321
        -
322
            - pref: OPACLocalCoverImages
323
              choices:
324
                  yes: Display
325
                  no: "Don't display"
326
            - local cover images on OPAC search and details pages.
327
        -
328
            - pref: AllowMultipleCovers
329
              choices:
330
                  yes: Allow
331
                  no: "Don't allow"
332
            - multiple images to be attached to each bibliographic record.
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt (+5 lines)
Lines 140-145 Link Here
140
    <dd>Managed staged MARC records, including completing and reversing imports</dd>
140
    <dd>Managed staged MARC records, including completing and reversing imports</dd>
141
    [% END %]
141
    [% END %]
142
142
143
    [% IF ( CAN_user_tools_upload_local_cover_images ) %]
144
    <dt><a href="/cgi-bin/koha/tools/upload-cover-image.pl">Upload Local Cover Image</a></dt>
145
    <dd>Utility to upload scanned cover images for display in OPAC</dd>
146
    [% END %]
147
143
</dl>
148
</dl>
144
</div>
149
</div>
145
150
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt (+130 lines)
Line 0 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Koha &rsaquo; Tools &rsaquo; Upload Images</title>
3
[% INCLUDE 'doc-head-close.inc' %]
4
[% INCLUDE 'file-upload.inc' %]
5
[% INCLUDE 'background-job.inc' %]
6
<style type="text/css">
7
	#uploadpanel,#fileuploadstatus,#fileuploadfailed,#jobpanel,#jobstatus,#jobfailed { display : none; }
8
	#fileuploadstatus,#jobstatus { margin:.4em; }
9
	#fileuploadprogress,#jobprogress{ width:150px;height:10px;border:1px solid #666;background:url('/intranet-tmpl/prog/img/progress.png') -300px 0px no-repeat; }</style>
10
<script type="text/javascript">
11
//<![CDATA[
12
$(document).ready(function(){
13
	$("#processfile").hide();
14
	$("#zipfile").click(function(){
15
		$("#bibnum").hide();
16
	});
17
	$("#image").click(function(){
18
		$("#bibnum").show();
19
	});
20
});
21
function CheckForm(f) {
22
    if ($("#fileToUpload").value == '') {
23
        alert(_('Please upload a file first.'));
24
    } else {
25
        return submitBackgroundJob(f);
26
    }
27
    return false;
28
}
29
30
//]]>
31
</script>
32
</head>
33
<body>
34
[% INCLUDE 'header.inc' %]
35
[% INCLUDE 'cat-search.inc' %]
36
37
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> &rsaquo; [% IF ( uploadimage ) %]<a href="/cgi-bin/koha/tools/upload-cover-image.pl">Upload Local Cover Image</a> &rsaquo; Upload Results[% ELSE %]Upload Local Cover Image[% END %]</div>
38
39
<div id="doc3" class="yui-t2">
40
41
   <div id="bd">
42
	<div id="yui-main">
43
	<div class="yui-b">
44
45
<h1>Upload Local Cover Image</h1>
46
[% IF ( uploadimage ) %]
47
<p>Image upload results :</p>
48
<ul>
49
	<li>[% total %]  images found</li>
50
    [% IF ( error ) %]
51
    <div class="dialog alert">
52
    [% IF ( error == 'UZIPFAIL' ) %]<p><b>Failed to unzip archive.<br />Please ensure you are uploading a valid zip file and try again.</b></p>
53
    [% ELSIF ( error == 'OPNLINK' ) %]<p><b>Cannot open folder index (idlink.txt or datalink.txt) to read.<br />Please verify that it exists.</b></p>
54
    [% 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>
55
    [% 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>
56
    [% ELSIF ( error == 'DBERR' ) %]<p><b>Unable to save image to database.</b></p>
57
    [% ELSE %]<p><b>An unknown error has occurred.<br />Please review the error log for more details.</b></p>[% END %]
58
    </div>
59
    </li>
60
    [% END %]
61
    <li><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblionumber %]">View final record</a></li>
62
	<li><a href="/cgi-bin/koha/tools/tools-home.pl">Back</a></li>
63
</ul>
64
<hr />
65
[% END %]
66
<ul>
67
	<li>Select an image file or ZIP file to upload. The tool will accept images in GIF, JPEG, PNG, and XPM formats.</li>
68
</ul>
69
<form method="post" action="[% SCRIPT_NAME %]" id="uploadfile" enctype="multipart/form-data">
70
<fieldset class="rows" id="uploadform">
71
<legend>Upload images</legend>
72
<ol>
73
	<li>
74
        <div id="fileuploadform">
75
		<label for="fileToUpload">Select the file to upload: </label>
76
		<input type="file" id="fileToUpload" name="fileToUpload" />
77
        </div>	</li>
78
</ol>
79
  <fieldset class="action"><button class="submit" onclick="return ajaxFileUpload();">Upload file</button></fieldset>
80
</fieldset>
81
82
        <div id="uploadpanel"><div id="fileuploadstatus">Upload progress: <div id="fileuploadprogress"></div> <span id="fileuploadpercent">0</span>%</div>
83
        <div id="fileuploadfailed"></div></div>
84
</form>
85
86
    <form method="post" id="processfile" action="[% SCRIPT_NAME %]" enctype="multipart/form-data">
87
<fieldset class="rows">
88
        <input type="hidden" name="uploadedfileid" id="uploadedfileid" value="" />
89
        <input type="hidden" name="runinbackground" id="runinbackground" value="" />
90
        <input type="hidden" name="completedJobID" id="completedJobID" value="" />
91
	</fieldset>
92
  <fieldset class="rows">
93
    <legend>File type</legend>
94
    <ol>
95
      <li class="radio">
96
        <input type="radio" id="zipfile" name="filetype" value="zip" [% IF (filetype != 'image' ) %]checked="checked"[% END %] />
97
        <label for="zipfile">ZIP file</label>
98
      </li>
99
      <li class="radio">
100
        <input type="radio" id="image" name="filetype" value="image" [% IF (filetype == 'image' ) %]checked="checked"[% END %] />
101
        <label for="imagefile">Image file</label>
102
      </li>
103
      <li class="radio">
104
        [% 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>
105
      </li>
106
    </ol>
107
  </fieldset>
108
  <fieldset class="rows">
109
    <legend>Options</legend>
110
    <ol>
111
      <li class="checkbox">
112
        <input type="checkbox" id="replace" name="replace" [% IF AllowMultipleCovers == 0 %]checked="checked" disabled="disabled"[% END %] />
113
        <label for="replace">Replace existing covers</label>
114
      </li>
115
    </ol>
116
  </fieldset>
117
  <fieldset class="action"><input type="submit" value="Process images" /></fieldset>
118
119
       <div id="jobpanel"><div id="jobstatus">Job progress: <div id="jobprogress"></div> <span id="jobprogresspercent">0</span>%</div>
120
     <div id="jobfailed"></div></div>
121
122
</form>
123
124
</div>
125
</div>
126
<div class="yui-b">
127
[% INCLUDE 'tools-menu.inc' %]
128
</div>
129
</div>
130
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/tools/upload-cover-image.pl (-1 / +169 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
#
3
# Copyright 2011 C & P Bibliography Services
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 2 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along with
17
# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18
# Suite 330, Boston, MA  02111-1307 USA
19
#
20
#
21
#
22
=head1 NAME
23
24
upload-cover-image.pl - Script for handling uploading of both single and bulk coverimages and importing them into the database.
25
26
=head1 SYNOPSIS
27
28
upload-cover-image.pl
29
30
=head1 DESCRIPTION
31
32
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.
33
Images will be resized into thumbnails of 140x200 pixels and larger images of
34
800x600 pixels. If the images that are uploaded are larger, they will be
35
resized, maintaining aspect ratio.
36
37
=cut
38
39
40
use strict;
41
use warnings;
42
43
use File::Temp;
44
use CGI;
45
use GD;
46
use C4::Context;
47
use C4::Auth;
48
use C4::Output;
49
use C4::Images;
50
use C4::UploadedFile;
51
52
my $debug = 1;
53
54
my $input = new CGI;
55
56
my $fileID=$input->param('uploadedfileid');
57
my ($template, $loggedinuser, $cookie)
58
	= get_template_and_user({template_name => "tools/upload-images.tmpl",
59
					query => $input,
60
					type => "intranet",
61
					authnotrequired => 0,
62
					flagsrequired => { tools => 'upload_cover_images'},
63
					debug => 0,
64
					});
65
66
my $filetype            = $input->param('filetype');
67
my $biblionumber        = $input->param('biblionumber');
68
my $uploadfilename      = $input->param('uploadfile');
69
my $replace             = $input->param('replace');
70
my $op                  = $input->param('op');
71
my %cookies             = parse CGI::Cookie($cookie);
72
my $sessionID           = $cookies{'CGISESSID'}->value;
73
74
my $error;
75
76
$template->{VARS}->{'filetype'} = $filetype;
77
$template->{VARS}->{'biblionumber'} = $biblionumber;
78
79
my $total = 0;
80
81
if ($fileID) {
82
    my $uploaded_file = C4::UploadedFile->fetch($sessionID, $fileID);
83
    if ($filetype eq 'image') {
84
        my $fh = $uploaded_file->fh();
85
        my $srcimage = GD::Image->new($fh);
86
        if (defined $srcimage) {
87
            my $dberror = PutImage($biblionumber, $srcimage, $replace);
88
            if ($dberror) {
89
                $error = 'DBERR';
90
            } else {
91
                $total = 1;
92
            }
93
        } else {
94
            $error = 'OPNIMG';
95
        }
96
        undef $srcimage;
97
    } else {
98
        my $filename = $uploaded_file->filename();
99
        my $dirname = File::Temp::tempdir( CLEANUP => 1);
100
        unless (system("unzip", $filename,  '-d', $dirname) == 0) {
101
            $error = 'UZIPFAIL';
102
        } else {
103
            my @directories;
104
            push @directories, "$dirname";
105
            foreach my $recursive_dir ( @directories ) {
106
                my $dir;
107
                opendir $dir, $recursive_dir;
108
                while ( my $entry = readdir $dir ) {
109
                    push @directories, "$recursive_dir/$entry" if ( -d "$recursive_dir/$entry" and $entry !~ /^[._]/ );
110
                }
111
                closedir $dir;
112
            }
113
            foreach my $dir ( @directories ) {
114
                my $file;
115
                if ( -e "$dir/idlink.txt" ) {
116
                    $file = "$dir/idlink.txt";
117
                } elsif ( -e "$dir/datalink.txt" ) {
118
                    $file = "$dir/datalink.txt";
119
                } else {
120
                    next;
121
                }
122
                if (open (FILE, $file)) {
123
                    while (my $line = <FILE>) {
124
                        my $delim = ($line =~ /\t/) ? "\t" : ($line =~ /,/) ? "," : "";
125
                        #$debug and warn "Delimeter is \'$delim\'";
126
                        unless ( $delim eq "," || $delim eq "\t" ) {
127
                            warn "Unrecognized or missing field delimeter. Please verify that you are using either a ',' or a 'tab'";
128
                            $error = 'DELERR';
129
                        } else {
130
                            ($biblionumber, $filename) = split $delim, $line;
131
                            $biblionumber =~ s/[\"\r\n]//g;  # remove offensive characters
132
                            $filename   =~ s/[\"\r\n\s]//g;
133
                            my $srcimage = GD::Image->new("$dir/$filename");
134
                            if (defined $srcimage) {
135
                                $total++;
136
                                my $dberror = PutImage($biblionumber, $srcimage, $replace);
137
                                if ($dberror) {
138
                                    $error = 'DBERR';
139
                                }
140
                            } else {
141
                                $error = 'OPNIMG';
142
                            }
143
                            undef $srcimage;
144
                        }
145
                    }
146
                    close(FILE);
147
                } else {
148
                    $error = 'OPNLINK';
149
                }
150
            }
151
        }
152
    }
153
    $template->{VARS}->{'total'} = $total;
154
    $template->{VARS}->{'uploadimage'} = 1;
155
    $template->{VARS}->{'error'} = $error;
156
    $template->{VARS}->{'biblionumber'} = $biblionumber;
157
}
158
159
output_html_with_http_headers $input, $cookie, $template->output;
160
161
exit 0;
162
163
=head1 AUTHORS
164
165
Written by Jared Camins-Esakov of C & P Bibliography Services, in part based on
166
code by Koustubha Kale of Anant Corporation and Chris Nighswonger of Foundation
167
Bible College.
168
169
=cut

Return to bug 1633