Added Ignoreid API endpoint.

This commit is contained in:
abdulmohsen
2024-04-28 14:01:08 +03:00
parent 748c85ae5d
commit 0ec860add2
5 changed files with 319 additions and 155 deletions

157
src/API/Backends/Ignore.php Normal file
View File

@@ -0,0 +1,157 @@
<?php
declare(strict_types=1);
namespace App\API\Backends;
use App\Libs\Attributes\Route\Delete;
use App\Libs\Attributes\Route\Get;
use App\Libs\Attributes\Route\Post;
use App\Libs\Config;
use App\Libs\ConfigFile;
use App\Libs\DataUtil;
use App\Libs\HTTP_STATUS;
use App\Libs\Traits\APITraits;
use Psr\Http\Message\ResponseInterface as iResponse;
use Psr\Http\Message\ServerRequestInterface as iRequest;
use Throwable;
final class Ignore
{
use APITraits;
private ConfigFile $file;
public function __construct()
{
$this->file = new ConfigFile(Config::get('path') . '/config/ignore.yaml', type: 'yaml', autoCreate: true);
}
#[Get(Index::URL . '/{name:backend}/ignore[/]', name: 'backends.backend.ignoredIds')]
public function ignoredIds(iRequest $request, array $args = []): iResponse
{
if (null === ($name = ag($args, 'name'))) {
return api_error('No backend was given.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
$list = [];
foreach ($this->file->getAll() as $guid => $date) {
$urlParts = parse_url($guid);
$backend = ag($urlParts, 'host');
$type = ag($urlParts, 'scheme');
$db = ag($urlParts, 'user');
$id = ag($urlParts, 'pass');
$scope = ag($urlParts, 'query');
if ($name !== $backend) {
continue;
}
$rule = makeIgnoreId($guid);
$list[] = [
'rule' => (string)$rule,
'type' => ucfirst($type),
'backend' => $backend,
'db' => $db,
'id' => $id,
'scoped' => null === $scope ? 'No' : 'Yes',
'created' => makeDate($date)->format('Y-m-d H:i:s T'),
];
}
$apiUrl = $request->getUri()->withHost('')->withPort(0)->withScheme('');
$response = [
'ignore' => $list,
'links' => [
'self' => (string)$apiUrl,
'list' => (string)$apiUrl->withPath(parseConfigValue(Index::URL)),
],
];
return api_response(HTTP_STATUS::HTTP_OK, $response);
}
#[Delete(Index::URL . '/{name:backend}/ignore[/]', name: 'backends.backend.ignoredIds.delete')]
public function deleteRule(iRequest $request, array $args = []): iResponse
{
$params = DataUtil::fromRequest($request);
if (null === ($rule = $params->get('rule'))) {
return api_error('No rule was given.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
try {
checkIgnoreRule($rule);
} catch (Throwable $e) {
return api_error($e->getMessage(), HTTP_STATUS::HTTP_BAD_REQUEST);
}
if (!$this->file->has($rule)) {
return api_error('Rule not found.', HTTP_STATUS::HTTP_NOT_FOUND);
}
$this->file->delete($rule)->persist();
return api_response(HTTP_STATUS::HTTP_OK);
}
#[Post(Index::URL . '/{name:backend}/ignore[/]', name: 'backends.backend.ignoredIds.add')]
public function addRule(iRequest $request, array $args = []): iResponse
{
if (null === ($name = ag($args, 'name'))) {
return api_error('No backend was given.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
$data = $this->getBackends(name: $name);
if (empty($data)) {
return api_error(r("Backend '{name}' not found.", ['name' => $name]), HTTP_STATUS::HTTP_NOT_FOUND);
}
$params = DataUtil::fromRequest($request);
if (null === ($rule = $params->get('rule'))) {
$partial = [
'type' => $params->get('type'),
'backend' => $name,
'db' => $params->get('db'),
'id' => $params->get('id'),
];
foreach ($partial as $k => $v) {
if (empty($v)) {
return api_error(r('No {key} was given.', ['key' => $k]), HTTP_STATUS::HTTP_BAD_REQUEST);
}
}
$partial['type'] = strtolower($partial['type']);
$rule = r('{type}://{db}:{id}@{backend}', $partial);
if (null !== ($scoped = $params->get('scoped'))) {
$rule .= '?id=' . $scoped;
}
}
try {
checkIgnoreRule($rule);
$id = makeIgnoreId($rule);
} catch (Throwable $e) {
return api_error($e->getMessage(), HTTP_STATUS::HTTP_BAD_REQUEST);
}
if (true === $this->file->has((string)$id)) {
return api_error('Rule already exists.', HTTP_STATUS::HTTP_CONFLICT);
}
if (true === $this->file->has((string)$id->withQuery(''))) {
return api_error('Global rule already exists.', HTTP_STATUS::HTTP_CONFLICT);
}
$this->file->set((string)$id, time())->persist();
return api_response(HTTP_STATUS::HTTP_CREATED);
}
}

View File

@@ -0,0 +1,87 @@
<?php
declare(strict_types=1);
namespace App\API\Backends\Library;
use App\API\Backends\Index as BackendsIndex;
use App\Libs\Attributes\Route\Route;
use App\Libs\Config;
use App\Libs\ConfigFile;
use App\Libs\DataUtil;
use App\Libs\HTTP_STATUS;
use App\Libs\Options;
use App\Libs\Traits\APITraits;
use Psr\Http\Message\ResponseInterface as iResponse;
use Psr\Http\Message\ServerRequestInterface as iRequest;
final class Ignore
{
use APITraits;
#[Route(['POST', 'DELETE'], BackendsIndex::URL . '/{name:backend}/library[/]', name: 'backends.library.ignore')]
public function _invoke(iRequest $request, array $args = []): iResponse
{
if (null === ($name = ag($args, 'name'))) {
return api_error('No backend was given.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
if (null === ($id = DataUtil::fromRequest($request, true)->get('id', null))) {
return api_error('No library id was given.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
$remove = 'DELETE' === $request->getMethod();
$config = ConfigFile::open(Config::get('backends_file'), 'yaml');
if (null === $config->get($name)) {
return api_error(r("Backend '{backend}' not found.", ['backend' => $name]), HTTP_STATUS::HTTP_NOT_FOUND);
}
$ignoreIds = array_map(
fn($v) => trim($v),
explode(',', (string)$config->get("{$name}.options." . Options::IGNORE, ''))
);
$mode = !(true === $remove);
if ($mode === in_array($id, $ignoreIds)) {
return api_error(r("Library id '{id}' is {message} ignored.", [
'id' => $id,
'message' => $remove ? "not" : 'already',
]), $remove ? HTTP_STATUS::HTTP_NOT_FOUND : HTTP_STATUS::HTTP_CONFLICT);
}
$found = false;
$libraries = $this->getClient(name: $name)->listLibraries();
foreach ($libraries as &$library) {
if ((string)ag($library, 'id') === (string)$id) {
$ignoreIds[] = $id;
$library['ignored'] = !$remove;
$found = true;
break;
}
}
if (false === $found) {
return api_error(r("The library id '{id}' is incorrect.", ['id' => $name]), HTTP_STATUS::HTTP_NOT_FOUND, [
'possible_ids' => array_column($libraries, 'id'),
]);
}
if (true === $remove) {
$ignoreIds = array_diff($ignoreIds, [$id]);
}
$config->set("{$name}.options." . Options::IGNORE, implode(',', array_values($ignoreIds)))->persist();
return api_response(HTTP_STATUS::HTTP_OK, [
'type' => $config->get("{$name}.type"),
'libraries' => $libraries,
'links' => [
'self' => (string)parseConfigValue(BackendsIndex::URL . "/{$name}/library"),
'backend' => (string)parseConfigValue(BackendsIndex::URL . "/{$name}"),
],
]);
}
}

View File

@@ -5,15 +5,10 @@ declare(strict_types=1);
namespace App\API\Backends\Library;
use App\API\Backends\Index as BackendsIndex;
use App\Libs\Attributes\Route\Delete;
use App\Libs\Attributes\Route\Get;
use App\Libs\Attributes\Route\Post;
use App\Libs\Config;
use App\Libs\ConfigFile;
use App\Libs\DataUtil;
use App\Libs\Exceptions\RuntimeException;
use App\Libs\HTTP_STATUS;
use App\Libs\Options;
use App\Libs\Traits\APITraits;
use Psr\Http\Message\ResponseInterface as iResponse;
use Psr\Http\Message\ServerRequestInterface as iRequest;
@@ -39,83 +34,11 @@ final class Index
'type' => ag(array_flip(Config::get('supported')), $client::class),
'libraries' => $client->listLibraries(),
'links' => [
'self' => (string)parseConfigValue(BackendsIndex::URL . "/{$name}/library"),
'self' => (string)$request->getUri()->withHost('')->withPort(0)->withScheme(''),
'backend' => (string)parseConfigValue(BackendsIndex::URL . "/{$name}"),
],
];
return api_response(HTTP_STATUS::HTTP_OK, $response);
}
#[Post(BackendsIndex::URL . '/{name:backend}/library[/]', name: 'backends.library.ignore')]
public function ignoreLibrary(iRequest $request, array $args = []): iResponse
{
if (null === ($name = ag($args, 'name'))) {
return api_error('No backend was given.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
if (null === ($id = DataUtil::fromRequest($request)->get('id', null))) {
return api_error('No library id was given.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
$remove = 'DELETE' === $request->getMethod();
$config = ConfigFile::open(Config::get('backends_file'), 'yaml');
if (null === $config->get($name)) {
return api_error(r("Backend '{backend}' not found.", ['backend' => $name]), HTTP_STATUS::HTTP_NOT_FOUND);
}
$ignoreIds = array_map(
fn($v) => trim($v),
explode(',', (string)$config->get("{$name}.options." . Options::IGNORE, ''))
);
$mode = !(true === $remove);
if ($mode === in_array($id, $ignoreIds)) {
return api_error(r("Library id '{id}' is {message} ignored.", [
'id' => $id,
'message' => $remove ? "not" : 'already',
]), $remove ? HTTP_STATUS::HTTP_NOT_FOUND : HTTP_STATUS::HTTP_CONFLICT);
}
$found = false;
$libraries = $this->getClient(name: $name)->listLibraries();
foreach ($libraries as &$library) {
if ((string)ag($library, 'id') === (string)$id) {
$ignoreIds[] = $id;
$library['ignored'] = !$remove;
$found = true;
break;
}
}
if (false === $found) {
return api_error(r("The library id '{id}' is incorrect.", ['id' => $name]), HTTP_STATUS::HTTP_NOT_FOUND, [
'possible_ids' => array_column($libraries, 'id'),
]);
}
if (true === $remove) {
$ignoreIds = array_diff($ignoreIds, [$id]);
}
$config->set("{$name}.options." . Options::IGNORE, implode(',', array_values($ignoreIds)))->persist();
return api_response(HTTP_STATUS::HTTP_OK, [
'type' => $config->get("{$name}.type"),
'libraries' => $libraries,
'links' => [
'self' => (string)parseConfigValue(BackendsIndex::URL . "/{$name}/library"),
'backend' => (string)parseConfigValue(BackendsIndex::URL . "/{$name}"),
],
]);
}
#[Delete(BackendsIndex::URL . '/{name:backend}/library/{id}[/]', name: 'backends.library.ignore.delete')]
public function deleteIgnoreLibrary(iRequest $request, array $args = []): iResponse
{
return $this->ignoreLibrary($request->withParsedBody(['id' => ag($args, 'id')]), $args);
}
}