Gilles has uploaded a new change for review. https://gerrit.wikimedia.org/r/135008
Change subject: [WIP] Generate thumbnails based on buckets ...................................................................... [WIP] Generate thumbnails based on buckets Change-Id: I285d56b2024c81365247338f85c1e0aa708cb21e Mingle: https://wikimedia.mingle.thoughtworks.com/projects/multimedia/cards/600 --- M includes/filerepo/file/File.php M includes/media/Bitmap.php A tests/phpunit/includes/filerepo/file/FileTest.php 3 files changed, 127 insertions(+), 10 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core refs/changes/08/135008/1 diff --git a/includes/filerepo/file/File.php b/includes/filerepo/file/File.php index 5895dda..f91db54 100644 --- a/includes/filerepo/file/File.php +++ b/includes/filerepo/file/File.php @@ -457,6 +457,48 @@ } /** + * Return the nearest width thumbnail bucket, if any + * + * $param int $desiredWidth + * @param int $page + * @return bool|int + */ + public function getThumbnailBucket( $desiredWidth, $page = 1 ) { + global $wgThumbnailBuckets; + + $imageWidth = $this->getWidth( $page ); + + if ( $imageWidth === false ) { + return false; + } + + if ( $desiredWidth > $imageWidth ) { + return false; + } + + if ( !is_array( $wgThumbnailBuckets ) || empty( $wgThumbnailBuckets ) ) { + return false; + } + + $sortedBuckets = $wgThumbnailBuckets; + + sort( $sortedBuckets ); + + foreach ( $sortedBuckets as $bucket ) { + if ( $bucket > $imageWidth ) { + return false; + } + + if ( $bucket >= $desiredWidth ) { + return $bucket; + } + } + + // Image is bigger than any available bucket + return false; + } + + /** * Returns ID or name of user who uploaded the file * STUB * @@ -1004,18 +1046,16 @@ } elseif ( $flags & self::RENDER_FORCE ) { wfDebug( __METHOD__ . " forcing rendering per flag File::RENDER_FORCE\n" ); } + + // If the backend is ready-only, don't keep generating thumbnails + // only to return transformation errors, just return the error now. + if ( $this->repo->getReadOnlyReason() !== false ) { + $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ); + break; + } } - // If the backend is ready-only, don't keep generating thumbnails - // only to return transformation errors, just return the error now. - if ( $this->repo->getReadOnlyReason() !== false ) { - $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ); - break; - } - - // Create a temp FS file with the same extension and the thumbnail - $thumbExt = FileBackend::extensionFromPath( $thumbPath ); - $tmpFile = TempFSFile::factory( 'transform_', $thumbExt ); + $tmpFile = $this->makeTransformTmpFile( $thumbPath ); if ( !$tmpFile ) { $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ); break; @@ -1065,6 +1105,16 @@ } /** + * Creates a temp FS file with the same extension and the thumbnail + * @param string $thumbPath Thumbnail path + * @returns TempFSFile + */ + public function makeTransformTmpFile( $thumbPath ) { + $thumbExt = FileBackend::extensionFromPath( $thumbPath ); + return TempFSFile::factory( 'transform_', $thumbExt ); + } + + /** * @param string $thumbName Thumbnail name * @param string $dispositionType Type of disposition (either "attachment" or "inline") * @return string Content-Disposition header value diff --git a/includes/media/Bitmap.php b/includes/media/Bitmap.php index 44be178..cc43708 100644 --- a/includes/media/Bitmap.php +++ b/includes/media/Bitmap.php @@ -117,6 +117,42 @@ if ( !$this->normaliseParams( $image, $params ) ) { return new TransformParameterError( $params ); } + + $bucket = $image->getThumbnailBucket( $params[ 'physicalWidth' ] ); + + if ( $image->repo && $bucket && $bucket != $params[ 'physicalWidth' ] ) { + wfDebug( __METHOD__ . ": checking existence of {$bucket} bucket\n" ); + + $normalisedParams = $params; + $normalisedParams['physicalWidth'] = $bucket; + unset( $normalisedParams['physicalHeight'] ); + $this->normaliseParams( $image, $normalisedParams ); + $thumbName = $image->thumbName( $normalisedParams ); + $thumbUrl = $image->getThumbUrl( $thumbName ); + $thumbPath = $image->getThumbPath( $thumbName ); + + if ( !$image->repo->fileExists( $thumbPath ) ) { + wfDebug( __METHOD__ . ": {$bucket} bucket doesn't exist yet: {$thumbPath}\n" ); + + $bucketTmpFile = $image->makeTransformTmpFile( $thumbPath ); + + if ( $bucketTmpFile ) { + wfDebug( __METHOD__ . ": generating {$bucket} bucket\n" ); + $this->doTransform( $image, $bucketTmpFile->getPath(), $thumbUrl, $normalisedParams ); + } else { + wfDebug( __METHOD__ . ": Could not create temp file for bucket: {$thumbPath}\n" ); + } + } + } else { + if ( !$image->repo ) { + wfDebug( __METHOD__ . ": no repo for image\n" ); + } elseif ( !$bucket ) { + wfDebug( __METHOD__ . ": no corresponding thumbnail bucket\n" ); + } else ( !$bucket ) { + wfDebug( __METHOD__ . ": bucket is the same size as current doTransform request\n" ); + } + } + # Create a parameter array to pass to the scaler $scalerParams = array( # The size to which the image will be resized diff --git a/tests/phpunit/includes/filerepo/file/FileTest.php b/tests/phpunit/includes/filerepo/file/FileTest.php new file mode 100644 index 0000000..00fb65d --- /dev/null +++ b/tests/phpunit/includes/filerepo/file/FileTest.php @@ -0,0 +1,31 @@ +<?php + +namespace FileTest { + +class FooFile extends \File { }; + +class FileTest extends \MediaWikiTestCase { + /** + * @covers File::getThumbnailBucket + */ + public function testGetThumbnailBucket() { + global $wgThumbnailBuckets; + + $wgThumbnailBuckets = array( 256, 512, 1024, 2048, 4096 ); + + $stub = $this->getMock( '\FileTest\FooFile', array( 'getWidth' ), array( 'Foo', false ) ); + + $stub->expects( $this->any() )->method( 'getWidth' )->will( $this->returnValue( 3000 ) ); + + $this->assertEquals( 256, $stub->getThumbnailBucket( 120 ) ); + $this->assertEquals( 512, $stub->getThumbnailBucket( 300 ) ); + $this->assertEquals( 1024, $stub->getThumbnailBucket( 1024 ) ); + $this->assertEquals( false, $stub->getThumbnailBucket( 3500 ) ); + + $wgThumbnailBuckets = null; + + $this->assertEquals( false, $stub->getThumbnailBucket( 1024 ) ); + } +} + +} \ No newline at end of file -- To view, visit https://gerrit.wikimedia.org/r/135008 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I285d56b2024c81365247338f85c1e0aa708cb21e Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/core Gerrit-Branch: master Gerrit-Owner: Gilles <gdu...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits