Revert "Update ContentCafe Added Content Module"
authorChris Sharp <csharp@georgialibraries.org>
Sun, 18 Jan 2015 20:20:09 +0000 (15:20 -0500)
committerChris Sharp <csharp@georgialibraries.org>
Sun, 17 Sep 2017 20:10:28 +0000 (16:10 -0400)
Experimenting with reverting this commit, which appears to
break Syndetics (and we don't use ContentCafe).

This reverts commit 164c7e7bc4e542af9ada4ea2716cbce784820e6d.

Open-ILS/examples/opensrf.xml.example
Open-ILS/src/perlmods/lib/OpenILS/WWW/AddedContent.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/AddedContent/ContentCafe.pm

index 48a3714..c81b6ee 100644 (file)
@@ -319,12 +319,11 @@ vim:et:ts=4:sw=4:
                 <password>MY_PASSWORD</password>
 
                 <!--
-                Which order to put identifiers in.
-                Default is "isbn,upc", ignoring currently unsupported issn.
-                Should be all lowercase.
-                Remove an identifier from the list to skip it.
+                If no cover/jacket image exists for a given ISBN, then a value of T here will
+                return an 80x120 pixel image containing the text "No Image Available".  A
+                value of 1 will return a 1x1 pixel image.
                 -->
-                <identifier_order>isbn,upc</identifier_order>
+                <return_behavior_on_no_jacket_image>T</return_behavior_on_no_jacket_image>
             </ContentCafe>
 
             <!--
index 254d790..be45a83 100644 (file)
@@ -296,20 +296,6 @@ sub get_url {
     return $res;
 }
 
-# returns an HTPP::Response object
-sub post_url {
-    my( $self, $url, $content ) = @_;
-
-    $logger->info("added content getting [timeout=$net_timeout, errors_remaining=$error_countdown] URL = $url");
-    my $agent = LWP::UserAgent->new(timeout => $net_timeout);
-
-    my $res = $agent->post($url, Content => $content);
-    $logger->info("added content request returned with code " . $res->code);
-    die "added content request failed: " . $res->status_line ."\n" unless $res->is_success;
-
-    return $res;
-}
-
 sub lookups_enabled {
     if( $cache->get_cache('ac.no_lookup') ) {
         $logger->info("added content lookup disabled");
index 3de07ff..008a0d6 100644 (file)
@@ -7,7 +7,6 @@ use OpenSRF::EX qw/:try/;
 use OpenILS::WWW::AddedContent;
 use XML::LibXML;
 use MIME::Base64;
-use DateTime;
 
 # Hack country_data to allow B&T fake ISBNs LP#1559281
 $Business::ISBN::country_data{630} = ['B&T' => ['0000000' => '9999999']];
@@ -15,7 +14,8 @@ $Business::ISBN::country_data{631} = ['B&T' => ['0000000' => '9999999']];
 
 my $AC = 'OpenILS::WWW::AddedContent';
 
-my $post_url = 'http://contentcafe2.btol.com/ContentCafe/ContentCafe.asmx/XmlPost';
+my $base_url = 'http://contentcafe2.btol.com/ContentCafe/ContentCafe.asmx/Single';
+my $cover_base_url = 'http://contentcafe2.btol.com/ContentCafe/Jacket.aspx';
 
 sub new {
     my( $class, $args ) = @_;
@@ -33,93 +33,39 @@ sub password {
     return $self->{ContentCafe}->{password};
 }
 
-sub identifier_order {
+sub return_behavior_on_no_jacket_image {
     my $self = shift;
-    if ($self->{ContentCafe}->{identifier_order}) {
-        my $order = [ split(',',$self->{ContentCafe}->{identifier_order}) ];
-        return $order;
-    }
-    return ['isbn','upc'];
-}
-
-sub expects_keyhash {
-    # we expect a keyhash as opposed to a simple scalar containing an ISBN
-    return 1;
-}
-
-# --------------------------------------------------------------------------
-
-# This function fetches everything and returns:
-#     0 if we had no usable keys
-#     0 if we had a lookup failure
-#     A hash of format_type => result if you called that directly
-sub fetch_all {
-    my( $self, $keyhash ) = @_;
-    my $doc = $self->fetch_xmldoc([
-        'TocDetail', # toc_*
-        'BiographyDetail', #anotes_*
-        'ExcerptDetail', #excerpt_*
-        'ReviewDetail', #reviews_*
-        'AnnotationDetail', #summary_*
-        {name => 'JacketDetail', attributes => [['Type','S'],['Encoding','HEX']]}, # jacket_small
-        {name => 'JacketDetail', attributes => [['Type','M'],['Encoding','HEX']]}, # jacket_medium
-        {name => 'JacketDetail', attributes => [['Type','L'],['Encoding','HEX']]}, # jacket_large
-    ], $keyhash);
-    return 0 unless defined $doc;
-    my $resulthash = {
-        toc_html        => $self->parse_toc_html($doc),
-        toc_json        => $self->send_json($doc, 'TocItems'),
-        toc_xml         => $self->send_xml($doc, 'TocItems'),
-        anotes_html     => $self->parse_anotes_html($doc),
-        anotes_json     => $self->send_json($doc, 'BiographyItems'),
-        anotes_xml      => $self->send_xml($doc, 'BiographyItems'),
-        excerpt_html    => $self->parse_excerpt_html($doc),
-        excerpt_json    => $self->send_json($doc, 'ExcerptItems'),
-        excerpt_xml     => $self->send_xml($doc, 'ExcerptItems'),
-        reviews_html    => $self->parse_reviews_html($doc),
-        reviews_json    => $self->send_json($doc, 'ReviewItems'),
-        reviews_xml     => $self->send_xml($doc, 'ReviewItems'),
-        summary_html    => $self->parse_summary_html($doc),
-        summary_json    => $self->send_json($doc, 'AnnotationItems'),
-        summary_xml     => $self->send_xml($doc, 'AnnotationItems'),
-        jacket_small    => $self->parse_jacket($doc, 'S'),
-        jacket_medium   => $self->parse_jacket($doc, 'M'),
-        jacket_large    => $self->parse_jacket($doc, 'L')
-    };
-    return $resulthash;
+    return $self->{ContentCafe}->{return_behavior_on_no_jacket_image};
 }
 
 # --------------------------------------------------------------------------
 sub jacket_small {
-    my( $self, $keyhash ) = @_;
-    return $self->send_jacket( $keyhash, 'S' );
+    my( $self, $key ) = @_;
+    return $self->send_img(
+        $self->fetch_cover_response('S', $key));
 }
 
 sub jacket_medium {
-    my( $self, $keyhash ) = @_;
-    return $self->send_jacket( $keyhash, 'M' );
-}
+    my( $self, $key ) = @_;
+    return $self->send_img(
+        $self->fetch_cover_response('M', $key));
 
+}
 sub jacket_large {
-    my( $self, $keyhash ) = @_;
-    return $self->send_jacket( $keyhash, 'L' );
+    my( $self, $key ) = @_;
+    return $self->send_img(
+        $self->fetch_cover_response('L', $key));
 }
 
 # --------------------------------------------------------------------------
 
 sub toc_html {
-    my( $self, $keyhash ) = @_;
-    my $doc = $self->fetch_xmldoc('TocDetail', $keyhash);
-    return 0 unless defined $doc;
-    return $self->parse_toc_html($doc);
-}
-
-sub parse_toc_html {
-    my( $self, $doc ) = @_;
+    my( $self, $key ) = @_;
+    my $xml = $self->fetch_content('TocDetail', $key);
+    my $doc = XML::LibXML->new->parse_string($xml);
+    $doc->documentElement->setNamespace('http://ContentCafe2.btol.com', 'cc');
     my $html = '';
-    my @nodes = $doc->findnodes('//cc:TocItems[*]');
-    return 0 if (scalar(@nodes) < 1);
-    @nodes = $nodes[0]->findnodes('.//cc:Toc');
+    my @nodes = $doc->findnodes('//cc:Toc');
     return 0 if (scalar(@nodes) < 1);
     foreach my $node ( @nodes ) {
         $html .= $node->textContent . '</P></P>';
@@ -128,34 +74,26 @@ sub parse_toc_html {
 }
 
 sub toc_xml {
-    my( $self, $keyhash ) = @_;
+    my( $self, $key ) = @_;
     return $self->send_xml(
-        $self->fetch_xmldoc('TocDetail', $keyhash),
-        'TocItems');
+        $self->fetch_content('TocDetail', $key));
 }
 
 sub toc_json {
-    my( $self, $keyhash ) = @_;
+    my( $self, $key ) = @_;
     return $self->send_json(
-        $self->fetch_xmldoc('TocDetail', $keyhash),
-        'TocItems');
+        $self->fetch_content('TocDetail', $key));
 }
 
 # --------------------------------------------------------------------------
 
 sub anotes_html {
-    my( $self, $keyhash ) = @_;
-    my $doc = $self->fetch_xmldoc('BiographyDetail', $keyhash);
-    return 0 unless defined $doc;
-    return $self->parse_anotes_html($doc);
-}
-
-sub parse_anotes_html {
-    my( $self, $doc ) = @_;
+    my( $self, $key ) = @_;
+    my $xml = $self->fetch_content('BiographyDetail', $key);
+    my $doc = XML::LibXML->new->parse_string($xml);
+    $doc->documentElement->setNamespace('http://ContentCafe2.btol.com', 'cc');
     my $html = '';
-    my @nodes = $doc->findnodes('//cc:BiographyItems[*]');
-    return 0 if (scalar(@nodes) < 1);
-    @nodes = $nodes[0]->findnodes('.//cc:Biography');
+    my @nodes = $doc->findnodes('//cc:Biography');
     return 0 if (scalar(@nodes) < 1);
     foreach my $node ( @nodes ) {
         $html .= '<P class="biography">' . $node->textContent . '</P>';
@@ -164,35 +102,27 @@ sub parse_anotes_html {
 }
 
 sub anotes_xml {
-    my( $self, $keyhash ) = @_;
+    my( $self, $key ) = @_;
     return $self->send_xml(
-        $self->fetch_xmldoc('BiographyDetail', $keyhash),
-        'BiographyItems');
+        $self->fetch_content('BiographyDetail', $key));
 }
 
 sub anotes_json {
-    my( $self, $keyhash ) = @_;
+    my( $self, $key ) = @_;
     return $self->send_json(
-        $self->fetch_xmldoc('BiographyDetail', $keyhash),
-        'BiographyItems');
+        $self->fetch_content('BiographyDetail', $key));
 }
 
 
 # --------------------------------------------------------------------------
 
 sub excerpt_html {
-    my( $self, $keyhash ) = @_;
-    my $doc = $self->fetch_xmldoc('ExcerptDetail', $keyhash);
-    return 0 unless defined $doc;
-    return $self->parse_excerpt_html($doc);
-}
-
-sub parse_excerpt_html {
-    my( $self, $doc ) = @_;
+    my( $self, $key ) = @_;
+    my $xml = $self->fetch_content('ExcerptDetail', $key);
+    my $doc = XML::LibXML->new->parse_string($xml);
+    $doc->documentElement->setNamespace('http://ContentCafe2.btol.com', 'cc');
     my $html = '';
-    my @nodes = $doc->findnodes('//cc:ExcerptItems[*]');
-    return 0 if (scalar(@nodes) < 1);
-    @nodes = $nodes[0]->findnodes('.//cc:Excerpt');
+    my @nodes = $doc->findnodes('//cc:Excerpt');
     return 0 if (scalar(@nodes) < 1);
     foreach my $node ( @nodes ) {
         $html .= $node->textContent;
@@ -201,34 +131,26 @@ sub parse_excerpt_html {
 }
 
 sub excerpt_xml {
-    my( $self, $keyhash ) = @_;
+    my( $self, $key ) = @_;
     return $self->send_xml(
-        $self->fetch_xmldoc('ExcerptDetail', $keyhash),
-        'ExcerptItems');
+        $self->fetch_content('ExcerptDetail', $key));
 }
 
 sub excerpt_json {
-    my( $self, $keyhash ) = @_;
+    my( $self, $key ) = @_;
     return $self->send_json(
-        $self->fetch_xmldoc('ExcerptDetail', $keyhash),
-        'ExcerptItems');
+        $self->fetch_content('ExcerptDetail', $key));
 }
 
 # --------------------------------------------------------------------------
 
 sub reviews_html {
-    my( $self, $keyhash ) = @_;
-    my $doc = $self->fetch_xmldoc('ReviewDetail', $keyhash);
-    return 0 unless defined $doc;
-    return $self->parse_reviews_html($doc);
-}
-
-sub parse_reviews_html {
-    my( $self, $doc ) = @_;
+    my( $self, $key ) = @_;
+    my $xml = $self->fetch_content('ReviewDetail', $key);
+    my $doc = XML::LibXML->new->parse_string($xml);
+    $doc->documentElement->setNamespace('http://ContentCafe2.btol.com', 'cc');
     my $html = '<ul>';
-    my @nodes = $doc->findnodes('//cc:ReviewItems[*]');
-    return 0 if (scalar(@nodes) < 1);
-    @nodes = $nodes[0]->findnodes('.//cc:ReviewItem');
+    my @nodes = $doc->findnodes('//cc:ReviewItem');
     return 0 if (scalar(@nodes) < 1);
     foreach my $node ( @nodes ) {
         my @s_nodes = $node->findnodes('./cc:Supplier');
@@ -245,34 +167,26 @@ sub parse_reviews_html {
 }
 
 sub reviews_xml {
-    my( $self, $keyhash ) = @_;
+    my( $self, $key ) = @_;
     return $self->send_xml(
-        $self->fetch_xmldoc('ReviewDetail', $keyhash),
-        'ReviewItems');
+        $self->fetch_content('ReviewDetail', $key));
 }
 
 sub reviews_json {
-    my( $self, $keyhash ) = @_;
+    my( $self, $key ) = @_;
     return $self->send_json(
-        $self->fetch_xmldoc('ReviewDetail', $keyhash),
-        'ReviewItems');
+        $self->fetch_content('ReviewDetail', $key));
 }
 
 # --------------------------------------------------------------------------
 
 sub summary_html {
-    my( $self, $keyhash ) = @_;
-    my $doc = $self->fetch_xmldoc('AnnotationDetail', $keyhash);
-    return 0 unless defined $doc;
-    return $self->parse_summary_html($doc);
-}
-
-sub parse_summary_html {
-    my( $self, $doc ) = @_;
+    my( $self, $key ) = @_;
+    my $xml = $self->fetch_content('AnnotationDetail', $key);
+    my $doc = XML::LibXML->new->parse_string($xml);
+    $doc->documentElement->setNamespace('http://ContentCafe2.btol.com', 'cc');
     my $html = '<ul>';
-    my @nodes = $doc->findnodes('//cc:AnnotationItems[*]');
-    return 0 if (scalar(@nodes) < 1);
-    @nodes = $nodes[0]->findnodes('.//cc:AnnotationItem');
+    my @nodes = $doc->findnodes('//cc:AnnotationItem');
     return 0 if (scalar(@nodes) < 1);
     foreach my $node ( @nodes ) {
         my @s_nodes = $node->findnodes('./cc:Supplier');
@@ -285,56 +199,77 @@ sub parse_summary_html {
 }
 
 sub summary_xml {
-    my( $self, $keyhash ) = @_;
+    my( $self, $key ) = @_;
     return $self->send_xml(
-        $self->fetch_xmldoc('AnnotationDetail', $keyhash),
-        'AnnotationItems');
+        $self->fetch_content('AnnotationDetail', $key));
 }
 
 sub summary_json {
-    my( $self, $keyhash ) = @_;
+    my( $self, $key ) = @_;
     return $self->send_json(
-        $self->fetch_xmldoc('AnnotationDetail', $keyhash),
-        'AnnotationItems');
+        $self->fetch_content('AnnotationDetail', $key));
+}
+
+sub available_json {
+    my($self, $key) = @_;
+    my $xml = $self->fetch_content('AvailableContent', $key);
+    my $doc = XML::LibXML->new->parse_string($xml);
+
+    my @avail;
+    for my $node ($doc->findnodes('//*[text()="true"]')) {
+        push(@avail, 'summary') if $node->nodeName eq 'Annotation';
+        push(@avail, 'jacket') if $node->nodeName eq 'Jacket';
+        push(@avail, 'toc') if $node->nodeName eq 'TOC';
+        push(@avail, 'anotes') if $node->nodeName eq 'Biography';
+        push(@avail, 'excerpt') if $node->nodeName eq 'Excerpt';
+        push(@avail, 'reviews') if $node->nodeName eq 'Review';
+    }
+
+    return { 
+        content_type => 'text/plain', 
+        content => OpenSRF::Utils::JSON->perl2JSON(\@avail)
+    };
 }
 
+
 # --------------------------------------------------------------------------
 
-sub build_keylist {
-    my ( $self, $keyhash ) = @_;
-    my $keys = []; # Start with an empty array
-    foreach my $identifier (@{$self->identifier_order}) {
-        foreach my $key (@{$keyhash->{$identifier}}) {
-            push @{$keys}, $key;
-        }
-    }
-    return $keys;
+
+sub data_exists {
+    my( $self, $data ) = @_;
+    return 0 if $data =~ m/<title>error<\/title>/iog;
+    return 1;
 }
 
+
 sub send_json {
-    my( $self, $doc, $contentNode ) = @_;
-    return 0 unless defined $doc;
-    my @nodes = $doc->findnodes('//cc:' . $contentNode . '[*]');
-    return 0 if (scalar(@nodes) < 1);
-    my $perl = OpenSRF::Utils::SettingsParser::XML2perl($nodes[0]);
+    my( $self, $xml ) = @_;
+    return 0 unless $self->data_exists($xml);
+    my $doc;
+
+    try {
+        $doc = XML::LibXML->new->parse_string($xml);
+    } catch Error with {
+        my $err = shift;
+        $logger->error("added content XML parser error: $err\n\n$xml");
+        $doc = undef;
+    };
+
+    return 0 unless $doc;
+    my $perl = OpenSRF::Utils::SettingsParser::XML2perl($doc->documentElement);
     my $json = OpenSRF::Utils::JSON->perl2JSON($perl);
     return { content_type => 'text/plain', content => $json };
 }
 
 sub send_xml {
-    my( $self, $doc, $contentNode ) = @_;
-    return 0 unless defined $doc;
-    my @nodes = $doc->findnodes('//cc:' . $contentNode . '[*]');
-    return 0 if (scalar(@nodes) < 1);
-    my $newdoc = XML::LibXML::Document->new( '1.0', 'utf-8' );
-    my $clonenode = $nodes[0]->cloneNode(1);
-    $newdoc->adoptNode($clonenode);
-    $newdoc->setDocumentElement($clonenode);
-    return { content_type => 'application/xml', content => $newdoc->toString() };
+    my( $self, $xml ) = @_;
+    return 0 unless $self->data_exists($xml);
+    return { content_type => 'application/xml', content => $xml };
 }
 
 sub send_html {
     my( $self, $content ) = @_;
+    return 0 unless $self->data_exists($content);
 
     # Hide anything that might contain a link since it will be broken
     my $HTML = <<"    HTML";
@@ -351,87 +286,39 @@ sub send_html {
     return { content_type => 'text/html', content => $HTML };
 }
 
-sub send_jacket {
-    my( $self, $keyhash, $size ) = @_;
-
-    my $doc = $self->fetch_xmldoc({name => 'JacketDetail', attributes => [['Type',$size],['Encoding','HEX']]}, $keyhash);
-    return 0 unless defined $doc;
-
-    return $self->parse_jacket($doc, $size);
-}
-
-sub parse_jacket {
-    my( $self, $doc, $size ) = @_;
-    my @nodes = $doc->findnodes("//cc:JacketItem[cc:Type/\@Code = '$size']");
-    return 0 if (scalar(@nodes) < 1);
-
-    my $jacketItem = shift(@nodes); # We only care about the first jacket
-    my @formatNodes = $jacketItem->findnodes('./cc:Format');
-    my $format = $formatNodes[0]->textContent;
-    my @jacketNodes = $jacketItem->findnodes('./cc:Jacket');
-    my $imageData = pack('H*',$jacketNodes[0]->textContent);
-
-    return {
-        content_type => 'image/' . lc($format),
-        content => $imageData,
+sub send_img {
+    my($self, $response) = @_;
+    return { 
+        content_type => $response->header('Content-type'),
+        content => $response->content, 
         binary => 1 
     };
 }
 
-# returns an XML document ready for parsing if $keyhash contained usable keys
-# otherwise returns undef
-sub fetch_xmldoc {
-    my( $self, $contentTypes, $keyhash ) = @_;
-
-    my $keys = $self->build_keylist($keyhash);
-    return undef unless @{$keys};
-
-    my $content = $self->fetch_response($contentTypes, $keys)->content;
-    my $doc = XML::LibXML->new->parse_string($content);
-    $doc->documentElement->setNamespace('http://ContentCafe2.btol.com', 'cc');
-    return $doc;
+# returns the raw content returned from the URL fetch
+sub fetch_content {
+    my( $self, $contentType, $key ) = @_;
+    return $self->fetch_response($contentType, $key)->content;
 }
 
 # returns the HTTP response object from the URL fetch
 sub fetch_response {
-    my( $self, $contentTypes, $keys ) = @_;
-
-    if (ref($contentTypes) ne 'ARRAY') {
-        $contentTypes = [ $contentTypes ];
-    }
+    my( $self, $contentType, $key ) = @_;
+    my $userid = $self->userid;
+    my $password = $self->password;
+    my $url = $base_url . "?UserID=$userid&Password=$password&Key=$key&Content=$contentType";
+    return $AC->get_url($url);
+}
 
-    my $xmlRequest = XML::LibXML::Document->new( '1.0', 'utf-8' );
-    my $root = $xmlRequest->createElementNS('http://ContentCafe2.btol.com','ContentCafe');
-    $root->addChild($xmlRequest->createAttribute('DateTime', DateTime->now()->datetime));
-    $xmlRequest->setDocumentElement($root);
-    my $requestItems = $xmlRequest->createElement('RequestItems');
-    $requestItems->addChild($xmlRequest->createAttribute('UserID', $self->userid));
-    $requestItems->addChild($xmlRequest->createAttribute('Password', $self->password));
-    $root->addChild($requestItems);
-
-    foreach my $key (@{$keys}) {
-        my $requestItem = $xmlRequest->createElement('RequestItem');
-        my $keyNode = $xmlRequest->createElement('Key');
-        $keyNode->addChild($xmlRequest->createTextNode($key));
-        $requestItem->addChild($keyNode);
-
-        foreach my $contentType (@{$contentTypes}) {
-            my $contentNode = $xmlRequest->createElement('Content');
-            if (ref($contentType) eq 'HASH') {
-                $contentNode->addChild($xmlRequest->createTextNode($contentType->{name}));
-                foreach my $contentAttribute (@{$contentType->{attributes}}) {
-                    $contentNode->addChild($xmlRequest->createAttribute($contentAttribute->[0], $contentAttribute->[1]));
-                }
-            } else {
-                $contentNode->addChild($xmlRequest->createTextNode($contentType));
-            }
-            $requestItem->addChild($contentNode);
-        }
-
-        $requestItems->addChild($requestItem);
-    }
-    my $response = $AC->post_url($post_url, $xmlRequest->toString);
-    return $response;
+# returns the HTTP response object from the URL fetch
+sub fetch_cover_response {
+    my( $self, $size, $key ) = @_;
+    my $userid = $self->userid;
+    my $password = $self->password;
+    my $return = $self->return_behavior_on_no_jacket_image;
+    my $url = $cover_base_url . "?UserID=$userid&Password=$password&Return=$return&Type=$size&Value=$key";
+    return $AC->get_url($url);
 }
 
+
 1;