Finish Added Content by record ID
authorJeff Godin <jgodin@tadl.org>
Wed, 25 Apr 2012 08:23:28 +0000 (04:23 -0400)
committerBen Shum <bshum@biblio.org>
Thu, 26 Sep 2013 17:56:21 +0000 (13:56 -0400)
OpenILS::WWW::AddedContent now supports fetching content by record ID.

To start, this lets us request content in a way that uses both ISBN
and UPC as keys, assuming the AC handler and provider support it.

The previous method of requesting AC data continues to be
supported, and should be unaffected.

Business::ISBN is used to clean ISBN values when fetching by record ID

If we find no valid ISBN and no UPC values in the record,
do not attempt to call an AC handler. This will need
to change when we have AC handlers that rely on other
possible keys.

Attempt to serve from cache before fetching keys from the bib
record in the database.

Signed-off-by: Jeff Godin <jgodin@tadl.org>
Signed-off-by: Ben Shum <bshum@biblio.org>
Open-ILS/src/perlmods/lib/OpenILS/WWW/AddedContent.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/AddedContent/Syndetic.pm

index dcd5d1f..a1e14e6 100644 (file)
@@ -20,6 +20,8 @@ use OpenILS::Utils::CStoreEditor;
 use LWP::UserAgent;
 use MIME::Base64;
 
+use Business::ISBN;
+
 my $AC = __PACKAGE__;
 
 
