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 2667-2672 CREATE TABLE `fieldmapping` ( -- koha to keyword mapping Link Here
2667
  PRIMARY KEY  (`id`)
2667
  PRIMARY KEY  (`id`)
2668
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2668
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2669
2669
2670
--
2671
-- Table structure for table `bibliocoverimage`
2672
--
2673
2674
DROP TABLE IF EXISTS `bibliocoverimage`;
2675
2676
CREATE TABLE `bibliocoverimage` (
2677
 `imagenumber` int(11) NOT NULL AUTO_INCREMENT,
2678
 `biblionumber` int(11) NOT NULL,
2679
 `mimetype` varchar(15) NOT NULL,
2680
 `imagefile` mediumblob NOT NULL,
2681
 `thumbnail` mediumblob NOT NULL,
2682
 PRIMARY KEY (`imagenumber`),
2683
 CONSTRAINT `bibliocoverimage_fk1` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE
2684
) ENGINE=InnoDB DEFAULT CHARSET=utf8
2670
2685
2671
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
2686
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
2672
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
2687
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
(-)a/installer/data/mysql/sysprefs.sql (-1 / +3 lines)
Lines 328-331 INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES(' Link Here
328
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OpacKohaUrl','1',"Show 'Powered by Koha' text on OPAC footer.",NULL,NULL);
328
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OpacKohaUrl','1',"Show 'Powered by Koha' text on OPAC footer.",NULL,NULL);
329
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');
329
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('OpacShowRecentComments',0,'If ON a link to recent comments will appear in the OPAC masthead',NULL,'YesNo');
330
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
331
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('OPACLocalCoverImages','0','Display local cover images on OPAC search and details pages.','1','YesNo');
332
INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('LocalCoverImages','0','Display local cover images on intranet details pages.','1','YesNo');
333
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 / +167 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
Files greater than 100K will be refused. Images should be 140x200 pixels. If they are larger they will be auto-resized to comply.
34
35
=cut
36
37
38
use strict;
39
use warnings;
40
41
use File::Temp;
42
use CGI;
43
use GD;
44
use C4::Context;
45
use C4::Auth;
46
use C4::Output;
47
use C4::Images;
48
use C4::UploadedFile;
49
50
my $debug = 1;
51
52
my $input = new CGI;
53
54
my $fileID=$input->param('uploadedfileid');
55
my ($template, $loggedinuser, $cookie)
56
	= get_template_and_user({template_name => "tools/upload-images.tmpl",
57
					query => $input,
58
					type => "intranet",
59
					authnotrequired => 0,
60
					flagsrequired => { tools => 'upload_cover_images'},
61
					debug => 0,
62
					});
63
64
my $filetype            = $input->param('filetype');
65
my $biblionumber        = $input->param('biblionumber');
66
my $uploadfilename      = $input->param('uploadfile');
67
my $replace             = $input->param('replace');
68
my $op                  = $input->param('op');
69
my %cookies             = parse CGI::Cookie($cookie);
70
my $sessionID           = $cookies{'CGISESSID'}->value;
71
72
my $error;
73
74
$template->{VARS}->{'filetype'} = $filetype;
75
$template->{VARS}->{'biblionumber'} = $biblionumber;
76
77
my $total = 0;
78
79
if ($fileID) {
80
    my $uploaded_file = C4::UploadedFile->fetch($sessionID, $fileID);
81
    if ($filetype eq 'image') {
82
        my $fh = $uploaded_file->fh();
83
        my $srcimage = GD::Image->new($fh);
84
        if (defined $srcimage) {
85
            my $dberror = PutImage($biblionumber, $srcimage, $replace);
86
            if ($dberror) {
87
                $error = 'DBERR';
88
            } else {
89
                $total = 1;
90
            }
91
        } else {
92
            $error = 'OPNIMG';
93
        }
94
        undef $srcimage;
95
    } else {
96
        my $filename = $uploaded_file->filename();
97
        my $dirname = File::Temp::tempdir( CLEANUP => 1);
98
        unless (system("unzip", $filename,  '-d', $dirname) == 0) {
99
            $error = 'UZIPFAIL';
100
        } else {
101
            my @directories;
102
            push @directories, "$dirname";
103
            foreach my $recursive_dir ( @directories ) {
104
                my $dir;
105
                opendir $dir, $recursive_dir;
106
                while ( my $entry = readdir $dir ) {
107
                    push @directories, "$recursive_dir/$entry" if ( -d "$recursive_dir/$entry" and $entry !~ /^[._]/ );
108
                }
109
                closedir $dir;
110
            }
111
            foreach my $dir ( @directories ) {
112
                my $file;
113
                if ( -e "$dir/idlink.txt" ) {
114
                    $file = "$dir/idlink.txt";
115
                } elsif ( -e "$dir/datalink.txt" ) {
116
                    $file = "$dir/datalink.txt";
117
                } else {
118
                    next;
119
                }
120
                if (open (FILE, $file)) {
121
                    while (my $line = <FILE>) {
122
                        my $delim = ($line =~ /\t/) ? "\t" : ($line =~ /,/) ? "," : "";
123
                        #$debug and warn "Delimeter is \'$delim\'";
124
                        unless ( $delim eq "," || $delim eq "\t" ) {
125
                            warn "Unrecognized or missing field delimeter. Please verify that you are using either a ',' or a 'tab'";
126
                            $error = 'DELERR';
127
                        } else {
128
                            ($biblionumber, $filename) = split $delim, $line;
129
                            $biblionumber =~ s/[\"\r\n]//g;  # remove offensive characters
130
                            $filename   =~ s/[\"\r\n\s]//g;
131
                            my $srcimage = GD::Image->new("$dir/$filename");
132
                            if (defined $srcimage) {
133
                                $total++;
134
                                my $dberror = PutImage($biblionumber, $srcimage, $replace);
135
                                if ($dberror) {
136
                                    $error = 'DBERR';
137
                                }
138
                            } else {
139
                                $error = 'OPNIMG';
140
                            }
141
                            undef $srcimage;
142
                        }
143
                    }
144
                    close(FILE);
145
                } else {
146
                    $error = 'OPNLINK';
147
                }
148
            }
149
        }
150
    }
151
    $template->{VARS}->{'total'} = $total;
152
    $template->{VARS}->{'uploadimage'} = 1;
153
    $template->{VARS}->{'error'} = $error;
154
    $template->{VARS}->{'biblionumber'} = $biblionumber;
155
}
156
157
output_html_with_http_headers $input, $cookie, $template->output;
158
159
exit 0;
160
161
=head1 AUTHORS
162
163
Written by Jared Camins-Esakov of C & P Bibliography Services, in part based on
164
code by Koustubha Kale of Anant Corporation and Chris Nighswonger of Foundation
165
Bible College.
166
167
=cut

Return to bug 1633