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

Dear Monks
I am trying to write a cgi perl cgi script that accepts a url like:
&xmin=100&xmax=200&other=parameters&
and return an image.
I am trying but new to cgi programming.
Here is my code. I know its a very very basic code that I have written but I guess its better to try then nothing ;)
#!/usr/bin/perl use CGI; my $query = new CGI; my $xmin = $query->param('xmin'); my $xmin = $query->param('xmax'); print "Content-type:text/html\n\n"; print "<html>"; if( $ENV{"REQUEST_METHOD" eq "GET"} ) { ($key, $value) = split(/=/,$ENV{"QUERY_STRING"}); } print "<li>Key is \" $key \" "; print "<li>Value is \" $value \" "; print "</html>";
I have to actually pass these values to a javascript like this in my html page:-
function query(x){ var url = '/MyScript.pl?chr=' + chr + '&version=5&layers=gene&organism=' + org + '&loc=' + x + '&' + 'ds=' + 588 jfetch(url,'query'); }
My input data can be like this
Chr1 100 200 cancer human Chr2 300 400 diabetes human Chr3 600 700 cough human
I know that I still have to work a lot on it but donno howto :(
I would really appreciate any help from dear Monks.
Thanks

Replies are listed 'Best First'.
Re: Help in a cgi script
by bradcathey (Prior) on Dec 11, 2008 at 02:25 UTC

    What is CGI about your code? Make your life easier by *actually* using CGI:

    use CGI; my $query = new CGI; my $xmin = $query->param('xmin'); etc.

    But as to the rest of what you are trying to do (javascript?), I'm clueless.

    —Brad
    "The important work of moving the world forward does not wait to be done by perfect men." George Eliot
Re: Help in a cgi script
by Your Mother (Archbishop) on Dec 11, 2008 at 03:19 UTC

    I could probably help you if your use case were more clear. It sounds like you're trying to do Ajax, maybe, and returning the image's source, maybe, or just its path. Show and explain how all the JS/DHTML is supposed to behave. Then the necessary Perl will become clear, I think.

      Hi,
      For further reference I am attaching my full html page
      <html xmlns="http://www.w3.org/1999/xhtml"> <head> <style type="text/css"> #map { width: 900px; height: 282; border: 1px solid black; } #zoomLevel { bottom: 10px; left: 0px; } #gene { background-color: red; color:white; } #mrna { background-color: blue; color:white; } #cds { background-color: green; color:white; } </style> <script src="/OpenLayers.js"></script> <script src="javascript/Genomic.js"></script> <script src="javascript/opengenes.js"></script> <script type="text/javascript"> /* ruler, chromosome, cds, rna, gene, protein, domain, other, cns, nt, gc, background, */ <!-- if(! window.console){ console={}; console.log = console.debug += function(){}} var map, layers; var chr = 7; var bp; var size= 285; var server = 'tiler.pl?' var ds = 588; var org = "rice"; function init(){ map = new OpenLayers.GenomeBrowser( $('map') , { maxExtent: new OpenLayers.Bounds(-50000,-10000,100000 +0000,10000), units :'bp', tileSize: new OpenLayers.Size(512, 285), //resolutions:[1024,512,256,128,64,32,16,8,4,2,1], resolutions:[128,64,32,16,8], controls: [new OpenLayers.Control.MouseDefaults()] }); layers = [ new OpenLayers.Layer.Genomic( "Ruler" , server ,{'chr':chr,layers:"background,ruler",'version':6,org +anism:org} ,{isBaseLayer:true} ), new OpenLayers.Layer.Genomic( "<span id='gene'>Genes</span +>" , server ,{'chr':chr,layers:"gene,CDS,mRNA",'version':6,organi +sm:org} ,{isBaseLayer:false} ) ] map.addControl(new OpenLayers.Control.LayerSwitcher()) /* gc.setVisibility(false); map.addLayer(gc) */ map.addLayers(layers); /* zoomLevel */ map.setCenter(new OpenLayers.BasePair(494000), 1); bp = new OpenLayers.Control.MousePosition() map.addControl(bp ); map.addControl(new OpenLayers.Control.PanZoomBar()); map.events.register('zoomend',map,updateZoom); map.events.triggerEvent('zoomend'); map.events.register('mousedown',map,mapMouseDown); map.events.register('mouseup',map,mapMouseUp); } function mapMouseDown(e){ map.lastMouseX = e.xy.x; map.lastMouseY = e.xy.y; } function mapMouseUp(e){ var tx = e.xy.x; var ty = e.xy.y; var tot = Math.abs(map.lastMouseX - tx) + Math.abs(map.lastMouseY - ty); if(4 > tot){ // dont need to figure out basepairs from pixels // just use the ones in the window already. query(parseInt(bp.element.innerHTML)); } } function updateZoom(){ $('resolution').innerHTML = map.getResolution() + 'bp/pixe +l'; } function query(x){ // var url = 'http://toxic.berkeley.edu/bpederse/cogex/FeatA +nno.pl?chr=' var url = '/CoGe/FeatAnno.pl?chr=' + chr + '&version=5&layers=gene&organism=' + org + '&loc=' + x + '&' + 'ds=' + 588 jfetch(url,'query'); } // --> </script> </head> <body onload="init()"> <div id="text"> This is a small hack of <a Ahja <pre>svn checkout https://genome-browser.googlecode.com/svn/trunk/ + genome-browser</pre> or <a href="http://code.google.com/p/genome-browser/downloads/list +"> tar ball</a> </div> <div id="map"> </div> <div id='resolution'></div> <div id='query'></div> </body> </html>
      #!/usr/bin/perl -wT use strict; use File::Spec::Functions; use File::Path; use LWP::Simple; use Data::Dumper; $ENV{'PATH'} = ''; use vars qw($IMGURL $BASEDIR); $IMGURL = 'http://'.$ENV{SERVER_NAME}.'My scriptPNG.pl?'; $IMGURL = 'MyscriptPNG.pl?'; # where to start the caching #$BASEDIR = "/_cache_/"; $BASEDIR = "/tmp/genecache/"; while (! -e $BASEDIR){ mkdir($BASEDIR); } print "Content-type: image/png; mode=24bit\n\n"; my $basedir = [split(/[\\\/]/,$BASEDIR)]; my ($dir) = get_dir_array(); my $reldir = catfile(@$dir) . '.png'; my $basepath = catfile(@$basedir); my $fn = catfile($basepath,@$dir) . '.png' ; my $data; #print STDERR $ENV{QUERY_STRING},"\n"; if(!-e $fn){ pop @$dir; # get rid of the file name umask (0); mkpath($basepath . '/' . join("/",@$dir)); LWP::Simple::getstore($IMGURL . $ENV{QUERY_STRING},$fn); # chmod (0777, $fn); # print STDERR $IMGURL.$ENV{QUERY_STRING},"\n"; } # DUMP THE IMAGE { local( *IMG,$/ ); my $mesg = "cant open $fn\nmake sure _cache_ dir is web writeable\n"; open( IMG,"<", $fn) or warn "cant open $mesg\n"; binmode IMG; print <IMG>; close(IMG); } #system 'chmod -R 777 /opt/apache/CoGe/_cache_/*'; ################################################## # Use %ENV to find where in directory structure # we are and make an array of directory names ################################################## sub get_dir_array { my ($qstr) = $ENV{QUERY_STRING} =~ /(.*)/; $qstr =~ s/[\s-]//; my @dir = (); # parse the url; my %query_pairs = map { split('=', $_) } split(/&/,$qstr); # keep order of entries but put the spatial pars last becuase # it just works out best that way. my $xmin = delete $query_pairs{xmin}; my $xmax = delete $query_pairs{xmax}; my $ds = delete $query_pairs{ds}; my $tilew = $query_pairs{width}; my $MAX = int(log(1000*abs($xmax - $xmin)/$tilew)/log(10)); my @keyvals = ('ds',sort keys %query_pairs); $query_pairs{xmin} = $xmin; $query_pairs{xmax} = $xmax; $query_pairs{ds} = $ds; push(@keyvals,"xmin"); push(@keyvals,"xmax"); # &layer=fred becomes layer__fred foreach my $key( @keyvals ){ next unless $key; my $val = $query_pairs{$key}; my @vals; # 123456 becomes /x__123/456/ if $MAX == 3 # 123456 becomes /x__123456/ if $MAX > 5 if($key eq "xmin" || $key eq "xmax"){ if($val !~ /(\D|-)+/){ $val =~ s/-/n/g; $val = scalar reverse($val); while($val =~ /(\d{1,$MAX}n?)/g){ unshift(@vals,scalar reverse($1)); } } } @vals = ($val) unless @vals; my $first = shift @vals; next unless $key && $first; push(@dir,$key . '__' . $first || ""); map { push(@dir,$_) } @vals; } return \@dir; }

        I got a little overwhelmed with other tasks so I can't explore this more right now though I'll try to look later. The JS package you seem to be using is genome-browser. I'd try to look at that code and any examples you can find using it.

        I am not sure but it looks like you're calling the JS incorrectly and that if you fix it, you just need to print the right headers for your image data and clean up the code a bit. Sorry I'm not more help right now. :(