<commit_before>package Bio::BioVeL::AsynchronousService::SMRT;
use strict;
use warnings;
use Bio::BioVeL::AsynchronousService ':status';
use Bio::Phylo::Util::Logger 'INFO';
use base 'Bio::BioVeL::AsynchronousService';


=head1 NAME

Bio::BioVeL::AsynchronousService::SMRT 

=head1 DESCRIPTION

This class launches the SUPERSMART web services. Each step of the pipeline
can be ran by specifying the subcommand in the 'command' argument passed to Apache. 
All other subcommands are then specified by the specific subcommand class 
that is invoked (subcommand classes are defined in Bio::SUPERSMART::App::smrt::Command::*).
The output file (or directory) produced by the subcommand is made accessible to the service via the
method C<response_location>.

=head1 METHODS

=over

=item launch

Launches a SUPERSMART subcommand, specified by the service parameter 'command'.
Arguments and options are passed to the subcommand via the parameters of the web service.


=cut

sub launch {
	my $self = shift;

	my $log = $self->logger;
	$log->VERBOSE( '-level' => INFO, '-class' => __PACKAGE__ );
	
	# collect parameters passed to web service
	my $params = $self->{'_params'};
	my $command = delete $params->{'command'};	
	delete $params->{'service'};
		
	# choose command class according to what was specified in parameter 'command'
	my $commandclass = "Bio::SUPERSMART::App::smrt::Command::" . $command;	
	eval "require $commandclass";
	
	# get options of the subcommand and remember the ones
	#  that require an actual file (and not just a filename)
	my @cmd_options = eval "$commandclass" . "::options()";
	my %file_options; 
	foreach my $option ( @cmd_options ) {
		# file options are specified by arg => file
		my $has_file_arg = eval {grep { ( UNIVERSAL::isa($_, "HASH") and ( $_->{arg} eq "file")) } @${option}};
		if ( $has_file_arg ){
			my $opt_name = @{$option}[0];
			# keep short name (one letter) and long name
			my ($long, $short) = ($opt_name=~/^(.+?)\|(.)/);
			@file_options{ ($long, $short) } = (1, 1);
		}
	}
	
	# parse the given parameters and construct
	#  an array that corresponds to the ARGV array that would
	#  be passed if we called the subcommand on the command-line
	my @argv;
	foreach my $paramname ( keys $params ) {
		my $paramvalue = $params->{ $paramname };
				
		# if the parameter is an input file, it might have to be decoded,
		#  downloaded and written to the working directory. Check 
		if (exists $file_options{ $paramname }) {
			$log->info("Input file argument $paramname = $paramvalue given, trying to resolve");
			my $readfh  = $self->get_handle( $paramvalue );	
			
			# set filename to name of input parameter
			my $infilename = $self->outdir . "/" .  $paramname . ".txt";
			open my $writefh, '>', $infilename;
			print $writefh $_ while <$readfh>; 
			$paramvalue = $infilename;
		}
		push @argv, length( $paramname) == 1  ? "-" . $paramname : "--" . $paramname;
		push @argv, $paramvalue;
	}
	
	# make command object using the argv array
	$log->info("Instantiating $command class with arguments " . join(" ", @argv));	
	my ($cmd, $opt, $args) = $commandclass->prepare( lc $command, @argv ); 

	# set working directory to directory accessible to the server
	$opt->{'workdir'} = $self->outdir;
	$self->response_location( $self->outdir . "/" . $opt->outfile );

	# here we need to serialize again because otherwise the parent process (and the
	#  serialized object would not know the response location. This is a bit dirty.
	$self->serialize;
	
	# write command output to logfile
	$opt->{'logfile'} = $command . ".log";

	# finally run the subcommand. Input checking is taken care of by the subcommand class	
	$cmd->validate_args( $opt, $args );
	$log->info("executing subcommand $command");
	my $success = $cmd->execute( $opt, $args );	
	$log->debug("command $command finished with return value $success");

	# this is to tell the parent process that we are done
	my $df = $self->done_flag;
	system("touch $df");
}

=item outdir

This object method returns a directory location where the child class can write its output

=cut

sub outdir {
	my $self = shift;
	my $dir  = $self->workdir;
	make_path($dir) if not -d $dir;
	return $dir;
}

=item response_location

Redirects the client to the output file (or directory) of the subcommand invoked.

=cut

sub response_location { 
	my $self = shift;
	$self->{'response_location'} = shift if @_;
	return $self->{'response_location'};
}

=item response_body

Returns the analysis result as a string. In this service, this is a list with the alignemnt files
produced in the working directory

=cut

sub response_body {
	my $self = shift;
	open my $fh, '<', $self->response_location;
	my @result = do { local $/; <$fh> };
	return join "\n", @result;
}<commit_msg>now removing parameters that are passed via apache and that are not meant for the subcommand invoked<commit_after>package Bio::BioVeL::AsynchronousService::SMRT;
use strict;
use warnings;
use Bio::BioVeL::AsynchronousService ':status';
use Bio::Phylo::Util::Logger 'INFO';
use base 'Bio::BioVeL::AsynchronousService';


