Compare commits
4 Commits
05c50387f6
...
545c495869
Author | SHA1 | Date | |
---|---|---|---|
545c495869 | |||
4131a019ca | |||
c4fb095eba | |||
e4018c269f |
2
.gitignore
vendored
2
.gitignore
vendored
@ -147,3 +147,5 @@ public/images/characters/**
|
|||||||
public/images/people/**
|
public/images/people/**
|
||||||
public/mal_mappings.json
|
public/mal_mappings.json
|
||||||
.phpunit.result.cache
|
.phpunit.result.cache
|
||||||
|
|
||||||
|
.is-dev
|
@ -25,10 +25,11 @@ use Aviat\AnimeClient\API\{
|
|||||||
Kitsu\KitsuRequestBuilder
|
Kitsu\KitsuRequestBuilder
|
||||||
};
|
};
|
||||||
use Aviat\AnimeClient\Model;
|
use Aviat\AnimeClient\Model;
|
||||||
use Aviat\Banker\Pool;
|
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\{Response, ServerRequestFactory};
|
use Laminas\Diactoros\{Response, ServerRequestFactory};
|
||||||
use Monolog\Handler\RotatingFileHandler;
|
use Monolog\Handler\RotatingFileHandler;
|
||||||
use Monolog\Logger;
|
use Monolog\Logger;
|
||||||
@ -64,10 +65,10 @@ return static function (array $configArray = []): Container {
|
|||||||
$container->set('config', fn () => new Config($configArray));
|
$container->set('config', fn () => new Config($configArray));
|
||||||
|
|
||||||
// Create Cache Object
|
// Create Cache Object
|
||||||
$container->set('cache', static function(ContainerInterface $container): Pool {
|
$container->set('cache', static function(ContainerInterface $container): CacheInterface {
|
||||||
$logger = $container->getLogger();
|
$logger = $container->getLogger();
|
||||||
$config = $container->get('config')->get('cache');
|
$config = $container->get('config')->get('cache');
|
||||||
return new Pool($config, $logger);
|
return new Teller($config, $logger);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create Aura Router Object
|
// Create Aura Router Object
|
||||||
@ -113,7 +114,7 @@ return static function (array $configArray = []): Container {
|
|||||||
|
|
||||||
// Models
|
// Models
|
||||||
$container->set('kitsu-model', static function(ContainerInterface $container): Kitsu\Model {
|
$container->set('kitsu-model', static function(ContainerInterface $container): Kitsu\Model {
|
||||||
$requestBuilder = new KitsuRequestBuilder();
|
$requestBuilder = new KitsuRequestBuilder($container);
|
||||||
$requestBuilder->setLogger($container->getLogger('kitsu-request'));
|
$requestBuilder->setLogger($container->getLogger('kitsu-request'));
|
||||||
|
|
||||||
$listItem = new Kitsu\ListItem();
|
$listItem = new Kitsu\ListItem();
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
# See https://git.timshomepage.net/aviat/banker for more information
|
# 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
|
# Null cache driver means no caching
|
||||||
driver = "redis"
|
driver = "redis"
|
||||||
|
|
||||||
|
5
app/views/settings/_field.php
Normal file
5
app/views/settings/_field.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<article>
|
||||||
|
<label for="<?= $fieldName ?>"><?= $field['title'] ?></label><br />
|
||||||
|
<small><?= $field['description'] ?></small><br />
|
||||||
|
<?= $helper->field($fieldName, $field); ?>
|
||||||
|
</article>
|
@ -6,19 +6,19 @@
|
|||||||
?>
|
?>
|
||||||
|
|
||||||
<?php foreach ($fields as $name => $field): ?>
|
<?php foreach ($fields as $name => $field): ?>
|
||||||
<?php $fieldname = ($section === 'config' || $nestedPrefix !== 'config') ? "{$nestedPrefix}[{$name}]" : "{$nestedPrefix}[{$section}][{$name}]"; ?>
|
<?php
|
||||||
|
$fieldName = ($section === 'config' || $nestedPrefix !== 'config')
|
||||||
|
? "{$nestedPrefix}[{$name}]"
|
||||||
|
: "{$nestedPrefix}[{$section}][{$name}]";
|
||||||
|
?>
|
||||||
<?php if ($field['type'] === 'subfield'): ?>
|
<?php if ($field['type'] === 'subfield'): ?>
|
||||||
<section>
|
<section>
|
||||||
<h4><?= $field['title'] ?></h4>
|
<h4><?= $field['title'] ?></h4>
|
||||||
<?php include_once '_form.php'; ?>
|
<?php include '_subfield.php'; ?>
|
||||||
</section>
|
</section>
|
||||||
<?php elseif ( ! empty($field['display'])): ?>
|
<?php elseif ( ! empty($field['display'])): ?>
|
||||||
<article>
|
<?php include '_field.php' ?>
|
||||||
<label for="<?= $fieldname ?>"><?= $field['title'] ?></label><br />
|
|
||||||
<small><?= $field['description'] ?></small><br />
|
|
||||||
<?= $helper->field($fieldname, $field); ?>
|
|
||||||
</article>
|
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php $hiddenFields[] = $helper->field($fieldname, $field); ?>
|
<?php $hiddenFields[] = $helper->field($fieldName, $field); ?>
|
||||||
<?php endif ?>
|
<?php endif ?>
|
||||||
<?php endforeach ?>
|
<?php endforeach ?>
|
||||||
|
20
app/views/settings/_subfield.php
Normal file
20
app/views/settings/_subfield.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
// Higher scoped variables:
|
||||||
|
// $field
|
||||||
|
// $fields
|
||||||
|
// $hiddenFields
|
||||||
|
// $nestedPrefix
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php foreach ($field['fields'] as $name => $field): ?>
|
||||||
|
<?php
|
||||||
|
$fieldName = ($section === 'config' || $nestedPrefix !== 'config')
|
||||||
|
? "{$nestedPrefix}[{$name}]"
|
||||||
|
: "{$nestedPrefix}[{$section}][{$name}]";
|
||||||
|
?>
|
||||||
|
<?php if ( ! empty($field['display'])): ?>
|
||||||
|
<?php include '_field.php' ?>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php $hiddenFields[] = $helper->field($fieldName, $field); ?>
|
||||||
|
<?php endif ?>
|
||||||
|
<?php endforeach ?>
|
@ -38,7 +38,7 @@
|
|||||||
"aura/html": "^2.5.0",
|
"aura/html": "^2.5.0",
|
||||||
"aura/router": "^3.1.0",
|
"aura/router": "^3.1.0",
|
||||||
"aura/session": "^2.1.0",
|
"aura/session": "^2.1.0",
|
||||||
"aviat/banker": "^2.0.0",
|
"aviat/banker": "^3.1.1",
|
||||||
"aviat/query": "^3.0.0",
|
"aviat/query": "^3.0.0",
|
||||||
"danielstjules/stringy": "^3.1.0",
|
"danielstjules/stringy": "^3.1.0",
|
||||||
"ext-dom": "*",
|
"ext-dom": "*",
|
||||||
|
@ -27,7 +27,7 @@ setlocale(LC_CTYPE, 'en_US');
|
|||||||
// Load composer autoloader
|
// Load composer autoloader
|
||||||
require_once __DIR__ . '/vendor/autoload.php';
|
require_once __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
if (array_key_exists('ENV', $_SERVER) && $_SERVER['ENV'] === 'development')
|
if (file_exists('.is-dev'))
|
||||||
{
|
{
|
||||||
$whoops = new Run;
|
$whoops = new Run;
|
||||||
$whoops->pushHandler(new PrettyPageHandler);
|
$whoops->pushHandler(new PrettyPageHandler);
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\API;
|
namespace Aviat\AnimeClient\API;
|
||||||
|
|
||||||
use Aviat\Banker\Pool;
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
use Psr\SimpleCache\InvalidArgumentException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper methods for dealing with the Cache
|
* Helper methods for dealing with the Cache
|
||||||
@ -24,17 +25,17 @@ use Aviat\Banker\Pool;
|
|||||||
trait CacheTrait {
|
trait CacheTrait {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Pool
|
* @var CacheInterface
|
||||||
*/
|
*/
|
||||||
protected Pool $cache;
|
protected CacheInterface $cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject the cache object
|
* Inject the cache object
|
||||||
*
|
*
|
||||||
* @param Pool $cache
|
* @param CacheInterface $cache
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setCache(Pool $cache): self
|
public function setCache(CacheInterface $cache): self
|
||||||
{
|
{
|
||||||
$this->cache = $cache;
|
$this->cache = $cache;
|
||||||
return $this;
|
return $this;
|
||||||
@ -43,13 +44,41 @@ trait CacheTrait {
|
|||||||
/**
|
/**
|
||||||
* Get the cache object if it exists
|
* Get the cache object if it exists
|
||||||
*
|
*
|
||||||
* @return Pool
|
* @return CacheInterface
|
||||||
*/
|
*/
|
||||||
public function getCache(): Pool
|
public function getCache(): CacheInterface
|
||||||
{
|
{
|
||||||
return $this->cache;
|
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
|
* 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
|
public function getHashForMethodCall($object, string $method, array $args = []): string
|
||||||
{
|
{
|
||||||
$keyObj = [
|
$keyObj = [
|
||||||
'class' => \get_class($object),
|
'class' => get_class($object),
|
||||||
'method' => $method,
|
'method' => $method,
|
||||||
'args' => $args,
|
'args' => $args,
|
||||||
];
|
];
|
||||||
|
@ -28,6 +28,8 @@ final class Kitsu {
|
|||||||
public const AUTH_TOKEN_CACHE_KEY = 'kitsu-auth-token';
|
public const AUTH_TOKEN_CACHE_KEY = 'kitsu-auth-token';
|
||||||
public const AUTH_TOKEN_EXP_CACHE_KEY = 'kitsu-auth-token-expires';
|
public const AUTH_TOKEN_EXP_CACHE_KEY = 'kitsu-auth-token-expires';
|
||||||
public const AUTH_TOKEN_REFRESH_CACHE_KEY = 'kitsu-auth-token-refresh';
|
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
|
* 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 Aura\Session\Segment;
|
||||||
|
|
||||||
use Aviat\Banker\Exception\InvalidArgumentException;
|
|
||||||
use const Aviat\AnimeClient\SESSION_SEGMENT;
|
use const Aviat\AnimeClient\SESSION_SEGMENT;
|
||||||
|
|
||||||
use Aviat\AnimeClient\API\{
|
use Aviat\AnimeClient\API\{
|
||||||
@ -29,8 +28,9 @@ use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
|
|||||||
use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException};
|
use Aviat\Ion\Di\Exception\{ContainerException, NotFoundException};
|
||||||
use Aviat\Ion\Event;
|
use Aviat\Ion\Event;
|
||||||
|
|
||||||
|
use Psr\SimpleCache\InvalidArgumentException;
|
||||||
|
|
||||||
use Throwable;
|
use Throwable;
|
||||||
use const PHP_SAPI;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kitsu API Authentication
|
* Kitsu API Authentication
|
||||||
@ -77,7 +77,6 @@ final class Auth {
|
|||||||
*
|
*
|
||||||
* @param string $password
|
* @param string $password
|
||||||
* @return boolean
|
* @return boolean
|
||||||
* @throws InvalidArgumentException
|
|
||||||
* @throws Throwable
|
* @throws Throwable
|
||||||
*/
|
*/
|
||||||
public function authenticate(string $password): bool
|
public function authenticate(string $password): bool
|
||||||
@ -95,12 +94,11 @@ final class Auth {
|
|||||||
*
|
*
|
||||||
* @param string $refreshToken
|
* @param string $refreshToken
|
||||||
* @return boolean
|
* @return boolean
|
||||||
* @throws InvalidArgumentException
|
* @throws Throwable|InvalidArgumentException
|
||||||
* @throws Throwable
|
|
||||||
*/
|
*/
|
||||||
public function reAuthenticate(?string $refreshToken): bool
|
public function reAuthenticate(?string $refreshToken): bool
|
||||||
{
|
{
|
||||||
$refreshToken ??= $this->getAuthToken();
|
$refreshToken ??= $this->getRefreshToken();
|
||||||
|
|
||||||
if (empty($refreshToken))
|
if (empty($refreshToken))
|
||||||
{
|
{
|
||||||
@ -116,6 +114,7 @@ final class Auth {
|
|||||||
* Check whether the current user is authenticated
|
* Check whether the current user is authenticated
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function isAuthenticated(): bool
|
public function isAuthenticated(): bool
|
||||||
{
|
{
|
||||||
@ -136,87 +135,59 @@ final class Auth {
|
|||||||
* Retrieve the authentication token from the session
|
* Retrieve the authentication token from the session
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
private function getAuthToken(): ?string
|
public function getAuthToken(): ?string
|
||||||
{
|
{
|
||||||
$now = time();
|
return $this->segment->get('auth_token', NULL)
|
||||||
|
?? $this->cache->get(K::AUTH_TOKEN_CACHE_KEY, NULL);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the refresh token
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
* @throws InvalidArgumentException
|
||||||
|
*/
|
||||||
private function getRefreshToken(): ?string
|
private function getRefreshToken(): ?string
|
||||||
{
|
{
|
||||||
return (PHP_SAPI === 'cli')
|
return $this->segment->get('refresh_token')
|
||||||
? $this->cacheGet(K::AUTH_TOKEN_REFRESH_CACHE_KEY, NULL)
|
?? $this->cache->get(K::AUTH_TOKEN_REFRESH_CACHE_KEY, NULL);
|
||||||
: $this->segment->get('refresh_token');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
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'];
|
$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
|
// Set the refresh token in the cache
|
||||||
$cacheItem = $this->cache->getItem(K::AUTH_TOKEN_REFRESH_CACHE_KEY);
|
$saved = $this->cache->setMultiple([
|
||||||
$cacheItem->set($auth['refresh_token']);
|
K::AUTH_TOKEN_CACHE_KEY => $auth['access_token'],
|
||||||
$cacheItem->save();
|
K::AUTH_TOKEN_EXP_CACHE_KEY => $expire_time,
|
||||||
|
K::AUTH_TOKEN_REFRESH_CACHE_KEY => $auth['refresh_token'],
|
||||||
|
]);
|
||||||
|
|
||||||
// Set the session values
|
// Set the session values
|
||||||
|
if ($saved)
|
||||||
|
{
|
||||||
$this->segment->set('auth_token', $auth['access_token']);
|
$this->segment->set('auth_token', $auth['access_token']);
|
||||||
$this->segment->set('auth_token_expires', $expire_time);
|
$this->segment->set('auth_token_expires', $expire_time);
|
||||||
$this->segment->set('refresh_token', $auth['refresh_token']);
|
$this->segment->set('refresh_token', $auth['refresh_token']);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
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
|
// End of KitsuAuth.php
|
@ -16,10 +16,26 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\API\Kitsu;
|
namespace Aviat\AnimeClient\API\Kitsu;
|
||||||
|
|
||||||
|
use const Aviat\AnimeClient\SESSION_SEGMENT;
|
||||||
use const Aviat\AnimeClient\USER_AGENT;
|
use const Aviat\AnimeClient\USER_AGENT;
|
||||||
|
|
||||||
|
use function Amp\Promise\wait;
|
||||||
|
use function Aviat\AnimeClient\getResponse;
|
||||||
|
|
||||||
|
use Amp\Http\Client\Request;
|
||||||
|
use Amp\Http\Client\Response;
|
||||||
use Aviat\AnimeClient\API\APIRequestBuilder;
|
use Aviat\AnimeClient\API\APIRequestBuilder;
|
||||||
|
use Aviat\AnimeClient\API\FailedResponseException;
|
||||||
|
use Aviat\AnimeClient\API\Kitsu as K;
|
||||||
|
use Aviat\AnimeClient\Enum\EventType;
|
||||||
|
use Aviat\Ion\Di\ContainerAware;
|
||||||
|
use Aviat\Ion\Di\ContainerInterface;
|
||||||
|
use Aviat\Ion\Event;
|
||||||
|
use Aviat\Ion\Json;
|
||||||
|
use Aviat\Ion\JsonException;
|
||||||
|
|
||||||
final class KitsuRequestBuilder extends APIRequestBuilder {
|
final class KitsuRequestBuilder extends APIRequestBuilder {
|
||||||
|
use ContainerAware;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base url for api requests
|
* The base url for api requests
|
||||||
@ -39,4 +55,217 @@ final class KitsuRequestBuilder extends APIRequestBuilder {
|
|||||||
'CLIENT_ID' => 'dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd',
|
'CLIENT_ID' => 'dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd',
|
||||||
'CLIENT_SECRET' => '54d7307928f63414defd96399fc31ba847961ceaecef3a5fd93144e960c0e151',
|
'CLIENT_SECRET' => '54d7307928f63414defd96399fc31ba847961ceaecef3a5fd93144e960c0e151',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function __construct(ContainerInterface $container)
|
||||||
|
{
|
||||||
|
$this->setContainer($container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a request object
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param string $url
|
||||||
|
* @param array $options
|
||||||
|
* @return Request
|
||||||
|
*/
|
||||||
|
public function setUpRequest(string $type, string $url, array $options = []): Request
|
||||||
|
{
|
||||||
|
$request = $this->newRequest($type, $url);
|
||||||
|
|
||||||
|
$sessionSegment = $this->getContainer()
|
||||||
|
->get('session')
|
||||||
|
->getSegment(SESSION_SEGMENT);
|
||||||
|
|
||||||
|
$cache = $this->getContainer()->get('cache');
|
||||||
|
$token = null;
|
||||||
|
|
||||||
|
if ($cache->has(K::AUTH_TOKEN_CACHE_KEY))
|
||||||
|
{
|
||||||
|
$token = $cache->get(K::AUTH_TOKEN_CACHE_KEY);
|
||||||
|
}
|
||||||
|
else if ($url !== K::AUTH_URL && $sessionSegment->get('auth_token') !== NULL)
|
||||||
|
{
|
||||||
|
$token = $sessionSegment->get('auth_token');
|
||||||
|
if ( ! (empty($token) || $cache->has(K::AUTH_TOKEN_CACHE_KEY)))
|
||||||
|
{
|
||||||
|
$cache->set(K::AUTH_TOKEN_CACHE_KEY, $token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($token !== NULL)
|
||||||
|
{
|
||||||
|
$request = $request->setAuth('bearer', $token);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('form_params', $options))
|
||||||
|
{
|
||||||
|
$request = $request->setFormFields($options['form_params']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('query', $options))
|
||||||
|
{
|
||||||
|
$request = $request->setQuery($options['query']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('body', $options))
|
||||||
|
{
|
||||||
|
$request = $request->setJsonBody($options['body']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists('headers', $options))
|
||||||
|
{
|
||||||
|
$request = $request->setHeaders($options['headers']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $request->getFullRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove some boilerplate for get requests
|
||||||
|
*
|
||||||
|
* @param mixed ...$args
|
||||||
|
* @throws Throwable
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getRequest(...$args): array
|
||||||
|
{
|
||||||
|
return $this->request('GET', ...$args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove some boilerplate for patch requests
|
||||||
|
*
|
||||||
|
* @param mixed ...$args
|
||||||
|
* @throws Throwable
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function patchRequest(...$args): array
|
||||||
|
{
|
||||||
|
return $this->request('PATCH', ...$args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove some boilerplate for post requests
|
||||||
|
*
|
||||||
|
* @param mixed ...$args
|
||||||
|
* @throws Throwable
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function postRequest(...$args): array
|
||||||
|
{
|
||||||
|
$logger = NULL;
|
||||||
|
if ($this->getContainer())
|
||||||
|
{
|
||||||
|
$logger = $this->container->getLogger('kitsu-request');
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = $this->getResponse('POST', ...$args);
|
||||||
|
$validResponseCodes = [200, 201];
|
||||||
|
|
||||||
|
if ( ! in_array($response->getStatus(), $validResponseCodes, TRUE) && $logger)
|
||||||
|
{
|
||||||
|
$logger->warning('Non 2xx response for POST api call', $response->getBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON::decode(wait($response->getBody()->buffer()), TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove some boilerplate for delete requests
|
||||||
|
*
|
||||||
|
* @param mixed ...$args
|
||||||
|
* @throws Throwable
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function deleteRequest(...$args): bool
|
||||||
|
{
|
||||||
|
$response = $this->getResponse('DELETE', ...$args);
|
||||||
|
return ($response->getStatus() === 204);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a request
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param string $url
|
||||||
|
* @param array $options
|
||||||
|
* @return Response
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
|
public function getResponse(string $type, string $url, array $options = []): Response
|
||||||
|
{
|
||||||
|
$logger = NULL;
|
||||||
|
if ($this->getContainer())
|
||||||
|
{
|
||||||
|
$logger = $this->container->getLogger('kitsu-request');
|
||||||
|
}
|
||||||
|
|
||||||
|
$request = $this->setUpRequest($type, $url, $options);
|
||||||
|
|
||||||
|
$response = getResponse($request);
|
||||||
|
|
||||||
|
if ($logger)
|
||||||
|
{
|
||||||
|
$logger->debug('Kitsu API Response', [
|
||||||
|
'response_status' => $response->getStatus(),
|
||||||
|
'request_headers' => $response->getOriginalRequest()->getHeaders(),
|
||||||
|
'response_headers' => $response->getHeaders()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a request
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param string $url
|
||||||
|
* @param array $options
|
||||||
|
* @throws JsonException
|
||||||
|
* @throws FailedResponseException
|
||||||
|
* @throws Throwable
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function request(string $type, string $url, array $options = []): array
|
||||||
|
{
|
||||||
|
$logger = NULL;
|
||||||
|
if ($this->getContainer())
|
||||||
|
{
|
||||||
|
$logger = $this->container->getLogger('kitsu-request');
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = $this->getResponse($type, $url, $options);
|
||||||
|
$statusCode = $response->getStatus();
|
||||||
|
|
||||||
|
// Check for requests that are unauthorized
|
||||||
|
if ($statusCode === 401 || $statusCode === 403)
|
||||||
|
{
|
||||||
|
Event::emit(EventType::UNAUTHORIZED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any other type of failed request
|
||||||
|
if ($statusCode > 299 || $statusCode < 200)
|
||||||
|
{
|
||||||
|
if ($logger)
|
||||||
|
{
|
||||||
|
$logger->warning('Non 2xx response for api call', (array)$response);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new FailedResponseException('Failed to get the proper response from the API');
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Json::decode(wait($response->getBody()->buffer()));
|
||||||
|
}
|
||||||
|
catch (JsonException $e)
|
||||||
|
{
|
||||||
|
print_r($e);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -16,25 +16,7 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\API\Kitsu;
|
namespace Aviat\AnimeClient\API\Kitsu;
|
||||||
|
|
||||||
use Aviat\AnimeClient\Enum\EventType;
|
|
||||||
use function in_array;
|
|
||||||
use const PHP_SAPI;
|
|
||||||
use const Aviat\AnimeClient\SESSION_SEGMENT;
|
|
||||||
|
|
||||||
use function Amp\Promise\wait;
|
|
||||||
use function Aviat\AnimeClient\getResponse;
|
|
||||||
|
|
||||||
use Amp\Http\Client\Request;
|
|
||||||
use Amp\Http\Client\Response;
|
|
||||||
use Aviat\AnimeClient\API\{FailedResponseException, Kitsu as K};
|
|
||||||
use Aviat\Ion\Event;
|
|
||||||
use Aviat\Ion\Json;
|
|
||||||
use Aviat\Ion\JsonException;
|
|
||||||
|
|
||||||
use Throwable;
|
|
||||||
|
|
||||||
trait KitsuTrait {
|
trait KitsuTrait {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The request builder for the Kitsu API
|
* The request builder for the Kitsu API
|
||||||
* @var KitsuRequestBuilder
|
* @var KitsuRequestBuilder
|
||||||
@ -52,212 +34,4 @@ trait KitsuTrait {
|
|||||||
$this->requestBuilder = $requestBuilder;
|
$this->requestBuilder = $requestBuilder;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a request object
|
|
||||||
*
|
|
||||||
* @param string $type
|
|
||||||
* @param string $url
|
|
||||||
* @param array $options
|
|
||||||
* @return Request
|
|
||||||
*/
|
|
||||||
public function setUpRequest(string $type, string $url, array $options = []): Request
|
|
||||||
{
|
|
||||||
$request = $this->requestBuilder->newRequest($type, $url);
|
|
||||||
|
|
||||||
$sessionSegment = $this->getContainer()
|
|
||||||
->get('session')
|
|
||||||
->getSegment(SESSION_SEGMENT);
|
|
||||||
|
|
||||||
$cache = $this->getContainer()->get('cache');
|
|
||||||
$cacheItem = $cache->getItem(K::AUTH_TOKEN_CACHE_KEY);
|
|
||||||
$token = null;
|
|
||||||
|
|
||||||
if (PHP_SAPI === 'cli' && $cacheItem->isHit())
|
|
||||||
{
|
|
||||||
$token = $cacheItem->get();
|
|
||||||
}
|
|
||||||
else if ($url !== K::AUTH_URL && $sessionSegment->get('auth_token') !== NULL)
|
|
||||||
{
|
|
||||||
$token = $sessionSegment->get('auth_token');
|
|
||||||
if ( ! (empty($token) || $cacheItem->isHit()))
|
|
||||||
{
|
|
||||||
$cacheItem->set($token);
|
|
||||||
$cacheItem->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($token !== NULL)
|
|
||||||
{
|
|
||||||
$request = $request->setAuth('bearer', $token);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists('form_params', $options))
|
|
||||||
{
|
|
||||||
$request = $request->setFormFields($options['form_params']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists('query', $options))
|
|
||||||
{
|
|
||||||
$request = $request->setQuery($options['query']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists('body', $options))
|
|
||||||
{
|
|
||||||
$request = $request->setJsonBody($options['body']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists('headers', $options))
|
|
||||||
{
|
|
||||||
$request = $request->setHeaders($options['headers']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $request->getFullRequest();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make a request
|
|
||||||
*
|
|
||||||
* @param string $type
|
|
||||||
* @param string $url
|
|
||||||
* @param array $options
|
|
||||||
* @return Response
|
|
||||||
* @throws Throwable
|
|
||||||
*/
|
|
||||||
private function getResponse(string $type, string $url, array $options = []): Response
|
|
||||||
{
|
|
||||||
$logger = NULL;
|
|
||||||
if ($this->getContainer())
|
|
||||||
{
|
|
||||||
$logger = $this->container->getLogger('kitsu-request');
|
|
||||||
}
|
|
||||||
|
|
||||||
$request = $this->setUpRequest($type, $url, $options);
|
|
||||||
|
|
||||||
$response = getResponse($request);
|
|
||||||
|
|
||||||
if ($logger)
|
|
||||||
{
|
|
||||||
$logger->debug('Kitsu API Response', [
|
|
||||||
'response_status' => $response->getStatus(),
|
|
||||||
'request_headers' => $response->getOriginalRequest()->getHeaders(),
|
|
||||||
'response_headers' => $response->getHeaders()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make a request
|
|
||||||
*
|
|
||||||
* @param string $type
|
|
||||||
* @param string $url
|
|
||||||
* @param array $options
|
|
||||||
* @throws JsonException
|
|
||||||
* @throws FailedResponseException
|
|
||||||
* @throws Throwable
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function request(string $type, string $url, array $options = []): array
|
|
||||||
{
|
|
||||||
$logger = NULL;
|
|
||||||
if ($this->getContainer())
|
|
||||||
{
|
|
||||||
$logger = $this->container->getLogger('kitsu-request');
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = $this->getResponse($type, $url, $options);
|
|
||||||
$statusCode = $response->getStatus();
|
|
||||||
|
|
||||||
// Check for requests that are unauthorized
|
|
||||||
if ($statusCode === 401 || $statusCode === 403)
|
|
||||||
{
|
|
||||||
Event::emit(EventType::UNAUTHORIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Any other type of failed request
|
|
||||||
if ($statusCode > 299 || $statusCode < 200)
|
|
||||||
{
|
|
||||||
if ($logger)
|
|
||||||
{
|
|
||||||
$logger->warning('Non 2xx response for api call', (array)$response);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new FailedResponseException('Failed to get the proper response from the API');
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return Json::decode(wait($response->getBody()->buffer()));
|
|
||||||
}
|
|
||||||
catch (JsonException $e)
|
|
||||||
{
|
|
||||||
print_r($e);
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove some boilerplate for get requests
|
|
||||||
*
|
|
||||||
* @param mixed ...$args
|
|
||||||
* @throws Throwable
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function getRequest(...$args): array
|
|
||||||
{
|
|
||||||
return $this->request('GET', ...$args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove some boilerplate for patch requests
|
|
||||||
*
|
|
||||||
* @param mixed ...$args
|
|
||||||
* @throws Throwable
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function patchRequest(...$args): array
|
|
||||||
{
|
|
||||||
return $this->request('PATCH', ...$args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove some boilerplate for post requests
|
|
||||||
*
|
|
||||||
* @param mixed ...$args
|
|
||||||
* @throws Throwable
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function postRequest(...$args): array
|
|
||||||
{
|
|
||||||
$logger = NULL;
|
|
||||||
if ($this->getContainer())
|
|
||||||
{
|
|
||||||
$logger = $this->container->getLogger('kitsu-request');
|
|
||||||
}
|
|
||||||
|
|
||||||
$response = $this->getResponse('POST', ...$args);
|
|
||||||
$validResponseCodes = [200, 201];
|
|
||||||
|
|
||||||
if ( ! in_array($response->getStatus(), $validResponseCodes, TRUE) && $logger)
|
|
||||||
{
|
|
||||||
$logger->warning('Non 201 response for POST api call', $response->getBody());
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSON::decode(wait($response->getBody()->buffer()), TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove some boilerplate for delete requests
|
|
||||||
*
|
|
||||||
* @param mixed ...$args
|
|
||||||
* @throws Throwable
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
protected function deleteRequest(...$args): bool
|
|
||||||
{
|
|
||||||
$response = $this->getResponse('DELETE', ...$args);
|
|
||||||
return ($response->getStatus() === 204);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -18,7 +18,6 @@ namespace Aviat\AnimeClient\API\Kitsu;
|
|||||||
|
|
||||||
use Aviat\Ion\Di\Exception\ContainerException;
|
use Aviat\Ion\Di\Exception\ContainerException;
|
||||||
use Aviat\Ion\Di\Exception\NotFoundException;
|
use Aviat\Ion\Di\Exception\NotFoundException;
|
||||||
use const Aviat\AnimeClient\SESSION_SEGMENT;
|
|
||||||
|
|
||||||
use function Amp\Promise\wait;
|
use function Amp\Promise\wait;
|
||||||
use function Aviat\AnimeClient\getResponse;
|
use function Aviat\AnimeClient\getResponse;
|
||||||
@ -78,7 +77,7 @@ final class ListItem extends AbstractListItem {
|
|||||||
|
|
||||||
$request = $this->requestBuilder->newRequest('POST', 'library-entries');
|
$request = $this->requestBuilder->newRequest('POST', 'library-entries');
|
||||||
|
|
||||||
if ($authHeader !== FALSE)
|
if ($authHeader !== NULL)
|
||||||
{
|
{
|
||||||
$request = $request->setHeader('Authorization', $authHeader);
|
$request = $request->setHeader('Authorization', $authHeader);
|
||||||
}
|
}
|
||||||
@ -97,7 +96,7 @@ final class ListItem extends AbstractListItem {
|
|||||||
$authHeader = $this->getAuthHeader();
|
$authHeader = $this->getAuthHeader();
|
||||||
$request = $this->requestBuilder->newRequest('DELETE', "library-entries/{$id}");
|
$request = $this->requestBuilder->newRequest('DELETE', "library-entries/{$id}");
|
||||||
|
|
||||||
if ($authHeader !== FALSE)
|
if ($authHeader !== NULL)
|
||||||
{
|
{
|
||||||
$request = $request->setHeader('Authorization', $authHeader);
|
$request = $request->setHeader('Authorization', $authHeader);
|
||||||
}
|
}
|
||||||
@ -119,7 +118,7 @@ final class ListItem extends AbstractListItem {
|
|||||||
'include' => 'media,media.categories,media.mappings'
|
'include' => 'media,media.categories,media.mappings'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($authHeader !== FALSE)
|
if ($authHeader !== NULL)
|
||||||
{
|
{
|
||||||
$request = $request->setHeader('Authorization', $authHeader);
|
$request = $request->setHeader('Authorization', $authHeader);
|
||||||
}
|
}
|
||||||
@ -159,7 +158,7 @@ final class ListItem extends AbstractListItem {
|
|||||||
$request = $this->requestBuilder->newRequest('PATCH', "library-entries/{$id}")
|
$request = $this->requestBuilder->newRequest('PATCH', "library-entries/{$id}")
|
||||||
->setJsonBody($requestData);
|
->setJsonBody($requestData);
|
||||||
|
|
||||||
if ($authHeader !== FALSE)
|
if ($authHeader !== NULL)
|
||||||
{
|
{
|
||||||
$request = $request->setHeader('Authorization', $authHeader);
|
$request = $request->setHeader('Authorization', $authHeader);
|
||||||
}
|
}
|
||||||
@ -172,24 +171,15 @@ final class ListItem extends AbstractListItem {
|
|||||||
* @throws ContainerException
|
* @throws ContainerException
|
||||||
* @throws NotFoundException
|
* @throws NotFoundException
|
||||||
*/
|
*/
|
||||||
private function getAuthHeader()
|
private function getAuthHeader(): ?string
|
||||||
{
|
{
|
||||||
$cache = $this->getContainer()->get('cache');
|
$auth = $this->getContainer()->get('auth');
|
||||||
$cacheItem = $cache->getItem('kitsu-auth-token');
|
$token = $auth->getAuthToken();
|
||||||
$sessionSegment = $this->getContainer()
|
|
||||||
->get('session')
|
|
||||||
->getSegment(SESSION_SEGMENT);
|
|
||||||
|
|
||||||
if ($sessionSegment->get('auth_token') !== NULL) {
|
if ( ! empty($token)) {
|
||||||
$token = $sessionSegment->get('auth_token');
|
|
||||||
return "bearer {$token}";
|
return "bearer {$token}";
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cacheItem->isHit()) {
|
return NULL;
|
||||||
$token = $cacheItem->get();
|
|
||||||
return "bearer {$token}";
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -116,7 +116,7 @@ final class Model {
|
|||||||
public function authenticate(string $username, string $password)
|
public function authenticate(string $username, string $password)
|
||||||
{
|
{
|
||||||
// K::AUTH_URL
|
// K::AUTH_URL
|
||||||
$response = $this->getResponse('POST', K::AUTH_URL, [
|
$response = $this->requestBuilder->getResponse('POST', K::AUTH_URL, [
|
||||||
'headers' => [
|
'headers' => [
|
||||||
'accept' => NULL,
|
'accept' => NULL,
|
||||||
'Content-type' => 'application/x-www-form-urlencoded',
|
'Content-type' => 'application/x-www-form-urlencoded',
|
||||||
@ -182,6 +182,7 @@ final class Model {
|
|||||||
* @param string $username
|
* @param string $username
|
||||||
* @return string
|
* @return string
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
|
* @throws Throwable
|
||||||
*/
|
*/
|
||||||
public function getUserIdByUsername(string $username = NULL): string
|
public function getUserIdByUsername(string $username = NULL): string
|
||||||
{
|
{
|
||||||
@ -190,11 +191,8 @@ final class Model {
|
|||||||
$username = $this->getUsername();
|
$username = $this->getUsername();
|
||||||
}
|
}
|
||||||
|
|
||||||
$cacheItem = $this->cache->getItem(K::AUTH_USER_ID_KEY);
|
return $this->getCached(K::AUTH_USER_ID_KEY, function(string $username) {
|
||||||
|
$data = $this->requestBuilder->getRequest('users', [
|
||||||
if ( ! $cacheItem->isHit())
|
|
||||||
{
|
|
||||||
$data = $this->getRequest('users', [
|
|
||||||
'query' => [
|
'query' => [
|
||||||
'filter' => [
|
'filter' => [
|
||||||
'name' => $username
|
'name' => $username
|
||||||
@ -202,11 +200,8 @@ final class Model {
|
|||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$cacheItem->set($data['data'][0]['id']);
|
return $data['data'][0]['id'] ?? NULL;
|
||||||
$cacheItem->save();
|
}, [$username]);
|
||||||
}
|
|
||||||
|
|
||||||
return $cacheItem->get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -217,14 +212,14 @@ final class Model {
|
|||||||
*/
|
*/
|
||||||
public function getCharacter(string $slug): array
|
public function getCharacter(string $slug): array
|
||||||
{
|
{
|
||||||
return $this->getRequest('characters', [
|
return $this->requestBuilder->getRequest('characters', [
|
||||||
'query' => [
|
'query' => [
|
||||||
'filter' => [
|
'filter' => [
|
||||||
'slug' => $slug,
|
'slug' => $slug,
|
||||||
],
|
],
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'anime' => 'canonicalTitle,titles,slug,posterImage',
|
'anime' => 'canonicalTitle,abbreviatedTitles,titles,slug,posterImage',
|
||||||
'manga' => 'canonicalTitle,titles,slug,posterImage'
|
'manga' => 'canonicalTitle,abbreviatedTitles,titles,slug,posterImage'
|
||||||
],
|
],
|
||||||
'include' => 'castings.person,castings.media'
|
'include' => 'castings.person,castings.media'
|
||||||
]
|
]
|
||||||
@ -240,11 +235,7 @@ final class Model {
|
|||||||
*/
|
*/
|
||||||
public function getPerson(string $id): array
|
public function getPerson(string $id): array
|
||||||
{
|
{
|
||||||
$cacheItem = $this->cache->getItem("kitsu-person-{$id}");
|
return $this->getCached("kitsu-person-{$id}", fn () => $this->requestBuilder->getRequest("people/{$id}", [
|
||||||
|
|
||||||
if ( ! $cacheItem->isHit())
|
|
||||||
{
|
|
||||||
$data = $this->getRequest("people/{$id}", [
|
|
||||||
'query' => [
|
'query' => [
|
||||||
'filter' => [
|
'filter' => [
|
||||||
'id' => $id,
|
'id' => $id,
|
||||||
@ -259,12 +250,7 @@ final class Model {
|
|||||||
],
|
],
|
||||||
'include' => 'voices.mediaCharacter.media,voices.mediaCharacter.character,staff.media',
|
'include' => 'voices.mediaCharacter.media,voices.mediaCharacter.character,staff.media',
|
||||||
],
|
],
|
||||||
]);
|
]));
|
||||||
$cacheItem->set($data);
|
|
||||||
$cacheItem->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $cacheItem->get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -275,7 +261,7 @@ final class Model {
|
|||||||
*/
|
*/
|
||||||
public function getUserData(string $username): array
|
public function getUserData(string $username): array
|
||||||
{
|
{
|
||||||
return $this->getRequest('users', [
|
return $this->requestBuilder->getRequest('users', [
|
||||||
'query' => [
|
'query' => [
|
||||||
'filter' => [
|
'filter' => [
|
||||||
'name' => $username,
|
'name' => $username,
|
||||||
@ -312,7 +298,7 @@ final class Model {
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
$raw = $this->getRequest($type, $options);
|
$raw = $this->requestBuilder->getRequest($type, $options);
|
||||||
$raw['included'] = JsonAPI::organizeIncluded($raw['included']);
|
$raw['included'] = JsonAPI::organizeIncluded($raw['included']);
|
||||||
|
|
||||||
foreach ($raw['data'] as &$item)
|
foreach ($raw['data'] as &$item)
|
||||||
@ -357,7 +343,7 @@ final class Model {
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
$raw = $this->getRequest('mappings', $options);
|
$raw = $this->requestBuilder->getRequest('mappings', $options);
|
||||||
|
|
||||||
if ( ! array_key_exists('included', $raw))
|
if ( ! array_key_exists('included', $raw))
|
||||||
{
|
{
|
||||||
@ -397,12 +383,24 @@ final class Model {
|
|||||||
* @throws Throwable
|
* @throws Throwable
|
||||||
*/
|
*/
|
||||||
public function getAnimeHistory(): array
|
public function getAnimeHistory(): array
|
||||||
|
{
|
||||||
|
$key = K::ANIME_HISTORY_LIST_CACHE_KEY;
|
||||||
|
$list = $this->cache->get($key, NULL);
|
||||||
|
|
||||||
|
if ($list === NULL)
|
||||||
{
|
{
|
||||||
$raw = $this->getRawHistoryList('anime');
|
$raw = $this->getRawHistoryList('anime');
|
||||||
|
|
||||||
$organized = JsonAPI::organizeData($raw);
|
$organized = JsonAPI::organizeData($raw);
|
||||||
$organized = array_filter($organized, fn ($item) => array_key_exists('relationships', $item));
|
$organized = array_filter($organized, fn ($item) => array_key_exists('relationships', $item));
|
||||||
|
|
||||||
return (new AnimeHistoryTransformer())->transform($organized);
|
$list = (new AnimeHistoryTransformer())->transform($organized);
|
||||||
|
|
||||||
|
$this->cache->set($key, $list);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -426,9 +424,11 @@ final class Model {
|
|||||||
*/
|
*/
|
||||||
public function getAnimeList(string $status): array
|
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) ?? [];
|
$data = $this->getRawAnimeList($status) ?? [];
|
||||||
|
|
||||||
@ -454,11 +454,11 @@ final class Model {
|
|||||||
$keyed[$item['id']] = $item;
|
$keyed[$item['id']] = $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cacheItem->set($keyed);
|
$list = $keyed;
|
||||||
$cacheItem->save();
|
$this->cache->set($key, $list);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $cacheItem->get();
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -547,7 +547,7 @@ final class Model {
|
|||||||
'include' => 'mappings'
|
'include' => 'mappings'
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
$data = $this->getRequest("anime/{$kitsuAnimeId}", $options);
|
$data = $this->requestBuilder->getRequest("anime/{$kitsuAnimeId}", $options);
|
||||||
|
|
||||||
if ( ! array_key_exists('included', $data))
|
if ( ! array_key_exists('included', $data))
|
||||||
{
|
{
|
||||||
@ -593,7 +593,7 @@ final class Model {
|
|||||||
];
|
];
|
||||||
$options = array_merge($defaultOptions, $options);
|
$options = array_merge($defaultOptions, $options);
|
||||||
|
|
||||||
return $this->setUpRequest('GET', 'library-entries', ['query' => $options]);
|
return $this->requestBuilder->setUpRequest('GET', 'library-entries', ['query' => $options]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -649,12 +649,22 @@ final class Model {
|
|||||||
* @throws Throwable
|
* @throws Throwable
|
||||||
*/
|
*/
|
||||||
public function getMangaHistory(): array
|
public function getMangaHistory(): array
|
||||||
|
{
|
||||||
|
$key = K::MANGA_HISTORY_LIST_CACHE_KEY;
|
||||||
|
$list = $this->cache->get($key, NULL);
|
||||||
|
|
||||||
|
if ($list === NULL)
|
||||||
{
|
{
|
||||||
$raw = $this->getRawHistoryList('manga');
|
$raw = $this->getRawHistoryList('manga');
|
||||||
$organized = JsonAPI::organizeData($raw);
|
$organized = JsonAPI::organizeData($raw);
|
||||||
$organized = array_filter($organized, fn ($item) => array_key_exists('relationships', $item));
|
$organized = array_filter($organized, fn ($item) => array_key_exists('relationships', $item));
|
||||||
|
|
||||||
return (new MangaHistoryTransformer())->transform($organized);
|
$list = (new MangaHistoryTransformer())->transform($organized);
|
||||||
|
|
||||||
|
$this->cache->set($key, $list);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -696,11 +706,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
|
// Bail out on no data
|
||||||
if (empty($data) || ( ! array_key_exists('included', $data)))
|
if (empty($data) || ( ! array_key_exists('included', $data)))
|
||||||
@ -717,13 +729,12 @@ final class Model {
|
|||||||
}
|
}
|
||||||
unset($item);
|
unset($item);
|
||||||
|
|
||||||
$transformed = $this->mangaListTransformer->transformCollection($data['data']);
|
$list = $this->mangaListTransformer->transformCollection($data['data']);
|
||||||
|
|
||||||
$cacheItem->set($transformed);
|
$this->cache->set($key, $list);
|
||||||
$cacheItem->save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $cacheItem->get();
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -822,7 +833,7 @@ final class Model {
|
|||||||
];
|
];
|
||||||
$options = array_merge($defaultOptions, $options);
|
$options = array_merge($defaultOptions, $options);
|
||||||
|
|
||||||
return $this->setUpRequest('GET', 'library-entries', ['query' => $options]);
|
return $this->requestBuilder->setUpRequest('GET', 'library-entries', ['query' => $options]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -839,7 +850,7 @@ final class Model {
|
|||||||
'include' => 'mappings'
|
'include' => 'mappings'
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
$data = $this->getRequest("manga/{$kitsuMangaId}", $options);
|
$data = $this->requestBuilder->getRequest("manga/{$kitsuMangaId}", $options);
|
||||||
$mappings = array_column($data['included'], 'attributes');
|
$mappings = array_column($data['included'], 'attributes');
|
||||||
|
|
||||||
foreach($mappings as $map)
|
foreach($mappings as $map)
|
||||||
@ -997,7 +1008,7 @@ final class Model {
|
|||||||
*/
|
*/
|
||||||
protected function getRawHistoryPage(string $type, int $offset, int $limit = 20): Request
|
protected function getRawHistoryPage(string $type, int $offset, int $limit = 20): Request
|
||||||
{
|
{
|
||||||
return $this->setUpRequest('GET', 'library-events', [
|
return $this->requestBuilder->setUpRequest('GET', 'library-events', [
|
||||||
'query' => [
|
'query' => [
|
||||||
'filter' => [
|
'filter' => [
|
||||||
'kind' => 'progressed,updated',
|
'kind' => 'progressed,updated',
|
||||||
@ -1059,7 +1070,7 @@ final class Model {
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
$data = $this->getRequest("{$type}/{$id}", $options);
|
$data = $this->requestBuilder->getRequest("{$type}/{$id}", $options);
|
||||||
|
|
||||||
if (empty($data['data']))
|
if (empty($data['data']))
|
||||||
{
|
{
|
||||||
@ -1099,7 +1110,7 @@ final class Model {
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
$data = $this->getRequest($type, $options);
|
$data = $this->requestBuilder->getRequest($type, $options);
|
||||||
|
|
||||||
if (empty($data['data']))
|
if (empty($data['data']))
|
||||||
{
|
{
|
||||||
@ -1132,7 +1143,7 @@ final class Model {
|
|||||||
$options['query']['filter']['status'] = $status;
|
$options['query']['filter']['status'] = $status;
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = $this->getRequest('library-entries', $options);
|
$response = $this->requestBuilder->getRequest('library-entries', $options);
|
||||||
|
|
||||||
return $response['meta']['count'];
|
return $response['meta']['count'];
|
||||||
}
|
}
|
||||||
@ -1198,6 +1209,6 @@ final class Model {
|
|||||||
];
|
];
|
||||||
$options = array_merge($defaultOptions, $options);
|
$options = array_merge($defaultOptions, $options);
|
||||||
|
|
||||||
return $this->setUpRequest('GET', 'library-entries', ['query' => $options]);
|
return $this->requestBuilder->setUpRequest('GET', 'library-entries', ['query' => $options]);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -149,7 +149,7 @@ final class CharacterTransformer extends AbstractTransformer {
|
|||||||
|
|
||||||
$person = $p['attributes'];
|
$person = $p['attributes'];
|
||||||
$person['id'] = $pid;
|
$person['id'] = $pid;
|
||||||
$person['image'] = $person['image']['original'];
|
$person['image'] = $person['image']['original'] ?? '';
|
||||||
|
|
||||||
uasort($role['relationships']['media']['anime'], static function ($a, $b) {
|
uasort($role['relationships']['media']['anime'], static function ($a, $b) {
|
||||||
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
return $a['attributes']['canonicalTitle'] <=> $b['attributes']['canonicalTitle'];
|
||||||
|
@ -98,16 +98,12 @@ final class MangaTransformer extends AbstractTransformer {
|
|||||||
|
|
||||||
if ( ! empty($characters['main']))
|
if ( ! empty($characters['main']))
|
||||||
{
|
{
|
||||||
uasort($characters['main'], static function ($a, $b) {
|
uasort($characters['main'], fn ($a, $b) => $a['name'] <=> $b['anime']);
|
||||||
return $a['name'] <=> $b['name'];
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! empty($characters['supporting']))
|
if ( ! empty($characters['supporting']))
|
||||||
{
|
{
|
||||||
uasort($characters['supporting'], static function ($a, $b) {
|
uasort($characters['supporting'], fn ($a, $b) => $a['name'] <=> $b['anime']);
|
||||||
return $a['name'] <=> $b['name'];
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ksort($characters);
|
ksort($characters);
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient;
|
namespace Aviat\AnimeClient;
|
||||||
|
|
||||||
|
use Aviat\AnimeClient\API\Kitsu;
|
||||||
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
use Psr\SimpleCache\InvalidArgumentException;
|
||||||
use function Amp\Promise\wait;
|
use function Amp\Promise\wait;
|
||||||
|
|
||||||
use Amp\Http\Client\Request;
|
use Amp\Http\Client\Request;
|
||||||
@ -26,6 +29,8 @@ use Amp\Http\Client\HttpClientBuilder;
|
|||||||
use Aviat\Ion\ConfigInterface;
|
use Aviat\Ion\ConfigInterface;
|
||||||
use Yosymfony\Toml\{Toml, TomlBuilder};
|
use Yosymfony\Toml\{Toml, TomlBuilder};
|
||||||
|
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
//! TOML Functions
|
//! TOML Functions
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -232,7 +237,7 @@ function getApiClient (): HttpClient
|
|||||||
*
|
*
|
||||||
* @param string|Request $request
|
* @param string|Request $request
|
||||||
* @return Response
|
* @return Response
|
||||||
* @throws \Throwable
|
* @throws Throwable
|
||||||
*/
|
*/
|
||||||
function getResponse ($request): Response
|
function getResponse ($request): Response
|
||||||
{
|
{
|
||||||
@ -256,7 +261,7 @@ function getResponse ($request): Response
|
|||||||
*/
|
*/
|
||||||
function getLocalImg ($kitsuUrl, $webp = TRUE): string
|
function getLocalImg ($kitsuUrl, $webp = TRUE): string
|
||||||
{
|
{
|
||||||
if ( ! is_string($kitsuUrl))
|
if (empty($kitsuUrl) || ( ! is_string($kitsuUrl)))
|
||||||
{
|
{
|
||||||
return 'images/placeholder.webp';
|
return 'images/placeholder.webp';
|
||||||
}
|
}
|
||||||
@ -346,3 +351,30 @@ function col_not_empty(array $search, string $key): bool
|
|||||||
$items = array_filter(array_column($search, $key), fn ($x) => ( ! empty($x)));
|
$items = array_filter(array_column($search, $key), fn ($x) => ( ! empty($x)));
|
||||||
return count($items) > 0;
|
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\{Model, UrlGenerator, Util};
|
||||||
use Aviat\AnimeClient\API\{Anilist, CacheTrait, Kitsu};
|
use Aviat\AnimeClient\API\{Anilist, CacheTrait, Kitsu};
|
||||||
use Aviat\AnimeClient\API\Kitsu\KitsuRequestBuilder;
|
use Aviat\AnimeClient\API\Kitsu\KitsuRequestBuilder;
|
||||||
use Aviat\Banker\Pool;
|
use Aviat\Banker\Teller;
|
||||||
use Aviat\Ion\Config;
|
use Aviat\Ion\Config;
|
||||||
use Aviat\Ion\Di\{Container, ContainerInterface, ContainerAware};
|
use Aviat\Ion\Di\{Container, ContainerInterface, ContainerAware};
|
||||||
use ConsoleKit\{Colors, Command, ConsoleException};
|
use ConsoleKit\{Colors, Command, ConsoleException};
|
||||||
@ -129,7 +129,17 @@ abstract class BaseCommand extends Command {
|
|||||||
|
|
||||||
$configArray = array_replace_recursive($baseConfig, $config, $overrideConfig);
|
$configArray = array_replace_recursive($baseConfig, $config, $overrideConfig);
|
||||||
|
|
||||||
$di = static function (array $configArray) use ($APP_DIR): Container {
|
return $this->_di($configArray, $APP_DIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _line(string $message, $fgColor = NULL, $bgColor = NULL): void
|
||||||
|
{
|
||||||
|
$message = Colors::colorize($message, $fgColor, $bgColor);
|
||||||
|
$this->getConsole()->writeln($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _di(array $configArray, string $APP_DIR): ContainerInterface
|
||||||
|
{
|
||||||
$container = new Container();
|
$container = new Container();
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
@ -156,7 +166,7 @@ abstract class BaseCommand extends Command {
|
|||||||
$container->set('cache', static function($container) {
|
$container->set('cache', static function($container) {
|
||||||
$logger = $container->getLogger();
|
$logger = $container->getLogger();
|
||||||
$config = $container->get('config')->get('cache');
|
$config = $container->get('config')->get('cache');
|
||||||
return new Pool($config, $logger);
|
return new Teller($config, $logger);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create Aura Router Object
|
// Create Aura Router Object
|
||||||
@ -177,7 +187,7 @@ abstract class BaseCommand extends Command {
|
|||||||
|
|
||||||
// Models
|
// Models
|
||||||
$container->set('kitsu-model', static function($container): Kitsu\Model {
|
$container->set('kitsu-model', static function($container): Kitsu\Model {
|
||||||
$requestBuilder = new KitsuRequestBuilder();
|
$requestBuilder = new KitsuRequestBuilder($container);
|
||||||
$requestBuilder->setLogger($container->getLogger('kitsu-request'));
|
$requestBuilder->setLogger($container->getLogger('kitsu-request'));
|
||||||
|
|
||||||
$listItem = new Kitsu\ListItem();
|
$listItem = new Kitsu\ListItem();
|
||||||
@ -219,14 +229,5 @@ abstract class BaseCommand extends Command {
|
|||||||
$container->set('util', fn ($container) => new Util($container));
|
$container->set('util', fn ($container) => new Util($container));
|
||||||
|
|
||||||
return $container;
|
return $container;
|
||||||
};
|
|
||||||
|
|
||||||
return $di($configArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function _line(string $message, $fgColor = NULL, $bgColor = NULL): void
|
|
||||||
{
|
|
||||||
$message = Colors::colorize($message, $fgColor, $bgColor);
|
|
||||||
$this->getConsole()->writeln($message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,6 +18,7 @@ namespace Aviat\AnimeClient\Command;
|
|||||||
|
|
||||||
use Aviat\Ion\Di\Exception\ContainerException;
|
use Aviat\Ion\Di\Exception\ContainerException;
|
||||||
use Aviat\Ion\Di\Exception\NotFoundException;
|
use Aviat\Ion\Di\Exception\NotFoundException;
|
||||||
|
use function Aviat\AnimeClient\clearCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the API Cache
|
* Clears the API Cache
|
||||||
@ -36,8 +37,17 @@ final class CacheClear extends BaseCommand {
|
|||||||
{
|
{
|
||||||
$this->setContainer($this->setupContainer());
|
$this->setContainer($this->setupContainer());
|
||||||
|
|
||||||
$this->container->get('cache')->clear();
|
$cache = $this->container->get('cache');
|
||||||
|
|
||||||
|
$cleared = clearCache($cache);
|
||||||
|
|
||||||
|
if ($cleared)
|
||||||
|
{
|
||||||
$this->echoBox('API Cache has been cleared.');
|
$this->echoBox('API Cache has been cleared.');
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->echoErrorBox('Failed to clear cache.');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,10 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\Command;
|
namespace Aviat\AnimeClient\Command;
|
||||||
|
|
||||||
|
use Aviat\AnimeClient\API\Kitsu;
|
||||||
use Aviat\Ion\Di\Exception\ContainerException;
|
use Aviat\Ion\Di\Exception\ContainerException;
|
||||||
use Aviat\Ion\Di\Exception\NotFoundException;
|
use Aviat\Ion\Di\Exception\NotFoundException;
|
||||||
|
use function Aviat\AnimeClient\clearCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the API Cache
|
* Clears the API Cache
|
||||||
@ -35,30 +37,25 @@ final class CachePrime extends BaseCommand {
|
|||||||
public function execute(array $args, array $options = []): void
|
public function execute(array $args, array $options = []): void
|
||||||
{
|
{
|
||||||
$this->setContainer($this->setupContainer());
|
$this->setContainer($this->setupContainer());
|
||||||
|
|
||||||
$cache = $this->container->get('cache');
|
$cache = $this->container->get('cache');
|
||||||
|
|
||||||
// Save the user id, if it exists, for priming the cache
|
$cleared = clearCache($cache);
|
||||||
$userIdItem = $cache->getItem('kitsu-auth-token');
|
if ( ! $cleared)
|
||||||
$userId = $userIdItem->isHit() ? $userIdItem->get() : null;
|
{
|
||||||
|
$this->echoErrorBox('Failed to clear cache.');
|
||||||
$cache->clear();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$this->echoBox('Cache cleared, re-priming...');
|
$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');
|
$kitsuModel = $this->container->get('kitsu-model');
|
||||||
|
|
||||||
// Prime anime list cache
|
// Prime anime list and history cache
|
||||||
|
$kitsuModel->getAnimeHistory();
|
||||||
$kitsuModel->getFullOrganizedAnimeList();
|
$kitsuModel->getFullOrganizedAnimeList();
|
||||||
|
|
||||||
// Prime manga list cache
|
// Prime manga list cache
|
||||||
|
$kitsuModel->getMangaHistory();
|
||||||
$kitsuModel->getFullOrganizedMangaList();
|
$kitsuModel->getFullOrganizedMangaList();
|
||||||
|
|
||||||
$this->echoBox('API Cache has been primed.');
|
$this->echoBox('API Cache has been primed.');
|
||||||
|
@ -16,16 +16,16 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient;
|
namespace Aviat\AnimeClient;
|
||||||
|
|
||||||
use Aviat\AnimeClient\Enum\EventType;
|
|
||||||
use function Aviat\Ion\_dir;
|
use function Aviat\Ion\_dir;
|
||||||
|
|
||||||
|
use Aviat\AnimeClient\Enum\EventType;
|
||||||
use Aura\Router\Generator;
|
use Aura\Router\Generator;
|
||||||
use Aura\Session\Segment;
|
use Aura\Session\Segment;
|
||||||
use Aviat\AnimeClient\API\Kitsu\Auth;
|
use Aviat\AnimeClient\API\Kitsu\Auth;
|
||||||
use Aviat\Ion\ConfigInterface;
|
use Aviat\Ion\ConfigInterface;
|
||||||
use Psr\Cache\CacheItemPoolInterface;
|
|
||||||
use Psr\Http\Message\ResponseInterface;
|
use Psr\Http\Message\ResponseInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
use Psr\SimpleCache\CacheInterface;
|
||||||
|
|
||||||
use Aviat\Ion\Di\{
|
use Aviat\Ion\Di\{
|
||||||
ContainerAware,
|
ContainerAware,
|
||||||
@ -53,9 +53,9 @@ class Controller {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache manager
|
* Cache manager
|
||||||
* @var CacheItemPoolInterface
|
* @var CacheInterface
|
||||||
*/
|
*/
|
||||||
protected CacheItemPoolInterface $cache;
|
protected CacheInterface $cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The global configuration object
|
* The global configuration object
|
||||||
@ -134,8 +134,9 @@ class Controller {
|
|||||||
'urlGenerator' => $urlGenerator,
|
'urlGenerator' => $urlGenerator,
|
||||||
];
|
];
|
||||||
|
|
||||||
Event::on(EventType::CLEAR_CACHE, fn () => $this->emptyCache());
|
// Set up 'global' events
|
||||||
Event::on(EventType::RESET_CACHE_KEY, fn (string $key) => $this->removeCacheItem($key));
|
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);
|
(new HttpView($this->container))->redirect($url, $code);
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function emptyCache(): void
|
|
||||||
{
|
|
||||||
$this->cache->emptyCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function removeCacheItem(string $key): void
|
|
||||||
{
|
|
||||||
$this->cache->deleteItem($key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// End of BaseController.php
|
// End of BaseController.php
|
@ -292,14 +292,14 @@ final class Dispatcher extends RoutingBase {
|
|||||||
'API request timed out',
|
'API request timed out',
|
||||||
'Failed to retrieve data from API (╯°□°)╯︵ ┻━┻');
|
'Failed to retrieve data from API (╯°□°)╯︵ ┻━┻');
|
||||||
}
|
}
|
||||||
finally
|
/* finally
|
||||||
{
|
{
|
||||||
// Log out on session/api token expiration
|
// Log out on session/api token expiration
|
||||||
Event::on(EventType::UNAUTHORIZED, static function () {
|
Event::on(EventType::UNAUTHORIZED, static function () {
|
||||||
$controllerName = DEFAULT_CONTROLLER;
|
$controllerName = DEFAULT_CONTROLLER;
|
||||||
(new $controllerName($this->container))->logout();
|
(new $controllerName($this->container))->logout();
|
||||||
});
|
});
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -92,7 +92,6 @@ const SETTINGS_MAP = [
|
|||||||
'title' => 'Cache Type',
|
'title' => 'Cache Type',
|
||||||
'description' => 'The Cache backend',
|
'description' => 'The Cache backend',
|
||||||
'options' => [
|
'options' => [
|
||||||
'APCu' => 'apcu',
|
|
||||||
'Memcached' => 'memcached',
|
'Memcached' => 'memcached',
|
||||||
'Redis' => 'redis',
|
'Redis' => 'redis',
|
||||||
'No Cache' => 'null'
|
'No Cache' => 'null'
|
||||||
|
Loading…
Reference in New Issue
Block a user