From: Mike Rylander Date: Wed, 10 Sep 2014 16:22:44 +0000 (-0400) Subject: LP#1367926: Add support for (nearly) direct access to the full unapi backend X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=4fbeac6d22deeeeb9d5998f072df8662f7ed2c68;p=evergreen%2Fequinox.git LP#1367926: Add support for (nearly) direct access to the full unapi backend Some parts of Evergreen (notably the TPAC), and various 3rd party services, would benefit from full and direct access to the power of the backend (read: faster, more complete, more API-stable) unAPI (um) API. Related, many moons ago, I built a perl module (OpenILS::Utils::TagURI) to make parsing of tag URIs systematic for use in OpenSearch and unAPI contexts. This branch uses O::U::TagURI and a simple shim inside open-ils.supercat to expose the power of that backend unAPI functionality. By way of example, here is the tag URI to look up a copy, by barcode, and request the call number, bib and bib attributes at the same time. The barcode in this example is "ACQ140": tag::U2@acp/ACQ140{acn,bre,mra}/-/0/barcode The full example URL would be something like: http://example.com/opac/extras/unapi?id=tag::U2@acp/ACQ140{acn,bre,mra}/-/0/barcode&format=xml Here is retrieving a bib in MODS 3.2 with holdings embedded: tag::U2@bre/267{holdings_xml,acn,acp,mra} And the URL: http://example.com/opac/extras/unapi?tag::U2@bre/267{holdings_xml,acn,acp,mra}&format=mods32 To test: Try the example URLs, varying record ID, classes, and includes. Some classes and includes available are: * bre (bibs) * acn (volumes) * acp (copies) * biblio_record_entry_feed (multiple bibs) * holdings_xml * cbs (bib source) * circ (circulation checkout and due dates) Signed-off-by: Mike Rylander Signed-off-by: Galen Charlton Signed-off-by: Kathy Lussier --- diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/SuperCat.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/SuperCat.pm index 1d94ef3372..26f23725ea 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/SuperCat.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/SuperCat.pm @@ -37,6 +37,7 @@ use OpenSRF::Utils::Logger qw($logger); use OpenILS::Utils::Fieldmapper; use OpenILS::Utils::CStoreEditor q/:funcs/; +use OpenILS::Utils::TagURI; our ( @@ -731,6 +732,60 @@ Returns the XML representation of the requested bibliographic record's holdings } ); +sub u2 { + my $self = shift; + my $client = shift; + + my $u2 = shift; + my $format = shift || 'xml'; + + $u2 = OpenILS::Utils::TagURI->new($u2); + return '' unless $u2; + + # Use pathinfo on acp as a lookup type specifier. + if ($u2->classname eq 'acp' and $u2->pathinfo =~ /\bbarcode\b/) { + my( $copy, $evt ) = $U->fetch_copy_by_barcode( $u2->id ); + $u2->id( $copy->id ); + } + + return OpenSRF::AppSession->create('open-ils.cstore')->request( + "open-ils.cstore.json_query.atomic", + { from => + [ 'unapi.' . $u2->classname, + $u2->id, + $format, + $u2->classname, + '{' . ( $u2->includes ? join( ',', keys %{ $u2->includes } ) : '' ) . '}', + $u2->location || undef, + $u2->depth || undef + ] + } + )->gather(1)->[0]{'unapi.'. $u2->classname}; +} +__PACKAGE__->register_method( + method => 'u2', + api_name => 'open-ils.supercat.u2', + api_level => 1, + argc => 2, + signature => + { desc => <<" DESC", +Returns the XML representation of the requested object + DESC + params => + [ + { name => 'u2', + desc => 'The U2 Tag URI (OpenILS::Utils::TagURI)', + type => 'object' }, + { name => 'format', + desc => 'For bre and bre feeds, the xml transform format', + type => 'string' } + ], + 'return' => + { desc => 'XML (or transformed) object data', + type => 'string' } + } +); + sub general_browse { my $self = shift; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Utils/TagURI.pm b/Open-ILS/src/perlmods/lib/OpenILS/Utils/TagURI.pm index a6679f4fdb..7e2adf8936 100755 --- a/Open-ILS/src/perlmods/lib/OpenILS/Utils/TagURI.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Utils/TagURI.pm @@ -90,8 +90,8 @@ sub parse { $self->classname($classname); $self->id($id); - $self->paging(($paging ? [ map { s/^\s*//; s/\s*$//; $_ } split(',', $paging) ] : [])); - $self->includes(($inc ? { map { /:/ ? split(':') : ($_,undef) } map { s/^\s*//; s/\s*$//; $_ } split(',', $inc) } : {})); + $self->paging(($paging ? [ map { s/^\s*//; s/\s*$//; $_ } split(',', $paging) ] : undef)); + $self->includes(($inc ? { map { /:/ ? split(':') : ($_,undef) } map { s/^\s*//; s/\s*$//; $_ } split(',', $inc) } : undef)); $self->location($loc); $self->depth($depth); $self->pathinfo($mods); @@ -122,7 +122,7 @@ sub toURI { $tag .= 'U2@' if ($self->version == 2); $tag .= $self->classname . '/' . $self->id; $tag .= '['. join(',', @{ $self->paging }) . ']' if defined($self->paging); - $tag .= '{'. join(',', map { $_ . ':' . $self->includes->{$_} } keys %{ $self->includes }) . '}' if defined($self->includes); + $tag .= '{'. join(',', map { $self->includes->{$_} ? ($_ . ':' . $self->includes->{$_}) : ($_) } keys %{ $self->includes }) . '}' if defined($self->includes); $tag .= '/' . $self->location if defined($self->location); $tag .= '/' . $self->depth if defined($self->depth); $tag .= '/' . $self->pathinfo if defined($self->pathinfo); diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/SuperCat.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/SuperCat.pm index ce5effe2fe..83274aca48 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/SuperCat.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/SuperCat.pm @@ -26,6 +26,7 @@ use OpenILS::Utils::Fieldmapper; use OpenILS::WWW::SuperCat::Feed; use OpenSRF::Utils::Logger qw/$logger/; use OpenILS::Application::AppUtils; +use OpenILS::Utils::TagURI; use MARC::Record; use MARC::File::XML ( BinaryEncoding => 'UTF-8' ); @@ -444,6 +445,26 @@ sub oisbn { return Apache2::Const::OK; } +sub unapi2 { + my $apache = shift; + my $u2 = shift; + my $format = shift; + + my $ctype = 'application/xml'; + # Only bre and biblio_record_entry_feed have tranforms, but we'll ignore that for now + if ($u2->classname =~ /^(?:bre|biblio_record_entry_feed)$/ and $format ne 'xml') { + # XXX set $ctype to something else + } + + print "Content-type: $ctype; charset=utf-8\n\n"; + print "\n"; + print $supercat + ->request("open-ils.supercat.u2", $u2->toURI, $format) + ->gather(1); + + return Apache2::Const::OK; +} + sub unapi { my $apache = shift; @@ -465,6 +486,14 @@ sub unapi { my $uri = $cgi->param('id') || ''; + + my $format = $cgi->param('format') || ''; + (my $base_format = $format) =~ s/(-full|-uris)$//o; + my $u2uri = OpenILS::Utils::TagURI->new($uri); + if ($format and $u2uri->version > 1) { + return unapi2($apache, $u2uri, $format); + } + my $host = $cgi->virtual_host || $cgi->server_name; my $skin = $cgi->param('skin') || 'default'; @@ -473,7 +502,6 @@ sub unapi { # Enable localized results of copy status, etc $supercat->session_locale($locale); - my $format = $cgi->param('format') || ''; my $flesh_feed = parse_feed_type($format); (my $base_format = $format) =~ s/(-full|-uris)$//o; my ($id,$type,$command,$lib,$depth,$paging) = ('','record','');