Version 5.1 - All the GraphQL #32
@ -84,18 +84,6 @@ class KitsuModel {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function getAnimeGenres($animeId): array
|
|
||||||
{
|
|
||||||
return $this->getGenres('anime', $animeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getMangaGenres($mangaId): array
|
|
||||||
{
|
|
||||||
return $this->getGenres('manga', $mangaId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAnime(string $animeId): array
|
public function getAnime(string $animeId): array
|
||||||
{
|
{
|
||||||
$baseData = $this->getRawAnimeData($animeId);
|
$baseData = $this->getRawAnimeData($animeId);
|
||||||
@ -121,7 +109,7 @@ class KitsuModel {
|
|||||||
'media_type' => 'Anime',
|
'media_type' => 'Anime',
|
||||||
'status' => $status,
|
'status' => $status,
|
||||||
],
|
],
|
||||||
'include' => 'media,user',
|
'include' => 'media',
|
||||||
'page' => [
|
'page' => [
|
||||||
'offset' => 0,
|
'offset' => 0,
|
||||||
'limit' => 200
|
'limit' => 200
|
||||||
@ -132,9 +120,9 @@ class KitsuModel {
|
|||||||
|
|
||||||
$data = $this->getRequest('library-entries', $options);
|
$data = $this->getRequest('library-entries', $options);
|
||||||
|
|
||||||
foreach($data['data'] as &$item)
|
foreach($data['data'] as $i => &$item)
|
||||||
{
|
{
|
||||||
$item['anime'] = $this->getRawAnimeData($item['relationships']['media']['data']['id']);
|
$item['anime'] = $data['included'][$i];
|
||||||
}
|
}
|
||||||
|
|
||||||
$transformed = $this->animeListTransformer->transformCollection($data['data']);
|
$transformed = $this->animeListTransformer->transformCollection($data['data']);
|
||||||
|
@ -120,7 +120,7 @@ trait KitsuTrait {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove some boilerplate for get requests
|
* Remove some boilerplate for post requests
|
||||||
*
|
*
|
||||||
* @param array $args
|
* @param array $args
|
||||||
* @return array
|
* @return array
|
||||||
@ -129,4 +129,15 @@ trait KitsuTrait {
|
|||||||
{
|
{
|
||||||
return $this->request('POST', ...$args);
|
return $this->request('POST', ...$args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove some boilerplate for delete requests
|
||||||
|
*
|
||||||
|
* @param array $args
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function deleteRequest(...$args): array
|
||||||
|
{
|
||||||
|
return $this->request('DELETE', ...$args);
|
||||||
|
}
|
||||||
}
|
}
|
@ -33,18 +33,18 @@ class AnimeListTransformer extends AbstractTransformer {
|
|||||||
public function transform($item)
|
public function transform($item)
|
||||||
{
|
{
|
||||||
/* ?><pre><?= print_r($item, TRUE) ?></pre><?php
|
/* ?><pre><?= print_r($item, TRUE) ?></pre><?php
|
||||||
die();*/
|
// die(); */
|
||||||
$anime =& $item['anime'];
|
$anime =& $item['anime'];
|
||||||
$genres = $item['anime']['genres'] ?? [];
|
$genres = $item['anime']['genres'] ?? [];
|
||||||
|
|
||||||
$rating = (int) 2 * $item['attributes']['rating'];
|
$rating = (int) 2 * $item['attributes']['rating'];
|
||||||
|
|
||||||
$total_episodes = is_numeric($anime['episodeCount'])
|
$total_episodes = array_key_exists('episodeCount', $item['anime'])
|
||||||
? $anime['episodeCount']
|
? (int) $anime['episodeCount']
|
||||||
: '-';
|
: '-';
|
||||||
|
|
||||||
$alternate_title = NULL;
|
$alternate_title = NULL;
|
||||||
if (array_key_exists('en_jp', $anime['titles']))
|
if (array_key_exists('titles', $item['anime']) && array_key_exists('en_jp', $anime['titles']))
|
||||||
{
|
{
|
||||||
// If the alternate title is very similar, or
|
// If the alternate title is very similar, or
|
||||||
// a subset of the main title, don't list the
|
// a subset of the main title, don't list the
|
||||||
@ -62,21 +62,21 @@ die();*/
|
|||||||
'episodes' => [
|
'episodes' => [
|
||||||
'watched' => $item['attributes']['progress'],
|
'watched' => $item['attributes']['progress'],
|
||||||
'total' => $total_episodes,
|
'total' => $total_episodes,
|
||||||
'length' => $anime['episodeLength'],
|
'length' => $anime['attributes']['episodeLength'],
|
||||||
],
|
],
|
||||||
'airing' => [
|
'airing' => [
|
||||||
'status' => $anime['status'] ?? '',
|
'status' => $anime['status'] ?? '',
|
||||||
'started' => $anime['startDate'],
|
'started' => $anime['attributes']['startDate'],
|
||||||
'ended' => $anime['endDate']
|
'ended' => $anime['attributes']['endDate']
|
||||||
],
|
],
|
||||||
'anime' => [
|
'anime' => [
|
||||||
'age_rating' => $anime['ageRating'],
|
'age_rating' => $anime['attributes']['ageRating'],
|
||||||
'title' => $anime['canonicalTitle'],
|
'title' => $anime['attributes']['canonicalTitle'],
|
||||||
'alternate_title' => $alternate_title,
|
'alternate_title' => $alternate_title,
|
||||||
'slug' => $item['relationships']['media']['data']['id'],//$anime['slug'],
|
'slug' => $item['relationships']['media']['data']['id'],//$anime['slug'],
|
||||||
'url' => $anime['url'] ?? '',
|
'url' => $anime['attributes']['url'] ?? '',
|
||||||
'type' => $anime['showType'],
|
'type' => $anime['attributes']['showType'],
|
||||||
'image' => $anime['posterImage']['small'],
|
'image' => $anime['attributes']['posterImage']['small'],
|
||||||
'genres' => $genres,
|
'genres' => $genres,
|
||||||
],
|
],
|
||||||
'watching_status' => $item['attributes']['status'],
|
'watching_status' => $item['attributes']['status'],
|
||||||
|
@ -16,23 +16,11 @@
|
|||||||
|
|
||||||
namespace Aviat\AnimeClient\Model;
|
namespace Aviat\AnimeClient\Model;
|
||||||
|
|
||||||
use Aviat\AnimeClient\AnimeClient;
|
|
||||||
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
|
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
|
||||||
use Aviat\Ion\Model;
|
use Aviat\Ion\Model;
|
||||||
use GuzzleHttp\Client;
|
|
||||||
use GuzzleHttp\Cookie\CookieJar;
|
|
||||||
use Psr\Http\Message\ResponseInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base model for api interaction
|
* Base model for api interaction
|
||||||
*
|
|
||||||
* @method ResponseInterface get(string $uri, array $options);
|
|
||||||
* @method ResponseInterface delete(string $uri, array $options);
|
|
||||||
* @method ResponseInterface head(string $uri, array $options);
|
|
||||||
* @method ResponseInterface options(string $uri, array $options);
|
|
||||||
* @method ResponseInterface patch(string $uri, array $options);
|
|
||||||
* @method ResponseInterface post(string $uri, array $options);
|
|
||||||
* @method ResponseInterface put(string $uri, array $options);
|
|
||||||
*/
|
*/
|
||||||
class API extends Model {
|
class API extends Model {
|
||||||
|
|
||||||
@ -44,24 +32,6 @@ class API extends Model {
|
|||||||
*/
|
*/
|
||||||
protected $config;
|
protected $config;
|
||||||
|
|
||||||
/**
|
|
||||||
* Base url for making api requests
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $base_url = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Guzzle http client object
|
|
||||||
* @var object
|
|
||||||
*/
|
|
||||||
protected $client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cookie jar object for api requests
|
|
||||||
* @var object
|
|
||||||
*/
|
|
||||||
protected $cookieJar;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache manager
|
* Cache manager
|
||||||
* @var \Aviat\Ion\Cache\CacheInterface
|
* @var \Aviat\Ion\Cache\CacheInterface
|
||||||
@ -83,87 +53,6 @@ class API extends Model {
|
|||||||
{
|
{
|
||||||
$this->container = $container;
|
$this->container = $container;
|
||||||
$this->config = $container->get('config');
|
$this->config = $container->get('config');
|
||||||
$this->cache = $container->get('cache');
|
|
||||||
$this->init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up the class properties
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function init()
|
|
||||||
{
|
|
||||||
$this->cookieJar = new CookieJar();
|
|
||||||
$this->client = new Client([
|
|
||||||
'base_uri' => $this->base_url,
|
|
||||||
'cookies' => TRUE,
|
|
||||||
'http_errors' => FALSE,
|
|
||||||
'defaults' => array_merge([
|
|
||||||
'cookies' => $this->cookieJar,
|
|
||||||
'headers' => [
|
|
||||||
'User-Agent' => "Tim's Anime Client/4.0",
|
|
||||||
'Accept-Encoding' => 'application/vnd.api+json',
|
|
||||||
'Content-Type' => 'application/vnd.api+json'
|
|
||||||
],
|
|
||||||
'timeout' => 25,
|
|
||||||
'connect_timeout' => 25
|
|
||||||
], $this->connectionDefaults)
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Magic methods to call guzzle api client
|
|
||||||
*
|
|
||||||
* @param string $method
|
|
||||||
* @param array $args
|
|
||||||
* @return ResponseInterface|null
|
|
||||||
*/
|
|
||||||
public function __call($method, $args)
|
|
||||||
{
|
|
||||||
$valid_methods = [
|
|
||||||
'get',
|
|
||||||
'getAsync',
|
|
||||||
'delete',
|
|
||||||
'deleteAsync',
|
|
||||||
'head',
|
|
||||||
'headAsync',
|
|
||||||
'options',
|
|
||||||
'optionsAsync',
|
|
||||||
'patch',
|
|
||||||
'patchAsync',
|
|
||||||
'post',
|
|
||||||
'postAsync',
|
|
||||||
'put',
|
|
||||||
'putAsync'
|
|
||||||
];
|
|
||||||
|
|
||||||
if ( ! in_array($method, $valid_methods))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
array_unshift($args, strtoupper($method));
|
|
||||||
return call_user_func_array([$this->client, 'request'], $args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the data for the specified library entry
|
|
||||||
*
|
|
||||||
* @param string $id
|
|
||||||
* @param string $status
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function get_library_item($id, $status)
|
|
||||||
{
|
|
||||||
$data = $this->_get_list_from_api($status);
|
|
||||||
$index_array = array_column($data, 'id');
|
|
||||||
|
|
||||||
$key = array_search($id, $index_array);
|
|
||||||
|
|
||||||
return $key !== FALSE
|
|
||||||
? $data[$key]
|
|
||||||
: [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -185,18 +74,5 @@ class API extends Model {
|
|||||||
|
|
||||||
array_multisort($sort, SORT_ASC, $array);
|
array_multisort($sort, SORT_ASC, $array);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Dummy function that should be abstract. Is not abstract because
|
|
||||||
* this class is used concretely for authorizing API calls
|
|
||||||
*
|
|
||||||
* @TODO Refactor, and make this abstract
|
|
||||||
* @param string $status
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
protected function _get_list_from_api(string $status): array
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// End of BaseApiModel.php
|
// End of BaseApiModel.php
|
@ -32,12 +32,6 @@ class Anime extends API {
|
|||||||
const ON_HOLD = 'On Hold';
|
const ON_HOLD = 'On Hold';
|
||||||
const COMPLETED = 'Completed';
|
const COMPLETED = 'Completed';
|
||||||
|
|
||||||
/**
|
|
||||||
* The base url for api requests
|
|
||||||
* @var string $base_url
|
|
||||||
*/
|
|
||||||
protected $base_url = "https://kitsu.io/api/edge/";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map of API status constants to display constants
|
* Map of API status constants to display constants
|
||||||
* @var array
|
* @var array
|
||||||
@ -60,91 +54,6 @@ class Anime extends API {
|
|||||||
$this->kitsuModel = $container->get('kitsu-model');
|
$this->kitsuModel = $container->get('kitsu-model');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the selected anime
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @return array|false
|
|
||||||
*/
|
|
||||||
public function update($data)
|
|
||||||
{
|
|
||||||
$auth = $this->container->get('auth');
|
|
||||||
if ( ! $auth->is_authenticated() OR ! array_key_exists('id', $data))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = $data['id'];
|
|
||||||
$data['auth_token'] = $auth->get_auth_token();
|
|
||||||
|
|
||||||
$response = $this->client->post("libraries/{$id}", [
|
|
||||||
'form_params' => $data
|
|
||||||
]);
|
|
||||||
|
|
||||||
return [
|
|
||||||
'statusCode' => $response->getStatusCode(),
|
|
||||||
'body' => Json::decode($response->getBody(), TRUE)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove an anime from a list
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @return array|false
|
|
||||||
*/
|
|
||||||
public function delete($data)
|
|
||||||
{
|
|
||||||
$auth = $this->container->get('auth');
|
|
||||||
if ( ! $auth->is_authenticated() OR ! array_key_exists('id', $data))
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = $data['id'];
|
|
||||||
$data['auth_token'] = $auth->get_auth_token();
|
|
||||||
|
|
||||||
$response = $this->client->post("libraries/{$id}/remove", [
|
|
||||||
'form_params' => $data
|
|
||||||
]);
|
|
||||||
|
|
||||||
return [
|
|
||||||
'statusCode' => $response->getStatusCode(),
|
|
||||||
'body' => Json::decode($response->getBody(), TRUE)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the full set of anime lists
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function get_all_lists()
|
|
||||||
{
|
|
||||||
$output = [
|
|
||||||
self::WATCHING => [],
|
|
||||||
self::PLAN_TO_WATCH => [],
|
|
||||||
self::ON_HOLD => [],
|
|
||||||
self::DROPPED => [],
|
|
||||||
self::COMPLETED => [],
|
|
||||||
];
|
|
||||||
|
|
||||||
$data = $this->_get_list_from_api();
|
|
||||||
|
|
||||||
foreach ($data as $datum)
|
|
||||||
{
|
|
||||||
$output[$this->const_map[$datum['watching_status']]][] = $datum;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort anime by name
|
|
||||||
foreach ($output as &$status_list)
|
|
||||||
{
|
|
||||||
$this->sort_by_name($status_list, 'anime');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a category out of the full list
|
* Get a category out of the full list
|
||||||
*
|
*
|
||||||
@ -172,52 +81,5 @@ class Anime extends API {
|
|||||||
{
|
{
|
||||||
return $this->kitsuModel->getAnime($anime_id);
|
return $this->kitsuModel->getAnime($anime_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Search for anime by name
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
* @return array
|
|
||||||
* @throws \RuntimeException
|
|
||||||
*/
|
|
||||||
public function search($name)
|
|
||||||
{
|
|
||||||
$logger = $this->container->getLogger('default');
|
|
||||||
|
|
||||||
$config = [
|
|
||||||
'query' => [
|
|
||||||
'query' => $name
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
$response = $this->get('search/anime', $config);
|
|
||||||
|
|
||||||
if ((int) $response->getStatusCode() !== 200)
|
|
||||||
{
|
|
||||||
$logger->warning("Non 200 response for search api call");
|
|
||||||
$logger->warning($response->getBody());
|
|
||||||
|
|
||||||
throw new \RuntimeException($response->getEffectiveUrl());
|
|
||||||
}
|
|
||||||
|
|
||||||
return Json::decode($response->getBody(), TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the full list from the api
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function get_raw_list()
|
|
||||||
{
|
|
||||||
$config = [
|
|
||||||
'allow_redirects' => FALSE
|
|
||||||
];
|
|
||||||
|
|
||||||
$username = $this->config->get('hummingbird_username');
|
|
||||||
|
|
||||||
$response = $this->get("users/{$username}/library", $config);
|
|
||||||
return Json::decode($response->getBody(), TRUE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// End of AnimeModel.php
|
// End of AnimeModel.php
|
Loading…
Reference in New Issue
Block a user