[open-ils-commits] r19514 - in trunk/Open-ILS: examples/apache src/perlmods/lib/OpenILS/Application src/perlmods/lib/OpenILS/WWW (dbs)

svn at svn.open-ils.org svn at svn.open-ils.org
Tue Feb 22 21:56:56 EST 2011


Author: dbs
Date: 2011-02-22 21:56:54 -0500 (Tue, 22 Feb 2011)
New Revision: 19514

Modified:
   trunk/Open-ILS/examples/apache/eg_vhost.conf
   trunk/Open-ILS/src/perlmods/lib/OpenILS/Application/SuperCat.pm
   trunk/Open-ILS/src/perlmods/lib/OpenILS/WWW/SuperCat.pm
Log:
Working SRU search for various authority records
    
We now have search indexes for:
  * ID
  * name
  * subject
  * title
  * topic
    
O:WWW:SuperCat::sru_search has been refactored somewhat to reduce
code duplication between the authority SRU and the bibliographic SRU.

This SRU interface lives, by default, at http://hostname/opac/extras/sru_auth

Explain output is still a bit wonky in the configInfo section.


Modified: trunk/Open-ILS/examples/apache/eg_vhost.conf
===================================================================
--- trunk/Open-ILS/examples/apache/eg_vhost.conf	2011-02-23 02:21:36 UTC (rev 19513)
+++ trunk/Open-ILS/examples/apache/eg_vhost.conf	2011-02-23 02:56:54 UTC (rev 19514)
@@ -307,6 +307,13 @@
     PerlSendHeader On
     allow from all
 </Location>
+<Location /opac/extras/sru_auth>
+    SetHandler perl-script
+    PerlHandler OpenILS::WWW::SuperCat::sru_auth_search
+    Options +ExecCGI
+    PerlSendHeader On
+    allow from all
+</Location>
 <Location /opac/extras/feed/freshmeat>
     SetHandler perl-script
     PerlHandler OpenILS::WWW::SuperCat::changes_feed

Modified: trunk/Open-ILS/src/perlmods/lib/OpenILS/Application/SuperCat.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/lib/OpenILS/Application/SuperCat.pm	2011-02-23 02:21:36 UTC (rev 19513)
+++ trunk/Open-ILS/src/perlmods/lib/OpenILS/Application/SuperCat.pm	2011-02-23 02:56:54 UTC (rev 19514)
@@ -2353,13 +2353,19 @@
 	my $client = shift;
 	my $ids = shift;
 
+	my $type = 'biblio';
+
+	if ($self->api_name =~ /authority/) {
+		$type = 'authority';
+	}
+
 	$ids = [$ids] unless (ref $ids);
 	$ids = [grep {$_} @$ids];
 
 	return [] unless (@$ids);
 
 	my $_storage = OpenSRF::AppSession->create( 'open-ils.cstore' );
-	return $_storage->request('open-ils.cstore.direct.biblio.record_entry.search.atomic' => { id => [grep {$_} @$ids] })->gather(1);
+	return $_storage->request("open-ils.cstore.direct.$type.record_entry.search.atomic" => { id => [grep {$_} @$ids] })->gather(1);
 }
 __PACKAGE__->register_method(
 	method    => 'retrieve_record_objects',
@@ -2382,6 +2388,26 @@
 		}
 );
 
+__PACKAGE__->register_method(
+	method    => 'retrieve_record_objects',
+	api_name  => 'open-ils.supercat.authority.object.retrieve',
+	api_level => 1,
+	argc      => 1,
+	signature =>
+		{ desc     => <<"		  DESC",
+Returns the Fieldmapper object representation of the requested authority records
+		  DESC
+		  params   =>
+		  	[
+				{ name => 'authIds',
+				  desc => 'OpenILS authority::record_entry ids',
+				  type => 'array' },
+			],
+		  'return' =>
+		  	{ desc => 'The authority records',
+			  type => 'array' }
+		}
+);
 
 sub retrieve_isbn_object {
 	my $self = shift;

Modified: trunk/Open-ILS/src/perlmods/lib/OpenILS/WWW/SuperCat.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/lib/OpenILS/WWW/SuperCat.pm	2011-02-23 02:21:36 UTC (rev 19513)
+++ trunk/Open-ILS/src/perlmods/lib/OpenILS/WWW/SuperCat.pm	2011-02-23 02:56:54 UTC (rev 19514)
@@ -1774,6 +1774,18 @@
 		},
 );
 
