Skip to content

Commit 6a611e3

Browse files
committed
Allow scanning for metadata with occ scan:file --metadata
Signed-off-by: Carl Schwan <carl@carlschwan.eu>
1 parent 9c42717 commit 6a611e3

File tree

2 files changed

+67
-15
lines changed

2 files changed

+67
-15
lines changed

apps/files/lib/Command/Scan.php

+65-15
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,17 @@
3737
use OC\Core\Command\InterruptedException;
3838
use OC\DB\Connection;
3939
use OC\DB\ConnectionAdapter;
40+
use OC\Files\Filesystem;
41+
use OC\Files\Node\File;
42+
use OC\Files\Node\Folder;
43+
use OC\Files\Node\NonExistingFile;
44+
use OC\Files\Node\NonExistingFolder;
45+
use OC\Files\View;
4046
use OC\ForbiddenException;
47+
use OC\Metadata\MetadataManager;
4148
use OCP\EventDispatcher\IEventDispatcher;
49+
use OCP\Files\FileInfo;
50+
use OCP\Files\IRootFolder;
4251
use OCP\Files\Mount\IMountPoint;
4352
use OCP\Files\NotFoundException;
4453
use OCP\Files\StorageNotAvailableException;
@@ -51,19 +60,18 @@
5160
use Symfony\Component\Console\Output\OutputInterface;
5261

5362
class Scan extends Base {
63+
private IUserManager $userManager;
64+
protected float $execTime = 0;
65+
protected int $foldersCounter = 0;
66+
protected int $filesCounter = 0;
67+
private IRootFolder $root;
68+
private View $view;
5469

55-
/** @var IUserManager $userManager */
56-
private $userManager;
57-
/** @var float */
58-
protected $execTime = 0;
59-
/** @var int */
60-
protected $foldersCounter = 0;
61-
/** @var int */
62-
protected $filesCounter = 0;
63-
64-
public function __construct(IUserManager $userManager) {
70+
public function __construct(IUserManager $userManager, IRootFolder $rootFolder, View $view) {
6571
$this->userManager = $userManager;
6672
parent::__construct();
73+
$this->root = $rootFolder;
74+
$this->view = $view;
6775
}
6876

6977
protected function configure() {
@@ -83,6 +91,13 @@ protected function configure() {
8391
InputArgument::OPTIONAL,
8492
'limit rescan to this path, eg. --path="/alice/files/Music", the user_id is determined by the path and the user_id parameter and --all are ignored'
8593
)
94+
->addOption(
95+
'metadata',
96+
null,
97+
InputOption::VALUE_NONE,
98+
'Add missing file metadata',
99+
false
100+
)
86101
->addOption(
87102
'all',
88103
null,
@@ -106,21 +121,28 @@ protected function configure() {
106121
);
107122
}
108123

109-
protected function scanFiles($user, $path, OutputInterface $output, $backgroundScan = false, $recursive = true, $homeOnly = false) {
124+
protected function scanFiles($user, $path, bool $scanMetadata, OutputInterface $output, $backgroundScan = false, $recursive = true, $homeOnly = false) {
110125
$connection = $this->reconnectToDatabase($output);
111126
$scanner = new \OC\Files\Utils\Scanner(
112127
$user,
113128
new ConnectionAdapter($connection),
114-
\OC::$server->query(IEventDispatcher::class),
129+
\OC::$server->get(IEventDispatcher::class),
115130
\OC::$server->get(LoggerInterface::class)
116131
);
117132

118133
# check on each file/folder if there was a user interrupt (ctrl-c) and throw an exception
119134

120-
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function ($path) use ($output) {
135+
/** @var MetadataManager $metadataManager */
136+
$metadataManager = \OC::$server->get(MetadataManager::class);
137+
138+
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function ($path) use ($output, $metadataManager, $scanMetadata) {
121139
$output->writeln("\tFile\t<info>$path</info>", OutputInterface::VERBOSITY_VERBOSE);
122140
++$this->filesCounter;
123141
$this->abortIfInterrupted();
142+
if ($scanMetadata) {
143+
$node = $this->getNodeForPath($path);
144+
$metadataManager->generateMetadata($node, true);
145+
}
124146
});
125147

126148
$scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function ($path) use ($output) {
@@ -150,7 +172,7 @@ protected function scanFiles($user, $path, OutputInterface $output, $backgroundS
150172
# exit the function if ctrl-c has been pressed
151173
$output->writeln('Interrupted by user');
152174
} catch (NotFoundException $e) {
153-
$output->writeln('<error>Path not found: ' . $e->getMessage() . '</error>');
175+
$output->writeln('<error>Path not found: ' . $e->getMessage() . '</error>' . var_export($e->getTraceAsString()));
154176
} catch (\Exception $e) {
155177
$output->writeln('<error>Exception during scan: ' . $e->getMessage() . '</error>');
156178
$output->writeln('<error>' . $e->getTraceAsString() . '</error>');
@@ -197,7 +219,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
197219
++$user_count;
198220
if ($this->userManager->userExists($user)) {
199221
$output->writeln("Starting scan for user $user_count out of $users_total ($user)");
200-
$this->scanFiles($user, $path, $output, $input->getOption('unscanned'), !$input->getOption('shallow'), $input->getOption('home-only'));
222+
$this->scanFiles($user, $path, $input->getOption('metadata'), $output, $input->getOption('unscanned'), !$input->getOption('shallow'), $input->getOption('home-only'));
201223
$output->writeln('', OutputInterface::VERBOSITY_VERBOSE);
202224
} else {
203225
$output->writeln("<error>Unknown user $user_count $user</error>");
@@ -312,4 +334,32 @@ protected function reconnectToDatabase(OutputInterface $output): Connection {
312334
}
313335
return $connection;
314336
}
337+
338+
private function getNodeForPath($path) {
339+
$pathParts = explode('/', $path);
340+
// FIXME ugly hack to get it working for local file
341+
array_shift($pathParts);
342+
array_shift($pathParts);
343+
array_shift($pathParts);
344+
$info = Filesystem::getFileInfo('/' . implode('/', $pathParts));
345+
if (!$info) {
346+
$fullPath = Filesystem::getView()->getAbsolutePath($path);
347+
if (isset($this->deleteMetaCache[$fullPath])) {
348+
$info = $this->deleteMetaCache[$fullPath];
349+
} else {
350+
$info = null;
351+
}
352+
if (Filesystem::is_dir($path)) {
353+
return new NonExistingFolder($this->root, $this->view, $fullPath, $info);
354+
} else {
355+
return new NonExistingFile($this->root, $this->view, $fullPath, $info);
356+
}
357+
}
358+
if ($info->getType() === FileInfo::TYPE_FILE) {
359+
return new File($this->root, $this->view, $info->getPath(), $info);
360+
} else {
361+
return new Folder($this->root, $this->view, $info->getPath(), $info);
362+
}
363+
}
364+
315365
}

lib/private/Files/View.php

+2
Original file line numberDiff line numberDiff line change
@@ -1385,9 +1385,11 @@ public function getFileInfo($path, $includeMountPoints = true) {
13851385
$mount = Filesystem::getMountManager()->find($path);
13861386
$storage = $mount->getStorage();
13871387
$internalPath = $mount->getInternalPath($path);
1388+
echo $internalPath . ' ' . $path . ' - ' . $mount->getMountPoint();
13881389
if ($storage) {
13891390
$data = $this->getCacheEntry($storage, $internalPath, $relativePath);
13901391

1392+
13911393
if (!$data instanceof ICacheEntry) {
13921394
return false;
13931395
}

0 commit comments

Comments
 (0)