Skip to content

Commit 54a91f4

Browse files
committed
feat(preview): Store original file mimetype in preview table
Allow to quickly query all the files from a specific mimetype like in the ResetRenderedTexts command. Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
1 parent 2912406 commit 54a91f4

File tree

11 files changed

+55
-32
lines changed

11 files changed

+55
-32
lines changed

core/BackgroundJobs/MovePreviewJob.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
use OCP\Files\SimpleFS\ISimpleFolder;
2525
use OCP\IAppConfig;
2626
use OCP\IDBConnection;
27-
use OCP\IPreview;
2827

2928
class MovePreviewJob extends TimedJob {
3029
private IAppData $appData;
@@ -138,7 +137,7 @@ private function processPreviews(int|string $fileId, bool $simplePaths): void {
138137
}
139138

140139
$qb = $this->connection->getQueryBuilder();
141-
$qb->select('*')
140+
$qb->select('storage', 'etag', 'mimetype')
142141
->from('filecache')
143142
->where($qb->expr()->eq('fileid', $qb->createNamedParameter($fileId)))
144143
->setMaxResults(1)
@@ -154,6 +153,7 @@ private function processPreviews(int|string $fileId, bool $simplePaths): void {
154153
$file = $previewFile['file'];
155154
$preview->setStorageId($result[0]['storage']);
156155
$preview->setEtag($result[0]['etag']);
156+
$preview->setSourceMimetype($result[0]['mimetype']);
157157
try {
158158
$preview = $this->previewMapper->insert($preview);
159159
} catch (Exception $e) {

core/Command/Preview/ResetRenderedTexts.php

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,7 @@ private function deleteAvatars(OutputInterface $output, bool $dryMode): void {
6767

6868
try {
6969
$avatar->remove();
70-
} catch (NotFoundException $e) {
71-
// continue
72-
} catch (NotPermittedException $e) {
70+
} catch (NotFoundException|NotPermittedException) {
7371
// continue
7472
}
7573
}
@@ -91,8 +89,8 @@ private function getAvatarsToDelete(): \Iterator {
9189
private function deletePreviews(OutputInterface $output, bool $dryMode): void {
9290
$previewsToDeleteCount = 0;
9391

94-
foreach ($this->getPreviewsToDelete() as ['path' => $filePath, 'preview' => $preview]) {
95-
$output->writeln('Deleting previews for ' . $filePath, OutputInterface::VERBOSITY_VERBOSE);
92+
foreach ($this->getPreviewsToDelete() as $preview) {
93+
$output->writeln('Deleting preview ' . $preview->getName() . ' for fileId ' . $preview->getFileId(), OutputInterface::VERBOSITY_VERBOSE);
9694

9795
$previewsToDeleteCount++;
9896

@@ -107,28 +105,13 @@ private function deletePreviews(OutputInterface $output, bool $dryMode): void {
107105
}
108106

109107
/**
110-
* @return \Iterator<array{path: string, preview: Preview}>
108+
* @return \Generator<Preview>
111109
*/
112-
private function getPreviewsToDelete(): \Iterator {
113-
$qb = $this->connection->getQueryBuilder();
114-
$qb->select('fileid', 'path')
115-
->from('filecache')
116-
->where(
117-
$qb->expr()->orX(
118-
$qb->expr()->eq('mimetype', $qb->createNamedParameter($this->mimeTypeLoader->getId('text/plain'))),
119-
$qb->expr()->eq('mimetype', $qb->createNamedParameter($this->mimeTypeLoader->getId('text/markdown'))),
120-
$qb->expr()->eq('mimetype', $qb->createNamedParameter($this->mimeTypeLoader->getId('text/x-markdown')))
121-
)
122-
);
123-
124-
$cursor = $qb->executeQuery();
125-
126-
while ($row = $cursor->fetch()) {
127-
foreach ($this->previewService->getAvailablePreviewForFile($row['fileid']) as $preview) {
128-
yield ['path' => $row['path'], 'preview' => $preview];
129-
}
130-
}
131-
132-
$cursor->closeCursor();
110+
private function getPreviewsToDelete(): \Generator {
111+
return $this->previewService->getPreviewsForMimeTypes([
112+
$this->mimeTypeLoader->getId('text/plain'),
113+
$this->mimeTypeLoader->getId('text/markdown'),
114+
$this->mimeTypeLoader->getId('text/x-markdown'),
115+
]);
133116
}
134117
}

lib/private/Preview/Db/Preview.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
* @method void setCropped(bool $cropped)
3636
* @method void setMimetype(int $mimetype) Set the mimetype of the preview.
3737
* @method int getMimetype() Get the mimetype of the preview.
38+
* @method void setSourceMimetype(int $sourceMimetype) Set the mimetype of the source file.
39+
* @method int getSourceMimetype() Get the mimetype of the source file.
3840
* @method int getMtime() Get the modification time of the preview.
3941
* @method void setMtime(int $mtime)
4042
* @method int getSize() Get the size of the preview.
@@ -61,6 +63,8 @@ class Preview extends Entity {
6163
protected ?int $width = null;
6264
protected ?int $height = null;
6365
protected ?int $mimetype = null;
66+
67+
protected ?int $sourceMimetype = null;
6468
protected ?int $mtime = null;
6569
protected ?int $size = null;
6670
protected ?bool $max = null;
@@ -77,6 +81,7 @@ public function __construct() {
7781
$this->addType('width', Types::INTEGER);
7882
$this->addType('height', Types::INTEGER);
7983
$this->addType('mimetype', Types::INTEGER);
84+
$this->addType('sourceMimetype', Types::INTEGER);
8085
$this->addType('mtime', Types::INTEGER);
8186
$this->addType('size', Types::INTEGER);
8287
$this->addType('max', Types::BOOLEAN);

lib/private/Preview/Db/PreviewMapper.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,19 @@ public function getPreviews(int $lastId, int $limit = 1000): \Generator {
139139
return $this->yieldEntities($qb);
140140

141141
}
142+
143+
/**
144+
* @param int[] $mimeTypes
145+
* @return \Generator<Preview>
146+
*/
147+
public function getPreviewsForMimeTypes(array $mimeTypes): \Generator {
148+
$qb = $this->db->getQueryBuilder();
149+
$this->joinLocation($qb)
150+
->where($qb->expr()->orX(
151+
...array_map(function (int $mimeType) use ($qb) {
152+
return $qb->expr()->eq('source_mimetype', $qb->createNamedParameter($mimeType, IQueryBuilder::PARAM_INT));
153+
}, $mimeTypes)
154+
));
155+
return $this->yieldEntities($qb);
156+
}
142157
}

lib/private/Preview/Generator.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use OC\Preview\Storage\StorageFactory;
1313
use OCP\EventDispatcher\IEventDispatcher;
1414
use OCP\Files\File;
15+
use OCP\Files\IMimeTypeLoader;
1516
use OCP\Files\InvalidPathException;
1617
use OCP\Files\NotFoundException;
1718
use OCP\Files\NotPermittedException;
@@ -38,6 +39,7 @@ public function __construct(
3839
private LoggerInterface $logger,
3940
private PreviewMapper $previewMapper,
4041
private StorageFactory $storageFactory,
42+
private IMimeTypeLoader $mimeTypeLoader,
4143
) {
4244
}
4345

@@ -541,6 +543,7 @@ public function savePreview(File $file, int $width, int $height, bool $crop, boo
541543
$previewEntry->setFileId($file->getId());
542544
$previewEntry->setStorageId($file->getMountPoint()->getNumericStorageId());
543545
$previewEntry->setWidth($width);
546+
$previewEntry->setSourceMimetype($this->mimeTypeLoader->getId($file->getMimeType()));
544547
$previewEntry->setHeight($height);
545548
$previewEntry->setVersion($version);
546549
$previewEntry->setMax($max);

lib/private/Preview/PreviewService.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,15 @@ public function getAvailableFileIds(): \Generator {
7171
* @return \Generator<Preview>
7272
*/
7373
public function getAvailablePreviewForFile(int $fileId): \Generator {
74-
yield from $this->previewMapper->getAvailablePreviewForFile($fileId);
74+
return $this->previewMapper->getAvailablePreviewForFile($fileId);
75+
}
76+
77+
/**
78+
* @param int[] $mimeTypes
79+
* @return \Generator<Preview>
80+
*/
81+
public function getPreviewsForMimeTypes(array $mimeTypes): \Generator {
82+
return $this->previewMapper->getPreviewsForMimeTypes($mimeTypes);
7583
}
7684

7785
public function deleteAll(): void {

lib/private/Preview/Storage/LocalPreviewStorage.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public function scan(): int {
101101
$preview->setEncrypted(false);
102102

103103
$qb = $this->connection->getQueryBuilder();
104-
$result = $qb->select('*')
104+
$result = $qb->select('storage', 'etag', 'mimetype')
105105
->from('filecache')
106106
->where($qb->expr()->eq('fileid', $qb->createNamedParameter($preview->getFileId())))
107107
->setMaxResults(1)
@@ -127,6 +127,7 @@ public function scan(): int {
127127

128128
$preview->setStorageId($result[0]['storage']);
129129
$preview->setEtag($result[0]['etag']);
130+
$preview->setSourceMimetype($result[0]['mimetype']);
130131

131132
// try to insert, if that fails the preview is already in the DB
132133
$this->previewMapper->insert($preview);

lib/private/PreviewManager.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use OCP\AppFramework\QueryException;
1717
use OCP\EventDispatcher\IEventDispatcher;
1818
use OCP\Files\File;
19+
use OCP\Files\IMimeTypeLoader;
1920
use OCP\Files\IRootFolder;
2021
use OCP\Files\NotFoundException;
2122
use OCP\Files\SimpleFS\ISimpleFile;
@@ -139,6 +140,7 @@ private function getGenerator(): Generator {
139140
$this->container->get(LoggerInterface::class),
140141
$this->container->get(PreviewMapper::class),
141142
$this->container->get(StorageFactory::class),
143+
$this->container->get(IMimeTypeLoader::class),
142144
);
143145
}
144146
return $this->generator;

tests/lib/Preview/GeneratorTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use OC\Preview\Storage\StorageFactory;
1515
use OCP\EventDispatcher\IEventDispatcher;
1616
use OCP\Files\File;
17+
use OCP\Files\IMimeTypeLoader;
1718
use OCP\Files\Mount\IMountPoint;
1819
use OCP\Files\NotFoundException;
1920
use OCP\IConfig;
@@ -34,6 +35,7 @@ class GeneratorTest extends TestCase {
3435
private LoggerInterface&MockObject $logger;
3536
private StorageFactory&MockObject $storageFactory;
3637
private PreviewMapper&MockObject $previewMapper;
38+
private IMimeTypeLoader&MockObject $mimeTypeLoader;
3739

3840
protected function setUp(): void {
3941
parent::setUp();
@@ -45,6 +47,7 @@ protected function setUp(): void {
4547
$this->logger = $this->createMock(LoggerInterface::class);
4648
$this->previewMapper = $this->createMock(PreviewMapper::class);
4749
$this->storageFactory = $this->createMock(StorageFactory::class);
50+
$this->mimetypeLoader = $this->createMock(IMimeTypeLoader::class);
4851

4952
$this->generator = new Generator(
5053
$this->config,
@@ -53,7 +56,8 @@ protected function setUp(): void {
5356
$this->eventDispatcher,
5457
$this->logger,
5558
$this->previewMapper,
56-
$this->storageFactory
59+
$this->storageFactory,
60+
$this->mimetypeLoader,
5761
);
5862
}
5963

tests/lib/Preview/PreviewMapperTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ private function createPreviewForFileId(int $fileId, ?int $bucket = null) {
6868
$preview->setCropped(true);
6969
$preview->setMax(true);
7070
$preview->setWidth(100);
71+
$preview->setSourceMimetype(1);
7172
$preview->setHeight(100);
7273
$preview->setSize(100);
7374
$preview->setMtime(time());

0 commit comments

Comments
 (0)