Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

How do I Select an uploaded file in cgi to further process?

by smeagol99 (Initiate)
on Sep 07, 2012 at 20:48 UTC ( #992373=perlquestion: print w/replies, xml ) Need Help??
smeagol99 has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to initialize or select an uploaded file to do further work on it in terms of processing. After I upload the file, I want to grab the file again, and do something else with it, not print it. thanks. </p?

#!/usr/bin/perl # Script for handling import of MARC data into Koha db # and Z39.50 lookups # Koha library project # Licensed under the GPL # Copyright 2000-2002 Katipo Communications # # This file is part of Koha. # # Koha is free software; you can redistribute it and/or modify it unde +r the # terms of the GNU General Public License as published by the Free Sof +tware # Foundation; either version 2 of the License, or (at your option) any + later # version. # # Koha is distributed in the hope that it will be useful, but WITHOUT +ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FI +TNESS FOR # A PARTICULAR PURPOSE. See the GNU General Public License for more d +etails. # # You should have received a copy of the GNU General Public License al +ong # with Koha; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. use strict; #use warnings; FIXME - Bug 2505 # standard or CPAN modules used use CGI; use CGI::Cookie; use MARC::File::USMARC; # Koha modules used use C4::Context; use C4::Auth; use C4::Output; use C4::Biblio; use C4::ImportBatch; use C4::Matcher; use C4::UploadedFile; use C4::BackgroundJob; use C4::Items; #PrepareItemRecord my $input = new CGI; my $dbh = C4::Context->dbh; $dbh->{AutoCommit} = 0; my $fileID=$input->param('uploadedfileid'); my $runinbackground = $input->param('runinbackground'); my $completedJobID = $input->param('completedJobID'); my $matcher_id = $input->param('matcher'); my $overlay_action = $input->param('overlay_action'); my $nomatch_action = $input->param('nomatch_action'); my $parse_items = $input->param('parse_items'); my $item_action = $input->param('item_action'); my $comments = $input->param('comments'); my $encoding = $input->param('encoding'); my $ordernumber = $input->param('ordernumber') || ''; my ($template, $loggedinuser, $cookie) = get_template_and_user({template_name => "tools/stage-marc-import +.tmpl", query => $input, type => "intranet", authnotrequired => 0, flagsrequired => {tools => 'stage_marc_import'}, debug => 1, }); $template->param(SCRIPT_NAME => $ENV{'SCRIPT_NAME'}, uploadmarc => $fileID); my %cookies = parse CGI::Cookie($cookie); my $sessionID = $cookies{'CGISESSID'}->value; if ($completedJobID) { my $job = C4::BackgroundJob->fetch($sessionID, $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 $marcrecord=''; $/ = "\035"; while (<$fh>) { s/^\s+//; s/\s+$//; $marcrecord.=$_; } my $filename = $uploaded_file->name(); my $job = undef; my $staging_callback = sub { }; my $matching_callback = sub { }; if ($runinbackground) { my $job_size = () = $marcrecord =~ /\035/g; # if we're matching, job size is doubled $job_size *= 2 if ($matcher_id ne ""); $job = C4::BackgroundJob->new($sessionID, $filename, $ENV{'SCR +IPT_NAME'}, $job_size); my $jobID = $job->id(); # fork off if (my $pid = fork) { # parent # return job ID as JSON # prevent parent exiting from # destroying the kid's database handle # FIXME: according to DBI doc, this may not work for Oracl +e $dbh->{InactiveDestroy} = 1; my $reply = CGI->new(""); print $reply->header(-type => 'text/html'); print '{"jobID":"' . $jobID . '"}'; exit 0; } elsif (defined $pid) { # child # close STDOUT to signal to Apache that # we're now running in the background close STDOUT; close STDERR; } else { # fork failed, so exit immediately warn "fork failed while attempting to run $ENV{'SCRIPT_NAM +E'} as a background job"; exit 0; } # if we get here, we're a child that has detached # itself from Apache $staging_callback = staging_progress_callback($job, $dbh); $matching_callback = matching_progress_callback($job, $dbh); } # FIXME branch code my ($batch_id, $num_valid, $num_items, @import_errors) = BatchStag +eMarcRecords($encoding, $marcrecord, $filename, $comments, '', $parse +_items, 0, 50, staging_progress_callback($job, $dbh)); $dbh->commit(); my $num_with_matches = 0; my $checked_matches = 0; my $matcher_failed = 0; my $matcher_code = ""; if ($matcher_id ne "") { my $matcher = C4::Matcher->fetch($matcher_id); if (defined $matcher) { $checked_matches = 1; $matcher_code = $matcher->code(); $num_with_matches = BatchFindBibDuplicates($batch_id, $mat +cher, 10, 50, matchin +g_progress_callback($job, $dbh)); SetImportBatchMatcher($batch_id, $matcher_id); SetImportBatchOverlayAction($batch_id, $overlay_action); SetImportBatchNoMatchAction($batch_id, $nomatch_action); SetImportBatchItemAction($batch_id, $item_action); $dbh->commit(); } else { $matcher_failed = 1; } } my $results = { staged => $num_valid, matched => $num_with_matches, num_items => $num_items, import_errors => scalar(@import_errors), total => $num_valid + scalar(@import_errors), checked_matches => $checked_matches, matcher_failed => $matcher_failed, matcher_code => $matcher_code, import_batch_id => $batch_id }; if ($runinbackground) { $job->finish($results); } else { $template->param(staged => $num_valid, matched => $num_with_matches, num_items => $num_items, import_errors => scalar(@import_errors), total => $num_valid + scalar(@import_errors), checked_matches => $checked_matches, matcher_failed => $matcher_failed, matcher_code => $matcher_code, import_batch_id => $batch_id ); } } else { # initial form if (C4::Context->preference("marcflavour") eq "UNIMARC") { $template->param("UNIMARC" => 1); } my @matchers = C4::Matcher::GetMatcherList(); $template->param(available_matchers => \@matchers); } if (C4::Context->preference('AcqCreateItem') eq 'ordering' && !$ordern +umber) { # prepare empty item form my $cell = PrepareItemrecordDisplay('','','','ACQ'); # warn "==> ".Data::Dumper::Dumper($cell); unless ($cell) { $cell = PrepareItemrecordDisplay('','','',''); $template->param('NoACQframework' => 1); } my @itemloop; push @itemloop,$cell; $template->param(items => \@itemloop); } # Get the item types list, but only if item_level_itype is YES. Otherw +ise, it will be in the item, no need to display it in the biblio my @itemtypes; @itemtypes = C4::ItemType->all unless C4::Context->preference('item-le +vel_itypes'); output_html_with_http_headers $input, $cookie, $template->output; exit 0; sub staging_progress_callback { my $job = shift; my $dbh = shift; return sub { my $progress = shift; $job->progress($progress); $dbh->commit(); } } sub matching_progress_callback { my $job = shift; my $dbh = shift; my $start_progress = $job->progress(); return sub { my $progress = shift; $job->progress($start_progress + $progress); $dbh->commit(); } }
Template file
[% INCLUDE '' %] <title>Koha &rsaquo; Tools &rsaquo; Stage MARC Records For Import</tit +le> [% INCLUDE '' %] [% INCLUDE '' %] [% INCLUDE '' %] <style type="text/css"> #uploadpanel,#fileuploadstatus,#fileuploadfailed,#jobpanel,#jobsta +tus,#jobfailed { display : none; } #fileuploadstatus,#jobstatus { margin:.4em; } #fileuploadprogress,#jobprogress{ width:150px;height:10px;border:1 +px solid #666;background:url('/intranet-tmpl/prog/img/progress.png') +-300px 0px no-repeat; }</style> <script type="text/javascript"> //<![CDATA[ $(document).ready(function(){ $("#processfile").hide(); }); function CheckForm(f) { if ($("#fileToUpload").value == '') { alert(_('Please upload a file first.')); } else { return submitBackgroundJob(f); } return false; } //]]> </script> </head> <body> [% INCLUDE '' %] [% INCLUDE '' %] <div id="breadcrumbs"><a href="/cgi-bin/koha/">Home</a> &rs +aquo; <a href="/cgi-bin/koha/tools/">Tools</a> &rsaquo; +[% IF ( uploadmarc ) %]<a href="/cgi-bin/koha/tools/stage-marc-import">Stage MARC Records For Import</a> &rsaquo; Upload Results[% ELSE + %]Stage MARC Records For Import[% END %]</div> <div id="doc3" class="yui-t2"> <div id="bd"> <div id="yui-main"> <div class="yui-b"> <h1>Stage MARC Records For Import</h1> [% IF ( uploadmarc ) %] <p>MARC Staging results :</p> <ul> <li>[% total %] records in file</li> <li>[% import_errors %] records not staged because of MARC error</ +li> <li>[% staged %] records staged</li> [% IF ( checked_matches ) %] <li>[% matched %] records with at least one match in catalog per m +atching rule &quot;[% matcher_code %]&quot;</li> [% ELSE %] [% IF ( matcher_failed ) %] <li>Record matching failed -- unable to retrieve selected ma +tching rule.</li> [% ELSE %] <li>Did not check for matches with existing records in catal +og</li> [% END %] [% END %] <li>[% num_items %] item records found and staged</li> [% IF ( label_batch ) %] <li>New label batch created: # [% label_batch %] </li> [% END %] <li><a href="/cgi-bin/koha/tools/ +h_id=[% import_batch_id %]">Manage staged records</a></li> <li><a href="/cgi-bin/koha/tools/">Back</a></li> </ul> [% ELSE %] <ul> <li>Select a MARC file to stage in the import reservoir. It will +be parsed, and each valid record staged for later import into the cat +alog.</li> <li>You can enter a name for this import. It may be useful, when c +reating a biblio, to remember where the suggested MARC data comes fro +m!</li> </ul> <form method="post" action="[% SCRIPT_NAME %]" id="uploadfile" enctype +="multipart/form-data"> <fieldset class="rows" id="uploadform"> <legend>Stage records into the reservoir</legend> <ol> <li> <div id="fileuploadform"> <label for="fileToUpload">Select the file to stage: </label> <input type="file" id="fileToUpload" name="fileToUpload" /> </div> </li> </ol> <fieldset class="action"><button class="submit" onclick="retur +n ajaxFileUpload();">Upload file</button></fieldset> </fieldset> <div id="uploadpanel"><div id="fileuploadstatus">Upload progre +ss: <div id="fileuploadprogress"></div> <span id="fileuploadpercent"> +0</span>%</div> <div id="fileuploadfailed"></div></div> </form> <form method="post" id="processfile" action="[% SCRIPT_NAME %]" en +ctype="multipart/form-data"> <fieldset class="rows"> <input type="hidden" name="uploadedfileid" id="uploadedfileid" + value="" /> <input type="hidden" name="runinbackground" id="runinbackgroun +d" value="" /> <input type="hidden" name="completedJobID" id="completedJobID" + value="" /> <ol><li> <label for="comments">Comments about this file: </label> <input type="text" id="comments" name="comments" /> </li> <li> <label for="encoding">Character encoding: </label> <select name="encoding" id="encoding"><option value="utf8" + selected="selected">UTF-8 (Default)</option><option value="MARC-8">M +ARC 8</option><option value="ISO_5426">ISO 5426</option><option value +="ISO_6937">ISO 6937</option><option value=ISO_8859-1">ISO 8859-1</op +tion><option value="EUC-KR">EUC-KR</option></select> </li> </ol></fieldset> <fieldset class="rows"> <legend>Look for existing records in catalog?</legend> <ol><li><label for="matcher">Record matching rule:</label> <select name="matcher" id="matcher"> <option value="">Do not look for matching records</option> [% FOREACH available_matcher IN available_matchers %] <option value="[% available_matcher.matcher_id %]">[% availa +ble_matcher.code %] ([% available_matcher.description %]) </option> [% END %] </select> </li> <li><label for="overlay_action">Action if matching bibliographic + record found: </label> [% INCLUDE '' %] </li> <li><label for="nomatch_action">Action if no match is found: </l +abel> [% INCLUDE '' %] </li> </ol> </fieldset> <fieldset class="rows"> <legend>Check for embedded item record data?</legend> <ol> <li class="radio"> <input type="radio" id="parse_itemsyes" name="parse_items" val +ue="1" checked="checked" /> <label for="parse_itemsyes">Yes</label> </li> <li class="radio"> <input type="radio" id="parse_itemsno" name="parse_items" valu +e="0" /> <label for="parse_itemsno">No</label> </li> </ol> [% IF ( items ) %] <fieldset class="rows"> <legend>Item</legend> [% IF ( NoACQframework ) %] <div class="dialog message">No ACQ framework, using defaul +t. You should create a framework with code ACQ, the items framework w +ould be used</div> [% END %] [% FOREACH item IN items %] <div id="outeritemblock"> <div id="itemblock"> <ol>[% FOREACH iteminformatio IN item.iteminformation %]<l +i style="[% iteminformatio.hidden %];"> <div class="subfield_line" id="subfield[% iteminformat +io.serialid %][% iteminformatio.countitems %][% iteminformatio.subfie +ld %][% iteminformatio.random %]"> <label>[% iteminformatio.subfield %] - [% IF ( ite +minformatio.mandatory ) %]<b>[% END %][% iteminformatio.marc_lib %][% + IF ( iteminformatio.mandatory ) %] *</b>[% END %]</label> [% iteminformatio.marc_value %] <input type="hidden" name="itemid" value="1" /> <input type="hidden" name="kohafield" value="[% it +eminformatio.kohafield %]" /> <input type="hidden" name="tag" value="[% iteminfo +rmatio.tag %]" /> <input type="hidden" name="subfield" value="[% ite +minformatio.subfield %]" /> <input type="hidden" name="mandatory" value="[% it +eminformatio.mandatory %]" /> [% IF ( iteminformatio.ITEM_SUBFIELDS_ARE_NOT_REPE +ATABLE ) %] <span class="buttonPlus" onclick="CloneSubfiel +d('subfield[% iteminformatio.serialid %][% iteminformatio.countitems +%][% iteminformatio.subfield %][% iteminformatio.random %]')">+</span +> [% END %] </div></li> [% END %] </ol> <a class="addItem" onclick="cloneItemBlock('itemblock[% it +em.itemBlockIndex %]')">Add</a> <a class="delItem" style="display:none;" onclick="deleteIt +emBlock('itemblock[% item.itemBlockIndex %]')">Delete</a> </div><!-- /iteminformation --> </div> [% END %] <!-- /items --> </fieldset> [% END %] <!-- items --> <ol> <li><label for="item_action">How to process items: </label> [% INCLUDE '' %] </li> </ol> </fieldset> <fieldset class="action"><input type="button" id="mainformsubmit" on +click="return CheckForm(this.form);" value="Stage for import" /></fie +ldset> <div id="jobpanel"><div id="jobstatus">Job progress: <div id="j +obprogress"></div> <span id="jobprogresspercent">0</span>%</div> <div id="jobfailed"></div></div> </form> [% END %] </div> </div> <div class="yui-b"> [% INCLUDE '' %] </div> </div> [% INCLUDE '' %]

Replies are listed 'Best First'.
Re: How do I Select an uploaded file in cgi to further process?
by davido (Archbishop) on Sep 07, 2012 at 21:12 UTC

    I take it this code was written by someone (not yourself) within the Koha community. And as your post stands, it would probably be accurate to assert that you haven't gained a good understanding of the code, or possibly even of programming with Perl. But you're not really asking a Perl question, or any question, for that matter. It seems that you're requesting that someone do the work of adding a feature to an existing project so that it will better fit your needs. It might be more effective to raise an issue with the project's developers requesting the feature, and maybe offering to contribute your support either in technical capital, or if you're not a programmer and don't intend to learn to be one, the green-paper kind.

    I see on the Koha website Get Involved, and Support, which also links to both mailing lists and support companies.

    If you're actually trying to work on this yourself and have encountered a technical hurdle to overcome, by all means, explain what's holding you up, what you've tried, and what questions you might need resolved in order to proceed. We're game to help if there's a Perl question in there somewhere. But, speaking for myself, I don't get too excited when presented with a narrowly-specialized need, 400 lines of code, and no sign of the existence of a programmer engaging at the OP end of the conversation.

    It's not too late to turn this thread positive. Tell us what you've done to get started. What your level of experience with Perl (and programming in general) is. Tell us where you're stuck. Explain your understanding of the problem and what you see as the challenges. And ask a question.


Re: How do I Select an uploaded file in cgi to further process?
by Anonymous Monk on Sep 07, 2012 at 21:02 UTC
      my %cookies = parse CGI::Cookie($cookie); my $sessionID = $cookies{'CGISESSID'}->value; if ($completedJobID) { my $job = C4::BackgroundJob->fetch($sessionID, $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 $marcrecord=''; $/ = "\035"; while (<$fh>) { s/^\s+//; s/\s+$//; $marcrecord.=$_; } my $filename = $uploaded_file->name(); my $job = undef; my $staging_callback = sub { }; my $matching_callback = sub { }; if ($runinbackground) { my $job_size = () = $marcrecord =~ /\035/g; # if we're matching, job size is doubled $job_size *= 2 if ($matcher_id ne ""); $job = C4::BackgroundJob->new($sessionID, $filename, $ENV{'SCR +IPT_NAME'}, $job_size); my $jobID = $job->id();

      Actually, what I would like to do is get the file that has been uploaded, select it, and do something else to it, (ie. apply items to a marc formatted bib record), but I'm not sure what to grab, or how to grab the file that's been uploaded. thanks, in advance.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://992373]
Approved by Corion
[jedikaiti]: 'ello Monks

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (8)
As of 2017-06-27 15:07 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (609 votes). Check out past polls.