Add X-Content-Dimensions support to DjVu
Bug: T150741 Change-Id: I4a3bae9bf056a7ba332f2f0a330697cdf59b4d04
This commit is contained in:
parent
1fdc4c6f53
commit
4511f6fa9f
1 changed files with 89 additions and 30 deletions
|
|
@ -304,11 +304,28 @@ class DjVuHandler extends ImageHandler {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$trees = $this->extractTreesFromMetadata( $metadata );
|
||||||
|
$image->djvuTextTree = $trees['TextTree'];
|
||||||
|
$image->dejaMetaTree = $trees['MetaTree'];
|
||||||
|
|
||||||
|
if ( $gettext ) {
|
||||||
|
return $image->djvuTextTree;
|
||||||
|
} else {
|
||||||
|
return $image->dejaMetaTree;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts metadata and text trees from metadata XML in string form
|
||||||
|
* @param string $metadata XML metadata as a string
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function extractTreesFromMetadata( $metadata ) {
|
||||||
MediaWiki\suppressWarnings();
|
MediaWiki\suppressWarnings();
|
||||||
try {
|
try {
|
||||||
// Set to false rather than null to avoid further attempts
|
// Set to false rather than null to avoid further attempts
|
||||||
$image->dejaMetaTree = false;
|
$metaTree = false;
|
||||||
$image->djvuTextTree = false;
|
$textTree = false;
|
||||||
$tree = new SimpleXMLElement( $metadata, LIBXML_PARSEHUGE );
|
$tree = new SimpleXMLElement( $metadata, LIBXML_PARSEHUGE );
|
||||||
if ( $tree->getName() == 'mw-djvu' ) {
|
if ( $tree->getName() == 'mw-djvu' ) {
|
||||||
/** @var SimpleXMLElement $b */
|
/** @var SimpleXMLElement $b */
|
||||||
|
|
@ -316,23 +333,20 @@ class DjVuHandler extends ImageHandler {
|
||||||
if ( $b->getName() == 'DjVuTxt' ) {
|
if ( $b->getName() == 'DjVuTxt' ) {
|
||||||
// @todo File::djvuTextTree and File::dejaMetaTree are declared
|
// @todo File::djvuTextTree and File::dejaMetaTree are declared
|
||||||
// dynamically. Add a public File::$data to facilitate this?
|
// dynamically. Add a public File::$data to facilitate this?
|
||||||
$image->djvuTextTree = $b;
|
$textTree = $b;
|
||||||
} elseif ( $b->getName() == 'DjVuXML' ) {
|
} elseif ( $b->getName() == 'DjVuXML' ) {
|
||||||
$image->dejaMetaTree = $b;
|
$metaTree = $b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$image->dejaMetaTree = $tree;
|
$metaTree = $tree;
|
||||||
}
|
}
|
||||||
} catch ( Exception $e ) {
|
} catch ( Exception $e ) {
|
||||||
wfDebug( "Bogus multipage XML metadata on '{$image->getName()}'\n" );
|
wfDebug( "Bogus multipage XML metadata\n" );
|
||||||
}
|
}
|
||||||
MediaWiki\restoreWarnings();
|
MediaWiki\restoreWarnings();
|
||||||
if ( $gettext ) {
|
|
||||||
return $image->djvuTextTree;
|
return [ 'MetaTree' => $metaTree, 'TextTree' => $textTree ];
|
||||||
} else {
|
|
||||||
return $image->dejaMetaTree;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getImageSize( $image, $path ) {
|
function getImageSize( $image, $path ) {
|
||||||
|
|
@ -394,14 +408,26 @@ class DjVuHandler extends ImageHandler {
|
||||||
$cache::TTL_INDEFINITE,
|
$cache::TTL_INDEFINITE,
|
||||||
function () use ( $file ) {
|
function () use ( $file ) {
|
||||||
$tree = $this->getMetaTree( $file );
|
$tree = $this->getMetaTree( $file );
|
||||||
if ( !$tree ) {
|
return $this->getDimensionInfoFromMetaTree( $tree );
|
||||||
|
},
|
||||||
|
[ 'pcTTL' => $cache::TTL_INDEFINITE ]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an XML metadata tree, returns dimension information about the document
|
||||||
|
* @param bool|SimpleXMLElement $metatree The file's XML metadata tree
|
||||||
|
* @return bool|array
|
||||||
|
*/
|
||||||
|
protected function getDimensionInfoFromMetaTree( $metatree ) {
|
||||||
|
if ( !$metatree ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$dimsByPage = [];
|
$dimsByPage = [];
|
||||||
$count = count( $tree->xpath( '//OBJECT' ) );
|
$count = count( $metatree->xpath( '//OBJECT' ) );
|
||||||
for ( $i = 0; $i < $count; $i++ ) {
|
for ( $i = 0; $i < $count; $i++ ) {
|
||||||
$o = $tree->BODY[0]->OBJECT[$i];
|
$o = $metatree->BODY[0]->OBJECT[$i];
|
||||||
if ( $o ) {
|
if ( $o ) {
|
||||||
$dimsByPage[$i] = [
|
$dimsByPage[$i] = [
|
||||||
'width' => (int)$o['width'],
|
'width' => (int)$o['width'],
|
||||||
|
|
@ -413,9 +439,6 @@ class DjVuHandler extends ImageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
return [ 'pageCount' => $count, 'dimensionsByPage' => $dimsByPage ];
|
return [ 'pageCount' => $count, 'dimensionsByPage' => $dimsByPage ];
|
||||||
},
|
|
||||||
[ 'pcTTL' => $cache::TTL_INDEFINITE ]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -438,4 +461,40 @@ class DjVuHandler extends ImageHandler {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get useful response headers for GET/HEAD requests for a file with the given metadata
|
||||||
|
* @param $metadata Array Contains this handler's unserialized getMetadata() for a file
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getContentHeaders( $metadata ) {
|
||||||
|
if ( !is_array( $metadata ) || !isset( $metadata['xml'] ) ) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$trees = $this->extractTreesFromMetadata( $metadata['xml'] );
|
||||||
|
$dimensionInfo = $this->getDimensionInfoFromMetaTree( $trees['MetaTree'] );
|
||||||
|
|
||||||
|
if ( !$dimensionInfo ) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$pagesByDimensions = [];
|
||||||
|
$count = $dimensionInfo['pageCount'];
|
||||||
|
|
||||||
|
for ( $i = 1; $i <= $count; $i++ ) {
|
||||||
|
$dimensions = $dimensionInfo['dimensionsByPage'][ $i - 1 ];
|
||||||
|
$dimensionString = $dimensions['width'] . 'x' . $dimensions['height'];
|
||||||
|
|
||||||
|
if ( isset ( $pagesByDimensions[ $dimensionString ] ) ) {
|
||||||
|
$pagesByDimensions[ $dimensionString ][] = $i;
|
||||||
|
} else {
|
||||||
|
$pagesByDimensions[ $dimensionString ] = [ $i ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$pageRangesByDimensions = MediaHandler::getPageRangesByDimensions( $pagesByDimensions );
|
||||||
|
|
||||||
|
return [ 'X-Content-Dimensions' => $pageRangesByDimensions ];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue