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

(-)a/C4/Images.pm (-15 / +70 lines)
Lines 24-29 use 5.010; Link Here
24
24
25
use C4::Context;
25
use C4::Context;
26
use GD;
26
use GD;
27
use Koha::Upload;
28
29
use File::Path qw(make_path);
27
30
28
use vars qw($debug $noimage @ISA @EXPORT);
31
use vars qw($debug $noimage @ISA @EXPORT);
29
32
Lines 54-60 Stores binary image data and thumbnail in database, optionally replacing existin Link Here
54
=cut
57
=cut
55
58
56
sub PutImage {
59
sub PutImage {
57
    my ( $biblionumber, $srcimage, $replace ) = @_;
60
    my ( $biblionumber, $srcimage, $replace, $uploadedfileid ) = @_;
58
61
59
    return -1 unless defined($srcimage);
62
    return -1 unless defined($srcimage);
60
63
Lines 66-90 sub PutImage { Link Here
66
69
67
    my $dbh = C4::Context->dbh;
70
    my $dbh = C4::Context->dbh;
68
    my $query =
71
    my $query =
69
"INSERT INTO biblioimages (biblionumber, mimetype, imagefile, thumbnail) VALUES (?,?,?,?);";
72
"INSERT INTO biblioimages (biblionumber, mimetype, imagefile, thumbnail, uploadedfileid) VALUES (?,?,?,?,?);";
70
    my $sth = $dbh->prepare($query);
73
    my $sth = $dbh->prepare($query);
71
74
72
    my $mimetype = 'image/png'
75
    my $mimetype = 'image/png'
73
      ; # GD autodetects three basic image formats: PNG, JPEG, XPM; we will convert all to PNG which is lossless...
76
      ; # GD autodetects three basic image formats: PNG, JPEG, XPM; we will convert all to PNG which is lossless...
74
77
    if( defined $uploadedfileid){
75
    # Check the pixel size of the image we are about to import...
78
        $sth->execute( $biblionumber, $mimetype, undef, undef, $uploadedfileid );
76
    my $thumbnail = _scale_image( $srcimage, 140, 200 )
79
    }else{
77
      ;    # MAX pixel dims are 140 X 200 for thumbnail...
80
        # Check the pixel size of the image we are about to import...
78
    my $fullsize = _scale_image( $srcimage, 600, 800 )
81
        my $thumbnail = _scale_image( $srcimage, 140, 200 )
79
      ;    # MAX pixel dims are 600 X 800 for full-size image...
82
          ;    # MAX pixel dims are 140 X 200 for thumbnail...
80
    $debug and warn "thumbnail is " . length($thumbnail) . " bytes.";
83
        my $fullsize = _scale_image( $srcimage, 600, 800 )
81
84
          ;    # MAX pixel dims are 600 X 800 for full-size image...
82
    $sth->execute( $biblionumber, $mimetype, $fullsize->png(),
85
        $debug and warn "thumbnail is " . length($thumbnail) . " bytes.";
83
        $thumbnail->png() );
86
87
        $sth->execute( $biblionumber, $mimetype, $fullsize->png(),
88
            $thumbnail->png(), $uploadedfileid );    
89
        undef $thumbnail;
90
        undef $fullsize;
91
    }
92
    
84
    my $dberror = $sth->errstr;
93
    my $dberror = $sth->errstr;
85
    warn "Error returned inserting $biblionumber.$mimetype." if $sth->errstr;
94
    warn "Error returned inserting $biblionumber.$mimetype." if $sth->errstr;
86
    undef $thumbnail;
87
    undef $fullsize;
88
    return $dberror;
95
    return $dberror;
89
}
96
}
90
97
Lines 100-119 sub RetrieveImage { Link Here
100
107
101
    my $dbh = C4::Context->dbh;
108
    my $dbh = C4::Context->dbh;
102
    my $query =
109
    my $query =
103
'SELECT imagenumber, mimetype, imagefile, thumbnail FROM biblioimages WHERE imagenumber = ?';
110
'SELECT imagenumber, mimetype, imagefile, thumbnail, uploadedfileid FROM biblioimages WHERE imagenumber = ?';
104
    my $sth = $dbh->prepare($query);
111
    my $sth = $dbh->prepare($query);
105
    $sth->execute($imagenumber);
112
    $sth->execute($imagenumber);
106
    my $imagedata = $sth->fetchrow_hashref;
113
    my $imagedata = $sth->fetchrow_hashref;
107
    if ( !$imagedata ) {
114
    if ( !$imagedata ) {
108
        $imagedata->{'thumbnail'} = $noimage;
115
        $imagedata->{'thumbnail'} = $noimage;
109
        $imagedata->{'imagefile'} = $noimage;
116
        $imagedata->{'imagefile'} = $noimage;
117
    }else{
118
        if (defined $imagedata->{'uploadedfileid'}){
119
            my ($thumbnail, $imagefile) = _retrieve_thumbs_images($imagedata->{'uploadedfileid'});
120
            $imagedata->{'thumbnail'} = $thumbnail;    # MAX pixel dims are 140 X 200 for thumbnail...
121
            $imagedata->{'imagefile'} = $imagefile;  
122
123
        }
110
    }
124
    }
125
111
    if ( $sth->err ) {
126
    if ( $sth->err ) {
112
        warn "Database error!" if $debug;
127
        warn "Database error!" if $debug;
113
    }
128
    }
114
    return $imagedata;
129
    return $imagedata;
115
}
130
}
116
131
132
sub _retrieve_thumbs_images {
133
    my ($uploadedfileid) = @_;
134
    my $thumbnail_name = '140_200.png';
135
    my $imagefile_name = '600_800.png';
136
    my $temp_directory = "/tmp/koha_thumbs_$uploadedfileid";
137
    my $files_exists = 0;
138
    #Check if the uploaded file id exists on the temp directory.
139
    #Check if a temp dir exists.
140
    if ( -d $temp_directory){
141
        if ( -e "$temp_directory/$thumbnail_name" && -e "$temp_directory/$imagefile_name"){
142
            $files_exists = 1;
143
        }
144
    }else{
145
        make_path("/tmp/koha_thumbs_$uploadedfileid");
146
    }
147
    my $thumbnail;
148
    my $imagefile;
149
    if($files_exists){
150
        $thumbnail = GD::Image->new("$temp_directory/$thumbnail_name")->png();
151
        $imagefile = GD::Image->new("$temp_directory/$imagefile_name")->png();
152
    }else{
153
        # There is none temp files, create them.
154
        my $upload = Koha::Upload->new->get({ id => $uploadedfileid, filehandle => 1 });
155
        my $srcimage = GD::Image->new($upload->{fh});
156
        $thumbnail = _scale_image( $srcimage, 140, 200 )->png();
157
        $imagefile = _scale_image( $srcimage, 600, 800 )->png();
158
        warn "$temp_directory/$thumbnail_name";
159
        open( IMAGE, ">$temp_directory/$thumbnail_name");
160
        binmode( IMAGE );
161
        print IMAGE $thumbnail;
162
        close IMAGE;
163
        warn "$temp_directory/$imagefile_name";
164
        open( IMAGE2, ">$temp_directory/$imagefile_name");
165
        binmode( IMAGE2 );
166
        print IMAGE2 $imagefile;
167
        close IMAGE2;
168
    }
169
    return ($thumbnail, $imagefile);
170
}
171
117
=head2 ListImagesForBiblio
172
=head2 ListImagesForBiblio
118
    my (@images) = ListImagesForBiblio($biblionumber);
