aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Chemineau <louis@chmn.me>2025-04-28 11:04:43 +0200
committerbackportbot[bot] <backportbot[bot]@users.noreply.github.com>2025-05-06 12:19:35 +0000
commitbea982dfd5be646c01f8197f94886d68fb014997 (patch)
treeeec65d005fca62d15eddcbac28a7d8dbf3293acc
parent8e255bc6f55b5f58262d77597f6ec465a940fa3b (diff)
downloadnextcloud-server-backport/52360/stable31.tar.gz
nextcloud-server-backport/52360/stable31.zip
fix(blurhash): Use preview API to generate the previewsbackport/52360/stable31
This allows to benefit from all the checks done by the preview API. This also use the newly introduced `cacheResult` argument to limit disk usage. Signed-off-by: Louis Chemineau <louis@chmn.me>
-rw-r--r--build/psalm-baseline.xml15
-rw-r--r--lib/private/Blurhash/Listener/GenerateBlurhashMetadata.php41
-rw-r--r--lib/private/Preview/Generator.php8
-rw-r--r--tests/lib/Preview/GeneratorTest.php32
4 files changed, 22 insertions, 74 deletions
diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml
index f73a6a15d1d..2ab9fedb1c6 100644
--- a/build/psalm-baseline.xml
+++ b/build/psalm-baseline.xml
@@ -2249,24 +2249,9 @@
</InvalidReturnStatement>
</file>
<file src="lib/private/Preview/Generator.php">
- <InvalidArgument>
- <code><![CDATA[$maxPreviewImage]]></code>
- </InvalidArgument>
<LessSpecificReturnType>
<code><![CDATA[null|string]]></code>
</LessSpecificReturnType>
- <MismatchingDocblockParamType>
- <code><![CDATA[ISimpleFile]]></code>
- </MismatchingDocblockParamType>
- <UndefinedInterfaceMethod>
- <code><![CDATA[height]]></code>
- <code><![CDATA[height]]></code>
- <code><![CDATA[preciseResizeCopy]]></code>
- <code><![CDATA[resizeCopy]]></code>
- <code><![CDATA[valid]]></code>
- <code><![CDATA[width]]></code>
- <code><![CDATA[width]]></code>
- </UndefinedInterfaceMethod>
</file>
<file src="lib/private/Preview/ProviderV1Adapter.php">
<InvalidReturnStatement>
diff --git a/lib/private/Blurhash/Listener/GenerateBlurhashMetadata.php b/lib/private/Blurhash/Listener/GenerateBlurhashMetadata.php
index 16f63594f19..982693bcfe8 100644
--- a/lib/private/Blurhash/Listener/GenerateBlurhashMetadata.php
+++ b/lib/private/Blurhash/Listener/GenerateBlurhashMetadata.php
@@ -19,6 +19,7 @@ use OCP\Files\NotPermittedException;
use OCP\FilesMetadata\AMetadataEvent;
use OCP\FilesMetadata\Event\MetadataBackgroundEvent;
use OCP\FilesMetadata\Event\MetadataLiveEvent;
+use OCP\IPreview;
use OCP\Lock\LockedException;
/**
@@ -27,11 +28,14 @@ use OCP\Lock\LockedException;
* @template-implements IEventListener<AMetadataEvent>
*/
class GenerateBlurhashMetadata implements IEventListener {
- private const RESIZE_BOXSIZE = 30;
-
private const COMPONENTS_X = 4;
private const COMPONENTS_Y = 3;
+ public function __construct(
+ private IPreview $preview,
+ ) {
+ }
+
/**
* @throws NotPermittedException
* @throws GenericFileException
@@ -64,7 +68,9 @@ class GenerateBlurhashMetadata implements IEventListener {
return;
}
- $image = $this->resizedImageFromFile($file);
+ $preview = $this->preview->getPreview($file, 64, 64, cacheResult: false);
+ $image = @imagecreatefromstring($preview->getContent());
+
if (!$image) {
return;
}
@@ -74,35 +80,6 @@ class GenerateBlurhashMetadata implements IEventListener {
}
/**
- * @param File $file
- *
- * @return GdImage|false
- * @throws GenericFileException
- * @throws NotPermittedException
- * @throws LockedException
- */
- private function resizedImageFromFile(File $file): GdImage|false {
- $image = @imagecreatefromstring($file->getContent());
- if ($image === false) {
- return false;
- }
-
- $currX = imagesx($image);
- $currY = imagesy($image);
-
- if ($currX > $currY) {
- $newX = self::RESIZE_BOXSIZE;
- $newY = intval($currY * $newX / $currX);
- } else {
- $newY = self::RESIZE_BOXSIZE;
- $newX = intval($currX * $newY / $currY);
- }
-
- $newImage = @imagescale($image, $newX, $newY);
- return ($newImage !== false) ? $newImage : $image;
- }
-
- /**
* @param GdImage $image
*
* @return string
diff --git a/lib/private/Preview/Generator.php b/lib/private/Preview/Generator.php
index 74e431a8ab8..00fc3b43d61 100644
--- a/lib/private/Preview/Generator.php
+++ b/lib/private/Preview/Generator.php
@@ -350,11 +350,10 @@ class Generator {
$path = $this->generatePath($preview->width(), $preview->height(), $crop, $max, $preview->dataMimeType(), $prefix);
try {
- $file = $previewFolder->newFile($path);
if ($preview instanceof IStreamImage) {
- $file->putContent($preview->resource());
+ return $previewFolder->newFile($path, $preview->resource());
} else {
- $file->putContent($preview->data());
+ return $previewFolder->newFile($path, $preview->data());
}
} catch (NotPermittedException $e) {
throw new NotFoundException();
@@ -540,14 +539,13 @@ class Generator {
$path = $this->generatePath($width, $height, $crop, false, $preview->dataMimeType(), $prefix);
try {
if ($cacheResult) {
- $file = $previewFolder->newFile($path, $preview->data());
+ return $previewFolder->newFile($path, $preview->data());
} else {
return new InMemoryFile($path, $preview->data());
}
} catch (NotPermittedException $e) {
throw new NotFoundException();
}
-
return $file;
}
diff --git a/tests/lib/Preview/GeneratorTest.php b/tests/lib/Preview/GeneratorTest.php
index 8a08d741909..607127a6495 100644
--- a/tests/lib/Preview/GeneratorTest.php
+++ b/tests/lib/Preview/GeneratorTest.php
@@ -22,25 +22,25 @@ use OCP\Preview\IProviderV2;
use Psr\Log\LoggerInterface;
class GeneratorTest extends \Test\TestCase {
- /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
+ /** @var IConfig&\PHPUnit\Framework\MockObject\MockObject */
private $config;
- /** @var IPreview|\PHPUnit\Framework\MockObject\MockObject */
+ /** @var IPreview&\PHPUnit\Framework\MockObject\MockObject */
private $previewManager;
- /** @var IAppData|\PHPUnit\Framework\MockObject\MockObject */
+ /** @var IAppData&\PHPUnit\Framework\MockObject\MockObject */
private $appData;
- /** @var GeneratorHelper|\PHPUnit\Framework\MockObject\MockObject */
+ /** @var GeneratorHelper&\PHPUnit\Framework\MockObject\MockObject */
private $helper;
- /** @var IEventDispatcher|\PHPUnit\Framework\MockObject\MockObject */
+ /** @var IEventDispatcher&\PHPUnit\Framework\MockObject\MockObject */
private $eventDispatcher;
/** @var Generator */
private $generator;
- private LoggerInterface|\PHPUnit\Framework\MockObject\MockObject $logger;
+ private LoggerInterface&\PHPUnit\Framework\MockObject\MockObject $logger;
protected function setUp(): void {
parent::setUp();
@@ -196,18 +196,10 @@ class GeneratorTest extends \Test\TestCase {
$previewFolder->method('getDirectoryListing')
->willReturn([]);
$previewFolder->method('newFile')
- ->willReturnCallback(function ($filename) use ($maxPreview, $previewFile) {
- if ($filename === '2048-2048-max.png') {
- return $maxPreview;
- } elseif ($filename === '256-256.png') {
- return $previewFile;
- }
- $this->fail('Unexpected file');
- });
-
- $maxPreview->expects($this->once())
- ->method('putContent')
- ->with($this->equalTo('my data'));
+ ->willReturnMap([
+ ['2048-2048-max.png', 'my data', $maxPreview],
+ ['256-256.png', 'my resized data', $previewFile],
+ ]);
$previewFolder->method('getFile')
->with($this->equalTo('256-256.png'))
@@ -218,10 +210,6 @@ class GeneratorTest extends \Test\TestCase {
->with($this->equalTo($maxPreview))
->willReturn($image);
- $previewFile->expects($this->once())
- ->method('putContent')
- ->with('my resized data');
-
$this->eventDispatcher->expects($this->once())
->method('dispatchTyped')
->with(new BeforePreviewFetchedEvent($file, 100, 100, false, IPreview::MODE_FILL, null));