#!/usr/bin/perl -Tw use strict; use CGI qw(:all delete_all escapeHTML); $|=1; ###################################################################### # Ensure all fatals go to browser during debugging and set-up. # # This must be comment out on production code for security. # ###################################################################### BEGIN { $|=1; print "Content-type: text/html\n\n"; use CGI::Carp('fatalsToBrowser'); } ###################################################################### # Untaint the path & Use CGI.pm. # ###################################################################### $ENV{PATH} = "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"; ###################################################################### # Create new CGI. # ###################################################################### my $cgi = new CGI; ###################################################################### # Untaint & Check the CGI. # ###################################################################### my ($error,$line); # Argument 1: $session contains the process id ####################### my $session = get_session_id(); # Combination of local time and process # Argument 2: $query contains query sequence ######################### my @query_info = (); my $query = "/tmp/query.$session"; # File containing the query sequence my $query_box = $cgi->param("query_box"); # Server box where the query was pasted my $query_file = $cgi->upload("query_file"); # Server upload file content containing the query ####################################### # 1. Extraction of the query sequence # ####################################### # If the user pasted the query in the query box... # if ($query_box ne "") { # Read the query sequence # @query_info = split(/\n/, $query_box); # If the user upload the query in a file... # } else { # Read the query sequence # while (<$query_file>) { chomp $_; push (@query_info, $_); } } ######################################################## # 2. Checking if the query sequence is in FASTA format # ######################################################## # Get the query tag & sequence # (my @query) = @{extract_sequences(\@query_info)}; # If more than 1 query was submitted... # if (scalar (@query) != 2) { # Error message # $error = "The query sequence is not in FASTA format or more than 1 query is submitted.\n"; # Erase temp files # unlink ($query); # Print error page # print_error_page($error); # Exit the CGI # exit 0; } ################################ # 3. Saving the query sequence # ################################ # Open file or give error message and exit the CGI # open (FILE, ">$query") or ($error = "ModLink+ encountered an error: Cannot create the file to write the query sequence ($query). Do please notify this error by sending an e-mail to the server administrator (ofornes\@imim.es). We will contact you once the error is solved. Thanks for your patience.\n" and unlink ($query) and print_error_page($error) and exit 0); # Foreach line of the file... # foreach $line (@query) { # Print the line # print FILE $line."\n"; } close (FILE); # Argument 5: $databases contains databases ########################## my $databases = ""; # If defined job title # foreach my $database ($cgi->param("databases")) { if ($database =~ /1-7/) { $databases .= $database; } } # Argument 3: $extrapolation contains SCOP codes extrapolation choice my $extrapolation = "none"; # String containing the SCOP codes extrapolation choice if ($cgi->param("expansion") eq "by family") { $extrapolation = "fa"; } elsif ($cgi->param("expansion") eq "by superfamily") { $extrapolation = "sf"; } elsif ($cgi->param("expansion") eq "by fold") { $extrapolation = "cf"; } # Argument 4: $MK_hub contains cut-off limit on the acceptance of hubs my $MK_hub = ""; # Integer containining the cut-off limit on the acceptance of hubs if ($cgi->param("hubs") =~ /(\d+)/) { $MK_hub = $1; } else { $MK_hub = "none"; } # Argument 5: $EVTE contains evalue threshold on extrapolation (EVTE) my $EVTE = ""; # Integer containing the EVTE if ($cgi->param("evte") =~ /(\d+)/) { $EVTE = $1; } else { $EVTE = 1e-12; } # Argument 6: $EVTH contains evalue threshold on sequence homologs (EVTH) my $EVTH = ""; # Integer containing the EVTH if ($cgi->param("evth") =~ /(\d+)/) { $EVTH = $1; } else { $EVTH = 1e-70; } # Argument 7: $interactor contains query sequence ################### my @interactors_info = (); my $interactor = "/tmp/interactor.$session"; # File containing the interactor sequences my $interactor_num = $cgi->param("interactor_num"); # Integer containing the number of interactor sequences my $interactor_box = $cgi->param("interactor_box"); # Server box where the interactors were pasted my $interactor_file = $cgi->upload("interactor_file"); # Server upload file content containing the interactors if ($interactor_box ne "" and $interactor_file ne "") { ############################################# # 1. Extraction of the interactor sequences # ############################################# # If the user pasted the interactors in the interactor box... # if ($interactor_box ne "") { # Read the interactor sequences # @interactors_info = split(/\n/, $interactor_box); # If the user upload the interactor in a file... # } else { # Read the interactor sequence # while (<$interactor_file>) { chomp $_; push (@interactors_info, $_); } } ############################################################### # 2. Checking if the interactor sequences are in FASTA format # ############################################################### # Get the interactor tags & sequences # (my @interactors) = @{extract_sequences(\@interactors_info)}; # If more than 1 query was submitted... # if (scalar (@interactors) != ($interactor_num*2)) { # Error message # $error = "The interactor sequences are not in FASTA format or number of interactors submited does not correspond with the number you selected.\n"; # Erase temp files # unlink ($query); unlink ($interactor); # Print error page # print_error_page($error); # Exit the CGI # exit 0; } ###################################### # 3. Saving the interactor sequences # ###################################### # Open file or give error message and exit the CGI # open (FILE, ">$query") or ($error = "ModLink+ encountered an error: Cannot create the file to write the interactor sequences ($interactor). Do please notify this error by sending an e-mail to the server administrator (ofornes\@imim.es). We will contact you once the error is solved. Thanks for your patience.\n" and unlink ($query) and unlink ($interactor) and print_error_page($error) and exit 0); foreach $line (@interactors) { # Print the line # print FILE $line."\n"; } close (FILE); # Not interactors submited # } else { $interactor = "none"; } 1; # Sub-routines from here ########################################################## sub print_error_page { ###################################################################### # This function prints the error html head and body (error message # # every single place where enters this function). # ###################################################################### # Input # my $error = $_[0]; # Print the errors page # print start_html('-title' => "Secrets of the Pyramids", '-author' => 'ofornes@imim.es', '-base' => "true", '-target' => "_blank", '-style' => { '-src' => "/styles/modlink.css" }, '-script' => { '-type' => 'JavaScript', '-src' => "/javascript/modlink.js" }), table({'-border' => "0", '-cellspacing' => 0}, Tr({'-background' => "blue"}, td({'-class' => "banner"}, [print_server_title_and_logos()]))), h2("Request not processed"), strong($error), end_html(); sub print_server_title_and_logos { table({'-border' => "0", '-cellspacing' => 10}, Tr( td({'-class' => "program_name"}, ["ModLink+
".print_server_options()]), td({'-class' => "grib", '-align' => "right"}, img{src => "/img/grib_logo.gif"}), td({'-class' => "sbi", '-align' => "right", '-valign' => "center"}, img {src => "/img/sbi_logo.gif"}))); } sub print_server_options { table({'-border' => "0", '-cellspacing' => 0}, Tr({'-valign' => "bottom"}, td({'-class' => "options", '-onMouseOut' => "style.color='white';", '-onMouseOver' => "style.cursor='pointer';style.color='black';"}, ["Home"]), td({'-class' => "options", '-onMouseOver' => "style.cursor='pointer';style.color='black';", '-onMouseOut' => "style.color='white';"}, ["Recent Results"]), td({'-class' => "options", '-onMouseOver' => "style.cursor='pointer';style.color='black';", '-onMouseOut' => "style.color='white';"}, ["Help"]))); } } sub extract_sequences { ###################################################################### # This function goes through the sequence data extracting lines that # # contains sequence or tags. # ###################################################################### my ($line); # Initialize # my $sequence = ""; my @sequences = (); # Input # my @extracted_data = @{$_[0]}; # Foreach line of sequence... # foreach $line (@extracted_data) { chomp $line; # Skip lines containing info... # if ($line =~ /^\s*$/) { next; } elsif ($line =~ /^\s*#/) { next; # Get the line with tag identifier # } elsif ($line =~ /^>/) { push (@sequences, $line); # Get the line with sequence and join it to the main sequence # } else { # If previous item saved is a tag identifier... # if ($sequences[scalar (@sequences) -1] =~ /^>/) { # Push the line with sequence to @sequences # push (@sequences, $line); # If previous item saved is a sequence... # } else { # Join the sequence to the main sequence # if (defined $sequences[scalar (@sequences) -1]) { $sequences[scalar (@sequences) -1] .= $line; } else { push (@sequences, $line); } } } } # Foreach position in @sequences # for (my $pos = 0; $pos < scalar (@sequences); $pos++) { # If item saved is sequence... # if (!($sequences[$pos] =~ /^>/)) { # Clean up the sequence # $sequences[$pos] =~ s/\n//mg; # make one line $sequences[$pos] =~ s/\r//mg; # make one line $sequences[$pos] =~ s/\W+//g; # eliminate non-word char $sequences[$pos] =~ s/_+//g; # eliminate underscore, since not covered by \W $sequences[$pos] =~ s/\d+//g; # eliminate numbers $sequences[$pos] =~ s/\*//; # eliminate *'s $sequences[$pos] =~ s/\s+//g; # eliminate spaces $sequences[$pos] =~ tr/a-z/A-Z/; # convert to uppercase } } return (\@sequences); } sub get_session_id { ###################################################################### # Defines self session id. # ###################################################################### require Digest::MD5; Digest::MD5::md5_hex(Digest::MD5::md5_hex(time().{}.rand().$$)); }