r24894 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r24893‎ | r24894 | r24895 >
Date:09:50, 18 August 2007
Author:thomasv
Status:old
Tags:
Comment:
Pdf Handler by Xarax
Modified paths:
  • /trunk/extensions/PdfHandler (added) (history)
  • /trunk/extensions/PdfHandler/PdfHandler.php (added) (history)
  • /trunk/extensions/PdfHandler/PdfImage.php (added) (history)
  • /trunk/extensions/PdfHandler/PdfLoader.php (added) (history)

Diff [purge]

Index: trunk/extensions/PdfHandler/PdfImage.php
@@ -0,0 +1,104 @@
 2+<?php
 3+
 4+ /**
 5+ *
 6+ * Copyright (C) 2007 Xarax <jodeldi@gmx.de>
 7+ *
 8+ * This program is free software; you can redistribute it and/or modify
 9+ * it under the terms of the GNU General Public License as published by
 10+ * the Free Software Foundation; either version 2 of the License, or
 11+ * (at your option) any later version.
 12+ *
 13+ * This program is distributed in the hope that it will be useful,
 14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 16+ * GNU General Public License for more details.
 17+ *
 18+ * You should have received a copy of the GNU General Public License along
 19+ * with this program; if not, write to the Free Software Foundation, Inc.,
 20+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 21+ * http://www.gnu.org/copyleft/gpl.html
 22+ *
 23+ */
 24+
 25+ /**
 26+ * inspired by djvuimage from brion vibber
 27+ * modified and written by xarax
 28+ */
 29+
 30+class PdfImage {
 31+
 32+ function __construct( $filename ) {
 33+ $this->mFilename = $filename;
 34+ }
 35+
 36+ public function isValid() {
 37+ return true;
 38+ }
 39+
 40+ public function getImageSize() {
 41+ global $wgPdfHandlerDpi;
 42+
 43+ $tree = new SimpleXMLElement( $this->retrieveMetadata( ) );
 44+
 45+ if ( !$tree ) return false;
 46+
 47+ $o = $tree->BODY[0]->Pagesize;
 48+
 49+ if ( $o ) {
 50+ $size = explode("x", $o, 2);
 51+
 52+ if ( $size ) {
 53+ $width = intval( round( trim($size[0]) / 72 * $wgPdfHandlerDpi ) );
 54+ $height = explode( " ", trim($size[1]), 2 );
 55+ $height = intval( round( trim($height[0]) / 72 * $wgPdfHandlerDpi ) );
 56+
 57+ return array( $width, $height, 'Pdf',
 58+ "width=\"$width\" height=\"$height\"" );
 59+ }
 60+ }
 61+ return false;
 62+ }
 63+
 64+ function retrieveMetaData() {
 65+ global $wgPdfInfo;
 66+
 67+ if ( $wgPdfInfo ) {
 68+ wfProfileIn( 'pdfinfo' );
 69+ $cmd = "(" . wfEscapeShellArg( $wgPdfInfo ) . " " . $this->mFilename . ")";
 70+ $dump = wfShellExec( $cmd, $retval );
 71+ $xml = $this->convertDumpToXML( $dump );
 72+ wfProfileOut( 'pdfinfo' );
 73+ } else {
 74+ $xml = null;
 75+ }
 76+ return $xml;
 77+ }
 78+
 79+ function createMetadataBody() {
 80+ $xml = "<?xml version=\"1.0\" ?>\n";
 81+ $xml .= "<!DOCTYPE PdfXML PUBLIC \"-//W3C//DTD PdfXML 1.1//EN\" \"pubtext/PdfXML-s.dtd\">\n";
 82+ $xml .= "<PdfXML>\n";
 83+ $xml .= "<HEAD></HEAD>\n";
 84+ $xml .= "<BODY>\n";
 85+ $xml .= "</BODY></PdfXML>";
 86+ return $xml;
 87+ }
 88+
 89+ function convertDumpToXML( $dump ) {
 90+ if ( strval( $dump ) == '' ) return false;
 91+
 92+ $xml = $this->createMetadataBody();
 93+ $doc = new SimpleXMLElement($xml);
 94+
 95+ if (!$doc) return;
 96+
 97+ $lines = explode("\n", $dump);
 98+
 99+ for ($i = 1; $i < count($lines); $i++) {
 100+ $value = explode(':', trim($lines[$i]), 2);
 101+ $doc->BODY[0]->addChild(str_replace(' ', '', $value[0]), trim($value[1]));
 102+ }
 103+ return $doc->asXML();
 104+ }
 105+}
Index: trunk/extensions/PdfHandler/PdfLoader.php
@@ -0,0 +1,42 @@
 2+<?php
 3+
 4+ /**
 5+ *
 6+ * Copyright (C) 2007 Martin Seidel <jodeldi@gmx.de>
 7+ *
 8+ * This program is free software; you can redistribute it and/or modify
 9+ * it under the terms of the GNU General Public License as published by
 10+ * the Free Software Foundation; either version 2 of the License, or
 11+ * (at your option) any later version.
 12+ *
 13+ * This program is distributed in the hope that it will be useful,
 14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 16+ * GNU General Public License for more details.
 17+ *
 18+ * You should have received a copy of the GNU General Public License along
 19+ * with this program; if not, write to the Free Software Foundation, Inc.,
 20+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 21+ * http://www.gnu.org/copyleft/gpl.html
 22+ *
 23+ */
 24+
 25+ # Not a valid entry point, skip unless MEDIAWIKI is defined
 26+ if (!defined('MEDIAWIKI')) {
 27+ echo "PdfHandler extension";
 28+ exit(1);
 29+ }
 30+
 31+ $wgExtensionCredits['other'][] = array(
 32+ 'name'=>'PDF Handler',
 33+ 'author'=>'Xarax',
 34+ 'description'=>"Handler for viewing PDF files in image mode",
 35+ 'url' => 'http://www.mediawiki.org/wiki/Extension:PdfHandler',
 36+ );
 37+
 38+ if (!isset($wgPdfOutputExtension)) $wgPdfOutputExtension = "jpg";
 39+ if (!isset($wgPdfHandlerDpi)) $wgPdfHandlerDpi = 150;
 40+
 41+ $wgAutoloadClasses['PdfImage'] = dirname(__FILE__) . '/PdfImage.php';
 42+ $wgAutoloadClasses['PdfHandler'] = dirname(__FILE__) . '/PdfHandler.php';
 43+ $wgMediaHandlers['application/pdf'] = 'PdfHandler';
