Merge branch 'master' of git@github.com:openlibrary/bookreader into browserlending
[bookreader.git] / BookReaderIA / datanode / BookReaderJSIA.php
index 027e728..f02a92e 100644 (file)
@@ -118,6 +118,44 @@ $metaData = simplexml_load_file($metaDataFile);
 //$firstLeaf = $scanData->pageData->page[0]['leafNum'];
 ?>
 
+// Error reporting - this helps us fix errors quickly
+function logError(description,page,line) {
+    if (typeof(archive_analytics) != 'undefined') {
+        var values = {
+            'bookreader': 'error',
+            'description': description,
+            'page': page,
+            'line': line,
+            'itemid': '<?echo $id;?>',
+            'subPrefix': '<?echo $subPrefix;?>',
+            'server': '<?echo $server;?>',
+            'bookPath': '<?echo $subItemPath;?>'
+        };
+
+        // if no referrer set '-' as referrer
+        if (document.referrer == '') {
+            values['referrer'] = '-';
+        } else {
+            values['referrer'] = document.referrer;
+        }
+        
+        if (typeof(br) != 'undefined') {
+            values['itemid'] = br.bookId;
+            values['subPrefix'] = br.subPrefix;
+            values['server'] = br.server;
+            values['bookPath'] = br.bookPath;
+        }
+        
+        var qs = archive_analytics.format_bug(values);
+
+        var error_img = new Image(100,25);
+        error_img.src = archive_analytics.img_src + "?" + qs;
+    }
+
+    return false; // allow browser error handling so user sees there was a problem
+}
+window.onerror=logError;
+
 br = new BookReader();
 
 <?
@@ -320,7 +358,7 @@ br.getEmbedURL = function(viewParams) {
         url += '/' + this.subPrefix;
     }
     url += '?ui=embed';
