Documentation, improvements on validation, refactor

Validate get boad
change pattern of api params
Import only one board by api
Populate data from api
Update class diagram
Update documentation
Add return when success
Sort comments
Fix order of cards
Instructions of attachments

Signed-off-by: Vitor Mattos <vitor@php.rio>
This commit is contained in:
Vitor Mattos
2021-07-25 00:15:50 -03:00
committed by Julius Härtl
parent 202ea30090
commit e87c063076
9 changed files with 400 additions and 175 deletions

View File

@@ -23,14 +23,11 @@
namespace OCA\Deck\Service;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\RequestException;
use OCP\AppFramework\Http;
use OCP\Http\Client\IClient;
use OCP\Http\Client\IClientService;
use OCP\IL10N;
use OCP\ILogger;
use OCP\IUserManager;
use Psr\Log\LoggerInterface;
class BoardImportTrelloApiService extends BoardImportTrelloJsonService {
/** @var string */
@@ -38,16 +35,17 @@ class BoardImportTrelloApiService extends BoardImportTrelloJsonService {
protected $needValidateData = false;
/** @var IClient */
private $httpClient;
/** @var ILogger */
/** @var LoggerInterface */
protected $logger;
/** @var string */
private $baseApiUrl = 'https://api.trello.com/1';
/** @var ?\stdClass[] */
private $boards;
public function __construct(
IUserManager $userManager,
IL10N $l10n,
ILogger $logger,
LoggerInterface $logger,
IClientService $httpClientService
) {
parent::__construct($userManager, $l10n);
@@ -56,44 +54,150 @@ class BoardImportTrelloApiService extends BoardImportTrelloJsonService {
}
public function bootstrap(): void {
$this->getBoards();
$this->populateBoard();
$this->populateMembers();
$this->populateLabels();
$this->populateLists();
$this->populateCheckLists();
$this->populateCards();
$this->populateActions();
parent::bootstrap();
}
private function getBoards() {
$boards = $this->doRequest('/members/me/boards');
private function populateActions(): void {
$data = $this->getImportService()->getData();
$data->actions = $this->doRequest(
'/boards/' . $data->id . '/actions',
[
'filter' => 'commentCard',
'fields=memberCreator,type,data,date',
'memberCreator_fields' => 'username',
'limit' => 1000
]
);
}
private function doRequest($path, $queryString = []) {
private function populateCards(): void {
$data = $this->getImportService()->getData();
$data->cards = $this->doRequest(
'/boards/' . $data->id . '/cards',
[
'fields' => 'id,idMembers,dateLastActivity,closed,idChecklists,name,idList,pos,desc,due,labels',
'attachments' => true,
'attachment_fields' => 'name,url,date',
'limit' => 1000
]
);
}
private function populateCheckLists(): void {
$data = $this->getImportService()->getData();
$data->checklists = $this->doRequest(
'/boards/' . $data->id . '/checkLists',
[
'fields' => 'id,idCard,name',
'checkItem_fields' => 'id,state,name',
'limit' => 1000
]
);
}
private function populateLists(): void {
$data = $this->getImportService()->getData();
$data->lists = $this->doRequest(
'/boards/' . $data->id . '/lists',
[
'fields' => 'id,name,closed',
'limit' => 1000
]
);
}
private function populateLabels(): void {
$data = $this->getImportService()->getData();
$data->labels = $this->doRequest(
'/boards/' . $data->id . '/labels',
[
'fields' => 'id,color,name',
'limit' => 1000
]
);
}
private function populateMembers(): void {
$data = $this->getImportService()->getData();
$data->members = $this->doRequest(
'/boards/' . $data->id . '/members',
[
'fields' => 'username',
'limit' => 1000
]
);
}
private function populateBoard(): void {
$toImport = $this->getImportService()->getConfig('board');
$board = $this->doRequest(
'/boards/' . $toImport,
['fields' => 'id,name']
);
if ($board instanceof \stdClass) {
$this->getImportService()->setData($board);
return;
}
throw new \Exception('Invalid board id to import');
}
/**
* @return array|\stdClass
*/
private function doRequest(string $path = '', array $queryString = []) {
$target = $this->baseApiUrl . $path;
try {
$target = $this->baseApiUrl . $path;
$result = $this->httpClient
->get($target, $this->getQueryString($queryString))
->getBody();
$data = json_decode($result);
} catch (ClientException $e) {
$status = $e->getCode();
if ($status === Http::STATUS_FORBIDDEN) {
$this->logger->info($target . ' refused.', ['app' => 'deck']);
} else {
$this->logger->info($target . ' responded with a ' . $status . ' containing: ' . $e->getMessage(), ['app' => 'deck']);
if (is_string($result)) {
$data = json_decode($result);
if (is_array($data)) {
$data = array_merge(
$data,
$this->paginate($path, $queryString, $data)
);
}
return $data;
}
} catch (RequestException $e) {
$this->logger->logException($e, [
'message' => 'Could not connect to ' . $target,
'level' => ILogger::INFO,
'app' => 'deck',
]);
throw new \Exception('Invalid return of api');
} catch (\Throwable $e) {
$this->logger->logException($e, ['app' => 'deck']);
$this->logger->critical(
$e->getMessage(),
['app' => 'deck']
);
throw new \Exception($e->getMessage());
}
return $data;
}
private function getQueryString($params = []): array {
private function paginate(string $path = '', array $queryString = [], array $data = []): array {
if (empty($queryString['limit'])) {
return [];
}
if (count($data) < $queryString['limit']) {
return [];
}
$queryString['before'] = end($data)->id;
$return = $this->doRequest($path, $queryString);
if (is_array($return)) {
return $return;
}
throw new \Exception('Invalid return of api');
}
private function getQueryString(array $params = []): array {
$apiSettings = $this->getImportService()->getConfig('api');
$params['key'] = $apiSettings->key;
$params['value'] = $apiSettings->token;
return $params;
$params['token'] = $apiSettings->token;
return [
'query' => $params
];
}
}