From 722518579f1e27ef0d6007f63b47efba35d877d0 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 31 Jul 2020 19:03:27 -0400 Subject: [PATCH] Increment chapter/episode counts via GraphQL --- app/bootstrap.php | 22 +- src/AnimeClient/API/Kitsu.php | 3 + src/AnimeClient/API/Kitsu/KitsuAnimeTrait.php | 4 +- .../API/Kitsu/KitsuJsonApiRequestBuilder.php | 271 ------------------ src/AnimeClient/API/Kitsu/KitsuMangaTrait.php | 6 +- .../API/Kitsu/KitsuRequestBuilder.php | 218 ++++++++++---- src/AnimeClient/API/Kitsu/KitsuTrait.php | 24 +- src/AnimeClient/API/Kitsu/ListItem.php | 20 +- src/AnimeClient/API/Kitsu/Model.php | 26 +- src/AnimeClient/Command/BaseCommand.php | 12 +- src/AnimeClient/Controller.php | 3 - src/AnimeClient/Controller/Manga.php | 4 +- src/AnimeClient/Model/Manga.php | 12 +- 13 files changed, 227 insertions(+), 398 deletions(-) delete mode 100644 src/AnimeClient/API/Kitsu/KitsuJsonApiRequestBuilder.php diff --git a/app/bootstrap.php b/app/bootstrap.php index 196457ed..56b253ec 100644 --- a/app/bootstrap.php +++ b/app/bootstrap.php @@ -21,8 +21,9 @@ use Aura\Router\RouterContainer; use Aura\Session\SessionFactory; use Aviat\AnimeClient\API\{ Anilist, + Anilist\AnilistRequestBuilder, Kitsu, - Kitsu\KitsuJsonApiRequestBuilder + Kitsu\KitsuRequestBuilder }; use Aviat\AnimeClient\Model; use Aviat\Banker\Teller; @@ -45,13 +46,13 @@ return static function (array $configArray = []): Container { // ------------------------------------------------------------------------- $appLogger = new Logger('animeclient'); - $appLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/app.log', Logger::NOTICE)); + $appLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/app.log', Logger::WARNING)); $anilistRequestLogger = new Logger('anilist-request'); - $anilistRequestLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/anilist_request.log', Logger::NOTICE)); + $anilistRequestLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/anilist_request.log', Logger::WARNING)); $kitsuRequestLogger = new Logger('kitsu-request'); - $kitsuRequestLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/kitsu_request.log', Logger::NOTICE)); + $kitsuRequestLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/kitsu_request.log', Logger::WARNING)); $container->setLogger($appLogger); $container->setLogger($anilistRequestLogger, 'anilist-request'); @@ -113,28 +114,23 @@ return static function (array $configArray = []): Container { // Models $container->set('kitsu-model', static function(ContainerInterface $container): Kitsu\Model { - $jsonApiRequestBuilder = new KitsuJsonApiRequestBuilder($container); - $jsonApiRequestBuilder->setLogger($container->getLogger('kitsu-request')); - - $requestBuilder = new Kitsu\KitsuRequestBuilder($container); + $requestBuilder = new KitsuRequestBuilder($container); $requestBuilder->setLogger($container->getLogger('kitsu-request')); $listItem = new Kitsu\ListItem(); $listItem->setContainer($container); - $listItem->setJsonApiRequestBuilder($jsonApiRequestBuilder) - ->setRequestBuilder($requestBuilder); + $listItem->setRequestBuilder($requestBuilder); $model = new Kitsu\Model($listItem); $model->setContainer($container); - $model->setJsonApiRequestBuilder($jsonApiRequestBuilder) - ->setRequestBuilder($requestBuilder); + $model->setRequestBuilder($requestBuilder); $cache = $container->get('cache'); $model->setCache($cache); return $model; }); $container->set('anilist-model', static function(ContainerInterface $container): Anilist\Model { - $requestBuilder = new Anilist\AnilistRequestBuilder(); + $requestBuilder = new AnilistRequestBuilder(); $requestBuilder->setLogger($container->getLogger('anilist-request')); $listItem = new Anilist\ListItem(); diff --git a/src/AnimeClient/API/Kitsu.php b/src/AnimeClient/API/Kitsu.php index fb1ece76..1104f2d1 100644 --- a/src/AnimeClient/API/Kitsu.php +++ b/src/AnimeClient/API/Kitsu.php @@ -32,6 +32,9 @@ final class Kitsu { public const ANIME_HISTORY_LIST_CACHE_KEY = 'kitsu-anime-history-list'; public const MANGA_HISTORY_LIST_CACHE_KEY = 'kitsu-manga-history-list'; + public const GRAPHQL_ENDPOINT = 'https://kitsu.io/api/graphql'; + public const JSON_API_ENDPOINT = 'https://kitsu.io/api/edge/'; + public const SECONDS_IN_MINUTE = 60; public const MINUTES_IN_HOUR = 60; public const MINUTES_IN_DAY = 1440; diff --git a/src/AnimeClient/API/Kitsu/KitsuAnimeTrait.php b/src/AnimeClient/API/Kitsu/KitsuAnimeTrait.php index 98196dc4..d0bbeaf9 100644 --- a/src/AnimeClient/API/Kitsu/KitsuAnimeTrait.php +++ b/src/AnimeClient/API/Kitsu/KitsuAnimeTrait.php @@ -247,7 +247,7 @@ trait KitsuAnimeTrait { 'include' => 'mappings' ] ]; - $data = $this->jsonApiRequestBuilder->getRequest("anime/{$kitsuAnimeId}", $options); + $data = $this->requestBuilder->getRequest("anime/{$kitsuAnimeId}", $options); if ( ! array_key_exists('included', $data)) { @@ -293,7 +293,7 @@ trait KitsuAnimeTrait { ]; $options = array_merge($defaultOptions, $options); - return $this->jsonApiRequestBuilder->setUpRequest('GET', 'library-entries', ['query' => $options]); + return $this->requestBuilder->setUpRequest('GET', 'library-entries', ['query' => $options]); } /** diff --git a/src/AnimeClient/API/Kitsu/KitsuJsonApiRequestBuilder.php b/src/AnimeClient/API/Kitsu/KitsuJsonApiRequestBuilder.php deleted file mode 100644 index 93c7601d..00000000 --- a/src/AnimeClient/API/Kitsu/KitsuJsonApiRequestBuilder.php +++ /dev/null @@ -1,271 +0,0 @@ - - * @copyright 2015 - 2020 Timothy J. Warren - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @version 5 - * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient - */ - -namespace Aviat\AnimeClient\API\Kitsu; - -use const Aviat\AnimeClient\SESSION_SEGMENT; -use const Aviat\AnimeClient\USER_AGENT; - -use function Amp\Promise\wait; -use function Aviat\AnimeClient\getResponse; - -use Amp\Http\Client\Request; -use Amp\Http\Client\Response; -use Aviat\AnimeClient\API\APIRequestBuilder; -use Aviat\AnimeClient\API\FailedResponseException; -use Aviat\AnimeClient\API\Kitsu as K; -use Aviat\AnimeClient\Enum\EventType; -use Aviat\Ion\Di\ContainerAware; -use Aviat\Ion\Di\ContainerInterface; -use Aviat\Ion\Event; -use Aviat\Ion\Json; -use Aviat\Ion\JsonException; - -final class KitsuJsonApiRequestBuilder extends APIRequestBuilder { - use ContainerAware; - - /** - * The base url for api requests - * @var string $base_url - */ - protected string $baseUrl = 'https://kitsu.io/api/edge/'; - - /** - * HTTP headers to send with every request - * - * @var array - */ - protected array $defaultHeaders = [ - 'User-Agent' => USER_AGENT, - 'Accept' => 'application/vnd.api+json', - 'Content-Type' => 'application/vnd.api+json', - 'CLIENT_ID' => 'dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd', - 'CLIENT_SECRET' => '54d7307928f63414defd96399fc31ba847961ceaecef3a5fd93144e960c0e151', - ]; - - public function __construct(ContainerInterface $container) - { - $this->setContainer($container); - } - - /** - * Create a request object - * - * @param string $type - * @param string $url - * @param array $options - * @return Request - */ - public function setUpRequest(string $type, string $url, array $options = []): Request - { - $request = $this->newRequest($type, $url); - - $sessionSegment = $this->getContainer() - ->get('session') - ->getSegment(SESSION_SEGMENT); - - $cache = $this->getContainer()->get('cache'); - $token = null; - - if ($cache->has(K::AUTH_TOKEN_CACHE_KEY)) - { - $token = $cache->get(K::AUTH_TOKEN_CACHE_KEY); - } - else if ($url !== K::AUTH_URL && $sessionSegment->get('auth_token') !== NULL) - { - $token = $sessionSegment->get('auth_token'); - if ( ! (empty($token) || $cache->has(K::AUTH_TOKEN_CACHE_KEY))) - { - $cache->set(K::AUTH_TOKEN_CACHE_KEY, $token); - } - } - - if ($token !== NULL) - { - $request = $request->setAuth('bearer', $token); - } - - if (array_key_exists('form_params', $options)) - { - $request = $request->setFormFields($options['form_params']); - } - - if (array_key_exists('query', $options)) - { - $request = $request->setQuery($options['query']); - } - - if (array_key_exists('body', $options)) - { - $request = $request->setJsonBody($options['body']); - } - - if (array_key_exists('headers', $options)) - { - $request = $request->setHeaders($options['headers']); - } - - return $request->getFullRequest(); - } - - /** - * Remove some boilerplate for get requests - * - * @param mixed ...$args - * @throws Throwable - * @return array - */ - public function getRequest(...$args): array - { - return $this->request('GET', ...$args); - } - - /** - * Remove some boilerplate for patch requests - * - * @param mixed ...$args - * @throws Throwable - * @return array - */ - public function patchRequest(...$args): array - { - return $this->request('PATCH', ...$args); - } - - /** - * Remove some boilerplate for post requests - * - * @param mixed ...$args - * @throws Throwable - * @return array - */ - public function postRequest(...$args): array - { - $logger = NULL; - if ($this->getContainer()) - { - $logger = $this->container->getLogger('kitsu-request'); - } - - $response = $this->getResponse('POST', ...$args); - $validResponseCodes = [200, 201]; - - if ( ! in_array($response->getStatus(), $validResponseCodes, TRUE) && $logger) - { - $logger->warning('Non 2xx response for POST api call', $response->getBody()); - } - - return JSON::decode(wait($response->getBody()->buffer()), TRUE); - } - - /** - * Remove some boilerplate for delete requests - * - * @param mixed ...$args - * @throws Throwable - * @return bool - */ - public function deleteRequest(...$args): bool - { - $response = $this->getResponse('DELETE', ...$args); - return ($response->getStatus() === 204); - } - - /** - * Make a request - * - * @param string $type - * @param string $url - * @param array $options - * @return Response - * @throws Throwable - */ - public function getResponse(string $type, string $url, array $options = []): Response - { - $logger = NULL; - if ($this->getContainer()) - { - $logger = $this->container->getLogger('kitsu-request'); - } - - $request = $this->setUpRequest($type, $url, $options); - - $response = getResponse($request); - - if ($logger) - { - $logger->debug('Kitsu API Response', [ - 'response_status' => $response->getStatus(), - 'request_headers' => $response->getOriginalRequest()->getHeaders(), - 'response_headers' => $response->getHeaders() - ]); - } - - return $response; - } - - /** - * Make a request - * - * @param string $type - * @param string $url - * @param array $options - * @throws JsonException - * @throws FailedResponseException - * @throws Throwable - * @return array - */ - private function request(string $type, string $url, array $options = []): array - { - $logger = NULL; - if ($this->getContainer()) - { - $logger = $this->container->getLogger('kitsu-request'); - } - - $response = $this->getResponse($type, $url, $options); - $statusCode = $response->getStatus(); - - // Check for requests that are unauthorized - if ($statusCode === 401 || $statusCode === 403) - { - Event::emit(EventType::UNAUTHORIZED); - } - - // Any other type of failed request - if ($statusCode > 299 || $statusCode < 200) - { - if ($logger) - { - $logger->warning('Non 2xx response for api call', (array)$response); - } - - throw new FailedResponseException('Failed to get the proper response from the API'); - } - - try - { - return Json::decode(wait($response->getBody()->buffer())); - } - catch (JsonException $e) - { - print_r($e); - die(); - } - } - - -} \ No newline at end of file diff --git a/src/AnimeClient/API/Kitsu/KitsuMangaTrait.php b/src/AnimeClient/API/Kitsu/KitsuMangaTrait.php index cf01f9e7..4a499417 100644 --- a/src/AnimeClient/API/Kitsu/KitsuMangaTrait.php +++ b/src/AnimeClient/API/Kitsu/KitsuMangaTrait.php @@ -143,7 +143,7 @@ trait KitsuMangaTrait { if ($list === NULL) { - $data = $this->jsonApiRequestBuilder->getRequest('library-entries', $options) ?? []; + $data = $this->requestBuilder->getRequest('library-entries', $options) ?? []; // Bail out on no data if (empty($data) || ( ! array_key_exists('included', $data))) @@ -264,7 +264,7 @@ trait KitsuMangaTrait { ]; $options = array_merge($defaultOptions, $options); - return $this->jsonApiRequestBuilder->setUpRequest('GET', 'library-entries', ['query' => $options]); + return $this->requestBuilder->setUpRequest('GET', 'library-entries', ['query' => $options]); } /** @@ -281,7 +281,7 @@ trait KitsuMangaTrait { 'include' => 'mappings' ] ]; - $data = $this->jsonApiRequestBuilder->getRequest("manga/{$kitsuMangaId}", $options); + $data = $this->requestBuilder->getRequest("manga/{$kitsuMangaId}", $options); $mappings = array_column($data['included'], 'attributes'); foreach($mappings as $map) diff --git a/src/AnimeClient/API/Kitsu/KitsuRequestBuilder.php b/src/AnimeClient/API/Kitsu/KitsuRequestBuilder.php index 7d176fca..8b24ddc3 100644 --- a/src/AnimeClient/API/Kitsu/KitsuRequestBuilder.php +++ b/src/AnimeClient/API/Kitsu/KitsuRequestBuilder.php @@ -16,20 +16,23 @@ namespace Aviat\AnimeClient\API\Kitsu; -use Amp\Http\Client\Request; -use Amp\Http\Client\Response; -use Aviat\AnimeClient\API\Anilist; -use Aviat\AnimeClient\API\Kitsu as K; -use Aviat\Ion\Di\ContainerAware; -use Aviat\Ion\Di\ContainerInterface; - -use Aviat\Ion\Json; -use function Amp\Promise\wait; -use function Aviat\AnimeClient\getResponse; use const Aviat\AnimeClient\SESSION_SEGMENT; use const Aviat\AnimeClient\USER_AGENT; +use function Amp\Promise\wait; +use function Aviat\AnimeClient\getResponse; + +use Amp\Http\Client\Request; +use Amp\Http\Client\Response; use Aviat\AnimeClient\API\APIRequestBuilder; +use Aviat\AnimeClient\API\FailedResponseException; +use Aviat\AnimeClient\API\Kitsu as K; +use Aviat\AnimeClient\Enum\EventType; +use Aviat\Ion\Di\ContainerAware; +use Aviat\Ion\Di\ContainerInterface; +use Aviat\Ion\Event; +use Aviat\Ion\Json; +use Aviat\Ion\JsonException; final class KitsuRequestBuilder extends APIRequestBuilder { use ContainerAware; @@ -38,13 +41,7 @@ final class KitsuRequestBuilder extends APIRequestBuilder { * The base url for api requests * @var string $base_url */ - protected string $baseUrl = 'https://kitsu.io/api/graphql'; - - /** - * Valid HTTP request methods - * @var array - */ - protected array $validMethods = ['POST']; + protected string $baseUrl = K::JSON_API_ENDPOINT; /** * HTTP headers to send with every request @@ -52,9 +49,11 @@ final class KitsuRequestBuilder extends APIRequestBuilder { * @var array */ protected array $defaultHeaders = [ - 'User-Agent' => USER_AGENT, - 'Accept' => 'application/json', - 'Content-Type' => 'application/json', + 'User-Agent' => USER_AGENT, + 'Accept' => 'application/vnd.api+json', + 'Content-Type' => 'application/vnd.api+json', + 'CLIENT_ID' => 'dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd', + 'CLIENT_SECRET' => '54d7307928f63414defd96399fc31ba847961ceaecef3a5fd93144e960c0e151', ]; public function __construct(ContainerInterface $container) @@ -64,14 +63,15 @@ final class KitsuRequestBuilder extends APIRequestBuilder { /** * Create a request object + * + * @param string $type * @param string $url * @param array $options * @return Request - * @throws Throwable */ - public function setUpRequest(string $url, array $options = []): Request + public function setUpRequest(string $type, string $url, array $options = []): Request { - $request = $this->newRequest('POST', $url); + $request = $this->newRequest($type, $url); $sessionSegment = $this->getContainer() ->get('session') @@ -121,6 +121,69 @@ final class KitsuRequestBuilder extends APIRequestBuilder { return $request->getFullRequest(); } + /** + * Remove some boilerplate for get requests + * + * @param mixed ...$args + * @throws Throwable + * @return array + */ + public function getRequest(...$args): array + { + return $this->request('GET', ...$args); + } + + /** + * Remove some boilerplate for patch requests + * + * @param mixed ...$args + * @throws Throwable + * @return array + */ + public function patchRequest(...$args): array + { + return $this->request('PATCH', ...$args); + } + + /** + * Remove some boilerplate for post requests + * + * @param mixed ...$args + * @throws Throwable + * @return array + */ + public function postRequest(...$args): array + { + $logger = NULL; + if ($this->getContainer()) + { + $logger = $this->container->getLogger('kitsu-request'); + } + + $response = $this->getResponse('POST', ...$args); + $validResponseCodes = [200, 201]; + + if ( ! in_array($response->getStatus(), $validResponseCodes, TRUE) && $logger) + { + $logger->warning('Non 2xx response for POST api call', $response->getBody()); + } + + return JSON::decode(wait($response->getBody()->buffer()), TRUE); + } + + /** + * Remove some boilerplate for delete requests + * + * @param mixed ...$args + * @throws Throwable + * @return bool + */ + public function deleteRequest(...$args): bool + { + $response = $this->getResponse('DELETE', ...$args); + return ($response->getStatus() === 204); + } + /** * Run a GraphQL API query * @@ -130,7 +193,7 @@ final class KitsuRequestBuilder extends APIRequestBuilder { */ public function runQuery(string $name, array $variables = []): array { - $file = realpath(__DIR__ . "/GraphQL/Queries/{$name}.graphql"); + $file =__DIR__ . "/GraphQL/Queries/{$name}.graphql"; if ( ! file_exists($file)) { throw new LogicException('GraphQL query file does not exist.'); @@ -151,7 +214,7 @@ final class KitsuRequestBuilder extends APIRequestBuilder { } } - return $this->postRequest([ + return $this->graphResponse([ 'body' => $body ]); } @@ -164,15 +227,14 @@ final class KitsuRequestBuilder extends APIRequestBuilder { */ public function mutateRequest (string $name, array $variables = []): Request { - $file = realpath(__DIR__ . "/GraphQL/Mutations/{$name}.graphql"); - if (!file_exists($file)) + $file = __DIR__ . "/GraphQL/Mutations/{$name}.graphql"; + if ( ! file_exists($file)) { throw new LogicException('GraphQL mutation file does not exist.'); } // $query = str_replace(["\t", "\n"], ' ', file_get_contents($file)); $query = file_get_contents($file); - $body = [ 'query' => $query ]; @@ -185,7 +247,7 @@ final class KitsuRequestBuilder extends APIRequestBuilder { } } - return $this->setUpRequest(Anilist::BASE_URL, [ + return $this->setUpRequest('POST', K::GRAPHQL_ENDPOINT, [ 'body' => $body, ]); } @@ -196,7 +258,7 @@ final class KitsuRequestBuilder extends APIRequestBuilder { * @return array * @throws Throwable */ - public function mutate (string $name, array $variables = []): array + public function mutate(string $name, array $variables = []): array { $request = $this->mutateRequest($name, $variables); $response = $this->getResponseFromRequest($request); @@ -207,29 +269,34 @@ final class KitsuRequestBuilder extends APIRequestBuilder { /** * Make a request * + * @param string $type * @param string $url * @param array $options * @return Response * @throws Throwable */ - private function getResponse(string $url, array $options = []): Response + public function getResponse(string $type, string $url, array $options = []): Response { $logger = NULL; if ($this->getContainer()) { - $logger = $this->container->getLogger('anilist-request'); + $logger = $this->container->getLogger('kitsu-request'); } - $request = $this->setUpRequest($url, $options); + $request = $this->setUpRequest($type, $url, $options); + $response = getResponse($request); - $logger->debug('Anilist response', [ - 'status' => $response->getStatus(), - 'reason' => $response->getReason(), - 'body' => $response->getBody(), - 'headers' => $response->getHeaders(), - 'requestHeaders' => $request->getHeaders(), - ]); + if ($logger) + { + $logger->debug('Kitsu API Response', [ + 'status' => $response->getStatus(), + 'reason' => $response->getReason(), + 'body' => $response->getBody(), + 'headers' => $response->getHeaders(), + 'requestHeaders' => $request->getHeaders(), + ]); + } return $response; } @@ -244,12 +311,12 @@ final class KitsuRequestBuilder extends APIRequestBuilder { $logger = NULL; if ($this->getContainer()) { - $logger = $this->container->getLogger('anilist-request'); + $logger = $this->container->getLogger('kitsu-request'); } $response = getResponse($request); - $logger->debug('Anilist response', [ + $logger->debug('Kitsu GraphQL response', [ 'status' => $response->getStatus(), 'reason' => $response->getReason(), 'body' => $response->getBody(), @@ -261,27 +328,26 @@ final class KitsuRequestBuilder extends APIRequestBuilder { } /** - * Remove some boilerplate for post requests + * Remove some boilerplate for GraphQL requests * * @param array $options * @return array - * @throws Throwable + * @throws \Throwable */ - protected function postRequest(array $options = []): array + protected function graphResponse(array $options = []): array { - $response = $this->getResponse($this->baseUrl, $options); + $response = $this->getResponse('POST', K::GRAPHQL_ENDPOINT, $options); $validResponseCodes = [200, 201]; $logger = NULL; if ($this->getContainer()) { $logger = $this->container->getLogger('kitsu-request'); - $logger->debug('Kitsu response', [ + $logger->debug('Kitsu GraphQL response', [ 'status' => $response->getStatus(), 'reason' => $response->getReason(), 'body' => $response->getBody(), 'headers' => $response->getHeaders(), - //'requestHeaders' => $request->getHeaders(), ]); } @@ -289,12 +355,62 @@ final class KitsuRequestBuilder extends APIRequestBuilder { { if ($logger !== NULL) { - $logger->warning('Non 200 response for POST api call', (array)$response->getBody()); + $logger->warning('Non 200 response for GraphQL call', (array)$response->getBody()); } } - // dump(wait($response->getBody()->buffer())); - return Json::decode(wait($response->getBody()->buffer())); } + + /** + * Make a request + * + * @param string $type + * @param string $url + * @param array $options + * @throws JsonException + * @throws FailedResponseException + * @throws Throwable + * @return array + */ + private function request(string $type, string $url, array $options = []): array + { + $logger = NULL; + if ($this->getContainer()) + { + $logger = $this->container->getLogger('kitsu-request'); + } + + $response = $this->getResponse($type, $url, $options); + $statusCode = $response->getStatus(); + + // Check for requests that are unauthorized + if ($statusCode === 401 || $statusCode === 403) + { + Event::emit(EventType::UNAUTHORIZED); + } + + // Any other type of failed request + if ($statusCode > 299 || $statusCode < 200) + { + if ($logger) + { + $logger->warning('Non 2xx response for api call', (array)$response); + } + + throw new FailedResponseException('Failed to get the proper response from the API'); + } + + try + { + return Json::decode(wait($response->getBody()->buffer())); + } + catch (JsonException $e) + { + print_r($e); + die(); + } + } + + } \ No newline at end of file diff --git a/src/AnimeClient/API/Kitsu/KitsuTrait.php b/src/AnimeClient/API/Kitsu/KitsuTrait.php index 694c3148..322678dc 100644 --- a/src/AnimeClient/API/Kitsu/KitsuTrait.php +++ b/src/AnimeClient/API/Kitsu/KitsuTrait.php @@ -18,19 +18,13 @@ namespace Aviat\AnimeClient\API\Kitsu; trait KitsuTrait { /** - * The request builder for the Kitsu GraphQL API + * The request builder for the Kitsu API * @var KitsuRequestBuilder */ - protected ?KitsuRequestBuilder $requestBuilder = null; + protected KitsuRequestBuilder $requestBuilder; /** - * The request builder for the Kitsu API - * @var KitsuJsonApiRequestBuilder - */ - protected KitsuJsonApiRequestBuilder $jsonApiRequestBuilder; - - /** - * Set the GraphQL request builder object + * Set the request builder object * * @param KitsuRequestBuilder $requestBuilder * @return $this @@ -40,16 +34,4 @@ trait KitsuTrait { $this->requestBuilder = $requestBuilder; return $this; } - - /** - * Set the request builder object - * - * @param KitsuJsonApiRequestBuilder $requestBuilder - * @return self - */ - public function setJsonApiRequestBuilder($requestBuilder): self - { - $this->jsonApiRequestBuilder = $requestBuilder; - return $this; - } } \ No newline at end of file diff --git a/src/AnimeClient/API/Kitsu/ListItem.php b/src/AnimeClient/API/Kitsu/ListItem.php index 2a0b38a3..27931b3c 100644 --- a/src/AnimeClient/API/Kitsu/ListItem.php +++ b/src/AnimeClient/API/Kitsu/ListItem.php @@ -75,7 +75,7 @@ final class ListItem extends AbstractListItem { $authHeader = $this->getAuthHeader(); - $request = $this->jsonApiRequestBuilder->newRequest('POST', 'library-entries'); + $request = $this->requestBuilder->newRequest('POST', 'library-entries'); if ($authHeader !== NULL) { @@ -94,7 +94,7 @@ final class ListItem extends AbstractListItem { public function delete(string $id): Request { $authHeader = $this->getAuthHeader(); - $request = $this->jsonApiRequestBuilder->newRequest('DELETE', "library-entries/{$id}"); + $request = $this->requestBuilder->newRequest('DELETE', "library-entries/{$id}"); if ($authHeader !== NULL) { @@ -113,7 +113,7 @@ final class ListItem extends AbstractListItem { { $authHeader = $this->getAuthHeader(); - $request = $this->jsonApiRequestBuilder->newRequest('GET', "library-entries/{$id}") + $request = $this->requestBuilder->newRequest('GET', "library-entries/{$id}") ->setQuery([ 'include' => 'media,media.categories,media.mappings' ]); @@ -128,9 +128,19 @@ final class ListItem extends AbstractListItem { return Json::decode(wait($response->getBody()->buffer())); } + /** + * Increase the progress on the medium by 1 + * + * @param string $id + * @param FormItemData $data + * @return Request + */ public function increment(string $id, FormItemData $data): Request { - return $this->update($id, $data); + return $this->requestBuilder->mutateRequest('IncrementLibraryItem', [ + 'id' => $id, + 'progress' => $data->progress + ]); } /** @@ -155,7 +165,7 @@ final class ListItem extends AbstractListItem { $data->progress = 0; } - $request = $this->jsonApiRequestBuilder->newRequest('PATCH', "library-entries/{$id}") + $request = $this->requestBuilder->newRequest('PATCH', "library-entries/{$id}") ->setJsonBody($requestData); if ($authHeader !== NULL) diff --git a/src/AnimeClient/API/Kitsu/Model.php b/src/AnimeClient/API/Kitsu/Model.php index 9dfa1220..a37c9511 100644 --- a/src/AnimeClient/API/Kitsu/Model.php +++ b/src/AnimeClient/API/Kitsu/Model.php @@ -81,7 +81,7 @@ final class Model { public function authenticate(string $username, string $password) { // K::AUTH_URL - $response = $this->jsonApiRequestBuilder->getResponse('POST', K::AUTH_URL, [ + $response = $this->requestBuilder->getResponse('POST', K::AUTH_URL, [ 'headers' => [ 'accept' => NULL, 'Content-type' => 'application/x-www-form-urlencoded', @@ -120,7 +120,7 @@ final class Model { */ public function reAuthenticate(string $token) { - $response = $this->jsonApiRequestBuilder->getResponse('POST', K::AUTH_URL, [ + $response = $this->requestBuilder->getResponse('POST', K::AUTH_URL, [ 'headers' => [ 'accept' => NULL, 'Content-type' => 'application/x-www-form-urlencoded', @@ -164,7 +164,7 @@ final class Model { } return $this->getCached(K::AUTH_USER_ID_KEY, function(string $username) { - $data = $this->jsonApiRequestBuilder->getRequest('users', [ + $data = $this->requestBuilder->getRequest('users', [ 'query' => [ 'filter' => [ 'name' => $username @@ -184,7 +184,7 @@ final class Model { */ public function getCharacter(string $slug): array { - return $this->jsonApiRequestBuilder->getRequest('characters', [ + return $this->requestBuilder->getRequest('characters', [ 'query' => [ 'filter' => [ 'slug' => $slug, @@ -207,7 +207,7 @@ final class Model { */ public function getPerson(string $id): array { - return $this->getCached("kitsu-person-{$id}", fn () => $this->jsonApiRequestBuilder->getRequest("people/{$id}", [ + return $this->getCached("kitsu-person-{$id}", fn () => $this->requestBuilder->getRequest("people/{$id}", [ 'query' => [ 'filter' => [ 'id' => $id, @@ -233,7 +233,7 @@ final class Model { */ public function getUserData(string $username): array { - return $this->jsonApiRequestBuilder->getRequest('users', [ + return $this->requestBuilder->getRequest('users', [ 'query' => [ 'filter' => [ 'name' => $username, @@ -270,7 +270,7 @@ final class Model { ] ]; - $raw = $this->jsonApiRequestBuilder->getRequest($type, $options); + $raw = $this->requestBuilder->getRequest($type, $options); $raw['included'] = JsonAPI::organizeIncluded($raw['included']); foreach ($raw['data'] as &$item) @@ -315,7 +315,7 @@ final class Model { ] ]; - $raw = $this->jsonApiRequestBuilder->getRequest('mappings', $options); + $raw = $this->requestBuilder->getRequest('mappings', $options); if ( ! array_key_exists('included', $raw)) { @@ -422,7 +422,7 @@ final class Model { */ protected function getRawHistoryPage(string $type, int $offset, int $limit = 20): Request { - return $this->jsonApiRequestBuilder->setUpRequest('GET', 'library-events', [ + return $this->requestBuilder->setUpRequest('GET', 'library-events', [ 'query' => [ 'filter' => [ 'kind' => 'progressed,updated', @@ -484,7 +484,7 @@ final class Model { ] ]; - $data = $this->jsonApiRequestBuilder->getRequest("{$type}/{$id}", $options); + $data = $this->requestBuilder->getRequest("{$type}/{$id}", $options); if (empty($data['data'])) { @@ -524,7 +524,7 @@ final class Model { ] ]; - $data = $this->jsonApiRequestBuilder->getRequest($type, $options); + $data = $this->requestBuilder->getRequest($type, $options); if (empty($data['data'])) { @@ -557,7 +557,7 @@ final class Model { $options['query']['filter']['status'] = $status; } - $response = $this->jsonApiRequestBuilder->getRequest('library-entries', $options); + $response = $this->requestBuilder->getRequest('library-entries', $options); return $response['meta']['count']; } @@ -623,6 +623,6 @@ final class Model { ]; $options = array_merge($defaultOptions, $options); - return $this->jsonApiRequestBuilder->setUpRequest('GET', 'library-entries', ['query' => $options]); + return $this->requestBuilder->setUpRequest('GET', 'library-entries', ['query' => $options]); } } \ No newline at end of file diff --git a/src/AnimeClient/Command/BaseCommand.php b/src/AnimeClient/Command/BaseCommand.php index e05b8f25..7f03656d 100644 --- a/src/AnimeClient/Command/BaseCommand.php +++ b/src/AnimeClient/Command/BaseCommand.php @@ -23,7 +23,7 @@ use Aura\Router\RouterContainer; use Aura\Session\SessionFactory; use Aviat\AnimeClient\{Model, UrlGenerator, Util}; use Aviat\AnimeClient\API\{Anilist, CacheTrait, Kitsu}; -use Aviat\AnimeClient\API\Kitsu\KitsuJsonApiRequestBuilder; +use Aviat\AnimeClient\API\Kitsu\KitsuRequestBuilder; use Aviat\Banker\Teller; use Aviat\Ion\Config; use Aviat\Ion\Di\{Container, ContainerInterface, ContainerAware}; @@ -187,20 +187,16 @@ abstract class BaseCommand extends Command { // Models $container->set('kitsu-model', static function($container): Kitsu\Model { - $jsonApiRequestBuilder = new KitsuJsonApiRequestBuilder($container); - $jsonApiRequestBuilder->setLogger($container->getLogger('kitsu-request')); - - $requestBuilder = new Kitsu\KitsuRequestBuilder($container); + $requestBuilder = new KitsuRequestBuilder($container); $requestBuilder->setLogger($container->getLogger('kitsu-request')); $listItem = new Kitsu\ListItem(); $listItem->setContainer($container); - $listItem->setJsonApiRequestBuilder($jsonApiRequestBuilder); + $listItem->setRequestBuilder($requestBuilder); $model = new Kitsu\Model($listItem); $model->setContainer($container); - $model->setJsonApiRequestBuilder($jsonApiRequestBuilder) - ->setRequestBuilder($requestBuilder); + $model->setRequestBuilder($requestBuilder); $cache = $container->get('cache'); $model->setCache($cache); diff --git a/src/AnimeClient/Controller.php b/src/AnimeClient/Controller.php index e012875d..9ece0a4c 100644 --- a/src/AnimeClient/Controller.php +++ b/src/AnimeClient/Controller.php @@ -23,7 +23,6 @@ use Aura\Router\Generator; use Aura\Session\Segment; use Aviat\AnimeClient\API\Kitsu\Auth; use Aviat\Ion\ConfigInterface; -use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\SimpleCache\CacheInterface; @@ -176,8 +175,6 @@ class Controller { * If one is not set, redirect to default url * * @throws InvalidArgumentException - * @throws ContainerException - * @throws NotFoundException * @return void */ public function sessionRedirect(): void diff --git a/src/AnimeClient/Controller/Manga.php b/src/AnimeClient/Controller/Manga.php index 49ce7d53..1783e394 100644 --- a/src/AnimeClient/Controller/Manga.php +++ b/src/AnimeClient/Controller/Manga.php @@ -264,10 +264,10 @@ final class Manga extends Controller { $data = $this->request->getParsedBody(); } - $response = $this->model->incrementLibraryItem(FormItem::from($data)); + [$body, $statusCode] = $this->model->incrementLibraryItem(FormItem::from($data)); $this->cache->clear(); - $this->outputJSON($response['body'], $response['statusCode']); + $this->outputJSON($body, $statusCode); } /** diff --git a/src/AnimeClient/Model/Manga.php b/src/AnimeClient/Model/Manga.php index 4cec1073..b6947184 100644 --- a/src/AnimeClient/Model/Manga.php +++ b/src/AnimeClient/Model/Manga.php @@ -199,13 +199,13 @@ class Manga extends API { } $results = $requester->makeRequests(); - $body = Json::decode($results['kitsu']); - $statusCode = array_key_exists('error', $body) ? 400 : 200; - return [ - 'body' => Json::decode($results['kitsu']), - 'statusCode' => $statusCode - ]; + $body = Json::decode($results['kitsu']); + $statusCode = array_key_exists('errors', $body) + ? $body['errors'][0]['status'] + : 200; + + return [$body, $statusCode]; } /**