|
Lines 23-31
use utf8;
Link Here
|
| 23 |
|
23 |
|
| 24 |
use Carp qw( carp ); |
24 |
use Carp qw( carp ); |
| 25 |
use DateTime; |
25 |
use DateTime; |
| 26 |
use Encode qw( from_to ); |
26 |
use Encode qw( from_to ); |
| 27 |
use English qw{ -no_match_vars }; |
27 |
use English qw{ -no_match_vars }; |
| 28 |
use File::Copy qw( copy move ); |
28 |
use File::Copy qw( copy move ); |
| 29 |
use File::Slurp qw( read_file ); |
29 |
use File::Slurp qw( read_file ); |
| 30 |
use Net::FTP; |
30 |
use Net::FTP; |
| 31 |
use Net::SFTP::Foreign; |
31 |
use Net::SFTP::Foreign; |
|
Lines 40-48
sub new {
Link Here
|
| 40 |
my $schema = $database->schema(); |
40 |
my $schema = $database->schema(); |
| 41 |
my $acct = $schema->resultset('VendorEdiAccount')->find($account_id); |
41 |
my $acct = $schema->resultset('VendorEdiAccount')->find($account_id); |
| 42 |
my $self = { |
42 |
my $self = { |
| 43 |
account => $acct, |
43 |
account => $acct, |
| 44 |
schema => $schema, |
44 |
schema => $schema, |
| 45 |
working_dir => C4::Context::temporary_directory, #temporary work directory |
45 |
working_dir => C4::Context::temporary_directory, #temporary work directory |
| 46 |
transfer_date => dt_from_string(), |
46 |
transfer_date => dt_from_string(), |
| 47 |
}; |
47 |
}; |
| 48 |
|
48 |
|
|
Lines 65-71
sub download_messages {
Link Here
|
| 65 |
my $sftp_server_id = $self->{account}->download_sftp_server_id; |
65 |
my $sftp_server_id = $self->{account}->download_sftp_server_id; |
| 66 |
my $sftp_server_transport; |
66 |
my $sftp_server_transport; |
| 67 |
$sftp_server_transport = Koha::SFTP::Servers->find($sftp_server_id)->transport |
67 |
$sftp_server_transport = Koha::SFTP::Servers->find($sftp_server_id)->transport |
| 68 |
if ( $sftp_server_id ); |
68 |
if ($sftp_server_id); |
| 69 |
|
69 |
|
| 70 |
my @retrieved_files; |
70 |
my @retrieved_files; |
| 71 |
|
71 |
|
|
Lines 88-94
sub upload_messages {
Link Here
|
| 88 |
my $sftp_server_id = $self->{account}->upload_sftp_server_id; |
88 |
my $sftp_server_id = $self->{account}->upload_sftp_server_id; |
| 89 |
my $sftp_server_transport; |
89 |
my $sftp_server_transport; |
| 90 |
$sftp_server_transport = Koha::SFTP::Servers->find($sftp_server_id)->transport |
90 |
$sftp_server_transport = Koha::SFTP::Servers->find($sftp_server_id)->transport |
| 91 |
if ( $sftp_server_id ); |
91 |
if ($sftp_server_id); |
| 92 |
|
92 |
|
| 93 |
if (@messages) { |
93 |
if (@messages) { |
| 94 |
if ( !$sftp_server_transport ) { |
94 |
if ( !$sftp_server_transport ) { |
|
Lines 109-116
sub file_download {
Link Here
|
| 109 |
|
109 |
|
| 110 |
my $file_ext = _get_file_ext( $self->{message_type} ); |
110 |
my $file_ext = _get_file_ext( $self->{message_type} ); |
| 111 |
|
111 |
|
| 112 |
my $dir = $self->{account}->download_directory; # makes code more readable |
112 |
my $dir = $self->{account}->download_directory; # makes code more readable |
| 113 |
# C = ready to retrieve E = Edifact |
113 |
# C = ready to retrieve E = Edifact |
| 114 |
my $msg_hash = $self->message_hash(); |
114 |
my $msg_hash = $self->message_hash(); |
| 115 |
if ( opendir my $dh, $dir ) { |
115 |
if ( opendir my $dh, $dir ) { |
| 116 |
my @file_list = readdir $dh; |
116 |
my @file_list = readdir $dh; |
|
Lines 119-126
sub file_download {
Link Here
|
| 119 |
|
119 |
|
| 120 |
if ( $filename =~ m/[.]$file_ext$/ ) { |
120 |
if ( $filename =~ m/[.]$file_ext$/ ) { |
| 121 |
if ( copy( "$dir/$filename", $self->{working_dir} ) ) { |
121 |
if ( copy( "$dir/$filename", $self->{working_dir} ) ) { |
| 122 |
} |
122 |
} else { |
| 123 |
else { |
|
|
| 124 |
carp "copy of $filename failed"; |
123 |
carp "copy of $filename failed"; |
| 125 |
next; |
124 |
next; |
| 126 |
} |
125 |
} |
|
Lines 131-138
sub file_download {
Link Here
|
| 131 |
} |
130 |
} |
| 132 |
} |
131 |
} |
| 133 |
$self->ingest( $msg_hash, @downloaded_files ); |
132 |
$self->ingest( $msg_hash, @downloaded_files ); |
| 134 |
} |
133 |
} else { |
| 135 |
else { |
|
|
| 136 |
carp "Cannot open $dir"; |
134 |
carp "Cannot open $dir"; |
| 137 |
return; |
135 |
return; |
| 138 |
} |
136 |
} |
|
Lines 162-184
sub sftp_download {
Link Here
|
| 162 |
timeout => 10, |
160 |
timeout => 10, |
| 163 |
); |
161 |
); |
| 164 |
if ( $sftp->error ) { |
162 |
if ( $sftp->error ) { |
| 165 |
return $self->_abort_download( undef, |
163 |
return $self->_abort_download( |
| 166 |
'Unable to connect to remote host: ' . $sftp->error ); |
164 |
undef, |
|
|
165 |
'Unable to connect to remote host: ' . $sftp->error |
| 166 |
); |
| 167 |
} |
167 |
} |
| 168 |
$sftp->setcwd( $self->{account}->download_directory ) |
168 |
$sftp->setcwd( $self->{account}->download_directory ) |
| 169 |
or return $self->_abort_download( $sftp, |
169 |
or return $self->_abort_download( |
| 170 |
"Cannot change remote dir: " . $sftp->error ); |
170 |
$sftp, |
|
|
171 |
"Cannot change remote dir: " . $sftp->error |
| 172 |
); |
| 171 |
my $file_list = $sftp->ls() |
173 |
my $file_list = $sftp->ls() |
| 172 |
or return $self->_abort_download( $sftp, |
174 |
or return $self->_abort_download( |
| 173 |
"cannot get file list from server: " . $sftp->error ); |
175 |
$sftp, |
|
|
176 |
"cannot get file list from server: " . $sftp->error |
| 177 |
); |
| 174 |
foreach my $file ( @{$file_list} ) { |
178 |
foreach my $file ( @{$file_list} ) { |
| 175 |
my $filename = $file->{filename}; |
179 |
my $filename = $file->{filename}; |
| 176 |
|
180 |
|
| 177 |
if ( $filename =~ m/[.]$file_ext$/ ) { |
181 |
if ( $filename =~ m/[.]$file_ext$/ ) { |
| 178 |
$sftp->get( $filename, "$self->{working_dir}/$filename" ); |
182 |
$sftp->get( $filename, "$self->{working_dir}/$filename" ); |
| 179 |
if ( $sftp->error ) { |
183 |
if ( $sftp->error ) { |
| 180 |
$self->_abort_download( $sftp, |
184 |
$self->_abort_download( |
| 181 |
"Error retrieving $filename: " . $sftp->error ); |
185 |
$sftp, |
|
|
186 |
"Error retrieving $filename: " . $sftp->error |
| 187 |
); |
| 182 |
last; |
188 |
last; |
| 183 |
} |
189 |
} |
| 184 |
push @downloaded_files, $filename; |
190 |
push @downloaded_files, $filename; |
|
Lines 188-195
sub sftp_download {
Link Here
|
| 188 |
#$sftp->atomic_rename( $filename, $processed_name ); |
194 |
#$sftp->atomic_rename( $filename, $processed_name ); |
| 189 |
my $ret = $sftp->rename( $filename, $processed_name ); |
195 |
my $ret = $sftp->rename( $filename, $processed_name ); |
| 190 |
if ( !$ret ) { |
196 |
if ( !$ret ) { |
| 191 |
$self->_abort_download( $sftp, |
197 |
$self->_abort_download( |
| 192 |
"Error renaming $filename: " . $sftp->error ); |
198 |
$sftp, |
|
|
199 |
"Error renaming $filename: " . $sftp->error |
| 200 |
); |
| 193 |
last; |
201 |
last; |
| 194 |
} |
202 |
} |
| 195 |
|
203 |
|
|
Lines 206-221
sub ingest {
Link Here
|
| 206 |
foreach my $f (@downloaded_files) { |
214 |
foreach my $f (@downloaded_files) { |
| 207 |
|
215 |
|
| 208 |
# Check file has not been downloaded already |
216 |
# Check file has not been downloaded already |
| 209 |
my $existing_file = $self->{schema}->resultset('EdifactMessage') |
217 |
my $existing_file = $self->{schema}->resultset('EdifactMessage')->find( { filename => $f, } ); |
| 210 |
->find( { filename => $f, } ); |
|
|
| 211 |
if ($existing_file) { |
218 |
if ($existing_file) { |
| 212 |
carp "skipping ingest of $f : filename exists"; |
219 |
carp "skipping ingest of $f : filename exists"; |
| 213 |
next; |
220 |
next; |
| 214 |
} |
221 |
} |
| 215 |
|
222 |
|
| 216 |
$msg_hash->{filename} = $f; |
223 |
$msg_hash->{filename} = $f; |
| 217 |
my $file_content = |
224 |
my $file_content = read_file( "$self->{working_dir}/$f", binmode => ':raw' ); |
| 218 |
read_file( "$self->{working_dir}/$f", binmode => ':raw' ); |
|
|
| 219 |
if ( !defined $file_content ) { |
225 |
if ( !defined $file_content ) { |
| 220 |
carp "Unable to read download file $f"; |
226 |
carp "Unable to read download file $f"; |
| 221 |
next; |
227 |
next; |
|
Lines 243-249
sub ftp_download {
Link Here
|
| 243 |
|
249 |
|
| 244 |
my $msg_hash = $self->message_hash(); |
250 |
my $msg_hash = $self->message_hash(); |
| 245 |
my @downloaded_files; |
251 |
my @downloaded_files; |
| 246 |
my $ftp = Net::FTP->new( |
252 |
my $ftp = Net::FTP->new( |
| 247 |
$sftp_server->host, |
253 |
$sftp_server->host, |
| 248 |
Port => $sftp_server->port, |
254 |
Port => $sftp_server->port, |
| 249 |
Timeout => 10, |
255 |
Timeout => 10, |
|
Lines 254-274
sub ftp_download {
Link Here
|
| 254 |
"Cannot connect to " . $sftp_server->host . ": " . $EVAL_ERROR |
260 |
"Cannot connect to " . $sftp_server->host . ": " . $EVAL_ERROR |
| 255 |
); |
261 |
); |
| 256 |
$ftp->login( $sftp_server->user_name, $sftp_server->plain_text_password ) |
262 |
$ftp->login( $sftp_server->user_name, $sftp_server->plain_text_password ) |
| 257 |
or return $self->_abort_download( $ftp, "Cannot login: $ftp->message()" ); |
263 |
or return $self->_abort_download( $ftp, "Cannot login: $ftp->message()" ); |
| 258 |
$ftp->cwd( $self->{account}->download_directory ) |
264 |
$ftp->cwd( $self->{account}->download_directory ) |
| 259 |
or return $self->_abort_download( $ftp, |
265 |
or return $self->_abort_download( |
| 260 |
"Cannot change remote dir : $ftp->message()" ); |
266 |
$ftp, |
|
|
267 |
"Cannot change remote dir : $ftp->message()" |
| 268 |
); |
| 261 |
my $file_list = $ftp->ls() |
269 |
my $file_list = $ftp->ls() |
| 262 |
or |
270 |
or return $self->_abort_download( $ftp, 'cannot get file list from server' ); |
| 263 |
return $self->_abort_download( $ftp, 'cannot get file list from server' ); |
|
|
| 264 |
|
271 |
|
| 265 |
foreach my $filename ( @{$file_list} ) { |
272 |
foreach my $filename ( @{$file_list} ) { |
| 266 |
|
273 |
|
| 267 |
if ( $filename =~ m/[.]$file_ext$/ ) { |
274 |
if ( $filename =~ m/[.]$file_ext$/ ) { |
| 268 |
|
275 |
|
| 269 |
if ( !$ftp->get( $filename, "$self->{working_dir}/$filename" ) ) { |
276 |
if ( !$ftp->get( $filename, "$self->{working_dir}/$filename" ) ) { |
| 270 |
$self->_abort_download( $ftp, |
277 |
$self->_abort_download( |
| 271 |
"Error retrieving $filename: $ftp->message" ); |
278 |
$ftp, |
|
|
279 |
"Error retrieving $filename: $ftp->message" |
| 280 |
); |
| 272 |
last; |
281 |
last; |
| 273 |
} |
282 |
} |
| 274 |
|
283 |
|
|
Lines 295-301
sub ftp_upload {
Link Here
|
| 295 |
return |
304 |
return |
| 296 |
unless $sftp_server; |
305 |
unless $sftp_server; |
| 297 |
|
306 |
|
| 298 |
my $ftp = Net::FTP->new( |
307 |
my $ftp = Net::FTP->new( |
| 299 |
$sftp_server->host, |
308 |
$sftp_server->host, |
| 300 |
Port => $sftp_server->port, |
309 |
Port => $sftp_server->port, |
| 301 |
Timeout => 10, |
310 |
Timeout => 10, |
|
Lines 306-315
sub ftp_upload {
Link Here
|
| 306 |
"Cannot connect to " . $sftp_server->host . ": " . $EVAL_ERROR |
315 |
"Cannot connect to " . $sftp_server->host . ": " . $EVAL_ERROR |
| 307 |
); |
316 |
); |
| 308 |
$ftp->login( $sftp_server->user_name, $sftp_server->plain_text_password ) |
317 |
$ftp->login( $sftp_server->user_name, $sftp_server->plain_text_password ) |
| 309 |
or return $self->_abort_download( $ftp, "Cannot login: $ftp->message()" ); |
318 |
or return $self->_abort_download( $ftp, "Cannot login: $ftp->message()" ); |
| 310 |
$ftp->cwd( $self->{account}->upload_directory ) |
319 |
$ftp->cwd( $self->{account}->upload_directory ) |
| 311 |
or return $self->_abort_download( $ftp, |
320 |
or return $self->_abort_download( |
| 312 |
"Cannot change remote dir : $ftp->message()" ); |
321 |
$ftp, |
|
|
322 |
"Cannot change remote dir : $ftp->message()" |
| 323 |
); |
| 313 |
foreach my $m (@messages) { |
324 |
foreach my $m (@messages) { |
| 314 |
my $content = $m->raw_msg; |
325 |
my $content = $m->raw_msg; |
| 315 |
if ($content) { |
326 |
if ($content) { |
|
Lines 319-326
sub ftp_upload {
Link Here
|
| 319 |
$m->transfer_date( $self->{transfer_date} ); |
330 |
$m->transfer_date( $self->{transfer_date} ); |
| 320 |
$m->status('sent'); |
331 |
$m->status('sent'); |
| 321 |
$m->update; |
332 |
$m->update; |
| 322 |
} |
333 |
} else { |
| 323 |
else { |
334 |
|
| 324 |
# error in transfer |
335 |
# error in transfer |
| 325 |
|
336 |
|
| 326 |
} |
337 |
} |
|
Lines 348-357
sub sftp_upload {
Link Here
|
| 348 |
port => $sftp_server->port, |
359 |
port => $sftp_server->port, |
| 349 |
timeout => 10, |
360 |
timeout => 10, |
| 350 |
); |
361 |
); |
| 351 |
$sftp->die_on_error("Cannot ssh to " . $sftp_server->host); |
362 |
$sftp->die_on_error( "Cannot ssh to " . $sftp_server->host ); |
| 352 |
$sftp->setcwd( $self->{account}->upload_directory ) |
363 |
$sftp->setcwd( $self->{account}->upload_directory ) |
| 353 |
or return $self->_abort_download( $sftp, |
364 |
or return $self->_abort_download( |
| 354 |
"Cannot change remote dir : " . $sftp->error ); |
365 |
$sftp, |
|
|
366 |
"Cannot change remote dir : " . $sftp->error |
| 367 |
); |
| 355 |
foreach my $m (@messages) { |
368 |
foreach my $m (@messages) { |
| 356 |
my $content = $m->raw_msg; |
369 |
my $content = $m->raw_msg; |
| 357 |
if ($content) { |
370 |
if ($content) { |
|
Lines 361-368
sub sftp_upload {
Link Here
|
| 361 |
$m->transfer_date( $self->{transfer_date} ); |
374 |
$m->transfer_date( $self->{transfer_date} ); |
| 362 |
$m->status('sent'); |
375 |
$m->status('sent'); |
| 363 |
$m->update; |
376 |
$m->update; |
| 364 |
} |
377 |
} else { |
| 365 |
else { |
378 |
|
| 366 |
# error in transfer |
379 |
# error in transfer |
| 367 |
|
380 |
|
| 368 |
} |
381 |
} |
|
Lines 388-402
sub file_upload {
Link Here
|
| 388 |
$m->transfer_date( $self->{transfer_date} ); |
401 |
$m->transfer_date( $self->{transfer_date} ); |
| 389 |
$m->status('sent'); |
402 |
$m->status('sent'); |
| 390 |
$m->update; |
403 |
$m->update; |
| 391 |
} |
404 |
} else { |
| 392 |
else { |
|
|
| 393 |
carp "Could not transfer $m->filename : $ERRNO"; |
405 |
carp "Could not transfer $m->filename : $ERRNO"; |
| 394 |
next; |
406 |
next; |
| 395 |
} |
407 |
} |
| 396 |
} |
408 |
} |
| 397 |
} |
409 |
} |
| 398 |
} |
410 |
} else { |
| 399 |
else { |
|
|
| 400 |
carp "Upload directory $dir does not exist"; |
411 |
carp "Upload directory $dir does not exist"; |
| 401 |
} |
412 |
} |
| 402 |
return; |
413 |
return; |