Make book preview image permalinks work for books in item sub-dirs. More consistent...
authorMichael Ang <mang@archive.org>
Wed, 21 Jul 2010 02:48:51 +0000 (02:48 +0000)
committerMichael Ang <mang@archive.org>
Wed, 21 Jul 2010 02:48:51 +0000 (02:48 +0000)
BookReader/BookReader.js
BookReaderIA/datanode/BookReaderImages.inc.php
BookReaderIA/datanode/BookReaderMeta.inc.php
BookReaderIA/datanode/BookReaderPreview.php
BookReaderIA/inc/BookReader.inc

index d26ba40..5390e66 100644 (file)
@@ -2858,7 +2858,7 @@ BookReader.prototype.getPrintURI = function() {
         indexToPrint = this.firstIndex; // $$$ the index in the middle of the viewport would make more sense
     }
     
-    var options = 'id=' + this.bookId + '&server=' + this.server + '&zip=' + this.zip
+    var options = 'id=' + this.subPrefix + '&server=' + this.server + '&zip=' + this.zip
         + '&format=' + this.imageFormat + '&file=' + this._getPageFile(indexToPrint)
         + '&width=' + this._getPageWidth(indexToPrint) + '&height=' + this._getPageHeight(indexToPrint);
    
index a5db859..df50bdc 100644 (file)
@@ -89,7 +89,7 @@ class BookReaderImages
         }
 
         if ( !file_exists($zipPath) ) {
-            $this->BRfatal('Image stack does not exist');
+            $this->BRfatal('Image stack does not exist at ' . $zipPath);
         }
         // Make sure the image stack is readable - return 403 if not
         $this->checkPrivs($zipPath);
@@ -384,7 +384,7 @@ class BookReaderImages
                 $bits = intval($tags["BitDepth"]);
                 break;
             default:
-                $this->BRfatal("Unsupported image type");
+                $this->BRfatal("Unsupported image type $type for file $file in $zipPath");
                 break;
         }
        
@@ -529,8 +529,6 @@ class BookReaderImages
     
     function BRfatal($string) {
         throw new Exception("Image error: $string");
-        //echo "alert('$string');\n";
-        //die(-1);
     }
     
     // Returns true if using a power node
index fcd1803..40c2b54 100644 (file)
@@ -43,14 +43,14 @@ class BookReaderMeta {
     );
 
     // Builds metadata object (to be encoded as JSON)
