Bug 9580 Cover images from Coce, a remote image URL cache
authorFrédéric Demians <f.demians@tamil.fr>
Thu, 7 Feb 2013 08:55:29 +0000 (09:55 +0100)
committerTomas Cohen Arazi <tomascohen@gmail.com>
Wed, 1 Apr 2015 12:31:42 +0000 (09:31 -0300)
Add to Koha support for displaying Book cover requested to Coce, a
remote image URL cache:

  https://github.com/fredericd/coce

With this enhancement, cover images are not fetched directly from
Amazon, Google, and so on. Their URL are requested via a web service to
Coce which manages a cache of URLs.

Three cover image providers are now available: Google Books (gb), Amazon
(aws), and Open Library (ol). Two system preferences enable this service:

  - CoceHost - URL of Coce server
  - CoceProviders - Ordered list of requested providers. For example
    gb,aws,ol, will return the first available URL from those providers.

Several advantages to this architecture:

  - If a book cover is not available from a provider, but is available
    from another one, Koha will be able to display a book cover, which
    isn't the case now
  - Since URLs are cached, it isn't necessary for each book cover to
    request, again and again, the provider, and several of them if
    necessary.
  - Amazon book covers are retrieved with Amazon Product Advertising
    API, which means that more covers are retrieved (ISBN13).

Test plan:

- Apply this patch, and test with 'Bootstrap' themes
- You can verify that nothing has changed on OPAC result and detail
  page, since new syspref haven't been filled
- Install Code: https://github.com/fredericd/coce
  Or ask me directly for the URL of a Coce server
- In sysprefs, tab Enhanced content, modify:
  CoceHost -- enter the URL of your Coce server
  CoceProviders -- fill with: gb,aws,ol
- Do a search. On result page, and detail page, you will see cover
  images originating from the 3 providers: fly over the image to see its
  URL. Try to compare with a Koha with just GoogleJacket or Amazon cover
  to confirm that you have more images. Verify that it's quick, and even
  quicker for cached images URLs.
- Check that Browse Shelf functionnality works properly.
- The ID sent to Coce is EAN or ISBN. Try with various type of biblios. DVD
  have often EAN, but no ISBN.
- You can try with those sysprefs:
    CoceProviders: aws,gb
    CoceHost: http://coce.tamil.fr:8080
  and this EAN (or ISBN): 3333297517744
  => OPACAmazonCoverImages enabled doesn't display a cover because, it's a DVD
  => Coce find and display the DVD cover.

Signed-off-by: Mark Tompsett <mtompset@hotmail.com>
Signed-off-by: Jonathan Druart <jonathan.druart@biblibre.com>
Amended patch: replaced 1 tab with spaces in C4/Shelfbrowser.pm

Signed-off-by: Tomas Cohen Arazi <tomascohen@gmail.com>

C4/ShelfBrowser.pm
installer/data/mysql/sysprefs.sql
installer/data/mysql/updatedatabase.pl
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref
koha-tmpl/opac-tmpl/bootstrap/en/includes/opac-bottom.inc
koha-tmpl/opac-tmpl/bootstrap/en/includes/shelfbrowser.inc
koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt
koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-results.tt
koha-tmpl/opac-tmpl/bootstrap/js/coce.js [new file with mode: 0644]

index 763b406..d891771 100644 (file)
@@ -73,6 +73,7 @@ to take into account.
          print $_->{browser_normalized_upc};
          print $_->{browser_normalized_oclc};
          print $_->{browser_normalized_isbn};
+      print $_->{browser_normalized_ean};
   }
 
   # This is the information required to scroll the browser to the next left
@@ -228,6 +229,7 @@ sub GetShelfInfo {
         $item->{'browser_normalized_upc'} = GetNormalizedUPC($this_record,$marcflavour);
         $item->{'browser_normalized_oclc'} = GetNormalizedOCLCNumber($this_record,$marcflavour);
         $item->{'browser_normalized_isbn'} = GetNormalizedISBN(undef,$this_record,$marcflavour);
+        $item->{'browser_normalized_ean'} = GetNormalizedEAN($this_record,$marcflavour);
         push @valid_items, $item;
     }
     return @valid_items;
index 30b7ee5..cb47d9e 100644 (file)
@@ -86,6 +86,8 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
 ('CircAutocompl','1',NULL,'If ON, autocompletion is enabled for the Circulation input','YesNo'),
 ('CircAutoPrintQuickSlip','qslip',NULL,'Choose what should happen when an empty barcode field is submitted in circulation: Display a print quick slip window, Display a print slip window or Clear the screen.','Choice'),
 ('CircControl','ItemHomeLibrary','PickupLibrary|PatronLibrary|ItemHomeLibrary','Specify the agency that controls the circulation and fines policy','Choice'),