173
    my (@images) = ListImagesForBiblio($biblionumber);
119
174
(-)a/installer/data/mysql/atomicupdate/bug_17650_save_cover_to_hd.sql (+16 lines)
Line 0 Link Here
1
ALTER TABLE `biblioimages` 
2
DROP FOREIGN KEY `bibliocoverimage_fk1`;
3
ALTER TABLE `biblioimages` 
4
CHANGE COLUMN `imagefile` `imagefile` MEDIUMBLOB NULL DEFAULT NULL ,
5
CHANGE COLUMN `thumbnail` `thumbnail` MEDIUMBLOB NULL DEFAULT NULL ,
6
ADD COLUMN `uploadedfileid` INT(11) NULL DEFAULT NULL AFTER `thumbnail`,
7
ADD INDEX `bibliocoverimage_fk2_idx` (`uploadedfileid` ASC);
8
ALTER TABLE `biblioimages` 
9
ADD CONSTRAINT `bibliocoverimage_fk2`
10
  FOREIGN KEY (`uploadedfileid`)
11
  REFERENCES `uploaded_files` (`id`)
12
  ON DELETE CASCADE
13
  ON UPDATE CASCADE;
14
  
15
  
16
INSERT IGNORE INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `type` ) VALUES ('SaveCoverOnDisk','0','','Save the covers on the the hard disk instead of the database.','YesNo');
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref (+6 lines)
Lines 311-316 Enhanced Content: Link Here
311
                  yes: Allow
