From e890f978dbd2c7c6d2134e6f87af11b9e82d6606 Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Mon, 24 Aug 2020 19:17:41 -0400 Subject: [PATCH] Update History to use GraphQL, resolves #29,#30 --- src/AnimeClient/API/Kitsu/AnimeTrait.php | 5 +- src/AnimeClient/API/Kitsu/MangaTrait.php | 5 +- src/AnimeClient/API/Kitsu/Model.php | 61 +------------------ .../API/Kitsu/Queries/GetUserHistory.graphql | 35 +++++++++++ .../Kitsu/Transformer/HistoryTransformer.php | 55 ++++++++--------- 5 files changed, 64 insertions(+), 97 deletions(-) create mode 100644 src/AnimeClient/API/Kitsu/Queries/GetUserHistory.graphql diff --git a/src/AnimeClient/API/Kitsu/AnimeTrait.php b/src/AnimeClient/API/Kitsu/AnimeTrait.php index 22ee319b..c5d26512 100644 --- a/src/AnimeClient/API/Kitsu/AnimeTrait.php +++ b/src/AnimeClient/API/Kitsu/AnimeTrait.php @@ -102,10 +102,7 @@ trait AnimeTrait { { $raw = $this->getRawHistoryList('anime'); - $organized = JsonAPI::organizeData($raw); - $organized = array_filter($organized, fn ($item) => array_key_exists('relationships', $item)); - - $list = (new AnimeHistoryTransformer())->transform($organized); + $list = (new AnimeHistoryTransformer())->transform($raw); $this->cache->set($key, $list); diff --git a/src/AnimeClient/API/Kitsu/MangaTrait.php b/src/AnimeClient/API/Kitsu/MangaTrait.php index cd3a938b..6f11ec09 100644 --- a/src/AnimeClient/API/Kitsu/MangaTrait.php +++ b/src/AnimeClient/API/Kitsu/MangaTrait.php @@ -97,10 +97,7 @@ trait MangaTrait { if ($list === NULL) { $raw = $this->getRawHistoryList('manga'); - $organized = JsonAPI::organizeData($raw); - $organized = array_filter($organized, fn ($item) => array_key_exists('relationships', $item)); - - $list = (new MangaHistoryTransformer())->transform($organized); + $list = (new MangaHistoryTransformer())->transform($raw); $this->cache->set($key, $list); } diff --git a/src/AnimeClient/API/Kitsu/Model.php b/src/AnimeClient/API/Kitsu/Model.php index ff210c41..b894bf0a 100644 --- a/src/AnimeClient/API/Kitsu/Model.php +++ b/src/AnimeClient/API/Kitsu/Model.php @@ -355,67 +355,12 @@ final class Model { /** * Get the aggregated pages of anime or manga history * - * @param string $type - * @param int $entries * @return array - * @throws InvalidArgumentException - * @throws Throwable */ - protected function getRawHistoryList(string $type = 'anime', int $entries = 120): array + protected function getRawHistoryList(): array { - $size = 20; - $pages = ceil($entries / $size); - - $requester = new ParallelAPIRequest(); - - // Set up requests - for ($i = 0; $i < $pages; $i++) - { - $offset = $i * $size; - $requester->addRequest($this->getRawHistoryPage($type, $offset, $size)); - } - - $responses = $requester->makeRequests(); - $output = []; - - foreach($responses as $response) - { - $data = Json::decode($response); - $output[] = $data; - } - - return array_merge_recursive(...$output); - } - - /** - * Retrieve one page of the anime or manga history - * - * @param string $type - * @param int $offset - * @param int $limit - * @return Request - * @throws InvalidArgumentException - */ - protected function getRawHistoryPage(string $type, int $offset, int $limit = 20): Request - { - return $this->requestBuilder->setUpRequest('GET', 'library-events', [ - 'query' => [ - 'filter' => [ - 'kind' => 'progressed,updated', - 'userId' => $this->getUserId(), - ], - 'page' => [ - 'offset' => $offset, - 'limit' => $limit, - ], - 'fields' => [ - 'anime' => 'canonicalTitle,titles,slug,posterImage', - 'manga' => 'canonicalTitle,titles,slug,posterImage', - 'libraryEntry' => 'reconsuming,reconsumeCount', - ], - 'sort' => '-updated_at', - 'include' => 'anime,manga,libraryEntry', - ], + return $this->requestBuilder->runQuery('GetUserHistory', [ + 'slug' => $this->getUsername(), ]); } diff --git a/src/AnimeClient/API/Kitsu/Queries/GetUserHistory.graphql b/src/AnimeClient/API/Kitsu/Queries/GetUserHistory.graphql new file mode 100644 index 00000000..66530029 --- /dev/null +++ b/src/AnimeClient/API/Kitsu/Queries/GetUserHistory.graphql @@ -0,0 +1,35 @@ +query ($slug: String!) { + findProfileBySlug(slug: $slug) { + libraryEvents { + nodes { + id + changedData + kind + libraryEntry { + reconsumeCount + reconsuming + private + notes + } + media { + __typename + id + slug + posterImage { + views { + width + height + url + } + } + titles { + alternatives + canonical + localized + } + } + updatedAt + } + } + } +} \ No newline at end of file diff --git a/src/AnimeClient/API/Kitsu/Transformer/HistoryTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/HistoryTransformer.php index 74810a22..1bad7db2 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/HistoryTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/HistoryTransformer.php @@ -60,18 +60,25 @@ abstract class HistoryTransformer { */ public function transform(array $data): array { + $base = $data['data']['findProfileBySlug']['libraryEvents']['nodes'] ?? []; $output = []; - foreach ($data as $entry) + foreach ($base as $entry) { - if ( ! isset($entry['relationships'][$this->type])) + if ( ! (strtolower($entry['media']['__typename']) === $this->type)) { continue; } - $kind = $entry['attributes']['kind']; + // Hide private library entries + if ($entry['libraryEntry']['private'] === true) + { + continue; + } - if ($kind === 'progressed' && ! empty($entry['attributes']['changedData']['progress'])) + $kind = strtolower($entry['kind']); + + if ($kind === 'progressed' && ! empty($entry['changedData']['progress'])) { $transformed = $this->transformProgress($entry); if ($transformed !== NULL) @@ -130,7 +137,7 @@ abstract class HistoryTransformer { foreach ($entries as $e) { - $progressItem = $e['original']['attributes']['changedData']['progress']; + $progressItem = $e['original']['changedData']['progress']; $items[] = array_pop($progressItem); $updated[] = $e['updated']; } @@ -176,11 +183,11 @@ abstract class HistoryTransformer { protected function transformProgress (array $entry): ?HistoryItem { - $id = array_keys($entry['relationships'][$this->type])[0]; - $data = $entry['relationships'][$this->type][$id]['attributes']; + $id = $entry['media']['id']; + $data = $entry['media']; $title = $this->linkTitle($data); $imgUrl = "images/{$this->type}/{$id}.webp"; - $item = end($entry['attributes']['changedData']['progress']); + $item = end($entry['changedData']['progress']); // No showing episode 0 nonsense if (((int)$item) === 0) @@ -198,23 +205,23 @@ abstract class HistoryTransformer { 'kind' => 'progressed', 'original' => $entry, 'title' => $title, - 'updated' => $this->parseDate($entry['attributes']['updatedAt']), + 'updated' => $this->parseDate($entry['updatedAt']), 'url' => $this->getUrl($data), ]); } protected function transformUpdated($entry): HistoryItem { - $id = array_keys($entry['relationships'][$this->type])[0]; - $data = $entry['relationships'][$this->type][$id]['attributes']; + $id = $entry['media']['id']; + $data = $entry['media']; $title = $this->linkTitle($data); $imgUrl = "images/{$this->type}/{$id}.webp"; - $kind = array_key_first($entry['attributes']['changedData']); + $kind = array_key_first($entry['changedData']); if ($kind === 'status') { - $status = array_pop($entry['attributes']['changedData']['status']); + $status = array_pop($entry['changedData']['status']); $statusName = $this->statusMap[$status]; if ($this->isReconsuming($entry)) @@ -230,7 +237,7 @@ abstract class HistoryTransformer { 'kind' => 'updated', 'original' => $entry, 'title' => $title, - 'updated' => $this->parseDate($entry['attributes']['updatedAt']), + 'updated' => $this->parseDate($entry['updatedAt']), 'url' => $this->getUrl($data), ]); } @@ -240,13 +247,13 @@ abstract class HistoryTransformer { protected function linkTitle (array $data): string { - return $data['canonicalTitle']; + return $data['titles']['canonical']; } protected function parseDate (string $date): DateTimeImmutable { $dateTime = DateTimeImmutable::createFromFormat( - DateTimeInterface::RFC3339_EXTENDED, + DateTimeInterface::RFC3339, $date ); @@ -260,20 +267,6 @@ abstract class HistoryTransformer { protected function isReconsuming ($entry): bool { - $le = $this->getLibraryEntry($entry); - return $le['reconsuming']; - } - - private function getLibraryEntry ($entry): ?array - { - if ( ! isset($entry['relationships']['libraryEntry']['libraryEntries'])) - { - return NULL; - } - - $libraryEntries = $entry['relationships']['libraryEntry']['libraryEntries']; - $id = array_keys($libraryEntries)[0]; - - return $libraryEntries[$id]['attributes']; + return $entry['libraryEntry']['reconsuming']; } } \ No newline at end of file