Skip to content

Commit d73b9bd

Browse files
artongebackportbot[bot]
authored andcommitted
feat(previews): Support in memory preview request
This allows callers to use the API without increasing the disk usage. Example: blurhash generation, where we request a preview for all uploaded pictures, but don't want to necessarily store that preview. Signed-off-by: Louis Chemineau <louis@chmn.me>
1 parent bacea74 commit d73b9bd

File tree

3 files changed

+41
-45
lines changed

3 files changed

+41
-45
lines changed

lib/private/Preview/Generator.php

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
use OCP\Files\InvalidPathException;
3636
use OCP\Files\NotFoundException;
3737
use OCP\Files\NotPermittedException;
38+
use OCP\Files\SimpleFS\InMemoryFile;
3839
use OCP\Files\SimpleFS\ISimpleFile;
3940
use OCP\Files\SimpleFS\ISimpleFolder;
4041
use OCP\IConfig;
@@ -80,17 +81,19 @@ public function __construct(
8081
* The cache is searched first and if nothing usable was found then a preview is
8182
* generated by one of the providers
8283
*
83-
* @param File $file
84-
* @param int $width
85-
* @param int $height
86-
* @param bool $crop
87-
* @param string $mode
88-
* @param string|null $mimeType
8984
* @return ISimpleFile
9085
* @throws NotFoundException
9186
* @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
9287
*/
93-
public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL, $mimeType = null) {
88+
public function getPreview(
89+
File $file,
90+
int $width = -1,
91+
int $height = -1,
92+
bool $crop = false,
93+
string $mode = IPreview::MODE_FILL,
94+
?string $mimeType = null,
95+
bool $cacheResult = true,
96+
): ISimpleFile {
9497
$specification = [
9598
'width' => $width,
9699
'height' => $height,
@@ -107,20 +110,16 @@ public function getPreview(File $file, $width = -1, $height = -1, $crop = false,
107110
));
108111

109112
// since we only ask for one preview, and the generate method return the last one it created, it returns the one we want
110-
return $this->generatePreviews($file, [$specification], $mimeType);
113+
return $this->generatePreviews($file, [$specification], $mimeType, $cacheResult);
111114
}
112115

113116
/**
114117
* Generates previews of a file
115118
*
116-
* @param File $file
117-
* @param non-empty-array $specifications
118-
* @param string $mimeType
119-
* @return ISimpleFile the last preview that was generated
120119
* @throws NotFoundException
121120
* @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
122121
*/
123-
public function generatePreviews(File $file, array $specifications, $mimeType = null) {
122+
public function generatePreviews(File $file, array $specifications, ?string $mimeType = null, bool $cacheResult = true): ISimpleFile {
124123
//Make sure that we can read the file
125124
if (!$file->isReadable()) {
126125
throw new NotFoundException('Cannot read file');
@@ -508,19 +507,20 @@ private function calculateSize($width, $height, $crop, $mode, $maxWidth, $maxHei
508507
}
509508

510509
/**
511-
* @param ISimpleFolder $previewFolder
512-
* @param ISimpleFile $maxPreview
513-
* @param int $width
514-
* @param int $height
515-
* @param bool $crop
516-
* @param int $maxWidth
517-
* @param int $maxHeight
518-
* @param string $prefix
519-
* @return ISimpleFile
520510
* @throws NotFoundException
521511
* @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
522512
*/
523-
private function generatePreview(ISimpleFolder $previewFolder, IImage $maxPreview, $width, $height, $crop, $maxWidth, $maxHeight, $prefix) {
513+
private function generatePreview(
514+
ISimpleFolder $previewFolder,
515+
IImage $maxPreview,
516+
int $width,
517+
int $height,
518+
bool $crop,
519+
int $maxWidth,
520+
int $maxHeight,
521+
string $prefix,
522+
bool $cacheResult,
523+
): ISimpleFile {
524524
$preview = $maxPreview;
525525
if (!$preview->valid()) {
526526
throw new \InvalidArgumentException('Failed to generate preview, failed to load image');
@@ -557,8 +557,11 @@ private function generatePreview(ISimpleFolder $previewFolder, IImage $maxPrevie
557557

558558
$path = $this->generatePath($width, $height, $crop, false, $preview->dataMimeType(), $prefix);
559559
try {
560-
$file = $previewFolder->newFile($path);
561-
$file->putContent($preview->data());
560+
if ($cacheResult) {
561+
$file = $previewFolder->newFile($path, $preview->data());
562+
} else {
563+
return new InMemoryFile($path, $preview->data());
564+
}
562565
} catch (NotPermittedException $e) {
563566
throw new NotFoundException();
564567
}

lib/private/PreviewManager.php

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -165,29 +165,20 @@ private function getGenerator(): Generator {
165165
return $this->generator;
166166
}
167167

168-
/**
169-
* Returns a preview of a file
170-
*
171-
* The cache is searched first and if nothing usable was found then a preview is
172-
* generated by one of the providers
173-
*
174-
* @param File $file
175-
* @param int $width
176-
* @param int $height
177-
* @param bool $crop
178-
* @param string $mode
179-
* @param string $mimeType
180-
* @return ISimpleFile
181-
* @throws NotFoundException
182-
* @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
183-
* @since 11.0.0 - \InvalidArgumentException was added in 12.0.0
184-
*/
185-
public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL, $mimeType = null) {
168+
public function getPreview(
169+
File $file,
170+
$width = -1,
171+
$height = -1,
172+
$crop = false,
173+
$mode = IPreview::MODE_FILL,
174+
$mimeType = null,
175+
bool $cacheResult = true,
176+
): ISimpleFile {
186177
$this->throwIfPreviewsDisabled();
187178
$previewConcurrency = $this->getGenerator()->getNumConcurrentPreviews('preview_concurrency_all');
188179
$sem = Generator::guardWithSemaphore(Generator::SEMAPHORE_ID_ALL, $previewConcurrency);
189180
try {
190-
$preview = $this->getGenerator()->getPreview($file, $width, $height, $crop, $mode, $mimeType);
181+
$preview = $this->getGenerator()->getPreview($file, $width, $height, $crop, $mode, $mimeType, $cacheResult);
191182
} finally {
192183
Generator::unguardWithSemaphore($sem);
193184
}

lib/public/IPreview.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,14 @@ public function hasProviders();
9090
* @param bool $crop
9191
* @param string $mode
9292
* @param string $mimeType To force a given mimetype for the file (files_versions needs this)
93+
* @param bool $cacheResult Whether or not to cache the preview on the filesystem. Default to true. Can be useful to set to false to limit the amount of stored previews.
9394
* @return ISimpleFile
9495
* @throws NotFoundException
9596
* @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
9697
* @since 11.0.0 - \InvalidArgumentException was added in 12.0.0
98+
* @since 32.0.0 - getPreview($cacheResult) added the $cacheResult argument to the signature
9799
*/
98-
public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL, $mimeType = null);
100+
public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL, $mimeType = null, bool $cacheResult = true);
99101

100102
/**
101103
* Returns true if the passed mime type is supported

0 commit comments

Comments
 (0)