Parse request for backend settings.
This commit is contained in:
@@ -4,15 +4,20 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\API\Backends;
|
||||
|
||||
use App\Backends\Common\Cache as BackendCache;
|
||||
use App\Backends\Common\ClientInterface;
|
||||
use App\Backends\Common\Context;
|
||||
use App\Libs\Attributes\Route\Post;
|
||||
use App\Libs\Config;
|
||||
use App\Libs\ConfigFile;
|
||||
use App\Libs\Container;
|
||||
use App\Libs\DataUtil;
|
||||
use App\Libs\Exceptions\Backends\InvalidContextException;
|
||||
use App\Libs\Exceptions\RuntimeException;
|
||||
use App\Libs\HTTP_STATUS;
|
||||
use App\Libs\Options;
|
||||
use App\Libs\Traits\APITraits;
|
||||
use App\Libs\Uri;
|
||||
use Psr\Http\Message\ResponseInterface as iResponse;
|
||||
use Psr\Http\Message\ServerRequestInterface as iRequest;
|
||||
|
||||
@@ -48,16 +53,28 @@ final class Add
|
||||
}
|
||||
|
||||
$instance = Container::getNew($class);
|
||||
assert($instance instanceof ClientInterface, new \RuntimeException('Invalid client class.'));
|
||||
assert($instance instanceof ClientInterface, new RuntimeException('Invalid client class.'));
|
||||
|
||||
try {
|
||||
$context = $instance->fromRequest($request);
|
||||
$config = DataUtil::fromArray($this->fromRequest($type, $request, $instance));
|
||||
|
||||
$context = new Context(
|
||||
clientName: $type,
|
||||
backendName: $name,
|
||||
backendUrl: new Uri($config->get('url')),
|
||||
cache: Container::get(BackendCache::class),
|
||||
backendId: $config->get('uuid', null),
|
||||
backendToken: $config->get('token'),
|
||||
backendUser: $config->get('user', null),
|
||||
options: $config->get('options', []),
|
||||
);
|
||||
|
||||
if (false === $instance->validateContext($context)) {
|
||||
throw new InvalidContextException('Invalid context.');
|
||||
return api_error('Invalid context information was given.', HTTP_STATUS::HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
$configFile = ConfigFile::open(Config::get('backends_file'), 'yaml', autoSave: false);
|
||||
$configFile->set($name, $context);
|
||||
$configFile = ConfigFile::open(Config::get('backends_file'), 'yaml');
|
||||
$configFile->set($name, $config);
|
||||
$configFile->persist();
|
||||
} catch (InvalidContextException $e) {
|
||||
return api_error($e->getMessage(), HTTP_STATUS::HTTP_BAD_REQUEST);
|
||||
@@ -70,4 +87,53 @@ final class Add
|
||||
|
||||
return api_response(HTTP_STATUS::HTTP_OK, $response);
|
||||
}
|
||||
|
||||
private function fromRequest(string $type, iRequest $request, ClientInterface|null $client = null): array
|
||||
{
|
||||
$data = DataUtil::fromArray($request->getParsedBody());
|
||||
|
||||
$config = [
|
||||
'type' => $type,
|
||||
'url' => $data->get('url'),
|
||||
'token' => $data->get('token'),
|
||||
'user' => $data->get('user'),
|
||||
'uuid' => $data->get('uuid'),
|
||||
'export' => [
|
||||
'enabled' => (bool)$data->get('export.enabled', false),
|
||||
'lastSync' => (int)$data->get('export.lastSync', 0),
|
||||
],
|
||||
'import' => [
|
||||
'enabled' => (bool)$data->get('import.enabled', false),
|
||||
'lastSync' => (int)$data->get('import.lastSync', 0),
|
||||
],
|
||||
'webhook' => [
|
||||
'token' => $data->get('webhook.token'),
|
||||
'match' => [
|
||||
'user' => (bool)$data->get('webhook.match.user', false),
|
||||
'uuid' => (bool)$data->get('webhook.match.uuid', false),
|
||||
],
|
||||
],
|
||||
'options' => [],
|
||||
];
|
||||
|
||||
$optionals = [
|
||||
Options::DUMP_PAYLOAD => 'bool',
|
||||
Options::LIBRARY_SEGMENT => 'int',
|
||||
Options::IGNORE => 'string',
|
||||
];
|
||||
|
||||
foreach ($optionals as $key => $type) {
|
||||
if (null !== ($value = $data->get($key))) {
|
||||
$val = $data->get($value, $type);
|
||||
settype($val, $type);
|
||||
$config = ag_set($config, "options.{$key}", $val);
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $client) {
|
||||
$config = ag_set($config, 'options', $client->fromRequest($request));
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace App\Backends\Common;
|
||||
|
||||
use App\Libs\Entity\StateInterface;
|
||||
use App\Libs\Exceptions\Backends\InvalidContextException;
|
||||
use App\Libs\Mappers\ImportInterface as iImport;
|
||||
use App\Libs\QueueRequests;
|
||||
use DateTimeInterface as iDate;
|
||||
@@ -201,12 +202,12 @@ interface ClientInterface
|
||||
public function listLibraries(array $opts = []): array;
|
||||
|
||||
/**
|
||||
* Parse backend config from request context.
|
||||
* Parse client specific options.
|
||||
*
|
||||
* @param ServerRequestInterface $request request to parse.
|
||||
* @return Context Returns a valid {@see Context} instance.
|
||||
* @return array parsed options.
|
||||
*/
|
||||
public function fromRequest(ServerRequestInterface $request): Context;
|
||||
public function fromRequest(ServerRequestInterface $request): array;
|
||||
|
||||
/**
|
||||
* Validate backend context.
|
||||
@@ -214,7 +215,7 @@ interface ClientInterface
|
||||
* @param Context $context context to validate.
|
||||
*
|
||||
* @return bool Returns true if context is valid.
|
||||
* @throws
|
||||
* @throws InvalidContextException if unable to validate context.
|
||||
*/
|
||||
public function validateContext(Context $context): bool;
|
||||
|
||||
|
||||
@@ -539,9 +539,9 @@ class EmbyClient implements iClient
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function fromRequest(ServerRequestInterface $request): Context
|
||||
public function fromRequest(ServerRequestInterface $request): array
|
||||
{
|
||||
return $this->context;
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -549,7 +549,7 @@ class EmbyClient implements iClient
|
||||
*/
|
||||
public function validateContext(Context $context): bool
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -572,9 +572,9 @@ class JellyfinClient implements iClient
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function fromRequest(ServerRequestInterface $request): Context
|
||||
public function fromRequest(ServerRequestInterface $request): array
|
||||
{
|
||||
return $this->context;
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -582,7 +582,7 @@ class JellyfinClient implements iClient
|
||||
*/
|
||||
public function validateContext(Context $context): bool
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,6 +29,7 @@ use App\Backends\Plex\Action\SearchId;
|
||||
use App\Backends\Plex\Action\SearchQuery;
|
||||
use App\Libs\Config;
|
||||
use App\Libs\Container;
|
||||
use App\Libs\DataUtil;
|
||||
use App\Libs\Entity\StateInterface as iState;
|
||||
use App\Libs\Exceptions\Backends\RuntimeException;
|
||||
use App\Libs\Exceptions\HttpException;
|
||||
@@ -553,9 +554,21 @@ class PlexClient implements iClient
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function fromRequest(ServerRequestInterface $request): Context
|
||||
public function fromRequest(ServerRequestInterface $request): array
|
||||
{
|
||||
return $this->context;
|
||||
$params = DataUtil::fromArray($request->getParsedBody());
|
||||
|
||||
$opts = [];
|
||||
|
||||
if (null !== ($uuid = $params->get('plex_user_uuid'))) {
|
||||
$opts['plex_user_uuid'] = $uuid;
|
||||
}
|
||||
|
||||
if (null !== ($adminToken = $params->get(Options::ADMIN_TOKEN))) {
|
||||
$opts[Options::ADMIN_TOKEN] = $adminToken;
|
||||
}
|
||||
|
||||
return $opts;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -563,7 +576,7 @@ class PlexClient implements iClient
|
||||
*/
|
||||
public function validateContext(Context $context): bool
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,26 +9,27 @@ namespace App\Libs;
|
||||
*/
|
||||
final class Options
|
||||
{
|
||||
public const DRY_RUN = 'DRY_RUN';
|
||||
public const NO_CACHE = 'NO_CACHE';
|
||||
public const CACHE_TTL = 'CACHE_TTL';
|
||||
public const FORCE_FULL = 'FORCE_FULL';
|
||||
public const DEBUG_TRACE = 'DEBUG_TRACE';
|
||||
public const IGNORE_DATE = 'IGNORE_DATE';
|
||||
public const EXPORT_ALLOWED_TIME_DIFF = 'EXPORT_TIME_DIFF';
|
||||
public const RAW_RESPONSE = 'SHOW_RAW_RESPONSE';
|
||||
public const MAPPER_ALWAYS_UPDATE_META = 'ALWAYS_UPDATE_META';
|
||||
public const MAPPER_DISABLE_AUTOCOMMIT = 'DISABLE_AUTOCOMMIT';
|
||||
public const IMPORT_METADATA_ONLY = 'IMPORT_METADATA_ONLY';
|
||||
public const MISMATCH_DEEP_SCAN = 'MISMATCH_DEEP_SCAN';
|
||||
public const DISABLE_GUID = 'DISABLE_GUID';
|
||||
public const LIBRARY_SEGMENT = 'LIBRARY_SEGMENT';
|
||||
public const STATE_UPDATE_EVENT = 'STATE_UPDATE_EVENT';
|
||||
public const DUMP_PAYLOAD = 'DUMP_PAYLOAD';
|
||||
public const ADMIN_TOKEN = 'ADMIN_TOKEN';
|
||||
public const NO_THROW = 'NO_THROW';
|
||||
public const NO_LOGGING = 'NO_LOGGING';
|
||||
public const MAX_EPISODE_RANGE = 'MAX_EPISODE_RANGE';
|
||||
public const string DRY_RUN = 'DRY_RUN';
|
||||
public const string NO_CACHE = 'NO_CACHE';
|
||||
public const string CACHE_TTL = 'CACHE_TTL';
|
||||
public const string FORCE_FULL = 'FORCE_FULL';
|
||||
public const string DEBUG_TRACE = 'DEBUG_TRACE';
|
||||
public const string IGNORE_DATE = 'IGNORE_DATE';
|
||||
public const string EXPORT_ALLOWED_TIME_DIFF = 'EXPORT_TIME_DIFF';
|
||||
public const string RAW_RESPONSE = 'SHOW_RAW_RESPONSE';
|
||||
public const string MAPPER_ALWAYS_UPDATE_META = 'ALWAYS_UPDATE_META';
|
||||
public const string MAPPER_DISABLE_AUTOCOMMIT = 'DISABLE_AUTOCOMMIT';
|
||||
public const string IMPORT_METADATA_ONLY = 'IMPORT_METADATA_ONLY';
|
||||
public const string MISMATCH_DEEP_SCAN = 'MISMATCH_DEEP_SCAN';
|
||||
public const string DISABLE_GUID = 'DISABLE_GUID';
|
||||
public const string LIBRARY_SEGMENT = 'LIBRARY_SEGMENT';
|
||||
public const string STATE_UPDATE_EVENT = 'STATE_UPDATE_EVENT';
|
||||
public const string DUMP_PAYLOAD = 'DUMP_PAYLOAD';
|
||||
public const string ADMIN_TOKEN = 'ADMIN_TOKEN';
|
||||
public const string NO_THROW = 'NO_THROW';
|
||||
public const string NO_LOGGING = 'NO_LOGGING';
|
||||
public const string MAX_EPISODE_RANGE = 'MAX_EPISODE_RANGE';
|
||||
public const string IGNORE = 'ignore';
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user