Display of first/last page in 2up. WIP.
[bookreader.git] / GnuBookIA / datanode / GnuBookJSIA.php
index 17ccaf0..7f5030e 100755 (executable)
@@ -20,7 +20,22 @@ This file is part of GnuBook.
 
 $id = $_REQUEST['id'];
 $itemPath = $_REQUEST['itemPath'];
-$server = $_REQUEST['server']; 
+$subPrefix = $_REQUEST['subPrefix'];
+$server = $_REQUEST['server'];
+
+// Check if we're on a dev vhost and point to JSIA in the user's public_html on the datanode
+// $$$ TODO consolidate this logic
+if (strpos($_SERVER["REQUEST_URI"], "/~mang") === 0) { // Serving out of home dir
+    $server .= ':80/~mang';
+} else if (strpos($_SERVER["REQUEST_URI"], "/~testflip") === 0) { // Serving out of home dir
+    $server .= ':80/~testflip';
+}
+
+if ($subPrefix) {
+    $subItemPath = $itemPath . '/' . $subPrefix;
+} else {
+    $subItemPath = $itemPath . '/' . $id;
+}
 
 if ("" == $id) {
     GBFatal("No identifier specified!");
@@ -34,17 +49,19 @@ if ("" == $server) {
     GBFatal("No server specified!");
 }
 
-
 if (!preg_match("|^/[0-3]/items/{$id}$|", $itemPath)) {
     GBFatal("Bad id!");
 }
 
+// XXX check here that subitem is okay
+
 $imageFormat = 'unknown';
-$zipFile = "$itemPath/{$id}_jp2.zip";
+$zipFile = "${subItemPath}_jp2.zip";
+
 if (file_exists($zipFile)) {
     $imageFormat = 'jp2';
 } else {
-  $zipFile = "$itemPath/${id}_tif.zip";
+  $zipFile = "${subItemPath}_tif.zip";
   if (file_exists($zipFile)) {
     $imageFormat = 'tif';
   }
@@ -54,7 +71,7 @@ if ("unknown" == $imageFormat) {
   GBfatal("Unknown image format");
 }
 
-$scanDataFile = "$itemPath/{$id}_scandata.xml";
+$scanDataFile = "${subItemPath}_scandata.xml";
 $scanDataZip  = "$itemPath/scandata.zip";
 if (file_exists($scanDataFile)) {
     $scanData = simplexml_load_file($scanDataFile);
@@ -85,46 +102,140 @@ $metaData = simplexml_load_file($metaDataFile);
 
 gb = new GnuBook();
 
+<?
+/* Output title leaf if marked */
+$titleLeaf = '';
+foreach ($scanData->pageData->page as $page) {
+    if (("Title Page" == $page->pageType) || ("Title" == $page->pageType)) {
+        $titleLeaf = "{$page['leafNum']}";
+        break;
+    }
+}
+    
+if ('' != $titleLeaf) {
+    printf("gb.titleLeaf = %d;\n", $titleLeaf);
+}
+?>
+
 gb.getPageWidth = function(index) {
     //return parseInt(this.pageW[index]/this.reduce);
+    
+    // XXX
+    if (index < 0) { // Synthesize
+        return this.pageW[0];
+    } else if (index >= this.numLeafs) {
+        return this.pageW[this.numLeafs - 1];
+    }
+    
     return this.pageW[index];
 }
 
 gb.getPageHeight = function(index) {
     //return parseInt(this.pageH[index]/this.reduce);
+
+    // XXX
+    if (index < 0) { // Synthesize
+        return this.pageH[0];
+    } else if (index >= gb.numLeafs) {
+        return this.pageH[gb.numLeafs - 1];
+    }
+    
     return this.pageH[index];
 }
 
-gb.getPageURI = function(index) {
-    var leafStr = '0000';            
-    var imgStr = this.leafMap[index].toString();
-    var re = new RegExp("0{"+imgStr.length+"}$");
+// Returns true if page image is available rotated
+gb.canRotatePage = function(index) {
+    return 'jp2' == this.imageFormat; // Assume single format for now
+}
+
+// reduce defaults to 1 (no reduction)
+// rotate defaults to 0 (no rotation)
+gb.getPageURI = function(index, reduce, rotate) {
+
+    // XXX
+    if (index < 0 || index >= this.numLeafs) { // Synthesize page
+        return "/bookreader/images/transparent.png";
+    }
+
+    var _reduce;
+    var _rotate;
 
+    if ('undefined' == typeof(reduce)) {
+        _reduce = 1;
+    } else {
+        _reduce = reduce;
+    }
+    if ('undefined' == typeof(rotate)) {
+        _rotate = 0;
+    } else {
+        _rotate = rotate;
+    }
+    
+    var file = this._getPageFile(index);
+        
+    // $$$ add more image stack formats here
     if (1==this.mode) {
-        var url = 'http://'+this.server+'/GnuBook/GnuBookImages.php?zip='+this.zip+'&file='+this.bookId+'_'+this.imageFormat+'/'+this.bookId+'_'+leafStr.replace(re, imgStr) + '.'+this.imageFormat+'&scale='+this.reduce;
+        var url = 'http://'+this.server+'/GnuBook/GnuBookImages.php?zip='+this.zip+'&file='+file+'&scale='+_reduce+'&rotate='+_rotate;
     } else {
-        var ratio = this.getPageHeight(index) / this.twoPageH;
-        var scale;
-        // $$$ we make an assumption here that the scales are available pow2 (like kakadu)
-        if (ratio <= 2) {
-            scale = 1;
-        } else if (ratio <= 4) {
-            scale = 2;
-        } else {
-            scale = 4;
-        }        
+        if ('undefined' == typeof(reduce)) {
+            // reduce not passed in
+            var ratio = this.getPageHeight(index) / this.twoPage.height;
+            var scale;
+            // $$$ we make an assumption here that the scales are available pow2 (like kakadu)
+            if (ratio < 2) {
+                scale = 1;
+            } else if (ratio < 4) {
+                scale = 2;
+            } else if (ratio < 8) {
+                scale = 4;
+            } else if (ratio < 16) {
+                scale = 8;
+            } else  if (ratio < 32) {
+                scale = 16;
+            } else {
+                scale = 32;
+            }
+            _reduce = scale;
+        }
     
-        //var url = 'http://'+this.server+'/GnuBook/GnuBookImages.php?zip='+this.zip+'&file='+this.bookId+'_jp2/'+this.bookId+'_'+leafStr.replace(re, imgStr) + '.jp2&height='+this.twoPageH+'&origHeight='+this.getPageHeight(index);
-        var url = 'http://'+this.server+'/GnuBook/GnuBookImages.php?zip='+this.zip+'&file='+this.bookId+'_'+this.imageFormat+'/'+this.bookId+'_'+leafStr.replace(re, imgStr) + '.'+this.imageFormat+'&scale='+scale;
+        var url = 'http://'+this.server+'/GnuBook/GnuBookImages.php?zip='+this.zip+'&file='+file+'&scale='+_reduce+'&rotate='+_rotate;
         
     }
     return url;
 }
 
+gb._getPageFile = function(index) {
+    var leafStr = '0000';
+    var imgStr = this.leafMap[index].toString();
+    var re = new RegExp("0{"+imgStr.length+"}$");
+    
+    var insideZipPrefix = this.subPrefix.match('[^/]+$');
+    var file = insideZipPrefix + '_' + this.imageFormat + '/' + insideZipPrefix + '_' + leafStr.replace(re, imgStr) + '.' + this.imageFormat;
+    
+    return file;
+}
+
 gb.getPageSide = function(index) {
     //assume the book starts with a cover (right-hand leaf)
     //we should really get handside from scandata.xml
     
+    <? // Use special function if we should infer the page sides based off the title page index
+    if (preg_match('/goog$/', $id) && ('' != $titleLeaf)) {
+    ?>
+    // assume page side based on title pagex
+    var titleIndex = gb.leafNumToIndex(gb.titleLeaf);
+    // assume title page is RHS
+    var delta = titleIndex - index;
+    if (0 == (delta & 0x1)) {
+        // even delta
+        return 'R';
+    } else {
+        return 'L';
+    }
+    <?
+    }
+    ?>
+    
     // $$$ we should get this from scandata instead of assuming the accessible
     //     leafs are contiguous
     if ('rl' != this.pageProgression) {
@@ -147,7 +258,12 @@ gb.getPageSide = function(index) {
 }
 
 gb.getPageNum = function(index) {
-    return this.pageNums[index];
+    var pageNum = this.pageNums[index];
+    if (pageNum) {
+        return pageNum;
+    } else {
+        return 'n' + index;
+    }
 }
 
 gb.leafNumToIndex = function(leafNum) {
@@ -195,6 +311,47 @@ gb.getSpreadIndices = function(pindex) {
     return spreadIndices;
 }
 
+// Remove the page number assertions for all but the highest index page with
+// a given assertion.  Ensures there is only a single page "{pagenum}"
+// e.g. the last page asserted as page 5 retains that assertion.
+gb.uniquifyPageNums = function() {
+    var seen = {};
+    
+    for (var i = gb.pageNums.length - 1; i--; i >= 0) {
+        var pageNum = gb.pageNums[i];
+        if ( !seen[pageNum] ) {
+            seen[pageNum] = true;
+        } else {
+            gb.pageNums[i] = null;
+        }
+    }
+
+}
+
+gb.cleanupMetadata = function() {
+    gb.uniquifyPageNums();
+}
+
+// getEmbedURL
+//________
+// Returns a URL for an embedded version of the current book
+gb.getEmbedURL = function() {
+    // We could generate a URL hash fragment here but for now we just leave at defaults
+    var url = 'http://' + window.location.host + '/stream/'+this.bookId;
+    if (this.subPrefix != this.bookId) { // Only include if needed
+        url += '/' + this.subPrefix;
+    }
+    url += '?ui=embed';
+    return url;
+}
+
+// getEmbedCode
+//________
+// Returns the embed code HTML fragment suitable for copy and paste
+gb.getEmbedCode = function() {
+    return "<iframe src='" + this.getEmbedURL() + "' width='480px' height='430px'></iframe>";
+}
+
 gb.pageW =             [
             <?
             $i=0;
@@ -252,30 +409,18 @@ gb.pageNums = [
             ?>    
             ];
             
-<?
-/* Output title leaf if marked */
-$titleLeaf = '';
-foreach ($scanData->pageData->page as $page) {
-    if (("Title Page" == $page->pageType) || ("Title" == $page->pageType)) {
-        $titleLeaf = "{$page['leafNum']}";
-        break;
-    }
-}
-    
-if ('' != $titleLeaf) {
-    printf("gb.titleLeaf = %d;\n", $titleLeaf);
-}
-?>
       
 gb.numLeafs = gb.pageW.length;
 
 gb.bookId   = '<?echo $id;?>';
 gb.zip      = '<?echo $zipFile;?>';
+gb.subPrefix = '<?echo $subPrefix;?>';
 gb.server   = '<?echo $server;?>';
 gb.bookTitle= '<?echo preg_replace("/\'/", "\\'", $metaData->title);?>';
-gb.bookPath = '<?echo $itemPath;?>';
+gb.bookPath = '<?echo $subItemPath;?>';
 gb.bookUrl  = '<?echo "http://www.archive.org/details/$id";?>';
 gb.imageFormat = '<?echo $imageFormat;?>';
+
 <?
 
 # Load some values from meta.xml
@@ -294,23 +439,34 @@ if ('bandersnatchhsye00scarrich' == $id) {
 
 ?>
 
-
 // Check for config object
+// $$$ change this to use the newer params object
 if (typeof(gbConfig) != 'undefined') {
+    if (typeof(gbConfig["ui"]) != 'undefined') {
+        gb.ui = gbConfig["ui"];
+    }
+
     if (gbConfig['mode'] == 1) {
-      gb.mode = 1;
+        gb.mode = 1;
+        if (typeof(gbConfig['reduce'] != 'undefined')) {
+            gb.reduce = gbConfig['reduce'];
+        }
     } else if (gbConfig['mode'] == 2) {
-      gb.mode = 2;
+        gb.mode = 2;
       
-      //$$$mang hack to override request for 2up for RTL until we have full RTL support
-      //        we need a better way to determine the mode and pass config options
-      //if ((typeof(gb.pageProgression) != 'undefined') && (gb.pageProgression == 'rl')) {
-      //  gb.mode = 1;
-      //}
-  
+<?
+        //$$$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 "gb.mode = 1;\n";
+        }
+?>
     }
-}
+} // gbConfig
 
+gb.cleanupMetadata();
 gb.init();
 
 <?
@@ -335,4 +491,4 @@ function shouldAddPage($page) {
     return true;
 }
 
-?>
\ No newline at end of file
+?>