=head1 NAME

Bio::BioVeL::AsynchronousService::SMRT 

=head1 DESCRIPTION

This class launches the SUPERSMART web services. Each step of the pipeline
can be ran by specifying the subcommand in the 'command' argument passed to Apache. 
All other subcommands are then specified by the specific subcommand class 
that is invoked (subcommand classes are defined in Bio::SUPERSMART::App::smrt::Command::*).
The output file (or directory) produced by the subcommand is made accessible to the service via the
method C<response_location>.

=head1 METHODS

=over

=item launch

Launches a SUPERSMART subcommand, specified by the service parameter 'command'.
Arguments and options are passed to the subcommand via the parameters of the web service.


=cut

sub launch {
	my $self = shift;

	my $log = $self->logger;
	$log->VERBOSE( '-level' => INFO, '-class' => __PACKAGE__ );
	
	# collect parameters passed to web service
	my $params = $self->{'_params'};
	my $command = delete $params->{'command'};	
	
	# delete params that are not meant for the subcommand
	delete $params->{'service'};
	delete $params->{'jobid'};
		
	# choose command class according to what was specified in parameter 'command'
	my $commandclass = "Bio::SUPERSMART::App::smrt::Command::" . $command;	
	eval "require $commandclass";
	
	# get options of the subcommand and remember the ones
	#  that require an actual file (and not just a filename)
	my @cmd_options = eval "$commandclass" . "::options()";
	my %file_options; 
	foreach my $option ( @cmd_options ) {
		# file options are specified by arg => file
		my $has_file_arg = eval {grep { ( UNIVERSAL::isa($_, "HASH") and ( $_->{arg} eq "file")) } @${option}};
		if ( $has_file_arg ){
			my $opt_name = @{$option}[0];
			# keep short name (one letter) and long name
			my ($long, $short) = ($opt_name=~/^(.+?)\|(.)/);
			@file_options{ ($long, $short) } = (1, 1);
		}
	}
	
	# parse the given parameters and construct
	#  an array that corresponds to the ARGV array that would
	#  be passed if we called the subcommand on the command-line
	my @argv;
	foreach my $paramname ( keys $params ) {
		my $paramvalue = $params->{ $paramname };
				
		# if the parameter is an input file, it might have to be decoded,
		#  downloaded and written to the working directory. Check 
		if (exists $file_options{ $paramname }) {
			$log->info("Input file argument $paramname = $paramvalue given, trying to resolve");
			my $readfh  = $self->get_handle( $paramvalue );	
			
			# set filename to name of input parameter
			my $infilename = $self->outdir . "/" .  $paramname . ".txt";
			open my $writefh, '>', $infilename;
			print $writefh $_ while <$readfh>; 
			$paramvalue = $infilename;
		}
		push @argv, length( $paramname) == 1  ? "-" . $paramname : "--" . $paramname;
		push @argv, $paramvalue;
	}
	
	# make command object using the argv array
	$log->info("Instantiating $command class with arguments " . join(" ", @argv));	
	my ($cmd, $opt, $args) = $commandclass->prepare( lc $command, @argv ); 

	# set working directory to directory accessible to the server
	$opt->{'workdir'} = $self->outdir;
	$self->response_location( $self->outdir . "/" . $opt->outfile );

	# here we need to serialize again because otherwise the parent process (and the
	#  serialized object would not know the response location. This is a bit dirty.
	$self->serialize;
	
	# write command output to logfile
	$opt->{'logfile'} = $command . ".log";

	# finally run the subcommand. Input checking is taken care of by the subcommand class	
	$cmd->validate_args( $opt, $args );
	$log->info("executing subcommand $command");
	my $success = $cmd->execute( $opt, $args );	
	$log->debug("command $command finished with return value $success");

	# this is to tell the parent process that we are done
	my $df = $self->done_flag;
	system("touch $df");
}

=item response_location

Redirects the client to the output file (or directory) of the subcommand invoked.

=cut

sub response_location { 
	my $self = shift;
	$self->{'response_location'} = shift if @_;
	return $self->{'response_location'};
}

=item response_body

Returns the analysis result as a string. In this service, this is a list with the alignemnt files
produced in the working directory

=cut

sub response_body {
	my $self = shift;
	open my $fh, '<', $self->response_location;
	my @result = do { local $/; <$fh> };
	return join "\n", @result;
}
{'fraction_non_alphanumeric': 0.12828111769686706, 'fraction_numerical': 0.0014817950889077054, 'mean_word_length': 4.180372807017544, 'pattern_counts': {'":': 2, '<': 11, '<?xml version=': 0, '>': 73, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2482240', 'n_tokens_mistral': 3118, 'n_tokens_neox': 2929, 'n_words': 1116}