+('CoceHost', NULL, NULL, 'Coce server URL', 'Free'),
+('CoceProviders', NULL, NULL, 'Coce providers, for example aws,gb', 'Free'),
 ('COinSinOPACResults','1','','If ON, use COinS in OPAC search results page.  NOTE: this can slow down search response time significantly','YesNo'),
 ('ConfirmFutureHolds','0','','Number of days for confirming future holds','Integer'),
 ('CurrencyFormat','US','US|FR','Determines the display format of currencies. eg: \'36000\' is displayed as \'360 000,00\'  in \'FR\' or \'360,000.00\'  in \'US\'.','Choice'),
index 4c6d9d9..8e13509 100755 (executable)
@@ -9953,6 +9953,20 @@ if ( CheckVersion($DBversion) ) {
     SetVersion ($DBversion);
 }
 
+$DBversion = "3.19.00.XXX";
+if ( CheckVersion($DBversion) ) {
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable, value, explanation, options, type)
+        VALUES('CoceHost', NULL, 'Coce server URL', NULL,'Free')
+    });
+    $dbh->do(q{
+        INSERT IGNORE INTO systempreferences (variable, value, explanation, options, type)
+        VALUES('CoceProviders', NULL, 'Coce Providers, for example: aws,gb', NULL,'Free')
+    });
+    print "Upgrade to $DBversion done (Bug 9580 - Cover image from Coce, a remote image URL cache)\n";
+    SetVersion($DBversion);
+}
+
 
 # DEVELOPER PROCESS, search for anything to execute in the db_update directory
 # SEE bug 13068
@@ -9967,7 +9981,6 @@ while ( my $file = readdir $dirh ) {
     my $rv = $installer->load_sql( $update_dir . $file ) ? 0 : 1;
 }
 
-
 =head1 FUNCTIONS
 
 =head2 TableExists($table)
index 627f095..cf639aa 100644 (file)
@@ -337,3 +337,12 @@ Enhanced Content:
             - "Show items from the OverDrive catalog of library #"
             - pref: OverDriveLibraryID
             - .
+    Coce Cover images cache:
+        -
+            - Coce server URL
+            - pref: CoceHost
+              class: url
+        -
+            - Providers
+            - pref: CoceProviders
+            - 'separated by comma, for example: aws,gb. Leave empty not to activate this service.'
index a79e84e..1b7520f 100644 (file)
@@ -165,6 +165,15 @@ $.widget.bridge('uitooltip', $.ui.tooltip);
         //]]>
     </script>
 [% END %]
+[% IF Koha.Preference('CoceProviders') %]
+    <script type="text/javascript" src="[% interface %]/[% theme %]/js/coce.js"></script>
+    <script type="text/javascript">
+        //<![CDATA[
+        var NO_COCE_JACKET = _("No cover image available");
+        //]]>
+    </script>
+[% END %]
+
 [% IF OpenLibraryCovers %]
     <script type="text/javascript" src="[% interface %]/[% theme %]/js/openlibrary.js"></script>
     <script type="text/javascript">
index bc5ef2c..9140199 100644 (file)
                                         <span class="no-image">No cover image available</span>
                                     [% END %]
                                 [% END %]
+                                [% IF ( Koha.Preference('CoceProviders') ) %]
+                                  [% coce_id = item.browser_normalized_ean || item.browser_normalized_isbn %]
+                                  <div title="[% item.biblionumber |url %]" class="[% coce_id %]" id="coce-thumbnail-preview-[% coce_id %]"></div>
+                                [% END %]
                                 [% IF ( BakerTaylorEnabled ) %]
                                     [% IF ( item.browser_normalized_isbn ) %]
                                         <img alt="See Baker &amp; Taylor" src="[% BakerTaylorImageURL |html %][% item.browser_normalized_isbn %]" />
