#!/usr/bin/perl # term-finder.cgi - input a word, browse more words # Eric Lease Morgan # November 7, 2008 - first cut; at WorldCat Hackathon (NYC) # November 19, 2008 - removed the explicit content-type header; made it generic # July 9, 2008 - begun extracting 450 fields -- see references # January 5, 2010 - made the See references not clickable; changed See to Use for # January 24, 2010 - added GNU Public License # P.S. The entire application, complete with support files ought to be # available (at least temporarily) from: # # http://zoia.library.nd.edu/sandbox/term-finder/term_finder-2010-01-24.tar.gz # Copyright (C) Eric Lease Morgan # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2, # as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # require/include use LWP::UserAgent; use strict; use XML::LibXML; use XML::LibXSLT; use CGI; # define use constant SEARCH => 'http://tspilot.oclc.org/lcsh/?query=oclcts.marcTags+%3D+%22150%22+and+oclcts.preferredTerm+%3D+%22##INPUT##%22&version=1.1&operation=searchRetrieve&recordSchema=info%3Asrw%2Fschema%2F1%2Fmarcxml-v1.1&maximumRecords=1000&startRecord=1&resultSetTTL=300&recordPacking=xml&recordXPath=&sortKeys='; use constant TRANS => './etc/related.xsl'; use constant TEMPLATE => './etc/template.txt'; use constant HOME => './etc/home.txt'; # initalize my $cgi = CGI->new; my $query = $cgi->param( 'query' ); # display home page if ( ! $query ) { # display the home page and quit my $html = &slurp( TEMPLATE ); $html =~ s/##CONTENT##//e; $html =~ s/##QUERY##/paper work/; &gracefulExit ( $html ); } else { # get the input $query =~ s/ /+/g; # create a url my $url = SEARCH; $url =~ s/##INPUT##/$query/e; # create a user agent, create a request, send it, and get a response my $ua = LWP::UserAgent->new; my $request = HTTP::Request->new( GET => $url ); my $response = $ua->request( $request ); # get the response my $parser = XML::LibXML->new; my $xslt = XML::LibXSLT->new; my $source = $parser->parse_string( $response->content ) or croak $!; my $style = $parser->parse_file( TRANS ) or croak $!; my $stylesheet = $xslt->parse_stylesheet( $style ) or croak $!; my $results = $stylesheet->transform( $source ) or croak $!; my @responses = split /\n/, $stylesheet->output_string( $results ); # initialize output my $response = ''; # check for responses; failure if ( ! @responses ) { $response = $cgi->p( 'No records found. Bummer!' ) } # success else { # broader $response .= $cgi->h2( 'Broader' ); my $list = ''; foreach ( split /\t/, @responses[ 0 ] ) { $list .= $cgi->li( $cgi->a({ -href => "./?query=$_" }, $_ ))} $response .= $cgi->ul( $list ); # narrower $response .= $cgi->h2( 'Narrower' ); $list = ''; foreach ( split /\t/, @responses[ 1 ] ) { $list .= $cgi->li( $cgi->a({ -href => "./?query=$_" }, $_ ))} $response .= $cgi->ul( $list ); # see $response .= $cgi->h2( 'Use for' ); $list = ''; foreach ( split /\t/, @responses[ 2 ] ) { $list .= $cgi->li( $_ )} $response .= $cgi->ul( $list ); } # display the home page and quit my $html = &slurp( TEMPLATE ); $html =~ s/##CONTENT##/$response/e; $html =~ s/##QUERY##/$cgi->param( 'query' )/e; &gracefulExit ( $html ); } sub slurp { # open a file named by the input and return its contents my $f = @_[0]; open (F, "< $f"); my $r = do { local $/; }; close F; return $r; } sub gracefulExit { # get the html, send a header, send the html, and quit my $html = shift; print $cgi->header(); print $html; exit; }