@@ -77,62 +79,102 @@ sub child_init {
 sub handler {
 
     my $r   = shift;
+
+    # If the URL requested matches a file on the filesystem, have Apache serve that file
+    # this allows for local content (most typically images) to be used for some requests
     return Apache2::Const::DECLINED if (-e $r->filename);
 
     my $cgi = CGI->new;
     my @path_parts = split( /\//, $r->unparsed_uri );
-    my $type = $path_parts[-3];
-    my $format = $path_parts[-2];
-    my $id = $path_parts[-1];
+
+    # Intended URL formats
+    # /opac/extras/ac/jacket/medium/ISBN_VALUE      -- classic keyed-off-isbn
+    # /opac/extras/ac/-3/-2/-1
+    # /opac/extras/ac/jacket/medium/r/RECORD_ID     -- provide record id (bre.id)
+    # /opac/extras/ac/-4/-3/-2/-1
+    # /opac/extras/ac/jacket/medium/m/RECORD_ID     -- XXX: future use for metarecord id
+
+    my $keytype_in_url = $path_parts[-2];  # if not in one of m, r, this will be the $format
+
+    my $type;
+    my $format;
+    my $keytype;
+    my $keyvalue;
+
+    if ($keytype_in_url =~ m/^(r|m)$/) {
+        $type = $path_parts[-4];
+        $format = $path_parts[-3];
+        $keyvalue = $path_parts[-1]; # a record/metarecord id
+        $keytype = 'record';
+    } else {
+        $type = $path_parts[-3];
+        $format = $path_parts[-2];
+        $keyvalue = $path_parts[-1]; # an isbn
+        $keytype = 'isbn';
+    }
+
     my $res;
+    my $keyhash;
+    my $cachekey;
+
+    $cachekey = ($keytype eq "isbn") ? $keyvalue : $keytype . '_' . $keyvalue;
 
     child_init() unless $handler;
 
-    return Apache2::Const::NOT_FOUND unless $handler and $type and $format and $id;
+    return Apache2::Const::NOT_FOUND unless $handler and $type and $format and $cachekey;
 
     my $err;
     my $data;
     my $method = "${type}_${format}";
 
     return Apache2::Const::NOT_FOUND unless $handler->can($method);
-    return $res if defined($res = $AC->serve_from_cache($type, $format, $id));
+    return $res if defined($res = $AC->serve_from_cache($type, $format, $cachekey));
     return Apache2::Const::NOT_FOUND unless $AC->lookups_enabled;
 
-    my $key_data = get_rec_keys($id);
-    my @isbns = grep {$_->{tag} eq '020'} @$key_data;
-    my @upcs = grep {$_->{tag} eq '024'} @$key_data;
-
-    my $keys = {
-        isbn => [map {$_->{value}} @isbns],
-        upc => [map {$_->{value}} @upcs]
-    };
-
-    # TODO clean isbn
+    if ($keytype eq "isbn") { # if this request uses isbn for the key
+        # craft a hash with the single isbn, because that's all we will have
+        $keyhash = {};
+        $keyhash->{"isbn"} = [$keyvalue];
+    } else {
+        my $key_data = get_rec_keys($keyvalue);
+        my @isbns = grep {$_->{tag} eq '020'} @$key_data;
+        my @upcs = grep {$_->{tag} eq '024'} @$key_data;
+
+        map {
+            my $isbn_obj = Business::ISBN->new($_->{value});
+            my $isbn_str;
+            $isbn_str = $isbn_obj->as_string([]) if defined($isbn_obj);
+            $_->{value} = $isbn_str;
+            undef $_ if !defined($_->{value});
+        } @isbns;
+
+        $keyhash = {
+            isbn => [map {$_->{value}} @isbns],
+            upc => [map {$_->{value}} @upcs]
+        };
+    }
 
-    # XXX DEBUG
-    use OpenSRF::Utils::JSON;
-    $logger->info("Added Content Keys: " . OpenSRF::Utils::JSON->perl2JSON($keys));
+    return Apache2::Const::NOT_FOUND unless @{$keyhash->{isbn}} || @{$keyhash->{upc}};
 
     try {
-        $data = $handler->$method($keys);
+        $data = $handler->$method($keyhash);
     } catch Error with {
         $err = shift;
         decr_error_countdown();
-        $logger->debug("added content handler failed: $method($id) => $err");
+        $logger->debug("added content handler failed: $method($keytype/$keyvalue) => $err"); # XXX: logs unhelpful hashref
     };
 
     return Apache2::Const::NOT_FOUND if $err;
-    next unless $data;
 
     if(!$data) {
         # if the AC lookup found no corresponding data, cache that information
-        $logger->debug("added content handler returned no results $method($id)") unless $data;
-        $AC->cache_result($type, $format, $id, {nocontent=>1});
+        $logger->debug("added content handler returned no results $method($keytype/$keyvalue)") unless $data;
+        $AC->cache_result($type, $format, $cachekey, {nocontent=>1});
         return Apache2::Const::NOT_FOUND;
     }
     
     $AC->print_content($data);
-    $AC->cache_result($type, $format, $id, $data);
+    $AC->cache_result($type, $format, $cachekey, $data);
 
     reset_error_countdown();
     return Apache2::Const::OK;
index 73d13a4..88f564e 100644 (file)
@@ -30,21 +30,21 @@ sub userid {
 
 # --------------------------------------------------------------------------
 sub jacket_small {
-    my( $self, $key ) = @_;
+    my( $self, $keys ) = @_;
     return $self->send_img(
-        $self->fetch_response('sc.gif', $key, 1));
+        $self->fetch_response('sc.gif', $keys, 1));
 }
 
 sub jacket_medium {
-    my( $self, $key ) = @_;
+    my( $self, $keys ) = @_;
     return $self->send_img(
-        $self->fetch_response('mc.gif', $key, 1));
+        $self->fetch_response('mc.gif', $keys, 1));
 
 }
 sub jacket_large {
-    my( $self, $key ) = @_;
+    my( $self, $keys ) = @_;
     return $self->send_img(
-        $self->fetch_response('lc.gif', $key, 1));
+        $self->fetch_response('lc.gif', $keys, 1));
 }
 
 # --------------------------------------------------------------------------
@@ -281,9 +281,14 @@ sub fetch_content {
 
 # returns the HTTP response object from the URL fetch
 sub fetch_response {
-    my( $self, $page, $key, $notype ) = @_;
+    my( $self, $page, $keys, $notype ) = @_;
     my $uname = $self->userid;
-    my $url = $self->base_url . "?isbn=$key/$page&client=$uname" . (($notype) ? '' : "&type=rw12");
+
+    # Fetch single isbn and single upc
+    my $isbn = $keys->{isbn}[0];
+    my $upc = $keys->{upc}[0];
+
+    my $url = $self->base_url . "?isbn=$isbn/$page&client=$uname" . (($notype) ? '' : "&type=rw12");
     return $AC->get_url($url);
 }