From 70a33e36c03745948a87c8970e83b0fdc7fcad8a Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 16 Oct 2020 13:28:35 -0400 Subject: [PATCH] Fetch Manga List via GraphQL, see #33 --- src/AnimeClient/API/Kitsu/AnimeTrait.php | 47 ------------------- src/AnimeClient/API/Kitsu/MangaTrait.php | 38 ++++----------- .../API/Kitsu/Queries/GetLibrary.graphql | 1 + .../Transformer/MangaListTransformer.php | 44 ++++++++--------- 4 files changed, 30 insertions(+), 100 deletions(-) diff --git a/src/AnimeClient/API/Kitsu/AnimeTrait.php b/src/AnimeClient/API/Kitsu/AnimeTrait.php index 2c6a20cf..fab16c70 100644 --- a/src/AnimeClient/API/Kitsu/AnimeTrait.php +++ b/src/AnimeClient/API/Kitsu/AnimeTrait.php @@ -20,7 +20,6 @@ use Amp\Http\Client\Request; use Aviat\AnimeClient\API\Kitsu\Transformer\AnimeListTransformer; use Aviat\AnimeClient\Kitsu as K; use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\Kitsu as KitsuWatchingStatus; -use Aviat\AnimeClient\API\JsonAPI; use Aviat\AnimeClient\API\Kitsu\Transformer\AnimeHistoryTransformer; use Aviat\AnimeClient\API\Kitsu\Transformer\OldAnimeListTransformer; use Aviat\AnimeClient\API\Kitsu\Transformer\AnimeTransformer; @@ -151,52 +150,6 @@ trait AnimeTrait { return $list; } - /** - * Get the anime list for the configured user - * - * @param string $status - The watching status to filter the list with - * @return array - * @throws InvalidArgumentException - */ - public function oldGetAnimeList(string $status): array - { - $key = "kitsu-anime-list-{$status}"; - - $list = $this->cache->get($key, NULL); - - if ($list === NULL) - { - $data = $this->getRawAnimeList($status) ?? []; - - // Bail out on no data - if (empty($data)) - { - return []; - } - - $included = JsonAPI::organizeIncludes($data['included']); - $included = JsonAPI::inlineIncludedRelationships($included, 'anime'); - - foreach($data['data'] as $i => &$item) - { - $item['included'] = $included; - } - unset($item); - $transformed = $this->oldListTransformer->transformCollection($data['data']); - $keyed = []; - - foreach($transformed as $item) - { - $keyed[$item['id']] = $item; - } - - $list = $keyed; - $this->cache->set($key, $list); - } - - return $list; - } - /** * Get the number of anime list items * diff --git a/src/AnimeClient/API/Kitsu/MangaTrait.php b/src/AnimeClient/API/Kitsu/MangaTrait.php index 45d50fac..94168d0d 100644 --- a/src/AnimeClient/API/Kitsu/MangaTrait.php +++ b/src/AnimeClient/API/Kitsu/MangaTrait.php @@ -21,6 +21,7 @@ use Aviat\AnimeClient\Kitsu as K; use Aviat\AnimeClient\API\Enum\MangaReadingStatus\Kitsu as KitsuReadingStatus; use Aviat\AnimeClient\API\JsonAPI; use Aviat\AnimeClient\API\Kitsu\Transformer\MangaHistoryTransformer; +use Aviat\AnimeClient\API\Kitsu\Transformer\MangaListTransformer; use Aviat\AnimeClient\API\Kitsu\Transformer\OldMangaListTransformer; use Aviat\AnimeClient\API\Kitsu\Transformer\MangaTransformer; use Aviat\AnimeClient\API\Mapping\MangaReadingStatus; @@ -109,54 +110,35 @@ trait MangaTrait { * Get the manga list for the configured user * * @param string $status - The reading status by which to filter the list - * @param int $limit - The number of list items to fetch per page - * @param int $offset - The page offset * @return array * @throws InvalidArgumentException */ - public function getMangaList(string $status, int $limit = 200, int $offset = 0): array + public function getMangaList(string $status): array { - $options = [ - 'query' => [ - 'filter' => [ - 'user_id' => $this->getUserId(), - 'kind' => 'manga', - 'status' => $status, - ], - 'include' => 'media,media.categories,media.mappings', - 'page' => [ - 'offset' => $offset, - 'limit' => $limit - ], - 'sort' => '-updated_at' - ] - ]; - $key = "kitsu-manga-list-{$status}"; $list = $this->cache->get($key, NULL); if ($list === NULL) { - $data = $this->requestBuilder->getRequest('library-entries', $options) ?? []; + $data = $this->getRawList(ListType::MANGA, $status) ?? []; // Bail out on no data - if (empty($data) || ( ! array_key_exists('included', $data))) + if (empty($data)) { return []; } - $included = JsonAPI::organizeIncludes($data['included']); - $included = JsonAPI::inlineIncludedRelationships($included, 'manga'); + $transformer = new MangaListTransformer(); + $transformed = $transformer->transformCollection($data); + $keyed = []; - foreach($data['data'] as $i => &$item) + foreach($transformed as $item) { - $item['included'] = $included; + $keyed[$item['id']] = $item; } - unset($item); - - $list = $this->mangaListTransformer->transformCollection($data['data']); + $list = $keyed; $this->cache->set($key, $list); } diff --git a/src/AnimeClient/API/Kitsu/Queries/GetLibrary.graphql b/src/AnimeClient/API/Kitsu/Queries/GetLibrary.graphql index e28e44a5..f2dd3bdd 100644 --- a/src/AnimeClient/API/Kitsu/Queries/GetLibrary.graphql +++ b/src/AnimeClient/API/Kitsu/Queries/GetLibrary.graphql @@ -79,6 +79,7 @@ query ( } ...on Manga { chapterCount + volumeCount subtype } } diff --git a/src/AnimeClient/API/Kitsu/Transformer/MangaListTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/MangaListTransformer.php index 435faf34..81a9d930 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/MangaListTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/MangaListTransformer.php @@ -36,21 +36,14 @@ final class MangaListTransformer extends AbstractTransformer { */ public function transform($item): MangaListItem { - $included = $item['included']; - $mangaId = $item['relationships']['media']['data']['id']; - $manga = $included['manga'][$mangaId]; + $mangaId = $item['media']['id']; + $manga = $item['media']; $genres = []; - foreach ($manga['relationships']['categories'] as $genre) - { - $genres[] = $genre['title']; - } - - sort($genres); - - $rating = (int) $item['attributes']['ratingTwenty'] !== 0 - ? $item['attributes']['ratingTwenty'] / 2 + // Rating is 1-20, we want 1-10 + $rating = (int) $item['rating'] !== 0 + ? $item['rating'] / 2 : '-'; $totalChapters = ((int) $manga['chapterCount'] !== 0) @@ -61,17 +54,18 @@ final class MangaListTransformer extends AbstractTransformer { ? $manga['volumeCount'] : '-'; - $readChapters = ((int) $item['attributes']['progress'] !== 0) - ? $item['attributes']['progress'] + $readChapters = ((int) $item['progress'] !== 0) + ? $item['progress'] : '-'; $MALid = NULL; - if (array_key_exists('mappings', $manga['relationships'])) + $mappings = $manga['mappings']['nodes'] ?? []; + if ( ! empty($mappings)) { - foreach ($manga['relationships']['mappings'] as $mapping) + foreach ($mappings as $mapping) { - if ($mapping['externalSite'] === 'myanimelist/manga') + if ($mapping['externalSite'] === 'MYANIMELIST_MANGA') { $MALid = $mapping['externalId']; break; @@ -79,8 +73,8 @@ final class MangaListTransformer extends AbstractTransformer { } } - $titles = Kitsu::filterTitles($manga); - $title = array_shift($titles); + $titles = Kitsu::getFilteredTitles($manga['titles']); + $title = $manga['titles']['canonical']; return MangaListItem::from([ 'id' => $item['id'], @@ -96,17 +90,17 @@ final class MangaListTransformer extends AbstractTransformer { 'manga' => MangaListItemDetail::from([ 'genres' => $genres, 'id' => $mangaId, - 'image' => $manga['posterImage']['small'], + 'image' => $manga['posterImage']['views'][1]['url'], 'slug' => $manga['slug'], 'title' => $title, 'titles' => $titles, - 'type' => (string)StringType::from($manga['subtype'])->upperCaseFirst(), + 'type' => (string)StringType::from($manga['subtype'])->toLowerCase()->upperCaseFirst(), 'url' => 'https://kitsu.io/manga/' . $manga['slug'], ]), - 'reading_status' => $item['attributes']['status'], - 'notes' => $item['attributes']['notes'], - 'rereading' => (bool)$item['attributes']['reconsuming'], - 'reread' => $item['attributes']['reconsumeCount'], + 'reading_status' => strtolower($item['status']), + 'notes' => $item['notes'], + 'rereading' => (bool)$item['reconsuming'], + 'reread' => $item['reconsumeCount'], 'user_rating' => $rating, ]); }