Skip to content

Commit 70545e3

Browse files
committed
Support getting and setting metadata in DAV requests
Signed-off-by: Louis Chemineau <louis@chmn.me>
1 parent 9285fe0 commit 70545e3

26 files changed

Lines changed: 104 additions & 878 deletions

apps/dav/lib/Connector/Sabre/Directory.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434

3535
use OC\Files\Mount\MoveableMount;
3636
use OC\Files\View;
37-
use OC\Metadata\FileMetadata;
3837
use OCA\DAV\AppInfo\Application;
3938
use OCA\DAV\Connector\Sabre\Exception\FileLocked;
4039
use OCA\DAV\Connector\Sabre\Exception\Forbidden;
@@ -70,9 +69,6 @@ class Directory extends \OCA\DAV\Connector\Sabre\Node implements \Sabre\DAV\ICol
7069
private ?array $quotaInfo = null;
7170
private ?CachingTree $tree = null;
7271

73-
/** @var array<string, array<int, FileMetadata>> */
74-
private array $metadata = [];
75-
7672
/**
7773
* Sets up the node, expects a full path name
7874
*/

apps/dav/lib/Connector/Sabre/File.php

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
use OC\Files\Filesystem;
4444
use OC\Files\Stream\HashWrapper;
4545
use OC\Files\View;
46-
use OC\Metadata\FileMetadata;
4746
use OCA\DAV\AppInfo\Application;
4847
use OCA\DAV\Connector\Sabre\Exception\BadGateway;
4948
use OCA\DAV\Connector\Sabre\Exception\EntityTooLarge;
@@ -81,9 +80,6 @@ class File extends Node implements IFile {
8180
protected IRequest $request;
8281
protected IL10N $l10n;
8382

84-
/** @var array<string, FileMetadata> */
85-
private array $metadata = [];
86-
8783
/**
8884
* Sets up the node, expects a full path name
8985
*
@@ -796,16 +792,4 @@ public function hash(string $type) {
796792
public function getNode(): \OCP\Files\File {
797793
return $this->node;
798794
}
799-
800-
public function getMetadata(string $group): FileMetadata {
801-
return $this->metadata[$group];
802-
}
803-
804-
public function setMetadata(string $group, FileMetadata $metadata): void {
805-
$this->metadata[$group] = $metadata;
806-
}
807-
808-
public function hasMetadata(string $group) {
809-
return array_key_exists($group, $this->metadata);
810-
}
811795
}

apps/dav/lib/Connector/Sabre/FilesPlugin.php

Lines changed: 57 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,20 @@
3535
namespace OCA\DAV\Connector\Sabre;
3636

3737
use OC\AppFramework\Http\Request;
38-
use OC\Metadata\IMetadataManager;
38+
use OC\FilesMetadata\Model\MetadataValueWrapper;
3939
use OCP\Constants;
4040
use OCP\Files\ForbiddenException;
4141
use OCP\Files\StorageNotAvailableException;
42+
use OCP\FilesMetadata\Exceptions\FilesMetadataNotFoundException;
43+
use OCP\FilesMetadata\IFilesMetadataManager;
44+
use OCP\FilesMetadata\Model\IMetadataValueWrapper;
4245
use OCP\IConfig;
4346
use OCP\IPreview;
4447
use OCP\IRequest;
4548
use OCP\IUserSession;
46-
use Psr\Log\LoggerInterface;
4749
use Sabre\DAV\Exception\Forbidden;
4850
use Sabre\DAV\Exception\NotFound;
4951
use Sabre\DAV\IFile;
50-
use Sabre\DAV\INode;
5152
use Sabre\DAV\PropFind;
5253
use Sabre\DAV\PropPatch;
5354
use Sabre\DAV\Server;
@@ -86,17 +87,6 @@ class FilesPlugin extends ServerPlugin {
8687
public const SUBFOLDER_COUNT_PROPERTYNAME = '{http://nextcloud.org/ns}contained-folder-count';
8788
public const SUBFILE_COUNT_PROPERTYNAME = '{http://nextcloud.org/ns}contained-file-count';
8889
public const FILE_METADATA_PREFIX = '{http://nextcloud.org/ns}metadata-';
89-
public const FILE_METADATA_SIZE = '{http://nextcloud.org/ns}file-metadata-size';
90-
public const FILE_METADATA_GPS = '{http://nextcloud.org/ns}file-metadata-gps';
91-
92-
public const ALL_METADATA_PROPS = [
93-
self::FILE_METADATA_SIZE => 'size',
94-
self::FILE_METADATA_GPS => 'gps',
95-
];
96-
public const METADATA_MIMETYPES = [
97-
'size' => 'image',
98-
'gps' => 'image',
99-
];
10090

10191
/** Reference to main server object */
10292
private ?Server $server = null;
@@ -434,31 +424,6 @@ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node)
434424
$propFind->handle(self::UPLOAD_TIME_PROPERTYNAME, function () use ($node) {
435425
return $node->getFileInfo()->getUploadTime();
436426
});
437-
438-
if ($this->config->getSystemValueBool('enable_file_metadata', true)) {
439-
foreach (self::ALL_METADATA_PROPS as $prop => $meta) {
440-
$propFind->handle($prop, function () use ($node, $meta) {
441-
if ($node->getFileInfo()->getMimePart() !== self::METADATA_MIMETYPES[$meta]) {
442-
return [];
443-
}
444-
445-
if ($node->hasMetadata($meta)) {
446-
$metadata = $node->getMetadata($meta);
447-
} else {
448-
// This code path should not be called since we try to preload
449-
// the metadata when loading the folder or the search results
450-
// in one go
451-
$metadataManager = \OC::$server->get(IMetadataManager::class);
452-
$metadata = $metadataManager->fetchMetadataFor($meta, [$node->getId()])[$node->getId()];
453-
454-
// TODO would be nice to display this in the profiler...
455-
\OC::$server->get(LoggerInterface::class)->debug('Inefficient fetching of metadata');
456-
}
457-
458-
return $metadata->getValue();
459-
});
460-
}
461-
}
462427
}
463428

