diff --git a/app/bootstrap.php b/app/bootstrap.php index d68ead0c..af80becb 100644 --- a/app/bootstrap.php +++ b/app/bootstrap.php @@ -25,10 +25,11 @@ use Aviat\Banker\Teller; use Aviat\Ion\Config; use Aviat\Ion\Di\Container; use Aviat\Ion\Di\ContainerInterface; -use Psr\SimpleCache\CacheInterface; use Laminas\Diactoros\ServerRequestFactory; +use Monolog\Formatter\JsonFormatter; use Monolog\Handler\RotatingFileHandler; use Monolog\Logger; +use Psr\SimpleCache\CacheInterface; // ----------------------------------------------------------------------------- // Setup DI container @@ -41,17 +42,18 @@ return static function (array $configArray = []): Container { // ------------------------------------------------------------------------- $appLogger = new Logger('animeclient'); - $appLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/app.log', 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)); - + $appLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/app.log', 2, Logger::WARNING)); $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 diff --git a/src/AnimeClient/API/Kitsu/RequestBuilder.php b/src/AnimeClient/API/Kitsu/RequestBuilder.php index 51516c0c..d688a941 100644 --- a/src/AnimeClient/API/Kitsu/RequestBuilder.php +++ b/src/AnimeClient/API/Kitsu/RequestBuilder.php @@ -319,16 +319,9 @@ final class RequestBuilder extends APIRequestBuilder { $response = $this->getResponse('POST', K::GRAPHQL_ENDPOINT, $options); $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)) { + $logger = $this->container->getLogger('kitsu-graphql'); $logger->warning('Non 200 response for GraphQL call', (array)$response->getBody()); } diff --git a/src/AnimeClient/API/Kitsu/Transformer/CharacterTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/CharacterTransformer.php index 52340f66..168b9839 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/CharacterTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/CharacterTransformer.php @@ -16,7 +16,6 @@ namespace Aviat\AnimeClient\API\Kitsu\Transformer; -use Aviat\AnimeClient\API\JsonAPI; use Aviat\AnimeClient\API\Kitsu; use Aviat\AnimeClient\Types\Character; @@ -74,6 +73,7 @@ final class CharacterTransformer extends AbstractTransformer { $titleSort = fn ($a, $b) => $a['title'] <=> $b['title']; + // First, let's deal with related media $rawMedia = array_column($data, 'media'); $rawAnime = array_filter($rawMedia, fn ($item) => $item['type'] === 'Anime'); $rawManga = array_filter($rawMedia, fn ($item) => $item['type'] === 'Manga'); @@ -103,6 +103,7 @@ final class CharacterTransformer extends AbstractTransformer { 'manga' => $manga, ]; + // And now, reorganize voice actor relationships $rawVoices = array_filter($data, fn($item) => count((array)$item['voices']['nodes']) > 0); if (empty($rawVoices)) @@ -155,154 +156,4 @@ final class CharacterTransformer extends AbstractTransformer { 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; - } } \ No newline at end of file diff --git a/src/AnimeClient/Command/BaseCommand.php b/src/AnimeClient/Command/BaseCommand.php index 1ba61d1d..08461764 100644 --- a/src/AnimeClient/Command/BaseCommand.php +++ b/src/AnimeClient/Command/BaseCommand.php @@ -16,6 +16,7 @@ namespace Aviat\AnimeClient\Command; +use Monolog\Formatter\JsonFormatter; use function Aviat\AnimeClient\loadToml; use function Aviat\AnimeClient\loadTomlFile; @@ -138,18 +139,19 @@ abstract class BaseCommand extends Command { // Logging // ------------------------------------------------------------------------- - $app_logger = new Logger('animeclient'); - $app_logger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/app-cli.log', Logger::WARNING)); + $appLogger = new Logger('animeclient'); + $appLogger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/app-cli.log', 2, Logger::WARNING)); + $container->setLogger($appLogger); - $kitsu_request_logger = new Logger('kitsu-request'); - $kitsu_request_logger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/kitsu_request-cli.log', Logger::WARNING)); + foreach (['anilist-request-cli', 'kitsu-request-cli'] as $channel) + { + $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'); - $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'); + $container->setLogger($logger, $channel); + } // Create Config Object $container->set('config', fn () => new Config($configArray));