newtoperlprog has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks

I have a script which fetches the summary file from the NCBI website using command line argument(accession number).

Example: ./efetch.pl NM_000040

Now I am trying to fetch the same file using a HTML webpage which takes the form request via a cgi script.

My question: Is it possible to combine the cgi and my perl script in one file and pass the HTML form argument from the cgi portion of the code to the perl script in single run.

I have tried to do some scripting but it seems that the argument from the cgi is not getting passed to the perl script.

Any help will be greatly appreciated

CGI and Perl Script in one single file #!/usr/bin/perl -wT use strict; use warnings; use LWP::Simple; use CGI::Carp qw(warningsToBrowser fatalsToBrowser); ################### Environmental Variables ################### my ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text + $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } #print "$buffer\n"; # Split information into name/value pairs + @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; # $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } my $access = $FORM{accession}; if ($access =~ m{\A(\w+\d+)\z}) { $access = $1; } print "Content-type:text/html\r\n\r\n"; print "<html>"; print "<head>"; print "<title> CGI Program</title>"; print "</head>"; print "<body>"; if ($access eq "") { print "<h2> Please check the accession number</h2>"; exit; } print "<h2>$access</h2>"; print "</body>"; print "</html>"; print <<HEADING <html> <head> <title> Output result of the program </title> </head> <body> <h1> Summary result </h1> <table border=1> <tr> <th>S.No.</th> <th>Fragment</th> <th>Position</th> <th>Region</th> <th>GC%</th> </tr> HEADING ; ######################## INPUT PARAMETERS ##################### my $utils = "http://www.ncbi.nlm.nih.gov/entrez/eutils"; my $db = "nuccore"; my $query = $access; #"$ARGV[0]" or die "Please provide input for the + accession number. $!"; ############### END OF INPUT PARAMETERS ###################### ############### FILE DOWNLOAD FROM NCBI ###################### my $report = "gb"; # downloads the summary text file open (IN,">", $query.".summary"); my $esearch = "$utils/esearch.fcgi?" . "db=$db&retmax=1&usehistory=y&t +erm="; my $esearch_result = get($esearch . $query); $esearch_result =~ m|<Count>(\d+)</Count>.*<QueryKey>(\d+)</QueryKey>. +*<WebEnv>(\S+)</WebEnv>|s; my $Count = $1; my $QueryKey = $2; my $WebEnv = $3; my $retstart; my $retmax=3; for($retstart = 0; $retstart < $Count; $retstart += $retmax) { my $efetch = "$utils/efetch.fcgi?" . "rettype=$report&retmode=text&retstart=$retstart&retmax=$retmax&" +. "db=$db&query_key=$QueryKey&WebEnv=$WebEnv"; my $efetch_result = get($efetch); print IN $efetch_result, "\n"; } close (IN);

Print command in the perl script prints the "$access" but it fails to pass the value of $access to $query.

HTML form: <form action="/cgi-bin/efetch.cgi" method="post" id="myform"> <div> NCBI accession number:<label for="accession"> <input type="tex +t" name="accession"></label><br> <input type="submit" value="Submit" form="myform"> </div> </form>

Replies are listed 'Best First'.
Re: CGI and Perl script one file, passing arguments
by Your Mother (Archbishop) on Dec 09, 2014 at 23:23 UTC

    Command line version. Adapt, amend, etc as necessary. What NetWallah said. Use CGI if you’re keeping it in the CGI realm (or another modern framework). Required reading: XML::LibXML, XML::LibXML::Node, URI, and as a pre-emptive measure if the following are daunting: Yes, even you can use CPAN, local::lib, cpanm. Getopt::Long if you want deep(er) argument handling.

    #!/usr/bin/env perl # Script/file named pm-1109805 use strictures; use XML::LibXML; use URI; my $term = shift || die "Give a term to search the nuccore DB!\n"; my %args = ( db => "nuccore", retmax => 1, usehistory => "y", term => $term ); my $uri = URI->new("http://www.ncbi.nlm.nih.gov/entrez/eutils/esearch. +fcgi"); $uri->query_form(%args); # If you don't expect errors and don't need cookies etc, use XML::LibX +ML, # if you do, use LWP::UserAgent or WWW::Mechanize or something. my $dom = XML::LibXML->load_xml( location => $uri->as_string ); # Expecting exactly ( one ), findnodes returns a list. my ( $result ) = $dom->findnodes("/eSearchResult"); my $error = $result->findvalue("/ERROR"); die "Error:", "$error", $/ if $error; my $count = $result->findvalue("Count"); my $showing = $result->findvalue("RetMax"); printf "Found %d result%s. Showing %d (RetMax).\n", $count, $count == 1 ? "" : "s", $showing; for my $id ( $result->findnodes("IdList/Id") ) { print "Id: ", $id->textContent, $/; } # print $dom->serialize(1); # To see the raw XML.
    moo@cow[54]~>pm-1109805 NM_000040 Found 1 result. Showing 1 (RetMax). Id: 4557322 moo@cow[55]~>pm-1109805 asdf Found 15 results. Showing 1 (RetMax). Id: 57648377
Re: CGI and Perl script one file, passing arguments
by NetWallah (Canon) on Dec 09, 2014 at 22:36 UTC
    ... fails to pass the value of $access to $query
    How are you coming to that conclusion ?

    Have you tried running this cgi script from the command-line under the perl debugger ?

    (set) QUERY_STRING=accession=your-number perl -d efetch-cgi.pl
    BTW - using the CGI module would simplify your life considerably.

            "You're only given one little spark of madness. You mustn't lose it."         - Robin Williams

Re: CGI and Perl script one file, passing arguments
by RonW (Parson) on Dec 09, 2014 at 22:31 UTC

    You can debug your new CGI from the command line:

    export REQUEST_METHOD=GET export QUERY_STRING=accession=NM_000040 perl -d efetch.cgi

    See perldebug for usage of the Perl debugger

Re: CGI and Perl script one file, passing arguments
by newtoperlprog (Sexton) on Dec 10, 2014 at 16:38 UTC

    Dear poj

    Thank you for your reply. How can we then deal with the read write permission from the webserver to the cgi-bin folder.

    Current permission for the cgi-bin folder: drwxr-xr-x

    Regards

      Write your file somewhere else, /tmp maybe while you are testing.
      poj

Re: CGI and Perl script one file, passing arguments
by newtoperlprog (Sexton) on Dec 10, 2014 at 15:26 UTC

    Dear All

    Thank you for your suggestions. I tried debugging using command line and passed the arguments and the script fetched the file and stored it on the local machine.

    I also pushed the arguments in @ARGV and later printed it in the web browser.

    Still not able to understand the logic how to pass it to the main perl script.

    This is my first attempt to use CGI with perl.

    Regards
      open (IN,">", $query.".summary");

      Check the script can write to the /cgi-bin/ folder by using

      open IN,'>', $query.'.summary' or die "Can't open file $!";

      For security cgi-bin folders are normally not writeable to by the webserver.

      poj