Better preview handling. Start of image options parsing. Test harness.
authorMichael Ang <mang@archive.org>
Fri, 23 Jul 2010 18:34:10 +0000 (18:34 +0000)
committerMichael Ang <mang@archive.org>
Fri, 23 Jul 2010 18:34:10 +0000 (18:34 +0000)
BookReaderIA/datanode/BookReaderImages.inc.php
BookReaderIA/datanode/BookReaderImages.php
BookReaderIA/datanode/BookReaderPreview.php
BookReaderIA/inc/BookReader.inc
BookReaderIA/test/BookReaderTest.php [new file with mode: 0644]

index df50bdc..b553f8f 100644 (file)
@@ -54,6 +54,102 @@ class BookReaderImages
     var $exiftool = '/petabox/sw/books/exiftool/exiftool';
     var $kduExpand = '/petabox/sw/bin/kdu_expand';
     
+    /*
+     * Serve an image request that requires looking up the book metadata
+     *
+     * Code path:
+     *   - Get book metadata
+     *   - Parse the requested page (e.g. cover_t.jpg, n5_r4.jpg) to determine which page type,
+     *       size and format (etc) is being requested
+     *   - Determine the leaf number corresponding to the page
+     *   - Determine scaling values
+     *   - Serve image request now that all information has been gathered
+     */
+
+    function serveLookupRequest($requestEnv) {
+        $brm = new BookReaderMeta();
+        try {
+            $metadata = $brm->buildMetadata($_REQUEST['id'], $_REQUEST['itemPath'], $_REQUEST['subPrefix'], $_REQUEST['server']);
+        } catch (Exception $e) {
+            $this->BRfatal($e->getMessage);
+        }
+        
+        $page = $_REQUEST['page'];
+
+        // Index of image to return
+        $imageIndex = null;
+
+        // XXX deal with subPrefix
+        $pageInfo = $this->parsePageRequest($page);
+
+        // Parse requested page for page type, size and format options
+        if (preg_match('#^([^_]+)#', $page, $matches) === 0) {
+            // Unrecognized page specifier
+            $this->BRfatal('Unrecognized page specifier');
+        }
+        $basePage = $matches[1];
+        
+        switch ($basePage) {
+            case 'title':
+                if (! array_key_exists('titleIndex', $metadata)) {
+                    $this->BRfatal("No title page asserted in book");
+                }
+                $imageIndex = $metadata['titleIndex'];
+                break;
+                
+            case 'cover':
+                if (! array_key_exists('coverIndices', $metadata)) {
+                    $this->BRfatal("No cover asserted in book");
+                }
+                $imageIndex = $metadata['coverIndices'][0]; // $$$ TODO add support for other covers
+                break;
+                
+            case 'preview':
+                // Preference is:
+                //   Cover page if book was published >= 1950
+                //   Title page
+                //   Cover page
+                //   Page 0
+                         
+                if ( array_key_exists('date', $metadata) && array_key_exists('coverIndices', $metadata) ) {
+                    if ($brm->parseYear($metadata['date']) >= 1950) {
+                        $imageIndex = $metadata['coverIndices'][0];                
+                        break;
+                    }
+                }
+                if (array_key_exists('titleIndex', $metadata)) {
+                    $imageIndex = $metadata['titleIndex'];
+                    break;
+                }
+                if (array_key_exists('coverIndices', $metadata)) {
+                    $imageIndex = $metadata['coverIndices'][0];
+                    break;
+                }
+                
+                // First page
+                $imageIndex = 0;
+                break;
+                
+            default:
+                // Shouldn't be possible
+                $this->BRfatal("Couldn't find page");
+                break;
+                
+        }
+        
+        $leaf = $brm->leafForIndex($imageIndex, $metadata['leafNums']);
+        
+        $requestEnv = array(
+            'zip' => $metadata['zip'],
+            'file' => $brm->imageFilePath($leaf, $metadata['subPrefix'], $metadata['imageFormat']),
+            'ext' => 'jpg',
+        );
+
+        // Return image data - will check privs        
+        $this->serveRequest($requestEnv);
+    
+    }
+    
     /*
      * Returns a page image when all parameters such as the image stack location are
      * passed in.
@@ -590,6 +686,88 @@ class BookReaderImages
         return strlen($binStr) - 1;
     }
     
+    /*
+     * Parses a page request like "page5_r2.jpg" or "cover_t.jpg" to corresponding
+     * page type, size, reduce, and format
+     */
+    function parsePageRequest($pageRequest, $bookPrefix) {
+    
+        $pageInfo = array();
+        
+        // Pull off extension
+        if (preg_match('#(.*)\.([^.]+)$#', $pageRequest, $matches) === 1) {
+            $pageRequest = $matches[1];
+            $extension = $matches[2];
+            if ($extension == 'jpeg') {
+                $extension = 'jpg';
+            }
+        } else {
+            $extension = 'jpg';
+        }
+        $pageInfo['extension'] = $extension;
+        
+        // Split parts out
+        $parts = explode('_', $pageRequest);
+
+        // Remove book prefix if it was included (historical)
+        if ($parts[0] == $bookPrefix) {
+            array_shift($parts);
+        }
+        
+        if (count($parts) === 0) {
+            $this->BRfatal('No page type specified');
+        }
+        $page = array_shift($parts);
+        
+        $pageTypes = array(
+            'page' => 'str',
+            'n' => 'num',
+            'cover' => 'single',
+            'preview' => 'single',
+            'title' => 'single'
+        );
+        
+        // Look for known page types
+        foreach ( $pageTypes as $pageName => $kind ) {
+            if ( preg_match('#^(' . $pageName . ')(.*)#', $page, $matches) === 1 ) {
+                $pageInfo['type'] = $matches[1];
+                switch ($kind) {
+                    case 'str':
+                        $pageInfo['value'] = $matches[2];
+                        break;
+                    case 'num':
+                        $pageInfo['value'] = intval($matches[2]);
+                        break;
+                    case 'single':
+                        break;
+                }
+            }
+        }
+        
+        if ( !array_key_exists('type', $pageInfo) ) {
+            $this->BRfatal('Unrecognized page type');
+        }
+        
+        // Look for other known parts
+        foreach ($parts as $part) {
+            $start = substr($part, 0, 1);
+            
+            switch ($start) {
+                case 't':
+                    $pageInfo['size'] = $start;
+                    break;
+                case 'r':
+                    $pageInfo['reduce'] = substr($part, 0);
+                    break;
+                default:
+                    // Unrecognized... just let it pass
+                    break;
+            }
+        }
+        
+        return $pageInfo;
+    }
+    
 }
 
 ?>
