Lines 30-53
use Modern::Perl;
Link Here
|
30 |
use CGI qw ( -utf8 ); |
30 |
use CGI qw ( -utf8 ); |
31 |
use CGI::Cookie; |
31 |
use CGI::Cookie; |
32 |
use MARC::File::USMARC; |
32 |
use MARC::File::USMARC; |
|
|
33 |
use Try::Tiny; |
33 |
|
34 |
|
34 |
# Koha modules used |
35 |
# Koha modules used |
35 |
use C4::Context; |
36 |
use C4::Context; |
36 |
use C4::Auth qw( get_template_and_user ); |
37 |
use C4::Auth qw( get_template_and_user ); |
37 |
use C4::Output qw( output_html_with_http_headers ); |
38 |
use C4::Output qw( output_html_with_http_headers ); |
38 |
use C4::ImportBatch qw( RecordsFromMARCXMLFile RecordsFromISO2709File RecordsFromMarcPlugin BatchStageMarcRecords BatchFindDuplicates SetImportBatchMatcher SetImportBatchOverlayAction SetImportBatchNoMatchAction SetImportBatchItemAction ); |
|
|
39 |
use C4::Matcher; |
39 |
use C4::Matcher; |
40 |
use Koha::UploadedFiles; |
40 |
use Koha::UploadedFiles; |
41 |
use C4::BackgroundJob; |
|
|
42 |
use C4::MarcModificationTemplates qw( GetModificationTemplates ); |
41 |
use C4::MarcModificationTemplates qw( GetModificationTemplates ); |
43 |
use Koha::Plugins; |
42 |
use Koha::Plugins; |
44 |
use Koha::ImportBatches; |
43 |
use Koha::ImportBatches; |
|
|
44 |
use Koha::BackgroundJob::StageMARCForImport; |
45 |
|
45 |
|
46 |
my $input = CGI->new; |
46 |
my $input = CGI->new; |
47 |
|
47 |
|
48 |
my $fileID = $input->param('uploadedfileid'); |
48 |
my $fileID = $input->param('uploadedfileid'); |
49 |
my $runinbackground = $input->param('runinbackground'); |
|
|
50 |
my $completedJobID = $input->param('completedJobID'); |
51 |
my $matcher_id = $input->param('matcher'); |
49 |
my $matcher_id = $input->param('matcher'); |
52 |
my $overlay_action = $input->param('overlay_action'); |
50 |
my $overlay_action = $input->param('overlay_action'); |
53 |
my $nomatch_action = $input->param('nomatch_action'); |
51 |
my $nomatch_action = $input->param('nomatch_action'); |
Lines 61-66
my $marc_modification_template = $input->param('marc_modification_template_id');
Link Here
|
61 |
my $basketno = $input->param('basketno'); |
59 |
my $basketno = $input->param('basketno'); |
62 |
my $booksellerid = $input->param('booksellerid'); |
60 |
my $booksellerid = $input->param('booksellerid'); |
63 |
my $profile_id = $input->param('profile_id'); |
61 |
my $profile_id = $input->param('profile_id'); |
|
|
62 |
my @messages; |
64 |
|
63 |
|
65 |
my ( $template, $loggedinuser, $cookie ) = get_template_and_user( |
64 |
my ( $template, $loggedinuser, $cookie ) = get_template_and_user( |
66 |
{ |
65 |
{ |
Lines 72-215
my ( $template, $loggedinuser, $cookie ) = get_template_and_user(
Link Here
|
72 |
); |
71 |
); |
73 |
|
72 |
|
74 |
$template->param( |
73 |
$template->param( |
75 |
SCRIPT_NAME => '/cgi-bin/koha/tools/stage-marc-import.pl', |
74 |
basketno => $basketno, |
76 |
uploadmarc => $fileID, |
|
|
77 |
record_type => $record_type, |
78 |
basketno => $basketno, |
79 |
booksellerid => $booksellerid, |
75 |
booksellerid => $booksellerid, |
80 |
); |
76 |
); |
81 |
|
77 |
|
82 |
my %cookies = CGI::Cookie->fetch(); |
78 |
if ($fileID) { |
83 |
my $sessionID = $cookies{'CGISESSID'}->value; |
|
|
84 |
if ($completedJobID) { |
85 |
my $job = C4::BackgroundJob->fetch($sessionID, $completedJobID); |
86 |
my $results = $job->results(); |
87 |
$template->param(map { $_ => $results->{$_} } keys %{ $results }); |
88 |
} elsif ($fileID) { |
89 |
my $upload = Koha::UploadedFiles->find( $fileID ); |
79 |
my $upload = Koha::UploadedFiles->find( $fileID ); |
90 |
my $file = $upload->full_path; |
80 |
my $filepath = $upload->full_path; |
91 |
my $filename = $upload->filename; |
81 |
my $filename = $upload->filename; |
92 |
|
82 |
|
93 |
my ( $errors, $marcrecords ); |
83 |
my $params = { |
94 |
if( $format eq 'MARCXML' ) { |
84 |
record_type => $record_type, |
95 |
( $errors, $marcrecords ) = C4::ImportBatch::RecordsFromMARCXMLFile( $file, $encoding); |
85 |
encoding => $encoding, |
96 |
} elsif( $format eq 'ISO2709' ) { |
86 |
format => $format, |
97 |
( $errors, $marcrecords ) = C4::ImportBatch::RecordsFromISO2709File( $file, $record_type, $encoding ); |
87 |
filepath => $filepath, |
98 |
} else { # plugin based |
88 |
filename => $filename, |
99 |
$errors = []; |
89 |
marc_modification_template => $marc_modification_template, |
100 |
$marcrecords = C4::ImportBatch::RecordsFromMarcPlugin( $file, $format, $encoding ); |
90 |
comments => $comments, |
101 |
} |
91 |
parse_items => $parse_items, |
102 |
warn "$filename: " . ( join ',', @$errors ) if @$errors; |
92 |
matcher_id => $matcher_id, |
103 |
# no need to exit if we have no records (or only errors) here |
93 |
overlay_action => $overlay_action, |
104 |
# BatchStageMarcRecords can handle that |
94 |
nomatch_action => $nomatch_action, |
105 |
|
95 |
item_action => $item_action, |
106 |
my $job = undef; |
96 |
}; |
107 |
if ($runinbackground) { |
97 |
try { |
108 |
my $job_size = scalar(@$marcrecords); |
98 |
my $job_id = Koha::BackgroundJob::StageMARCForImport->new->enqueue( $params ); |
109 |
# if we're matching, job size is doubled |
99 |
if ($job_id) { |
110 |
$job_size *= 2 if ($matcher_id ne ""); |
100 |
$template->param( |
111 |
$job = C4::BackgroundJob->new($sessionID, $filename, '/cgi-bin/koha/tools/stage-marc-import.pl', $job_size); |
101 |
job_enqueued => 1, |
112 |
my $jobID = $job->id(); |
102 |
job_id => $job_id, |
113 |
|
103 |
); |
114 |
# fork off |
|
|
115 |
if (my $pid = fork) { |
116 |
# parent |
117 |
# return job ID as JSON |
118 |
my $reply = CGI->new(""); |
119 |
print $reply->header(-type => 'text/html'); |
120 |
print '{"jobID":"' . $jobID . '"}'; |
121 |
exit 0; |
122 |
} elsif (defined $pid) { |
123 |
# child |
124 |
# close STDOUT/STDERR to signal to end CGI session with Apache |
125 |
# Otherwise, the AJAX request to this script won't return properly |
126 |
close STDOUT; |
127 |
close STDERR; |
128 |
} else { |
129 |
# fork failed, so exit immediately |
130 |
warn "fork failed while attempting to run tools/stage-marc-import.pl as a background job: $!"; |
131 |
exit 0; |
132 |
} |
133 |
|
134 |
# if we get here, we're a child that has detached |
135 |
# itself from Apache |
136 |
|
137 |
} |
138 |
|
139 |
my $schema = Koha::Database->new->schema; |
140 |
$schema->storage->txn_begin; |
141 |
|
142 |
# FIXME branch code |
143 |
my ( $batch_id, $num_valid, $num_items, @import_errors ) = |
144 |
BatchStageMarcRecords( |
145 |
$record_type, $encoding, |
146 |
$marcrecords, $filename, |
147 |
$marc_modification_template, |
148 |
$comments, '', |
149 |
$parse_items, 0, |
150 |
50, staging_progress_callback( $job ) |
151 |
); |
152 |
|
153 |
if($profile_id) { |
154 |
my $ibatch = Koha::ImportBatches->find($batch_id); |
155 |
$ibatch->set({profile_id => $profile_id})->store; |
156 |
} |
157 |
|
158 |
my $num_with_matches = 0; |
159 |
my $checked_matches = 0; |
160 |
my $matcher_failed = 0; |
161 |
my $matcher_code = ""; |
162 |
if ($matcher_id ne "") { |
163 |
my $matcher = C4::Matcher->fetch($matcher_id); |
164 |
if (defined $matcher) { |
165 |
$checked_matches = 1; |
166 |
$matcher_code = $matcher->code(); |
167 |
$num_with_matches = |
168 |
BatchFindDuplicates( $batch_id, $matcher, 10, 50, |
169 |
matching_progress_callback($job) ); |
170 |
SetImportBatchMatcher($batch_id, $matcher_id); |
171 |
SetImportBatchOverlayAction($batch_id, $overlay_action); |
172 |
SetImportBatchNoMatchAction($batch_id, $nomatch_action); |
173 |
SetImportBatchItemAction($batch_id, $item_action); |
174 |
$schema->storage->txn_commit; |
175 |
} else { |
176 |
$matcher_failed = 1; |
177 |
$schema->storage->txn_rollback; |
178 |
} |
104 |
} |
179 |
} else { |
|
|
180 |
$schema->storage->txn_commit; |
181 |
} |
105 |
} |
182 |
|
106 |
catch { |
183 |
my $results = { |
107 |
warn $_; |
184 |
staged => $num_valid, |
108 |
push @messages, |
185 |
matched => $num_with_matches, |
109 |
{ |
186 |
num_items => $num_items, |
110 |
type => 'error', |
187 |
import_errors => scalar(@import_errors), |
111 |
code => 'cannot_enqueue_job', |
188 |
total => $num_valid + scalar(@import_errors), |
112 |
error => $_, |
189 |
checked_matches => $checked_matches, |
113 |
}; |
190 |
matcher_failed => $matcher_failed, |
|
|
191 |
matcher_code => $matcher_code, |
192 |
import_batch_id => $batch_id, |
193 |
booksellerid => $booksellerid, |
194 |
basketno => $basketno |
195 |
}; |
114 |
}; |
196 |
if ($runinbackground) { |
|
|
197 |
$job->finish($results); |
198 |
exit 0; |
199 |
} else { |
200 |
$template->param(staged => $num_valid, |
201 |
matched => $num_with_matches, |
202 |
num_items => $num_items, |
203 |
import_errors => scalar(@import_errors), |
204 |
total => $num_valid + scalar(@import_errors), |
205 |
checked_matches => $checked_matches, |
206 |
matcher_failed => $matcher_failed, |
207 |
matcher_code => $matcher_code, |
208 |
import_batch_id => $batch_id, |
209 |
booksellerid => $booksellerid, |
210 |
basketno => $basketno |
211 |
); |
212 |
} |
213 |
|
115 |
|
214 |
} else { |
116 |
} else { |
215 |
# initial form |
117 |
# initial form |
Lines 231-253
if ($completedJobID) {
Link Here
|
231 |
} |
133 |
} |
232 |
} |
134 |
} |
233 |
|
135 |
|
234 |
output_html_with_http_headers $input, $cookie, $template->output; |
136 |
$template->param( messages => \@messages ); |
235 |
|
|
|
236 |
exit 0; |
237 |
|
137 |
|
238 |
sub staging_progress_callback { |
138 |
output_html_with_http_headers $input, $cookie, $template->output; |
239 |
my $job = shift; |
|
|
240 |
return sub { |
241 |
my $progress = shift; |
242 |
$job->progress($progress); |
243 |
} |
244 |
} |
245 |
|
246 |
sub matching_progress_callback { |
247 |
my $job = shift; |
248 |
my $start_progress = $job->progress(); |
249 |
return sub { |
250 |
my $progress = shift; |
251 |
$job->progress($start_progress + $progress); |
252 |
} |
253 |
} |
254 |
- |
|
|