#!/usr/bin/perl # name-finder.cgi - input a first and last name, get back a list of names and the ability to choose a subject term # Eric Lease Morgan # November 19, 2008 - removed the specific content-type header; made more generic # November 8, 2008 - first cut; at WorldCat Hackathon (NYC) # October 27, 2009 - tweaked the SEARCH constant; "Thanks, Ralph!" # December 3, 2009 - moved to zoia # December 8, 2009 - updated with www.worldcat.org host # 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/name-finder/name_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://www.worldcat.org/identities/search/PersonalIdentities?query=FamilyName+%3D+%22##LASTNAME##%22+and+FirstName+%3D+%22##FIRSTNAME##%22&maximumRecords=250&sortKeys=holdingscount'; use constant TRANS => './etc/name-finder.xsl'; use constant TEMPLATE => './etc/template.txt'; use constant TERMFINDER => 'http://zoia.library.nd.edu/sandbox/term-finder/?query='; # initalize my $cgi = CGI->new; my $first_name = $cgi->param( 'first_name' ); my $last_name = $cgi->param( 'last_name' ); # display home page if ( ! $first_name | ! $last_name ) { # display the home page and quit my $html = &slurp( TEMPLATE ); $html =~ s/##CONTENT##//e; $html =~ s/##FIRSTNAME##/Albert/; $html =~ s/##LASTNAME##/Einstein/; &gracefulExit ( $html ); } else { # get the input $first_name =~ s/ /+/g; $last_name =~ s/ /+/g; # create a url my $url = SEARCH; $url =~ s/##FIRSTNAME##/$first_name/e; $url =~ s/##LASTNAME##/$last_name/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 = ''; my $index = 0; # check for responses; failure if ( ! @responses ) { $response = $cgi->p( 'No records found. Bummer!' ) } # success else { # loop through each name my $resonse = $cgi->h2( 'Names' ); my $names = ''; foreach ( @responses ) { # get the name my @fields = split /#/, $_; $index++; $names .= $cgi->li( $fields[ 0 ] . ' ' . $cgi->a({ href => "javascript:expand('d". $index. "')", style => 'color: silver' }, '(Subjects)' )); # get their subjects my $subjects = ''; foreach ( split /\t/, $fields[ 1 ] ) { # remove subheadings, and add the result to the list s/--.*$//; $subjects .= $cgi->li( $cgi->a({ href => TERMFINDER . $_ }, $_ )); } # add the subjects to the person's name $names .= $cgi->div({ id => "d$index", style => 'display: none' }, $cgi->ul( $subjects )); } $response .= $cgi->ul( $names ); } # display the home page and quit my $html = &slurp( TEMPLATE ); $html =~ s/##CONTENT##/$response/e; $html =~ s/##FIRSTNAME##/$cgi->param( 'first_name' )/e; $html =~ s/##LASTNAME##/$cgi->param( 'last_name' )/e; &gracefulExit ( $html ); } sub slurp { # open a file named by the input and return its contents my $f = @_[0]; my $r; open (F, "< $f"); while () { $r .= $_ } 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; }