+# Our authority search options are currently pretty impoverished;
+# just right-truncated string match on a few categories, or by
+# ID number
+our %nested_auth_qualifier_map = (
+        eg => {
+            id          => ['id', 'Record number'],
+            name        => ['author', 'Personal or corporate author, or meeting name'],
+            title       => ['title', 'Uniform title'],
+            subject     => ['subject', 'Chronological term, topical term, geographic name, or genre/form term'],
+            topic       => ['topic', 'Topical term'],
+        },
+);
 
 my $base_explain = <<XML;
 <explain
@@ -1808,7 +1820,7 @@
 	</schemaInfo>
 
 	<configInfo>
-		<default type="numberOfRecords">50</default>
+		<default type="numberOfRecords">10</default>
 		<default type="contextSet">eg</default>
 		<default type="index">keyword</default>
 		<default type="relation">all</default>
@@ -1923,62 +1935,11 @@
 		$resp->numberOfRecords($recs->{count});
 
 	} elsif ( $resp->type eq 'explain' ) {
-		if (!$ex_doc) {
-			my $host = $cgi->virtual_host || $cgi->server_name;
+		return_sru_explain($cgi, $req, $resp, \$ex_doc,
+			\%OpenILS::WWW::SuperCat::nested_qualifier_map,
+			\%OpenILS::WWW::SuperCat::qualifier_ids
+		);
 
-			my $add_path = 0;
-			if ( $cgi->server_software !~ m|^Apache/2.2| ) {
-				my $rel_name = $cgi->url(-relative=>1);
-				$add_path = 1 if ($cgi->url(-path_info=>1) !~ /$rel_name$/);
-			}
-			my $base = $cgi->url(-base=>1);
-			my $url = $cgi->url(-path_info=>$add_path);
-			$url =~ s/^$base\///o;
-
-			my $doc = $parser->parse_string($base_explain);
-			my $e = $doc->documentElement;
-			$e->findnodes('/z:explain/z:serverInfo/z:host')->shift->appendText( $host );
-			$e->findnodes('/z:explain/z:serverInfo/z:port')->shift->appendText( $cgi->server_port );
-			$e->findnodes('/z:explain/z:serverInfo/z:database')->shift->appendText( $url );
-
-			for my $name ( keys %OpenILS::WWW::SuperCat::nested_qualifier_map ) {
-
-				my $identifier = $OpenILS::WWW::SuperCat::qualifier_ids{ $name };
-
-				next unless $identifier;
-
-				my $set_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'set' );
-				$set_node->setAttribute( identifier => $identifier );
-				$set_node->setAttribute( name => $name );
-
-				$e->findnodes('/z:explain/z:indexInfo')->shift->appendChild( $set_node );
-
-				for my $index ( keys %{ $OpenILS::WWW::SuperCat::nested_qualifier_map{$name} } ) {
-					my $desc = $OpenILS::WWW::SuperCat::nested_qualifier_map{$name}{$index}[1] || $index;
-
-					my $name_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'name' );
-
-					my $map_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'map' );
-					$map_node->appendChild( $name_node );
-
-					my $title_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'title' );
-
-					my $index_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'index' );
-					$index_node->appendChild( $title_node );
-					$index_node->appendChild( $map_node );
-
-					$index_node->setAttribute( id => $name . '.' . $index );
-					$title_node->appendText( $desc );
-					$name_node->setAttribute( set => $name );
-					$name_node->appendText($index );
-
-					$e->findnodes('/z:explain/z:indexInfo')->shift->appendChild( $index_node );
-				}
-			}
-
-			$ex_doc = $e->toString;
-		}
-
 		$resp->record(
 			SRU::Response::Record->new(
 				recordSchema	=> 'info:srw/cql-context-set/2/zeerex-1.1',
@@ -2009,6 +1970,10 @@
         return  "$leftStr $rightStr";
     }
 
+    sub toEvergreenAuth {
+        return toEvergreen(shift);
+    }
+
     package CQL::TermNode;
 
     sub toEvergreen {
@@ -2019,13 +1984,13 @@
 
         my $query;
         if ( $qualifier ) {
-			my ($qset, $qname) = split(/\./, $qualifier);
+            my ($qset, $qname) = split(/\./, $qualifier);
 
-			$log->debug("SRU toEvergreen: $qset, $qname   $OpenILS::WWW::SuperCat::nested_qualifier_map{$qset}{$qname}[0]\n");
+            $log->debug("SRU toEvergreen: $qset, $qname   $OpenILS::WWW::SuperCat::nested_qualifier_map{$qset}{$qname}[0]\n");
 
             if ( exists($OpenILS::WWW::SuperCat::nested_qualifier_map{$qset}{$qname}) ) {
                 $qualifier = $OpenILS::WWW::SuperCat::nested_qualifier_map{$qset}{$qname}[0] || 'kw';
-			}
+            }
 
             my @modifiers = $relation->getModifiers();
 
@@ -2054,8 +2019,169 @@
 
         return "$qualifier:$term";
     }
+
+    sub toEvergreenAuth {
+        my $self      = shift;
+        my $qualifier = $self->getQualifier();
+        my $term      = $self->getTerm();
+        my $relation  = $self->getRelation();
+
+        my $query;
+        if ( $qualifier ) {
+            my ($qset, $qname) = split(/\./, $qualifier);
+
+            $log->debug("SRU toEvergreenAuth: $qset, $qname   $OpenILS::WWW::SuperCat::nested_auth_qualifier_map{$qset}{$qname}[0]\n");
+
+            if ( exists($OpenILS::WWW::SuperCat::nested_auth_qualifier_map{$qset}{$qname}) ) {
+                $qualifier = $OpenILS::WWW::SuperCat::nested_auth_qualifier_map{$qset}{$qname}[0] || 'author';
+            }
+        }
+        return { qualifier => $qualifier, term => $term };
+    }
 }
 