-    function buildMetadata($id, $itemPath, $bookId, $server) {
+    function buildMetadata($id, $itemPath, $subPrefix, $server) {
     
         $response = array();
         
-        if (! $bookId) {
-            $bookId = $id;
+        if (! $subPrefix) {
+            $subPrefix = $id;
         }
-        $subItemPath = $itemPath . '/' . $bookId;
+        $subItemPath = $itemPath . '/' . $subPrefix;
         
         if ("" == $id) {
             $this->BRFatal("No identifier specified!");
@@ -78,7 +78,7 @@ class BookReaderMeta {
             $this->BRfatal("File metadata not found!");
         }
         
-        $imageStackInfo = $this->findImageStack($bookId, $filesData);
+        $imageStackInfo = $this->findImageStack($subPrefix, $filesData);
         if ($imageStackInfo['imageFormat'] == 'unknown') {
             $this->BRfatal('Couldn\'t find image stack');
         }
@@ -187,7 +187,7 @@ class BookReaderMeta {
         
         // Internet Archive specific
         $response['itemId'] = $id; // $$$ renamed
-        $response['bookId'] = $bookId;  // $$$ renamed
+        $response['subPrefix'] = $subPrefix;  // $$$ renamed
         $response['itemPath'] = $itemPath;
         $response['zip'] = $imageStackFile;
         $response['server'] = $server;
@@ -286,7 +286,7 @@ class BookReaderMeta {
                 }
             }
         }
-        
+                
         return array('imageFormat' => 'unknown', 'archiveFormat' => 'unknown', 'imageStackFile' => 'unknown');    
     }
     
@@ -314,7 +314,7 @@ class BookReaderMeta {
         // e.g. http://ia311213.us.archive.org/BookReader/BookReaderImages.php?zip=/0/items/coloritsapplicat00andriala/coloritsapplicat00andriala_jp2.zip&file=coloritsapplicat00andriala_jp2/coloritsapplicat00andriala_0009.jp2&scale=8&rotate=0
         
     
-        $filePath = $this->imageFilePath($leafNum, $metadata['bookId'], $metadata['imageFormat']);
+        $filePath = $this->imageFilePath($leafNum, $metadata['subPrefix'], $metadata['imageFormat']);
         $url = 'http://' . $metadata['server'] . '/BookReader/BookReaderImages.php?zip=' . $metadata['zip'] . '&file=' . $filePath;
         
         if ($scale !== null) {
@@ -331,7 +331,7 @@ class BookReaderMeta {
     function previewURL($page, $metadata) {
         $query = array(
             'id' => $metadata['itemId'],
-            'bookId' => $metadata['bookId'],
+            'subPrefix' => $metadata['subPrefix'],
             'itemPath' => $metadata['itemPath'],
             'server' => $metadata['server'],
             'page' => $page,
@@ -340,8 +340,10 @@ class BookReaderMeta {
         return 'http://' . $metadata['server'] . '/BookReader/BookReaderPreview.php?' . http_build_query($query, '', '&');
     }
     
-    function imageFilePath($leafNum, $bookId, $format) {
-        return sprintf("%s_%s/%s_%04d.%s", $bookId, $format, $bookId, intval($leafNum), $format);
+    function imageFilePath($leafNum, $subPrefix, $format) {
+        $pathParts = pathinfo($subPrefix);
+        $almostIdentifier = $pathParts['filename'];
+        return sprintf("%s_%s/%s_%04d.%s", $almostIdentifier, $format, $almostIdentifier, intval($leafNum), $format);
     }
     
     // Parse date from _meta.xml to integer
@@ -356,7 +358,7 @@ class BookReaderMeta {
     function processRequest($requestEnv) {
         $id = $requestEnv['itemId']; // $$$ renamed
         $itemPath = $requestEnv['itemPath'];
-        $bookId = $requestEnv['bookId']; // $$$ renamed
+        $subPrefix = $requestEnv['subPrefix']; // $$$ renamed
         $server = $requestEnv['server'];
         
         // Check if we're on a dev vhost and point to JSIA in the user's public_html on the datanode
@@ -367,7 +369,7 @@ class BookReaderMeta {
             $server .= ':80/~testflip';
         }
         
-        $this->emitResponse( $this->buildMetadata($id, $itemPath, $bookId, $server) );
+        $this->emitResponse( $this->buildMetadata($id, $itemPath, $subPrefix, $server) );
     }
     
     function checkPrivs($filename) {
index 30b963f..dcb34be 100644 (file)
@@ -36,7 +36,7 @@ function BRfatal($message) {
 
 $brm = new BookReaderMeta();
 try {
-    $metadata = $brm->buildMetadata($_REQUEST['id'], $_REQUEST['itemPath'], $_REQUEST['bookId'], $_REQUEST['server']);
+    $metadata = $brm->buildMetadata($_REQUEST['id'], $_REQUEST['itemPath'], $_REQUEST['subPrefix'], $_REQUEST['server']);
 } catch (Exception $e) {
     BRfatal($e->getMessage);
 }
@@ -108,7 +108,7 @@ $leaf = $brm->leafForIndex($imageIndex, $metadata['leafNums']);
 
 $requestEnv = array(
     'zip' => $metadata['zip'],
-    'file' => $brm->imageFilePath($leaf, $metadata['bookId'], $metadata['imageFormat']),
+    'file' => $brm->imageFilePath($leaf, $metadata['subPrefix'], $metadata['imageFormat']),
     'ext' => 'jpg',
 );
 
index ae25c5c..9f775a8 100644 (file)
@@ -3,6 +3,9 @@
 class BookReader
 {
 
+  // Operators recognized in BookReader download URLs
+  public static $downloadOperators = array('page');
+
   // Returns true if can display the book in item with a given prefix (typically the item identifier)
   public static function canDisplay($item, $prefix, $checkOldScandata = false)
   {
@@ -232,37 +235,51 @@ class BookReader
     // $path should look like {itemId}/{operator}/{filename}
     // Other operators may be added
     
-    $parts = preg_split('#/#', $path, 3);
-    if (count($parts) != 3) {
-        return null;
+    $urlParts = BookReader::parsePath($path);
+    
+    // Check for non-handled cases
+    $required = array('identifier', 'operator', 'operand');
+    foreach ($required as $key) {
+        if (!array_key_exists($key, $urlParts)) {
+            return null;
+        }
     }
-    $identifier = $parts[0];
-    $operator = $parts[1];
-    $filename = $parts[2];
+    
+    $identifier = $urlParts['identifier'];
+    $operator = $urlParts['operator'];
+    $filename = $urlParts['operand'];
+    $subPrefix = $urlParts['subPrefix'];
     
     $serverBaseURL = BookReader::serverBaseURL($item->getServer());
-            
+    
+    // Baseline query params
+    $query = array(
+        'id' => $identifier,
+        'itemPath' => $item->getMainDir(),
+        'server' => $serverBaseURL
+    );
+    if ($subPrefix) {
+        $query['subPrefix'] = $subPrefix;
+    }
+    
     switch ($operator) {
         case 'page':
             // Find bookId and which page was requested
             $pathParts = pathinfo($filename);
             
-            // Look for preview request
-            if (preg_match('/^(.*)_(cover|title|preview)$/', $pathParts['filename'], $matches) === 0) {
+            // Look for old-style preview request
+            // $$$ currently ignoring file extension
+            if (preg_match('/^(.*)_(cover|title|preview)/', $filename, $matches) === 0) {
                 return null;
             }
-            $bookId = $matches[1];
             $page = $matches[2];
-            $query = array(
-                'id' => $identifier,
-                'bookId' => $bookId,
-                'itemPath' => $item->getMainDir(),
-                'server' => $serverBaseURL,
-                'page' => $page,
-            );
+            
+            $query['page'] = $page;
+            
             return 'http://' . $serverBaseURL . '/BookReader/BookReaderPreview.php?' . http_build_query($query, '', '&');
         
         default:
+            // Unknown operator
             return null;            
     }
       
@@ -300,6 +317,42 @@ class BookReader
       }
       return array();
   }
+  
+  public static function parsePath($path) {
+    // Parse the BookReader path and return the parts
+    // e.g. itemid/some/sub/dir/page/cover.jpg -> array( 'identifier' => 'itemid', 'subPrefix' => 'some/sub/dir',
+    //            'operator' => 'page', 'filename' => 'cover.jpg')
+    
+    $parts = array();
+    
+    // Pull off query
+    if (preg_match('#(.*?)(\?.*)#', $path, $matches) === 1) {
+        $parts['query'] = $matches[2];
+        $path = $matches[1];
+    }
+    
+    // Pull off identifier
+    if (preg_match('#[^/&?]+#', $path, $matches) === 0) {
+        // no match
+        return $parts;
+    }
+    $parts['identifier'] = $matches[0];
+    $path = substr($path, strlen($matches[0]));
+    
+    // Look for operators
+    // The sub-prefix can be arbitrary, so we match up until the first operator
+    $operators = '(' . join('|', self::$downloadOperators) . ')';
+    $pattern = '#/(?P<subPrefix>.*?)/(?P<operator>' . $operators . ')/(?P<operand>.*)#';
+    if (preg_match($pattern, $path, $matches) === 1) {
+        $parts['subPrefix'] = $matches['subPrefix'];
+        $parts['operator'] = $matches['operator'];
+        $parts['operand'] = $matches['operand'];
+    } else {
+        $parts['subPrefix'] = $path;
+    }
+    
+    return $parts;
+  }
     
 }