From ad81a5f33394f2666f57c0c21e6bb49e4989a49e Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 21 Apr 2023 18:16:03 +0200 Subject: [PATCH] add command to delete a file Signed-off-by: Robin Appelman --- core/Command/Info/Delete.php | 115 +++++++++++++++++++++++++++++++++++ core/Command/Info/Get.php | 5 ++ core/register_command.php | 1 + 3 files changed, 121 insertions(+) create mode 100644 core/Command/Info/Delete.php diff --git a/core/Command/Info/Delete.php b/core/Command/Info/Delete.php new file mode 100644 index 00000000000..867938b03e2 --- /dev/null +++ b/core/Command/Info/Delete.php @@ -0,0 +1,115 @@ + + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see . + * + */ + +namespace OC\Core\Command\Info; + +use OCA\Files_Sharing\SharedStorage; +use OCP\Files\Folder; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\QuestionHelper; +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\Question\ConfirmationQuestion; + +class Delete extends Command { + private FileUtils $fileUtils; + + public function __construct(FileUtils $fileUtils) { + $this->fileUtils = $fileUtils; + parent::__construct(); + } + + protected function configure(): void { + $this + ->setName('info:file:delete') + ->setDescription('Delete a file or folder') + ->addArgument('file', InputArgument::REQUIRED, "File id or path") + ->addOption('force', 'f', InputOption::VALUE_NONE, "Don't ask for configuration and don't output any warnings"); + } + + public function execute(InputInterface $input, OutputInterface $output): int { + $fileInput = $input->getArgument('file'); + $inputIsId = is_numeric($fileInput); + $force = $input->getOption('force'); + $node = $this->fileUtils->getNode($fileInput); + + if (!$node) { + $output->writeln("file $fileInput not found"); + return 1; + } + + $deleteConfirmed = $force; + if (!$deleteConfirmed) { + /** @var QuestionHelper $helper */ + $helper = $this->getHelper('question'); + $storage = $node->getStorage(); + if (!$inputIsId && $storage->instanceOfStorage(SharedStorage::class) && $node->getInternalPath() === '') { + /** @var SharedStorage $storage */ + [,$user] = explode('/', $fileInput, 3); + $question = new ConfirmationQuestion("$fileInput in a shared file, do you want to unshare the file $user instead of deleting the source file? [Y/n] ", true); + if ($helper->ask($input, $output, $question)) { + $storage->unshareStorage(); + return 0; + } else { + $node = $storage->getShare()->getNode(); + $output->writeln(""); + } + } + + $filesByUsers = $this->fileUtils->getFilesByUser($node); + if (count($filesByUsers) > 1) { + $output->writeln("Warning: the provided file is accessible by more than one user"); + $output->writeln(" all of the following users will lose access to the file when deleted:"); + $output->writeln(""); + foreach ($filesByUsers as $user => $filesByUser) { + $output->writeln($user . ":"); + foreach($filesByUser as $file) { + $output->writeln(" - " . $file->getPath()); + } + } + $output->writeln(""); + } + + if ($node instanceof Folder) { + $maybeContents = " and all it's contents"; + } else { + $maybeContents = ""; + } + $question = new ConfirmationQuestion("Delete " . $node->getPath() . $maybeContents . "? [y/N] ", false); + $deleteConfirmed = $helper->ask($input, $output, $question); + } + + if ($deleteConfirmed) { + if ($node->isDeletable()) { + $node->delete(); + } else { + $output->writeln("File cannot be deleted, insufficient permissions."); + } + } + + return 0; + } + +} diff --git a/core/Command/Info/Get.php b/core/Command/Info/Get.php index a4323490c0b..f3ab5dde58a 100644 --- a/core/Command/Info/Get.php +++ b/core/Command/Info/Get.php @@ -53,6 +53,11 @@ class Get extends Command { $outputName = $input->getOption('output'); $node = $this->fileUtils->getNode($fileInput); + if (!$node) { + $output->writeln("file $fileInput not found"); + return 1; + } + if ($node instanceof File) { $isTTY = stream_isatty(STDOUT); if ($outputName === null && $isTTY && $node->getMimePart() !== 'text') { diff --git a/core/register_command.php b/core/register_command.php index a93acc2797e..dfbaac86551 100644 --- a/core/register_command.php +++ b/core/register_command.php @@ -106,6 +106,7 @@ if (\OC::$server->getConfig()->getSystemValue('installed', false)) { $application->add(\OC::$server->get(OC\Core\Command\Info\File::class)); $application->add(\OC::$server->get(OC\Core\Command\Info\Space::class)); $application->add(\OC::$server->get(OC\Core\Command\Info\Get::class)); + $application->add(\OC::$server->get(OC\Core\Command\Info\Delete::class)); $application->add(new OC\Core\Command\Db\ConvertType(\OC::$server->getConfig(), new \OC\DB\ConnectionFactory(\OC::$server->getSystemConfig()))); $application->add(new OC\Core\Command\Db\ConvertMysqlToMB4(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection(), \OC::$server->getURLGenerator(), \OC::$server->get(LoggerInterface::class))); -- 2.39.5