-    if (viewParams) {
+    if (typeof(viewParams) != 'undefined') {
         url += '#' + this.fragmentFromParams(viewParams);
     }
     return url;
@@ -329,28 +367,30 @@ br.getEmbedURL = function(viewParams) {
 // getEmbedCode
 //________
 // Returns the embed code HTML fragment suitable for copy and paste
-br.getEmbedCode = function() {
-    return "<iframe src='" + this.getEmbedURL() + "' width='480px' height='430px'></iframe>";
+br.getEmbedCode = function(frameWidth, frameHeight, viewParams) {
+    return "<iframe src='" + this.getEmbedURL(viewParams) + "' width='" + frameWidth + "' height='" + frameHeight + "' frameborder='0' ></iframe>";
 }
 
 // getOpenLibraryRecord
 br.getOpenLibraryRecord = function(callback) {
     // Try looking up by ocaid first, then by source_record
     
-    var jsonURL = 'http://openlibrary.org/query.json?type=/type/edition&*=&ocaid=' + br.bookId;
+    var self = this; // closure
+    
+    var jsonURL = self.olHost + '/query.json?type=/type/edition&*=&ocaid=' + self.bookId;
     $.ajax({
         url: jsonURL,
         success: function(data) {
             if (data && data.length > 0) {
-                callback(br, data[0]);
+                callback(self, data[0]);
             } else {
                 // try sourceid
-                jsonURL = 'http://openlibrary.org/query.json?type=/type/edition&*=&source_records=ia:' + br.bookId;
+                jsonURL = self.olHost + '/query.json?type=/type/edition&*=&source_records=ia:' + self.bookId;
                 $.ajax({
                     url: jsonURL,
                     success: function(data) {
                         if (data && data.length > 0) {
-                            callback(br, data[0]);
+                            callback(self, data[0]);
                         }
                     },
                     dataType: 'jsonp'
@@ -366,11 +406,15 @@ br.buildInfoDiv = function(jInfoDiv) {
 
     var escapedTitle = BookReader.util.escapeHTML(this.bookTitle);
     var domainRe = /(\w+\.(com|org))/;
-    var domain = domainRe.exec(this.bookUrl)[1];
-        
+    var domainMatch = domainRe.exec(this.bookUrl);
+    var domain = this.bookUrl;
+    if (domainMatch) {
+        domain = domainMatch[1];
+    }
+       
     // $$$ cover looks weird before it loads
     jInfoDiv.find('.BRfloatCover').append([
-                    '<a href="', this.bookUrl, '"><img src="http://www.archive.org/download/', this.bookId, '/page/cover_t.jpg" alt="', escapedTitle, '" height="140" /></a>'].join('')
+                    '<div style="height: 140px; min-width: 80px; padding: 0; margin: 0;"><a href="', this.bookUrl, '"><img src="http://www.archive.org/download/', this.bookId, '/page/cover_t.jpg" alt="' + escapedTitle + '" height="140px" /></a></div>'].join('')
     );
 
     jInfoDiv.find('.BRfloatMeta').append([
@@ -385,8 +429,7 @@ br.buildInfoDiv = function(jInfoDiv) {
                         '<li><a href="http://www.archive.org/download/', this.bookId, '/', this.subPrefix, '_djvu.txt">Plain Text</a><span>|</span></li>',
                         '<li><a href="http://www.archive.org/download/', this.bookId, '/', this.subPrefix, '_daisy.zip">DAISY</a><span>|</span></li>',
                         '<li><a href="http://www.archive.org/download/', this.bookId, '/', this.subPrefix, '.epub">ePub</a><span>|</span></li>',
-                        '<li><a href="https://www.amazon.com/gp/digital/fiona/web-to-kindle?clientid=IA&itemid=', this.bookId, '&docid=', this.subPrefix, '">Send to Kindle</a><span>|</span></li>',
-                        '<li><a href="', this.bookUrl, '">More...</a></li>',
+                        '<li><a href="https://www.amazon.com/gp/digital/fiona/web-to-kindle?clientid=IA&itemid=', this.bookId, '&docid=', this.subPrefix, '">Send to Kindle</a></li>',
                     '</ul>',
                     '<p class="moreInfo"><span></span>More information on <a href="'+ this.bookUrl + '">' + domain + '</a>  </p>'].join('\n'));
                     
@@ -402,6 +445,8 @@ br.buildInfoDiv = function(jInfoDiv) {
     }
     
     jInfoDiv.find('.BRfloatTitle a').attr({'href': this.bookUrl, 'alt': this.bookTitle}).text(this.bookTitle);
+    var bookPath = (window.location + '').replace('#','%23');
+    jInfoDiv.find('a.problem').attr('href','http://openlibrary.org/contact?path=' + bookPath);
 
 }
 
@@ -486,18 +531,27 @@ if ('' != $metaData->{'page-progression'}) {
 }
 
 $useOLAuth = false;
+$protected = false;
 foreach ($metaData->xpath('//collection') as $collection) {
     if('browserlending' == $collection) {
         $useOLAuth = true;
+        $protected = true;
     }
 }
 
+echo "br.olHost = 'http://openlibrary.org'\n";
+#echo "br.olHost = 'http://ol-mang:8080'\n";
+
 if ($useOLAuth) {
     echo "br.olAuth = true;\n";
 } else {
     echo "br.olAuth = false;\n";
 }
 
+if ($protected) {
+    echo "br.protected = true;\n";
+}
+
 # Special cases
 if ('bandersnatchhsye00scarrich' == $id) {
     echo "br.mode     = 2;\n";
@@ -519,74 +573,109 @@ if (typeof(brConfig) != 'undefined') {
             br.reduce = brConfig['reduce'];
         }
     } else if (brConfig['mode'] == 2) {
-        br.mode = 2;
-      
-<?
-        //$$$mang hack to override request for 2up for books with attribution page
-        //   as first page until we can display that page in 2up
-        $needle = 'goog';
-        if (strrpos($id, $needle) === strlen($id)-strlen($needle)) {
-            print "// override for books with attribution page\n";
-            print "br.mode = 1;\n";
-        }
-?>
+        br.mode = 2;      
+    }
+    
+    if (typeof(brConfig["isAdmin"]) != 'undefined') {
+        br.isAdmin = brConfig["isAdmin"];
+    } else {
+        br.isAdmin = false;
     }
 } // brConfig
 
 
 function OLAuth() {
-    this.authUrl = 'http://openlibrary.org/ia_auth/' + br.bookId;
+    this.authUrl = br.olHost + '/ia_auth/' + br.bookId;
     this.olConnect = false;
+    this.loanUUID = false;
+    this.permsToken = false;
+    
+    var cookieRe = /;\s*/;
+    var cookies = document.cookie.split(cookieRe);
+    var length = cookies.length;
+    var i;
+    for (i=0; i<length; i++) {
+        if (0 == cookies[i].indexOf('br-loan-' + br.bookId)) {
+            this.loanUUID = cookies[i].split('=')[1];
+        }
+        if (0 == cookies[i].indexOf('loan-' + br.bookId)) {
+            this.permsToken = cookies[i].split('=')[1];
+        }
+    }
+
     return this;
 }
 
 OLAuth.prototype.init = function() {
-    var htmlStr =  '<p style="text-align:center;"><b>Authenticating in-browser loan with openlibrary.org!</b></p>';
-    htmlStr    +=  '<p>Please wait...</p>';
+    var htmlStr =  'Checking loan status with Open Library';
 
-    this.showPopup("#ddd", "#000", htmlStr);
-    $.ajax({url:this.authUrl, dataType:'jsonp', jsonpCallback:'olAuth.initCallback'});
+    this.showPopup("#F0EEE2", "#000", htmlStr, 'Please wait as we check the status of this book...');
+    var authUrl = this.authUrl+'?rand='+Math.random();
+    if (false !== this.loanUUID) {
+        authUrl += '&loan='+this.loanUUID
+    }
+    if (false !== this.permsToken) {
+        authUrl += '&token='+this.permsToken
+    }
+    $.ajax({url:authUrl, dataType:'jsonp', jsonpCallback:'olAuth.initCallback'});
 }
 
-OLAuth.prototype.showPopup = function(bgColor, textColor, msg) {
+OLAuth.prototype.showPopup = function(bgColor, textColor, msg, resolution) {
     this.popup = document.createElement("div");
     $(this.popup).css({
         position: 'absolute',
-        top:      '20px',
+        top:      '50px',
         left:     ($('#BookReader').attr('clientWidth')-400)/2 + 'px',
         width:    '400px',
-        padding:  "20px",
+        padding:  "15px",
         border:   "3px double #999999",
         zIndex:   3,
+        textAlign: 'center',
         backgroundColor: bgColor,
         color: textColor
     }).appendTo('#BookReader');
 
-    this.popup.innerHTML = msg;
+    this.setPopupMsg(msg, resolution);
+
+}
+
+OLAuth.prototype.setPopupMsg = function(msg, resolution) {
+    this.popup.innerHTML = ['<p><strong>', msg, '</strong></p><p>', resolution, '</p>'].join('\n');
+}
+
+OLAuth.prototype.showError = function(msg, resolution) {
+   $(this.popup).css({
+        backgroundColor: "#fff",
+        color: "#000"
+    });
 
+    this.setPopupMsg(msg, resolution);
 }
 
 OLAuth.prototype.initCallback = function(obj) {
     if (false == obj.success) {
-        $(this.popup).css({
-            backgroundColor: "#f00",
-            color: "#fff"
-        });
-
-        this.popup.innerHTML = obj.msg;
-        return;
+        if (br.isAdmin) {
+            ret = confirm("We couldn't authenticate your loan with Open Library, but since you are an administrator or uploader of this book, you can access this book for QA purposes. Would you like to QA this book?");
+            if (!ret) {
+                this.showError(obj.msg, obj.resolution)
+            } else {
+                br.init();
+            }
+        } else {
+            this.showError(obj.msg, obj.resolution)
+        }       
+    } else {    
+        //user is authenticated
+        this.setCookie(obj.token);
+        this.olConnect = true;
+        this.startPolling();    
+        br.init();
     }
-    
-    //user is authenticated
-    this.setCookie(obj.token);
-    this.olConnect = true;
-    this.startPolling();    
-    br.init();
 }
 
 OLAuth.prototype.callback = function(obj) {
     if (false == obj.success) {
-        this.showPopup("#f00", "#fff", obj.msg);
+        this.showPopup("#F0EEE2", "#000", obj.msg, obj.resolution);
         clearInterval(this.poller);
         this.ttsPoller = null;
     } else {
@@ -597,27 +686,59 @@ OLAuth.prototype.callback = function(obj) {
 
 OLAuth.prototype.setCookie = function(value) {
     var date = new Date();
-    date.setTime(date.getTime()+(24*60*60*1000));  //one day expiry
+    date.setTime(date.getTime()+(10*60*1000));  //10 min expiry
     var expiry = date.toGMTString();
     var cookie = 'loan-'+br.bookId+'='+value;
     cookie    += '; expires='+expiry;
     cookie    += '; path=/; domain=.archive.org;';
-    document.cookie = cookie; 
+    document.cookie = cookie;
+    this.permsToken = value;
+    
+    //refresh the br-loan uuid cookie with current expiry, if needed
+    if (false !== this.loanUUID) {
+        cookie = 'br-loan-'+br.bookId+'='+this.loanUUID;
+        cookie    += '; expires='+expiry;
+        cookie    += '; path=/; domain=.archive.org;';
+        document.cookie = cookie;
+    }
+}
+
+OLAuth.prototype.deleteCookies = function() {
+    var date = new Date();
+    date.setTime(date.getTime()-(24*60*60*1000));  //one day ago
+    var expiry = date.toGMTString();
+    var cookie = 'loan-'+br.bookId+'=""';
+    cookie    += '; expires='+expiry;
+    cookie    += '; path=/; domain=.archive.org;';
+    document.cookie = cookie;
+    
+    cookie = 'br-loan-'+br.bookId+'=""';
+    cookie    += '; expires='+expiry;
+    cookie    += '; path=/; domain=.archive.org;';
+    document.cookie = cookie;
 }
 
 OLAuth.prototype.startPolling = function () {    
     var self = this;
     this.poller=setInterval(function(){
         if (!self.olConnect) {
-          self.showPopup("#f00", "#fff", 'Cound not connect to Open Library for authentication. Please check to see if you are still connected to the Internet, and then reload this web page.');
+          self.showPopup("#F0EEE2", "#000", 'Connection error', 'The BookReader cannot reach Open Library. This might mean that you are offline or that Open Library is down. Please check your Internet connection and refresh this page or try again later.');
           clearInterval(self.poller);
           self.ttsPoller = null;        
         } else {
           self.olConnect = false;
           //be sure to add random param to authUrl to avoid stale cache
-          $.ajax({url:self.authUrl+'?rand='+Math.random(), dataType:'jsonp', jsonpCallback:'olAuth.callback'});
+          var authUrl = self.authUrl+'?rand='+Math.random();
+          if (false !== self.loanUUID) {
+              authUrl += '&loan='+self.loanUUID
+          }
+          if (false !== self.permsToken) {
+              authUrl += '&token='+self.permsToken
+          }
+
+          $.ajax({url:authUrl, dataType:'jsonp', jsonpCallback:'olAuth.callback'});
         }
-    },300000);   
+    },300000);   //five minute interval
 }
 
 br.cleanupMetadata();
@@ -631,8 +752,34 @@ if (br.olAuth) {
 
 
 function BRFatal($string) {
-    // $$$ TODO log error
-    echo "alert('$string')\n";
+    // log error
+    ?>
+    
+    if (typeof(archive_analytics) != 'undefined') {
+        var values = {
+            'bookreader': 'fatal',
+            'description': "<? echo $string; ?>",
+            'itemid': "<? echo $_REQUEST['id']; ?>",
+            'server': "<? echo $_REQUEST['server']; ?>",
+            'request_uri': "<? echo $_SERVER["REQUEST_URI"]; ?>"
+        }
+        
+        if (document.referrer == '') {
+            values['referrer'] = '-';
+        } else {
+            values['referrer'] = document.referrer;
+        }
+        
+        var qs = archive_analytics.format_bug(values);
+
+        var error_img = new Image(100,25);
+        error_img.src = archive_analytics.img_src + "?" + qs;
+    }
+
+    alert("<? echo $string;?>");
+    
+    <?
+    
     die(-1);
 }