#!/usr/bin/perl -I/opt/local/lib/perl # # $Id: cdsbib.pl,v 1.2 1997/03/19 20:10:31 alberto Exp alberto $ # # Emulates the CGI script handling WAIS searches of the CDS bibliographies # by translating them into queries to hte ADS WWW bibliographic # services. To be run as a CGI/1.x script. # # $Log: cdsbib.pl,v $ # Revision 1.2 1997/03/19 20:10:31 alberto # Added support for comment searches; cleaned up code especially # in the mapping of CDS and ADS parameters; implemented bibcode # query. # # Revision 1.1 1997/02/16 19:43:43 alberto # Initial revision # # include PERL libraries $CGILIB = "/proj/ads0/soft/www/cgi/lib" if(!defined($CGILIB = $ENV{'CGI_LIB'})); $CGIBIN = "/proj/ads0/soft/www/cgi/lib" if(!defined($CGIBIN = $ENV{'CGI_BIN'})); $CGILOG = "/proj/ads0/logs/cgi" if(!defined($CGILOG = $ENV{'CGI_LOG'})); unshift(@INC,$CGILIB); require 'cgi-lib.pl'; require 'adswww.pl'; # the following signals are caught and cause the script to exit $SIG{'TERM'} = "IntHandler"; $SIG{'ALRM'} = "IntHandler"; sub IntHandler { exit(0); } $| = 1; # unbuffer output alarm(300); # time out after 5 minutes $script = 'http://' . $ENV{'SERVER_NAME'} . $ENV{'SCRIPT_NAME'}; # read input from HTML form &ReadParse(*input); # setup global variables used by this program &SetupVars(); # set debugging flag if ($input{'debug'}) { undef($input{'debug'}); ($prog = $0) =~ s:^.*/::; $ads::debug = 1; print "Content-type: text/plain\n\n"; eval 'sub pdebug { print "$prog: ", @_; }'; } else { eval 'sub pdebug { 1 }'; } &pdebug("input query: $input\n"); # figure out what kind of query we're running if ($input{'screen'} eq 'help') { print "Content-Type: text/html\n\n", &HelpPage(); exit(0); } elsif ($input{'screen'} eq 'wordquery') { print "Content-Type: text/html\n\n", &WordQueryForm(); exit(0); } elsif ($input{'screen'} eq 'bibquery') { print "Content-Type: text/html\n\n", &BibQueryForm(); exit(0); } elsif ($input{'screen'} eq 'resultlist') { $form = 1; # output is free-text query results %adsquery = &CdsQuery2AdsQuery(%input); &pdebug("retrieving query results through adswww client...\n"); ($result,$status) = &ads::abstract_query(%adsquery); } elsif ($input{'screen'} eq 'resultref') { $form = 0; # output is reference %adsbib = &CdsBib2AdsBib(%input); &pdebug("retrieving references through adswww client...\n"); ($result,$status) = &ads::bib_query(%adsbib); } elsif ($input{'screen'}) { print "Content-Type: text/html\n\n", &NotImplemented($input{'screen'}); exit(0); } else { print "Content-Type: text/html\n\n", &WordQueryForm(); exit(0); } if ($status) { &Error("query returned the following error message:\n$result\n", "(status code = $status)\n"); exit(0); } # parse query results into associative arrays @references = &ads::parse_bib($result,*score,*title,*author,*pubdate, *journal,*affiliation,*keywords,*origin, *copyright,*abstract,*table,*url,*comment, *object,*items); # see if we have to do any sorting if ($input{'opt_sort'} =~ /desc/) { # sort by desc. year, vol @references = sort { substr($b,0,4) <=> substr($a,0,4) || substr($b,9,4) cmp substr($a,9,4) } @references; } elsif ($input{'opt_sort'} =~ /asc/) { # sort by asc. year, vol @references = sort { substr($a,0,4) <=> substr($b,0,4) || substr($a,9,4) cmp substr($b,9,4) } @references; } elsif ($input{'opt_sort'} =~ /journal/) { # sort by journal, vol @references = sort { substr($a,4,9) cmp substr($b,4,9) } @references; } &pdebug("generating HTML output\n\n"); print "Content-Type: text/html\n\n", &CdsHeader($form,$ads::ref_selected,$ads::ref_returned,$input{'opt_sort'}, %adsquery), &CdsFmt2HTML($form,@references), &CdsFooter($form); exit(0); ############################################################################### sub CdsBib2AdsBib { local(%query) = @_; local(%cds); local(%ads) = ('db_key', 'AST', 'data_type', 'PORTABLE', ); foreach (split("\0",$query{'mbib'})) { &pdebug("bibcode request is \"$_\"\n"); $ads{$cds2ads{'mbib'}} .= $_ . ';'; } chop($ads{$cds2ads{'mbib'}}); return(%ads); } sub CdsQuery2AdsQuery { local(%query) = @_; local(%ads,%cds,$query); local($bibcode,$y,$j,$v,$p); # handle bibcode query if ($input{'opt_field'} eq 'simref') { $ads{'db_key'} = 'AST'; $ads{'version'} = 1; $_ = $query{'query'}; $y = "$1" if (s/^\W*(\d+)//); $y = "19$y" if ($y =~ /^\d\d$/); $j = "$1" if (s/^\W*([a-zA-Z&]+)//); $v = "$1" if (s/^\D*(\d+)//); $p = "$1" if (s/^\D*([LlPp]?\d+)//); $bibcode = $y if ($y); if ($j) { $j = sprintf("%-5.5s", $j); $bibcode .= $j; } if ($v){ $v = sprintf("%4d",$v); $v = substr($v,0,4); $bibcode .= $v; } if ($p) { $p =~ s/([LPlp])//; $p = sprintf("%5d",$p); $p = substr($p,0,5); substr($p,0,1) = "$1" if ("$1"); $bibcode .= $p; } ($ads{'bibcode'} = $bibcode) =~ s/ /./g; &pdebug("bibcode query is: $ads{'bibcode'}\n") } else { # format WAIS query if ($query{'field'} ne 'all' && $query{'fd'}) { foreach (split("\0",$query{'fd'})) { $query .= "$_=($query{'query'}) "; } chop($query); } else { $query = $query{'query'}; } # translate into an ADS query &pdebug("CDS query is: $query\n"); %ads = &ads::wais2ads($query, %cds2ads); # select filter options based on input query if ($query{'database'} eq 'simref') { # filter on data group $ads{'simb_obj'} = 'YES'; $ads{'data_and'} = 'NO'; &pdebug("data selection is simb_obj\n"); } else { # filter on bibcode $ads{'jou_pick'} = 'YES'; foreach (split("\0",$query{'db'})) { &pdebug("bibstem selection is \"$cds2ads{$_}\"\n"); $ads{'ref_stems'} .= $cds2bib{$_} . ' '; } } chop($ads{'ref_stems'}); } $ads{'nr_to_return'} = $query{'opt_max'}; $ads{'data_type'} = 'PORTABLE'; return (%ads); } sub Error { print <<"EOF"; Content-Type: text/html Query Error

