Bug 28180: Reintroduce and adjust OpenLibrary
[koha-ffzg.git] / koha-tmpl / opac-tmpl / bootstrap / js / openlibrary.js
1 if (typeof KOHA == "undefined" || !KOHA) {
2     var KOHA = {};
3 }
4
5 /**
6  * A namespace for OpenLibrary related functions.
7  */
8 KOHA.OpenLibrary = new function() {
9
10     /**
11      * Search all:
12      *    <div title="biblionumber" id="isbn" class="openlibrary-thumbnail"></div>
13      * or
14      *    <div title="biblionumber" id="isbn" class="openlibrary-thumbnail-preview"></div>
15      * and run a search with all collected isbns to Open Library Book Search.
16      * The result is asynchronously returned by OpenLibrary and catched by
17      * olCallBack().
18      */
19     this.GetCoverFromIsbn = function() {
20         var bibkeys = [];
21         $("[id^=openlibrary-thumbnail]").each(function(i) {
22             bibkeys.push("ISBN:" + $(this).attr("class")); // id=isbn
23         });
24         bibkeys = bibkeys.join(',');
25         var scriptElement = document.createElement("script");
26         scriptElement.setAttribute("id", "jsonScript");
27         scriptElement.setAttribute("src",
28             "https://openlibrary.org/api/books?bibkeys=" + escape(bibkeys) +
29             "&callback=KOHA.OpenLibrary.olCallBack&jscmd=data");
30         scriptElement.setAttribute("type", "text/javascript");
31         document.documentElement.firstChild.appendChild(scriptElement);
32     }
33
34     /**
35      * Add cover pages <div
36      * and link to preview if div id is gbs-thumbnail-preview
37      */
38     this.olCallBack = function(booksInfo) {
39         for (id in booksInfo) {
40             var book = booksInfo[id];
41             var isbn = id.substring(5);
42             $("[id^=openlibrary-thumbnail]."+isbn).each(function() {
43                 var a = document.createElement("a");
44                 a.href = booksInfo.url;
45                 if (book.cover) {
46                     if ( $(this).data('use-data-link') ) {
47                          var a = document.createElement("a");
48                          a.href = book.cover.large;
49                          var img = document.createElement("img");
50                          img.src = book.cover.medium;
51                          img.setAttribute('data-link', book.cover.large);
52                          a.append(img)
53                          $(this).empty().append(a);
54                     } else {
55                         var img = document.createElement("img");
56                         img.src = book.cover.medium;
57                         img.height = '110';
58                         $(this).append(img);
59                     }
60                 } else {
61                     var message =  document.createElement("span");
62                     $(message).attr("class","no-image");
63                     $(message).html(NO_OL_JACKET);
64                     $(this).append(message);
65                 }
66             });
67         }
68     }
69
70     var search_url = 'https://openlibrary.org/search?';
71     this.searchUrl = function( q ) {
72         var params = {q: q};
73         return search_url + $.param(params);
74     };
75
76     var search_url_json = 'https://openlibrary.org/search.json';
77     this.search = function( q, page_no, callback ) {
78         var params = {q: q};
79         if (page_no) {
80             params.page = page_no;
81         }
82         $.ajax( {
83             type: 'GET',
84             url: search_url_json,
85             dataType: 'json',
86             data: params,
87             error: function( xhr, error ) {
88                 try {
89                     callback( JSON.parse( xhr.responseText ));
90                 } catch ( e ) {
91                     callback( {error: xhr.responseText || true} );
92                 }
93             },
94             success: callback
95         } );
96     };
97 };
98 /* readapi_automator.js */
99
100 /*
101 This script helps to put readable links to Open Library books into
102 online book catalogs.
103 When loaded, it searches the DOM for <div> elements with class
104 "ol_readapi_book", extracts book identifiers from them (e.g. isbn,
105 lccn, etc.) and puts those into an asynchronous call to the Read API.
106 When the call returns, the results are used to add clickable links
107 to the "ol_readapi_book" elements found earlier.
108 A demonstration use of this script is available here:
109 http://internetarchive.github.com/read_api_extras/readapi_demo.html
110 */
111
112 var ol_readapi_automator =
113 (function () { // open anonymous scope for tidiness
114
115 // 'constants'
116 var readapi_bibids = ['isbn', 'lccn', 'oclc', 'olid', 'iaid', 'bibkeys'];
117 var magic_classname = 'ol_readapi_book';
118 var ol_readapi_books = $("." + magic_classname );
119 var result;
120
121 // added to book divs to correlate with API results
122 var magic_bookid = 'ol_bookid';
123 var ol_button_classname = 'ol_readapi_button';
124
125 // Find all book divs and concatenate ids from them to create a read
126 // API query url
127 function create_query() {
128     var q = 'https://openlibrary.org/api/volumes/brief/json/';
129
130     function add_el(i, el) {
131         // tag with number found so it's easy to discover later
132         // (necessary?  just go by index?)
133         // (choose better name?)
134         $(el).attr(magic_bookid, i);
135
136         if (i > 0) {
137             q += '|';
138         }
139         q += 'id:' + i;
140
141         for (bi in readapi_bibids) {
142             bibid = readapi_bibids[bi];
143             if ($(el).attr(bibid)) {
144                 q += ';' + bibid + ':' + $(el).attr(bibid);
145             }
146         }
147     }
148
149     $('.' + magic_classname).each(add_el);
150     return q;
151 }
152
153 function make_read_button(bookdata) {
154     buttons = {
155         'full access':
156         "https://openlibrary.org/images/button-read-open-library.png",
157         'lendable':
158         "https://openlibrary.org/images/button-borrow-open-library.png",
159         'checked out':
160         "https://openlibrary.org/images/button-checked-out-open-library.png"
161     };
162     if (bookdata.items.length == 0) {
163         return false;
164     }
165     first = bookdata.items[0];
166     if (!(first.status in buttons)) {
167         return false;
168     }
169     result = '<a target="_blank" href="' + first.itemURL + '">' +
170       '<img class="' + ol_button_classname +
171       '" src="' + buttons[first.status] + '"/></a>';
172     console.log( result );
173     return result;
174 }
175
176 // Default function for decorating document elements with read API data
177 function default_decorate_el_fn(el, bookdata) {
178     // Note that 'bookdata' may be undefined, if the Read API call
179     // didn't return results for this book
180     var decoration;
181     if (bookdata) {
182         decoration = make_read_button(bookdata);
183     }
184     if (decoration) {
185         el.innerHTML += decoration;
186         el.style.display = 'block'
187     } else {
188         el.style.display = 'none';
189     }
190 }
191
192 function do_query(q, decorate_el_fn) {
193     if (!decorate_el_fn) {
194         decorate_el_fn = default_decorate_el_fn;
195     }
196     var starttime = (new Date()).getTime();
197
198     // Call a function on each <div class="ol_readapi_book"> element
199     // with the target element and the data found for that element.
200     // Use decorate_el_fn if supplied, falling back to
201     // default_decorate_el_fn, above.
202     function query_callback(data, textStatus, jqXHR) {
203         var endtime = (new Date()).getTime();
204         var duration = (endtime - starttime) / 1000;
205         // console.log('took ' + duration + ' seconds');
206
207         $('.' + magic_classname).each(function(i, el) {
208                 var bookid = $(el).attr(magic_bookid);
209                 if (bookid && bookid in data) {
210                     decorate_el_fn(el, data[bookid]);
211                 } else {
212                     decorate_el_fn(el);
213                 }
214             });
215     }
216
217     // console.log('calling ' + q);
218     $.ajax({ url: q,
219                 data: { 'show_all_items': 'true' },
220                 dataType: 'jsonp',
221                 success: query_callback
222                 });
223 }
224
225 if( ol_readapi_books.length > 0 ){
226     // Do stuff
227     var q = create_query();
228     do_query(q);
229
230     result = {
231         do_query: do_query,
232         create_query: create_query,
233         make_read_button: make_read_button
234     };
235 }
236
237 return result;
238 })(); // close anonymous scope
239
240 /*
241 Possible futures:
242 * Support alternate query targets, e.g. Hathi
243 * show_all_items
244 * show_inlibrary
245 * ezproxy prefix (implies show_inlibrary?)
246 * console debug output? (check all console.log)
247 */