package LIMS::Controller::DataImport;
use base 'LIMS::Base';
use Moose;
has temp_files_sub_dir => ( is => 'rw', isa => 'Str' );
__PACKAGE__->meta->make_immutable(inline_constructor => 0);
use IO::All;
use Data::Dumper;
use LIMS::Local::Utils;
use LIMS::Local::ExcelHandler;
use constant MAX_FILE_SIZE => 50_000 * 1_024; # Limit upload to 50MB
use constant TMP_DIR => 'src/data/tmp_files'; # relative path below app root
#-------------------------------------------------------------------------------
sub default : StartRunmode {
my $self = shift;
# shouldn't be called here - redirect to /
$self->redirect( $self->query->url );
}
#-------------------------------------------------------------------------------
sub bcr_abl : Runmode { # run /wdir/Q922_data.zip test file
my $self = shift;
# if 1st call to method, or no file uploaded:
$self->query->param('source') || return $self->tt_process(); # warn $self->query->param('source');
# set sub-directory for upload file processing:
$self->temp_files_sub_dir('bcr_abl');
# process zip file upload & get IO::All object for contents of upload/extract
# dir (sets flash msg & returns empty on failure):
my $io = $self->_process_upload('bcr_abl') || return $self->tt_process();
# spreadsheet field defs:
my %field_for = (
WELL => 0, # plate well id, eg A1-12, B1-12, etc
LAB_REF => 1, # lab_no & surname
TARGET => 2, # ABL / BCR ABL
);
my $xl = LIMS::Local::ExcelHandler->new(); # $self->debug($xl);
CONTENT : foreach my $content ($io->all) {
# skip non-XL files:
next CONTENT unless $content->filename =~ /\.xls\Z/; # warn $content->filename;
my $xl_file = $content->name; # name() = path/to/file
my $data = $xl->parse_xl_file($xl_file); # warn Dumper $data; # arrayref
# open my $fh, '>data.txt'; print $fh Dumper $data;
warn $_->[$field_for{LAB_REF}] for @$data;
}
# clean up:
$self->_clean_up($io);
}
#--------------------------- private methods -----------------------------------
sub _process_upload {
my ($self, $sub_dir) = @_;
my $src_file = $self->query->upload('source'); # CGI method
unless ( $src_file =~ /\.zip$/ ) {
$self->flash( error => $self->messages('file_upload')->{not_zip_file} );
return 0;
}
# set sub-directory for upload file processing:
$self->temp_files_sub_dir($sub_dir);
# unzip file & stash contents of zip:
$self->_unzip_file($src_file);
# location of zip contents:
my $files_dir = $self->_get_temp_files_dir;
if ( my $io = io($files_dir) ) {
return $io;
}
else {
$self->flash( error => 'could not read contents of upload directory' );
return 0;
}
}
sub _unzip_file {
my ($self, $src_file) = @_; # warn $src_file;
my $upload_dir = $self->_get_temp_files_dir;
my %args = (
upload_dir => $upload_dir,
src_file => $src_file,
);
# create unzip file, extract & report zip contents list:
my @zip_contents = LIMS::Local::Utils::unzip_file(\%args);
# stuff zip_contents into stash:
$self->stash->{zip_contents} = \@zip_contents;
}
# where to extract zip file:
sub _get_temp_files_dir {
my $self = shift;
my $path_to_temp_files = join '/',
$self->cfg('path_to_app_root'), TMP_DIR , $self->temp_files_sub_dir;
return $path_to_temp_files;
}
# delete all from unzip dir:
sub _clean_up {
my ($self, $io) = @_;
foreach ($io->all) { # warn $_->name; # if $_->is_file;
$_->unlink if $_->is_file;
}
}
1;