зеркало из https://github.com/nextcloud/spreed.git
Add console commands to manage commands
Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Родитель
18aa82dabf
Коммит
835e6bdc77
|
@ -62,6 +62,10 @@ And in the works for the [coming versions](https://github.com/nextcloud/spreed/m
|
|||
</repair-steps>
|
||||
|
||||
<commands>
|
||||
<command>OCA\Spreed\Command\Command\Add</command>
|
||||
<command>OCA\Spreed\Command\Command\Delete</command>
|
||||
<command>OCA\Spreed\Command\Command\ListCommand</command>
|
||||
<command>OCA\Spreed\Command\Command\Update</command>
|
||||
<command>OCA\Spreed\Command\Stun\Add</command>
|
||||
<command>OCA\Spreed\Command\Stun\Delete</command>
|
||||
<command>OCA\Spreed\Command\Stun\ListCommand</command>
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2019 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Spreed\Command\Command;
|
||||
|
||||
use OCA\Spreed\Service\CommandService;
|
||||
use OC\Core\Command\Base;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Add extends Base {
|
||||
|
||||
use TRenderCommand;
|
||||
|
||||
/** @var CommandService */
|
||||
private $service;
|
||||
|
||||
public function __construct(CommandService $service) {
|
||||
parent::__construct();
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
protected function configure(): void {
|
||||
$this
|
||||
->setName('talk:command:add')
|
||||
->setDescription('Add a new command')
|
||||
->addArgument(
|
||||
'cmd',
|
||||
InputArgument::REQUIRED,
|
||||
'The command as used in the chat "/help" => "help"'
|
||||
)
|
||||
->addArgument(
|
||||
'name',
|
||||
InputArgument::REQUIRED,
|
||||
'Name of the user posting the response'
|
||||
)
|
||||
->addArgument(
|
||||
'script',
|
||||
InputArgument::REQUIRED,
|
||||
'Script to execute'
|
||||
)
|
||||
->addArgument(
|
||||
'response',
|
||||
InputArgument::REQUIRED,
|
||||
'Who should see the response: 0 - No one, 1 - User, 2 - All'
|
||||
)
|
||||
->addArgument(
|
||||
'enabled',
|
||||
InputArgument::REQUIRED,
|
||||
'Who can use this command: 0 - Disabled, 1 - Moderators, 2 - Users, 3 - Guests'
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||
$cmd = $input->getArgument('cmd');
|
||||
$name = $input->getArgument('name');
|
||||
$script = $input->getArgument('script');
|
||||
$response = (int) $input->getArgument('response');
|
||||
$enabled = (int) $input->getArgument('enabled');
|
||||
|
||||
try {
|
||||
$command = $this->service->create('', $cmd, $name, $script, $response, $enabled);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
switch ($e->getCode()) {
|
||||
case 1:
|
||||
$output->writeln('<error>The command already exists</error>');
|
||||
break;
|
||||
case 4:
|
||||
$output->writeln('<error>The response value is invalid</error>');
|
||||
break;
|
||||
case 5:
|
||||
$output->writeln('<error>The enabled value is invalid</error>');
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
$output->writeln('<info>Command added</info>');
|
||||
$output->writeln('');
|
||||
$this->renderCommands(Base::OUTPUT_FORMAT_PLAIN, $output, [$command]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2019 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Spreed\Command\Command;
|
||||
|
||||
use OCA\Spreed\Service\CommandService;
|
||||
use OC\Core\Command\Base;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Delete extends Base {
|
||||
|
||||
/** @var CommandService */
|
||||
private $service;
|
||||
|
||||
public function __construct(CommandService $service) {
|
||||
parent::__construct();
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
protected function configure():void {
|
||||
$this
|
||||
->setName('talk:command:delete')
|
||||
->setDescription('Remove an existing command')
|
||||
->addArgument(
|
||||
'command-id',
|
||||
InputArgument::REQUIRED
|
||||
);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||
$id = (int) $input->getArgument('command-id');
|
||||
|
||||
try {
|
||||
$this->service->delete($id);
|
||||
} catch (DoesNotExistException $e) {
|
||||
$output->writeln('<error>The given command ID does not exist</error>');
|
||||
return 1;
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
$output->writeln('<error>The help command cannot be deleted</error>');
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2019 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Spreed\Command\Command;
|
||||
|
||||
use OCA\Spreed\Service\CommandService;
|
||||
use OC\Core\Command\Base;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ListCommand extends Base {
|
||||
|
||||
use TRenderCommand;
|
||||
|
||||
/** @var CommandService */
|
||||
private $service;
|
||||
|
||||
public function __construct(CommandService $service) {
|
||||
parent::__construct();
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
protected function configure(): void {
|
||||
parent::configure();
|
||||
|
||||
$this
|
||||
->setName('talk:command:list')
|
||||
->setDescription('List all available commands')
|
||||
->addArgument('app', InputArgument::OPTIONAL, 'Only list the commands of a specific app, "custom" to list all custom commands')
|
||||
;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||
$app = $input->getArgument('app');
|
||||
if ($app === null) {
|
||||
$commands = $this->service->findAll();
|
||||
} else {
|
||||
$commands = $this->service->findByApp($app === 'custom' ? '' : $app);
|
||||
}
|
||||
|
||||
$this->renderCommands($input->getOption('output'), $output, $commands, true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2019 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Spreed\Command\Command;
|
||||
|
||||
use OCA\Spreed\Model\Command;
|
||||
use OC\Core\Command\Base;
|
||||
use Symfony\Component\Console\Helper\Table;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
trait TRenderCommand {
|
||||
|
||||
protected function renderCommands(string $outputFormat, OutputInterface $output, array $commands, bool $showHelp = false): void {
|
||||
$result = array_map(function(Command $command) {
|
||||
return $command->asArray();
|
||||
}, $commands);
|
||||
|
||||
if ($outputFormat === Base::OUTPUT_FORMAT_PLAIN) {
|
||||
if ($showHelp) {
|
||||
$output->writeln('Response values: 0 - No one, 1 - User, 2 - All');
|
||||
$output->writeln('Enabled values: 0 - Disabled, 1 - Moderators, 2 - Users, 3 - Guests');
|
||||
$output->writeln('');
|
||||
}
|
||||
|
||||
$table = new Table($output);
|
||||
if (isset($result[0])) {
|
||||
$table->setHeaders(array_keys($result[0]));
|
||||
}
|
||||
$table->addRows($result);
|
||||
$table->render();
|
||||
} else {
|
||||
$this->writeMixedInOutputFormat($input, $output, $result);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* @copyright Copyright (c) 2019 Joas Schilling <coding@schilljs.com>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OCA\Spreed\Command\Command;
|
||||
|
||||
use OCA\Spreed\Service\CommandService;
|
||||
use OC\Core\Command\Base;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class Update extends Base {
|
||||
|
||||
use TRenderCommand;
|
||||
|
||||
/** @var CommandService */
|
||||
private $service;
|
||||
|
||||
public function __construct(CommandService $service) {
|
||||
parent::__construct();
|
||||
$this->service = $service;
|
||||
}
|
||||
|
||||
protected function configure(): void {
|
||||
$this
|
||||
->setName('talk:command:update')
|
||||
->setDescription('Add a new command')
|
||||
->addArgument(
|
||||
'command-id',
|
||||
InputArgument::REQUIRED
|
||||
)
|
||||
->addArgument(
|
||||
'cmd',
|
||||
InputArgument::REQUIRED,
|
||||
'The command as used in the chat "/help" => "help"'
|
||||
)
|
||||
->addArgument(
|
||||
'name',
|
||||
InputArgument::REQUIRED,
|
||||
'Name of the user posting the response'
|
||||
)
|
||||
->addArgument(
|
||||
'script',
|
||||
InputArgument::REQUIRED,
|
||||
'Script to execute'
|
||||
)
|
||||
->addArgument(
|
||||
'response',
|
||||
InputArgument::REQUIRED,
|
||||
'Who should see the response: 0 - No one, 1 - User, 2 - All'
|
||||
)
|
||||
->addArgument(
|
||||
'enabled',
|
||||
InputArgument::REQUIRED,
|
||||
'Who can use this command: 0 - Disabled, 1 - Moderators, 2 - Users, 3 - Guests'
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||
$id = (int) $input->getArgument('command-id');
|
||||
$cmd = $input->getArgument('cmd');
|
||||
$name = $input->getArgument('name');
|
||||
$script = $input->getArgument('script');
|
||||
$response = (int) $input->getArgument('response');
|
||||
$enabled = (int) $input->getArgument('enabled');
|
||||
|
||||
try {
|
||||
$command = $this->service->update($id, $cmd, $name, $script, $response, $enabled);
|
||||
} catch (DoesNotExistException $e) {
|
||||
$output->writeln('<error>The given command ID does not exist</error>');
|
||||
return 1;
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
switch ($e->getCode()) {
|
||||
case 0:
|
||||
$output->writeln('<error>The help command and predefined commands cannot be updated</error>');
|
||||
break;
|
||||
case 1:
|
||||
$output->writeln('<error>The command already exists</error>');
|
||||
break;
|
||||
case 4:
|
||||
$output->writeln('<error>The response value is invalid</error>');
|
||||
break;
|
||||
case 5:
|
||||
$output->writeln('<error>The enabled value is invalid</error>');
|
||||
break;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
$output->writeln('<info>Command updated</info>');
|
||||
$output->writeln('');
|
||||
$this->renderCommands(Base::OUTPUT_FORMAT_PLAIN, $output, [$command]);
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
namespace OCA\Spreed\Controller;
|
||||
|
||||
use OCA\Spreed\Model\Command;
|
||||
use OCA\Spreed\Service\CommandService;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
use OCP\AppFramework\Http;
|
||||
|
@ -53,18 +54,9 @@ class CommandController extends OCSController {
|
|||
public function index(): DataResponse {
|
||||
$commands = $this->commandService->findAll();
|
||||
|
||||
$result = [];
|
||||
foreach ($commands as $command) {
|
||||
$result[] = [
|
||||
'id' => $command->getId(),
|
||||
'app' => $command->getApp(),
|
||||
'name' => $command->getName(),
|
||||
'pattern' => $command->getCommand(),
|
||||
'script' => $command->getScript(),
|
||||
'response' => $command->getResponse(),
|
||||
'enabled' => $command->getEnabled(),
|
||||
];
|
||||
}
|
||||
$result = array_map(function(Command $command) {
|
||||
return $command->asArray();
|
||||
}, $commands);
|
||||
|
||||
return new DataResponse($result);
|
||||
}
|
||||
|
@ -84,15 +76,7 @@ class CommandController extends OCSController {
|
|||
return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
return new DataResponse([
|
||||
'id' => $command->getId(),
|
||||
'app' => $command->getApp(),
|
||||
'name' => $command->getName(),
|
||||
'pattern' => $command->getCommand(),
|
||||
'script' => $command->getScript(),
|
||||
'response' => $command->getResponse(),
|
||||
'enabled' => $command->getEnabled(),
|
||||
]);
|
||||
return new DataResponse($command->asArray());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,6 +88,8 @@ class CommandController extends OCSController {
|
|||
$this->commandService->delete($id);
|
||||
} catch (DoesNotExistException $e) {
|
||||
return new DataResponse([], Http::STATUS_NOT_FOUND);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return new DataResponse(['error' => $e->getMessage()], Http::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
return new DataResponse();
|
||||
|
|
|
@ -75,4 +75,19 @@ class Command extends Entity {
|
|||
$this->addType('response', 'int');
|
||||
$this->addType('enabled', 'int');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function asArray(): array {
|
||||
return [
|
||||
'id' => $this->getId(),
|
||||
'app' => $this->getApp(),
|
||||
'name' => $this->getName(),
|
||||
'command' => $this->getCommand(),
|
||||
'script' => $this->getScript(),
|
||||
'response' => $this->getResponse(),
|
||||
'enabled' => $this->getEnabled(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,12 +38,12 @@ class CommandMapper extends QBMapper {
|
|||
* @return Command[]
|
||||
*/
|
||||
public function findAll(): array {
|
||||
$qb = $this->db->getQueryBuilder();
|
||||
$qb->select('*')
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->select('*')
|
||||
->from($this->getTableName())
|
||||
->orderBy('id', 'ASC');
|
||||
|
||||
return $this->findEntities($qb);
|
||||
return $this->findEntities($query);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,6 +60,20 @@ class CommandMapper extends QBMapper {
|
|||
return $this->findEntity($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $app
|
||||
* @return Command[]
|
||||
*/
|
||||
public function findByApp(string $app): array {
|
||||
$query = $this->db->getQueryBuilder();
|
||||
$query->select('*')
|
||||
->from($this->getTableName())
|
||||
->where($query->expr()->eq('app', $query->createNamedParameter($app)))
|
||||
->orderBy('id', 'ASC');
|
||||
|
||||
return $this->findEntities($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $app
|
||||
* @param string $cmd
|
||||
|
|
|
@ -100,6 +100,10 @@ class CommandService {
|
|||
*/
|
||||
public function update(int $id, string $cmd, string $name, string $script, int $response, int $enabled): Command {
|
||||
$command = $this->mapper->findById($id);
|
||||
if ($command->getApp() !== '' || $command->getCommand() === 'help') {
|
||||
throw new \InvalidArgumentException('app', 0);
|
||||
}
|
||||
|
||||
if (!\in_array($response, [Command::RESPONSE_NONE, Command::RESPONSE_USER, Command::RESPONSE_ALL], true)) {
|
||||
throw new \InvalidArgumentException('response', 4);
|
||||
}
|
||||
|
@ -108,10 +112,6 @@ class CommandService {
|
|||
throw new \InvalidArgumentException('enabled', 5);
|
||||
}
|
||||
|
||||
if ($command->getApp() !== '' || $command->getCommand() === 'help') {
|
||||
throw new \InvalidArgumentException('app', 0);
|
||||
}
|
||||
|
||||
if ($cmd !== $command->getCommand()) {
|
||||
try {
|
||||
$this->mapper->find('', $cmd);
|
||||
|
@ -136,11 +136,18 @@ class CommandService {
|
|||
* @param int $id
|
||||
* @return Command
|
||||
* @throws DoesNotExistException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function delete(int $id): Command {
|
||||
$command = $this->mapper->findById($id);
|
||||
|
||||
if ($command->getApp() !== '' || $command->getCommand() === 'help') {
|
||||
throw new \InvalidArgumentException('app', 0);
|
||||
}
|
||||
|
||||
return $this->mapper->delete($command);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $app
|
||||
* @param string $cmd
|
||||
|
@ -151,6 +158,14 @@ class CommandService {
|
|||
return $this->mapper->find($app, $cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $app
|
||||
* @return Command[]
|
||||
*/
|
||||
public function findByApp(string $app): array {
|
||||
return $this->mapper->findByApp($app);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return Command
|
||||
|
|
Загрузка…
Ссылка в новой задаче