-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Maxence Lange <[email protected]>
- Loading branch information
1 parent
d439317
commit e62e9e3
Showing
44 changed files
with
3,721 additions
and
144 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ | |
* @author Christoph Wurst <[email protected]> | ||
* @author Joas Schilling <[email protected]> | ||
* @author Lukas Reschke <[email protected]> | ||
* @author Maxence Lange <[email protected]> | ||
* @author Michael Jobst <[email protected]> | ||
* @author Morris Jobke <[email protected]> | ||
* @author Robin Appelman <[email protected]> | ||
|
@@ -49,8 +50,8 @@ | |
use Sabre\DAV\INode; | ||
use Sabre\DAV\PropFind; | ||
use Sabre\DAV\PropPatch; | ||
use Sabre\DAV\ServerPlugin; | ||
use Sabre\DAV\Server; | ||
use Sabre\DAV\ServerPlugin; | ||
use Sabre\DAV\Tree; | ||
use Sabre\HTTP\RequestInterface; | ||
use Sabre\HTTP\ResponseInterface; | ||
|
@@ -84,6 +85,7 @@ class FilesPlugin extends ServerPlugin { | |
public const SHARE_NOTE = '{http://nextcloud.org/ns}note'; | ||
public const SUBFOLDER_COUNT_PROPERTYNAME = '{http://nextcloud.org/ns}contained-folder-count'; | ||
public const SUBFILE_COUNT_PROPERTYNAME = '{http://nextcloud.org/ns}contained-file-count'; | ||
public const FILE_METADATA_PREFIX = '{http://nextcloud.org/ns}metadata-'; | ||
public const FILE_METADATA_SIZE = '{http://nextcloud.org/ns}file-metadata-size'; | ||
public const FILE_METADATA_GPS = '{http://nextcloud.org/ns}file-metadata-gps'; | ||
|
||
|
@@ -389,6 +391,11 @@ public function handleGetProperties(PropFind $propFind, \Sabre\DAV\INode $node) | |
$propFind->handle(self::CREATION_TIME_PROPERTYNAME, function () use ($node) { | ||
return $node->getFileInfo()->getCreationTime(); | ||
}); | ||
|
||
foreach ($node->getFileInfo()->getMetadata() as $metadataKey => $metadataValue) { | ||
$propFind->handle(self::FILE_METADATA_PREFIX . $metadataKey, $metadataValue); | ||
} | ||
|
||
/** | ||
* Return file/folder name as displayname. The primary reason to | ||
* implement it this way is to avoid costly fallback to | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
* | ||
* @author Christian <[email protected]> | ||
* @author Christoph Wurst <[email protected]> | ||
* @author Maxence Lange <[email protected]> | ||
* @author Robin Appelman <[email protected]> | ||
* @author Roeland Jago Douma <[email protected]> | ||
* | ||
|
@@ -42,6 +43,9 @@ | |
use OCP\Files\Search\ISearchOperator; | ||
use OCP\Files\Search\ISearchOrder; | ||
use OCP\Files\Search\ISearchQuery; | ||
use OCP\FilesMetadata\IFilesMetadataManager; | ||
use OCP\FilesMetadata\Model\IMetadataQuery; | ||
use OCP\FilesMetadata\Model\IMetadataValueWrapper; | ||
use OCP\IUser; | ||
use OCP\Share\IManager; | ||
use Sabre\DAV\Exception\NotFound; | ||
|
@@ -57,37 +61,14 @@ | |
class FileSearchBackend implements ISearchBackend { | ||
public const OPERATOR_LIMIT = 100; | ||
|
||
/** @var CachingTree */ | ||
private $tree; | ||
|
||
/** @var IUser */ | ||
private $user; | ||
|
||
/** @var IRootFolder */ | ||
private $rootFolder; | ||
|
||
/** @var IManager */ | ||
private $shareManager; | ||
|
||
/** @var View */ | ||
private $view; | ||
|
||
/** | ||
* FileSearchBackend constructor. | ||
* | ||
* @param CachingTree $tree | ||
* @param IUser $user | ||
* @param IRootFolder $rootFolder | ||
* @param IManager $shareManager | ||
* @param View $view | ||
* @internal param IRootFolder $rootFolder | ||
*/ | ||
public function __construct(CachingTree $tree, IUser $user, IRootFolder $rootFolder, IManager $shareManager, View $view) { | ||
$this->tree = $tree; | ||
$this->user = $user; | ||
$this->rootFolder = $rootFolder; | ||
$this->shareManager = $shareManager; | ||
$this->view = $view; | ||
public function __construct( | ||
private CachingTree $tree, | ||
private IUser $user, | ||
private IRootFolder $rootFolder, | ||
private IManager $shareManager, | ||
private View $view, | ||
private IFilesMetadataManager $filesMetadataManager, | ||
) { | ||
} | ||
|
||
/** | ||
|
@@ -115,7 +96,7 @@ public function getPropertyDefinitionsForScope(string $href, ?string $path): arr | |
// all valid scopes support the same schema | ||
|
||
//todo dynamically load all propfind properties that are supported | ||
return [ | ||
$props = [ | ||
// queryable properties | ||
new SearchPropertyDefinition('{DAV:}displayname', true, true, true), | ||
new SearchPropertyDefinition('{DAV:}getcontenttype', true, true, true), | ||
|
@@ -137,6 +118,33 @@ public function getPropertyDefinitionsForScope(string $href, ?string $path): arr | |
new SearchPropertyDefinition(FilesPlugin::FILE_METADATA_SIZE, true, false, false, SearchPropertyDefinition::DATATYPE_STRING), | ||
new SearchPropertyDefinition(FilesPlugin::FILEID_PROPERTYNAME, true, false, false, SearchPropertyDefinition::DATATYPE_NONNEGATIVE_INTEGER), | ||
]; | ||
|
||
return array_merge($props, $this->getPropertyDefinitionsForMetadata()); | ||
} | ||
|
||
|
||
private function getPropertyDefinitionsForMetadata(): array { | ||
$metadataProps = []; | ||
$metadata = $this->filesMetadataManager->getKnownMetadata(); | ||
$indexes = $metadata->getIndexes(); | ||
foreach ($metadata->getKeys() as $key) { | ||
$isIndex = in_array($key, $indexes); | ||
$type = match ($metadata->getType($key)) { | ||
IMetadataValueWrapper::TYPE_INT => SearchPropertyDefinition::DATATYPE_INTEGER, | ||
IMetadataValueWrapper::TYPE_FLOAT => SearchPropertyDefinition::DATATYPE_DECIMAL, | ||
IMetadataValueWrapper::TYPE_BOOL => SearchPropertyDefinition::DATATYPE_BOOLEAN, | ||
default => SearchPropertyDefinition::DATATYPE_STRING | ||
}; | ||
$metadataProps[] = new SearchPropertyDefinition( | ||
FilesPlugin::FILE_METADATA_PREFIX . $key, | ||
true, | ||
$isIndex, | ||
$isIndex, | ||
$type | ||
); | ||
} | ||
|
||
return $metadataProps; | ||
} | ||
|
||
/** | ||
|
@@ -300,11 +308,20 @@ private function getHrefForNode(Node $node) { | |
|
||
/** | ||
* @param Query $query | ||
* | ||
* @return ISearchQuery | ||
*/ | ||
private function transformQuery(Query $query): ISearchQuery { | ||
$orders = array_map(function (Order $order): ISearchOrder { | ||
$direction = $order->order === Order::ASC ? ISearchOrder::DIRECTION_ASCENDING : ISearchOrder::DIRECTION_DESCENDING; | ||
if (str_starts_with($order->property->name, FilesPlugin::FILE_METADATA_PREFIX)) { | ||
return new SearchOrder($direction, substr($order->property->name, strlen(FilesPlugin::FILE_METADATA_PREFIX)), IMetadataQuery::EXTRA); | ||
} else { | ||
return new SearchOrder($direction, $this->mapPropertyNameToColumn($order->property)); | ||
} | ||
}, $query->orderBy); | ||
|
||
$limit = $query->limit; | ||
$orders = array_map([$this, 'mapSearchOrder'], $query->orderBy); | ||
$offset = $limit->firstResult; | ||
|
||
$limitHome = false; | ||
|
@@ -352,14 +369,6 @@ private function countSearchOperators(Operator $operator): int { | |
} | ||
} | ||
|
||
/** | ||
* @param Order $order | ||
* @return ISearchOrder | ||
*/ | ||
private function mapSearchOrder(Order $order) { | ||
return new SearchOrder($order->order === Order::ASC ? ISearchOrder::DIRECTION_ASCENDING : ISearchOrder::DIRECTION_DESCENDING, $this->mapPropertyNameToColumn($order->property)); | ||
} | ||
|
||
/** | ||
* @param Operator $operator | ||
* @return ISearchOperator | ||
|
@@ -387,7 +396,16 @@ private function transformSearchOperation(Operator $operator) { | |
if (!($operator->arguments[1] instanceof Literal)) { | ||
throw new \InvalidArgumentException('Invalid argument 2 for ' . $trimmedType . ' operation, expected literal'); | ||
} | ||
return new SearchComparison($trimmedType, $this->mapPropertyNameToColumn($operator->arguments[0]), $this->castValue($operator->arguments[0], $operator->arguments[1]->value)); | ||
|
||
$property = $operator->arguments[0]; | ||
$value = $this->castValue($property, $operator->arguments[1]->value); | ||
if (str_starts_with($property->name, FilesPlugin::FILE_METADATA_PREFIX)) { | ||
return new SearchComparison($trimmedType, substr($property->name, strlen(FilesPlugin::FILE_METADATA_PREFIX)), $value, IMetadataQuery::EXTRA); | ||
} else { | ||
return new SearchComparison($trimmedType, $this->mapPropertyNameToColumn($property), $value); | ||
} | ||
|
||
// no break | ||
case Operator::OPERATION_IS_COLLECTION: | ||
return new SearchComparison('eq', 'mimetype', ICacheEntry::DIRECTORY_MIMETYPE); | ||
default: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ | |
* @author Joas Schilling <[email protected]> | ||
* @author John Molakvoæ <[email protected]> | ||
* @author Lukas Reschke <[email protected]> | ||
* @author Maxence Lange <[email protected]> | ||
* @author Morris Jobke <[email protected]> | ||
* @author Robin Appelman <[email protected]> | ||
* @author Roeland Jago Douma <[email protected]> | ||
|
@@ -76,6 +77,7 @@ | |
use OCP\AppFramework\Http\Response; | ||
use OCP\Diagnostics\IEventLogger; | ||
use OCP\EventDispatcher\IEventDispatcher; | ||
use OCP\FilesMetadata\IFilesMetadataManager; | ||
use OCP\ICacheFactory; | ||
use OCP\IRequest; | ||
use OCP\Profiler\IProfiler; | ||
|
@@ -316,7 +318,8 @@ public function __construct(IRequest $request, string $baseUri) { | |
$user, | ||
\OC::$server->getRootFolder(), | ||
\OC::$server->getShareManager(), | ||
$view | ||
$view, | ||
\OCP\Server::get(IFilesMetadataManager::class) | ||
)); | ||
$this->server->addPlugin( | ||
new BulkUploadPlugin( | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ | |
* @author Joel S <[email protected]> | ||
* @author Jörn Friedrich Dreyer <[email protected]> | ||
* @author [email protected] <[email protected]> | ||
* @author Maxence Lange <[email protected]> | ||
* @author Robin Appelman <[email protected]> | ||
* @author Roeland Jago Douma <[email protected]> | ||
* @author Thomas Müller <[email protected]> | ||
|
@@ -37,17 +38,19 @@ | |
use OC\Core\Command\InterruptedException; | ||
use OC\DB\Connection; | ||
use OC\DB\ConnectionAdapter; | ||
use OC\FilesMetadata\FilesMetadataManager; | ||
use OC\ForbiddenException; | ||
use OC\Metadata\MetadataManager; | ||
use OCP\EventDispatcher\IEventDispatcher; | ||
use OCP\Files\Events\FileCacheUpdated; | ||
use OCP\Files\Events\NodeAddedToCache; | ||
use OCP\Files\Events\NodeRemovedFromCache; | ||
use OCP\Files\File; | ||
use OC\ForbiddenException; | ||
use OC\Metadata\MetadataManager; | ||
use OCP\EventDispatcher\IEventDispatcher; | ||
use OCP\Files\IRootFolder; | ||
use OCP\Files\Mount\IMountPoint; | ||
use OCP\Files\NotFoundException; | ||
use OCP\Files\StorageNotAvailableException; | ||
use OCP\FilesMetadata\IFilesMetadataManager; | ||
use OCP\IUserManager; | ||
use Psr\Log\LoggerInterface; | ||
use Symfony\Component\Console\Helper\Table; | ||
|
@@ -69,6 +72,7 @@ public function __construct( | |
private IUserManager $userManager, | ||
private IRootFolder $rootFolder, | ||
private MetadataManager $metadataManager, | ||
private FilesMetadataManager $filesMetadataManager, | ||
private IEventDispatcher $eventDispatcher, | ||
private LoggerInterface $logger, | ||
) { | ||
|
@@ -140,6 +144,11 @@ protected function scanFiles(string $user, string $path, bool $scanMetadata, Out | |
if ($node instanceof File) { | ||
$this->metadataManager->generateMetadata($node, false); | ||
} | ||
|
||
$this->filesMetadataManager->refreshMetadata( | ||
$node, | ||
IFilesMetadataManager::PROCESS_LIVE | IFilesMetadataManager::PROCESS_BACKGROUND | ||
); | ||
} | ||
}); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
/** | ||
* @copyright Copyright (c) 2018 Robin Appelman <[email protected]> | ||
* | ||
* @author Maxence Lange <[email protected]> | ||
* @author Robin Appelman <[email protected]> | ||
* | ||
* @license GNU AGPL version 3 or any later version | ||
|
@@ -23,6 +24,7 @@ | |
namespace OCA\Files_Trashbin\Trash; | ||
|
||
use OCP\Files\FileInfo; | ||
use OCP\FilesMetadata\Model\IFilesMetadata; | ||
use OCP\IUser; | ||
|
||
class TrashItem implements ITrashItem { | ||
|
@@ -190,4 +192,12 @@ public function getUploadTime(): int { | |
public function getParentId(): int { | ||
return $this->fileInfo->getParentId(); | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
* @return array<string, int|string|bool|float|string[]|int[]> | ||
*/ | ||
public function getMetadata(): array { | ||
return $this->fileInfo->getMetadata(); | ||
} | ||
} |
Oops, something went wrong.