311
                  yes: Allow
312
                  no: "Don't allow"
312
                  no: "Don't allow"
313
            - multiple images to be attached to each bibliographic record.
313
            - multiple images to be attached to each bibliographic record.
314
        -
315
            - pref: SaveCoverOnDisk
316
              choices:
317
                  yes: "Yes"
318
                  no: "No"
319
            - Save the covers on the the hard disk instead of the database.
314
    HTML5 Media:
320
    HTML5 Media:
315
        -
321
        -
316
            - Show a tab with a HTML5 media player for files catalogued in field 856
322
            - Show a tab with a HTML5 media player for files catalogued in field 856
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/file-search.tt (+29 lines)
Line 0 Link Here
1
[% USE Koha %]
2
<table>
3
	<thead>
4
		<tr>
5
		    <th>Filename</th>
6
		    <th>Size</th>
7
		    <th>Hashvalue</th>
8
		    <th>Category</th>
9
		    <th>Public</th>
10
		    <th>Temporary</th>
11
		    <th>Actions</th>
12
		</tr>
13
	</thead>
14
	<tbody>
15
		[% FOREACH record IN uploads %]
16
		<tr>
17
		    <td>[% record.name %]</td>
18
		    <td>[% record.filesize %]</td>
19
		    <td>[% record.hashvalue %]</td>
20
		    <td>[% record.uploadcategorycode %]</td>
21
	        <td>[% IF record.public %]Yes[% ELSE %]No[% END %]</td>
22
	        <td>[% IF record.permanent %]No[% ELSE %]Yes[% END %]</td>
23
		    <td class="actions">
24
		        <button class="btn btn-mini choose_entry" data-record-id="[% record.id %]" onclick="selectFileToAssociate([% record.id %])"><i class="fa fa-view"></i>Choose</button>
25
		    </td>
26
		</tr>
27
		[% END %]
28
	</tbody>
