Version 5.1 - All the GraphQL #32

Closed
timw4mail wants to merge 1160 commits from develop into master
15 changed files with 173 additions and 40 deletions
Showing only changes of commit ba8663b22a - Show all commits

View File

@ -10,6 +10,3 @@ whose_list = "Tim"
# do you wish to show the anime collection? # do you wish to show the anime collection?
show_anime_collection = true show_anime_collection = true
# path to public directory on the server
asset_dir = "/../../public"

View File

@ -29,10 +29,10 @@ use Aviat\AnimeClient\API\Enum\{
* Constants and mappings for the Anilist API * Constants and mappings for the Anilist API
*/ */
final class Anilist { final class Anilist {
const AUTH_URL = 'https://anilist.co/api/v2/oauth/authorize'; public const AUTH_URL = 'https://anilist.co/api/v2/oauth/authorize';
const BASE_URL = 'https://graphql.anilist.co'; public const BASE_URL = 'https://graphql.anilist.co';
const KITSU_ANILIST_WATCHING_STATUS_MAP = [ public const KITSU_ANILIST_WATCHING_STATUS_MAP = [
KAWS::WATCHING => AnimeWatchingStatus::WATCHING, KAWS::WATCHING => AnimeWatchingStatus::WATCHING,
KAWS::COMPLETED => AnimeWatchingStatus::COMPLETED, KAWS::COMPLETED => AnimeWatchingStatus::COMPLETED,
KAWS::ON_HOLD => AnimeWatchingStatus::ON_HOLD, KAWS::ON_HOLD => AnimeWatchingStatus::ON_HOLD,
@ -40,7 +40,7 @@ final class Anilist {
KAWS::PLAN_TO_WATCH => AnimeWatchingStatus::PLAN_TO_WATCH, KAWS::PLAN_TO_WATCH => AnimeWatchingStatus::PLAN_TO_WATCH,
]; ];
const ANILIST_KITSU_WATCHING_STATUS_MAP = [ public const ANILIST_KITSU_WATCHING_STATUS_MAP = [
AnimeWatchingStatus::WATCHING => KAWS::WATCHING, AnimeWatchingStatus::WATCHING => KAWS::WATCHING,
AnimeWatchingStatus::COMPLETED => KAWS::COMPLETED, AnimeWatchingStatus::COMPLETED => KAWS::COMPLETED,
AnimeWatchingStatus::ON_HOLD => KAWS::ON_HOLD, AnimeWatchingStatus::ON_HOLD => KAWS::ON_HOLD,
@ -48,7 +48,7 @@ final class Anilist {
AnimeWatchingStatus::PLAN_TO_WATCH => KAWS::PLAN_TO_WATCH, AnimeWatchingStatus::PLAN_TO_WATCH => KAWS::PLAN_TO_WATCH,
]; ];
const KITSU_ANILIST_READING_STATUS_MAP = [ public const KITSU_ANILIST_READING_STATUS_MAP = [
KMRS::READING => MangaReadingStatus::READING, KMRS::READING => MangaReadingStatus::READING,
KMRS::COMPLETED => MangaReadingStatus::COMPLETED, KMRS::COMPLETED => MangaReadingStatus::COMPLETED,
KMRS::ON_HOLD => MangaReadingStatus::ON_HOLD, KMRS::ON_HOLD => MangaReadingStatus::ON_HOLD,
@ -56,7 +56,7 @@ final class Anilist {
KMRS::PLAN_TO_READ => MangaReadingStatus::PLAN_TO_READ, KMRS::PLAN_TO_READ => MangaReadingStatus::PLAN_TO_READ,
]; ];
const ANILIST_KITSU_READING_STATUS_MAP = [ public const ANILIST_KITSU_READING_STATUS_MAP = [
MangaReadingStatus::READING => KMRS::READING, MangaReadingStatus::READING => KMRS::READING,
MangaReadingStatus::COMPLETED => KMRS::COMPLETED, MangaReadingStatus::COMPLETED => KMRS::COMPLETED,
MangaReadingStatus::ON_HOLD => KMRS::ON_HOLD, MangaReadingStatus::ON_HOLD => KMRS::ON_HOLD,

View File

@ -341,9 +341,9 @@ final class Model {
* Get information about a particular anime * Get information about a particular anime
* *
* @param string $animeId * @param string $animeId
* @return array * @return Anime
*/ */
public function getAnimeById(string $animeId): array public function getAnimeById(string $animeId): Anime
{ {
$baseData = $this->getRawMediaDataById('anime', $animeId); $baseData = $this->getRawMediaDataById('anime', $animeId);
return $this->animeTransformer->transform($baseData); return $this->animeTransformer->transform($baseData);
@ -455,7 +455,7 @@ final class Model {
} }
/** /**
* Get all the anine entries, that are organized for output to html * Get all the anime entries, that are organized for output to html
* *
* @return array * @return array
*/ */

View File

@ -40,7 +40,7 @@ final class AnimeTransformer extends AbstractTransformer {
sort($item['genres']); sort($item['genres']);
$title = $item['canonicalTitle']; $title = $item['canonicalTitle'];
$titles = array_diff($item['titles'], [$title]); $titles = array_unique(array_diff($item['titles'], [$title]));
return new Anime([ return new Anime([
'age_rating' => $item['ageRating'], 'age_rating' => $item['ageRating'],

View File

@ -33,7 +33,6 @@ final class MangaTransformer extends AbstractTransformer {
*/ */
public function transform($item): MangaPage public function transform($item): MangaPage
{ {
// \dump($item);
$genres = []; $genres = [];
foreach($item['included'] as $included) foreach($item['included'] as $included)
@ -46,11 +45,13 @@ final class MangaTransformer extends AbstractTransformer {
sort($genres); sort($genres);
$title = $item['canonicalTitle'];
$titles = array_unique(array_diff($item['titles'], [$title]));
return new MangaPage([ return new MangaPage([
'id' => $item['id'], 'id' => $item['id'],
'title' => $item['canonicalTitle'], 'title' => $title,
'en_title' => $item['titles']['en'], 'titles' => $titles,
'jp_title' => $item['titles']['en_jp'],
'cover_image' => $item['posterImage']['small'], 'cover_image' => $item['posterImage']['small'],
'manga_type' => $item['mangaType'], 'manga_type' => $item['mangaType'],
'chapter_count' => $this->count($item['chapterCount']), 'chapter_count' => $this->count($item['chapterCount']),

View File

@ -85,11 +85,11 @@ final class ListItem {
* Update a list item * Update a list item
* *
* @param string $id * @param string $id
* @param AbstractType $data * @param array $data
* @param string $type * @param string $type
* @return Request * @return Request
*/ */
public function update(string $id, AbstractType $data, string $type = 'anime'): Request public function update(string $id, array $data, string $type = 'anime'): Request
{ {
$config = $this->container->get('config'); $config = $this->container->get('config');

View File

@ -148,11 +148,11 @@ final class Model {
/** /**
* Update a list item * Update a list item
* *
* @param FormItem $data * @param array $data
* @param string $type "anime" or "manga" * @param string $type "anime" or "manga"
* @return Request * @return Request
*/ */
public function updateListItem(FormItem $data, string $type = 'anime'): Request public function updateListItem($data, string $type = 'anime'): Request
{ {
$updateData = []; $updateData = [];

View File

@ -38,10 +38,10 @@ final class AnimeListTransformer extends AbstractTransformer {
/** /**
* Transform Kitsu episode data to MAL episode data * Transform Kitsu episode data to MAL episode data
* *
* @param array $item * @param mixed $item
* @return AnimeFormItem * @return array
*/ */
public function untransform(array $item): AnimeFormItem public function untransform($item): array
{ {
$map = [ $map = [
'id' => $item['mal_id'], 'id' => $item['mal_id'],
@ -81,6 +81,6 @@ final class AnimeListTransformer extends AbstractTransformer {
} }
} }
return new AnimeFormItem($map); return $map;
} }
} }

View File

@ -37,18 +37,16 @@ final class MangaListTransformer extends AbstractTransformer {
/** /**
* Transform Kitsu data to MAL data * Transform Kitsu data to MAL data
* *
* @param array $item * @param mixed $item
* @return array * @return
*/ */
public function untransform(array $item): array public function untransform($item): array
{ {
$map = [ $map = [
'id' => $item['mal_id'], 'id' => $item['mal_id'] ?? $item['malId'],
'data' => [] 'data' => []
]; ];
$data =& $item['data'];
foreach($item['data'] as $key => $value) foreach($item['data'] as $key => $value)
{ {
switch($key) switch($key)

View File

@ -17,7 +17,7 @@
namespace Aviat\AnimeClient; namespace Aviat\AnimeClient;
use Aviat\Ion\ConfigInterface; use Aviat\Ion\ConfigInterface;
use Yosymfony\Toml\Toml; use Yosymfony\Toml\{Toml, TomlBuilder};
/** /**
* Load configuration options from .toml files * Load configuration options from .toml files
@ -51,6 +51,86 @@ function loadToml(string $path): array
return $output; return $output;
} }
/**
* Is the array sequential, not associative?
*
* @param mixed $array
* @return bool
*/
function isSequentialArray($array): bool
{
if ( ! is_array($array))
{
return FALSE;
}
$i = 0;
foreach ($array as $k => $v)
{
if ($k !== $i++)
{
return FALSE;
}
}
return TRUE;
}
function _iterateToml(TomlBuilder $builder, $data, $parentKey = NULL): void
{
foreach ($data as $key => $value)
{
if ($value === NULL)
{
continue;
}
if (is_scalar($value) || isSequentialArray($value))
{
// $builder->addTable('');
$builder->addValue($key, $value);
continue;
}
$newKey = ($parentKey !== NULL)
? "{$parentKey}.{$key}"
: $key;
if ( ! isSequentialArray($value))
{
$builder->addTable($newKey);
}
_iterateToml($builder, $value, $newKey);
}
}
/**
* Serialize config data into a Toml file
*
* @param mixed $data
* @return string
*/
function arrayToToml($data): string
{
$builder = new TomlBuilder();
_iterateToml($builder, $data);
return $builder->getTomlString();
}
/**
* Serialize toml back to an array
*
* @param string $toml
* @return array
*/
function tomlToArray(string $toml): array
{
return Toml::parse($toml);
}
/** /**
* Check that folder permissions are correct for proper operation * Check that folder permissions are correct for proper operation
* *
@ -64,7 +144,6 @@ function checkFolderPermissions(ConfigInterface $config): array
$pathMap = [ $pathMap = [
'app/logs' => realpath(__DIR__ . '/../app/logs'), 'app/logs' => realpath(__DIR__ . '/../app/logs'),
'public/js/cache' => "{$publicDir}/js/cache",
'public/images/avatars' => "{$publicDir}/images/avatars", 'public/images/avatars' => "{$publicDir}/images/avatars",
'public/images/anime' => "{$publicDir}/images/anime", 'public/images/anime' => "{$publicDir}/images/anime",
'public/images/characters' => "{$publicDir}/images/characters", 'public/images/characters' => "{$publicDir}/images/characters",

View File

@ -170,9 +170,8 @@ final class Index extends BaseController {
$auth = $this->container->get('auth'); $auth = $this->container->get('auth');
$this->outputHTML('settings', [ $this->outputHTML('settings', [
'auth' => $auth, 'auth' => $auth,
'config' => $this->config,
'title' => $this->config->get('whose_list') . "'s Settings", 'title' => $this->config->get('whose_list') . "'s Settings",
'base_settings' => $this->config->get('default_config'),
'user_settings' => $this->config->get('user_config_settings'),
]); ]);
} }

View File

@ -109,9 +109,9 @@ class Anime extends API {
* Get anime by its kitsu id * Get anime by its kitsu id
* *
* @param string $animeId * @param string $animeId
* @return array * @return AnimeType
*/ */
public function getAnimeById(string $animeId): array public function getAnimeById(string $animeId): AnimeType
{ {
return $this->kitsuModel->getAnimeById($animeId); return $this->kitsuModel->getAnimeById($animeId);
} }

View File

@ -19,7 +19,7 @@ namespace Aviat\AnimeClient\Types;
use ArrayAccess; use ArrayAccess;
use LogicException; use LogicException;
abstract class AbstractType implements ArrayAccess { class AbstractType implements ArrayAccess {
/** /**
* Populate values for unserializing data * Populate values for unserializing data
* *

View File

@ -22,14 +22,13 @@ namespace Aviat\AnimeClient\Types;
final class MangaPage extends AbstractType { final class MangaPage extends AbstractType {
public $chapter_count; public $chapter_count;
public $cover_image; public $cover_image;
public $en_title;
public $genres; public $genres;
public $id; public $id;
public $included; public $included;
public $jp_title;
public $manga_type; public $manga_type;
public $synopsis; public $synopsis;
public $title; public $title;
public $titles;
public $url; public $url;
public $volume_count; public $volume_count;
} }

60
tests/AnimeClientTest.php Normal file
View File

@ -0,0 +1,60 @@
<?php declare(strict_types=1);
/**
* Hummingbird Anime List Client
*
* An API client for Kitsu and MyAnimeList to manage anime and manga watch lists
*
* PHP version 7
*
* @package HummingbirdAnimeClient
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2015 - 2018 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @version 4.0
* @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient
*/
namespace Aviat\AnimeClient\Tests;
use function Aviat\AnimeClient\arrayToToml;
use function Aviat\AnimeClient\tomlToArray;
class AnimeClientTest extends AnimeClientTestCase
{
public function testArrayToToml ()
{
$arr = [
'cat' => false,
'foo' => 'bar',
'dateTime' => (array) new \DateTime(),
'bar' => [
'a' => 1,
'b' => 2,
'c' => 3,
],
'baz' => [
'x' => [1, 2, 3],
'y' => [2, 4, 6],
'z' => [3, 6, 9],
],
'foobar' => [
'z' => 22/7,
'a' => [
'aa' => -8,
'b' => [
'aaa' => 4028,
'c' => [1, 2, 3],
],
],
],
];
$toml = arrayToToml($arr);
echo $toml . "\n";
$parsedArray = tomlToArray($toml);
$this->assertEquals($arr, $parsedArray);
}
}