Teach OpenLibrary.pm how to extract ebook links from OpenLibrary results
authordbs <dbs@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 27 Apr 2011 15:54:48 +0000 (15:54 +0000)
committerdbs <dbs@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 27 Apr 2011 15:54:48 +0000 (15:54 +0000)
If the Internet Archive has an available ebook, then OpenLibrary will
provide links to it in various formats. For now, we return the results
as a plain set of <div> elements with class attributes denoting what
kind of ebook was returned; i18n will have to take care of providing
an actual label. Oh, and I guess we want to turn these into actual
<a> links...

Signed-off-by: Dan Scott <dscott@laurentian.ca>

git-svn-id: svn://svn.open-ils.org/ILS/trunk@20344 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/perlmods/lib/OpenILS/WWW/AddedContent/OpenLibrary.pm

index fab9ea9..c3d6c07 100644 (file)
@@ -1,6 +1,6 @@
 # ---------------------------------------------------------------
 # Copyright (C) 2009 David Christensen <david.a.christensen@gmail.com>
-# Copyright (C) 2009 Dan Scott <dscott@laurentian.ca>
+# Copyright (C) 2009-2011 Dan Scott <dscott@laurentian.ca>
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -30,7 +30,13 @@ my $AC = 'OpenILS::WWW::AddedContent';
 
 # These URLs are always the same for OpenLibrary, so there's no advantage to
 # pulling from opensrf.xml; we hardcode them here
-my $base_url = 'http://openlibrary.org/api/books?details=true&bibkeys=ISBN:';
+
+# jscmd=details is unstable but includes goodies such as Table of Contents
+my $base_url_details = 'http://openlibrary.org/api/books?format=json&jscmd=details&bibkeys=ISBN:';
+
+# jscmd=data is stable and contains links to ebooks, excerpts, etc
+my $base_url_data = 'http://openlibrary.org/api/books?format=json&jscmd=data&bibkeys=ISBN:';
+
 my $cover_base_url = 'http://covers.openlibrary.org/b/isbn/';
 
 sub new {
@@ -60,6 +66,62 @@ sub jacket_large {
 
 # --------------------------------------------------------------------------
 
+sub ebooks_html {
+    my( $self, $key ) = @_;
+    my $book_data_json = $self->fetch_data_response($key)->content();
+
+    $logger->debug("$key: " . $book_data_json);
+
+    my $ebook_html;
+    
+    my $book_data = OpenSRF::Utils::JSON->JSON2perl($book_data_json);
+    my $book_key = (keys %$book_data)[0];
+
+    # We didn't find a matching book; short-circuit our response
+    if (!$book_key) {
+        $logger->debug("$key: no found book");
+        return 0;
+    }
+
+    my $ebooks_json = $book_data->{$book_key}->{ebooks};
+
+    # No ebooks are available for this book; short-circuit
+    if (!$ebooks_json or !scalar(@$ebooks_json)) {
+        $logger->debug("$key: no ebooks");
+        return 0;
+    }
+
+    # Check the availability of the ebooks
+    my $available = $ebooks_json->[0]->{'availability'} || '';
+    if (!$available) {
+        $logger->debug("$key: no available ebooks");
+        return 0;
+    }
+
+    # Build a basic list of available ebook types and their URLs
+    # ebooks appears to be an array containing one element - a hash
+
+    # First element of the hash is 'read_url' which is a URL to
+    # Internet Archive online reader
+    my $stream_url = $ebooks_json->[0]->{'read_url'} || '';
+    if ($stream_url) {
+        $ebook_html .= "<div class='ebook_stream'>$stream_url</div>\n";
+        $logger->debug("$key: stream URL = $stream_url");
+    }
+
+    my $ebook_formats = $ebooks_json->[0]->{'formats'} || '';
+    # Next elements are various ebook formats that are available
+    foreach my $ebook (keys %{$ebook_formats}) {
+        if ($ebook_formats->{$ebook} eq 'read_url') {
+            next;
+        }
+        $ebook_html .= "<div class='$ebook'>" . 
+            $ebook_formats->{$ebook}->{'url'} . "</div>\n";
+    }
+
+    $logger->debug("$key: $ebook_html");
+    $self->send_html("<div class='ebooks'>$ebook_html</div>");
+}
 =head1
 
 OpenLibrary returns a JSON hash of zero or more book responses matching our
@@ -74,12 +136,7 @@ HTML table.
 
 sub toc_html {
     my( $self, $key ) = @_;
-    my $book_details_json = $self->fetch_response($key)->content();
-
-
-    # Trim the "var _OlBookInfo = " declaration that makes this
-    # invalid JSON
-    $book_details_json =~ s/^.+?({.*?});$/$1/s;
+    my $book_details_json = $self->fetch_details_response($key)->content();
 
     $logger->debug("$key: " . $book_details_json);
 
@@ -127,7 +184,7 @@ sub toc_html {
 sub toc_json {
     my( $self, $key ) = @_;
     my $toc = $self->send_json(
-        $self->fetch_response($key)
+        $self->fetch_details_response($key)
     );
 }
 
@@ -167,9 +224,16 @@ sub send_html {
 }
 
 # returns the HTTP response object from the URL fetch
-sub fetch_response {
+sub fetch_data_response {
+    my( $self, $key ) = @_;
+    my $url = $base_url_data . "$key";
+    my $response = $AC->get_url($url);
+    return $response;
+}
+# returns the HTTP response object from the URL fetch
+sub fetch_details_response {
     my( $self, $key ) = @_;
-    my $url = $base_url . "$key";
+    my $url = $base_url_details . "$key";
     my $response = $AC->get_url($url);
     return $response;
 }