From 7af8f124a6eadc1df22c3bdf06f6dfa54094e1ea Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 20 Nov 2024 14:48:59 -0500 Subject: [PATCH] feat(files): Add help + update description of `files:scan` Also: Fixes #27031 (improves error output) Fixes #27029 (adds exit status 1 if any errors during a run) Refactor: moved main "worker" function location for readability Signed-off-by: Josh --- apps/files/lib/Command/Scan.php | 131 +++++++++++++++++--------------- 1 file changed, 69 insertions(+), 62 deletions(-) diff --git a/apps/files/lib/Command/Scan.php b/apps/files/lib/Command/Scan.php index cf1cb04b9afe3..0d965d4970fae 100644 --- a/apps/files/lib/Command/Scan.php +++ b/apps/files/lib/Command/Scan.php @@ -55,48 +55,109 @@ protected function configure(): void { $this ->setName('files:scan') - ->setDescription('rescan filesystem') + ->setDescription('Scans the filesystem for new files and updates the file cache') + ->setHelp('You can rescan all files or only those of select user(s) or a select path. Statistics will be shown at the end of the scan by default.') ->addArgument( 'user_id', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, - 'will rescan all files of the given user(s)' + 'Rescan all files of the specified user(s)' ) ->addOption( 'path', 'p', InputOption::VALUE_REQUIRED, - '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' + 'Limit rescan to the specified path, eg. --path="/alice/files/Music". Overrides the user_id and --all parameters; the user_id is determined from the path.' ) ->addOption( 'generate-metadata', null, InputOption::VALUE_OPTIONAL, - 'Generate metadata for all scanned files; if specified only generate for named value', + 'Generate metadata for all scanned files; if specified only generate for named value.', '' ) ->addOption( 'all', null, InputOption::VALUE_NONE, - 'will rescan all files of all known users' + 'Rescan all files of all known users' )->addOption( 'unscanned', null, InputOption::VALUE_NONE, - 'only scan files which are marked as not fully scanned' + 'Only scan files which are marked as not fully scanned' )->addOption( 'shallow', null, InputOption::VALUE_NONE, - 'do not scan folders recursively' + 'Do not scan folders recursively' )->addOption( 'home-only', null, InputOption::VALUE_NONE, - 'only scan the home storage, ignoring any mounted external storage or share' + 'Only scan the home storage, ignoring any mounted external storage or share' ); } + protected function execute(InputInterface $input, OutputInterface $output): int { + $inputPath = $input->getOption('path'); + if ($inputPath) { + $inputPath = '/' . trim($inputPath, '/'); + [, $user,] = explode('/', $inputPath, 3); + $users = [$user]; + } elseif ($input->getOption('all')) { + $users = $this->userManager->search(''); + } else { + $users = $input->getArgument('user_id'); + } + + # check quantity of users to be process and show it on the command line + $users_total = count($users); + if ($users_total === 0) { + $output->writeln('Please specify the user id to scan, --all to scan for all users or --path=...'); + return self::FAILURE; + } + + $this->initTools($output); + + // getOption() logic on VALUE_OPTIONAL + $metadata = null; // null if --generate-metadata is not set, empty if option have no value, value if set + if ($input->getOption('generate-metadata') !== '') { + $metadata = $input->getOption('generate-metadata') ?? ''; + } + + $user_count = 0; + foreach ($users as $user) { + if (is_object($user)) { + $user = $user->getUID(); + } + $path = $inputPath ?: '/' . $user; + ++$user_count; + if ($this->userManager->userExists($user)) { + $output->writeln("Starting scan for user $user_count out of $users_total ($user)"); + $this->scanFiles($user, $path, $metadata, $output, $input->getOption('unscanned'), !$input->getOption('shallow'), $input->getOption('home-only')); + $output->writeln('', OutputInterface::VERBOSITY_VERBOSE); + } else { + $output->writeln("User $user_count out of $users_total not found ($user)"); + $output->writeln('', OutputInterface::VERBOSITY_VERBOSE); + ++$this->errorsCounter; + } + + try { + $this->abortIfInterrupted(); + } catch (InterruptedException $e) { + break; + } + } + + $this->presentStats($output); + + if ($this->errorsCounter > 0) { + return self::FAILURE; + } + + return self::SUCCESS; + } + protected function scanFiles(string $user, string $path, ?string $scanMetadata, OutputInterface $output, bool $backgroundScan = false, bool $recursive = true, bool $homeOnly = false): void { $connection = $this->reconnectToDatabase($output); $scanner = new Scanner( @@ -176,60 +237,6 @@ public function filterHomeMount(IMountPoint $mountPoint): bool { return substr_count($mountPoint->getMountPoint(), '/') <= 3; } - protected function execute(InputInterface $input, OutputInterface $output): int { - $inputPath = $input->getOption('path'); - if ($inputPath) { - $inputPath = '/' . trim($inputPath, '/'); - [, $user,] = explode('/', $inputPath, 3); - $users = [$user]; - } elseif ($input->getOption('all')) { - $users = $this->userManager->search(''); - } else { - $users = $input->getArgument('user_id'); - } - - # check quantity of users to be process and show it on the command line - $users_total = count($users); - if ($users_total === 0) { - $output->writeln('Please specify the user id to scan, --all to scan for all users or --path=...'); - return self::FAILURE; - } - - $this->initTools($output); - - // getOption() logic on VALUE_OPTIONAL - $metadata = null; // null if --generate-metadata is not set, empty if option have no value, value if set - if ($input->getOption('generate-metadata') !== '') { - $metadata = $input->getOption('generate-metadata') ?? ''; - } - - $user_count = 0; - foreach ($users as $user) { - if (is_object($user)) { - $user = $user->getUID(); - } - $path = $inputPath ?: '/' . $user; - ++$user_count; - if ($this->userManager->userExists($user)) { - $output->writeln("Starting scan for user $user_count out of $users_total ($user)"); - $this->scanFiles($user, $path, $metadata, $output, $input->getOption('unscanned'), !$input->getOption('shallow'), $input->getOption('home-only')); - $output->writeln('', OutputInterface::VERBOSITY_VERBOSE); - } else { - $output->writeln("Unknown user $user_count $user"); - $output->writeln('', OutputInterface::VERBOSITY_VERBOSE); - } - - try { - $this->abortIfInterrupted(); - } catch (InterruptedException $e) { - break; - } - } - - $this->presentStats($output); - return self::SUCCESS; - } - /** * Initialises some useful tools for the Command */