Vastly simplify logic for getting a user's anime library. Most basic API functionality seems to be working
This commit is contained in:
parent
1ad4427584
commit
0e684736bd
@ -18,9 +18,9 @@ use const Aviat\AnimeClient\{
|
|||||||
ALPHA_SLUG_PATTERN,
|
ALPHA_SLUG_PATTERN,
|
||||||
DEFAULT_CONTROLLER,
|
DEFAULT_CONTROLLER,
|
||||||
DEFAULT_CONTROLLER_METHOD,
|
DEFAULT_CONTROLLER_METHOD,
|
||||||
|
KITSU_SLUG_PATTERN,
|
||||||
NUM_PATTERN,
|
NUM_PATTERN,
|
||||||
SLUG_PATTERN,
|
SLUG_PATTERN,
|
||||||
SLUG_SPACE_PATTERN,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
@ -28,7 +28,7 @@ use const Aviat\AnimeClient\{
|
|||||||
//
|
//
|
||||||
// Maps paths to controllers and methods
|
// Maps paths to controllers and methods
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
$routes = [
|
$base_routes = [
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
// AJAX Routes
|
// AJAX Routes
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
@ -60,7 +60,7 @@ $routes = [
|
|||||||
'path' => '/anime/details/{id}',
|
'path' => '/anime/details/{id}',
|
||||||
'action' => 'details',
|
'action' => 'details',
|
||||||
'tokens' => [
|
'tokens' => [
|
||||||
'id' => SLUG_PATTERN,
|
'id' => KITSU_SLUG_PATTERN,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'anime.delete' => [
|
'anime.delete' => [
|
||||||
@ -97,7 +97,7 @@ $routes = [
|
|||||||
'path' => '/manga/details/{id}',
|
'path' => '/manga/details/{id}',
|
||||||
'action' => 'details',
|
'action' => 'details',
|
||||||
'tokens' => [
|
'tokens' => [
|
||||||
'id' => SLUG_PATTERN,
|
'id' => KITSU_SLUG_PATTERN,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
@ -191,13 +191,13 @@ $routes = [
|
|||||||
'character' => [
|
'character' => [
|
||||||
'path' => '/character/{slug}',
|
'path' => '/character/{slug}',
|
||||||
'tokens' => [
|
'tokens' => [
|
||||||
'slug' => SLUG_PATTERN,
|
'slug' => KITSU_SLUG_PATTERN,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'person' => [
|
'person' => [
|
||||||
'path' => '/people/{slug}',
|
'path' => '/people/{slug}',
|
||||||
'tokens' => [
|
'tokens' => [
|
||||||
'slug' => SLUG_PATTERN,
|
'slug' => KITSU_SLUG_PATTERN,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'default_user_info' => [
|
'default_user_info' => [
|
||||||
@ -291,8 +291,8 @@ $routes = [
|
|||||||
'path' => '/{controller}/edit/{id}/{status}',
|
'path' => '/{controller}/edit/{id}/{status}',
|
||||||
'action' => 'edit',
|
'action' => 'edit',
|
||||||
'tokens' => [
|
'tokens' => [
|
||||||
'id' => SLUG_PATTERN,
|
'id' => KITSU_SLUG_PATTERN,
|
||||||
'status' => SLUG_SPACE_PATTERN,
|
'status' => SLUG_PATTERN,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'list' => [
|
'list' => [
|
||||||
@ -315,15 +315,10 @@ $defaultMap = [
|
|||||||
'verb' => 'get',
|
'verb' => 'get',
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($routes as &$route)
|
$routes = [];
|
||||||
|
foreach ($base_routes as $name => $route)
|
||||||
{
|
{
|
||||||
foreach ($defaultMap as $key => $val)
|
$routes[$name] = array_merge($defaultMap, $route);
|
||||||
{
|
|
||||||
if ( ! array_key_exists($key, $route))
|
|
||||||
{
|
|
||||||
$route[$key] = $val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $routes;
|
return $routes;
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
"require": {
|
"require": {
|
||||||
"amphp/http-client": "^v5.0.0",
|
"amphp/http-client": "^v5.0.0",
|
||||||
"aura/html": "^2.5.0",
|
"aura/html": "^2.5.0",
|
||||||
"aura/router": "3.2.0",
|
"aura/router": "^3.3.0",
|
||||||
"aura/session": "^2.1.0",
|
"aura/session": "^2.1.0",
|
||||||
"aviat/banker": "^4.1.2",
|
"aviat/banker": "^4.1.2",
|
||||||
"aviat/query": "^4.1.0",
|
"aviat/query": "^4.1.0",
|
||||||
|
@ -24,7 +24,6 @@ use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException};
|
|||||||
use Aviat\Ion\Json;
|
use Aviat\Ion\Json;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use function Amp\Promise\wait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Anilist API Model
|
* Anilist API Model
|
||||||
@ -67,7 +66,7 @@ final class Model
|
|||||||
|
|
||||||
$response = $this->requestBuilder->getResponseFromRequest($request);
|
$response = $this->requestBuilder->getResponseFromRequest($request);
|
||||||
|
|
||||||
return Json::decode(wait($response->getBody()->buffer()));
|
return Json::decode($response->getBody()->buffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,8 +22,6 @@ use Aviat\Ion\{Json, JsonException};
|
|||||||
use LogicException;
|
use LogicException;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
use function Amp\Promise\wait;
|
|
||||||
|
|
||||||
use function Aviat\AnimeClient\getResponse;
|
use function Aviat\AnimeClient\getResponse;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
use const Aviat\AnimeClient\USER_AGENT;
|
use const Aviat\AnimeClient\USER_AGENT;
|
||||||
@ -170,7 +168,7 @@ final class RequestBuilder extends APIRequestBuilder
|
|||||||
$request = $this->mutateRequest($name, $variables);
|
$request = $this->mutateRequest($name, $variables);
|
||||||
$response = $this->getResponseFromRequest($request);
|
$response = $this->getResponseFromRequest($request);
|
||||||
|
|
||||||
return Json::decode(wait($response->getBody()->buffer()));
|
return Json::decode($response->getBody()->buffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -246,7 +244,7 @@ final class RequestBuilder extends APIRequestBuilder
|
|||||||
$logger?->warning('Non 200 response for POST api call', (array) $response->getBody());
|
$logger?->warning('Non 200 response for POST api call', (array) $response->getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
$rawBody = wait($response->getBody()->buffer());
|
$rawBody = $response->getBody()->buffer();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
30
src/AnimeClient/API/Kitsu/Enum/MediaStatus.php
Normal file
30
src/AnimeClient/API/Kitsu/Enum/MediaStatus.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* Hummingbird Anime List Client
|
||||||
|
*
|
||||||
|
* An API client for Kitsu to manage anime and manga watch lists
|
||||||
|
*
|
||||||
|
* PHP version 8.1
|
||||||
|
*
|
||||||
|
* @copyright 2015 - 2023 Timothy J. Warren <tim@timshome.page>
|
||||||
|
* @license http://www.opensource.org/licenses/mit-license.html MIT License
|
||||||
|
* @version 5.2
|
||||||
|
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Aviat\AnimeClient\API\Kitsu\Enum;
|
||||||
|
|
||||||
|
use Aviat\Ion\Enum as BaseEnum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Status of when anime is being/was/will be aired
|
||||||
|
*/
|
||||||
|
final class MediaStatus extends BaseEnum
|
||||||
|
{
|
||||||
|
public const CURRENT = 'CURRENT';
|
||||||
|
public const PLANNED = 'PLANNED';
|
||||||
|
public const ON_HOLD = 'ON_HOLD';
|
||||||
|
public const DROPPED = 'DROPPED';
|
||||||
|
public const COMPLETED = 'COMPLETED';
|
||||||
|
}
|
||||||
|
// End of MediaStatus
|
@ -14,8 +14,6 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\API\Kitsu;
|
namespace Aviat\AnimeClient\API\Kitsu;
|
||||||
|
|
||||||
use Amp;
|
|
||||||
use Amp\Future;
|
|
||||||
use Aviat\AnimeClient\API\Kitsu\Transformer\{
|
use Aviat\AnimeClient\API\Kitsu\Transformer\{
|
||||||
AnimeHistoryTransformer,
|
AnimeHistoryTransformer,
|
||||||
AnimeListTransformer,
|
AnimeListTransformer,
|
||||||
@ -29,6 +27,7 @@ use Aviat\AnimeClient\API\{
|
|||||||
CacheTrait,
|
CacheTrait,
|
||||||
Enum\AnimeWatchingStatus\Kitsu as KitsuWatchingStatus,
|
Enum\AnimeWatchingStatus\Kitsu as KitsuWatchingStatus,
|
||||||
Enum\MangaReadingStatus\Kitsu as KitsuReadingStatus,
|
Enum\MangaReadingStatus\Kitsu as KitsuReadingStatus,
|
||||||
|
Kitsu\Enum\MediaStatus,
|
||||||
Mapping\AnimeWatchingStatus,
|
Mapping\AnimeWatchingStatus,
|
||||||
Mapping\MangaReadingStatus
|
Mapping\MangaReadingStatus
|
||||||
};
|
};
|
||||||
@ -553,27 +552,7 @@ final class Model
|
|||||||
*/
|
*/
|
||||||
public function getThumbList(string $type): array
|
public function getThumbList(string $type): array
|
||||||
{
|
{
|
||||||
$statuses = [
|
return $this->getZippedListPerStatus('GetLibraryThumbs', $type);
|
||||||
'CURRENT',
|
|
||||||
'PLANNED',
|
|
||||||
'ON_HOLD',
|
|
||||||
'DROPPED',
|
|
||||||
'COMPLETED',
|
|
||||||
];
|
|
||||||
|
|
||||||
$pages = [];
|
|
||||||
|
|
||||||
// Although I can fetch the whole list without segregating by status,
|
|
||||||
// this way is much faster...
|
|
||||||
foreach ($statuses as $status)
|
|
||||||
{
|
|
||||||
foreach ($this->getPages($this->getThumbListPages(...), strtoupper($type), $status) as $page)
|
|
||||||
{
|
|
||||||
$pages[] = $page;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_merge(...$pages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -583,27 +562,7 @@ final class Model
|
|||||||
*/
|
*/
|
||||||
public function getSyncList(string $type): array
|
public function getSyncList(string $type): array
|
||||||
{
|
{
|
||||||
$statuses = [
|
return $this->getZippedListPerStatus('GetSyncLibrary', $type);
|
||||||
'CURRENT',
|
|
||||||
'PLANNED',
|
|
||||||
'ON_HOLD',
|
|
||||||
'DROPPED',
|
|
||||||
'COMPLETED',
|
|
||||||
];
|
|
||||||
|
|
||||||
$pages = [];
|
|
||||||
|
|
||||||
// Although I can fetch the whole list without segregating by status,
|
|
||||||
// this way is much faster...
|
|
||||||
foreach ($statuses as $status)
|
|
||||||
{
|
|
||||||
foreach ($this->getPages($this->getSyncPages(...), strtoupper($type), $status) as $page)
|
|
||||||
{
|
|
||||||
$pages[] = $page;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_merge(...$pages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -619,15 +578,39 @@ final class Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the raw anime/manga list from GraphQL
|
* Get all the raw data for the current list, chunking by status
|
||||||
*
|
*
|
||||||
* @return mixed[]
|
* @param string $queryName - The GraphQL query
|
||||||
|
* @param string $type - Media type (anime, manga)
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function getList(string $type, string $status = ''): array
|
protected function getZippedListPerStatus(string $queryName, string $type): array
|
||||||
|
{
|
||||||
|
$statusPages = [];
|
||||||
|
|
||||||
|
// Although I can fetch the whole list without segregating by status,
|
||||||
|
// this way is much faster...
|
||||||
|
foreach (MediaStatus::getConstList() as $status)
|
||||||
|
{
|
||||||
|
$statusPages[] = $this->getZippedList($queryName, $type, $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_merge(...$statusPages);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all the raw data for the current list
|
||||||
|
*
|
||||||
|
* @param string $queryName - The GraphQL query
|
||||||
|
* @param string $type - Media type (anime, manga)
|
||||||
|
* @param string $status - Media 'consumption' status
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function getZippedList(string $queryName, string $type, string $status): array
|
||||||
{
|
{
|
||||||
$pages = [];
|
$pages = [];
|
||||||
|
|
||||||
foreach ($this->getPages($this->getListPages(...), strtoupper($type), strtoupper($status)) as $page)
|
foreach ($this->getListPages($queryName, $type, $status) as $page)
|
||||||
{
|
{
|
||||||
$pages[] = $page;
|
$pages[] = $page;
|
||||||
}
|
}
|
||||||
@ -635,31 +618,48 @@ final class Model
|
|||||||
return array_merge(...$pages);
|
return array_merge(...$pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getListPages(string $type, string $status = ''): Amp\Iterator
|
/**
|
||||||
|
* Get the raw anime/manga list from GraphQL
|
||||||
|
*
|
||||||
|
* @return mixed[]
|
||||||
|
*/
|
||||||
|
protected function getList(string $type, string $status = ''): array
|
||||||
|
{
|
||||||
|
return $this->getZippedList('GetLibrary', $type, $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A generator returning the relevant snippet for each 'page' of
|
||||||
|
* a media list request
|
||||||
|
*
|
||||||
|
* @param string $queryName - The GraphQL query
|
||||||
|
* @param string $type - Media type (anime, manga)
|
||||||
|
* @param string $status - Media 'consumption' status
|
||||||
|
* @return iterable
|
||||||
|
*/
|
||||||
|
private function getListPages(string $queryName, string $type, string $status): iterable
|
||||||
{
|
{
|
||||||
$cursor = '';
|
$cursor = '';
|
||||||
$username = $this->getUsername();
|
$username = $this->getUsername();
|
||||||
|
|
||||||
return new Amp\Producer(function (callable $emit) use ($type, $status, $cursor, $username): Generator {
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
$vars = [
|
$vars = [
|
||||||
'type' => $type,
|
'type' => strtoupper($type),
|
||||||
'slug' => $username,
|
'slug' => $username,
|
||||||
];
|
];
|
||||||
if ($status !== '')
|
if ($status !== '')
|
||||||
{
|
{
|
||||||
$vars['status'] = $status;
|
$vars['status'] = strtoupper($status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cursor !== '')
|
if ($cursor !== '')
|
||||||
{
|
{
|
||||||
$vars['after'] = $cursor;
|
$vars['after'] = $cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
$request = $this->requestBuilder->queryRequest('GetLibrary', $vars);
|
$request = $this->requestBuilder->queryRequest($queryName, $vars);
|
||||||
$response = yield getApiClient()->request($request);
|
$response = getApiClient()->request($request);
|
||||||
$json = yield $response->getBody()->buffer();
|
$json = $response->getBody()->buffer();
|
||||||
|
|
||||||
$rawData = Json::decode($json);
|
$rawData = Json::decode($json);
|
||||||
$data = $rawData['data']['findProfileBySlug']['library']['all'] ?? [];
|
$data = $rawData['data']['findProfileBySlug']['library']['all'] ?? [];
|
||||||
@ -679,112 +679,29 @@ final class Model
|
|||||||
|
|
||||||
$cursor = $page['endCursor'];
|
$cursor = $page['endCursor'];
|
||||||
|
|
||||||
yield $emit($data['nodes']);
|
yield $data['nodes'];
|
||||||
|
|
||||||
if ($page['hasNextPage'] !== TRUE)
|
if ($page['hasNextPage'] === FALSE || $page === [])
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getSyncPages(string $type, string $status): Amp\Iterator
|
private function getListCount(string $type, string $status = ''): int
|
||||||
{
|
{
|
||||||
$cursor = '';
|
$args = [
|
||||||
$username = $this->getUsername();
|
'type' => strtoupper($type),
|
||||||
|
'slug' => $this->getUsername(),
|
||||||
return new Amp\Producer(function (callable $emit) use ($type, $status, $cursor, $username): Generator {
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
$vars = [
|
|
||||||
'type' => $type,
|
|
||||||
'slug' => $username,
|
|
||||||
'status' => $status,
|
|
||||||
];
|
];
|
||||||
if ($cursor !== '')
|
if ($status !== '')
|
||||||
{
|
{
|
||||||
$vars['after'] = $cursor;
|
$args['status'] = strtoupper($status);
|
||||||
}
|
}
|
||||||
|
|
||||||
$request = $this->requestBuilder->queryRequest('GetSyncLibrary', $vars);
|
$res = $this->requestBuilder->runQuery('GetLibraryCount', $args);
|
||||||
$response = yield getApiClient()->request($request);
|
|
||||||
$json = yield $response->getBody()->buffer();
|
|
||||||
|
|
||||||
$rawData = Json::decode($json);
|
return $res['data']['findProfileBySlug']['library']['all']['totalCount'];
|
||||||
$data = $rawData['data']['findProfileBySlug']['library']['all'] ?? [];
|
|
||||||
$page = $data['pageInfo'];
|
|
||||||
if (empty($data))
|
|
||||||
{
|
|
||||||
dump($rawData);
|
|
||||||
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
$cursor = $page['endCursor'];
|
|
||||||
|
|
||||||
yield $emit($data['nodes']);
|
|
||||||
|
|
||||||
if ($page['hasNextPage'] === FALSE)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getThumbListPages(string $type, string $status): Amp\Iterator
|
|
||||||
{
|
|
||||||
$cursor = '';
|
|
||||||
$username = $this->getUsername();
|
|
||||||
|
|
||||||
return new Amp\Producer(function (callable $emit) use ($type, $status, $cursor, $username): Generator {
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
$vars = [
|
|
||||||
'type' => $type,
|
|
||||||
'slug' => $username,
|
|
||||||
'status' => $status,
|
|
||||||
];
|
|
||||||
if ($cursor !== '')
|
|
||||||
{
|
|
||||||
$vars['after'] = $cursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
$request = $this->requestBuilder->queryRequest('GetLibraryThumbs', $vars);
|
|
||||||
$response = yield getApiClient()->request($request);
|
|
||||||
$json = yield $response->getBody()->buffer();
|
|
||||||
|
|
||||||
$rawData = Json::decode($json);
|
|
||||||
$data = $rawData['data']['findProfileBySlug']['library']['all'] ?? [];
|
|
||||||
$page = $data['pageInfo'];
|
|
||||||
if (empty($data))
|
|
||||||
{
|
|
||||||
dump($rawData);
|
|
||||||
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
$cursor = $page['endCursor'];
|
|
||||||
|
|
||||||
yield $emit($data['nodes']);
|
|
||||||
|
|
||||||
if ($page['hasNextPage'] === FALSE)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getPages(callable $method, mixed ...$args): Generator
|
|
||||||
{
|
|
||||||
$items = $method(...$args);
|
|
||||||
|
|
||||||
while (wait($items->advance()))
|
|
||||||
{
|
|
||||||
yield $items->getCurrent();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getUserId(): string
|
protected function getUserId(): string
|
||||||
@ -808,20 +725,4 @@ final class Model
|
|||||||
->get('config')
|
->get('config')
|
||||||
->get(['kitsu_username']);
|
->get(['kitsu_username']);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getListCount(string $type, string $status = ''): int
|
|
||||||
{
|
|
||||||
$args = [
|
|
||||||
'type' => strtoupper($type),
|
|
||||||
'slug' => $this->getUsername(),
|
|
||||||
];
|
|
||||||
if ($status !== '')
|
|
||||||
{
|
|
||||||
$args['status'] = strtoupper($status);
|
|
||||||
}
|
|
||||||
|
|
||||||
$res = $this->requestBuilder->runQuery('GetLibraryCount', $args);
|
|
||||||
|
|
||||||
return $res['data']['findProfileBySlug']['library']['all']['totalCount'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
|
|||||||
use Aviat\Ion\{Event, Json, JsonException};
|
use Aviat\Ion\{Event, Json, JsonException};
|
||||||
|
|
||||||
use LogicException;
|
use LogicException;
|
||||||
use function Amp\Promise\wait;
|
|
||||||
use function Aviat\AnimeClient\getResponse;
|
use function Aviat\AnimeClient\getResponse;
|
||||||
use function in_array;
|
use function in_array;
|
||||||
use const Aviat\AnimeClient\{SESSION_SEGMENT, USER_AGENT};
|
use const Aviat\AnimeClient\{SESSION_SEGMENT, USER_AGENT};
|
||||||
@ -125,13 +124,10 @@ final class RequestBuilder extends APIRequestBuilder
|
|||||||
if ( ! in_array($response->getStatus(), $validResponseCodes, TRUE))
|
if ( ! in_array($response->getStatus(), $validResponseCodes, TRUE))
|
||||||
{
|
{
|
||||||
$logger = $this->container->getLogger('kitsu-graphql');
|
$logger = $this->container->getLogger('kitsu-graphql');
|
||||||
if ($logger !== NULL)
|
$logger?->warning('Non 200 response for GraphQL call', (array)$response->getBody());
|
||||||
{
|
|
||||||
$logger->warning('Non 200 response for GraphQL call', (array) $response->getBody());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Json::decode(wait($response->getBody()->buffer()));
|
return Json::decode($response->getBody()->buffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,13 +144,10 @@ final class RequestBuilder extends APIRequestBuilder
|
|||||||
if ( ! in_array($response->getStatus(), $validResponseCodes, TRUE))
|
if ( ! in_array($response->getStatus(), $validResponseCodes, TRUE))
|
||||||
{
|
{
|
||||||
$logger = $this->container->getLogger('kitsu-graphql');
|
$logger = $this->container->getLogger('kitsu-graphql');
|
||||||
if ($logger !== NULL)
|
$logger?->warning('Non 200 response for GraphQL call', (array)$response->getBody());
|
||||||
{
|
|
||||||
$logger->warning('Non 200 response for GraphQL call', (array) $response->getBody());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Json::decode(wait($response->getBody()->buffer()));
|
return Json::decode($response->getBody()->buffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,13 +14,11 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\API;
|
namespace Aviat\AnimeClient\API;
|
||||||
|
|
||||||
use Amp\Http\Client\{HttpException, Request};
|
use Amp\Future;
|
||||||
use Generator;
|
use Amp\Http\Client\{Request, Response};
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use function Amp\call;
|
|
||||||
|
|
||||||
// use function Amp\Future\{async, await};
|
use function Amp\async;
|
||||||
use function Amp\Promise\{all, wait};
|
|
||||||
use function Aviat\AnimeClient\getApiClient;
|
use function Aviat\AnimeClient\getApiClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,7 +67,14 @@ final class ParallelAPIRequest
|
|||||||
*/
|
*/
|
||||||
public function makeRequests(): array
|
public function makeRequests(): array
|
||||||
{
|
{
|
||||||
return $this->makeRequestOld();
|
$futures = [];
|
||||||
|
|
||||||
|
foreach ($this->requests as $key => $url)
|
||||||
|
{
|
||||||
|
$futures[$key] = async(static fn () => self::bodyHandler($url));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Future\await($futures);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,54 +83,6 @@ final class ParallelAPIRequest
|
|||||||
* @throws Throwable
|
* @throws Throwable
|
||||||
*/
|
*/
|
||||||
public function getResponses(): array
|
public function getResponses(): array
|
||||||
{
|
|
||||||
return $this->getResponsesOld();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function makeRequestOld(): array
|
|
||||||
{
|
|
||||||
$client = getApiClient();
|
|
||||||
|
|
||||||
$promises = [];
|
|
||||||
|
|
||||||
foreach ($this->requests as $key => $url)
|
|
||||||
{
|
|
||||||
$promises[$key] = call(static function () use ($client, $url): Generator {
|
|
||||||
$response = yield $client->request($url);
|
|
||||||
return yield $response->getBody()->buffer();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return wait(all($promises));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function makeRequestsNew(): array
|
|
||||||
{
|
|
||||||
$futures = [];
|
|
||||||
|
|
||||||
foreach ($this->requests as $key => $url)
|
|
||||||
{
|
|
||||||
$futures[$key] = async(static fn () => self::bodyHandler($url));
|
|
||||||
}
|
|
||||||
|
|
||||||
return await($futures);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getResponsesOld(): array
|
|
||||||
{
|
|
||||||
$client = getApiClient();
|
|
||||||
|
|
||||||
$promises = [];
|
|
||||||
|
|
||||||
foreach ($this->requests as $key => $url)
|
|
||||||
{
|
|
||||||
$promises[$key] = call(static fn () => yield $client->request($url));
|
|
||||||
}
|
|
||||||
|
|
||||||
return wait(all($promises));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getResponsesNew(): array
|
|
||||||
{
|
{
|
||||||
$futures = [];
|
$futures = [];
|
||||||
|
|
||||||
@ -134,7 +91,7 @@ final class ParallelAPIRequest
|
|||||||
$futures[$key] = async(static fn () => self::responseHandler($url));
|
$futures[$key] = async(static fn () => self::responseHandler($url));
|
||||||
}
|
}
|
||||||
|
|
||||||
return await($futures);
|
return Future\await($futures);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function bodyHandler(string|Request $uri): string
|
private static function bodyHandler(string|Request $uri): string
|
||||||
@ -150,7 +107,7 @@ final class ParallelAPIRequest
|
|||||||
return $response->getBody()->buffer();
|
return $response->getBody()->buffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function responseHandler(string|Request $uri)
|
private static function responseHandler(string|Request $uri): Response
|
||||||
{
|
{
|
||||||
$client = getApiClient();
|
$client = getApiClient();
|
||||||
|
|
||||||
|
@ -17,9 +17,7 @@ namespace Aviat\AnimeClient\Controller;
|
|||||||
use Aviat\AnimeClient\Controller as BaseController;
|
use Aviat\AnimeClient\Controller as BaseController;
|
||||||
use Aviat\Ion\Attribute\{Controller, Route};
|
use Aviat\Ion\Attribute\{Controller, Route};
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use function Amp\Promise\wait;
|
|
||||||
use function Aviat\AnimeClient\{createPlaceholderImage, getResponse};
|
use function Aviat\AnimeClient\{createPlaceholderImage, getResponse};
|
||||||
use function imagepalletetotruecolor;
|
|
||||||
|
|
||||||
use function in_array;
|
use function in_array;
|
||||||
|
|
||||||
@ -130,7 +128,7 @@ final class Images extends BaseController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = wait($response->getBody()->buffer());
|
$data = $response->getBody()->buffer();
|
||||||
|
|
||||||
$size = getimagesizefromstring($data);
|
$size = getimagesizefromstring($data);
|
||||||
if ($size === FALSE)
|
if ($size === FALSE)
|
||||||
|
@ -27,8 +27,12 @@ const USER_AGENT = "Tim's Anime Client/5.2";
|
|||||||
// Regex patterns
|
// Regex patterns
|
||||||
const ALPHA_SLUG_PATTERN = '[a-zA-Z_]+';
|
const ALPHA_SLUG_PATTERN = '[a-zA-Z_]+';
|
||||||
const NUM_PATTERN = '[0-9]+';
|
const NUM_PATTERN = '[0-9]+';
|
||||||
|
/**
|
||||||
|
* Eugh...url slugs can have weird characters
|
||||||
|
* So...if it's not a forward slash, sure it's valid 😅
|
||||||
|
*/
|
||||||
|
const KITSU_SLUG_PATTERN = '[^\/]+';
|
||||||
const SLUG_PATTERN = '[a-zA-Z0-9\- ]+';
|
const SLUG_PATTERN = '[a-zA-Z0-9\- ]+';
|
||||||
const SLUG_SPACE_PATTERN = '[a-zA-Z_\- ]+';
|
|
||||||
|
|
||||||
// Why doesn't this already exist?
|
// Why doesn't this already exist?
|
||||||
const MILLI_FROM_NANO = 1000 * 1000;
|
const MILLI_FROM_NANO = 1000 * 1000;
|
||||||
|
Loading…
Reference in New Issue
Block a user