Update History to use GraphQL, resolves #29,#30
All checks were successful
timw4mail/HummingBirdAnimeClient/pipeline/head This commit looks good
All checks were successful
timw4mail/HummingBirdAnimeClient/pipeline/head This commit looks good
This commit is contained in:
parent
ba276cc86e
commit
3f8c0432d2
@ -102,10 +102,7 @@ trait AnimeTrait {
|
|||||||
{
|
{
|
||||||
$raw = $this->getRawHistoryList('anime');
|
$raw = $this->getRawHistoryList('anime');
|
||||||
|
|
||||||
$organized = JsonAPI::organizeData($raw);
|
$list = (new AnimeHistoryTransformer())->transform($raw);
|
||||||
$organized = array_filter($organized, fn ($item) => array_key_exists('relationships', $item));
|
|
||||||
|
|
||||||
$list = (new AnimeHistoryTransformer())->transform($organized);
|
|
||||||
|
|
||||||
$this->cache->set($key, $list);
|
$this->cache->set($key, $list);
|
||||||
|
|
||||||
|
@ -97,10 +97,7 @@ trait MangaTrait {
|
|||||||
if ($list === NULL)
|
if ($list === NULL)
|
||||||
{
|
{
|
||||||
$raw = $this->getRawHistoryList('manga');
|
$raw = $this->getRawHistoryList('manga');
|
||||||
$organized = JsonAPI::organizeData($raw);
|
$list = (new MangaHistoryTransformer())->transform($raw);
|
||||||
$organized = array_filter($organized, fn ($item) => array_key_exists('relationships', $item));
|
|
||||||
|
|
||||||
$list = (new MangaHistoryTransformer())->transform($organized);
|
|
||||||
|
|
||||||
$this->cache->set($key, $list);
|
$this->cache->set($key, $list);
|
||||||
}
|
}
|
||||||
|
@ -355,67 +355,12 @@ final class Model {
|
|||||||
/**
|
/**
|
||||||
* Get the aggregated pages of anime or manga history
|
* Get the aggregated pages of anime or manga history
|
||||||
*
|
*
|
||||||
* @param string $type
|
|
||||||
* @param int $entries
|
|
||||||
* @return array
|
* @return array
|
||||||
* @throws InvalidArgumentException
|
|
||||||
* @throws Throwable
|
|
||||||
*/
|
*/
|
||||||
protected function getRawHistoryList(string $type = 'anime', int $entries = 120): array
|
protected function getRawHistoryList(): array
|
||||||
{
|
{
|
||||||
$size = 20;
|
return $this->requestBuilder->runQuery('GetUserHistory', [
|
||||||
$pages = ceil($entries / $size);
|
'slug' => $this->getUsername(),
|
||||||
|
|
||||||
$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',
|
|
||||||
],
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
35
src/AnimeClient/API/Kitsu/Queries/GetUserHistory.graphql
Normal file
35
src/AnimeClient/API/Kitsu/Queries/GetUserHistory.graphql
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -60,18 +60,25 @@ abstract class HistoryTransformer {
|
|||||||
*/
|
*/
|
||||||
public function transform(array $data): array
|
public function transform(array $data): array
|
||||||
{
|
{
|
||||||
|
$base = $data['data']['findProfileBySlug']['libraryEvents']['nodes'] ?? [];
|
||||||
$output = [];
|
$output = [];
|
||||||
|
|
||||||
foreach ($data as $entry)
|
foreach ($base as $entry)
|
||||||
{
|
{
|
||||||
if ( ! isset($entry['relationships'][$this->type]))
|
if ( ! (strtolower($entry['media']['__typename']) === $this->type))
|
||||||
{
|
{
|
||||||
continue;
|
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);
|
$transformed = $this->transformProgress($entry);
|
||||||
if ($transformed !== NULL)
|
if ($transformed !== NULL)
|
||||||
@ -130,7 +137,7 @@ abstract class HistoryTransformer {
|
|||||||
|
|
||||||
foreach ($entries as $e)
|
foreach ($entries as $e)
|
||||||
{
|
{
|
||||||
$progressItem = $e['original']['attributes']['changedData']['progress'];
|
$progressItem = $e['original']['changedData']['progress'];
|
||||||
$items[] = array_pop($progressItem);
|
$items[] = array_pop($progressItem);
|
||||||
$updated[] = $e['updated'];
|
$updated[] = $e['updated'];
|
||||||
}
|
}
|
||||||
@ -176,11 +183,11 @@ abstract class HistoryTransformer {
|
|||||||
|
|
||||||
protected function transformProgress (array $entry): ?HistoryItem
|
protected function transformProgress (array $entry): ?HistoryItem
|
||||||
{
|
{
|
||||||
$id = array_keys($entry['relationships'][$this->type])[0];
|
$id = $entry['media']['id'];
|
||||||
$data = $entry['relationships'][$this->type][$id]['attributes'];
|
$data = $entry['media'];
|
||||||
$title = $this->linkTitle($data);
|
$title = $this->linkTitle($data);
|
||||||
$imgUrl = "images/{$this->type}/{$id}.webp";
|
$imgUrl = "images/{$this->type}/{$id}.webp";
|
||||||
$item = end($entry['attributes']['changedData']['progress']);
|
$item = end($entry['changedData']['progress']);
|
||||||
|
|
||||||
// No showing episode 0 nonsense
|
// No showing episode 0 nonsense
|
||||||
if (((int)$item) === 0)
|
if (((int)$item) === 0)
|
||||||
@ -198,23 +205,23 @@ abstract class HistoryTransformer {
|
|||||||
'kind' => 'progressed',
|
'kind' => 'progressed',
|
||||||
'original' => $entry,
|
'original' => $entry,
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'updated' => $this->parseDate($entry['attributes']['updatedAt']),
|
'updated' => $this->parseDate($entry['updatedAt']),
|
||||||
'url' => $this->getUrl($data),
|
'url' => $this->getUrl($data),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function transformUpdated($entry): HistoryItem
|
protected function transformUpdated($entry): HistoryItem
|
||||||
{
|
{
|
||||||
$id = array_keys($entry['relationships'][$this->type])[0];
|
$id = $entry['media']['id'];
|
||||||
$data = $entry['relationships'][$this->type][$id]['attributes'];
|
$data = $entry['media'];
|
||||||
$title = $this->linkTitle($data);
|
$title = $this->linkTitle($data);
|
||||||
$imgUrl = "images/{$this->type}/{$id}.webp";
|
$imgUrl = "images/{$this->type}/{$id}.webp";
|
||||||
|
|
||||||
$kind = array_key_first($entry['attributes']['changedData']);
|
$kind = array_key_first($entry['changedData']);
|
||||||
|
|
||||||
if ($kind === 'status')
|
if ($kind === 'status')
|
||||||
{
|
{
|
||||||
$status = array_pop($entry['attributes']['changedData']['status']);
|
$status = array_pop($entry['changedData']['status']);
|
||||||
$statusName = $this->statusMap[$status];
|
$statusName = $this->statusMap[$status];
|
||||||
|
|
||||||
if ($this->isReconsuming($entry))
|
if ($this->isReconsuming($entry))
|
||||||
@ -230,7 +237,7 @@ abstract class HistoryTransformer {
|
|||||||
'kind' => 'updated',
|
'kind' => 'updated',
|
||||||
'original' => $entry,
|
'original' => $entry,
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'updated' => $this->parseDate($entry['attributes']['updatedAt']),
|
'updated' => $this->parseDate($entry['updatedAt']),
|
||||||
'url' => $this->getUrl($data),
|
'url' => $this->getUrl($data),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -240,13 +247,13 @@ abstract class HistoryTransformer {
|
|||||||
|
|
||||||
protected function linkTitle (array $data): string
|
protected function linkTitle (array $data): string
|
||||||
{
|
{
|
||||||
return $data['canonicalTitle'];
|
return $data['titles']['canonical'];
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function parseDate (string $date): DateTimeImmutable
|
protected function parseDate (string $date): DateTimeImmutable
|
||||||
{
|
{
|
||||||
$dateTime = DateTimeImmutable::createFromFormat(
|
$dateTime = DateTimeImmutable::createFromFormat(
|
||||||
DateTimeInterface::RFC3339_EXTENDED,
|
DateTimeInterface::RFC3339,
|
||||||
$date
|
$date
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -260,20 +267,6 @@ abstract class HistoryTransformer {
|
|||||||
|
|
||||||
protected function isReconsuming ($entry): bool
|
protected function isReconsuming ($entry): bool
|
||||||
{
|
{
|
||||||
$le = $this->getLibraryEntry($entry);
|
return $entry['libraryEntry']['reconsuming'];
|
||||||
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'];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user