summaryrefslogtreecommitdiffstats
path: root/apps/cloud_federation_api
Commit message (Expand)AuthorAgeFilesLines
* [tx-robot] updated from transifexNextcloud bot2021-03-142-0/+14
* Move requesthandler controller to LoggerInterfaceRoeland Jago Douma2021-03-101-3/+3
* Update autoloader filesRoeland Jago Douma2021-03-021-2/+4
* [tx-robot] updated from transifexNextcloud bot2021-02-122-0/+14
* This is 22Joas Schilling2021-02-031-1/+1
* Update all composer autoloader filesChristoph Wurst2021-01-282-1/+33
* [tx-robot] updated from transifexNextcloud bot2021-01-282-0/+14
* [tx-robot] updated from transifexNextcloud bot2021-01-222-0/+14
* [tx-robot] updated from transifexNextcloud bot2021-01-192-2/+2
* [tx-robot] updated from transifexNextcloud bot2021-01-174-4/+18
* [tx-robot] updated from transifexNextcloud bot2021-01-142-0/+14
* [tx-robot] updated from transifexNextcloud bot2020-12-282-0/+14
* [tx-robot] updated from transifexNextcloud bot2020-12-102-0/+14
* [tx-robot] updated from transifexNextcloud bot2020-12-082-0/+14
* [tx-robot] updated from transifexNextcloud bot2020-12-062-0/+14
* rebuild autoloader scripts with 2.0.7Robin Appelman2020-11-264-3/+5
* [tx-robot] updated from transifexNextcloud bot2020-11-262-0/+14
* [tx-robot] updated from transifexNextcloud bot2020-11-252-2/+4
* [tx-robot] updated from transifexNextcloud bot2020-11-112-0/+14
* [tx-robot] updated from transifexNextcloud bot2020-11-102-0/+14
* [tx-robot] updated from transifexNextcloud bot2020-10-312-0/+14
* [tx-robot] updated from transifexNextcloud bot2020-10-292-0/+14
* [tx-robot] updated from transifexNextcloud bot2020-10-204-0/+26
* [tx-robot] updated from transifexNextcloud bot2020-10-192-0/+14
* [tx-robot] updated from transifexNextcloud bot2020-10-142-0/+14
* [tx-robot] updated from transifexNextcloud bot2020-10-022-0/+14
* [tx-robot] updated from transifexNextcloud bot2020-10-012-0/+14
* [tx-robot] updated from transifexNextcloud bot2020-09-264-6/+20
* Update autloaderRoeland Jago Douma2020-09-241-1/+1
* [tx-robot] updated from transifexNextcloud bot2020-09-242-2/+2
* [tx-robot] updated from transifexNextcloud bot2020-09-234-0/+28
* [tx-robot] updated from transifexNextcloud bot2020-09-2010-0/+70
* Add transifex config for all new appsMorris Jobke2020-09-181-0/+0
* Bump versionsJoas Schilling2020-09-181-2/+2
* Update the license headers for Nextcloud 20Christoph Wurst2020-08-241-0/+1
* Move cloud_federation_api to bootstrap mechanismMorris Jobke2020-07-082-31/+16
* Bump app versions and requirementsJoas Schilling2020-05-071-17/+17
* Update license headers for 19Christoph Wurst2020-04-292-1/+5
* Fix route definitions of cloud_federation_apiJoas Schilling2020-04-181-11/+13
* PHP CS fixesJoas Schilling2020-04-181-0/+1
* Allow some apps to have root URLs in their own routing fileJoas Schilling2020-04-181-0/+36
* Format control structures, classes, methods and functionChristoph Wurst2020-04-103-9/+3
* Remove spaces after method or function callChristoph Wurst2020-04-091-1/+1
* Use exactly one empty line after the namespace declarationChristoph Wurst2020-04-093-2/+1
* Update the license headers for Nextcloud 19Christoph Wurst2020-03-311-0/+1
* Merge pull request #20170 from nextcloud/techdebt/remove-unused-importsChristoph Wurst2020-03-271-2/+0
|\
| * Remove unused importsChristoph Wurst2020-03-251-2/+0
* | Use the short array syntax, everywhereChristoph Wurst2020-03-261-1/+1
|/
* Update autoloaders for composer v1.10.1Christoph Wurst2020-03-191-0/+3
* Fix app updatesRoeland Jago Douma2020-01-211-2/+2
Argument::IS_ARRAY, 'will rescan all files of the given user(s)' ) ->addOption( 'path', 'p', InputArgument::OPTIONAL, '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' ) ->addOption( 'quiet', 'q', InputOption::VALUE_NONE, 'suppress any output' ) ->addOption( 'verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'verbose the output' ) ->addOption( 'all', null, InputOption::VALUE_NONE, 'will rescan all files of all known users' ); } public function checkScanWarning($fullPath, OutputInterface $output) { $normalizedPath = basename(\OC\Files\Filesystem::normalizePath($fullPath)); $path = basename($fullPath); if ($normalizedPath !== $path) { $output->writeln("\t<error>Entry \"" . $fullPath . '" will not be accessible due to incompatible encoding</error>'); } } protected function scanFiles($user, $path, $verbose, OutputInterface $output) { $scanner = new \OC\Files\Utils\Scanner($user, \OC::$server->getDatabaseConnection(), \OC::$server->getLogger()); # check on each file/folder if there was a user interrupt (ctrl-c) and throw an exception # printout and count if ($verbose) { $scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function ($path) use ($output) { $output->writeln("\tFile <info>$path</info>"); $this->filesCounter += 1; if ($this->hasBeenInterrupted()) { throw new \Exception('ctrl-c'); } }); $scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function ($path) use ($output) { $output->writeln("\tFolder <info>$path</info>"); $this->foldersCounter += 1; if ($this->hasBeenInterrupted()) { throw new \Exception('ctrl-c'); } }); $scanner->listen('\OC\Files\Utils\Scanner', 'StorageNotAvailable', function (StorageNotAvailableException $e) use ($output) { $output->writeln("Error while scanning, storage not available (" . $e->getMessage() . ")"); }); # count only } else { $scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function () use ($output) { $this->filesCounter += 1; if ($this->hasBeenInterrupted()) { throw new \Exception('ctrl-c'); } }); $scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function () use ($output) { $this->foldersCounter += 1; if ($this->hasBeenInterrupted()) { throw new \Exception('ctrl-c'); } }); } $scanner->listen('\OC\Files\Utils\Scanner', 'scanFile', function($path) use ($output) { $this->checkScanWarning($path, $output); }); $scanner->listen('\OC\Files\Utils\Scanner', 'scanFolder', function($path) use ($output) { $this->checkScanWarning($path, $output); }); try { $scanner->scan($path); } catch (ForbiddenException $e) { $output->writeln("<error>Home storage for user $user not writable</error>"); $output->writeln("Make sure you're running the scan command only as the user the web server runs as"); } catch (\Exception $e) { if ($e->getMessage() !== 'ctrl-c') { $output->writeln('<error>Exception while scanning: ' . $e->getMessage() . "\n" . $e->getTraceAsString() . '</error>'); } return; } } protected function execute(InputInterface $input, OutputInterface $output) { $inputPath = $input->getOption('path'); if ($inputPath) { $inputPath = '/' . trim($inputPath, '/'); list (, $user,) = explode('/', $inputPath, 3); $users = array($user); } else if ($input->getOption('all')) { $users = $this->userManager->search(''); } else { $users = $input->getArgument('user_id'); } # no messaging level option means: no full printout but statistics # $quiet means no print at all # $verbose means full printout including statistics # -q -v full stat # 0 0 no yes # 0 1 yes yes # 1 -- no no (quiet overrules verbose) $verbose = $input->getOption('verbose'); $quiet = $input->getOption('quiet'); # restrict the verbosity level to VERBOSITY_VERBOSE if ($output->getVerbosity()>OutputInterface::VERBOSITY_VERBOSE) { $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); } if ($quiet) { $verbose = false; } # check quantity of users to be process and show it on the command line $users_total = count($users); if ($users_total === 0) { $output->writeln("<error>Please specify the user id to scan, \"--all\" to scan for all users or \"--path=...\"</error>"); return; } else { if ($users_total > 1) { $output->writeln("\nScanning files for $users_total users"); } } $this->initTools(); $user_count = 0; foreach ($users as $user) { if (is_object($user)) { $user = $user->getUID(); } $path = $inputPath ? $inputPath : '/' . $user; $user_count += 1; if ($this->userManager->userExists($user)) { # add an extra line when verbose is set to optical separate users if ($verbose) {$output->writeln(""); } $output->writeln("Starting scan for user $user_count out of $users_total ($user)"); # full: printout data if $verbose was set $this->scanFiles($user, $path, $verbose, $output); } else { $output->writeln("<error>Unknown user $user_count $user</error>"); } # check on each user if there was a user interrupt (ctrl-c) and exit foreach if ($this->hasBeenInterrupted()) { break; } } # stat: printout statistics if $quiet was not set if (!$quiet) { $this->presentStats($output); } } /** * Initialises some useful tools for the Command */ protected function initTools() { // Start the timer $this->execTime = -microtime(true); // Convert PHP errors to exceptions set_error_handler([$this, 'exceptionErrorHandler'], E_ALL); } /** * Processes PHP errors as exceptions in order to be able to keep track of problems * * @see https://secure.php.net/manual/en/function.set-error-handler.php * * @param int $severity the level of the error raised * @param string $message * @param string $file the filename that the error was raised in * @param int $line the line number the error was raised * * @throws \ErrorException */ public function exceptionErrorHandler($severity, $message, $file, $line) { if (!(error_reporting() & $severity)) { // This error code is not included in error_reporting return; } throw new \ErrorException($message, 0, $severity, $file, $line); } /** * @param OutputInterface $output */ protected function presentStats(OutputInterface $output) { // Stop the timer $this->execTime += microtime(true); $output->writeln(""); $headers = [ 'Folders', 'Files', 'Elapsed time' ]; $this->showSummary($headers, null, $output); } /** * Shows a summary of operations * * @param string[] $headers * @param string[] $rows * @param OutputInterface $output */ protected function showSummary($headers, $rows, OutputInterface $output) { $niceDate = $this->formatExecTime(); if (!$rows) { $rows = [ $this->foldersCounter, $this->filesCounter, $niceDate, ]; } $table = new Table($output); $table ->setHeaders($headers) ->setRows([$rows]); $table->render(); } /** * Formats microtime into a human readable format * * @return string */ protected function formatExecTime() { list($secs, $tens) = explode('.', sprintf("%.1f", ($this->execTime))); # if you want to have microseconds add this: . '.' . $tens; return date('H:i:s', $secs); } }