diff --git a/app/bootstrap.php b/app/bootstrap.php
index 01e06953..599a275b 100644
--- a/app/bootstrap.php
+++ b/app/bootstrap.php
@@ -19,17 +19,9 @@ namespace Aviat\AnimeClient;
use Aura\Html\HelperLocatorFactory;
use Aura\Router\RouterContainer;
use Aura\Session\SessionFactory;
-use Aviat\AnimeClient\API\Kitsu\{
- Auth as KitsuAuth,
- ListItem as KitsuListItem,
- KitsuRequestBuilder,
- Model as KitsuModel
-};
-use Aviat\AnimeClient\API\MAL\{
- ListItem as MALListItem,
- MALRequestBuilder,
- Model as MALModel
-};
+use Aviat\AnimeClient\API\{Kitsu, MAL};
+use Aviat\AnimeClient\API\Kitsu\KitsuRequestBuilder;
+use Aviat\AnimeClient\API\MAL\MALRequestBuilder;
use Aviat\AnimeClient\Model;
use Aviat\Banker\Pool;
use Aviat\Ion\Config;
@@ -119,15 +111,15 @@ return function(array $config_array = []) {
$container->set('kitsu-model', function($container) {
$requestBuilder = new KitsuRequestBuilder();
$requestBuilder->setLogger($container->getLogger('kitsu-request'));
-
- $listItem = new KitsuListItem();
+
+ $listItem = new Kitsu\ListItem();
$listItem->setContainer($container);
$listItem->setRequestBuilder($requestBuilder);
-
- $model = new KitsuModel($listItem);
+
+ $model = new Kitsu\Model($listItem);
$model->setContainer($container);
$model->setRequestBuilder($requestBuilder);
-
+
$cache = $container->get('cache');
$model->setCache($cache);
return $model;
@@ -135,12 +127,12 @@ return function(array $config_array = []) {
$container->set('mal-model', function($container) {
$requestBuilder = new MALRequestBuilder();
$requestBuilder->setLogger($container->getLogger('mal-request'));
-
- $listItem = new MALListItem();
+
+ $listItem = new MAL\ListItem();
$listItem->setContainer($container);
$listItem->setRequestBuilder($requestBuilder);
-
- $model = new MALModel($listItem);
+
+ $model = new MAL\Model($listItem);
$model->setContainer($container);
$model->setRequestBuilder($requestBuilder);
return $model;
@@ -161,7 +153,7 @@ return function(array $config_array = []) {
// Miscellaneous Classes
$container->set('auth', function($container) {
- return new KitsuAuth($container);
+ return new Kitsu\Auth($container);
});
$container->set('url-generator', function($container) {
return new UrlGenerator($container);
diff --git a/app/config/routes.php b/app/config/routes.php
index df9329ad..4ead95bf 100644
--- a/app/config/routes.php
+++ b/app/config/routes.php
@@ -14,6 +14,11 @@
* @link https://github.com/timw4mail/HummingBirdAnimeClient
*/
+use const Aviat\AnimeClient\{
+ DEFAULT_CONTROLLER_METHOD,
+ DEFAULT_CONTROLLER_NAMESPACE
+};
+
use Aviat\AnimeClient\AnimeClient;
return [
@@ -148,25 +153,25 @@ return [
'cache_purge' => [
'path' => '/cache_purge',
'action' => 'clearCache',
- 'controller' => AnimeClient::DEFAULT_CONTROLLER_NAMESPACE,
+ 'controller' => DEFAULT_CONTROLLER_NAMESPACE,
'verb' => 'get',
],
'login' => [
'path' => '/login',
'action' => 'login',
- 'controller' => AnimeClient::DEFAULT_CONTROLLER_NAMESPACE,
+ 'controller' => DEFAULT_CONTROLLER_NAMESPACE,
'verb' => 'get',
],
'login.post' => [
'path' => '/login',
'action' => 'loginAction',
- 'controller' => AnimeClient::DEFAULT_CONTROLLER_NAMESPACE,
+ 'controller' => DEFAULT_CONTROLLER_NAMESPACE,
'verb' => 'post',
],
'logout' => [
'path' => '/logout',
'action' => 'logout',
- 'controller' => AnimeClient::DEFAULT_CONTROLLER_NAMESPACE,
+ 'controller' => DEFAULT_CONTROLLER_NAMESPACE,
],
'update' => [
'path' => '/{controller}/update',
@@ -194,7 +199,7 @@ return [
],
'list' => [
'path' => '/{controller}/{type}{/view}',
- 'action' => AnimeClient::DEFAULT_CONTROLLER_METHOD,
+ 'action' => DEFAULT_CONTROLLER_METHOD,
'tokens' => [
'type' => '[a-z_]+',
'view' => '[a-z_]+',
@@ -202,7 +207,7 @@ return [
],
'index_redirect' => [
'path' => '/',
- 'controller' => AnimeClient::DEFAULT_CONTROLLER_NAMESPACE,
+ 'controller' => DEFAULT_CONTROLLER_NAMESPACE,
'action' => 'redirectToDefaultRoute',
],
],
diff --git a/composer.json b/composer.json
index c21f88ae..4b91d3b0 100644
--- a/composer.json
+++ b/composer.json
@@ -3,6 +3,9 @@
"description": "A self-hosted anime/manga client for Kitsu.",
"license":"MIT",
"autoload": {
+ "files": [
+ "src/AnimeClient.php"
+ ],
"psr-4": {
"Aviat\\AnimeClient\\": "src/"
}
@@ -20,7 +23,6 @@
"aviat/banker": "^1.0.0",
"aviat/ion": "1.0.*",
"filp/whoops": "^2.1.5",
- "guzzlehttp/guzzle": "^6.0",
"monolog/monolog": "^1.0",
"psr/http-message": "~1.0",
"psr/log": "~1.0",
@@ -46,4 +48,4 @@
"build:css": "cd public && npm run build && cd ..",
"watch:css": "cd public && npm run watch"
}
-}
+}
\ No newline at end of file
diff --git a/index.php b/index.php
index fff3616a..0d8a5615 100644
--- a/index.php
+++ b/index.php
@@ -15,6 +15,8 @@
*/
namespace Aviat\AnimeClient;
+use function Aviat\AnimeClient\loadToml;
+
use Aviat\AnimeClient\AnimeClient;
use Whoops\Handler\PrettyPageHandler;
use Whoops\Run;
@@ -42,7 +44,7 @@ $APP_DIR = _dir(__DIR__, 'app');
$CONF_DIR = _dir($APP_DIR, 'config');
// Load composer autoloader
-require _dir(__DIR__, '/vendor/autoload.php');
+require _dir(__DIR__, 'vendor/autoload.php');
// -------------------------------------------------------------------------
// Setup error handling
@@ -54,10 +56,7 @@ $defaultHandler = new PrettyPageHandler();
$whoops->pushHandler($defaultHandler);
// Register as the error handler
-if (array_key_exists('whoops', $_GET))
-{
- $whoops->register();
-}
+$whoops->register();
// -----------------------------------------------------------------------------
// Dependency Injection setup
@@ -65,7 +64,7 @@ if (array_key_exists('whoops', $_GET))
require _dir($CONF_DIR, 'base_config.php'); // $base_config
$di = require _dir($APP_DIR, 'bootstrap.php');
-$config = AnimeClient::loadToml($CONF_DIR);
+$config = loadToml($CONF_DIR);
$config_array = array_merge($base_config, $config);
$container = $di($config_array);
@@ -77,6 +76,4 @@ unset($CONF_DIR);
// -----------------------------------------------------------------------------
// Dispatch to the current route
// -----------------------------------------------------------------------------
-$container->get('dispatcher')->__invoke();
-
-// End of index.php
\ No newline at end of file
+$container->get('dispatcher')->__invoke();
\ No newline at end of file
diff --git a/src/API/APIRequestBuilder.php b/src/API/APIRequestBuilder.php
index 0ea1f77a..d3d2a037 100644
--- a/src/API/APIRequestBuilder.php
+++ b/src/API/APIRequestBuilder.php
@@ -16,12 +16,14 @@
namespace Aviat\AnimeClient\API;
+use Amp;
use Amp\Artax\{
Client,
FormBody,
Request
};
use Aviat\Ion\Di\ContainerAware;
+use Aviat\Ion\Json;
use InvalidArgumentException;
use Psr\Log\LoggerAwareTrait;
@@ -67,6 +69,21 @@ class APIRequestBuilder {
*/
protected $request;
+ /**
+ * Set an authorization header
+ *
+ * @param string $type The type of authorization, eg, basic, bearer, etc.
+ * @param string $value The authorization value
+ * @return self
+ */
+ public function setAuth(string $type, string $value): self
+ {
+ $authString = ucfirst($type) . ' ' . $value;
+ $this->setHeader('Authorization', $authString);
+
+ return $this;
+ }
+
/**
* Set a basic authentication header
*
@@ -76,9 +93,7 @@ class APIRequestBuilder {
*/
public function setBasicAuth(string $username, string $password): self
{
- $authString = 'Basic ' . base64_encode($username . ':' . $password);
- $this->setHeader('Authorization', $authString);
-
+ $this->setAuth('basic', base64_encode($username . ':' . $password));
return $this;
}
@@ -139,6 +154,18 @@ class APIRequestBuilder {
return $this;
}
+ /**
+ * Set the request body
+ *
+ * @param array|FormBody|string $body
+ * @return self
+ */
+ public function setJsonBody(array $body): self
+ {
+ $requestBody = Json::encode($body);
+ return $this->setBody($requestBody);
+ }
+
/**
* Append a query string in array format
*
@@ -159,7 +186,7 @@ class APIRequestBuilder {
public function getFullRequest()
{
$this->buildUri();
-
+
if ($this->logger)
{
$this->logger->debug('API Request', [
@@ -168,7 +195,7 @@ class APIRequestBuilder {
'request_body' => $this->request->getBody()
]);
}
-
+
return $this->request;
}
@@ -191,13 +218,13 @@ class APIRequestBuilder {
$this->request
->setMethod($type)
->setProtocol('1.1');
-
+
$this->path = $uri;
-
+
if ( ! empty($this->defaultHeaders))
{
$this->setHeaders($this->defaultHeaders);
- }
+ }
return $this;
}
@@ -232,7 +259,7 @@ class APIRequestBuilder {
*/
private function fixBody(FormBody $formBody): string
{
- $rawBody = \Amp\wait($formBody->getBody());
+ $rawBody = Amp\wait($formBody->getBody());
return html_entity_decode($rawBody, \ENT_HTML5, 'UTF-8');
}
diff --git a/src/API/APIClient.php b/src/API/FailedResponseException.php
similarity index 61%
rename from src/API/APIClient.php
rename to src/API/FailedResponseException.php
index 05d3b8a9..648bb83d 100644
--- a/src/API/APIClient.php
+++ b/src/API/FailedResponseException.php
@@ -16,24 +16,8 @@
namespace Aviat\AnimeClient\API;
-use Amp;
-use Amp\Artax\{
- Client,
- Response,
- Request
-}
+use UnexpectedValueException;
-class APIClient {
+class FailedResponseException extends UnexpectedValueException {
- /**
- * Get a syncronous response for a request
- *
- * @param Request $request
- * @return Response
- */
- static public function syncResponse(Request $request): Response
- {
- $client = new Client();
- return wait($client->request($request));
- }
}
\ No newline at end of file
diff --git a/src/API/GuzzleTrait.php b/src/API/GuzzleTrait.php
deleted file mode 100644
index 6af78cde..00000000
--- a/src/API/GuzzleTrait.php
+++ /dev/null
@@ -1,41 +0,0 @@
-
- * @copyright 2015 - 2017 Timothy J. Warren
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
- * @version 4.0
- * @link https://github.com/timw4mail/HummingBirdAnimeClient
- */
-
-namespace Aviat\AnimeClient\API;
-
-/**
- * Base trait for api interaction
- */
-trait GuzzleTrait {
- /**
- * The Guzzle http client object
- * @var object
- */
- protected $client;
-
- /**
- * Cookie jar object for api requests
- * @var object
- */
- protected $cookieJar;
-
- /**
- * Set up the class properties
- *
- * @return void
- */
- abstract protected function init();
-}
\ No newline at end of file
diff --git a/src/API/Kitsu.php b/src/API/Kitsu.php
index 34907c90..117f7bdd 100644
--- a/src/API/Kitsu.php
+++ b/src/API/Kitsu.php
@@ -23,6 +23,10 @@ use Aviat\AnimeClient\API\Kitsu\Enum\{
};
use DateTimeImmutable;
+const AUTH_URL = 'https://kitsu.io/api/oauth/token';
+const AUTH_USER_ID_KEY = 'kitsu-auth-userid';
+const AUTH_TOKEN_CACHE_KEY = 'kitsu-auth-token';
+
/**
* Data massaging helpers for the Kitsu API
*/
@@ -91,7 +95,7 @@ class Kitsu {
return AnimeAiringStatus::NOT_YET_AIRED;
}
}
-
+
/**
* Get the name and logo for the streaming service of the current link
*
@@ -108,22 +112,22 @@ class Kitsu {
'link' => true,
'logo' => ''
];
-
+
case 'www.funimation.com':
return [
'name' => 'Funimation',
'link' => true,
'logo' => ''
];
-
+
case 'www.hulu.com':
return [
'name' => 'Hulu',
'link' => true,
'logo' => ''
];
-
- // Default to Netflix, because the API links are broken,
+
+ // Default to Netflix, because the API links are broken,
// and there's no other real identifier for Netflix
default:
return [
@@ -133,7 +137,7 @@ class Kitsu {
];
}
}
-
+
/**
* Reorganize streaming links
*
@@ -146,13 +150,13 @@ class Kitsu {
{
return [];
}
-
+
$links = [];
-
+
foreach ($included['streamingLinks'] as $streamingLink)
{
$host = parse_url($streamingLink['url'], \PHP_URL_HOST);
-
+
$links[] = [
'meta' => static::getServiceMetaData($host),
'link' => $streamingLink['url'],
@@ -160,10 +164,10 @@ class Kitsu {
'dubs' => $streamingLink['dubs']
];
}
-
+
return $links;
}
-
+
/**
* Reorganize streaming links for the current list item
*
@@ -192,10 +196,10 @@ class Kitsu {
];
}
}
-
+
return $links;
}
-
+
return [];
}
diff --git a/src/API/Kitsu/Auth.php b/src/API/Kitsu/Auth.php
index 70691eb1..7e01e592 100644
--- a/src/API/Kitsu/Auth.php
+++ b/src/API/Kitsu/Auth.php
@@ -16,6 +16,9 @@
namespace Aviat\AnimeClient\API\Kitsu;
+use const Aviat\AnimeClient\SESSION_SEGMENT;
+use const Aviat\AnimeClient\API\Kitsu\AUTH_TOKEN_CACHE_KEY;
+
use Aviat\AnimeClient\AnimeClient;
use Aviat\AnimeClient\API\{
CacheTrait,
@@ -55,7 +58,7 @@ class Auth {
$this->setContainer($container);
$this->setCache($container->get('cache'));
$this->segment = $container->get('session')
- ->getSegment(AnimeClient::SESSION_SEGMENT);
+ ->getSegment(SESSION_SEGMENT);
$this->model = $container->get('kitsu-model');
}
@@ -70,7 +73,7 @@ class Auth {
{
$config = $this->container->get('config');
$username = $config->get(['kitsu_username']);
-
+
try
{
$auth = $this->model->authenticate($username, $password);
@@ -79,15 +82,15 @@ class Auth {
{
return FALSE;
}
-
+
if (FALSE !== $auth)
{
// Set the token in the cache for command line operations
- $cacheItem = $this->cache->getItem(K::AUTH_TOKEN_CACHE_KEY);
+ $cacheItem = $this->cache->getItem(AUTH_TOKEN_CACHE_KEY);
$cacheItem->set($auth['access_token']);
$cacheItem->save();
-
+
$this->segment->set('auth_token', $auth['access_token']);
return TRUE;
}
diff --git a/src/API/Kitsu/KitsuRequestBuilder.php b/src/API/Kitsu/KitsuRequestBuilder.php
index c155794a..7a3cab02 100644
--- a/src/API/Kitsu/KitsuRequestBuilder.php
+++ b/src/API/Kitsu/KitsuRequestBuilder.php
@@ -20,8 +20,8 @@ use Aviat\AnimeClient\API\APIRequestBuilder;
use Aviat\AnimeClient\API\Kitsu as K;
use Aviat\Ion\Json;
-class KitsuRequestBuilder extends APIRequestBuilder {
-
+class KitsuRequestBuilder extends APIRequestBuilder {
+
/**
* The base url for api requests
* @var string $base_url
@@ -40,16 +40,4 @@ class KitsuRequestBuilder extends APIRequestBuilder {
'client_id' => 'dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd',
'client_secret' => '54d7307928f63414defd96399fc31ba847961ceaecef3a5fd93144e960c0e151',
];
-
- /**
- * Set the request body
- *
- * @param array|FormBody|string $body
- * @return self
- */
- public function setJsonBody(array $body): self
- {
- $requestBody = Json::encode($body);
- return $this->setBody($requestBody);
- }
-}
+}
\ No newline at end of file
diff --git a/src/API/Kitsu/KitsuTrait.php b/src/API/Kitsu/KitsuTrait.php
index 612ee747..75b9e554 100644
--- a/src/API/Kitsu/KitsuTrait.php
+++ b/src/API/Kitsu/KitsuTrait.php
@@ -16,13 +16,14 @@
namespace Aviat\AnimeClient\API\Kitsu;
+use const Aviat\AnimeClient\SESSION_SEGMENT;
+
+use function Amp\wait;
+
+use Amp\Artax\Client;
use Aviat\AnimeClient\AnimeClient;
-use Aviat\AnimeClient\API\GuzzleTrait;
use Aviat\AnimeClient\API\Kitsu as K;
use Aviat\Ion\Json;
-use GuzzleHttp\Client;
-use GuzzleHttp\Cookie\CookieJar;
-use GuzzleHttp\Psr7\Response;
use InvalidArgumentException;
use RuntimeException;
@@ -34,37 +35,6 @@ trait KitsuTrait {
*/
protected $requestBuilder;
- /**
- * The Guzzle http client object
- * @var object
- */
- protected $client;
-
- /**
- * Cookie jar object for api requests
- * @var object
- */
- protected $cookieJar;
-
- /**
- * The base url for api requests
- * @var string $base_url
- */
- protected $baseUrl = "https://kitsu.io/api/edge/";
-
- /**
- * HTTP headers to send with every request
- *
- * @var array
- */
- protected $defaultHeaders = [
- 'User-Agent' => "Tim's Anime Client/4.0",
- 'Accept-Encoding' => 'application/vnd.api+json',
- 'Content-Type' => 'application/vnd.api+json',
- 'client_id' => 'dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd',
- 'client_secret' => '54d7307928f63414defd96399fc31ba847961ceaecef3a5fd93144e960c0e151',
- ];
-
/**
* Set the request builder object
*
@@ -78,30 +48,45 @@ trait KitsuTrait {
}
/**
- * Set up the class properties
+ * Create a request object
*
- * @return void
+ * @param string $type
+ * @param string $url
+ * @param array $options
+ * @return \Amp\Artax\Response
*/
- protected function init()
+ public function setUpRequest(string $type, string $url, array $options = [])
{
- $defaults = [
- 'cookies' => $this->cookieJar,
- 'headers' => $this->defaultHeaders,
- 'timeout' => 25,
- 'connect_timeout' => 25
- ];
+ $config = $this->container->get('config');
- $this->cookieJar = new CookieJar();
- $this->client = new Client([
- 'base_uri' => $this->baseUrl,
- 'cookies' => TRUE,
- 'http_errors' => TRUE,
- 'defaults' => $defaults
- ]);
+ $request = $this->requestBuilder->newRequest($type, $url);
+
+ $sessionSegment = $this->getContainer()
+ ->get('session')
+ ->getSegment(SESSION_SEGMENT);
+
+ if ($sessionSegment->get('auth_token') !== null && $url !== K::AUTH_URL)
+ {
+ $token = $sessionSegment->get('auth_token');
+ $request = $request->setAuth('bearer', $token);
+ // $defaultOptions['headers']['Authorization'] = "bearer {$token}";
+ }
+
+ if (array_key_exists('query', $options))
+ {
+ $request->setQuery($options['query']);
+ }
+
+ if (array_key_exists('body', $options))
+ {
+ $request->setJsonBody($options['body']);
+ }
+
+ return $request->getFullRequest();
}
/**
- * Make a request via Guzzle
+ * Make a request
*
* @param string $type
* @param string $url
@@ -110,48 +95,24 @@ trait KitsuTrait {
*/
private function getResponse(string $type, string $url, array $options = [])
{
- $logger = null;
- $validTypes = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'];
-
- if ( ! in_array($type, $validTypes))
- {
- throw new InvalidArgumentException('Invalid http request type');
- }
-
- $defaultOptions = [
- 'headers' => $this->defaultHeaders
- ];
-
+ $request = $this->setUpRequest($type, $url, $options);
$logger = $this->container->getLogger('kitsu-request');
- $sessionSegment = $this->getContainer()
- ->get('session')
- ->getSegment(AnimeClient::SESSION_SEGMENT);
- if ($sessionSegment->get('auth_token') !== null && $url !== K::AUTH_URL)
- {
- $token = $sessionSegment->get('auth_token');
- $defaultOptions['headers']['Authorization'] = "bearer {$token}";
- }
+ $response = wait((new Client)->request($request));
- $options = array_merge($defaultOptions, $options);
-
- $response = $this->client->request($type, $url, $options);
-
- $logger->debug('Kitsu API request', [
- 'requestParams' => [
- 'type' => $type,
- 'url' => $url,
- ],
- 'responseValues' => [
- 'status' => $response->getStatusCode()
- ]
- ]);
+ /* $logger->debug('Kitsu api response', [
+ 'status' => $response->getStatus(),
+ 'reason' => $response->getReason(),
+ 'body' => $response->getBody(),
+ 'headers' => $response->getAllHeaders(),
+ 'requestHeaders' => $request->getAllHeaders(),
+ ]); */
return $response;
}
/**
- * Make a request via Guzzle
+ * Make a request
*
* @param string $type
* @param string $url
@@ -168,7 +129,7 @@ trait KitsuTrait {
$response = $this->getResponse($type, $url, $options);
- if ((int) $response->getStatusCode() > 299 || (int) $response->getStatusCode() < 200)
+ if ((int) $response->getStatus() > 299 || (int) $response->getStatus() < 200)
{
if ($logger)
{
@@ -218,7 +179,7 @@ trait KitsuTrait {
$response = $this->getResponse('POST', ...$args);
$validResponseCodes = [200, 201];
- if ( ! in_array((int) $response->getStatusCode(), $validResponseCodes))
+ if ( ! in_array((int) $response->getStatus(), $validResponseCodes))
{
if ($logger)
{
@@ -238,6 +199,6 @@ trait KitsuTrait {
protected function deleteRequest(...$args): bool
{
$response = $this->getResponse('DELETE', ...$args);
- return ((int) $response->getStatusCode() === 204);
+ return ((int) $response->getStatus() === 204);
}
}
\ No newline at end of file
diff --git a/src/API/Kitsu/ListItem.php b/src/API/Kitsu/ListItem.php
index 51121471..c57d6d3e 100644
--- a/src/API/Kitsu/ListItem.php
+++ b/src/API/Kitsu/ListItem.php
@@ -16,11 +16,12 @@
namespace Aviat\AnimeClient\API\Kitsu;
+use const Aviat\AnimeClient\SESSION_SEGMENT;
+
+use Amp\Artax\Request;
use Aviat\AnimeClient\API\AbstractListItem;
use Aviat\Ion\Di\ContainerAware;
use Aviat\Ion\Json;
-use GuzzleHttp\Exception\ClientException;
-use GuzzleHttp\Psr7\Response;
use RuntimeException;
/**
@@ -30,12 +31,22 @@ class ListItem extends AbstractListItem {
use ContainerAware;
use KitsuTrait;
- public function __construct()
+ private function getAuthHeader()
{
- $this->init();
+ $sessionSegment = $this->getContainer()
+ ->get('session')
+ ->getSegment(SESSION_SEGMENT);
+
+ if ($sessionSegment->get('auth_token') !== null)
+ {
+ $token = $sessionSegment->get('auth_token');
+ return "bearer {$token}";
+ }
+
+ return FALSE;
}
- public function create(array $data): bool
+ public function create(array $data): Request
{
$body = [
'data' => [
@@ -60,21 +71,35 @@ class ListItem extends AbstractListItem {
]
]
];
-
- $request = $this->requestBuilder->newRequest('POST', 'library-entries')
- ->setJsonBody($body)
- ->getFullRequest();
- $response = $this->getResponse('POST', 'library-entries', [
- 'body' => Json::encode($body)
- ]);
- return ($response->getStatusCode() === 201);
+ $authHeader = $this->getAuthHeader();
+
+ $request = $this->requestBuilder->newRequest('POST', 'library-entries');
+
+ if ($authHeader !== FALSE)
+ {
+ $request = $request->setHeader('Authorization', $authHeader);
+ }
+
+ return $request->setJsonBody($body)
+ ->getFullRequest();
+
+ // return ($response->getStatus() === 201);
}
- public function delete(string $id): bool
+ public function delete(string $id): Request
{
- $response = $this->getResponse('DELETE', "library-entries/{$id}");
- return ($response->getStatusCode() === 204);
+ $authHeader = $this->getAuthHeader();
+ $request = $this->requestBuilder->newRequest('DELETE', "library-entries/{$id}");
+
+ if ($authHeader !== FALSE)
+ {
+ $request = $request->setHeader('Authorization', $authHeader);
+ }
+
+ return $request->getFullRequest();
+
+ // return ($response->getStatus() === 204);
}
public function get(string $id): array
@@ -84,17 +109,12 @@ class ListItem extends AbstractListItem {
'include' => 'media,media.genres,media.mappings'
])
->getFullRequest();
- /*return $this->getRequest("library-entries/{$id}", [
- 'query' => [
- 'include' => 'media,media.genres,media.mappings'
- ]
- ]);*/
-
+
$response = \Amp\wait((new \Amp\Artax\Client)->request($request));
return Json::decode($response->getBody());
}
- public function update(string $id, array $data): Response
+ public function update(string $id, array $data): Request
{
$requestData = [
'data' => [
diff --git a/src/API/Kitsu/Model.php b/src/API/Kitsu/Model.php
index 7077f809..1a401b1c 100644
--- a/src/API/Kitsu/Model.php
+++ b/src/API/Kitsu/Model.php
@@ -16,6 +16,7 @@
namespace Aviat\AnimeClient\API\Kitsu;
+use Amp\Artax\Request;
use Aviat\AnimeClient\API\CacheTrait;
use Aviat\AnimeClient\API\JsonAPI;
use Aviat\AnimeClient\API\Kitsu as K;
@@ -27,7 +28,6 @@ use Aviat\AnimeClient\API\Kitsu\Transformer\{
};
use Aviat\Ion\Di\ContainerAware;
use Aviat\Ion\Json;
-use GuzzleHttp\Exception\ClientException;
/**
* Kitsu API Model
@@ -72,9 +72,6 @@ class Model {
*/
public function __construct(ListItem $listItem)
{
- // Set up Guzzle trait
- $this->init();
-
$this->animeTransformer = new AnimeTransformer();
$this->animeListTransformer = new AnimeListTransformer();
$this->listItem = $listItem;
@@ -355,9 +352,9 @@ class Model {
* Create a list item
*
* @param array $data
- * @return bool
+ * @return Request
*/
- public function createListItem(array $data): bool
+ public function createListItem(array $data): Request
{
$data['user_id'] = $this->getUserIdByUsername($this->getUsername());
return $this->listItem->create($data);
@@ -397,22 +394,22 @@ class Model {
* Modify a list item
*
* @param array $data
- * @return array
+ * @return Request
*/
- public function updateListItem(array $data)
+ public function updateListItem(array $data): Request
{
try
{
$response = $this->listItem->update($data['id'], $data['data']);
return [
- 'statusCode' => $response->getStatusCode(),
+ 'statusCode' => $response->getStatus(),
'body' => $response->getBody(),
];
}
catch(ClientException $e)
{
return [
- 'statusCode' => $e->getResponse()->getStatusCode(),
+ 'statusCode' => $e->getResponse()->getStatus(),
'body' => Json::decode((string)$e->getResponse()->getBody())
];
}
@@ -422,9 +419,9 @@ class Model {
* Remove a list item
*
* @param string $id - The id of the list item to remove
- * @return bool
+ * @return Request
*/
- public function deleteListItem(string $id): bool
+ public function deleteListItem(string $id): Request
{
return $this->listItem->delete($id);
}
diff --git a/src/API/ListItemInterface.php b/src/API/ListItemInterface.php
index b0001428..17f0cad8 100644
--- a/src/API/ListItemInterface.php
+++ b/src/API/ListItemInterface.php
@@ -16,7 +16,7 @@
namespace Aviat\AnimeClient\API;
-use GuzzleHttp\Psr7\Response;
+use Amp\Artax\Request;
/**
* Common interface for anime and manga list item CRUD
@@ -29,7 +29,7 @@ interface ListItemInterface {
* @param array $data -
* @return bool
*/
- public function create(array $data): bool;
+ public function create(array $data): Request;
/**
* Retrieve a list item
@@ -46,7 +46,7 @@ interface ListItemInterface {
* @param array $data - The data with which to update the list item
* @return Response
*/
- public function update(string $id, array $data): Response;
+ public function update(string $id, array $data): Request;
/**
* Delete a list item
@@ -54,5 +54,5 @@ interface ListItemInterface {
* @param string $id - The id of the list item to delete
* @return bool
*/
- public function delete(string $id): bool;
+ public function delete(string $id): Request;
}
\ No newline at end of file
diff --git a/src/API/MAL/ListItem.php b/src/API/MAL/ListItem.php
index 8c87b166..d1d16dfd 100644
--- a/src/API/MAL/ListItem.php
+++ b/src/API/MAL/ListItem.php
@@ -16,7 +16,7 @@
namespace Aviat\AnimeClient\API\MAL;
-use Amp\Artax\FormBody;
+use Amp\Artax\Request;
use Aviat\AnimeClient\API\{
AbstractListItem,
XML
@@ -30,7 +30,7 @@ class ListItem {
use ContainerAware;
use MALTrait;
- public function create(array $data)
+ public function create(array $data): Request
{
$id = $data['id'];
$createData = [
@@ -40,29 +40,36 @@ class ListItem {
])
];
- // $config = $this->container->get('config');
+ $config = $this->container->get('config');
- /*$request = $this->requestBuilder->newRequest('POST', "animelist/add/{$id}.xml")
+ return $this->requestBuilder->newRequest('POST', "animelist/add/{$id}.xml")
->setFormFields($createData)
->setBasicAuth($config->get(['mal','username']), $config->get(['mal', 'password']))
- ->getFullRequest();*/
+ ->getFullRequest();
- $response = $this->getResponse('POST', "animelist/add/{$id}.xml", [
+ /* $response = $this->getResponse('POST', "animelist/add/{$id}.xml", [
'body' => $this->fixBody((new FormBody)->addFields($createData))
]);
- return $response->getBody() === 'Created';
-
- // return $request;
+ return $response->getBody() === 'Created'; */
}
- public function delete(string $id): bool
+ public function delete(string $id): Request
{
- $response = $this->getResponse('DELETE', "animelist/delete/{$id}.xml", [
+ $config = $this->container->get('config');
+
+ return $this->requestBuilder->newRequest('DELETE', "animelist/delete/{$id}.xml")
+ ->setFormFields([
+ 'id' => $id
+ ])
+ ->setBasicAuth($config->get(['mal','username']), $config->get(['mal', 'password']))
+ ->getFullRequest();
+
+ /*$response = $this->getResponse('DELETE', "animelist/delete/{$id}.xml", [
'body' => $this->fixBody((new FormBody)->addField('id', $id))
]);
- return $response->getBody() === 'Deleted';
+ return $response->getBody() === 'Deleted';*/
}
public function get(string $id): array
@@ -70,15 +77,25 @@ class ListItem {
return [];
}
- public function update(string $id, array $data)
+ public function update(string $id, array $data): Request
{
+ $config = $this->container->get('config');
+
$xml = XML::toXML(['entry' => $data]);
$body = (new FormBody)
->addField('id', $id)
->addField('data', $xml);
- return $this->getResponse('POST', "animelist/update/{$id}.xml", [
+ return $this->requestBuilder->newRequest('POST', "animelist/update/{$id}.xml")
+ ->setFormFields([
+ 'id' => $id,
+ 'data' => $xml
+ ])
+ ->setBasicAuth($config->get(['mal','username']), $config->get(['mal', 'password']))
+ ->getFullRequest();
+
+ /* return $this->getResponse('POST', "animelist/update/{$id}.xml", [
'body' => $this->fixBody($body)
- ]);
+ ]); */
}
}
\ No newline at end of file
diff --git a/src/API/MAL/MALTrait.php b/src/API/MAL/MALTrait.php
index 8769f632..ba69da6e 100644
--- a/src/API/MAL/MALTrait.php
+++ b/src/API/MAL/MALTrait.php
@@ -85,7 +85,7 @@ trait MALTrait {
* @param string $type
* @param string $url
* @param array $options
- * @return \Amp\Promise
+ * @return \Amp\Artax\Response
*/
public function setUpRequest(string $type, string $url, array $options = [])
{
diff --git a/src/API/MAL/Model.php b/src/API/MAL/Model.php
index a2d0633e..e8458121 100644
--- a/src/API/MAL/Model.php
+++ b/src/API/MAL/Model.php
@@ -16,6 +16,7 @@
namespace Aviat\AnimeClient\API\MAL;
+use Amp\Artax\Request;
use Aviat\AnimeClient\API\MAL as M;
use Aviat\AnimeClient\API\MAL\ListItem;
use Aviat\AnimeClient\API\MAL\Transformer\AnimeListTransformer;
@@ -43,7 +44,7 @@ class Model {
$this->listItem = $listItem;
}
- public function createListItem(array $data): bool
+ public function createListItem(array $data): Request
{
$createData = [
'id' => $data['id'],
@@ -77,13 +78,13 @@ class Model {
return [];
}
- public function updateListItem(array $data)
+ public function updateListItem(array $data): Request
{
$updateData = $this->animeListTransformer->untransform($data);
return $this->listItem->update($updateData['id'], $updateData['data']);
}
- public function deleteListItem(string $id): bool
+ public function deleteListItem(string $id): Request
{
return $this->listItem->delete($id);
}
diff --git a/src/AnimeClient.php b/src/AnimeClient.php
index 0ffaca69..b43531bd 100644
--- a/src/AnimeClient.php
+++ b/src/AnimeClient.php
@@ -20,50 +20,43 @@ use Yosymfony\Toml\Toml;
define('SRC_DIR', realpath(__DIR__));
+const SESSION_SEGMENT = 'Aviat\AnimeClient\Auth';
+const DEFAULT_CONTROLLER_NAMESPACE = 'Aviat\AnimeClient\Controller';
+const DEFAULT_CONTROLLER = 'Aviat\AnimeClient\Controller\Anime';
+const DEFAULT_CONTROLLER_METHOD = 'index';
+const NOT_FOUND_METHOD = 'notFound';
+const ERROR_MESSAGE_METHOD = 'errorPage';
+const SRC_DIR = SRC_DIR;
+
/**
- * Application constants
+ * Load configuration options from .toml files
+ *
+ * @param string $path - Path to load config
+ * @return array
*/
-class AnimeClient {
+function loadToml(string $path): array
+{
+ $output = [];
+ $files = glob("{$path}/*.toml");
- const SESSION_SEGMENT = 'Aviat\AnimeClient\Auth';
- const DEFAULT_CONTROLLER_NAMESPACE = 'Aviat\AnimeClient\Controller';
- const DEFAULT_CONTROLLER = 'Aviat\AnimeClient\Controller\Anime';
- const DEFAULT_CONTROLLER_METHOD = 'index';
- const NOT_FOUND_METHOD = 'notFound';
- const ERROR_MESSAGE_METHOD = 'errorPage';
- const SRC_DIR = SRC_DIR;
-
- /**
- * Load configuration options from .toml files
- *
- * @param string $path - Path to load config
- * @return array
- */
- public static function loadToml(string $path): array
+ foreach ($files as $file)
{
- $output = [];
- $files = glob("{$path}/*.toml");
+ $key = str_replace('.toml', '', basename($file));
+ $toml = file_get_contents($file);
+ $config = Toml::Parse($toml);
- foreach ($files as $file)
+ if ($key === 'config')
{
- $key = str_replace('.toml', '', basename($file));
- $toml = file_get_contents($file);
- $config = Toml::Parse($toml);
-
- if ($key === 'config')
+ foreach($config as $name => $value)
{
- foreach($config as $name => $value)
- {
- $output[$name] = $value;
- }
-
- continue;
+ $output[$name] = $value;
}
- $output[$key] = $config;
+ continue;
}
- return $output;
+ $output[$key] = $config;
}
-}
-// End of AnimeClient.php
\ No newline at end of file
+
+ return $output;
+}
\ No newline at end of file
diff --git a/src/Command/BaseCommand.php b/src/Command/BaseCommand.php
index e929578f..63fc16c6 100644
--- a/src/Command/BaseCommand.php
+++ b/src/Command/BaseCommand.php
@@ -16,21 +16,18 @@
namespace Aviat\AnimeClient\Command;
+use function Aviat\AnimeClient\loadToml;
+
use Aura\Session\SessionFactory;
use Aviat\AnimeClient\{
AnimeClient,
Model,
Util
};
-use Aviat\AnimeClient\API\CacheTrait;
-use Aviat\AnimeClient\API\Kitsu\{
- Auth as KitsuAuth,
- ListItem as KitsuListItem,
- Model as KitsuModel
-};
-use Aviat\AnimeClient\API\MAL\{
- ListItem as MALListItem,
- Model as MALModel
+use Aviat\AnimeClient\API\{
+ CacheTrait,
+ Kitsu,
+ MAL
};
use Aviat\Banker\Pool;
use Aviat\Ion\Config;
@@ -72,23 +69,26 @@ class BaseCommand extends Command {
$CONF_DIR = realpath("{$APP_DIR}/config/");
require_once $CONF_DIR . '/base_config.php'; // $base_config
- $config = AnimeClient::loadToml($CONF_DIR);
+ $config = loadToml($CONF_DIR);
$config_array = array_merge($base_config, $config);
$di = function ($config_array) use ($APP_DIR) {
$container = new Container();
-
+
// -------------------------------------------------------------------------
// Logging
// -------------------------------------------------------------------------
$app_logger = new Logger('animeclient');
$app_logger->pushHandler(new NullHandler);
- $request_logger = new Logger('request');
- $request_logger->pushHandler(new NullHandler);
+ $kitsu_request_logger = new Logger('kitsu-request');
+ $kitsu_request_logger->pushHandler(new NullHandler);
+ $mal_request_logger = new Logger('mal-request');
+ $mal_request_logger->pushHandler(new NullHandler);
$container->setLogger($app_logger, 'default');
- $container->setLogger($request_logger, 'request');
-
+ $container->setLogger($kitsu_request_logger, 'kitsu-request');
+ $container->setLogger($mal_request_logger, 'mal-request');
+
// Create Config Object
$container->set('config', function() use ($config_array) {
return new Config($config_array);
@@ -108,18 +108,18 @@ class BaseCommand extends Command {
// Models
$container->set('kitsu-model', function($container) {
- $listItem = new KitsuListItem();
+ $listItem = new Kitsu\istItem();
$listItem->setContainer($container);
- $model = new KitsuModel($listItem);
+ $model = new Kitsu\Model($listItem);
$model->setContainer($container);
$cache = $container->get('cache');
$model->setCache($cache);
return $model;
});
$container->set('mal-model', function($container) {
- $listItem = new MALListItem();
+ $listItem = new MAL\ListItem();
$listItem->setContainer($container);
- $model = new MALModel($listItem);
+ $model = new MAL\Model($listItem);
$model->setContainer($container);
return $model;
});
diff --git a/src/Command/SyncKitsuWithMal.php b/src/Command/SyncKitsuWithMal.php
index 93a714c2..d7f13daf 100644
--- a/src/Command/SyncKitsuWithMal.php
+++ b/src/Command/SyncKitsuWithMal.php
@@ -23,49 +23,10 @@ use Aviat\AnimeClient\API\Kitsu;
* Clears the API Cache
*/
class SyncKitsuWithMal extends BaseCommand {
-
+
protected $kitsuModel;
-
- public function getKitsuAnimeListPageCount()
- {
- $cacheItem = $this->cache->getItem(Kitsu::AUTH_TOKEN_CACHE_KEY);
-
- $query = http_build_query([
- 'filter' => [
- 'user_id' => $this->kitsuModel->getUserIdByUsername(),
- 'media_type' => 'Anime'
- ],
- 'include' => 'anime,anime.genres,anime.mappings,anime.streamingLinks',
- 'page' => [
- 'limit' => 1
- ],
- 'sort' => '-updated_at'
- ]);
- $request = (new Artax\Request)
- ->setUri("https://kitsu.io/api/edge/library-entries?{$query}")
- ->setProtocol('1.1')
- ->setAllHeaders([
- 'Accept' => 'application/vnd.api+json',
- 'Content-Type' => 'application/vnd.api+json',
- 'User-Agent' => "Tim's Anime Client/4.0"
- ]);
-
- if ($cacheItem->isHit())
- {
- $token = $cacheItem->get();
- $request->setHeader('Authorization', "bearer {$token}");
- }
- else
- {
- $this->echoBox("WARNING: NOT LOGGED IN\nSome data might be missing");
- }
-
- $response = \Amp\wait((new Artax\Client)->request($request));
-
- $body = json_decode($response->getBody(), TRUE);
- return $body['meta']['count'];
- }
-
+ protected $malModel;
+
/**
* Run the image conversion script
*
@@ -79,8 +40,102 @@ class SyncKitsuWithMal extends BaseCommand {
$this->setContainer($this->setupContainer());
$this->setCache($this->container->get('cache'));
$this->kitsuModel = $this->container->get('kitsu-model');
-
- $kitsuCount = $this->getKitsuAnimeListPageCount();
- $this->echoBox("List item count: {$kitsuCount}");
+ $this->malModel = $this->container->get('mal-model');
+
+ //$kitsuCount = $this->getKitsuAnimeListPageCount();
+ //$this->echoBox("List item count: {$kitsuCount}");
+ $this->MALItemCreate();
+
+ //echo json_encode($this->getMALList(), \JSON_PRETTY_PRINT);
}
-}
+
+
+ public function getMALList()
+ {
+ return $this->malModel->getFullList();
+ }
+
+ public function getKitsuAnimeListPageCount()
+ {
+ $cacheItem = $this->cache->getItem(Kitsu::AUTH_TOKEN_CACHE_KEY);
+
+ $query = http_build_query([
+ 'filter' => [
+ 'user_id' => $this->kitsuModel->getUserIdByUsername(),
+ 'media_type' => 'Anime'
+ ],
+ // 'include' => 'anime,anime.genres,anime.mappings,anime.streamingLinks',
+ 'page' => [
+ 'limit' => 1
+ ],
+ 'sort' => '-updated_at'
+ ]);
+ $request = (new Artax\Request)
+ ->setUri("https://kitsu.io/api/edge/library-entries?{$query}")
+ ->setProtocol('1.1')
+ ->setAllHeaders([
+ 'Accept' => 'application/vnd.api+json',
+ 'Content-Type' => 'application/vnd.api+json',
+ 'User-Agent' => "Tim's Anime Client/4.0"
+ ]);
+
+ if ($cacheItem->isHit())
+ {
+ $token = $cacheItem->get();
+ $request->setHeader('Authorization', "bearer {$token}");
+ }
+ else
+ {
+ $this->echoBox("WARNING: NOT LOGGED IN\nSome data might be missing");
+ }
+
+ $response = \Amp\wait((new Artax\Client)->request($request));
+
+ $body = json_decode($response->getBody(), TRUE);
+ return $body['meta']['count'];
+ }
+
+ public function MALItemCreate()
+ {
+ $input = json_decode('{
+ "watching_status": "current",
+ "user_rating": "",
+ "episodes_watched": "4",
+ "rewatched": "0",
+ "notes": "",
+ "id": "15794526",
+ "mal_id": "33731",
+ "edit": "true"
+ }', TRUE);
+
+ $response = $this->malModel->createListItem([
+ 'id' => 12255,
+ 'status' => 'planned',
+ 'type' => 'anime'
+ ]);
+
+ //$response = $this->malModel->updateListItem($input);
+ //print_r($response);
+ //echo $response->getBody();
+
+ }
+
+ public function diffLists()
+ {
+ // Get libraryEntries with media.mappings from Kitsu
+ // Organize mappings, and ignore entries without mappings
+
+ // Get MAL list data
+
+ // Compare each list entry
+ // If a list item exists only on MAL, create it on Kitsu with the existing data from MAL
+ // If a list item exists only on Kitsu, create it on MAL with the existing data from Kitsu
+ // If an item already exists on both APIS:
+ // Compare last updated dates, and use the later one
+ // Otherwise, use rewatch count, then episode progress as critera for selecting the more up
+ // to date entry
+ // Based on the 'newer' entry, update the other api list item
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/Controller.php b/src/Controller.php
index 91148358..e83d71cd 100644
--- a/src/Controller.php
+++ b/src/Controller.php
@@ -16,6 +16,8 @@
namespace Aviat\AnimeClient;
+use const Aviat\AnimeClient\SESSION_SEGMENT;
+
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
use Aviat\Ion\View\{HtmlView, HttpView, JsonView};
use InvalidArgumentException;
@@ -102,7 +104,7 @@ class Controller {
$this->urlGenerator = $urlGenerator;
$session = $container->get('session');
- $this->session = $session->getSegment(AnimeClient::SESSION_SEGMENT);
+ $this->session = $session->getSegment(SESSION_SEGMENT);
// Set a 'previous' flash value for better redirects
$server_params = $this->request->getServerParams();
diff --git a/src/Dispatcher.php b/src/Dispatcher.php
index 9b5892aa..f06a185b 100644
--- a/src/Dispatcher.php
+++ b/src/Dispatcher.php
@@ -16,9 +16,16 @@
namespace Aviat\AnimeClient;
+use const Aviat\AnimeClient\{
+ DEFAULT_CONTROLLER,
+ DEFAULT_CONTROLLER_NAMESPACE,
+ ERROR_MESSAGE_METHOD,
+ NOT_FOUND_METHOD,
+ SRC_DIR
+};
+
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Friend;
-use GuzzleHttp\Exception\ServerException;
/**
* Basic routing/ dispatch
@@ -125,27 +132,12 @@ class Dispatcher extends RoutingBase {
// If not route was matched, return an appropriate http
// error message
$error_route = $this->getErrorParams();
- $controllerName = AnimeClient::DEFAULT_CONTROLLER;
+ $controllerName = DEFAULT_CONTROLLER;
$actionMethod = $error_route['action_method'];
$params = $error_route['params'];
}
-
- // Try to catch API errors in a presentable fashion
- try
- {
- // Actually instantiate the controller
- $this->call($controllerName, $actionMethod, $params);
- }
- catch (ServerException $e)
- {
- $response = $e->getResponse();
- $this->call(AnimeClient::DEFAULT_CONTROLLER, AnimeClient::ERROR_MESSAGE_METHOD, [
- $response->getStatusCode(),
- 'API Error',
- 'There was a problem getting data from an external source.',
- (string) $response->getBody()
- ]);
- }
+
+ $this->call($controllerName, $actionMethod, $params);
}
/**
@@ -176,7 +168,7 @@ class Dispatcher extends RoutingBase {
$action_method = (array_key_exists('action', $route->attributes))
? $route->attributes['action']
- : AnimeClient::NOT_FOUND_METHOD;
+ : NOT_FOUND_METHOD;
$params = [];
if ( ! empty($route->__get('tokens')))
@@ -229,11 +221,11 @@ class Dispatcher extends RoutingBase {
*/
public function getControllerList()
{
- $default_namespace = AnimeClient::DEFAULT_CONTROLLER_NAMESPACE;
+ $default_namespace = DEFAULT_CONTROLLER_NAMESPACE;
$path = str_replace('\\', '/', $default_namespace);
$path = str_replace('Aviat/AnimeClient/', '', $path);
$path = trim($path, '/');
- $actual_path = realpath(_dir(AnimeClient::SRC_DIR, $path));
+ $actual_path = realpath(_dir(SRC_DIR, $path));
$class_files = glob("{$actual_path}/*.php");
$controllers = [];
@@ -285,7 +277,7 @@ class Dispatcher extends RoutingBase {
$logger->info('Dispatcher - failed route');
$logger->info(print_r($failure, TRUE));
- $action_method = AnimeClient::ERROR_MESSAGE_METHOD;
+ $action_method = ERROR_MESSAGE_METHOD;
$params = [];
@@ -308,7 +300,7 @@ class Dispatcher extends RoutingBase {
default:
// Fall back to a 404 message
- $action_method = AnimeClient::NOT_FOUND_METHOD;
+ $action_method = NOT_FOUND_METHOD;
break;
}
@@ -337,7 +329,7 @@ class Dispatcher extends RoutingBase {
$controller_map = $this->getControllerList();
$controller_class = (array_key_exists($route_type, $controller_map))
? $controller_map[$route_type]
- : AnimeClient::DEFAULT_CONTROLLER;
+ : DEFAULT_CONTROLLER;
if (array_key_exists($route_type, $controller_map))
{
diff --git a/src/Model/API.php b/src/Model/API.php
index d2c423af..24879073 100644
--- a/src/Model/API.php
+++ b/src/Model/API.php
@@ -38,12 +38,6 @@ class API extends Model {
*/
protected $cache;
- /**
- * Default settings for Guzzle
- * @var array
- */
- protected $connectionDefaults = [];
-
/**
* Constructor
*
@@ -74,4 +68,4 @@ class API extends Model {
array_multisort($sort, SORT_ASC, $array);
}
-}
+}
\ No newline at end of file
diff --git a/src/Model/Anime.php b/src/Model/Anime.php
index 14bc58a1..328c8819 100644
--- a/src/Model/Anime.php
+++ b/src/Model/Anime.php
@@ -15,6 +15,10 @@
*/
namespace Aviat\AnimeClient\Model;
+
+use function Amp\some;
+use function Amp\wait;
+use Amp\Artax\Client;
use Aviat\AnimeClient\API\Kitsu\Enum\AnimeWatchingStatus;
use Aviat\Ion\Di\ContainerInterface;
use Aviat\Ion\Json;
@@ -91,9 +95,15 @@ class Anime extends API {
return $this->kitsuModel->getAnime($slug);
}
- public function getAnimeById($anime_id)
+ /**
+ * Get anime by its kitsu id
+ *
+ * @param string $animeId
+ * @return array
+ */
+ public function getAnimeById($animeId)
{
- return $this->kitsuModel->getAnimeById($anime_id);
+ return $this->kitsuModel->getAnimeById($animeId);
}
/**
@@ -104,7 +114,6 @@ class Anime extends API {
*/
public function search($name)
{
- // $raw = $this->kitsuModel->search('anime', $name);
return $this->kitsuModel->search('anime', $name);
}
@@ -128,6 +137,8 @@ class Anime extends API {
*/
public function createLibraryItem(array $data): bool
{
+ $requests = [];
+
if ($this->useMALAPI)
{
$malData = $data;
@@ -136,11 +147,17 @@ class Anime extends API {
if ( ! is_null($malId))
{
$malData['id'] = $malId;
- $this->malModel->createListItem($malData);
+ $requests['mal'] = $this->malModel->createListItem($malData);
}
}
- return $this->kitsuModel->createListItem($data);
+ $requests['kitsu'] = $this->kitsuModel->createListItem($data);
+
+ $promises = (new Client)->requestMulti($requests);
+
+ $results = wait(some($promises));
+
+ return count($results[1]) > 0;
}
/**
@@ -168,12 +185,18 @@ class Anime extends API {
*/
public function deleteLibraryItem(string $id, string $malId = null): bool
{
+ $requests = [];
+
if ($this->useMALAPI && ! is_null($malId))
{
- $this->malModel->deleteListItem($malId);
+ $requests['mal'] = $this->malModel->deleteListItem($malId);
}
- return $this->kitsuModel->deleteListItem($id);
+ $requests['kitsu'] = $this->kitsuModel->deleteListItem($id);
+
+ $results = wait(some((new Client)->requestMulti($requests)));
+
+ return count($results[1]) > 0;
}
}
// End of AnimeModel.php
\ No newline at end of file
diff --git a/tests/API/APIRequestBuilderTest.php b/tests/API/APIRequestBuilderTest.php
index 4b3b10aa..f2050e86 100644
--- a/tests/API/APIRequestBuilderTest.php
+++ b/tests/API/APIRequestBuilderTest.php
@@ -29,13 +29,13 @@ class APIRequestBuilderTest extends TestCase {
{
$this->builder = new class extends APIRequestBuilder {
protected $baseUrl = 'https://httpbin.org/';
-
+
protected $defaultHeaders = ['User-Agent' => "Tim's Anime Client Testsuite / 4.0"];
};
-
+
$this->builder->setLogger(new NullLogger);
}
-
+
public function testGzipRequest()
{
$request = $this->builder->newRequest('GET', 'gzip')
@@ -44,26 +44,26 @@ class APIRequestBuilderTest extends TestCase {
$body = Json::decode($response->getBody());
$this->assertEquals(1, $body['gzipped']);
}
-
+
public function testInvalidRequestMethod()
{
$this->expectException(\InvalidArgumentException::class);
$this->builder->newRequest('FOO', 'gzip')
->getFullRequest();
}
-
+
public function testRequestWithBasicAuth()
{
$request = $this->builder->newRequest('GET', 'headers')
->setBasicAuth('username', 'password')
->getFullRequest();
-
+
$response = Amp\wait((new Client)->request($request));
$body = Json::decode($response->getBody());
-
+
$this->assertEquals('Basic dXNlcm5hbWU6cGFzc3dvcmQ=', $body['headers']['Authorization']);
}
-
+
public function testRequestWithQueryString()
{
$query = [
@@ -75,40 +75,40 @@ class APIRequestBuilderTest extends TestCase {
'bar' => 'foo'
]
];
-
+
$expected = [
'foo' => 'bar',
'bar[foo]' => 'bar',
'baz[bar]' => 'foo'
];
-
+
$request = $this->builder->newRequest('GET', 'get')
->setQuery($query)
->getFullRequest();
-
+
$response = Amp\wait((new Client)->request($request));
$body = Json::decode($response->getBody());
-
- $this->assertEquals($expected, $body['args']);
+
+ $this->assertEquals($expected, $body['args']);
}
-
+
public function testFormValueRequest()
{
$formValues = [
'foo' => 'bar',
'bar' => 'foo'
];
-
+
$request = $this->builder->newRequest('POST', 'post')
->setFormFields($formValues)
->getFullRequest();
-
+
$response = Amp\wait((new Client)->request($request));
$body = Json::decode($response->getBody());
-
+
$this->assertEquals($formValues, $body['form']);
}
-
+
public function testFullUrlRequest()
{
$data = [
@@ -121,16 +121,15 @@ class APIRequestBuilderTest extends TestCase {
]
]
];
-
+
$request = $this->builder->newRequest('PUT', 'https://httpbin.org/put')
->setHeader('Content-Type', 'application/json')
- ->setBody(Json::encode($data))
+ ->setJsonBody($data)
->getFullRequest();
-
+
$response = Amp\wait((new Client)->request($request));
$body = Json::decode($response->getBody());
-
+
$this->assertEquals($data, $body['json']);
}
-}
-
+}
\ No newline at end of file
diff --git a/tests/AnimeClient_TestCase.php b/tests/AnimeClient_TestCase.php
index 6e8ab7fa..90733e39 100644
--- a/tests/AnimeClient_TestCase.php
+++ b/tests/AnimeClient_TestCase.php
@@ -1,12 +1,10 @@
$handler]);
-
- return $client;
- }
}
// End of AnimeClient_TestCase.php
\ No newline at end of file