\ No newline at end of file
index a3d2517..f3b8da7 100644 (file)
@@ -41,5 +41,4 @@ try {
     echo $e->getTraceAsString();
 }
 
-?>
-
+?>
\ No newline at end of file
index dcb34be..4192fb8 100644 (file)
@@ -41,6 +41,7 @@ try {
     BRfatal($e->getMessage);
 }
 
+// $$$ allow size information
 $knownPages = array('title','cover','preview');
 $page = $_REQUEST['page'];
 if (! in_array($page, $knownPages) ) {
index 9f775a8..8d8934f 100644 (file)
@@ -264,19 +264,19 @@ class BookReader
     
     switch ($operator) {
         case 'page':
-            // Find bookId and which page was requested
-            $pathParts = pathinfo($filename);
             
             // Look for old-style preview request
             // $$$ currently ignoring file extension
-            if (preg_match('/^(.*)_(cover|title|preview)/', $filename, $matches) === 0) {
-                return null;
+            if (preg_match('/^(.*)_(cover|title|preview)/', $filename, $matches) === 1) {
+                // Serve preview image
+                $page = $matches[2];
+                $query['page'] = $page;
+                return 'http://' . $serverBaseURL . '/BookReader/BookReaderPreview.php?' . http_build_query($query, '', '&');
             }
-            $page = $matches[2];
             
-            $query['page'] = $page;
-            
-            return 'http://' . $serverBaseURL . '/BookReader/BookReaderPreview.php?' . http_build_query($query, '', '&');
+            // Asking for a non-preview page
+            $query['page'] = $filename;
+            return 'http://' . $serverBaseURL . '/BookReader/BookReaderImages.php?' . http_build_query($query, '', '&');
         
         default:
             // Unknown operator
diff --git a/BookReaderIA/test/BookReaderTest.php b/BookReaderIA/test/BookReaderTest.php
new file mode 100644 (file)
index 0000000..5f6b302
--- /dev/null
@@ -0,0 +1,60 @@
+<?php
+
+/*
+Copyright(c) 2010 Internet Archive. Software license AGPL version 3.
+
+This file is part of BookReader.  The full source code can be found at GitHub:
+http://github.com/openlibrary/bookreader
+
+Author:
+  Michael Ang <http://github.com/mangtronix>
+
+    BookReader is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BookReader is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with BookReader.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+require_once('../datanode/BookReaderImages.inc.php');
+
+try {
+    switch ($_REQUEST['test']) {
+        case 'pageparse':
+            $bri = new BookReaderImages();
+            ok('text/javascript');
+            print( json_encode($bri->parsePageRequest($_REQUEST['value'], $_REQUEST['bookPrefix'])) );
+            break;
+            
+        default:
+            ok('text/html');
+            print "<html><head><title>BookReader Tests</title></head>";
+            print "<body>";
+            print "<h1>Available tests</h1>";
+            print "<pre>";
+            print "<a href='BookReaderTest.php?test=pageparse&value=cover_r4.jpg'>pageparse</a> value bookPrefix";
+            print "</body>";
+            print "</html>";
+            break;
+    }
+    
+} catch (Exception $e) {
+    print "Error serving request:\n";
+    print "  " . $e->getMessage() . "\n\n";
+    print "Debugging information:\n";
+    echo $e->getTraceAsString();
+}
+
+function ok($type) {
+    header('HTTP/1.0 200 OK');
+    header('Content-type: ' . $type);
+}
+
+?>
\ No newline at end of file