diff options
author | Joas Schilling <nickvergessen@gmx.de> | 2016-05-12 12:07:06 +0200 |
---|---|---|
committer | Thomas Müller <DeepDiver1975@users.noreply.github.com> | 2016-05-12 12:07:06 +0200 |
commit | b34bacd0718fa24c67a8ef0aa6f3b824a9b525bb (patch) | |
tree | 904bda1263850905c2c8164f4f1367d8c7bc9d46 /apps/files/command | |
parent | eea98f1d74daf2a20c6b08b9df743f0478c48103 (diff) | |
download | nextcloud-server-b34bacd0718fa24c67a8ef0aa6f3b824a9b525bb.tar.gz nextcloud-server-b34bacd0718fa24c67a8ef0aa6f3b824a9b525bb.zip |
Move Files app to PSR-4 (#24569)
* Move lib/ of Files app to PSR-4
* Move tests to PSR-4
Diffstat (limited to 'apps/files/command')
-rw-r--r-- | apps/files/command/deleteorphanedfiles.php | 84 | ||||
-rw-r--r-- | apps/files/command/scan.php | 310 | ||||
-rw-r--r-- | apps/files/command/transferownership.php | 240 |
3 files changed, 0 insertions, 634 deletions
diff --git a/apps/files/command/deleteorphanedfiles.php b/apps/files/command/deleteorphanedfiles.php deleted file mode 100644 index 91043471ce5..00000000000 --- a/apps/files/command/deleteorphanedfiles.php +++ /dev/null @@ -1,84 +0,0 @@ -<?php -/** - * @author Joas Schilling <nickvergessen@owncloud.com> - * @author Morris Jobke <hey@morrisjobke.de> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OCA\Files\Command; - -use Doctrine\DBAL\Platforms\PostgreSqlPlatform; -use Doctrine\DBAL\Platforms\SqlitePlatform; -use OCP\IDBConnection; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Delete all file entries that have no matching entries in the storage table. - */ -class DeleteOrphanedFiles extends Command { - - const CHUNK_SIZE = 200; - - /** - * @var IDBConnection - */ - protected $connection; - - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - parent::__construct(); - } - - protected function configure() { - $this - ->setName('files:cleanup') - ->setDescription('cleanup filecache'); - } - - public function execute(InputInterface $input, OutputInterface $output) { - $deletedEntries = 0; - - $query = $this->connection->getQueryBuilder(); - $query->select('fc.fileid') - ->from('filecache', 'fc') - ->where($query->expr()->isNull('s.numeric_id')) - ->leftJoin('fc', 'storages', 's', $query->expr()->eq('fc.storage', 's.numeric_id')) - ->setMaxResults(self::CHUNK_SIZE); - - $deleteQuery = $this->connection->getQueryBuilder(); - $deleteQuery->delete('filecache') - ->where($deleteQuery->expr()->eq('fileid', $deleteQuery->createParameter('objectid'))); - - $deletedInLastChunk = self::CHUNK_SIZE; - while ($deletedInLastChunk === self::CHUNK_SIZE) { - $deletedInLastChunk = 0; - $result = $query->execute(); - while ($row = $result->fetch()) { - $deletedInLastChunk++; - $deletedEntries += $deleteQuery->setParameter('objectid', (int) $row['fileid']) - ->execute(); - } - $result->closeCursor(); - } - - $output->writeln("$deletedEntries orphaned file cache entries deleted"); - } - -} diff --git a/apps/files/command/scan.php b/apps/files/command/scan.php deleted file mode 100644 index 1ae04c585bb..00000000000 --- a/apps/files/command/scan.php +++ /dev/null @@ -1,310 +0,0 @@ -<?php -/** - * @author Bart Visscher <bartv@thisnet.nl> - * @author Jörn Friedrich Dreyer <jfd@butonic.de> - * @author martin.mattel@diemattels.at <martin.mattel@diemattels.at> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <icewind@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OCA\Files\Command; - -use OC\Core\Command\Base; -use OC\ForbiddenException; -use OCP\Files\StorageNotAvailableException; -use OCP\IUserManager; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Console\Helper\Table; - -class Scan extends Base { - - /** @var IUserManager $userManager */ - private $userManager; - /** @var float */ - protected $execTime = 0; - /** @var int */ - protected $foldersCounter = 0; - /** @var int */ - protected $filesCounter = 0; - - public function __construct(IUserManager $userManager) { - $this->userManager = $userManager; - parent::__construct(); - } - - protected function configure() { - parent::configure(); - - $this - ->setName('files:scan') - ->setDescription('rescan filesystem') - ->addArgument( - 'user_id', - InputArgument::OPTIONAL | InputArgument::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); - } - -} diff --git a/apps/files/command/transferownership.php b/apps/files/command/transferownership.php deleted file mode 100644 index 1f46efdde0d..00000000000 --- a/apps/files/command/transferownership.php +++ /dev/null @@ -1,240 +0,0 @@ -<?php -/** - * @author Thomas Müller <thomas.mueller@tmit.eu> - * - * @copyright Copyright (c) 2016, ownCloud, Inc. - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -namespace OCA\Files\Command; - -use OC\Files\Filesystem; -use OC\Files\View; -use OCP\Files\FileInfo; -use OCP\Files\Mount\IMountManager; -use OCP\IUserManager; -use OCP\Share\IManager; -use OCP\Share\IShare; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Helper\ProgressBar; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class TransferOwnership extends Command { - - /** @var IUserManager $userManager */ - private $userManager; - - /** @var IManager */ - private $shareManager; - - /** @var IMountManager */ - private $mountManager; - - /** @var FileInfo[] */ - private $allFiles = []; - - /** @var FileInfo[] */ - private $encryptedFiles = []; - - /** @var IShare[] */ - private $shares = []; - - /** @var string */ - private $sourceUser; - - /** @var string */ - private $destinationUser; - - /** @var string */ - private $finalTarget; - - public function __construct(IUserManager $userManager, IManager $shareManager, IMountManager $mountManager) { - $this->userManager = $userManager; - $this->shareManager = $shareManager; - $this->mountManager = $mountManager; - parent::__construct(); - } - - protected function configure() { - $this - ->setName('files:transfer-ownership') - ->setDescription('All files and folders are moved to another user - shares are moved as well.') - ->addArgument( - 'source-user', - InputArgument::REQUIRED, - 'owner of files which shall be moved' - ) - ->addArgument( - 'destination-user', - InputArgument::REQUIRED, - 'user who will be the new owner of the files' - ); - } - - protected function execute(InputInterface $input, OutputInterface $output) { - $this->sourceUser = $input->getArgument('source-user'); - $this->destinationUser = $input->getArgument('destination-user'); - if (!$this->userManager->userExists($this->sourceUser)) { - $output->writeln("<error>Unknown source user $this->sourceUser</error>"); - return; - } - if (!$this->userManager->userExists($this->destinationUser)) { - $output->writeln("<error>Unknown destination user $this->destinationUser</error>"); - return; - } - - // target user has to be ready - if (!\OC::$server->getEncryptionManager()->isReadyForUser($this->destinationUser)) { - $output->writeln("<error>The target user is not ready to accept files. The user has at least to be logged in once.</error>"); - return; - } - - $date = date('c'); - $this->finalTarget = "$this->destinationUser/files/transferred from $this->sourceUser on $date"; - - // setup filesystem - Filesystem::initMountPoints($this->sourceUser); - Filesystem::initMountPoints($this->destinationUser); - - // analyse source folder - $this->analyse($output); - - // collect all the shares - $this->collectUsersShares($output); - - // transfer the files - $this->transfer($output); - - // restore the shares - $this->restoreShares($output); - } - - private function walkFiles(View $view, $path, \Closure $callBack) { - foreach ($view->getDirectoryContent($path) as $fileInfo) { - if (!$callBack($fileInfo)) { - return; - } - if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) { - $this->walkFiles($view, $fileInfo->getPath(), $callBack); - } - } - } - - /** - * @param OutputInterface $output - * @throws \Exception - */ - protected function analyse(OutputInterface $output) { - $view = new View(); - $output->writeln("Analysing files of $this->sourceUser ..."); - $progress = new ProgressBar($output); - $progress->start(); - $self = $this; - $this->walkFiles($view, "$this->sourceUser/files", - function (FileInfo $fileInfo) use ($progress, $self) { - if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) { - return true; - } - $progress->advance(); - $this->allFiles[] = $fileInfo; - if ($fileInfo->isEncrypted()) { - $this->encryptedFiles[] = $fileInfo; - } - return true; - }); - $progress->finish(); - $output->writeln(''); - - // no file is allowed to be encrypted - if (!empty($this->encryptedFiles)) { - $output->writeln("<error>Some files are encrypted - please decrypt them first</error>"); - foreach($this->encryptedFiles as $encryptedFile) { - /** @var FileInfo $encryptedFile */ - $output->writeln(" " . $encryptedFile->getPath()); - } - throw new \Exception('Execution terminated.'); - } - - } - - /** - * @param OutputInterface $output - */ - private function collectUsersShares(OutputInterface $output) { - $output->writeln("Collecting all share information for files and folder of $this->sourceUser ..."); - - $progress = new ProgressBar($output, count($this->shares)); - foreach([\OCP\Share::SHARE_TYPE_USER, \OCP\Share::SHARE_TYPE_GROUP, \OCP\Share::SHARE_TYPE_LINK, \OCP\Share::SHARE_TYPE_REMOTE] as $shareType) { - $offset = 0; - while (true) { - $sharePage = $this->shareManager->getSharesBy($this->sourceUser, $shareType, null, true, 50, $offset); - $progress->advance(count($sharePage)); - if (empty($sharePage)) { - break; - } - $this->shares = array_merge($this->shares, $sharePage); - $offset += 50; - } - } - - $progress->finish(); - $output->writeln(''); - } - - /** - * @param OutputInterface $output - */ - protected function transfer(OutputInterface $output) { - $view = new View(); - $output->writeln("Transferring files to $this->finalTarget ..."); - $view->rename("$this->sourceUser/files", $this->finalTarget); - // because the files folder is moved away we need to recreate it - $view->mkdir("$this->sourceUser/files"); - } - - /** - * @param OutputInterface $output - */ - private function restoreShares(OutputInterface $output) { - $output->writeln("Restoring shares ..."); - $progress = new ProgressBar($output, count($this->shares)); - - foreach($this->shares as $share) { - if ($share->getSharedWith() === $this->destinationUser) { - // Unmount the shares before deleting, so we don't try to get the storage later on. - $shareMountPoint = $this->mountManager->find('/' . $this->destinationUser . '/files' . $share->getTarget()); - if ($shareMountPoint) { - $this->mountManager->removeMount($shareMountPoint->getMountPoint()); - } - $this->shareManager->deleteShare($share); - } else { - if ($share->getShareOwner() === $this->sourceUser) { - $share->setShareOwner($this->destinationUser); - } - if ($share->getSharedBy() === $this->sourceUser) { - $share->setSharedBy($this->destinationUser); - } - - $this->shareManager->updateShare($share); - } - $progress->advance(); - } - $progress->finish(); - $output->writeln(''); - } -} |