X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=tools%2Fmanage-marc-import.pl;h=e7ff78e8b6100d5635df39c26ae75f76c3d088a3;hb=49e0a8fc786b61b56d15d77d79c180c60c595943;hp=1eb41dd0557d2129463ed2517dbc56f118973bb2;hpb=b69facedc4f0c1c2194244df9d97460851b273a5;p=koha_fer diff --git a/tools/manage-marc-import.pl b/tools/manage-marc-import.pl index 1eb41dd055..e7ff78e8b6 100755 --- a/tools/manage-marc-import.pl +++ b/tools/manage-marc-import.pl @@ -13,44 +13,70 @@ # 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, write to the Free Software Foundation, Inc., 59 Temple Place, -# Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU General Public License along +# 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; # 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::Input; use C4::Output; use C4::Biblio; use C4::ImportBatch; use C4::Matcher; +use C4::BackgroundJob; +use C4::Labels::Batch 1.000000; +use C4::Branch qw(get_branch_code_from_name); my $script_name = "/cgi-bin/koha/tools/manage-marc-import.pl"; my $input = new CGI; -my $op = $input->param('op'); -my $import_batch_id = $input->param('import_batch_id'); +my $op = $input->param('op') || ''; +my $completedJobID = $input->param('completedJobID'); +my $runinbackground = $input->param('runinbackground'); +my $import_batch_id = $input->param('import_batch_id') || ''; # record list displays my $offset = $input->param('offset') || 0; -my $results_per_page = $input->param('results_per_page') || 10; +my $results_per_page = $input->param('results_per_page') || 25; my ($template, $loggedinuser, $cookie) = get_template_and_user({template_name => "tools/manage-marc-import.tmpl", query => $input, type => "intranet", authnotrequired => 0, - flagsrequired => {parameters => 1}, + flagsrequired => {tools => 'manage_staged_marc'}, debug => 1, }); +my %cookies = parse CGI::Cookie($cookie); +my $sessionID = $cookies{'CGISESSID'}->value; +my $dbh = C4::Context->dbh; + +if ($op eq "create_labels") { + #create a batch of labels, then lose $op & $import_batch_id so we get back to import batch list. + my $label_batch_id = create_labelbatch_from_importbatch($import_batch_id); + if ($label_batch_id == -1) { + $template->param( label_batch_msg => "Error attempting to create label batch. Please ask your system administrator to check the log for more details.", + message_type => 'alert', + ); + } + else { + $template->param( label_batch_msg => "Label batch #$label_batch_id created.", + message_type => 'dialog', + ); + } + $op=''; + $import_batch_id=''; +} if ($op) { $template->param(script_name => $script_name, $op => 1); } else { @@ -59,35 +85,76 @@ if ($op) { if ($op eq "") { # displaying a list - if ($import_batch_id eq "") { + if ($import_batch_id eq '') { import_batches_list($template, $offset, $results_per_page); } else { import_biblios_list($template, $import_batch_id, $offset, $results_per_page); } } elsif ($op eq "commit-batch") { - commit_batch($template, $import_batch_id); + if ($completedJobID) { + add_saved_job_results_to_template($template, $completedJobID); + } else { + commit_batch($template, $import_batch_id); + } import_biblios_list($template, $import_batch_id, $offset, $results_per_page); } elsif ($op eq "revert-batch") { - revert_batch($template, $import_batch_id); + if ($completedJobID) { + add_saved_job_results_to_template($template, $completedJobID); + } else { + revert_batch($template, $import_batch_id); + } import_biblios_list($template, $import_batch_id, $offset, $results_per_page); } elsif ($op eq "clean-batch") { - ; + CleanBatch($import_batch_id); + import_batches_list($template, $offset, $results_per_page); + $template->param( + did_clean => 1, + import_batch_id => $import_batch_id, + ); } elsif ($op eq "redo-matching") { my $new_matcher_id = $input->param('new_matcher_id'); my $current_matcher_id = $input->param('current_matcher_id'); - redo_matching($template, $import_batch_id, $new_matcher_id, $current_matcher_id); + my $overlay_action = $input->param('overlay_action'); + my $nomatch_action = $input->param('nomatch_action'); + my $item_action = $input->param('item_action'); + redo_matching($template, $import_batch_id, $new_matcher_id, $current_matcher_id, + $overlay_action, $nomatch_action, $item_action); import_biblios_list($template, $import_batch_id, $offset, $results_per_page); -} +} output_html_with_http_headers $input, $cookie, $template->output; exit 0; sub redo_matching { - my ($template, $import_batch_id, $new_matcher_id, $current_matcher_id) = @_; + my ($template, $import_batch_id, $new_matcher_id, $current_matcher_id, $overlay_action, $nomatch_action, $item_action) = @_; my $rematch_failed = 0; return if not defined $new_matcher_id and not defined $current_matcher_id; - return if $new_matcher_id == $current_matcher_id; + my $old_overlay_action = GetImportBatchOverlayAction($import_batch_id); + my $old_nomatch_action = GetImportBatchNoMatchAction($import_batch_id); + my $old_item_action = GetImportBatchItemAction($import_batch_id); + return if $new_matcher_id eq $current_matcher_id and + $old_overlay_action eq $overlay_action and + $old_nomatch_action eq $nomatch_action and + $old_item_action eq $item_action; + + if ($old_overlay_action ne $overlay_action) { + SetImportBatchOverlayAction($import_batch_id, $overlay_action); + $template->param('changed_overlay_action' => 1); + } + if ($old_nomatch_action ne $nomatch_action) { + SetImportBatchNoMatchAction($import_batch_id, $nomatch_action); + $template->param('changed_nomatch_action' => 1); + } + if ($old_item_action ne $item_action) { + SetImportBatchItemAction($import_batch_id, $item_action); + $template->param('changed_item_action' => 1); + } + + if ($new_matcher_id eq $current_matcher_id) { + return; + } + my $num_with_matches = 0; if (defined $new_matcher_id and $new_matcher_id ne "") { my $matcher = C4::Matcher->fetch($new_matcher_id); @@ -99,13 +166,34 @@ sub redo_matching { } } else { $num_with_matches = BatchFindBibDuplicates($import_batch_id, undef); - SetImportBatchMatcher($import_batch_id, undef); + SetImportBatchMatcher($import_batch_id, undef); + SetImportBatchOverlayAction('create_new'); } $template->param(rematch_failed => $rematch_failed); $template->param(rematch_attempted => 1); $template->param(num_with_matches => $num_with_matches); } +sub create_labelbatch_from_importbatch { + my ($batch_id) = @_; + my $err = undef; + my $branch_code = get_branch_code_from_name($template->param('LoginBranchname')); + my $batch = C4::Labels::Batch->new(branch_code => $branch_code); + my @items = GetItemNumbersFromImportBatch($batch_id); + if (grep{$_ == 0} @items) { + warn sprintf('create_labelbatch_from_importbatch() : Call to C4::ImportBatch::GetItemNumbersFromImportBatch returned no item number(s) from import batch #%s.', $batch_id); + return -1; + } + foreach my $item_number (@items) { + $err = $batch->add_item($item_number); + if ($err == -1) { + warn sprintf('create_labelbatch_from_importbatch() : Error attempting to add item #%s of import batch #%s to label batch.', $item_number, $batch_id); + return -1; + } + } + return $batch->get_attr('batch_id'); +} + sub import_batches_list { my ($template, $offset, $results_per_page) = @_; my $batches = GetImportBatchRangeDesc($offset, $results_per_page); @@ -119,7 +207,8 @@ sub import_batches_list { upload_timestamp => $batch->{'upload_timestamp'}, import_status => $batch->{'import_status'}, file_name => $batch->{'file_name'}, - comments => $batch->{'comments'} + comments => $batch->{'comments'}, + can_clean => ($batch->{'import_status'} ne 'cleaned') ? 1 : 0, }; } $template->param(batch_list => \@list); @@ -134,23 +223,119 @@ sub import_batches_list { sub commit_batch { my ($template, $import_batch_id) = @_; - my ($num_added, $num_updated, $num_items_added, $num_ignored) = BatchCommitBibRecords($import_batch_id); - $template->param(did_commit => 1); - $template->param(num_added => $num_added); - $template->param(num_updated => $num_updated); - $template->param(num_items_added => $num_items_added); - $template->param(num_ignored => $num_ignored); + + my $job = undef; + $dbh->{AutoCommit} = 0; + my $callback = sub {}; + if ($runinbackground) { + $job = put_in_background($import_batch_id); + $callback = progress_callback($job, $dbh); + } + my ($num_added, $num_updated, $num_items_added, $num_items_errored, $num_ignored) = + BatchCommitBibRecords($import_batch_id, 50, $callback); + $dbh->commit(); + + my $results = { + did_commit => 1, + num_added => $num_added, + num_updated => $num_updated, + num_items_added => $num_items_added, + num_items_errored => $num_items_errored, + num_ignored => $num_ignored + }; + if ($runinbackground) { + $job->finish($results); + } else { + add_results_to_template($template, $results); + } } sub revert_batch { my ($template, $import_batch_id) = @_; - my ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, $num_ignored) = BatchRevertBibRecords($import_batch_id); - $template->param(did_revert => 1); - $template->param(num_deleted => $num_deleted); - $template->param(num_items_deleted => $num_items_deleted); - $template->param(num_errors => $num_errors); - $template->param(num_reverted => $num_reverted); - $template->param(num_ignored => $num_ignored); + + $dbh->{AutoCommit} = 0; + my $job = undef; + my $callback = sub {}; + if ($runinbackground) { + $job = put_in_background($import_batch_id); + $callback = progress_callback($job, $dbh); + } + my ($num_deleted, $num_errors, $num_reverted, $num_items_deleted, $num_ignored) = + BatchRevertBibRecords($import_batch_id, 50, $callback); + $dbh->commit(); + + my $results = { + did_revert => 1, + num_deleted => $num_deleted, + num_items_deleted => $num_items_deleted, + num_errors => $num_errors, + num_reverted => $num_reverted, + num_ignored => $num_ignored, + }; + if ($runinbackground) { + $job->finish($results); + } else { + add_results_to_template($template, $results); + } +} + +sub put_in_background { + my $import_batch_id = shift; + + my $batch = GetImportBatch($import_batch_id); + my $job = C4::BackgroundJob->new($sessionID, $batch->{'file_name'}, $ENV{'SCRIPT_NAME'}, $batch->{'num_biblios'}); + 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 Oracle + $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_NAME'} as a background job"; + exit 0; + } + return $job; +} + +sub progress_callback { + my $job = shift; + my $dbh = shift; + return sub { + my $progress = shift; + $job->progress($progress); + $dbh->commit(); + } +} + +sub add_results_to_template { + my $template = shift; + my $results = shift; + $template->param(map { $_ => $results->{$_} } keys %{ $results }); +} + +sub add_saved_job_results_to_template { + my $template = shift; + my $completedJobID = shift; + my $job = C4::BackgroundJob->fetch($sessionID, $completedJobID); + my $results = $job->results(); + add_results_to_template($template, $results); } sub import_biblios_list { @@ -167,17 +352,25 @@ sub import_biblios_list { $citation .= ", " if $biblio->{'issn'} and $biblio->{'isbn'}; $citation .= $biblio->{'issn'} if $biblio->{'issn'}; $citation .= ")" if $biblio->{'issn'} or $biblio->{'isbn'}; + my $match = GetImportRecordMatches($biblio->{'import_record_id'}, 1); - push @list, { - import_record_id => $biblio->{'import_record_id'}, - citation => $citation, - status => $biblio->{'status'}, - record_sequence => $biblio->{'record_sequence'}, - overlay_status => $biblio->{'overlay_status'}, - match_biblionumber => $#$match > -1 ? $match->[0]->{'biblionumber'} : 0, - match_citation => $#$match > -1 ? $match->[0]->{'title'} . ' ' . $match->[0]->{'author'} : '', - match_score => $#$match > -1 ? $match->[0]->{'score'} : 0, - }; + my $match_citation = ''; + if ($#$match > -1) { + $match_citation .= $match->[0]->{'title'} if defined($match->[0]->{'title'}); + $match_citation .= ' ' . $match->[0]->{'author'} if defined($match->[0]->{'author'}); + } + + push @list, + { import_record_id => $biblio->{'import_record_id'}, + final_match_biblionumber => $biblio->{'matched_biblionumber'}, + citation => $citation, + status => $biblio->{'status'}, + record_sequence => $biblio->{'record_sequence'}, + overlay_status => $biblio->{'overlay_status'}, + match_biblionumber => $#$match > -1 ? $match->[0]->{'biblionumber'} : 0, + match_citation => $match_citation, + match_score => $#$match > -1 ? $match->[0]->{'score'} : 0, + }; } my $num_biblios = $batch->{'num_biblios'}; $template->param(biblio_list => \@list); @@ -187,6 +380,15 @@ sub import_biblios_list { $template->param(num_results => $num_biblios); $template->param(results_per_page => $results_per_page); $template->param(import_batch_id => $import_batch_id); + my $overlay_action = GetImportBatchOverlayAction($import_batch_id); + $template->param("overlay_action_${overlay_action}" => 1); + $template->param(overlay_action => $overlay_action); + my $nomatch_action = GetImportBatchNoMatchAction($import_batch_id); + $template->param("nomatch_action_${nomatch_action}" => 1); + $template->param(nomatch_action => $nomatch_action); + my $item_action = GetImportBatchItemAction($import_batch_id); + $template->param("item_action_${item_action}" => 1); + $template->param(item_action => $item_action); batch_info($template, $batch); } @@ -200,11 +402,16 @@ sub batch_info { $template->param(upload_timestamp => $batch->{'upload_timestamp'}); $template->param(num_biblios => $batch->{'num_biblios'}); $template->param(num_items => $batch->{'num_biblios'}); - if ($batch->{'import_status'} eq 'staged' or $batch->{'import_status'} eq 'reverted') { - $template->param(can_commit => 1); + if ($batch->{'import_status'} ne 'cleaned') { + $template->param(can_clean => 1); } - if ($batch->{'import_status'} eq 'imported') { - $template->param(can_revert => 1); + if ($batch->{'num_biblios'} > 0) { + if ($batch->{'import_status'} eq 'staged' or $batch->{'import_status'} eq 'reverted') { + $template->param(can_commit => 1); + } + if ($batch->{'import_status'} eq 'imported') { + $template->param(can_revert => 1); + } } if (defined $batch->{'matcher_id'}) { my $matcher = C4::Matcher->fetch($batch->{'matcher_id'}); @@ -222,7 +429,7 @@ sub add_matcher_list { my @matchers = C4::Matcher::GetMatcherList(); if (defined $current_matcher_id) { for (my $i = 0; $i <= $#matchers; $i++) { - if ($matchers[$i]->{'matcher_id'} == $current_matcher_id) { + if ($matchers[$i]->{'matcher_id'} eq $current_matcher_id) { $matchers[$i]->{'selected'} = 1; } }