All in GraphQL #34
@ -25,10 +25,11 @@ use Aviat\Banker\Teller;
|
|||||||
use Aviat\Ion\Config;
|
use Aviat\Ion\Config;
|
||||||
use Aviat\Ion\Di\Container;
|
use Aviat\Ion\Di\Container;
|
||||||
use Aviat\Ion\Di\ContainerInterface;
|
use Aviat\Ion\Di\ContainerInterface;
|
||||||
use Psr\SimpleCache\CacheInterface;
|
|
||||||
use Laminas\Diactoros\ServerRequestFactory;
|
use Laminas\Diactoros\ServerRequestFactory;
|
||||||
|
use Monolog\Formatter\JsonFormatter;
|
||||||
use Monolog\Handler\RotatingFileHandler;
|
use Monolog\Handler\RotatingFileHandler;
|
||||||
use Monolog\Logger;
|
use Monolog\Logger;
|
||||||
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Setup DI container
|
// Setup DI container
|
||||||
@ -41,17 +42,18 @@ return static function (array $configArray = []): Container {
|
|||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
$appLogger = new Logger('animeclient');
|
$appLogger = new Logger('animeclient');
|
||||||
$appLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/app.log', Logger::WARNING));
|
$appLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/app.log', 2, Logger::WARNING));
|
||||||
|
|
||||||
$anilistRequestLogger = new Logger('anilist-request');
|
|
||||||
$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::WARNING));
|
|
||||||
|
|
||||||
$container->setLogger($appLogger);
|
$container->setLogger($appLogger);
|
||||||
$container->setLogger($anilistRequestLogger, 'anilist-request');
|
|
||||||
$container->setLogger($kitsuRequestLogger, 'kitsu-request');
|
foreach (['anilist-request', 'kitsu-request', 'kitsu-graphql'] as $channel)
|
||||||
|
{
|
||||||
|
$logger = new Logger($channel);
|
||||||
|
$handler = new RotatingFileHandler(__DIR__ . "/logs/{$channel}.log", 2, Logger::WARNING);
|
||||||
|
$handler->setFormatter(new JsonFormatter());
|
||||||
|
$logger->pushHandler($handler);
|
||||||
|
|
||||||
|
$container->setLogger($logger, $channel);
|
||||||
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Injected Objects
|
// Injected Objects
|
||||||
|
@ -319,16 +319,9 @@ final class RequestBuilder extends APIRequestBuilder {
|
|||||||
$response = $this->getResponse('POST', K::GRAPHQL_ENDPOINT, $options);
|
$response = $this->getResponse('POST', K::GRAPHQL_ENDPOINT, $options);
|
||||||
$validResponseCodes = [200, 201];
|
$validResponseCodes = [200, 201];
|
||||||
|
|
||||||
$logger = $this->container->getLogger('kitsu-request');
|
|
||||||
$logger->debug('Kitsu GraphQL response', [
|
|
||||||
'status' => $response->getStatus(),
|
|
||||||
'reason' => $response->getReason(),
|
|
||||||
'body' => $response->getBody(),
|
|
||||||
'headers' => $response->getHeaders(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ( ! \in_array($response->getStatus(), $validResponseCodes, TRUE))
|
if ( ! \in_array($response->getStatus(), $validResponseCodes, TRUE))
|
||||||
{
|
{
|
||||||
|
$logger = $this->container->getLogger('kitsu-graphql');
|
||||||
$logger->warning('Non 200 response for GraphQL call', (array)$response->getBody());
|
$logger->warning('Non 200 response for GraphQL call', (array)$response->getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\API\Kitsu\Transformer;
|
namespace Aviat\AnimeClient\API\Kitsu\Transformer;
|
||||||
|
|
||||||
use Aviat\AnimeClient\API\JsonAPI;
|
|
||||||
use Aviat\AnimeClient\API\Kitsu;
|
use Aviat\AnimeClient\API\Kitsu;
|
||||||
use Aviat\AnimeClient\Types\Character;
|
use Aviat\AnimeClient\Types\Character;
|
||||||
|
|
||||||
@ -74,6 +73,7 @@ final class CharacterTransformer extends AbstractTransformer {
|
|||||||
|
|
||||||
$titleSort = fn ($a, $b) => $a['title'] <=> $b['title'];
|
$titleSort = fn ($a, $b) => $a['title'] <=> $b['title'];
|
||||||
|
|
||||||
|
// First, let's deal with related media
|
||||||
$rawMedia = array_column($data, 'media');
|
$rawMedia = array_column($data, 'media');
|
||||||
$rawAnime = array_filter($rawMedia, fn ($item) => $item['type'] === 'Anime');
|
$rawAnime = array_filter($rawMedia, fn ($item) => $item['type'] === 'Anime');
|
||||||
$rawManga = array_filter($rawMedia, fn ($item) => $item['type'] === 'Manga');
|
$rawManga = array_filter($rawMedia, fn ($item) => $item['type'] === 'Manga');
|
||||||
@ -103,6 +103,7 @@ final class CharacterTransformer extends AbstractTransformer {
|
|||||||
'manga' => $manga,
|
'manga' => $manga,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// And now, reorganize voice actor relationships
|
||||||
$rawVoices = array_filter($data, fn($item) => count((array)$item['voices']['nodes']) > 0);
|
$rawVoices = array_filter($data, fn($item) => count((array)$item['voices']['nodes']) > 0);
|
||||||
|
|
||||||
if (empty($rawVoices))
|
if (empty($rawVoices))
|
||||||
@ -155,154 +156,4 @@ final class CharacterTransformer extends AbstractTransformer {
|
|||||||
|
|
||||||
return [$media, $castings];
|
return [$media, $castings];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $characterData
|
|
||||||
* @return Character
|
|
||||||
*/
|
|
||||||
public function oldTransform($characterData): Character
|
|
||||||
{
|
|
||||||
$data = JsonAPI::organizeData($characterData);
|
|
||||||
$attributes = $data[0]['attributes'];
|
|
||||||
$castings = [];
|
|
||||||
|
|
||||||
$names = array_unique(
|
|
||||||
array_merge(
|
|
||||||
[$attributes['canonicalName']],
|
|
||||||
$attributes['names']
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$name = array_shift($names);
|
|
||||||
|
|
||||||
if (array_key_exists('included', $data))
|
|
||||||
{
|
|
||||||
if (array_key_exists('anime', $data['included']))
|
|
||||||
{
|
|
||||||
uasort($data['included']['anime'], static function ($a, $b) {
|
|
||||||
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists('manga', $data['included']))
|
|
||||||
{
|
|
||||||
uasort($data['included']['manga'], static function ($a, $b) {
|
|
||||||
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists('castings', $data['included']))
|
|
||||||
{
|
|
||||||
$castings = $this->organizeCast($data['included']['castings']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Character::from([
|
|
||||||
'castings' => $castings,
|
|
||||||
'description' => $attributes['description'],
|
|
||||||
'id' => $data[0]['id'],
|
|
||||||
'media' => [
|
|
||||||
'anime' => $data['included']['anime'] ?? [],
|
|
||||||
'manga' => $data['included']['manga'] ?? [],
|
|
||||||
],
|
|
||||||
'name' => $name,
|
|
||||||
'names' => $names,
|
|
||||||
'otherNames' => $attributes['otherNames'],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Organize VA => anime relationships
|
|
||||||
*
|
|
||||||
* @param array $cast
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function dedupeCast(array $cast): array
|
|
||||||
{
|
|
||||||
$output = [];
|
|
||||||
$people = [];
|
|
||||||
|
|
||||||
$i = 0;
|
|
||||||
foreach ($cast as &$role)
|
|
||||||
{
|
|
||||||
if (empty($role['attributes']['role']))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$person = current($role['relationships']['person']['people'])['attributes'];
|
|
||||||
$hasName = array_key_exists($person['name'], $people);
|
|
||||||
|
|
||||||
if ( ! $hasName)
|
|
||||||
{
|
|
||||||
$people[$person['name']] = $i;
|
|
||||||
$role['relationships']['media']['anime'] = [current($role['relationships']['media']['anime'])];
|
|
||||||
$output[$i] = $role;
|
|
||||||
|
|
||||||
$i++;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists('anime', $role['relationships']['media']))
|
|
||||||
{
|
|
||||||
$key = $people[$person['name']];
|
|
||||||
$output[$key]['relationships']['media']['anime'][] = current($role['relationships']['media']['anime']);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function organizeCast(array $cast): array
|
|
||||||
{
|
|
||||||
$cast = $this->dedupeCast($cast);
|
|
||||||
$output = [];
|
|
||||||
|
|
||||||
foreach ($cast as $id => $role)
|
|
||||||
{
|
|
||||||
if (empty($role['attributes']['role']))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$language = $role['attributes']['language'];
|
|
||||||
$roleName = $role['attributes']['role'];
|
|
||||||
$isVA = $role['attributes']['voiceActor'];
|
|
||||||
|
|
||||||
if ($isVA)
|
|
||||||
{
|
|
||||||
foreach ($role['relationships']['person']['people'] as $pid => $peoples)
|
|
||||||
{
|
|
||||||
$p = $peoples;
|
|
||||||
|
|
||||||
$person = $p['attributes'];
|
|
||||||
$person['id'] = $pid;
|
|
||||||
$person['image'] = $person['image']['original'] ?? '';
|
|
||||||
|
|
||||||
uasort($role['relationships']['media']['anime'], static function ($a, $b) {
|
|
||||||
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
|
||||||
});
|
|
||||||
|
|
||||||
$item = [
|
|
||||||
'person' => $person,
|
|
||||||
'series' => $role['relationships']['media']['anime']
|
|
||||||
];
|
|
||||||
|
|
||||||
$output[$roleName][$language][] = $item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach ($role['relationships']['person']['people'] as $pid => $person)
|
|
||||||
{
|
|
||||||
$person['id'] = $pid;
|
|
||||||
$output[$roleName][$pid] = $person;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\Command;
|
namespace Aviat\AnimeClient\Command;
|
||||||
|
|
||||||
|
use Monolog\Formatter\JsonFormatter;
|
||||||
use function Aviat\AnimeClient\loadToml;
|
use function Aviat\AnimeClient\loadToml;
|
||||||
use function Aviat\AnimeClient\loadTomlFile;
|
use function Aviat\AnimeClient\loadTomlFile;
|
||||||
|
|
||||||
@ -138,18 +139,19 @@ abstract class BaseCommand extends Command {
|
|||||||
// Logging
|
// Logging
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
$app_logger = new Logger('animeclient');
|
$appLogger = new Logger('animeclient');
|
||||||
$app_logger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/app-cli.log', Logger::WARNING));
|
$appLogger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/app-cli.log', 2, Logger::WARNING));
|
||||||
|
$container->setLogger($appLogger);
|
||||||
|
|
||||||
$kitsu_request_logger = new Logger('kitsu-request');
|
foreach (['anilist-request-cli', 'kitsu-request-cli'] as $channel)
|
||||||
$kitsu_request_logger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/kitsu_request-cli.log', Logger::WARNING));
|
{
|
||||||
|
$logger = new Logger($channel);
|
||||||
|
$handler = new RotatingFileHandler( "{$APP_DIR}/logs/{$channel}.log", 2, Logger::WARNING);
|
||||||
|
$handler->setFormatter(new JsonFormatter());
|
||||||
|
$logger->pushHandler($handler);
|
||||||
|
|
||||||
$anilistRequestLogger = new Logger('anilist-request');
|
$container->setLogger($logger, $channel);
|
||||||
$anilistRequestLogger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/anilist_request-cli.log', Logger::WARNING));
|
}
|
||||||
|
|
||||||
$container->setLogger($app_logger);
|
|
||||||
$container->setLogger($anilistRequestLogger, 'anilist-request');
|
|
||||||
$container->setLogger($kitsu_request_logger, 'kitsu-request');
|
|
||||||
|
|
||||||
// Create Config Object
|
// Create Config Object
|
||||||
$container->set('config', fn () => new Config($configArray));
|
$container->set('config', fn () => new Config($configArray));
|
||||||
|
Loading…
Reference in New Issue
Block a user