Version 5.1 - All the GraphQL #32
4
.gitignore
vendored
4
.gitignore
vendored
@ -146,4 +146,6 @@ public/images/manga/**
|
||||
public/images/characters/**
|
||||
public/images/people/**
|
||||
public/mal_mappings.json
|
||||
.phpunit.result.cache
|
||||
.phpunit.result.cache
|
||||
|
||||
.is-dev
|
@ -25,10 +25,11 @@ use Aviat\AnimeClient\API\{
|
||||
Kitsu\KitsuRequestBuilder
|
||||
};
|
||||
use Aviat\AnimeClient\Model;
|
||||
use Aviat\Banker\Pool;
|
||||
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\{Response, ServerRequestFactory};
|
||||
use Monolog\Handler\RotatingFileHandler;
|
||||
use Monolog\Logger;
|
||||
@ -64,10 +65,10 @@ return static function (array $configArray = []): Container {
|
||||
$container->set('config', fn () => new Config($configArray));
|
||||
|
||||
// Create Cache Object
|
||||
$container->set('cache', static function(ContainerInterface $container): Pool {
|
||||
$container->set('cache', static function(ContainerInterface $container): CacheInterface {
|
||||
$logger = $container->getLogger();
|
||||
$config = $container->get('config')->get('cache');
|
||||
return new Pool($config, $logger);
|
||||
return new Teller($config, $logger);
|
||||
});
|
||||
|
||||
// Create Aura Router Object
|
||||
@ -113,7 +114,7 @@ return static function (array $configArray = []): Container {
|
||||
|
||||
// Models
|
||||
$container->set('kitsu-model', static function(ContainerInterface $container): Kitsu\Model {
|
||||
$requestBuilder = new KitsuRequestBuilder();
|
||||
$requestBuilder = new KitsuRequestBuilder($container);
|
||||
$requestBuilder->setLogger($container->getLogger('kitsu-request'));
|
||||
|
||||
$listItem = new Kitsu\ListItem();
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
# See https://git.timshomepage.net/aviat/banker for more information
|
||||
|
||||
# Available drivers are apcu, memcache, memcached, redis or null
|
||||
# Available drivers are memcached, redis or null
|
||||
# Null cache driver means no caching
|
||||
driver = "redis"
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
"aura/html": "^2.5.0",
|
||||
"aura/router": "^3.1.0",
|
||||
"aura/session": "^2.1.0",
|
||||
"aviat/banker": "^2.0.0",
|
||||
"aviat/banker": "^3.1.1",
|
||||
"aviat/query": "^3.0.0",
|
||||
"danielstjules/stringy": "^3.1.0",
|
||||
"ext-dom": "*",
|
||||
|
@ -27,7 +27,7 @@ setlocale(LC_CTYPE, 'en_US');
|
||||
// Load composer autoloader
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
if (array_key_exists('ENV', $_SERVER) && $_SERVER['ENV'] === 'development')
|
||||
if (file_exists('.is-dev'))
|
||||
{
|
||||
$whoops = new Run;
|
||||
$whoops->pushHandler(new PrettyPageHandler);
|
||||
|
@ -16,7 +16,8 @@
|
||||
|
||||
namespace Aviat\AnimeClient\API;
|
||||
|
||||
use Aviat\Banker\Pool;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Psr\SimpleCache\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Helper methods for dealing with the Cache
|
||||
@ -24,17 +25,17 @@ use Aviat\Banker\Pool;
|
||||
trait CacheTrait {
|
||||
|
||||
/**
|
||||
* @var Pool
|
||||
* @var CacheInterface
|
||||
*/
|
||||
protected Pool $cache;
|
||||
protected CacheInterface $cache;
|
||||
|
||||
/**
|
||||
* Inject the cache object
|
||||
*
|
||||
* @param Pool $cache
|
||||
* @param CacheInterface $cache
|
||||
* @return $this
|
||||
*/
|
||||
public function setCache(Pool $cache): self
|
||||
public function setCache(CacheInterface $cache): self
|
||||
{
|
||||
$this->cache = $cache;
|
||||
return $this;
|
||||
@ -43,13 +44,41 @@ trait CacheTrait {
|
||||
/**
|
||||
* Get the cache object if it exists
|
||||
*
|
||||
* @return Pool
|
||||
* @return CacheInterface
|
||||
*/
|
||||
public function getCache(): Pool
|
||||
public function getCache(): CacheInterface
|
||||
{
|
||||
return $this->cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cached value if it exists, otherwise set the cache value
|
||||
* and return it.
|
||||
*
|
||||
* @param string $key
|
||||
* @param callable $primer
|
||||
* @param array $primeArgs
|
||||
* @return mixed|null
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function getCached(string $key, callable $primer, ?array $primeArgs = [])
|
||||
{
|
||||
$value = $this->cache->get($key, NULL);
|
||||
|
||||
if ($value === NULL)
|
||||
{
|
||||
$value = $primer(...$primeArgs);
|
||||
if ($value === NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$this->cache->set($key, $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a hash as a cache key from the current method call
|
||||
*
|
||||
@ -61,7 +90,7 @@ trait CacheTrait {
|
||||
public function getHashForMethodCall($object, string $method, array $args = []): string
|
||||
{
|
||||
$keyObj = [
|
||||
'class' => \get_class($object),
|
||||
'class' => get_class($object),
|
||||
'method' => $method,
|
||||
'args' => $args,
|
||||
];
|
||||
|
@ -28,6 +28,8 @@ final class Kitsu {
|
||||
public const AUTH_TOKEN_CACHE_KEY = 'kitsu-auth-token';
|
||||
public const AUTH_TOKEN_EXP_CACHE_KEY = 'kitsu-auth-token-expires';
|
||||
public const AUTH_TOKEN_REFRESH_CACHE_KEY = 'kitsu-auth-token-refresh';
|
||||
public const ANIME_HISTORY_LIST_CACHE_KEY = 'kitsu-anime-history-list';
|
||||
public const MANGA_HISTORY_LIST_CACHE_KEY = 'kitsu-manga-history-list';
|
||||
|
||||
/**
|
||||
* Determine whether an anime is airing, finished airing, or has not yet aired
|
||||
|
@ -18,7 +18,6 @@ namespace Aviat\AnimeClient\API\Kitsu;
|
||||
|
||||
use Aura\Session\Segment;
|
||||
|
||||
use Aviat\Banker\Exception\InvalidArgumentException;
|
||||
use const Aviat\AnimeClient\SESSION_SEGMENT;
|
||||
|
||||
use Aviat\AnimeClient\API\{
|
||||
@ -29,8 +28,9 @@ use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
|
||||
use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException};
|
||||
use Aviat\Ion\Event;
|
||||
|
||||
use Psr\SimpleCache\InvalidArgumentException;
|
||||
|
||||
use Throwable;
|
||||
use const PHP_SAPI;
|
||||
|
||||
/**
|
||||
* Kitsu API Authentication
|
||||
@ -77,7 +77,6 @@ final class Auth {
|
||||
*
|
||||
* @param string $password
|
||||
* @return boolean
|
||||
* @throws InvalidArgumentException
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function authenticate(string $password): bool
|
||||
@ -95,12 +94,11 @@ final class Auth {
|
||||
*
|
||||
* @param string $refreshToken
|
||||
* @return boolean
|
||||
* @throws InvalidArgumentException
|
||||
* @throws Throwable
|
||||
* @throws Throwable|InvalidArgumentException
|
||||
*/
|
||||
public function reAuthenticate(?string $refreshToken): bool
|
||||
{
|
||||
$refreshToken ??= $this->getAuthToken();
|
||||
$refreshToken ??= $this->getRefreshToken();
|
||||
|
||||
if (empty($refreshToken))
|
||||
{
|
||||
@ -116,6 +114,7 @@ final class Auth {
|
||||
* Check whether the current user is authenticated
|
||||
*
|
||||
* @return boolean
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function isAuthenticated(): bool
|
||||
{
|
||||
@ -136,87 +135,59 @@ final class Auth {
|
||||
* Retrieve the authentication token from the session
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function getAuthToken(): ?string
|
||||
public function getAuthToken(): ?string
|
||||
{
|
||||
$now = time();
|
||||
|
||||
if (PHP_SAPI === 'cli')
|
||||
{
|
||||
$token = $this->cacheGet(K::AUTH_TOKEN_CACHE_KEY, NULL);
|
||||
$refreshToken = $this->cacheGet(K::AUTH_TOKEN_REFRESH_CACHE_KEY, NULL);
|
||||
$expireTime = $this->cacheGet(K::AUTH_TOKEN_EXP_CACHE_KEY);
|
||||
$isExpired = $now > $expireTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
$token = $this->segment->get('auth_token', NULL);
|
||||
$refreshToken = $this->segment->get('refresh_token', NULL);
|
||||
$isExpired = $now > $this->segment->get('auth_token_expires', $now + 5000);
|
||||
}
|
||||
|
||||
// Attempt to re-authenticate with refresh token
|
||||
/* if ($isExpired === TRUE && $refreshToken !== NULL)
|
||||
{
|
||||
if ($this->reAuthenticate($refreshToken) !== NULL)
|
||||
{
|
||||
return (PHP_SAPI === 'cli')
|
||||
? $this->cacheGet(K::AUTH_TOKEN_CACHE_KEY, NULL)
|
||||
: $this->segment->get('auth_token', NULL);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}*/
|
||||
|
||||
return $token;
|
||||
return $this->segment->get('auth_token', NULL)
|
||||
?? $this->cache->get(K::AUTH_TOKEN_CACHE_KEY, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the refresh token
|
||||
*
|
||||
* @return string|null
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function getRefreshToken(): ?string
|
||||
{
|
||||
return (PHP_SAPI === 'cli')
|
||||
? $this->cacheGet(K::AUTH_TOKEN_REFRESH_CACHE_KEY, NULL)
|
||||
: $this->segment->get('refresh_token');
|
||||
return $this->segment->get('refresh_token')
|
||||
?? $this->cache->get(K::AUTH_TOKEN_REFRESH_CACHE_KEY, NULL);
|
||||
}
|
||||
|
||||
private function storeAuth(bool $auth): bool
|
||||
/**
|
||||
* Save the new authentication information
|
||||
*
|
||||
* @param $auth
|
||||
* @return bool
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function storeAuth($auth): bool
|
||||
{
|
||||
if (FALSE !== $auth)
|
||||
{
|
||||
// Set the token in the cache for command line operations
|
||||
$cacheItem = $this->cache->getItem(K::AUTH_TOKEN_CACHE_KEY);
|
||||
$cacheItem->set($auth['access_token']);
|
||||
$cacheItem->save();
|
||||
|
||||
// Set the token expiration in the cache
|
||||
$expire_time = $auth['created_at'] + $auth['expires_in'];
|
||||
$cacheItem = $this->cache->getItem(K::AUTH_TOKEN_EXP_CACHE_KEY);
|
||||
$cacheItem->set($expire_time);
|
||||
$cacheItem->save();
|
||||
|
||||
// Set the token in the cache for command line operations
|
||||
// Set the token expiration in the cache
|
||||
// Set the refresh token in the cache
|
||||
$cacheItem = $this->cache->getItem(K::AUTH_TOKEN_REFRESH_CACHE_KEY);
|
||||
$cacheItem->set($auth['refresh_token']);
|
||||
$cacheItem->save();
|
||||
$saved = $this->cache->setMultiple([
|
||||
K::AUTH_TOKEN_CACHE_KEY => $auth['access_token'],
|
||||
K::AUTH_TOKEN_EXP_CACHE_KEY => $expire_time,
|
||||
K::AUTH_TOKEN_REFRESH_CACHE_KEY => $auth['refresh_token'],
|
||||
]);
|
||||
|
||||
// Set the session values
|
||||
$this->segment->set('auth_token', $auth['access_token']);
|
||||
$this->segment->set('auth_token_expires', $expire_time);
|
||||
$this->segment->set('refresh_token', $auth['refresh_token']);
|
||||
return TRUE;
|
||||
if ($saved)
|
||||
{
|
||||
$this->segment->set('auth_token', $auth['access_token']);
|
||||
$this->segment->set('auth_token_expires', $expire_time);
|
||||
$this->segment->set('refresh_token', $auth['refresh_token']);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
private function cacheGet(string $key, $default = NULL)
|
||||
{
|
||||
$cacheItem = $this->cache->getItem($key);
|
||||
if ( ! $cacheItem->isHit())
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $cacheItem->get();
|
||||
}
|
||||
}
|
||||
// End of KitsuAuth.php
|
@ -190,11 +190,8 @@ final class Model {
|
||||
$username = $this->getUsername();
|
||||
}
|
||||
|
||||
$cacheItem = $this->cache->getItem(K::AUTH_USER_ID_KEY);
|
||||
|
||||
if ( ! $cacheItem->isHit())
|
||||
{
|
||||
$data = $this->getRequest('users', [
|
||||
return $this->getCached(K::AUTH_USER_ID_KEY, function(string $username) {
|
||||
$data = $this->requestBuilder->getRequest('users', [
|
||||
'query' => [
|
||||
'filter' => [
|
||||
'name' => $username
|
||||
@ -202,11 +199,8 @@ final class Model {
|
||||
]
|
||||
]);
|
||||
|
||||
$cacheItem->set($data['data'][0]['id']);
|
||||
$cacheItem->save();
|
||||
}
|
||||
|
||||
return $cacheItem->get();
|
||||
return $data['data'][0]['id'] ?? NULL;
|
||||
}, [$username]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -398,11 +392,23 @@ final class Model {
|
||||
*/
|
||||
public function getAnimeHistory(): array
|
||||
{
|
||||
$raw = $this->getRawHistoryList('anime');
|
||||
$organized = JsonAPI::organizeData($raw);
|
||||
$organized = array_filter($organized, fn ($item) => array_key_exists('relationships', $item));
|
||||
$key = K::ANIME_HISTORY_LIST_CACHE_KEY;
|
||||
$list = $this->cache->get($key, NULL);
|
||||
|
||||
return (new AnimeHistoryTransformer())->transform($organized);
|
||||
if ($list === NULL)
|
||||
{
|
||||
$raw = $this->getRawHistoryList('anime');
|
||||
|
||||
$organized = JsonAPI::organizeData($raw);
|
||||
$organized = array_filter($organized, fn ($item) => array_key_exists('relationships', $item));
|
||||
|
||||
$list = (new AnimeHistoryTransformer())->transform($organized);
|
||||
|
||||
$this->cache->set($key, $list);
|
||||
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -426,9 +432,11 @@ final class Model {
|
||||
*/
|
||||
public function getAnimeList(string $status): array
|
||||
{
|
||||
$cacheItem = $this->cache->getItem("kitsu-anime-list-{$status}");
|
||||
$key = "kitsu-anime-list-{$status}";
|
||||
|
||||
if ( ! $cacheItem->isHit())
|
||||
$list = $this->cache->get($key, NULL);
|
||||
|
||||
if ($list === NULL)
|
||||
{
|
||||
$data = $this->getRawAnimeList($status) ?? [];
|
||||
|
||||
@ -454,11 +462,11 @@ final class Model {
|
||||
$keyed[$item['id']] = $item;
|
||||
}
|
||||
|
||||
$cacheItem->set($keyed);
|
||||
$cacheItem->save();
|
||||
$list = $keyed;
|
||||
$this->cache->set($key, $list);
|
||||
}
|
||||
|
||||
return $cacheItem->get();
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -650,11 +658,21 @@ final class Model {
|
||||
*/
|
||||
public function getMangaHistory(): array
|
||||
{
|
||||
$raw = $this->getRawHistoryList('manga');
|
||||
$organized = JsonAPI::organizeData($raw);
|
||||
$organized = array_filter($organized, fn ($item) => array_key_exists('relationships', $item));
|
||||
$key = K::MANGA_HISTORY_LIST_CACHE_KEY;
|
||||
$list = $this->cache->get($key, NULL);
|
||||
|
||||
return (new MangaHistoryTransformer())->transform($organized);
|
||||
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);
|
||||
|
||||
$this->cache->set($key, $list);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -696,11 +714,13 @@ final class Model {
|
||||
]
|
||||
];
|
||||
|
||||
$cacheItem = $this->cache->getItem("kitsu-manga-list-{$status}");
|
||||
$key = "kitsu-manga-list-{$status}";
|
||||
|
||||
if ( ! $cacheItem->isHit())
|
||||
$list = $this->cache->get($key, NULL);
|
||||
|
||||
if ($list === NULL)
|
||||
{
|
||||
$data = $this->getRequest('library-entries', $options) ?? [];
|
||||
$data = $this->requestBuilder->getRequest('library-entries', $options) ?? [];
|
||||
|
||||
// Bail out on no data
|
||||
if (empty($data) || ( ! array_key_exists('included', $data)))
|
||||
@ -717,13 +737,12 @@ final class Model {
|
||||
}
|
||||
unset($item);
|
||||
|
||||
$transformed = $this->mangaListTransformer->transformCollection($data['data']);
|
||||
$list = $this->mangaListTransformer->transformCollection($data['data']);
|
||||
|
||||
$cacheItem->set($transformed);
|
||||
$cacheItem->save();
|
||||
$this->cache->set($key, $list);
|
||||
}
|
||||
|
||||
return $cacheItem->get();
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,7 +149,7 @@ final class CharacterTransformer extends AbstractTransformer {
|
||||
|
||||
$person = $p['attributes'];
|
||||
$person['id'] = $pid;
|
||||
$person['image'] = $person['image']['original'];
|
||||
$person['image'] = $person['image']['original'] ?? '';
|
||||
|
||||
uasort($role['relationships']['media']['anime'], static function ($a, $b) {
|
||||
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
||||
|
@ -98,16 +98,12 @@ final class MangaTransformer extends AbstractTransformer {
|
||||
|
||||
if ( ! empty($characters['main']))
|
||||
{
|
||||
uasort($characters['main'], static function ($a, $b) {
|
||||
return $a['name'] <=> $b['name'];
|
||||
});
|
||||
uasort($characters['main'], fn ($a, $b) => $a['name'] <=> $b['anime']);
|
||||
}
|
||||
|
||||
if ( ! empty($characters['supporting']))
|
||||
{
|
||||
uasort($characters['supporting'], static function ($a, $b) {
|
||||
return $a['name'] <=> $b['name'];
|
||||
});
|
||||
uasort($characters['supporting'], fn ($a, $b) => $a['name'] <=> $b['anime']);
|
||||
}
|
||||
|
||||
ksort($characters);
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
namespace Aviat\AnimeClient;
|
||||
|
||||
use Aviat\AnimeClient\API\Kitsu;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use Psr\SimpleCache\InvalidArgumentException;
|
||||
use function Amp\Promise\wait;
|
||||
|
||||
use Amp\Http\Client\Request;
|
||||
@ -26,6 +29,8 @@ use Amp\Http\Client\HttpClientBuilder;
|
||||
use Aviat\Ion\ConfigInterface;
|
||||
use Yosymfony\Toml\{Toml, TomlBuilder};
|
||||
|
||||
use Throwable;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//! TOML Functions
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -232,7 +237,7 @@ function getApiClient (): HttpClient
|
||||
*
|
||||
* @param string|Request $request
|
||||
* @return Response
|
||||
* @throws \Throwable
|
||||
* @throws Throwable
|
||||
*/
|
||||
function getResponse ($request): Response
|
||||
{
|
||||
@ -256,7 +261,7 @@ function getResponse ($request): Response
|
||||
*/
|
||||
function getLocalImg ($kitsuUrl, $webp = TRUE): string
|
||||
{
|
||||
if ( ! is_string($kitsuUrl))
|
||||
if (empty($kitsuUrl) || ( ! is_string($kitsuUrl)))
|
||||
{
|
||||
return 'images/placeholder.webp';
|
||||
}
|
||||
@ -345,4 +350,31 @@ function col_not_empty(array $search, string $key): bool
|
||||
{
|
||||
$items = array_filter(array_column($search, $key), fn ($x) => ( ! empty($x)));
|
||||
return count($items) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the cache, but save user auth data
|
||||
*
|
||||
* @param CacheInterface $cache
|
||||
* @return bool
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
function clearCache(CacheInterface $cache): bool
|
||||
{
|
||||
// Save the user data, if it exists, for priming the cache
|
||||
$userData = $cache->getMultiple([
|
||||
Kitsu::AUTH_USER_ID_KEY,
|
||||
Kitsu::AUTH_TOKEN_CACHE_KEY,
|
||||
Kitsu::AUTH_TOKEN_EXP_CACHE_KEY,
|
||||
Kitsu::AUTH_TOKEN_REFRESH_CACHE_KEY,
|
||||
], NULL);
|
||||
|
||||
$userData = array_filter((array)$userData, fn ($value) => $value !== NULL);
|
||||
$cleared = $cache->clear();
|
||||
|
||||
$saved = ( ! empty($userData))
|
||||
? $cache->setMultiple($userData)
|
||||
: TRUE;
|
||||
|
||||
return $cleared && $saved;
|
||||
}
|
@ -24,7 +24,7 @@ use Aura\Session\SessionFactory;
|
||||
use Aviat\AnimeClient\{Model, UrlGenerator, Util};
|
||||
use Aviat\AnimeClient\API\{Anilist, CacheTrait, Kitsu};
|
||||
use Aviat\AnimeClient\API\Kitsu\KitsuRequestBuilder;
|
||||
use Aviat\Banker\Pool;
|
||||
use Aviat\Banker\Teller;
|
||||
use Aviat\Ion\Config;
|
||||
use Aviat\Ion\Di\{Container, ContainerInterface, ContainerAware};
|
||||
use ConsoleKit\{Colors, Command, ConsoleException};
|
||||
@ -129,99 +129,7 @@ abstract class BaseCommand extends Command {
|
||||
|
||||
$configArray = array_replace_recursive($baseConfig, $config, $overrideConfig);
|
||||
|
||||
$di = static function (array $configArray) use ($APP_DIR): Container {
|
||||
$container = new Container();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Logging
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
$app_logger = new Logger('animeclient');
|
||||
$app_logger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/app-cli.log', Logger::NOTICE));
|
||||
|
||||
$kitsu_request_logger = new Logger('kitsu-request');
|
||||
$kitsu_request_logger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/kitsu_request-cli.log', Logger::NOTICE));
|
||||
|
||||
$anilistRequestLogger = new Logger('anilist-request');
|
||||
$anilistRequestLogger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/anilist_request-cli.log', Logger::NOTICE));
|
||||
|
||||
$container->setLogger($app_logger);
|
||||
$container->setLogger($anilistRequestLogger, 'anilist-request');
|
||||
$container->setLogger($kitsu_request_logger, 'kitsu-request');
|
||||
|
||||
// Create Config Object
|
||||
$container->set('config', fn () => new Config($configArray));
|
||||
|
||||
// Create Cache Object
|
||||
$container->set('cache', static function($container) {
|
||||
$logger = $container->getLogger();
|
||||
$config = $container->get('config')->get('cache');
|
||||
return new Pool($config, $logger);
|
||||
});
|
||||
|
||||
// Create Aura Router Object
|
||||
$container->set('aura-router', fn () => new RouterContainer);
|
||||
|
||||
// Create Request/Response Objects
|
||||
$container->set('request', fn () => ServerRequestFactory::fromGlobals(
|
||||
$_SERVER,
|
||||
$_GET,
|
||||
$_POST,
|
||||
$_COOKIE,
|
||||
$_FILES
|
||||
));
|
||||
$container->set('response', fn () => new Response);
|
||||
|
||||
// Create session Object
|
||||
$container->set('session', fn () => (new SessionFactory())->newInstance($_COOKIE));
|
||||
|
||||
// Models
|
||||
$container->set('kitsu-model', static function($container): Kitsu\Model {
|
||||
$requestBuilder = new KitsuRequestBuilder();
|
||||
$requestBuilder->setLogger($container->getLogger('kitsu-request'));
|
||||
|
||||
$listItem = new Kitsu\ListItem();
|
||||
$listItem->setContainer($container);
|
||||
$listItem->setRequestBuilder($requestBuilder);
|
||||
|
||||
$model = new Kitsu\Model($listItem);
|
||||
$model->setContainer($container);
|
||||
$model->setRequestBuilder($requestBuilder);
|
||||
|
||||
$cache = $container->get('cache');
|
||||
$model->setCache($cache);
|
||||
return $model;
|
||||
});
|
||||
$container->set('anilist-model', static function ($container): Anilist\Model {
|
||||
$requestBuilder = new Anilist\AnilistRequestBuilder();
|
||||
$requestBuilder->setLogger($container->getLogger('anilist-request'));
|
||||
|
||||
$listItem = new Anilist\ListItem();
|
||||
$listItem->setContainer($container);
|
||||
$listItem->setRequestBuilder($requestBuilder);
|
||||
|
||||
$model = new Anilist\Model($listItem);
|
||||
$model->setContainer($container);
|
||||
$model->setRequestBuilder($requestBuilder);
|
||||
|
||||
return $model;
|
||||
});
|
||||
$container->set('settings-model', static function($container): Model\Settings {
|
||||
$model = new Model\Settings($container->get('config'));
|
||||
$model->setContainer($container);
|
||||
return $model;
|
||||
});
|
||||
|
||||
$container->set('auth', fn ($container) => new Kitsu\Auth($container));
|
||||
|
||||
$container->set('url-generator', fn ($container) => new UrlGenerator($container));
|
||||
|
||||
$container->set('util', fn ($container) => new Util($container));
|
||||
|
||||
return $container;
|
||||
};
|
||||
|
||||
return $di($configArray);
|
||||
return $this->_di($configArray, $APP_DIR);
|
||||
}
|
||||
|
||||
private function _line(string $message, $fgColor = NULL, $bgColor = NULL): void
|
||||
@ -229,4 +137,97 @@ abstract class BaseCommand extends Command {
|
||||
$message = Colors::colorize($message, $fgColor, $bgColor);
|
||||
$this->getConsole()->writeln($message);
|
||||
}
|
||||
|
||||
private function _di(array $configArray, string $APP_DIR): ContainerInterface
|
||||
{
|
||||
$container = new Container();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Logging
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
$app_logger = new Logger('animeclient');
|
||||
$app_logger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/app-cli.log', Logger::NOTICE));
|
||||
|
||||
$kitsu_request_logger = new Logger('kitsu-request');
|
||||
$kitsu_request_logger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/kitsu_request-cli.log', Logger::NOTICE));
|
||||
|
||||
$anilistRequestLogger = new Logger('anilist-request');
|
||||
$anilistRequestLogger->pushHandler(new RotatingFileHandler($APP_DIR . '/logs/anilist_request-cli.log', Logger::NOTICE));
|
||||
|
||||
$container->setLogger($app_logger);
|
||||
$container->setLogger($anilistRequestLogger, 'anilist-request');
|
||||
$container->setLogger($kitsu_request_logger, 'kitsu-request');
|
||||
|
||||
// Create Config Object
|
||||
$container->set('config', fn () => new Config($configArray));
|
||||
|
||||
// Create Cache Object
|
||||
$container->set('cache', static function($container) {
|
||||
$logger = $container->getLogger();
|
||||
$config = $container->get('config')->get('cache');
|
||||
return new Teller($config, $logger);
|
||||
});
|
||||
|
||||
// Create Aura Router Object
|
||||
$container->set('aura-router', fn () => new RouterContainer);
|
||||
|
||||
// Create Request/Response Objects
|
||||
$container->set('request', fn () => ServerRequestFactory::fromGlobals(
|
||||
$_SERVER,
|
||||
$_GET,
|
||||
$_POST,
|
||||
$_COOKIE,
|
||||
$_FILES
|
||||
));
|
||||
$container->set('response', fn () => new Response);
|
||||
|
||||
// Create session Object
|
||||
$container->set('session', fn () => (new SessionFactory())->newInstance($_COOKIE));
|
||||
|
||||
// Models
|
||||
$container->set('kitsu-model', static function($container): Kitsu\Model {
|
||||
$requestBuilder = new KitsuRequestBuilder($container);
|
||||
$requestBuilder->setLogger($container->getLogger('kitsu-request'));
|
||||
|
||||
$listItem = new Kitsu\ListItem();
|
||||
$listItem->setContainer($container);
|
||||
$listItem->setRequestBuilder($requestBuilder);
|
||||
|
||||
$model = new Kitsu\Model($listItem);
|
||||
$model->setContainer($container);
|
||||
$model->setRequestBuilder($requestBuilder);
|
||||
|
||||
$cache = $container->get('cache');
|
||||
$model->setCache($cache);
|
||||
return $model;
|
||||
});
|
||||
$container->set('anilist-model', static function ($container): Anilist\Model {
|
||||
$requestBuilder = new Anilist\AnilistRequestBuilder();
|
||||
$requestBuilder->setLogger($container->getLogger('anilist-request'));
|
||||
|
||||
$listItem = new Anilist\ListItem();
|
||||
$listItem->setContainer($container);
|
||||
$listItem->setRequestBuilder($requestBuilder);
|
||||
|
||||
$model = new Anilist\Model($listItem);
|
||||
$model->setContainer($container);
|
||||
$model->setRequestBuilder($requestBuilder);
|
||||
|
||||
return $model;
|
||||
});
|
||||
$container->set('settings-model', static function($container): Model\Settings {
|
||||
$model = new Model\Settings($container->get('config'));
|
||||
$model->setContainer($container);
|
||||
return $model;
|
||||
});
|
||||
|
||||
$container->set('auth', fn ($container) => new Kitsu\Auth($container));
|
||||
|
||||
$container->set('url-generator', fn ($container) => new UrlGenerator($container));
|
||||
|
||||
$container->set('util', fn ($container) => new Util($container));
|
||||
|
||||
return $container;
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ namespace Aviat\AnimeClient\Command;
|
||||
|
||||
use Aviat\Ion\Di\Exception\ContainerException;
|
||||
use Aviat\Ion\Di\Exception\NotFoundException;
|
||||
use function Aviat\AnimeClient\clearCache;
|
||||
|
||||
/**
|
||||
* Clears the API Cache
|
||||
@ -36,8 +37,17 @@ final class CacheClear extends BaseCommand {
|
||||
{
|
||||
$this->setContainer($this->setupContainer());
|
||||
|
||||
$this->container->get('cache')->clear();
|
||||
$cache = $this->container->get('cache');
|
||||
|
||||
$this->echoBox('API Cache has been cleared.');
|
||||
$cleared = clearCache($cache);
|
||||
|
||||
if ($cleared)
|
||||
{
|
||||
$this->echoBox('API Cache has been cleared.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->echoErrorBox('Failed to clear cache.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,10 @@
|
||||
|
||||
namespace Aviat\AnimeClient\Command;
|
||||
|
||||
use Aviat\AnimeClient\API\Kitsu;
|
||||
use Aviat\Ion\Di\Exception\ContainerException;
|
||||
use Aviat\Ion\Di\Exception\NotFoundException;
|
||||
use function Aviat\AnimeClient\clearCache;
|
||||
|
||||
/**
|
||||
* Clears the API Cache
|
||||
@ -35,30 +37,25 @@ final class CachePrime extends BaseCommand {
|
||||
public function execute(array $args, array $options = []): void
|
||||
{
|
||||
$this->setContainer($this->setupContainer());
|
||||
|
||||
$cache = $this->container->get('cache');
|
||||
|
||||
// Save the user id, if it exists, for priming the cache
|
||||
$userIdItem = $cache->getItem('kitsu-auth-token');
|
||||
$userId = $userIdItem->isHit() ? $userIdItem->get() : null;
|
||||
|
||||
$cache->clear();
|
||||
$cleared = clearCache($cache);
|
||||
if ( ! $cleared)
|
||||
{
|
||||
$this->echoErrorBox('Failed to clear cache.');
|
||||
return;
|
||||
}
|
||||
|
||||
$this->echoBox('Cache cleared, re-priming...');
|
||||
|
||||
if ($userId !== NULL)
|
||||
{
|
||||
$userIdItem = $cache->getItem('kitsu-auth-token');
|
||||
$userIdItem->set($userId);
|
||||
$userIdItem->save();
|
||||
}
|
||||
|
||||
$kitsuModel = $this->container->get('kitsu-model');
|
||||
|
||||
// Prime anime list cache
|
||||
// Prime anime list and history cache
|
||||
$kitsuModel->getAnimeHistory();
|
||||
$kitsuModel->getFullOrganizedAnimeList();
|
||||
|
||||
// Prime manga list cache
|
||||
$kitsuModel->getMangaHistory();
|
||||
$kitsuModel->getFullOrganizedMangaList();
|
||||
|
||||
$this->echoBox('API Cache has been primed.');
|
||||
|
@ -16,16 +16,16 @@
|
||||
|
||||
namespace Aviat\AnimeClient;
|
||||
|
||||
use Aviat\AnimeClient\Enum\EventType;
|
||||
use function Aviat\Ion\_dir;
|
||||
|
||||
use Aviat\AnimeClient\Enum\EventType;
|
||||
use Aura\Router\Generator;
|
||||
use Aura\Session\Segment;
|
||||
use Aviat\AnimeClient\API\Kitsu\Auth;
|
||||
use Aviat\Ion\ConfigInterface;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
|
||||
use Aviat\Ion\Di\{
|
||||
ContainerAware,
|
||||
@ -53,9 +53,9 @@ class Controller {
|
||||
|
||||
/**
|
||||
* Cache manager
|
||||
* @var CacheItemPoolInterface
|
||||
* @var CacheInterface
|
||||
*/
|
||||
protected CacheItemPoolInterface $cache;
|
||||
protected CacheInterface $cache;
|
||||
|
||||
/**
|
||||
* The global configuration object
|
||||
@ -134,8 +134,9 @@ class Controller {
|
||||
'urlGenerator' => $urlGenerator,
|
||||
];
|
||||
|
||||
Event::on(EventType::CLEAR_CACHE, fn () => $this->emptyCache());
|
||||
Event::on(EventType::RESET_CACHE_KEY, fn (string $key) => $this->removeCacheItem($key));
|
||||
// Set up 'global' events
|
||||
Event::on(EventType::CLEAR_CACHE, fn () => clearCache($this->cache));
|
||||
Event::on(EventType::RESET_CACHE_KEY, fn (string $key) => $this->cache->delete($key));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -435,15 +436,5 @@ class Controller {
|
||||
(new HttpView($this->container))->redirect($url, $code);
|
||||
exit();
|
||||
}
|
||||
|
||||
private function emptyCache(): void
|
||||
{
|
||||
$this->cache->emptyCache();
|
||||
}
|
||||
|
||||
private function removeCacheItem(string $key): void
|
||||
{
|
||||
$this->cache->deleteItem($key);
|
||||
}
|
||||
}
|
||||
// End of BaseController.php
|
Loading…
Reference in New Issue
Block a user