+my $auth_ex_doc;
+sub sru_auth_search {
+    my $cgi = new CGI;
+
+    my $req = SRU::Request->newFromCGI( $cgi );
+    my $resp = SRU::Response->newFromRequest( $req );
+
+    if ( $resp->type eq 'searchRetrieve' ) {
+        return_auth_response($cgi, $req, $resp);
+    } elsif ( $resp->type eq 'explain' ) {
+        return_sru_explain($cgi, $req, $resp, \$auth_ex_doc,
+            \%OpenILS::WWW::SuperCat::nested_auth_qualifier_map,
+            \%OpenILS::WWW::SuperCat::qualifier_ids
+        );
+    }
+
+    print $cgi->header( -type => 'application/xml' );
+    print $U->entityize($resp->asXML) . "\n";
+    return Apache2::Const::OK;
+}
+
+sub explain_header {
+    my $cgi = shift;
+
+    my $host = $cgi->virtual_host || $cgi->server_name;
+
+    my $add_path = 0;
+    if ( $cgi->server_software !~ m|^Apache/2.2| ) {
+        my $rel_name = $cgi->url(-relative=>1);
+        $add_path = 1 if ($cgi->url(-path_info=>1) !~ /$rel_name$/);
+    }
+    my $base = $cgi->url(-base=>1);
+    my $url = $cgi->url(-path_info=>$add_path);
+    $url =~ s/^$base\///o;
+
+    my $doc = $parser->parse_string($base_explain);
+    my $e = $doc->documentElement;
+    $e->findnodes('/z:explain/z:serverInfo/z:host')->shift->appendText( $host );
+    $e->findnodes('/z:explain/z:serverInfo/z:port')->shift->appendText( $cgi->server_port );
+    $e->findnodes('/z:explain/z:serverInfo/z:database')->shift->appendText( $url );
+
+    return ($doc, $e);
+}
+
+sub return_sru_explain {
+    my ($cgi, $req, $resp, $explain, $qualifier_map, $qualifier_ids) = @_;
+
+    if (!$$explain) {
+        my ($doc, $e) = explain_header($cgi);
+        for my $name ( keys %$qualifier_map ) {
+
+            my $identifier = $qualifier_ids->{ $name };
+
+            next unless $identifier;
+
+            my $set_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'set' );
+            $set_node->setAttribute( identifier => $identifier );
+            $set_node->setAttribute( name => $name );
+
+            $e->findnodes('/z:explain/z:indexInfo')->shift->appendChild( $set_node );
+
+            for my $index ( keys %{ $qualifier_map->{$name} } ) {
+                my $desc = $qualifier_map->{$name}{$index}[1] || $index;
+
+                my $name_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'name' );
+
+                my $map_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'map' );
+                $map_node->appendChild( $name_node );
+
+                my $title_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'title' );
+
+                my $index_node = $doc->createElementNS( 'http://explain.z3950.org/dtd/2.0/', 'index' );
+                $index_node->appendChild( $title_node );
+                $index_node->appendChild( $map_node );
+
+                $index_node->setAttribute( id => $name . '.' . $index );
+                $title_node->appendText( $desc );
+                $name_node->setAttribute( set => $name );
+                $name_node->appendText($index );
+
+                $e->findnodes('/z:explain/z:indexInfo')->shift->appendChild( $index_node );
+            }
+        }
+
+        $$explain = $e->toString;
+    }
+
+    $resp->record(
+        SRU::Response::Record->new(
+            recordSchema    => 'info:srw/cql-context-set/2/zeerex-1.1',
+            recordData      => $$explain
+        )
+    );
+
+}
+
+sub return_auth_response {
+    my ($cgi, $req, $resp) = @_;
+
+    my $cql_query = decode_utf8($req->query);
+    my $search = $req->cql->toEvergreenAuth;
+
+    my $qualifier = decode_utf8($search->{qualifier});
+    my $term = decode_utf8($search->{term});
+
+    $log->info("SRU NAF search string [$cql_query] converted to "
+        . "[$qualifier:$term]\n");
+
+    my $page_size = $req->maximumRecords;
+    $page_size ||= 10;
+
+    # startwith deals with pages, so convert startRecord to a page number
+    my $page = ($req->startRecord / $page_size) || 0;
+
+    my $recs;
+    if ($qualifier eq "id") {
+        $recs = [ int($term) ];
+    } else {
+        $recs = $supercat->request(
+            "open-ils.supercat.authority.$qualifier.startwith", $term, $page_size, $page
+        )->gather(1);
+    }
+
+    my $record_position = $req->startRecord;
+    my $cstore = OpenSRF::AppSession->create('open-ils.cstore');
+    foreach my $record (@$recs) {
+        my $marcxml = $cstore->request(
+            'open-ils.cstore.direct.authority.record_entry.retrieve', $record
+        )->gather(1)->marc;
+
+        $resp->addRecord(
+            SRU::Response::Record->new(
+                recordSchema    => 'info:srw/schema/1/marcxml-v1.1',
+                recordData => $marcxml,
+                recordPosition => ++$record_position
+            )
+        );
+    }
+
+    $resp->numberOfRecords(scalar(@$recs));
+}
+
 =head2 get_ou($org_unit)
 
 Returns an aou object for a given actor.org_unit shortname or ID.
@@ -2085,4 +2211,4 @@
 
 1;
 
-# vim: noet:ts=4:sw=4
+# vim: et:ts=4:sw=4



More information about the open-ils-commits mailing list