Bugzilla – Attachment 42413 Details for
Bug 14321
Merge UploadedFile and UploadedFiles into Koha::Upload
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 14321: Integrate Upload.pm into Koha
Bug-14321-Integrate-Uploadpm-into-Koha.patch (text/plain), 47.16 KB, created by
Marcel de Rooy
on 2015-09-04 15:43:34 UTC
(
hide
)
Description:
Bug 14321: Integrate Upload.pm into Koha
Filename:
MIME Type:
Creator:
Marcel de Rooy
Created:
2015-09-04 15:43:34 UTC
Size:
47.16 KB
patch
obsolete
>From 6644509a2c5669a623e12a21578c6090d7819de0 Mon Sep 17 00:00:00 2001 >From: Marcel de Rooy <m.de.rooy@rijksmuseum.nl> >Date: Sat, 8 Aug 2015 17:28:25 +0200 >Subject: [PATCH] Bug 14321: Integrate Upload.pm into Koha >Content-Type: text/plain; charset=utf-8 > >This patch makes the following changes to achieve that: >[1] Use Upload.pm in stage-marc-import.pl, upload-cover-image.pl, > offline_circ/process_koc.pl and enqueue_koc.pl. >[2] A new file-upload.js replaces file-upload.inc in the associated template. > We now use ajax to get progress figures instead of launching perl script > upload-file-progress. > The js changes now also allow for aborting a file upload. >[3] Adds a tools/upload script and template. It allows to upload multiple > files at once. >[4] Makes upload-file return error messages in JSON. For a multiple upload, > we could have some files with errors and others without errors. > The upload is now marked as Failed only if there was no upload at all. >[5] The upload plugin is converted to use tools/upload with plugin param. > Deleting an upload is now presented via the search results form. > >NOTE: In editing the process_koc.tt I noticed that the form enqueuefile was >hidden and no longer used (with associated code in process_koc.pl). When a >file has been uploaded, I display the form again (with the Apply directly >button). The code still works. > >NOTE: We fix an error in upload-file from one of the patches of bug 6874. >The userid of the Koha admin user is passed to haspermission, but we >should pick the userid from the session. > >NOTE: Bug 14686 will add a specific permission for tools/upload.pl, and >will add the tools/upload script to the Tools menu. >For now, you need edit_catalogue to start upload.pl and you will >additionally need a permission like upload_local_cover_images >to successfully upload a new file. > >Test plan: >[1] Upload a marc file in stage-marc-import. (This is temp storage.) >[2] Check new entry in table uploaded_files. Look for the file in your > temporary directory (/tmp ?), subfolder koha_upload. > Bonus: Remove permissions on this subfolder. Retry, check error and > restore permissions again. >[3] Upload another (larger) file and abort the upload. Check table and > directory again. You should have a partial file, but no record. >[4] Verify that Stage for import still works as expected. >[5] Test Upload local cover image. (Enable OPACLocalCoverImages.) You can > test an individual image or a zip file including images and a file > called datalink.txt (with lines biblionumber,filename). >[6] Test uploading a offline circulation file: > Enable AllowOfflineCirculation, and create a koc file (plain text): > Line1: Version=1.0\tA=1\tB=2 > Line2: 2015-08-06 08:00:00 345\treturn\t[barcode] > Note: Replace tabs and barcode. The number of tabs is essential! > Checkout the item with your barcode. > Go to Offline circulation file upload. Upload and click Apply directly. > Checkout again. Upload again, click Add to offline circulation queue. >[7] Upload three files via tools/upload.pl with a category and marked as > public. Check the results in the table. > Verify that you can download the file in OPAC without being logged in. >[8] Pick one new file and one of the files of step 7. Upload them in the > same category. One upload should succeed. Check for reported error. >[9] Connect upload.pl to field 856$u. > Goto Cataloguing editor. > In an empty 856$u, click the tag editor. Upload a file and click Choose. > Save the record. Open the record in the OPAC and click the link. > Copy this link to your clipboard for next step. >[A] Go back to editor. Click the tag editor on the same 856 field. > Choose for Delete. > Open the link in your clipboard again. Error message? >[B] Check the process of upload, search, download and delete of an upload > with some diacritical characters in the filename. (Bonus points for > adding special chars in the category code.) > Note: You can add categories via authorized values, UPLOAD key. >--- > cataloguing/value_builder/upload.pl | 153 ++------- > koha-tmpl/intranet-tmpl/prog/en/js/file-upload.js | 32 ++ > .../prog/en/modules/offline_circ/process_koc.tt | 39 ++- > .../prog/en/modules/tools/stage-marc-import.tt | 64 +++- > .../prog/en/modules/tools/upload-images.tt | 45 ++- > .../intranet-tmpl/prog/en/modules/tools/upload.tt | 342 ++++++++++++++++++++ > .../bootstrap/en/modules/opac-retrieve-file.tt | 6 + > offline_circ/enqueue_koc.pl | 6 +- > offline_circ/process_koc.pl | 8 +- > opac/opac-retrieve-file.pl | 36 ++- > tools/stage-marc-import.pl | 9 +- > tools/upload-cover-image.pl | 8 +- > tools/upload-file.pl | 82 ++--- > tools/upload.pl | 98 ++++++ > 14 files changed, 708 insertions(+), 220 deletions(-) > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/js/file-upload.js > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload.tt > create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-retrieve-file.tt > create mode 100755 tools/upload.pl > >diff --git a/cataloguing/value_builder/upload.pl b/cataloguing/value_builder/upload.pl >index 72bed79..e26bca7 100755 >--- a/cataloguing/value_builder/upload.pl >+++ b/cataloguing/value_builder/upload.pl >@@ -4,6 +4,7 @@ > > # This file is part of Koha. > # >+# Copyright (C) 2015 Rijksmuseum > # Copyright (C) 2011-2012 BibLibre > # > # Koha is free software; you can redistribute it and/or modify it >@@ -20,145 +21,33 @@ > # along with Koha; if not, see <http://www.gnu.org/licenses>. > > use Modern::Perl; >-use CGI qw/-utf8/; > >-use C4::Auth; >-use C4::Context; >-use C4::Output; >-use C4::UploadedFiles; >+# This plugin does not use the plugin launcher. It refers to tools/upload.pl. >+# That script and template support using it as a plugin. >+ >+# If the plugin is called with the pattern [id=some_hashvalue] in the >+# corresponding field, it starts the upload script as a search, providing >+# the possibility to delete the uploaded file. If the field is empty, you >+# can upload a new file. > > my $builder = sub { > my ( $params ) = @_; >- my $function_name = $params->{id}; >- my $res = " >- <script type=\"text/javascript\"> >- function Click$function_name(event) { >+ return <<"SCRIPT"; >+<script type=\"text/javascript\"> >+ function Click$params->{id}(event) { > var index = event.data.id; >- var id = document.getElementById(index).value; >- var IsFileUploadUrl=0; >- if (id.match(/opac-retrieve-file/)) { >- IsFileUploadUrl=1; >- } >- if(id.match(/id=([0-9a-f]+)/)){ >- id = RegExp.\$1; >- } >- var newin=window.open(\"../cataloguing/plugin_launcher.pl?plugin_name=upload.pl&index=\"+index+\"&id=\"+id+\"&from_popup=0\"+\"&IsFileUploadUrl=\"+IsFileUploadUrl, 'upload', 'width=600,height=400,toolbar=false,scrollbars=no'); >- newin.focus(); >- } >- </script> >-"; >- return $res; >-}; >- >-my $launcher = sub { >- my ( $params ) = @_; >- my $input = $params->{cgi}; >- my $index = $input->param('index'); >- my $id = $input->param('id'); >- my $delete = $input->param('delete'); >- my $uploaded_file = $input->param('uploaded_file'); >- my $from_popup = $input->param('from_popup'); >- my $isfileuploadurl = $input->param('IsFileUploadUrl'); >- my $dangling = C4::UploadedFiles::DanglingEntry($id,$isfileuploadurl); >- my $template_name; >- if ($delete || ($id && ($dangling==0 || $dangling==1))) { >- $template_name = "upload_delete_file.tt"; >- } >- else { >- $template_name = "upload.tt"; >- } >- >- my ( $template, $loggedinuser, $cookie ) = get_template_and_user( >- { template_name => "cataloguing/value_builder/$template_name", >- query => $input, >- type => "intranet", >- authnotrequired => 0, >- flagsrequired => { editcatalogue => '*' }, >- debug => 1, >- } >- ); >- >- if ($dangling==2) { >- $template->param( dangling => 1 ); >- } >- >- # Dealing with the uploaded file >- my $dir = $input->param('uploadcategory'); >- if ($uploaded_file and $dir) { >- my $fh = $input->upload('uploaded_file'); >- >- $id = C4::UploadedFiles::UploadFile($uploaded_file, $dir, $fh->handle); >- my $OPACBaseURL = C4::Context->preference('OPACBaseURL') // ''; >- $OPACBaseURL =~ s#/$##; >- if (!$OPACBaseURL) { >- $template->param(MissingURL => 1); >- } >- if($id && $OPACBaseURL) { >- my $return = "$OPACBaseURL/cgi-bin/koha/opac-retrieve-file.pl?id=$id"; >- $template->param( >- success => 1, >- return => $return, >- uploaded_file => $uploaded_file, >- ); >- } else { >- $template->param(error => 1); >- } >- } elsif ($delete || ($id && ($dangling==0 || $dangling==1))) { >- # If there's already a file uploaded for this field, >- # We handle its deletion >- if ($delete) { >- if(C4::UploadedFiles::DelUploadedFile($id)==0) {; >- $template->param(error => 1); >+ var str = document.getElementById(index).value; >+ var myurl, term; >+ if( str && str.match(/id=([0-9a-f]+)/) ) { >+ term = RegExp.\$1; >+ myurl = '../tools/upload.pl?op=search&index='+index+'&term='+term+'&plugin=1'; > } else { >- $template->param(success => 1); >+ myurl = '../tools/upload.pl?op=new&index='+index+'&plugin=1'; > } >+ window.open( myurl, 'tag_editor', 'width=800,height=400,toolbar=false,scrollbars=yes' ); > } >- } else { >- my $upload_path = C4::Context->config('upload_path'); >- if ($upload_path) { >- my $filefield = CGI::filefield( >- -name => 'uploaded_file', >- -size => 50, >- ); >- $template->param( >- filefield => $filefield, >- uploadcategories => C4::UploadedFiles::getCategories(), >- ); >- } else { >- $template->param( error_upload_path_not_configured => 1 ); >- } >- >- if (!$uploaded_file && !$dir && $from_popup) { >- $template->param(error_nothing_selected => 1); >- } >- elsif (!$uploaded_file && $dir) { >- $template->param(error_no_file_selected => 1); >- } >- if ($uploaded_file and not $dir) { >- $template->param(error_no_dir_selected => 1); >- } >- >- } >- >- $template->param( >- index => $index, >- id => $id, >- ); >- >- output_html_with_http_headers $input, $cookie, $template->output; >+</script> >+SCRIPT > }; > >-return { builder => $builder, launcher => $launcher }; >- >-1; >- >-__END__ >- >-=head1 upload.pl >- >-This plugin allows to upload files on the server and reference it in a marc >-field. >- >-It uses config variable upload_path and pref OPACBaseURL. >- >-=cut >+return { builder => $builder }; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/js/file-upload.js b/koha-tmpl/intranet-tmpl/prog/en/js/file-upload.js >new file mode 100644 >index 0000000..f6817cb >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/js/file-upload.js >@@ -0,0 +1,32 @@ >+function AjaxUpload ( input, progressbar, xtra, callback ) { >+ // input and progressbar are jQuery objects >+ // callback is the callback function for completion >+ var formData= new FormData(); >+ $.each( input.prop('files'), function( dx, file ) { >+ formData.append( "uploadfile", file ); >+ }); >+ var xhr= new XMLHttpRequest(); >+ var url= '/cgi-bin/koha/tools/upload-file.pl?' + xtra; >+ progressbar.val( 0 ); >+ progressbar.next('.fileuploadpercent').text( '0' ); >+ xhr.open('POST', url, true); >+ xhr.upload.onprogress = function (e) { >+ var p = Math.round( (e.loaded/e.total) * 100 ); >+ progressbar.val( p ); >+ progressbar.next('.fileuploadpercent').text( p ); >+ } >+ xhr.onload = function (e) { >+ var data = JSON.parse( xhr.responseText ); >+ if( data.status == 'done' ) { >+ progressbar.val( 100 ); >+ progressbar.next('.fileuploadpercent').text( '100' ); >+ } >+ callback( data.status, data.fileid, data.errors ); >+ } >+ xhr.onerror = function (e) { >+ // Probably only fires for network failure >+ alert('An error occurred while uploading.'); >+ } >+ xhr.send( formData ); >+ return xhr; >+} >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/process_koc.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/process_koc.tt >index 76c317a..714596f 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/process_koc.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/process_koc.tt >@@ -1,22 +1,43 @@ > [% INCLUDE 'doc-head-open.inc' %] > <title>Koha › Circulation › Offline circulation file upload</title> > [% INCLUDE 'doc-head-close.inc' %] >-[% INCLUDE 'file-upload.inc' %] >+ > <script type="text/javascript" src="[% themelang %]/js/background-job-progressbar.js"></script> >+<script type="text/javascript" src="[% themelang %]/js/file-upload.js"></script> > <script type="text/javascript"> > //<![CDATA[ >+var xhr; > $(document).ready(function(){ > $("#enqueuefile").hide(); > $("#processfile").hide(); > }); > >-function CheckUpload(f){ >- if (f.fileToUpload.value == ""){ >- alert(_("Please choose a file to upload")); >+function StartUpload() { >+ if( $('#fileToUpload').prop('files').length == 0 ) return; >+ $('#fileuploadform input.submit').prop('disabled',true); >+ $("#fileuploadfailed").hide(); >+ $("#processfile").hide(); >+ $("#fileuploadstatus").show(); >+ $("form#processfile #uploadedfileid").val(''); >+ $("form#enqueuefile #uploadedfileid").val(''); >+ xhr= AjaxUpload( $('#fileToUpload'), $('#fileuploadprogress'), 'temp=1', cbUpload ); >+} >+ >+function cbUpload( status, fileid ) { >+ if( status=='done' ) { >+ $("form#processfile #uploadedfileid").val( fileid ); >+ $("form#enqueuefile #uploadedfileid").val( fileid ); >+ $('#fileToUpload').prop('disabled',true); >+ $("#processfile").show(); >+ $("#enqueuefile").show(); > } else { >- return ajaxFileUpload() >+ $("#fileuploadstatus").hide(); >+ $("#fileuploadfailed").show(); >+ $("#fileuploadfailed").text( _("Upload status: ") + >+ ( status=='failed'? _("Failed"): >+ ( status=='denied'? _("Denied"): status )) >+ ); > } >- return false; > } > > function CheckForm(f) { >@@ -25,6 +46,8 @@ function CheckForm(f) { > } else { > $("#fileuploadstatus").hide(); > $("#fileuploadform").slideUp(); >+ $("#mainformsubmit").prop('disabled',true); >+ $("#queueformsubmit").prop('disabled',true); > return submitBackgroundJob(f); > } > return false; >@@ -70,10 +93,10 @@ function CheckForm(f) { > <fieldset class="brief"> > <ol><li><label for="fileToUpload">Choose .koc file: </label> > <input type="file" id="fileToUpload" size="50" name="fileToUpload" /></li></ol> >- <fieldset class="action"><input type="button" class="submit" value="Upload file" onclick="CheckUpload(this.form);" /></fieldset> >+ <fieldset class="action"><input type="button" class="submit" value="Upload file" onclick="StartUpload();return false;" /></fieldset> > </fieldset> > </form> >- <div id="fileuploadstatus" style="display:none">Upload progress: <div id="fileuploadprogress"></div> <span id="fileuploadpercent">0</span>%</div> >+ <div id="fileuploadstatus" style="display:none">Upload progress: <progress id="fileuploadprogress" min="0" max="100" value="0"></progress> <span class="fileuploadpercent">0</span>%</div> > <div id="fileuploadfailed" style="display:none"></div> > </div> > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt >index dea732a..67a07f4 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/stage-marc-import.tt >@@ -1,14 +1,19 @@ > [% INCLUDE 'doc-head-open.inc' %] > <title>Koha › Tools › Stage MARC records for import</title> > [% INCLUDE 'doc-head-close.inc' %] >-[% INCLUDE 'file-upload.inc' %] >+ > <script type="text/javascript" src="[% themelang %]/js/background-job-progressbar.js"></script> >+<script type="text/javascript" src="[% themelang %]/js/file-upload.js"></script> >+ > <style type="text/css"> >- #uploadpanel,#fileuploadstatus,#fileuploadfailed,#jobpanel,#jobstatus,#jobfailed { display : none; } >+ #fileuploadstatus,#fileuploadfailed,#fileuploadcancel,#jobpanel,#jobstatus,#jobfailed { display : none; } > #fileuploadstatus,#jobstatus { margin:.4em; } >- #fileuploadprogress,#jobprogress{ width:150px;height:10px;border:1px solid #666;background:url('[% interface %]/[% theme %]/img/progress.png') -300px 0px no-repeat; }</style> >+ #fileuploadprogress,#jobprogress { width:150px;height:10px;border:1px solid #666;background:url('[% interface %]/[% theme %]/img/progress.png') -300px 0px no-repeat; } >+</style> >+ > <script type="text/javascript"> > //<![CDATA[ >+var xhr; > $(document).ready(function(){ > $("#processfile").hide(); > $("#record_type").change(function() { >@@ -27,7 +32,43 @@ function CheckForm(f) { > } > return false; > } >- >+function StartUpload() { >+ if( $('#fileToUpload').prop('files').length == 0 ) return; >+ $('#fileuploadbutton').hide(); >+ $("#fileuploadfailed").hide(); >+ $("#processfile").hide(); >+ $("#fileuploadstatus").show(); >+ $("#uploadedfileid").val(''); >+ xhr= AjaxUpload( $('#fileToUpload'), $('#fileuploadprogress'), 'temp=1', cbUpload ); >+ $("#fileuploadcancel").show(); >+} >+function CancelUpload() { >+ if( xhr ) xhr.abort(); >+ $("#fileuploadstatus").hide(); >+ $('#fileuploadbutton').show(); >+ $("#fileuploadcancel").hide(); >+ $("#fileuploadfailed").show(); >+ $("#fileuploadfailed").text( _("Upload status: Cancelled ") ); >+} >+function cbUpload( status, fileid ) { >+ if( status=='done' ) { >+ $("#uploadedfileid").val( fileid ); >+ $('#fileToUpload').prop('disabled',true); >+ $('#fileuploadbutton').prop('disabled',true); >+ $('#fileuploadbutton').show(); >+ $("#fileuploadcancel").hide(); >+ $("#processfile").show(); >+ } else { >+ $('#fileuploadbutton').show(); >+ $("#fileuploadcancel").hide(); >+ $("#fileuploadstatus").hide(); >+ $("#fileuploadfailed").show(); >+ $("#fileuploadfailed").text( _("Upload status: ") + >+ ( status=='failed'? _("Failed"): >+ ( status=='denied'? _("Denied"): status )) >+ ); >+ } >+} > //]]> > </script> > </head> >@@ -90,11 +131,20 @@ function CheckForm(f) { > <input type="file" id="fileToUpload" name="fileToUpload" /> > </div> </li> > </ol> >- <fieldset class="action"><button class="submit" onclick="return ajaxFileUpload();">Upload file</button></fieldset> >+ <fieldset class="action"> >+ <button id="fileuploadbutton" onclick="StartUpload(); return false;">Upload file</button> >+ <button id="fileuploadcancel" onclick="CancelUpload(); return false;">Cancel</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> >+ <div id="fileuploadpanel"> >+ <div id="fileuploadstatus">Upload progress: >+ <progress id="fileuploadprogress" min="0" max="100" value="0"> >+ </progress> >+ <span class="fileuploadpercent">0</span>% >+ </div> >+ <div id="fileuploadfailed"></div> >+ </div> > </form> > > <form method="post" id="processfile" action="[% SCRIPT_NAME %]" enctype="multipart/form-data"> >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 >index 4565995..f501a90 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload-images.tt >@@ -1,14 +1,40 @@ > [% INCLUDE 'doc-head-open.inc' %] > <title>Koha › Tools › Upload images</title> > [% INCLUDE 'doc-head-close.inc' %] >-[% INCLUDE 'file-upload.inc' %] >+ > <script type="text/javascript" src="[% themelang %]/js/background-job-progressbar.js"></script> >+<script type="text/javascript" src="[% themelang %]/js/file-upload.js"></script> >+ > <style type="text/css"> >- #uploadpanel,#fileuploadstatus,#fileuploadfailed,#jobpanel,#jobstatus,#jobfailed { display : none; } >+ #fileuploadstatus,#fileuploadfailed,#jobpanel,#jobstatus,#jobfailed { display : none; } > #fileuploadstatus,#jobstatus { margin:.4em; } >- #fileuploadprogress,#jobprogress{ width:150px;height:10px;border:1px solid #666;background:url('[% interface %]/[% theme %]/img/progress.png') -300px 0px no-repeat; }</style> >+ #fileuploadprogress,#jobprogress { width:150px;height:10px;border:1px solid #666;background:url('[% interface %]/[% theme %]/img/progress.png') -300px 0px no-repeat; } >+</style> >+ > <script type="text/javascript"> > //<![CDATA[ >+function StartUpload() { >+ if( $('#fileToUpload').prop('files').length == 0 ) return; >+ $('#uploadform button.submit').prop('disabled',true); >+ $("#fileuploadstatus").show(); >+ $("#uploadedfileid").val(''); >+ xhr= AjaxUpload( $('#fileToUpload'), $('#fileuploadprogress'), 'temp=1', cbUpload ); >+} >+function cbUpload( status, fileid ) { >+ if( status=='done' ) { >+ $("#uploadedfileid").val( fileid ); >+ $('#fileToUpload').prop('disabled',true); >+ $("#processfile").show(); >+ } else { >+ $("#fileuploadstatus").hide(); >+ $("#fileuploadfailed").show(); >+ $("#fileuploadfailed").text( _("Upload status: ") + >+ ( status=='failed'? _("Failed"): >+ ( status=='denied'? _("Denied"): status )) >+ ); >+ $("#processfile").hide(); >+ } >+} > $(document).ready(function(){ > $("#processfile").hide(); > $("#zipfile").click(function(){ >@@ -19,7 +45,8 @@ $(document).ready(function(){ > }); > $("#uploadfile").validate({ > submitHandler: function(form) { >- ajaxFileUpload(); >+ StartUpload(); >+ return false; > } > }); > }); >@@ -76,8 +103,14 @@ $(document).ready(function(){ > <fieldset class="action"><button class="submit">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> >+ <div id="uploadpanel"> >+ <div id="fileuploadstatus">Upload progress: >+ <progress min="0" max="100" value="0" id="fileuploadprogress"> >+ </progress> >+ <span class="fileuploadpercent">0</span>% >+ </div> >+ <div id="fileuploadfailed"></div> >+ </div> > </form> > > <form method="post" id="processfile" action="[% SCRIPT_NAME %]" enctype="multipart/form-data"> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload.tt >new file mode 100644 >index 0000000..44b8c0b >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/upload.tt >@@ -0,0 +1,342 @@ >+[% INCLUDE 'doc-head-open.inc' %] >+[% USE Koha %] >+[% IF plugin %] >+ <title>Upload plugin</title> >+[% ELSE %] >+ <title>Koha › Tools › Upload</title> >+[% END %] >+[% INCLUDE 'doc-head-close.inc' %] >+ >+[% BLOCK plugin_pars %] >+ [% IF plugin %] >+ <input type="hidden" name="plugin" value="1" /> >+ <input type="hidden" name="index" value="[% index %]" /> >+ [% END %] >+[% END %] >+ >+[% BLOCK breadcrumbs %] >+ <div id="breadcrumbs"> >+ <a href="/cgi-bin/koha/mainpage.pl">Home</a> >+ › >+ <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> >+ › >+ <a href="/cgi-bin/koha/tools/upload.pl">Upload</a> >+ › >+ <span id="lastbreadcrumb"> >+ [% IF mode=='new' || mode =='deleted'%] >+ Add new upload or search >+ [% ELSE %] >+ Results >+ [% END %] >+ </span> >+ </div> >+[% END %] >+ >+[% BLOCK form_new %] >+ <form method="post" action="[% SCRIPT_NAME %]" id="uploadfile" enctype="multipart/form-data"> >+ [% PROCESS plugin_pars %] >+ <fieldset class="rows" id="uploadform"> >+ <legend>Upload new files</legend> >+ <ol> >+ <li> >+ <div id="fileuploadform"> >+ <label for="fileToUpload">Select files: </label> >+ <input type="file" id="fileToUpload" name="fileToUpload" multiple/> >+ </div> >+ </li> >+ [% IF uploadcategories %] >+ <li> >+ <label for="uploadcategory">Category: </label> >+ <select id="uploadcategory" name="uploadcategory"> >+ [% IF !plugin %] >+ <option value="" disabled hidden selected></option> >+ [% END %] >+ [% FOREACH cat IN uploadcategories %] >+ <option value="[% cat.code %]">[% cat.name %]</option> >+ [% END %] >+ </select> >+ </li> >+ [% END %] >+ [% IF !plugin %] >+ <li> >+ [% IF uploadcategories %] >+ <div class="hint">Note: For temporary uploads do not select a category.</div> >+ [% ELSE %] >+ <div class="hint">Note: No upload categories have been defined. All uploads will be marked as temporary.</div> >+ [% END %] >+ </li> >+ [% END %] >+ <li> >+ [% IF plugin %] >+ <input type="hidden" id="public" name="public" value="1"/> >+ [% ELSE %] >+ <label> </label> >+ <input type="checkbox" id="public" name="public"> >+ Allow public downloads >+ </input> >+ [% END %] >+ </li> >+ </ol> >+ <fieldset class="action"> >+ <button id="fileuploadbutton" onclick="StartUpload(); return false;">Upload</button> >+ <button id="fileuploadcancel" onclick="CancelUpload(); return false;">Cancel</button> >+ </fieldset> >+ </fieldset> >+ <div id="fileuploadpanel"> >+ <div id="fileuploadstatus">Upload progress: >+ <progress id="fileuploadprogress" min="0" max="100" value="0"> >+ </progress> >+ <span class="fileuploadpercent">0</span>% >+ </div> >+ <div id="fileuploadfailed"></div> >+ </div> >+ </form> >+[% END %] >+ >+[% BLOCK form_search %] >+ <form method="post" id="searchfile" action="[% SCRIPT_NAME %]" enctype="multipart/form-data"> >+ [% PROCESS plugin_pars %] >+ <input type="hidden" name="op" value="search"/> >+ <fieldset class="rows"> >+ <legend>Search uploads by name or hashvalue</legend> >+ <ol> >+ <li> >+ <label for="searchupload">Search term: </label> >+ <input type="text" id="term" name="term" value=""/> >+ </li> >+ <li> >+ <fieldset class="action"> >+ <button id="searchbutton" onclick="return CheckSearch();" class="submit">Search</button> >+ </fieldset> >+ </li> >+ </ol> >+ </fieldset> >+ </form> >+[% END %] >+ >+[% BLOCK submitter %] >+ <form id="submitter" style="display:none;" method="post"> >+ [% PROCESS plugin_pars %] >+ <input type="hidden" name="op" id="op" value=""/> >+ <input type="hidden" name="id" id="id" value="" /> >+ <input type="hidden" name="msg" id="msg" value="" /> >+ </form> >+[% END %] >+ >+[% BLOCK closer %] >+ [% IF plugin %] >+ <form id="closer"> >+ <fieldset class="action"> >+ <button onclick="window.close();return false;">Close</button> >+ </fieldset> >+ </form> >+ [% END %] >+[% END %] >+ >+[% BLOCK newsearch %] >+ <form id="newsearch"> >+ <fieldset class="action"> >+ <button onclick="SubmitMe('new'); return false;">New search</button> >+ [% IF plugin %] >+ <button onclick="window.close();return false;">Close</button> >+ [% END %] >+ </fieldset> >+ </form> >+[% END %] >+ >+[% BLOCK table_results %] >+ <table> >+ <thead> >+ <tr> >+ <th>Filename</td> >+ <th>Size</td> >+ <th>Hashvalue</td> >+ <th>Category</td> >+ [% IF !plugin %]<th>Public</td>[% END %] >+ [% IF !plugin %]<th>Temporary</td>[% END %] >+ <th>Actions</td> >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH record IN uploads %] >+ <tr> >+ <td>[% record.name %]</td> >+ <td>[% record.filesize %]</td> >+ <td>[% record.hashvalue %]</td> >+ <td>[% record.categorycode %]</td> >+ [% IF !plugin %] >+ <td>[% IF record.public %]Yes[% ELSE %]No[% END %]</td> >+ <td>[% IF record.permanent %]No[% ELSE %]Yes[% END %]</td> >+ [% END %] >+ <td> >+ [% IF plugin %] >+ <a href="" onclick="Choose('[% record.hashvalue %]'); return false;">Choose</a> >+ [% END %] >+ <a href="" onclick="SubmitMe( 'download', [% record.id %] ); return false;">Download</a> >+ <a href="" onclick="ClearField(); SubmitMe( 'delete', [% record.id %] ); return false;">Delete</a> >+ </td> >+ </tr> >+ [% END %] >+ </tbody> >+ </table> >+[% END %] >+ >+<style type="text/css"> >+ #fileuploadstatus,#fileuploadfailed { display : none; } >+ #fileuploadstatus { margin:.4em; } >+ #fileuploadprogress { width:150px;height:10px;border:1px solid #666;background:url('[% interface %]/[% theme %]/img/progress.png') -300px 0px no-repeat; } >+</style> >+ >+<script type="text/javascript"> >+//<![CDATA[ >+ var errMESSAGES = [ >+ "Error 0: Not in use", >+ _("This file already exists (in this category)."), >+ _("File could not be created. Check permissions."), >+ _("Your koha-conf.xml does not contain a valid upload_path."), >+ _("No temporary directory found."), >+ _("File could not be read."), >+ _("File has been deleted."), >+ _("File could not be deleted."), >+ ]; >+//]]> >+</script> >+<script type="text/javascript" src="[% themelang %]/js/file-upload.js"></script> >+<script type="text/javascript"> >+//<![CDATA[ >+function StartUpload() { >+ if( $('#fileToUpload').prop('files').length == 0 ) return; >+ $('#fileToUpload').prop('disabled',true); >+ $('#fileuploadbutton').hide(); >+ $("#fileuploadcancel").show(); >+ $("#fileuploadfailed").html(''); >+ $("#myalerts").hide(''); >+ $("#myalerts").html(''); >+ $("#fileuploadstatus").show(); >+ $("#uploadedfileid").val(''); >+ $("#searchfile").hide(); >+ $("#lastbreadcrumb").text( _("Add a new upload") ); >+ >+ var cat, xtra=''; >+ if( $("#uploadcategory").val() ) >+ cat = encodeURIComponent( $("#uploadcategory").val() ); >+ if( cat ) xtra= 'category=' + cat + '&'; >+ [% IF plugin %] >+ xtra = xtra + 'public=1&temp=0'; >+ [% ELSE %] >+ if( !cat ) xtra = 'temp=1&'; >+ if( $('#public').prop('checked') ) xtra = xtra + 'public=1'; >+ [% END %] >+ xhr= AjaxUpload( $('#fileToUpload'), $('#fileuploadprogress'), xtra, cbUpload ); >+} >+function CancelUpload() { >+ if( xhr ) xhr.abort(); >+ $("#fileuploadstatus").hide(); >+ $('#fileToUpload').prop('disabled', false); >+ $('#fileuploadbutton').show(); >+ $("#fileuploadcancel").hide(); >+ $("#fileuploadfailed").show(); >+ $("#fileuploadfailed").text( _("Upload status: Cancelled ") ); >+} >+function cbUpload( status, fileid, err ) { >+ $('#fileToUpload').prop('disabled', false); >+ if( status=='done' ) { >+ var e = err? JSON.stringify(err): ''; >+ SubmitMe( 'search', fileid, e ); >+ } else { >+ $('#fileuploadbutton').show(); >+ $("#fileuploadcancel").hide(); >+ $("#fileuploadstatus").hide(); >+ $("#fileuploadfailed").show(); >+ $("#fileuploadfailed").html( _("Upload status: ") + >+ ( status=='failed'? _("Failed"): >+ ( status=='denied'? _("Denied"): status )) >+ ); >+ ShowAlerts( err ); >+ } >+} >+function ShowAlerts(err) { >+ var str = ''; >+ for( var file in err ) { >+ str= str + '<p>' + file + ': ' + >+ errMESSAGES[ err[file] ] + '</p>'; >+ } >+ if( str ) { >+ $('#myalerts').html(str); >+ $('#myalerts').show(); >+ } >+} >+function CheckSearch() { >+ if( $("#term").val()=="" ) { >+ alert( _("Please enter a search term.") ); >+ return false; >+ } >+ return true; >+} >+function SubmitMe(op, id, msg ) { >+ $("#submitter #op").val( op ); >+ $("#submitter #id").val( id ); >+ $("#submitter #msg").val( msg ); >+ $("#submitter").submit(); >+} >+function ClearField() { >+ [% IF plugin %] >+ $(window.opener.document).find('#[% index %]').val( '' ); >+ [% END %] >+} >+function Choose(hashval) { >+ var res = '[% Koha.Preference('OPACBaseURL') %]'; >+ res = res.replace( /\/$/, ''); >+ res = res + '/cgi-bin/koha/opac-retrieve-file.pl?id=' + hashval; >+ [% IF index %] >+ $(window.opener.document).find('#[% index %]').val( res ); >+ [% END %] >+ window.close(); >+} >+$(document).ready(function() { >+ [% IF msg %] >+ ShowAlerts( [% msg %] ); >+ [% END %] >+ $("#fileuploadcancel").hide(); >+}); >+//]]> >+</script> >+</head> >+ >+<body id="tools_upload" class="tools"> >+[% IF !plugin %] >+ [% INCLUDE 'header.inc' %] >+ [% INCLUDE 'cat-search.inc' %] >+ [% PROCESS breadcrumbs %] >+[% END %] >+ >+<div id="doc3" class="yui-t2"> >+ <div id="bd"> >+ <div id="yui-main"> >+ <div class="yui-b"> >+ >+<h1>Upload</h1> >+ >+<div class="dialog alert" id="myalerts" style="display:none;"></div> >+ >+[% PROCESS submitter %] >+[% IF mode == 'new' || mode == 'deleted' %] >+ [% PROCESS form_new %] >+ [% PROCESS form_search %] >+ [% PROCESS closer %] >+[% ELSIF mode == 'report' %] >+ [% IF uploads %] >+ <h3>Your request gave the following results:</h3> >+ [% PROCESS table_results %] >+ [% PROCESS closer %] >+ [% ELSE %] >+ <h4>Sorry, your request had no results.</h4> >+ [% PROCESS newsearch %] >+ [% END %] >+[% END %] >+ >+</div> >+</div> >+</div> >+ >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-retrieve-file.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-retrieve-file.tt >new file mode 100644 >index 0000000..581d9ea >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-retrieve-file.tt >@@ -0,0 +1,6 @@ >+[%# This template is called only for a very simple error message %] >+<html> >+<body> >+Your search [% IF hash %]for [% hash %][% END %] was not successful. >+</body> >+</html> >diff --git a/offline_circ/enqueue_koc.pl b/offline_circ/enqueue_koc.pl >index 6798f3f..a81aecb 100755 >--- a/offline_circ/enqueue_koc.pl >+++ b/offline_circ/enqueue_koc.pl >@@ -32,7 +32,7 @@ use C4::Circulation; > use C4::Items; > use C4::Members; > use C4::Stats; >-use C4::UploadedFile; >+use Koha::Upload; > > use Date::Calc qw( Add_Delta_Days Date_to_Days ); > >@@ -60,8 +60,8 @@ my $sessionID = $cookies{'CGISESSID'}->value; > our $dbh = C4::Context->dbh(); > > if ($fileID) { >- my $uploaded_file = C4::UploadedFile->fetch($sessionID, $fileID); >- my $fh = $uploaded_file->fh(); >+ my $upload = Koha::Upload->new->get({ id => $fileID, filehandle => 1 }); >+ my $fh = $upload->{fh}; > my @input_lines = <$fh>; > > my $header_line = shift @input_lines; >diff --git a/offline_circ/process_koc.pl b/offline_circ/process_koc.pl >index d7e5606..21462ef 100755 >--- a/offline_circ/process_koc.pl >+++ b/offline_circ/process_koc.pl >@@ -32,7 +32,7 @@ use C4::Circulation; > use C4::Items; > use C4::Members; > use C4::Stats; >-use C4::UploadedFile; >+use Koha::Upload; > use C4::BackgroundJob; > > use Date::Calc qw( Add_Delta_Days Date_to_Days ); >@@ -69,11 +69,11 @@ if ($completedJobID) { > $template->param(transactions_loaded => 1); > $template->param(messages => $results->{results}); > } elsif ($fileID) { >- my $uploaded_file = C4::UploadedFile->fetch($sessionID, $fileID); >- my $fh = $uploaded_file->fh(); >+ my $upload = Koha::Upload->new->get({ id => $fileID, filehandle => 1 }); >+ my $fh = $upload->{fh}; >+ my $filename = $upload->{name}; > my @input_lines = <$fh>; > >- my $filename = $uploaded_file->name(); > my $job = undef; > > if ($runinbackground) { >diff --git a/opac/opac-retrieve-file.pl b/opac/opac-retrieve-file.pl >index 419f2bd..b443a7c 100755 >--- a/opac/opac-retrieve-file.pl >+++ b/opac/opac-retrieve-file.pl >@@ -19,19 +19,33 @@ > > use Modern::Perl; > use CGI; >+use Encode; > >+use C4::Auth; > use C4::Context; >-use C4::UploadedFiles; >+use C4::Output; >+use Koha::Upload; > >-my $input = new CGI; >+my $input = CGI::->new; >+my $hash = $input->param('id'); # historically called id (used in URLs?) > >-my $id = $input->param('id'); >-my $file = C4::UploadedFiles::GetUploadedFile($id); >-exit 1 if !$file || !-f $file->{filepath}; >- >-open my $fh, '<', $file->{filepath} or die "Can't open file: $!"; >-print $input->header( C4::UploadedFiles::httpheaders( $file->{filename} )); >-while(<$fh>) { >- print $_; >+my $upl = Koha::Upload->new({ public => 1 }); >+my $rec = $upl->get({ hashvalue => $hash, filehandle => 1 }); >+my $fh = $rec->{fh}; >+if( !$rec || !$fh ) { >+ my ( $template, $user, $cookie ) = get_template_and_user({ >+ query => $input, >+ template_name => 'opac-retrieve-file.tt', >+ type => 'opac', >+ authnotrequired => 1, >+ }); >+ $template->param( hash => $hash ); >+ output_html_with_http_headers $input, $cookie, $template->output; >+} else { >+ my @hdr = $upl->httpheaders( $rec->{name} ); >+ print Encode::encode_utf8( $input->header( @hdr ) ); >+ while( <$fh> ) { >+ print $_; >+ } >+ $fh->close; > } >-close $fh; >diff --git a/tools/stage-marc-import.pl b/tools/stage-marc-import.pl >index c39b6ff..1a7b587 100755 >--- a/tools/stage-marc-import.pl >+++ b/tools/stage-marc-import.pl >@@ -39,7 +39,7 @@ use C4::Output; > use C4::Biblio; > use C4::ImportBatch; > use C4::Matcher; >-use C4::UploadedFile; >+use Koha::Upload; > use C4::BackgroundJob; > use C4::MarcModificationTemplates; > use Koha::Plugins; >@@ -84,8 +84,9 @@ if ($completedJobID) { > my $results = $job->results(); > $template->param(map { $_ => $results->{$_} } keys %{ $results }); > } elsif ($fileID) { >- my $uploaded_file = C4::UploadedFile->fetch($sessionID, $fileID); >- my $fh = $uploaded_file->fh(); >+ my $upload = Koha::Upload->new->get({ id => $fileID, filehandle => 1 }); >+ my $fh = $upload->{fh}; >+ my $filename = $upload->{name}; # filename only, no path > my $marcrecord=''; > $/ = "\035"; > while (<$fh>) { >@@ -93,8 +94,8 @@ if ($completedJobID) { > s/\s+$//; > $marcrecord.=$_; > } >+ $fh->close; > >- my $filename = $uploaded_file->name(); > my $job = undef; > my $dbh; > if ($runinbackground) { >diff --git a/tools/upload-cover-image.pl b/tools/upload-cover-image.pl >index a2576ac..79c37f2 100755 >--- a/tools/upload-cover-image.pl >+++ b/tools/upload-cover-image.pl >@@ -47,7 +47,7 @@ use C4::Context; > use C4::Auth; > use C4::Output; > use C4::Images; >-use C4::UploadedFile; >+use Koha::Upload; > use C4::Log; > > my $debug = 1; >@@ -83,9 +83,9 @@ $template->{VARS}->{'biblionumber'} = $biblionumber; > my $total = 0; > > if ($fileID) { >- my $uploaded_file = C4::UploadedFile->fetch( $sessionID, $fileID ); >+ my $upload = Koha::Upload->new->get({ id => $fileID, filehandle => 1 }); > if ( $filetype eq 'image' ) { >- my $fh = $uploaded_file->fh(); >+ my $fh = $upload->{fh}; > my $srcimage = GD::Image->new($fh); > if ( defined $srcimage ) { > my $dberror = PutImage( $biblionumber, $srcimage, $replace ); >@@ -102,7 +102,7 @@ if ($fileID) { > undef $srcimage; > } > else { >- my $filename = $uploaded_file->filename(); >+ my $filename = $upload->{path}; > my $dirname = File::Temp::tempdir( CLEANUP => 1 ); > unless ( system( "unzip", $filename, '-d', $dirname ) == 0 ) { > $error = 'UZIPFAIL'; >diff --git a/tools/upload-file.pl b/tools/upload-file.pl >index 94a33a6..f54d6b1 100755 >--- a/tools/upload-file.pl >+++ b/tools/upload-file.pl >@@ -17,18 +17,17 @@ > # You should have received a copy of the GNU General Public License > # along with Koha; if not, see <http://www.gnu.org/licenses>. > >-use strict; >-#use warnings; FIXME - Bug 2505 >+use Modern::Perl; > >-# standard or CPAN modules used >-use IO::File; > use CGI qw ( -utf8 ); >-use CGI::Session; >+use CGI::Cookie; >+use Encode; >+use JSON; >+use URI::Escape; >+ > use C4::Context; > use C4::Auth qw/check_cookie_auth haspermission/; >-use CGI::Cookie; # need to check cookies before >- # having CGI parse the POST request >-use C4::UploadedFile; >+use Koha::Upload; > > # upload-file.pl must authenticate the user > # before processing the POST request, >@@ -36,7 +35,7 @@ use C4::UploadedFile; > # not authorized. Consequently, unlike > # most of the other CGI scripts, upload-file.pl > # requires that the session cookie already >-# have been created. >+# has been created. > > my $flags_required = [ > {circulate => 'circulate_remaining_permissions'}, >@@ -44,52 +43,53 @@ my $flags_required = [ > {tools => 'upload_local_cover_images'} > ]; > >-my %cookies = fetch CGI::Cookie; >+my %cookies = CGI::Cookie->fetch; >+my $sid = $cookies{'CGISESSID'}->value; > > my $auth_failure = 1; >-my ( $auth_status, $sessionID ) = check_cookie_auth( $cookies{'CGISESSID'}->value ); >+my ( $auth_status, $sessionID ) = check_cookie_auth( $sid ); >+my $uid = C4::Auth::get_session($sid)->param('id'); > foreach my $flag_required ( @{$flags_required} ) { >- if ( my $flags = haspermission( C4::Context->config('user'), $flag_required ) ) { >+ if ( my $flags = haspermission( $uid, $flag_required ) ) { > $auth_failure = 0 if $auth_status eq 'ok'; > } > } > > if ($auth_failure) { >- $auth_status = 'denied' if $auth_status eq 'failed'; >- send_reply($auth_status, ""); >+ send_reply( 'denied' ); > exit 0; > } > >-our $uploaded_file = C4::UploadedFile->new($sessionID); >-unless (defined $uploaded_file) { >- # FIXME - failed to create file for some reason >- send_reply('failed', ''); >- exit 0; >+my $upload = Koha::Upload->new( upload_pars($ENV{QUERY_STRING}) ); >+if( !$upload || !$upload->cgi || !$upload->count ) { >+ # not one upload succeeded >+ send_reply( 'failed', undef, $upload? $upload->err: undef ); >+} else { >+ # in case of multiple uploads, at least one got through >+ send_reply( 'done', $upload->result, $upload->err ); > } >-$uploaded_file->max_size($ENV{'CONTENT_LENGTH'}); # may not be the file size, exactly >- >-my $query; >-$query = new CGI \&upload_hook; >-$uploaded_file->done(); >-send_reply('done', $uploaded_file->id()); >- >-# FIXME - if possible, trap signal caused by user cancelling upload >-# FIXME - something is wrong during cleanup: \t(in cleanup) Can't call method "commit" on unblessed reference at /usr/local/share/perl/5.8.8/CGI/Session/Driver/DBI.pm line 130 during global destruction. > exit 0; > >-sub upload_hook { >- my ($file_name, $buffer, $bytes_read, $session) = @_; >- $uploaded_file->stash(\$buffer, $bytes_read); >- if ( ! $uploaded_file->name && $file_name ) { # save name on first chunk >- $uploaded_file->name($file_name); >- } >+sub send_reply { # response will be sent back as JSON >+ my ( $upload_status, $data, $error ) = @_; >+ my $reply = CGI->new(""); >+ print $reply->header( -type => 'text/html', -charset => 'UTF-8' ); >+ print JSON::encode_json({ >+ status => $upload_status, >+ fileid => $data, >+ errors => $error, >+ }); > } > >-sub send_reply { >- my ($upload_status, $fileid) = @_; >- >- my $reply = CGI->new(""); >- print $reply->header(-type => 'text/html'); >- # response will be sent back as JSON >- print '{"status":"' . $upload_status . '","fileid":"' . $fileid . '"}'; >+sub upload_pars { >+ my ( $qstr ) = @_; >+ $qstr = Encode::decode_utf8( uri_unescape( $qstr ) ); >+ # category could include a utf8 character >+ my $rv = {}; >+ foreach my $p ( qw[public category temp] ) { >+ if( $qstr =~ /(^|&)$p=(\w+)(&|$)/ ) { >+ $rv->{$p} = $2; >+ } >+ } >+ return $rv; > } >diff --git a/tools/upload.pl b/tools/upload.pl >new file mode 100755 >index 0000000..47c28f5 >--- /dev/null >+++ b/tools/upload.pl >@@ -0,0 +1,98 @@ >+#!/usr/bin/perl >+ >+# This file is part of Koha. >+# >+# Copyright (C) 2015 Rijksmuseum >+# >+# 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 3 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, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use CGI qw/-utf8/; >+use JSON; >+ >+use C4::Auth; >+use C4::Output; >+use Koha::Upload; >+ >+my $input = CGI::->new; >+my $op = $input->param('op') // 'new'; >+my $plugin = $input->param('plugin'); >+my $index = $input->param('index'); # MARC editor input field id >+my $term = $input->param('term'); >+my $id = $input->param('id'); >+my $msg = $input->param('msg'); >+ >+my ( $template, $loggedinuser, $cookie ) = get_template_and_user( >+ { template_name => "tools/upload.tt", >+ query => $input, >+ type => "intranet", >+ authnotrequired => 0, >+ flagsrequired => { editcatalogue => '*' }, >+ } >+); >+ >+$template->param( >+ plugin => $plugin, >+ index => $index, >+); >+ >+my $upar = $plugin? { public => 1 }: {}; >+if( $op eq 'new' ) { >+ $template->param( >+ mode => 'new', >+ uploadcategories => Koha::Upload->getCategories, >+ ); >+ output_html_with_http_headers $input, $cookie, $template->output; >+} elsif( $op eq 'search' ) { >+ my $h = $id? { id => $id }: { term => $term }; >+ my @uploads = Koha::Upload->new( $upar )->get( $h ); >+ $template->param( >+ mode => 'report', >+ msg => $msg, >+ uploads => \@uploads, >+ ); >+ output_html_with_http_headers $input, $cookie, $template->output; >+} elsif( $op eq 'delete' ) { >+ # delete only takes the id parameter >+ my $upl = Koha::Upload->new( $upar ); >+ my ( $fn ) = $upl->delete({ id => $id }); >+ my $e = $upl->err; >+ my $msg = $fn? JSON::to_json({ $fn => 6 }): >+ $e? JSON::to_json( $e ): undef; >+ $template->param( >+ mode => 'deleted', >+ msg => $msg, >+ uploadcategories => $upl->getCategories, >+ ); >+ output_html_with_http_headers $input, $cookie, $template->output; >+} elsif( $op eq 'download' ) { >+ my $upl = Koha::Upload->new( $upar ); >+ my $rec = $upl->get({ id => $id, filehandle => 1 }); >+ my $fh = $rec->{fh}; >+ if( !$rec || !$fh ) { >+ $template->param( >+ mode => 'new', >+ msg => JSON::to_json({ $id => 5 }), >+ uploadcategories => $upl->getCategories, >+ ); >+ output_html_with_http_headers $input, $cookie, $template->output; >+ } else { >+ my @hdr = $upl->httpheaders( $rec->{name} ); >+ print Encode::encode_utf8( $input->header( @hdr ) ); >+ while( <$fh> ) { >+ print $_; >+ } >+ $fh->close; >+ } >+} >-- >1.7.10.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 14321
:
41498
|
41499
|
41500
|
41501
|
41555
|
41556
|
41557
|
41558
|
41559
|
41560
|
41561
|
41562
|
41665
|
41666
|
41667
|
41668
|
41669
|
41677
|
41873
|
41874
|
41875
|
41876
|
41877
|
41878
|
41879
|
41880
|
41881
|
42411
|
42412
|
42413
|
42414
|
42558
|
42559
|
42560
|
42561
|
42584
|
42587
|
42588
|
42589
|
42590
|
42591
|
42660
|
42661
|
42662
|
42663
|
42664
|
42665
|
42666
|
42707
|
42726
|
42727
|
42728
|
42729
|
42730
|
42731
|
42732
|
42889
|
42890