Scan.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OCA\Files_External\Command;
  8. use OC\Files\Cache\Scanner;
  9. use OCA\Files_External\Service\GlobalStoragesService;
  10. use OCP\IUserManager;
  11. use Symfony\Component\Console\Helper\Table;
  12. use Symfony\Component\Console\Input\InputArgument;
  13. use Symfony\Component\Console\Input\InputInterface;
  14. use Symfony\Component\Console\Input\InputOption;
  15. use Symfony\Component\Console\Output\OutputInterface;
  16. class Scan extends StorageAuthBase {
  17. protected float $execTime = 0;
  18. protected int $foldersCounter = 0;
  19. protected int $filesCounter = 0;
  20. public function __construct(
  21. GlobalStoragesService $globalService,
  22. IUserManager $userManager
  23. ) {
  24. parent::__construct($globalService, $userManager);
  25. }
  26. protected function configure(): void {
  27. $this
  28. ->setName('files_external:scan')
  29. ->setDescription('Scan an external storage for changed files')
  30. ->addArgument(
  31. 'mount_id',
  32. InputArgument::REQUIRED,
  33. 'the mount id of the mount to scan'
  34. )->addOption(
  35. 'user',
  36. 'u',
  37. InputOption::VALUE_REQUIRED,
  38. 'The username for the remote mount (required only for some mount configuration that don\'t store credentials)'
  39. )->addOption(
  40. 'password',
  41. 'p',
  42. InputOption::VALUE_REQUIRED,
  43. 'The password for the remote mount (required only for some mount configuration that don\'t store credentials)'
  44. )->addOption(
  45. 'path',
  46. '',
  47. InputOption::VALUE_OPTIONAL,
  48. 'The path in the storage to scan',
  49. ''
  50. );
  51. parent::configure();
  52. }
  53. protected function execute(InputInterface $input, OutputInterface $output): int {
  54. [, $storage] = $this->createStorage($input, $output);
  55. if ($storage === null) {
  56. return 1;
  57. }
  58. $path = $input->getOption('path');
  59. $this->execTime = -microtime(true);
  60. /** @var Scanner $scanner */
  61. $scanner = $storage->getScanner();
  62. $scanner->listen('\OC\Files\Cache\Scanner', 'scanFile', function (string $path) use ($output) {
  63. $output->writeln("\tFile\t<info>$path</info>", OutputInterface::VERBOSITY_VERBOSE);
  64. ++$this->filesCounter;
  65. $this->abortIfInterrupted();
  66. });
  67. $scanner->listen('\OC\Files\Cache\Scanner', 'scanFolder', function (string $path) use ($output) {
  68. $output->writeln("\tFolder\t<info>$path</info>", OutputInterface::VERBOSITY_VERBOSE);
  69. ++$this->foldersCounter;
  70. $this->abortIfInterrupted();
  71. });
  72. $scanner->scan($path);
  73. $this->presentStats($output);
  74. return 0;
  75. }
  76. /**
  77. * @param OutputInterface $output
  78. */
  79. protected function presentStats(OutputInterface $output): void {
  80. // Stop the timer
  81. $this->execTime += microtime(true);
  82. $headers = [
  83. 'Folders', 'Files', 'Elapsed time'
  84. ];
  85. $this->showSummary($headers, [], $output);
  86. }
  87. /**
  88. * Shows a summary of operations
  89. *
  90. * @param string[] $headers
  91. * @param string[] $rows
  92. * @param OutputInterface $output
  93. */
  94. protected function showSummary(array $headers, array $rows, OutputInterface $output): void {
  95. $niceDate = $this->formatExecTime();
  96. if (!$rows) {
  97. $rows = [
  98. $this->foldersCounter,
  99. $this->filesCounter,
  100. $niceDate,
  101. ];
  102. }
  103. $table = new Table($output);
  104. $table
  105. ->setHeaders($headers)
  106. ->setRows([$rows]);
  107. $table->render();
  108. }
  109. /**
  110. * Formats microtime into a human readable format
  111. *
  112. * @return string
  113. */
  114. protected function formatExecTime(): string {
  115. $secs = round($this->execTime);
  116. # convert seconds into HH:MM:SS form
  117. return sprintf('%02d:%02d:%02d', ($secs / 3600), ($secs / 60 % 60), $secs % 60);
  118. }
  119. }