Index: trunk/extensions/PdfHandler/PdfHandler.php
@@ -0,0 +1,232 @@
 2+<?php
 3+
 4+ /**
 5+ *
 6+ * Copyright (C) 2007 Xarax <jodeldi@gmx.de>
 7+ *
 8+ * This program is free software; you can redistribute it and/or modify
 9+ * it under the terms of the GNU General Public License as published by
 10+ * the Free Software Foundation; either version 2 of the License, or
 11+ * (at your option) any later version.
 12+ *
 13+ * This program is distributed in the hope that it will be useful,
 14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 16+ * GNU General Public License for more details.
 17+ *
 18+ * You should have received a copy of the GNU General Public License along
 19+ * with this program; if not, write to the Free Software Foundation, Inc.,
 20+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 21+ * http://www.gnu.org/copyleft/gpl.html
 22+ *
 23+ */
 24+
 25+ /*
 26+ * inspired by djvuhandler from tim starling
 27+ * modified and written by xarax
 28+ */
 29+
 30+class PdfHandler extends ImageHandler {
 31+
 32+ function isEnabled() {
 33+ global $wgPdfProcessor;
 34+ global $wgPdfPostProcessor;
 35+ global $wgPdfInfo;
 36+
 37+ if ( !isset( $wgPdfProcessor ) || !isset( $wgPdfPostProcessor) || !isset( $wgPdfInfo ) ) {
 38+ wfDebug( "PdfHandler is disabled, please set the following\n" );
 39+ wfDebug( "variables in LocalSettings.php:\n" );
 40+ wfDebug( "\$wgPdfProcessor, \$wgPdfPostProcessor, \$wgPdfInfo\n" );
 41+ return false;
 42+ }
 43+ return true;
 44+ }
 45+
 46+ function mustRender() { return true; }
 47+
 48+ function isMultiPage() { return true; }
 49+
 50+ function validateParam( $name, $value ) {
 51+ if ( in_array( $name, array( 'width', 'height', 'page' ) ) )
 52+ return ( $value <= 0 ) ? false : true;
 53+ else
 54+ return false;
 55+ }
 56+
 57+ function makeParamString( $params ) {
 58+ $page = isset( $params['page'] ) ? $params['page'] : 1;
 59+ if ( !isset( $params['width'] ) ) return false;
 60+ return "page{$page}-{$params['width']}px";
 61+ }
 62+
 63+ function parseParamString( $str ) {
 64+ $m = false;
 65+
 66+ if ( preg_match( '/^page(\d+)-(\d+)px$/', $str, $m ) )
 67+ return array( 'width' => $m[2], 'page' => $m[1] );
 68+
 69+ return false;
 70+ }
 71+
 72+ function getScriptParams( $params ) {
 73+ return array(
 74+ 'width' => $params['width'],
 75+ 'page' => $params['page'],
 76+ );
 77+ }
 78+
 79+ function doTransform( $image, $dstPath, $dstUrl, $params, $flags = 0 ) {
 80+ global $wgPdfProcessor;
 81+ global $wgPdfPostProcessor;
 82+ global $wgPdfHandlerDpi;
 83+
 84+ $xml = $image->getMetadata();
 85+
 86+ if ( !$xml )
 87+ return new MediaTransformError( 'thumbnail_error',
 88+ @$params['width'],
 89+ @$params['height'],
 90+ wfMsg( 'pdf_no_xml' ) );
 91+
 92+ if ( !$this->normaliseParams( $image, $params ) )
 93+ return new TransformParameterError( $params );
 94+
 95+ $width = $params['width'];
 96+ $height = $params['height'];
 97+ $srcPath = $image->getPath();
 98+ $page = $params['page'];
 99+
 100+ if ( $page > $this->pageCount( $image ) )
 101+ return new MediaTransformError( 'thumbnail_error',
 102+ $width,
 103+ $height,
 104+ wfMsg( 'pdf_page_error' ) );
 105+
 106+ if ( $flags & self::TRANSFORM_LATER )
 107+ return new ThumbnailImage( $dstUrl,
 108+ $width,
 109+ $height,
 110+ $dstPath );
 111+
 112+ if ( !wfMkdirParents( dirname( $dstPath ) ) )
 113+ return new MediaTransformError( 'thumbnail_error',
 114+ $width,
 115+ $height,
 116+ wfMsg( 'thumbnail_dest_directory' ) );
 117+
 118+ $cmd = '(' . wfEscapeShellArg( $wgPdfProcessor );
 119+ $cmd .= " -sDEVICE=jpeg -sOutputFile=- -dFirstPage={$page} -dLastPage={$page}";
 120+ $cmd .= " -r{$wgPdfHandlerDpi} -dBATCH -dNOPAUSE -q ". wfEscapeShellArg( $srcPath );
 121+ $cmd .= " | " . wfEscapeShellArg( $wgPdfPostProcessor );
 122+ $cmd .= " -depth 8 -resize {$width} - ";
 123+ $cmd .= wfEscapeShellArg( $dstPath ) . ")";
 124+
 125+ wfProfileIn( 'PdfHandler' );
 126+ wfDebug( __METHOD__.": $cmd\n" );
 127+ $err = wfShellExec( $cmd, $retval );
 128+ wfProfileOut( 'PdfHandler' );
 129+
 130+ $removed = $this->removeBadFile( $dstPath, $retval );
 131+
 132+ if ( $retval != 0 || $removed ) {
 133+ wfDebugLog( 'thumbnail',
 134+ sprintf( 'thumbnail failed on %s: error %d "%s" from "%s"',
 135+ wfHostname(), $retval, trim($err), $cmd ) );
 136+ return new MediaTransformError( 'thumbnail_error', $width, $height, $err );
 137+ } else {
 138+ return new ThumbnailImage( $dstUrl, $width, $height, $dstPath );
 139+ }
 140+ }
 141+
 142+ function getPdfImage( $image, $path ) {
 143+ if ( !$image )
 144+ $pdfimg = new PdfImage( $path );
 145+ elseif ( !isset( $image->pdfImage ) )
 146+ $pdfimg = $image->pdfImage = new PdfImage( $path );
 147+ else
 148+ $pdfimg = $image->pdfImage;
 149+
 150+ return $pdfimg;
 151+ }
 152+
 153+ function getMetaTree( $image ) {
 154+ if ( isset( $image->pdfMetaTree ) )
 155+ return $image->pdfMetaTree;
 156+
 157+ $metadata = $image->getMetadata();
 158+
 159+ if ( !$this->isMetadataValid( $image, $metadata ) ) {
 160+ wfDebug( "Pdf XML metadata is invalid or missing, should have been fixed in upgradeRow\n" );
 161+ return false;
 162+ }
 163+
 164+ wfProfileIn( __METHOD__ );
 165+ wfSuppressWarnings();
 166+
 167+ try {
 168+ $image->pdfMetaTree = new SimpleXMLElement( $metadata );
 169+ } catch( Exception $e ) {
 170+ $image->pdfMetaTree = false;
 171+ }
 172+
 173+ wfRestoreWarnings();
 174+ wfProfileOut( __METHOD__ );
 175+
 176+ return $image->pdfMetaTree;
 177+ }
 178+
 179+ function getImageSize( $image, $path ) {
 180+ return $this->getPdfImage( $image, $path )->getImageSize();
 181+ }
 182+
 183+ function getThumbType( $ext, $mime ) {
 184+ global $wgPdfOutputExtension;
 185+ static $mime;
 186+
 187+ if ( !isset( $mime ) ) {
 188+ $magic = MimeMagic::singleton();
 189+ $mime = $magic->guessTypesForExtension( $wgPdfOutputExtension );
 190+ }
 191+ return array( $wgPdfOutputExtension, $mime );
 192+ }
 193+
 194+ function getMetadata( $image, $path ) {
 195+ return $this->getPdfImage( $image, $path )->retrieveMetaData();
 196+ }
 197+
 198+ function isMetadataValid( $image, $metadata ) {
 199+ return !empty( $metadata ) && $metadata != serialize(array());
 200+ }
 201+
 202+ function pageCount( $image ) {
 203+ $tree = $this->getMetaTree( $image );
 204+ if ( !$tree ) return false;
 205+ return intval( $tree->BODY[0]->Pages );
 206+ }
 207+
 208+ function getPageDimensions( $image, $page ) {
 209+ global $wgPdfHandlerDpi;
 210+
 211+ $tree = $this->getMetaTree( $image );
 212+
 213+ if ( $tree ) {
 214+ $o = $tree->BODY[0]->Pagesize;
 215+
 216+ if ( $o ) {
 217+ $size = explode("x", $o, 2);
 218+
 219+ if ( $size ) {
 220+ $width = intval( trim($size[0]) / 72 * $wgPdfHandlerDpi );
 221+ $height = explode( " ", trim($size[1]), 2 );
 222+ $height = intval( trim($height[0]) / 72 * $wgPdfHandlerDpi );
 223+
 224+ return array(
 225+ 'width' => $width,
 226+ 'height' => $height
 227+ );
 228+ }
 229+ }
 230+ }
 231+ return false;
 232+ }
 233+}

Status & tagging log