Error Message

EOF print @_, "\n"; return; } sub Escape { local($str) = shift(@_); $str =~ s/\&/&/g; $str =~ s/\/>/g; return($str); } sub Encode { local($str) = shift(@_); local($pat) = $_[0] || '[\x00-\x2A/;<=>?\x7F-\xFF]'; $str =~ s/($pat)/sprintf("%%%02lx",unpack('C',$1))/ge; return($str); } sub CdsFmt2HTML { local($short) = shift(@_); local($out,$ua,%item,@items); while ($_ = shift(@_)) { if ($short) { $out .= "
". "\n". &Escape($_) . "\n
$title{$_}\n". "
(score: $score{$_})\n"; } else { ($ua = $author{$_}) =~ tr/a-z/A-Z/; $abstract{$_} =~ s/^\s*not\s+available\s*$//i; $out .= "
". &Escape($_) ." - ". &Escape($journal{$_}) ."

\n". &Escape($title{$_}) ."\n

". &Escape($ua) ."\n"; $out .= "

". &Escape($abstract{$_}) ."\n" if ($abstract{$_}); $out .= "

Keyword(s): ". &Escape($keywords{$_}) ."\n" if ($keywords{$_}); $out .= "

Simbad comments: ". &Escape($comment{$_}) ."\n" if ($comment{$_}); $out .= "

Link(s): "; %item = &ads::parse_items($items{$_}); # put SIMBAD links first to keep our friends happy ;-) @items = ('SIMBAD') if ($item{'SIMBAD'}); push(@items,sort(grep(! /^SIMBAD$/,keys(%item)))); # get rid of abstract links, just let the ads bibcode # query pull up the proper one @items = grep ($item{$_} !~ /abstract/i,@items); foreach $i (@items) { $out .= "". "$item{$i} · "; } $out .= "ADS reference\n"; } } return($out); } sub CdsHeader { local($short,$selected,$retrieved,$sortby,%query) = @_; local($query,$logic); local(%short) = &ads::abstract_fields_aux(); foreach (keys(%ads2cds)) { $query .= "$ads2cds{$_}=($query{$_}) " if ($query{$_}); } foreach (keys(%short)) { $logic .= "$ads2cds{$_}; " if ($query{$short{$_}."_req"}); } $query .= "
\nRequired fields: $logic\n" if ($logic); if ($short) { return <<"EOF"; CDS bibliographic service


CDS logo


CDS bibliographic service

CDS | Simbad | VizieR | Catalogues | Nomenclature | Biblio | StarPages | AstroWeb
WORDS QUERY FORM BIBCODE QUERY FORM HELP

Your query has been interpreted as:
$query

$retrieved references returned ($selected selected), sorted by $sortby.

Click on a reference to retrieve the related data or select some references and press the Fetch references button.
EOF } else { return <<"EOF"; CDS bibliographic service

CDS logo


CDS bibliographic service

CDS | Simbad | VizieR | Catalogues | Nomenclature | Biblio | StarPages | AstroWeb
WORDS QUERY FORM BIBCODE QUERY FORM HELP
EOF } } sub CdsFooter { local($short) = shift(@_); if ($short) { return <<"EOF";

Centre de Données astronomiques de Strasbourg Question\@simbad
EOF } else { return <<"EOF";
Centre de Données astronomiques de Strasbourg Question\@simbad
EOF } } sub WordQueryForm { return <<"EOF"; CDS bibliographic service

CDS logo


CDS bibliographic service

CDS | Simbad | VizieR | Catalogues | Nomenclature | Biblio | StarPages | AstroWeb
Following an agreement with the Editors of Astronomy & Astrophysics and PASP, the CDS provides access to abstracts from the Astronomy and Astrophysics main Journal, Supplement Series and Publications of the Astronomical Society of the Pacific. In addition, the CDS offers access to the bibliographic references of the Simbad database.
WORDS QUERY FORM BIBCODE QUERY FORM HELP
Your words query:
Specify the databases:
search the Simbad bibliographic references
search journal databases (check them):
Astronomy and Astrophysics
Astronomy and Astrophysics Supplements
Publications of the Astronomical Society of the Pacific

Specify the options query:
in all fields (title, authors, abstract, keywords, comments...)
in specific fields (check them):
       Abstract (ab)      Author (au)        Simbad comments (co)
       Keywords (ke)      Title (ti)        
Result options:
    Max hits:   Sort:       or 


Centre de Données astronomiques de Strasbourg Question\@simbad
EOF } sub BibQueryForm { return <<"EOF"; CDS bibliographic service

CDS logo


CDS bibliographic service

CDS | Simbad | VizieR | Catalogues | Nomenclature | Biblio | StarPages | AstroWeb
Following an agreement with the Editors of Astronomy & Astrophysics and PASP, the CDS provides access to abstracts from the Astronomy and Astrophysics main Journal, Supplement Series and Publications of the Astronomical Society of the Pacific. In addition, the CDS offers access to the bibliographic references of the Simbad database.
WORDS QUERY FORM BIBCODE QUERY FORM HELP
Bibcode (year journal volume page) query:
Result options:
    Max hits:   Sort:                  


Centre de Données astronomiques de Strasbourg Question\@simbad
EOF } sub HelpPage { return <<"EOF"; CDS bibliographic services via ADS

CDS bib via ADS client

This script implements some of the existing CDS bibliographic services via the ADSWWW client library. It is intended as a simple demo of the capabilities of this library.
EOF } sub NotImplemented { return <<"EOF"; Not Implemented

Query "$_[0]" not implemented yet

EOF } sub SetupVars { local($k,$v); # mapping between CDS params and ADS ones %cds2ads = ('ab', 'text', 'au', 'author', 'ke', 'keywords', 'ti', 'title', 'co', 'comment', 'mbib', 'bibcode', ); # create opposite associative array while (($k,$v) = each(%cds2ads)) { $ads2cds{$v} = $k; } %cds2bib = ('abib.A+A', 'A&A..', 'abib.A+AS', 'A&AS.', 'abib.PASP', 'PASP.', ); }