Version 5.1 - All the GraphQL #32
@ -84,18 +84,6 @@ class KitsuModel {
|
||||
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
|
||||
{
|
||||
$baseData = $this->getRawAnimeData($animeId);
|
||||
@ -121,7 +109,7 @@ class KitsuModel {
|
||||
'media_type' => 'Anime',
|
||||
'status' => $status,
|
||||
],
|
||||
'include' => 'media,user',
|
||||
'include' => 'media',
|
||||
'page' => [
|
||||
'offset' => 0,
|
||||
'limit' => 200
|
||||
@ -132,9 +120,9 @@ class KitsuModel {
|
||||
|
||||
$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']);
|
||||
|
@ -120,7 +120,7 @@ trait KitsuTrait {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove some boilerplate for get requests
|
||||
* Remove some boilerplate for post requests
|
||||
*
|
||||
* @param array $args
|
||||
* @return array
|
||||
@ -129,4 +129,15 @@ trait KitsuTrait {
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* ?><pre><?= print_r($item, TRUE) ?></pre><?php
|
||||
die();*/
|
||||
// die(); */
|
||||
$anime =& $item['anime'];
|
||||
$genres = $item['anime']['genres'] ?? [];
|
||||
|
||||
$rating = (int) 2 * $item['attributes']['rating'];
|
||||
|
||||
$total_episodes = is_numeric($anime['episodeCount'])
|
||||
? $anime['episodeCount']
|
||||
$total_episodes = array_key_exists('episodeCount', $item['anime'])
|
||||
? (int) $anime['episodeCount']
|
||||
: '-';
|
||||
|
||||
$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
|
||||
// a subset of the main title, don't list the
|
||||
@ -62,21 +62,21 @@ die();*/
|
||||
'episodes' => [
|
||||
'watched' => $item['attributes']['progress'],
|
||||
'total' => $total_episodes,
|
||||
'length' => $anime['episodeLength'],
|
||||
'length' => $anime['attributes']['episodeLength'],
|
||||
],
|
||||
'airing' => [
|
||||
'status' => $anime['status'] ?? '',
|
||||
'started' => $anime['startDate'],
|
||||
'ended' => $anime['endDate']
|
||||
'started' => $anime['attributes']['startDate'],
|
||||
'ended' => $anime['attributes']['endDate']
|
||||
],
|
||||
'anime' => [
|
||||
'age_rating' => $anime['ageRating'],
|
||||
'title' => $anime['canonicalTitle'],
|
||||
'age_rating' => $anime['attributes']['ageRating'],
|
||||
'title' => $anime['attributes']['canonicalTitle'],
|
||||
'alternate_title' => $alternate_title,
|
||||
'slug' => $item['relationships']['media']['data']['id'],//$anime['slug'],
|
||||
'url' => $anime['url'] ?? '',
|
||||
'type' => $anime['showType'],
|
||||
'image' => $anime['posterImage']['small'],
|
||||
'url' => $anime['attributes']['url'] ?? '',
|
||||
'type' => $anime['attributes']['showType'],
|
||||
'image' => $anime['attributes']['posterImage']['small'],
|
||||
'genres' => $genres,
|
||||
],
|
||||
'watching_status' => $item['attributes']['status'],
|
||||
|
@ -16,23 +16,11 @@
|
||||
|
||||
namespace Aviat\AnimeClient\Model;
|
||||
|
||||
use Aviat\AnimeClient\AnimeClient;
|
||||
use Aviat\Ion\Di\{ContainerAware, ContainerInterface};
|
||||
use Aviat\Ion\Model;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Cookie\CookieJar;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
@ -44,24 +32,6 @@ class API extends Model {
|
||||
*/
|
||||
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
|
||||
* @var \Aviat\Ion\Cache\CacheInterface
|
||||
@ -83,87 +53,6 @@ class API extends Model {
|
||||
{
|
||||
$this->container = $container;
|
||||
$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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
@ -32,12 +32,6 @@ class Anime extends API {
|
||||
const ON_HOLD = 'On Hold';
|
||||
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
|
||||
* @var array
|
||||
@ -60,91 +54,6 @@ class Anime extends API {
|
||||
$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
|
||||
*
|
||||
@ -172,52 +81,5 @@ class Anime extends API {
|
||||
{
|
||||
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
|
Loading…
Reference in New Issue
Block a user