@@ -83,4 +87,4 @@
             </table>
         </div>
     [% END # /IF OpenOPACShelfBrowser %]
-[% END # end of shelfbrowser block %]
\ No newline at end of file
+[% END # end of shelfbrowser block %]
index dc759b6..b0805d1 100644 (file)
                     [% IF ( GoogleJackets ) %]
                         <div title="[% biblionumber |url %]" class="[% normalized_isbn %]" id="gbs-thumbnail-preview"></div>
                     [% END %]
+                    [% IF ( Koha.Preference('CoceProviders') ) %]
+                      [% coce_id = normalized_ean || normalized_isbn %]
+                      <div style="block" title="[% biblionumber |url %]" class="[% coce_id %]" id="coce-thumbnail-preview"></div>
+                    [% END %]
                     [% IF OpenLibraryCovers %]
                         <div title="[% biblionumber |url %]" class="[% normalized_isbn %]" id="openlibrary-thumbnail-preview"></div>
                     [% END %]
     [% IF ( GoogleJackets ) %]
         KOHA.Google.GetCoverFromIsbn([% covernewwindow %]);
     [% END %]
+    [% IF ( Koha.Preference('CoceProviders') ) %]
+        KOHA.coce.getURL('[% Koha.Preference('CoceHost') %]', '[% Koha.Preference('CoceProviders') %]',[% covernewwindow %]);
+    [% END %]
+
     [% IF OpenLibraryCovers %]
         KOHA.OpenLibrary.GetCoverFromIsbn();
     [% END %]
                     [% IF ( GoogleJackets ) %]
                       KOHA.Google.GetCoverFromIsbn([% covernewwindow %]);
                     [% END %]
+                    [% IF ( Koha.Preference('CoceProviders') ) %]
+                      KOHA.coce.getURL('[% Koha.Preference('CoceHost') %]', '[% Koha.Preference('CoceProviders') %]',[% covernewwindow %]);
+                    [% END %]
                     [% IF OpenLibraryCovers %]
                       KOHA.OpenLibrary.GetCoverFromIsbn();
                     [% END %]
                     [% IF ( GoogleJackets ) %]
                       KOHA.Google.GetCoverFromIsbn([% covernewwindow %]);
                     [% END %]
+                    [% IF ( Koha.Preference('CoceProviders') ) %]
+                      KOHA.coce.getURL('[% Koha.Preference('CoceHost') %]', '[% Koha.Preference('CoceProviders') %]',[% covernewwindow %]);
+                    [% END %]
                     [% IF OpenLibraryCovers %]
                       KOHA.OpenLibrary.GetCoverFromIsbn();
                     [% END %]
index d01ddeb..a995258 100644 (file)
                                                             [% END %]
                                                         [% END %]
 
+                                                        [% IF ( Koha.Preference('CoceProviders') ) %]
+                                                          [% coce_id = SEARCH_RESULT.normalized_ean || SEARCH_RESULT.normalized_isbn %]
+                                                          [% IF ( coce_id ) %]
+                                                            <span style="block" title="[% SEARCH_RESULT.biblionumber |url %]" class="[% coce_id %]" id="coce-thumbnail[% loop.count %]"></span>
+                                                          [% ELSE %]
+                                                            <span class="no-image">No cover image available</span>
+                                                          [% END %]
+                                                        [% END %]
+
                                                         [% IF OpenLibraryCovers %]
                                                             [% IF SEARCH_RESULT.normalized_isbn %]
                                                                 <span style="block" title="[% SEARCH_RESULT.biblionumber %]" class="[% SEARCH_RESULT.normalized_isbn %]" id="openlibrary-thumbnail[% loop.count %]"></span>
@@ -904,6 +913,7 @@ $(document).ready(function(){
 [% IF OpenLibraryCovers %]KOHA.OpenLibrary.GetCoverFromIsbn();[% END %]
 [% IF OPACLocalCoverImages %]KOHA.LocalCover.GetCoverFromBibnumber(false);[% END %]
 [% IF ( GoogleJackets ) %]KOHA.Google.GetCoverFromIsbn();[% END %]
+[% IF ( Koha.Preference('CoceProviders') ) %]KOHA.coce.getURL('[% Koha.Preference('CoceHost') %]', '[% Koha.Preference('CoceProviders') %]');[% END %]
 
 [% IF ( DidYouMean ) %]
     $("#didyoumean").load("/cgi-bin/koha/svc/suggestion?render=stub&q=[% querystring |uri %]",
diff --git a/koha-tmpl/opac-tmpl/bootstrap/js/coce.js b/koha-tmpl/opac-tmpl/bootstrap/js/coce.js
new file mode 100644 (file)
index 0000000..95669a0
--- /dev/null
@@ -0,0 +1,43 @@
+if (KOHA === undefined || !KOHA) { var KOHA = {}; }
+
+
+/**
+ * A namespace for Coce cover images cache
+ */
+KOHA.coce = {
+
+  /**
+   * Search all:
+   *    <div title="biblionumber" id="isbn" class="coce-thumbnail"></div>
+   * or
+   *    <div title="biblionumber" id="isbn" class="coce-thumbnail-preview"></div>
+   * and run a search with all collected isbns to coce cover service.
+   * The result is asynchronously returned, and used to append <img>.
+   */
+  getURL: function(host,provider,newWindow) {
+    var ids = [];
+    $("[id^=coce-thumbnail]").each(function(i) {
+        var id = $(this).attr("class"); // id=isbn
+        if ( id !== '' ) { ids.push(id); }
+    });
+    if (ids.length == 0) return;
+    ids = ids.join(',');
+    var coceURL = host + '/cover?id=' + ids + '&provider=' + provider;
+    $.ajax({
+      url: coceURL,
+      dataType: 'jsonp',
+      success: function(urlPerID){
+        for (var id in urlPerID) {
+          var url = urlPerID[id];
+          $("[id^=coce-thumbnail]."+id).each(function() {
+            var img = document.createElement("img");
+            img.src = url;
+            img.title = url; //FIXME: to delete
+            $(this).html(img);
+         });
+        }
+      }
+    });
+  }
+
+};