29
</table>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt (-1 / +55 lines)
Lines 16-22 function StartUpload() { Link Here
16
    $('#uploadform button.submit').prop('disabled',true);
16
    $('#uploadform button.submit').prop('disabled',true);
17
    $("#fileuploadstatus").show();
17
    $("#fileuploadstatus").show();
18
    $("#uploadedfileid").val('');
18
    $("#uploadedfileid").val('');
19
    xhr= AjaxUpload( $('#fileToUpload'), $('#fileuploadprogress'), 'temp=1', cbUpload );
19
    xhr= AjaxUpload( $('#fileToUpload'), $('#fileuploadprogress'), 'temp=[% IF SaveCoverOnDisk %]0&category=covers[% ELSE %]1[% END %]', cbUpload );
20
}
20
}
21
function cbUpload( status, fileid ) {
21
function cbUpload( status, fileid ) {
22
    if( status=='done' ) {
22
    if( status=='done' ) {
Lines 33-40 function cbUpload( status, fileid ) { Link Here
33
        $("#processfile").hide();
33
        $("#processfile").hide();
34
    }
34
    }
35
}
35
}
36
[% IF SaveCoverOnDisk %]
37
function searchFile(form){
38
      $.ajax({
39
      url: $(form).attr('action'),
40
      data: $(form).serialize(),
41
      type: 'post',
42
      success: function(html){
43
        $("#searchfilepanel").html(html);
44
      }
45
      , 
46
      complete: function()
47
      {
48
      }
49
  });
50
  return false; 
51
}
52
53
function selectFileToAssociate(fileid){
54
    $("#uploadedfileid").val( fileid );
55
    $('#fileToUpload').prop('disabled',true);
56
    $("#processfile").show();
57
}
58
[% END %]
59
36
$(document).ready(function(){
60
$(document).ready(function(){
37
	$("#processfile").hide();
61
	$("#processfile").hide();
62
38
	$("#zipfile").click(function(){
63
	$("#zipfile").click(function(){
39
		$("#bibnum").hide();
64
		$("#bibnum").hide();
40
	});
65
	});
Lines 47-52 $(document).ready(function(){ Link Here
47
            return false;
72
            return false;
48
        }
73
        }
49
    });
74
    });
75
    [% IF SaveCoverOnDisk %]
76
    $("#searchbutton").on("click",function(e){
77
        e.preventDefault();
78
        searchFile($('#searchfile'));
79
    });
80
    $(".choose_entry").on("click",function(e){
81
        e.preventDefault();
82
        selectFileToAssociate($(this).data("record-id"));
83
    });
84
    [% END %]
50
});
85
});
51
//]]>
86
//]]>
52
</script>
87
</script>
Lines 110-116 $(document).ready(function(){ Link Here
110
        <div id="fileuploadfailed"></div>
145
        <div id="fileuploadfailed"></div>
111
    </div>
146
    </div>
112
</form>
147
</form>
148
[% IF SaveCoverOnDisk %]
149
<form method="post" id="searchfile" action="/cgi-bin/koha/tools/file-search.pl">
150
    <input type="hidden" name="op" value="search"/>
151
    <input type="hidden" name="category" value="covers"/>
152
    <fieldset class="rows">
153
        <legend>Search uploads by name or hashvalue</legend>
154
        <ol>
155
        <li>
156
            <label for="term">Search term: </label>
157
            <input type="text" id="term" name="term" value=""/>
158
        </li>
159
        </ol>
160
        <fieldset class="action">
161
            <button id="searchbutton" class="submit">Search</button>
162
        </fieldset>
163
    </fieldset>
164
</form>
113
165
166
<div id="searchfilepanel"></div>
167
[% END %]
114
    <form method="post" id="processfile" action="/cgi-bin/koha/tools/upload-cover-image.pl" enctype="multipart/form-data">
168
    <form method="post" id="processfile" action="/cgi-bin/koha/tools/upload-cover-image.pl" enctype="multipart/form-data">
115
<fieldset class="rows">
169
<fieldset class="rows">
116
        <input type="hidden" name="uploadedfileid" id="uploadedfileid" value="" />
170
        <input type="hidden" name="uploadedfileid" id="uploadedfileid" value="" />
(-)a/tools/file-search.pl (+67 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Converted to new plugin style (Bug 13437)
4
5
# Copyright 2000-2002 Katipo Communications
6
#
7
# This file is part of Koha.
8
#
9
# Koha is free software; you can redistribute it and/or modify it
10
# under the terms of the GNU General Public License as published by
11
# the Free Software Foundation; either version 3 of the License, or
12
# (at your option) any later version.
13
#
14
# Koha is distributed in the hope that it will be useful, but
15
# WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
# GNU General Public License for more details.
18
#
19
# You should have received a copy of the GNU General Public License
20
# along with Koha; if not, see <http://www.gnu.org/licenses>.
21
22
use Modern::Perl;
23
use CGI qw ( -utf8 );
24
use JSON;
25
26
use warnings;
27
no warnings 'redefine'; # otherwise loading up multiple plugins fills the log with subroutine redefine warnings
28
29
use C4::Auth;
30
use C4::Context;
31
use C4::Output;
32
33
use Koha::Upload;
34
35
use Data::Dumper;
36
37
use vars qw($debug);
38
39
BEGIN {
40
    $debug = $ENV{DEBUG} || 0;
41
}
42
43
my $dbh = C4::Context->dbh;
44
my $input = CGI->new;
45
$debug or $debug = $input->param('debug') || 0;
46
my $content_type = 'json';
47
48
my $term = $input->param('term');
49
50
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
51
    {   template_name   => "tools/file-search.tt",
52
        query           => $input,
53
        type            => "intranet",
54
        authnotrequired => 0,
55
        flagsrequired   => { editcatalogue => '*' },
56
        debug           => 1,
57
    }
58
);
59
60
my $upar = {};
61
my $h = { term => $term, uploadcategorycode => 'covers' };
62
my @uploads = Koha::Upload->new($upar)->get($h);
63
$template->param(
64
    uploads => \@uploads,
65
);
66
67
output_with_http_headers $input, $cookie, $template->output, 'html';
(-)a/tools/upload-cover-image.pl (-2 / +3 lines)
Lines 49-54 use C4::Output; Link Here
49
use C4::Images;
49
use C4::Images;
50
use Koha::Upload;
50
use Koha::Upload;
51
use C4::Log;
51
use C4::Log;
52
use Data::Dumper;
52
53
53
my $debug = 1;
54
my $debug = 1;
54
55
Lines 79-94 my $error; Link Here
79
80
80
$template->{VARS}->{'filetype'}     = $filetype;
81
$template->{VARS}->{'filetype'}     = $filetype;
81
$template->{VARS}->{'biblionumber'} = $biblionumber;
82
$template->{VARS}->{'biblionumber'} = $biblionumber;
83
$template->{VARS}->{'SaveCoverOnDisk'} = C4::Context->preference("SaveCoverOnDisk"); 
82
84
83
my $total = 0;
85
my $total = 0;
84
85
if ($fileID) {
86
if ($fileID) {
86
    my $upload = Koha::Upload->new->get({ id => $fileID, filehandle => 1 });
87
    my $upload = Koha::Upload->new->get({ id => $fileID, filehandle => 1 });
87
    if ( $filetype eq 'image' ) {
88
    if ( $filetype eq 'image' ) {
88
        my $fh       = $upload->{fh};
89
        my $fh       = $upload->{fh};
89
        my $srcimage = GD::Image->new($fh);
90
        my $srcimage = GD::Image->new($fh);
90
        if ( defined $srcimage ) {
91
        if ( defined $srcimage ) {
91
            my $dberror = PutImage( $biblionumber, $srcimage, $replace );
92
            my $dberror = PutImage( $biblionumber, $srcimage, $replace, $fileID );
92
            if ($dberror) {
93
            if ($dberror) {
93
                $error = 'DBERR';
94
                $error = 'DBERR';
94
            }
95
            }
(-)a/tools/upload-file.pl (-1 / +2 lines)
Lines 28-33 use URI::Escape; Link Here
28
use C4::Context;
28
use C4::Context;
29
use C4::Auth qw/check_cookie_auth haspermission/;
29
use C4::Auth qw/check_cookie_auth haspermission/;
30
use Koha::Upload;
30
use Koha::Upload;
31
use Data::Dumper;
31
32
32
# upload-file.pl must authenticate the user
33
# upload-file.pl must authenticate the user
33
# before processing the POST request,
34
# before processing the POST request,
Lines 80-84 sub upload_pars { # this sub parses QUERY_STRING in order to build the Link Here
80
            $rv->{$p} = $2;
81
            $rv->{$p} = $2;
81
        }
82
        }
82
    }
83
    }
84
    warn Dumper($rv);
83
    return $rv;
85
    return $rv;
84
}
86
}
85
- 

Return to bug 17650