464429
if ($node instanceof Directory) {
@@ -472,39 +437,6 @@ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node)
472437

473438
$requestProperties = $propFind->getRequestedProperties();
474439

475-
$requestedMetaData = [];
476-
foreach ($requestProperties as $requestProperty) {
477-
if (isset(self::ALL_METADATA_PROPS[$requestProperty])) {
478-
$requestedMetaData[] = self::ALL_METADATA_PROPS[$requestProperty];
479-
}
480-
}
481-
if (
482-
$this->config->getSystemValueBool('enable_file_metadata', true) &&
483-
$propFind->getDepth() === 1 &&
484-
$requestedMetaData
485-
) {
486-
$children = $node->getChildren();
487-
// Preloading of the metadata
488-
489-
/** @var IMetaDataManager $metadataManager */
490-
$metadataManager = \OC::$server->get(IMetadataManager::class);
491-
492-
foreach ($requestedMetaData as $requestedMeta) {
493-
$relevantMimeType = self::METADATA_MIMETYPES[$requestedMeta];
494-
$childrenForMeta = array_filter($children, function (INode $child) use ($relevantMimeType) {
495-
return $child instanceof File && $child->getFileInfo()->getMimePart() === $relevantMimeType;
496-
});
497-
$fileIds = array_map(function (File $child) {
498-
return $child->getFileInfo()->getId();
499-
}, $childrenForMeta);
500-
$preloadedMetadata = $metadataManager->fetchMetadataFor($requestedMeta, $fileIds);
501-
502-
foreach ($childrenForMeta as $child) {
503-
$child->setMetadata($requestedMeta, $preloadedMetadata[$child->getFileInfo()->getId()]);
504-
}
505-
}
506-
}
507-
508440
if (in_array(self::SUBFILE_COUNT_PROPERTYNAME, $requestProperties, true)
509441
|| in_array(self::SUBFOLDER_COUNT_PROPERTYNAME, $requestProperties, true)) {
510442
$nbFiles = 0;
@@ -590,6 +522,59 @@ public function handleUpdateProperties($path, PropPatch $propPatch) {
590522
$node->setCreationTime((int) $time);
591523
return true;
592524
});
525+
526+
527+
/** @var IFilesMetadataManager */
528+
$filesMetadataManager = \OCP\Server::get(IFilesMetadataManager::class);
529+
$knownMetadata = $filesMetadataManager->getKnownMetadata();
530+
$metadata = $filesMetadataManager->getMetadata((int)$node->getFileId(), true);
531+
532+
// TODO: test different types
533+
// 1. cast value
534+
foreach ($propPatch->getRemainingMutations() as $mutation) {
535+
if (!str_starts_with($mutation, self::FILE_METADATA_PREFIX)) {
536+
continue;
537+
}
538+
539+
$propPatch->handle($mutation, function (mixed $value) use ($knownMetadata, $metadata, $mutation, $filesMetadataManager): bool {
540+
$metadataKey = substr($mutation, strlen(self::FILE_METADATA_PREFIX));
541+
542+
// If the metadata is unknown, it defaults to string.
543+
try {
544+
$type = $knownMetadata->getType($metadataKey);
545+
} catch (FilesMetadataNotFoundException) {
546+
$type = IMetadataValueWrapper::TYPE_STRING;
547+
}
548+
549+
switch ($type) {
550+
case IMetadataValueWrapper::TYPE_STRING:
551+
$metadata->setString($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
552+
break;
553+
case IMetadataValueWrapper::TYPE_INT:
554+
$metadata->setInt($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
555+
break;
556+
case IMetadataValueWrapper::TYPE_FLOAT:
557+
$metadata->setFloat($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
558+
break;
559+
case IMetadataValueWrapper::TYPE_BOOL:
560+
$metadata->setBool($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
561+
break;
562+
case IMetadataValueWrapper::TYPE_ARRAY:
563+
$metadata->setArray($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
564+
break;
565+
case IMetadataValueWrapper::TYPE_STRING_LIST:
566+
$metadata->setStringList($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
567+
break;
568+
case IMetadataValueWrapper::TYPE_INT_LIST:
569+
$metadata->setIntList($metadataKey, $value, $knownMetadata->isIndex($metadataKey));
570+
break;
571+
}
572+
573+
$filesMetadataManager->saveMetadata($metadata);
574+
return true;
575+
});
576+
}
577+
593578
/**
594579
* Disable modification of the displayname property for files and
595580
* folders via PROPPATCH. See PROPFIND for more information.

apps/dav/lib/Files/FileSearchBackend.php

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
use OC\Files\Search\SearchOrder;
3232
use OC\Files\Search\SearchQuery;
3333
use OC\Files\View;
34-
use OC\Metadata\IMetadataManager;
3534
use OCA\DAV\Connector\Sabre\CachingTree;
3635
use OCA\DAV\Connector\Sabre\Directory;
3736
use OCA\DAV\Connector\Sabre\FilesPlugin;
@@ -115,7 +114,6 @@ public function getPropertyDefinitionsForScope(string $href, ?string $path): arr
115114
new SearchPropertyDefinition(FilesPlugin::OWNER_DISPLAY_NAME_PROPERTYNAME, true, false, false),
116115
new SearchPropertyDefinition(FilesPlugin::DATA_FINGERPRINT_PROPERTYNAME, true, false, false),
117116
new SearchPropertyDefinition(FilesPlugin::HAS_PREVIEW_PROPERTYNAME, true, false, false, SearchPropertyDefinition::DATATYPE_BOOLEAN),
118-
new SearchPropertyDefinition(FilesPlugin::FILE_METADATA_SIZE, true, false, false, SearchPropertyDefinition::DATATYPE_STRING),
119117
new SearchPropertyDefinition(FilesPlugin::FILEID_PROPERTYNAME, true, false, false, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER),
120118
];
121119

@@ -152,27 +150,6 @@ private function getPropertyDefinitionsForMetadata(): array {
152150
* @param string[] $requestProperties
153151
*/
154152
public function preloadPropertyFor(array $nodes, array $requestProperties): void {
155-
if (in_array(FilesPlugin::FILE_METADATA_SIZE, $requestProperties, true)) {
156-
// Preloading of the metadata
157-
$fileIds = [];
158-
foreach ($nodes as $node) {
159-
/** @var \OCP\Files\Node|\OCA\DAV\Connector\Sabre\Node $node */
160-
if (str_starts_with($node->getFileInfo()->getMimeType(), 'image/')) {
161-
/** @var \OCA\DAV\Connector\Sabre\File $node */
162-
$fileIds[] = $node->getFileInfo()->getId();
163-
}
164-
}
165-
/** @var IMetaDataManager $metadataManager */
166-
$metadataManager = \OC::$server->get(IMetadataManager::class);
167-
$preloadedMetadata = $metadataManager->fetchMetadataFor('size', $fileIds);
168-
foreach ($nodes as $node) {
169-
/** @var \OCP\Files\Node|\OCA\DAV\Connector\Sabre\Node $node */
170-
if (str_starts_with($node->getFileInfo()->getMimeType(), 'image/')) {
171-
/** @var \OCA\DAV\Connector\Sabre\File $node */
172-
$node->setMetadata('size', $preloadedMetadata[$node->getFileInfo()->getId()]);
173-
}
174-
}
175-
}
176153
}
177154

178155
/**

apps/files/lib/Command/Scan.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,10 @@
4040
use OC\DB\ConnectionAdapter;
4141
use OC\FilesMetadata\FilesMetadataManager;
4242
use OC\ForbiddenException;
43-
use OC\Metadata\MetadataManager;
4443
use OCP\EventDispatcher\IEventDispatcher;
4544
use OCP\Files\Events\FileCacheUpdated;
4645
use OCP\Files\Events\NodeAddedToCache;
4746
use OCP\Files\Events\NodeRemovedFromCache;
48-
use OCP\Files\File;
4947
use OCP\Files\IRootFolder;
5048
use OCP\Files\Mount\IMountPoint;
5149
use OCP\Files\NotFoundException;
@@ -71,7 +69,6 @@ class Scan extends Base {
7169
public function __construct(
7270
private IUserManager $userManager,
7371
private IRootFolder $rootFolder,
74-
private MetadataManager $metadataManager,
7572
private FilesMetadataManager $filesMetadataManager,
7673
private IEventDispatcher $eventDispatcher,
7774
private LoggerInterface $logger,
@@ -141,10 +138,6 @@ protected function scanFiles(string $user, string $path, bool $scanMetadata, Out
141138
$this->abortIfInterrupted();
142139
if ($scanMetadata) {
143140
$node = $this->rootFolder->get($path);
144-
if ($node instanceof File) {
145-
$this->metadataManager->generateMetadata($node, false);
146-
}
147-
148141
$this->filesMetadataManager->refreshMetadata(
149142
$node,
150143
IFilesMetadataManager::PROCESS_LIVE | IFilesMetadataManager::PROCESS_BACKGROUND

apps/files_trashbin/lib/Trashbin.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
use OCP\Files\Folder;
6060
use OCP\Files\NotFoundException;
6161
use OCP\Files\NotPermittedException;
62+
use OCP\FilesMetadata\IFilesMetadataManager;
6263
use OCP\IConfig;
6364
use OCP\Lock\ILockingProvider;
6465
use OCP\Lock\LockedException;
@@ -993,7 +994,8 @@ private static function getVersionsFromTrash($filename, $timestamp, string $user
993994
$query = new CacheQueryBuilder(
994995
\OC::$server->getDatabaseConnection(),
995996
\OC::$server->getSystemConfig(),
996-
\OC::$server->get(LoggerInterface::class)
997+
\OC::$server->get(LoggerInterface::class),
998+
\OC::$server->get(IFilesMetadataManager::class),
997999
);
9981000
$normalizedParentPath = ltrim(Filesystem::normalizePath(dirname('files_trashbin/versions/'. $filename)), '/');
9991001
$parentId = $cache->getId($normalizedParentPath);

core/Application.php

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
use OC\Authentication\Notifications\Notifier as AuthenticationNotifier;
4545
use OC\Core\Listener\BeforeTemplateRenderedListener;
4646
use OC\Core\Notification\CoreNotifier;
47-
use OC\Metadata\FileEventListener;
4847
use OC\TagManager;
4948
use OCP\AppFramework\App;
5049
use OCP\AppFramework\Http\Events\BeforeLoginTemplateRenderedEvent;
@@ -54,13 +53,9 @@
5453
use OCP\DB\Events\AddMissingPrimaryKeyEvent;
5554
use OCP\DB\Types;
5655
use OCP\EventDispatcher\IEventDispatcher;
57-
use OCP\Files\Events\Node\NodeDeletedEvent;
58-
use OCP\Files\Events\Node\NodeWrittenEvent;
59-
use OCP\Files\Events\NodeRemovedFromCache;
6056
use OCP\User\Events\BeforeUserDeletedEvent;
6157
use OCP\User\Events\UserDeletedEvent;
6258
use OCP\Util;
63-
use OCP\IConfig;
6459

6560
/**
6661
* Class Application
@@ -331,18 +326,6 @@ public function __construct() {
331326
$eventDispatcher->addServiceListener(UserDeletedEvent::class, UserDeletedFilesCleanupListener::class);
332327
$eventDispatcher->addServiceListener(UserDeletedEvent::class, UserDeletedWebAuthnCleanupListener::class);
333328

334-
// Metadata
335-
/** @var IConfig $config */
336-
$config = $container->get(IConfig::class);
337-
if ($config->getSystemValueBool('enable_file_metadata', true)) {
338-
/** @psalm-suppress InvalidArgument */
339-
$eventDispatcher->addServiceListener(NodeDeletedEvent::class, FileEventListener::class);
340-
/** @psalm-suppress InvalidArgument */
341-
$eventDispatcher->addServiceListener(NodeRemovedFromCache::class, FileEventListener::class);
342-
/** @psalm-suppress InvalidArgument */
343-
$eventDispatcher->addServiceListener(NodeWrittenEvent::class, FileEventListener::class);
344-
}
345-
346329
// Tags
347330
$eventDispatcher->addServiceListener(UserDeletedEvent::class, TagManager::class);
348331
}

lib/composer/composer/autoload_classmap.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,14 +1496,6 @@
14961496
'OC\\Memcache\\Redis' => $baseDir . '/lib/private/Memcache/Redis.php',
14971497
'OC\\Memcache\\WithLocalCache' => $baseDir . '/lib/private/Memcache/WithLocalCache.php',
14981498
'OC\\MemoryInfo' => $baseDir . '/lib/private/MemoryInfo.php',
1499-
'OC\\Metadata\\Capabilities' => $baseDir . '/lib/private/Metadata/Capabilities.php',
1500-
'OC\\Metadata\\FileEventListener' => $baseDir . '/lib/private/Metadata/FileEventListener.php',
1501-
'OC\\Metadata\\FileMetadata' => $baseDir . '/lib/private/Metadata/FileMetadata.php',
1502-
'OC\\Metadata\\FileMetadataMapper' => $baseDir . '/lib/private/Metadata/FileMetadataMapper.php',
1503-
'OC\\Metadata\\IMetadataManager' => $baseDir . '/lib/private/Metadata/IMetadataManager.php',
1504-
'OC\\Metadata\\IMetadataProvider' => $baseDir . '/lib/private/Metadata/IMetadataProvider.php',
1505-
'OC\\Metadata\\MetadataManager' => $baseDir . '/lib/private/Metadata/MetadataManager.php',
1506-
'OC\\Metadata\\Provider\\ExifProvider' => $baseDir . '/lib/private/Metadata/Provider/ExifProvider.php',
15071499
'OC\\Migration\\BackgroundRepair' => $baseDir . '/lib/private/Migration/BackgroundRepair.php',
15081500
'OC\\Migration\\ConsoleOutput' => $baseDir . '/lib/private/Migration/ConsoleOutput.php',
15091501
'OC\\Migration\\SimpleOutput' => $baseDir . '/lib/private/Migration/SimpleOutput.php',

lib/composer/composer/autoload_static.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,14 +1529,6 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
15291529
'OC\\Memcache\\Redis' => __DIR__ . '/../../..' . '/lib/private/Memcache/Redis.php',
15301530
'OC\\Memcache\\WithLocalCache' => __DIR__ . '/../../..' . '/lib/private/Memcache/WithLocalCache.php',
15311531
'OC\\MemoryInfo' => __DIR__ . '/../../..' . '/lib/private/MemoryInfo.php',
1532-
'OC\\Metadata\\Capabilities' => __DIR__ . '/../../..' . '/lib/private/Metadata/Capabilities.php',
1533-
'OC\\Metadata\\FileEventListener' => __DIR__ . '/../../..' . '/lib/private/Metadata/FileEventListener.php',
1534-
'OC\\Metadata\\FileMetadata' => __DIR__ . '/../../..' . '/lib/private/Metadata/FileMetadata.php',
1535-
'OC\\Metadata\\FileMetadataMapper' => __DIR__ . '/../../..' . '/lib/private/Metadata/FileMetadataMapper.php',
1536-
'OC\\Metadata\\IMetadataManager' => __DIR__ . '/../../..' . '/lib/private/Metadata/IMetadataManager.php',
1537-
'OC\\Metadata\\IMetadataProvider' => __DIR__ . '/../../..' . '/lib/private/Metadata/IMetadataProvider.php',
1538-
'OC\\Metadata\\MetadataManager' => __DIR__ . '/../../..' . '/lib/private/Metadata/MetadataManager.php',
1539-
'OC\\Metadata\\Provider\\ExifProvider' => __DIR__ . '/../../..' . '/lib/private/Metadata/Provider/ExifProvider.php',
15401532
'OC\\Migration\\BackgroundRepair' => __DIR__ . '/../../..' . '/lib/private/Migration/BackgroundRepair.php',
15411533
'OC\\Migration\\ConsoleOutput' => __DIR__ . '/../../..' . '/lib/private/Migration/ConsoleOutput.php',
15421534
'OC\\Migration\\SimpleOutput' => __DIR__ . '/../../..' . '/lib/private/Migration/SimpleOutput.php',

0 commit comments

Comments
 (0)