Skip to content

Commit

Permalink
feat(systemtags): add commands to manage tags on files
Browse files Browse the repository at this point in the history
Resolve #32735

Signed-off-by: schaarsc <schaarsc@users.noreply.github.com>
  • Loading branch information
schaarsc committed Sep 23, 2024
1 parent 46301a1 commit 819385c
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 0 deletions.
90 changes: 90 additions & 0 deletions core/Command/SystemTag/Files/Add.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php

declare(strict_types = 1);

/**
* SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OC\Core\Command\SystemTag\Files;

use OC\Core\Command\Info\FileUtils;
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ISystemTagObjectMapper;
use OCP\SystemTag\TagAlreadyExistsException;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Add extends Command {

public function __construct(
private FileUtils $fileUtils,
private ISystemTagManager $systemTagManager,
private ISystemTagObjectMapper $systemTagObjectMapper,
) {
parent::__construct();
}

protected function configure(): void {
$this->setName('tag:files:add')
->setDescription('Add a system-tag to a file or folder')
->addArgument('target', InputArgument::REQUIRED, 'file id or path')
->addArgument('tags', InputArgument::REQUIRED, 'Name of the tag(s) to add, comma separated')
->addArgument('access', InputArgument::REQUIRED, 'access level of the tag (public, restricted or invisible)');
}

public function execute(InputInterface $input, OutputInterface $output): int {
$targetInput = $input->getArgument('target');
$tagsInput = $input->getArgument('tags');

if ($tagsInput === '') {
$output->writeln('<error>`tags` can\'t be empty</error>');
return 3;
}

$tagNameArray = explode(',', $tagsInput);

$access = $input->getArgument('access');
switch ($access) {
case 'public':
$userVisible = true;
$userAssignable = true;
break;
case 'restricted':
$userVisible = true;
$userAssignable = false;
break;
case 'invisible':
$userVisible = false;
$userAssignable = false;
break;
default:
$output->writeln('<error>`access` property is invalid</error>');
return 1;
}

$targetNode = $this->fileUtils->getNode($targetInput);

if (! $targetNode) {
$output->writeln("<error>file $targetInput not found</error>");
return 1;
}

foreach ($tagNameArray as $tagName) {
try {
$tag = $this->systemTagManager->createTag($tagName, $userVisible, $userAssignable);
$output->writeln("<info>$access</info> tag named <info>$tagName</info> created.");
} catch (TagAlreadyExistsException $e) {
$tag = $this->systemTagManager->getTag($tagName, $userVisible, $userAssignable);
}

$this->systemTagObjectMapper->assignTags((string)$targetNode->getId(), 'files', $tag->getId());
$output->writeln("<info>$access</info> tag named <info>$tagName</info> added.");
}

return 0;
}
}
88 changes: 88 additions & 0 deletions core/Command/SystemTag/Files/Delete.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

declare(strict_types = 1);

/**
* SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OC\Core\Command\SystemTag\Files;

use OC\Core\Command\Info\FileUtils;
use OCP\SystemTag\ISystemTagManager;
use OCP\SystemTag\ISystemTagObjectMapper;
use OCP\SystemTag\TagNotFoundException;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Delete extends Command {

public function __construct(
private FileUtils $fileUtils,
private ISystemTagManager $systemTagManager,
private ISystemTagObjectMapper $systemTagObjectMapper,
) {
parent::__construct();
}

protected function configure(): void {
$this->setName('tag:files:delete')
->setDescription('Delete a system-tag from a file or folder')
->addArgument('target', InputArgument::REQUIRED, 'file id or path')
->addArgument('tags', InputArgument::REQUIRED, 'Name of the tag(s) to delete, comma separated')
->addArgument('access', InputArgument::REQUIRED, 'access level of the tag (public, restricted or invisible)');
}

public function execute(InputInterface $input, OutputInterface $output): int {
$targetInput = $input->getArgument('target');
$tagsInput = $input->getArgument('tags');

if ($tagsInput === '') {
$output->writeln('<error>`tags` can\'t be empty</error>');
return 3;
}

$tagNameArray = explode(',', $tagsInput);

$access = $input->getArgument('access');
switch ($access) {
case 'public':
$userVisible = true;
$userAssignable = true;
break;
case 'restricted':
$userVisible = true;
$userAssignable = false;
break;
case 'invisible':
$userVisible = false;
$userAssignable = false;
break;
default:
$output->writeln('<error>`access` property is invalid</error>');
return 1;
}

$targetNode = $this->fileUtils->getNode($targetInput);

if (! $targetNode) {
$output->writeln("<error>file $targetInput not found</error>");
return 1;
}

foreach ($tagNameArray as $tagName) {
try {
$tag = $this->systemTagManager->getTag($tagName, $userVisible, $userAssignable);
$this->systemTagObjectMapper->unassignTags((string)$targetNode->getId(), 'files', $tag->getId());
$output->writeln("<info>$access</info> tag named <info>$tagName</info> removed.");
} catch (TagNotFoundException $e) {
$output->writeln("<info>$access</info> tag named <info>$tagName</info> does not exist!");
}
}

return 0;
}
}
49 changes: 49 additions & 0 deletions core/Command/SystemTag/Files/DeleteAll.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types = 1);

/**
* SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OC\Core\Command\SystemTag\Files;

use OC\Core\Command\Info\FileUtils;
use OCP\SystemTag\ISystemTagObjectMapper;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class DeleteAll extends Command {

public function __construct(
private FileUtils $fileUtils,
private ISystemTagObjectMapper $systemTagObjectMapper,
) {
parent::__construct();
}

protected function configure(): void {
$this->setName('tag:files:delete-all')
->setDescription('Delete all system-tags from a file or folder')
->addArgument('target', InputArgument::REQUIRED, 'file id or path');
}

public function execute(InputInterface $input, OutputInterface $output): int {
$targetInput = $input->getArgument('target');
$targetNode = $this->fileUtils->getNode($targetInput);

if (! $targetNode) {
$output->writeln("<error>file $targetInput not found</error>");
return 1;
}

$tags = $this->systemTagObjectMapper->getTagIdsForObjects($targetNode->getId(), 'files');
$this->systemTagObjectMapper->unassignTags((string)$targetNode->getId(), 'files', $tags[$targetNode->getId()]);
$output->writeln('<info>all tags removed.</info>');

return 0;
}
}
3 changes: 3 additions & 0 deletions core/register_command.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@
$application->add(Server::get(Command\SystemTag\Delete::class));
$application->add(Server::get(Command\SystemTag\Add::class));
$application->add(Server::get(Command\SystemTag\Edit::class));
$application->add(Server::get(Command\SystemTag\Files\Delete::class));
$application->add(Server::get(Command\SystemTag\Files\DeleteAll::class));
$application->add(Server::get(Command\SystemTag\Files\Add::class));

$application->add(Server::get(Command\Security\ListCertificates::class));
$application->add(Server::get(Command\Security\ExportCertificates::class));
Expand Down
3 changes: 3 additions & 0 deletions lib/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,9 @@
'OC\\Core\\Command\\SystemTag\\Add' => $baseDir . '/core/Command/SystemTag/Add.php',
'OC\\Core\\Command\\SystemTag\\Delete' => $baseDir . '/core/Command/SystemTag/Delete.php',
'OC\\Core\\Command\\SystemTag\\Edit' => $baseDir . '/core/Command/SystemTag/Edit.php',
'OC\\Core\\Command\\SystemTag\\Files\\Add' => $baseDir . '/core/Command/SystemTag/Files/Add.php',
'OC\\Core\\Command\\SystemTag\\Files\\Delete' => $baseDir . '/core/Command/SystemTag/Files/Delete.php',
'OC\\Core\\Command\\SystemTag\\Files\\DeleteAll' => $baseDir . '/core/Command/SystemTag/Files/DeleteAll.php',
'OC\\Core\\Command\\SystemTag\\ListCommand' => $baseDir . '/core/Command/SystemTag/ListCommand.php',
'OC\\Core\\Command\\TaskProcessing\\ListCommand' => $baseDir . '/core/Command/TaskProcessing/ListCommand.php',
'OC\\Core\\Command\\TaskProcessing\\Statistics' => $baseDir . '/core/Command/TaskProcessing/Statistics.php',
Expand Down
3 changes: 3 additions & 0 deletions lib/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,9 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
'OC\\Core\\Command\\SystemTag\\Add' => __DIR__ . '/../../..' . '/core/Command/SystemTag/Add.php',
'OC\\Core\\Command\\SystemTag\\Delete' => __DIR__ . '/../../..' . '/core/Command/SystemTag/Delete.php',
'OC\\Core\\Command\\SystemTag\\Edit' => __DIR__ . '/../../..' . '/core/Command/SystemTag/Edit.php',
'OC\\Core\\Command\\SystemTag\\Files\\Add' => __DIR__ . '/../../..' . '/core/Command/SystemTag/Files/Add.php',
'OC\\Core\\Command\\SystemTag\\Files\\Delete' => __DIR__ . '/../../..' . '/core/Command/SystemTag/Files/Delete.php',
'OC\\Core\\Command\\SystemTag\\Files\\DeleteAll' => __DIR__ . '/../../..' . '/core/Command/SystemTag/Files/DeleteAll.php',
'OC\\Core\\Command\\SystemTag\\ListCommand' => __DIR__ . '/../../..' . '/core/Command/SystemTag/ListCommand.php',
'OC\\Core\\Command\\TaskProcessing\\ListCommand' => __DIR__ . '/../../..' . '/core/Command/TaskProcessing/ListCommand.php',
'OC\\Core\\Command\\TaskProcessing\\Statistics' => __DIR__ . '/../../..' . '/core/Command/TaskProcessing/Statistics.php',
Expand Down

0 comments on commit 819385c

Please sign in to comment.