Import participants

Big refactor to create route
Import participants

Signed-off-by: Vitor Mattos <vitor@php.rio>
This commit is contained in:
Vitor Mattos
2021-07-14 23:49:31 -03:00
committed by Julius Härtl
parent fd92fc3c4d
commit c5d10dafb8
18 changed files with 868 additions and 521 deletions

View File

@@ -23,40 +23,28 @@
namespace OCA\Deck\Command;
use JsonSchema\Constraints\Constraint;
use JsonSchema\Validator;
use OCA\Deck\Command\ImportHelper\AImport;
use OCA\Deck\Command\ImportHelper\TrelloHelper;
use OCA\Deck\Service\BoardImportCommandService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\Question;
class BoardImport extends Command {
/** @var string */
private $system;
private $allowedSystems;
/** @var TrelloHelper */
private $trelloHelper;
/** @var boardImportCommandService */
private $boardImportCommandService;
public function __construct(
TrelloHelper $trelloHelper
BoardImportCommandService $boardImportCommandService
) {
$this->boardImportCommandService = $boardImportCommandService;
parent::__construct();
$this->trelloHelper = $trelloHelper;
}
/**
* @return void
*/
protected function configure() {
$allowedSystems = glob(__DIR__ . '/ImportHelper/*Helper.php');
$this->allowedSystems = array_map(function ($name) {
preg_match('/\/(?<system>\w+)Helper\.php$/', $name, $matches);
return lcfirst($matches['system']);
}, $allowedSystems);
$allowedSystems = $this->boardImportCommandService->getAllowedImportSystems();
$this
->setName('deck:import')
->setDescription('Import data')
@@ -64,7 +52,7 @@ class BoardImport extends Command {
'system',
null,
InputOption::VALUE_REQUIRED,
'Source system for import. Available options: ' . implode(', ', $this->allowedSystems) . '.',
'Source system for import. Available options: ' . implode(', ', $allowedSystems) . '.',
'trello'
)
->addOption(
@@ -90,89 +78,10 @@ class BoardImport extends Command {
* @return void
*/
protected function interact(InputInterface $input, OutputInterface $output) {
$this->validateSystem($input, $output);
$this->validateConfig($input, $output);
$this->getSystemHelper()
->validate($input, $output);
}
protected function validateConfig(InputInterface $input, OutputInterface $output): void {
$configFile = $input->getOption('config');
if (!is_file($configFile)) {
$helper = $this->getHelper('question');
$question = new Question(
'Please inform a valid config json file: ',
'config.json'
);
$question->setValidator(function ($answer) {
if (!is_file($answer)) {
throw new \RuntimeException(
'config file not found'
);
}
return $answer;
});
$configFile = $helper->ask($input, $output, $question);
$input->setOption('config', $configFile);
}
$config = json_decode(file_get_contents($configFile));
$schemaPath = __DIR__ . '/ImportHelper/fixtures/config-' . $this->getSystem() . '-schema.json';
$validator = new Validator();
$validator->validate(
$config,
(object)['$ref' => 'file://' . realpath($schemaPath)],
Constraint::CHECK_MODE_APPLY_DEFAULTS
);
if (!$validator->isValid()) {
$output->writeln('<error>Invalid config file</error>');
$output->writeln(array_map(function ($v) {
return $v['message'];
}, $validator->getErrors()));
$output->writeln('Valid schema:');
$output->writeln(print_r(file_get_contents($schemaPath), true));
$input->setOption('config', null);
$this->validateConfig($input, $output);
}
$this->getSystemHelper()->setConfigInstance($config);
}
private function setSystem(string $system): void {
$this->system = $system;
}
public function getSystem() {
return $this->system;
}
/**
* @return AImport
*/
private function getSystemHelper() {
$helper = $this->{$this->system . 'Helper'};
$helper->setCommand($this);
return $helper;
}
/**
* @return void
*/
private function validateSystem(InputInterface $input, OutputInterface $output) {
$system = $input->getOption('system');
if (in_array($system, $this->allowedSystems)) {
$this->setSystem($system);
return;
}
$helper = $this->getHelper('question');
$question = new ChoiceQuestion(
'Please inform a source system',
$this->allowedSystems,
0
);
$question->setErrorMessage('System %s is invalid.');
$system = $helper->ask($input, $output, $question);
$input->setOption('system', $system);
$this->setSystem($system);
$this->boardImportCommandService
->setInput($input)
->setOutput($output)
->validate();
}
/**
@@ -182,8 +91,11 @@ class BoardImport extends Command {
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output): int {
$this->getSystemHelper()
->import($input, $output);
$this
->boardImportCommandService
->setInput($input)
->setOutput($output)
->import();
$output->writeln('Done!');
return 0;
}

View File

@@ -1,75 +0,0 @@
<?php
namespace OCA\Deck\Command\ImportHelper;
use OCA\Deck\Command\BoardImport;
use OCA\Deck\Service\AImportService;
use OCA\Deck\Service\TrelloImportService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
abstract class AImport extends AImportService {
/** @var TrelloImportService */
protected $trelloImportService;
/** @var Command */
private $command;
/**
* Data object created from config JSON
*
* @var \StdClass
*/
public $config;
public function __construct(
TrelloImportService $trelloImportService
) {
$this->trelloImportService = $trelloImportService;
}
abstract public function validate(InputInterface $input, OutputInterface $output): void;
abstract public function import(InputInterface $input, OutputInterface $output): void;
/**
* Define Command instance
*
* @param Command $command
* @return void
*/
public function setCommand(Command $command): void {
$this->command = $command;
}
/**
* @return BoardImport
*/
public function getCommand() {
return $this->command;
}
public function setConfigInstance(\stdClass $config) {
$this->trelloImportService->setConfigInstance($config);
}
/**
* Define a config
*
* @param string $configName
* @param mixed $value
* @return void
*/
public function setConfig(string $configName, $value): void {
$this->trelloImportService->setConfig($configName, $value);
}
/**
* Get a config
*
* @param string $configName config name
* @return mixed
*/
public function getConfig(string $configName = null) {
return $this->trelloImportService->getConfig($configName);
}
}

View File

@@ -1,79 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 Vitor Mattos <vitor@php.rio>
*
* @author Vitor Mattos <vitor@php.rio>
*
* @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\Deck\Command\ImportHelper;
use OCA\Deck\Command\BoardImport;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
interface ImportInterface {
/**
* Validate data before run execute method
*
* @param InputInterface $input
* @param OutputInterface $output
* @return void
*/
public function validate(InputInterface $input, OutputInterface $output): void;
/**
* Run import
*
* @param InputInterface $input
* @param OutputInterface $output
* @return void
*/
public function import(InputInterface $input, OutputInterface $output): void;
/**
* Define Command instance
*
* @param Command $command
* @return void
*/
public function setCommand(Command $command): void;
/**
* @return BoardImport
*/
public function getCommand();
/**
* Define a config
*
* @param string $configName
* @param mixed $value
* @return void
*/
public function setConfig(string $configName, $value): void;
/**
* Get a config
*
* @param string $configName config name
* @return mixed
*/
public function getConfig($configName);
}

View File

@@ -1,76 +0,0 @@
<?php
/**
* @copyright Copyright (c) 2021 Vitor Mattos <vitor@php.rio>
*
* @author Vitor Mattos <vitor@php.rio>
*
* @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\Deck\Command\ImportHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
class TrelloHelper extends AImport {
public function validate(InputInterface $input, OutputInterface $output): void {
$this->validateData($input, $output);
$this->trelloImportService->validateOwner();
$this->trelloImportService->validateUsers();
}
public function import(InputInterface $input, OutputInterface $output): void {
$this->trelloImportService->setUserId();
$output->writeln('Importing board...');
$this->trelloImportService->importBoard();
$output->writeln('Assign users to board...');
$this->trelloImportService->assignUsersToBoard();
$output->writeln('Importing labels...');
$this->trelloImportService->importLabels();
$output->writeln('Importing stacks...');
$this->trelloImportService->importStacks();
$output->writeln('Importing cards...');
$this->trelloImportService->importCards();
}
private function validateData(InputInterface $input, OutputInterface $output): void {
$filename = $input->getOption('data');
if (!is_file($filename)) {
$helper = $this->getCommand()->getHelper('question');
$question = new Question(
'Please inform a valid data json file: ',
'data.json'
);
$question->setValidator(function ($answer) {
if (!is_file($answer)) {
throw new \RuntimeException(
'Data file not found'
);
}
return $answer;
});
$data = $helper->ask($input, $output, $question);
$input->setOption('data', $data);
}
$this->trelloImportService->setData(json_decode(file_get_contents($filename)));
if (!$this->trelloImportService->getData()) {
$output->writeln('<error>Is not a json file: ' . $filename . '</error>');
$this->validateData($input, $output);
}
}
}

View File

@@ -1,24 +0,0 @@
{
"type": "object",
"properties": {
"uidRelation": {
"type": "object",
"comment": "Relationship between Trello and Nextcloud usernames",
"example": {
"johndoe": "admin"
}
},
"owner": {
"type": "string",
"required": true,
"comment": "Nextcloud owner username"
},
"color": {
"type": "string",
"required": true,
"pattern": "^[0-9a-fA-F]{6}$",
"comment": "Default color for the board. If you don't inform, the default color will be used.",
"default": "0800fd"
}
}
}