From 0dcf25e16c8568c2ce7ecd17754bfbb49aa2dcef Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Fri, 10 Aug 2018 20:10:19 -0400 Subject: [PATCH] More refactoring work, some groundwork for Anilist integration --- app/appConf/routes.php | 15 +- app/bootstrap.php | 4 + src/API/Anilist.php | 73 +++++++ src/API/Anilist/AnilistRequestBuilder.php | 49 +++++ src/API/Anilist/AnilistTrait.php | 179 ++++++++++++++++++ src/API/Anilist/ListItem.php | 109 +++++++++++ src/API/Anilist/Model.php | 23 +++ src/API/Enum/AnimeWatchingStatus/Anilist.php | 31 +++ src/API/Enum/MangaReadingStatus/Anilist.php | 31 +++ src/API/Kitsu.php | 33 ++-- .../Kitsu/Transformer/AnimeTransformer.php | 4 +- src/API/MAL/MALRequestBuilder.php | 4 +- src/API/Mapping/AnimeWatchingStatus.php | 18 +- src/API/Mapping/MangaReadingStatus.php | 19 +- src/Controller/Index.php | 18 ++ src/Controller/Manga.php | 5 +- src/Model/Manga.php | 17 +- src/constants.php | 3 +- 18 files changed, 600 insertions(+), 35 deletions(-) create mode 100644 src/API/Anilist.php create mode 100644 src/API/Anilist/AnilistRequestBuilder.php create mode 100644 src/API/Anilist/AnilistTrait.php create mode 100644 src/API/Anilist/ListItem.php create mode 100644 src/API/Anilist/Model.php create mode 100644 src/API/Enum/AnimeWatchingStatus/Anilist.php create mode 100644 src/API/Enum/MangaReadingStatus/Anilist.php diff --git a/app/appConf/routes.php b/app/appConf/routes.php index 387c74c8..f2157a8a 100644 --- a/app/appConf/routes.php +++ b/app/appConf/routes.php @@ -8,13 +8,12 @@ * * @package HummingbirdAnimeClient * @author Timothy J. Warren - * @copyright 2015 - 2017 Timothy J. Warren + * @copyright 2015 - 2018 Timothy J. Warren * @license http://www.opensource.org/licenses/mit-license.html MIT License * @version 4.0 - * @link https://github.com/timw4mail/HummingBirdAnimeClient + * @link https://git.timshomepage.net/timw4mail/HummingBirdAnimeClient */ - use const Aviat\AnimeClient\{ DEFAULT_CONTROLLER_METHOD, DEFAULT_CONTROLLER @@ -184,6 +183,16 @@ return [ // --------------------------------------------------------------------- // Default / Shared routes // --------------------------------------------------------------------- + 'anilist-redirect' => [ + 'path' => '/anilist-redirect', + 'action' => 'anilistRedirect', + 'controller' => DEFAULT_CONTROLLER, + ], + 'anilist-oauth' => [ + 'path' => '/anilist-oauth', + 'action' => 'anilistCallback', + 'controller' => DEFAULT_CONTROLLER, + ], 'image_proxy' => [ 'path' => '/public/images/{type}/{file}', 'action' => 'images', diff --git a/app/bootstrap.php b/app/bootstrap.php index 1ee84cb5..e216fbb3 100644 --- a/app/bootstrap.php +++ b/app/bootstrap.php @@ -20,6 +20,7 @@ use Aura\Html\HelperLocatorFactory; use Aura\Router\RouterContainer; use Aura\Session\SessionFactory; use Aviat\AnimeClient\API\{ + Anilist, Kitsu, MAL, Kitsu\KitsuRequestBuilder, @@ -45,11 +46,14 @@ return function (array $configArray = []) { $appLogger = new Logger('animeclient'); $appLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/app.log', Logger::NOTICE)); + $anilistRequestLogger = new Logger('anilist-request'); + $anilistRequestLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/anilist_request.log', Logger::NOTICE)); $kitsuRequestLogger = new Logger('kitsu-request'); $kitsuRequestLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/kitsu_request.log', Logger::NOTICE)); $malRequestLogger = new Logger('mal-request'); $malRequestLogger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/mal_request.log', Logger::NOTICE)); $container->setLogger($appLogger); + $container->setLogger($anilistRequestLogger, 'anilist-request'); $container->setLogger($kitsuRequestLogger, 'kitsu-request'); $container->setLogger($malRequestLogger, 'mal-request'); diff --git a/src/API/Anilist.php b/src/API/Anilist.php new file mode 100644 index 00000000..ec5bb837 --- /dev/null +++ b/src/API/Anilist.php @@ -0,0 +1,73 @@ + + * @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\API; + +use Aviat\AnimeClient\API\Enum\{ + AnimeWatchingStatus\Kitsu as KAWS, + MangaReadingStatus\Kitsu as KMRS +}; +use Aviat\AnimeClient\API\Enum\{ + AnimeWatchingStatus\Anilist as AnimeWatchingStatus, + MangaReadingStatus\Anilist as MangaReadingStatus +}; + +/** + * Constants and mappings for the Anilist API + */ +final class Anilist { + const AUTH_URL = 'https://anilist.co/api/v2/oauth/authorize'; + const BASE_URL = 'https://graphql.anilist.co'; + + const KITSU_ANILIST_WATCHING_STATUS_MAP = [ + KAWS::WATCHING => AnimeWatchingStatus::WATCHING, + KAWS::COMPLETED => AnimeWatchingStatus::COMPLETED, + KAWS::ON_HOLD => AnimeWatchingStatus::ON_HOLD, + KAWS::DROPPED => AnimeWatchingStatus::DROPPED, + KAWS::PLAN_TO_WATCH => AnimeWatchingStatus::PLAN_TO_WATCH, + ]; + + const ANILIST_KITSU_WATCHING_STATUS_MAP = [ + 'CURRENT' => KAWS::WATCHING, + 'COMPLETED' => KAWS::COMPLETED, + 'PAUSED' => KAWS::ON_HOLD, + 'DROPPED' => KAWS::DROPPED, + 'PLANNING' => KAWS::PLAN_TO_WATCH, + ]; + + public static function getIdToWatchingStatusMap() + { + return [ + 'CURRENT' => AnimeWatchingStatus::WATCHING, + 'COMPLETED' => AnimeWatchingStatus::COMPLETED, + 'PAUSED' => AnimeWatchingStatus::ON_HOLD, + 'DROPPED' => AnimeWatchingStatus::DROPPED, + 'PLANNING' => AnimeWatchingStatus::PLAN_TO_WATCH, + 'REPEATING' => AnimeWatchingStatus::WATCHING, + ]; + } + + public static function getIdToReadingStatusMap() + { + return [ + 'CURRENT' => MangaReadingStatus::READING, + 'COMPLETED' => MangaReadingStatus::COMPLETED, + 'PAUSED' => MangaReadingStatus::ON_HOLD, + 'DROPPED' => MangaReadingStatus::DROPPED, + 'PLANNING' => MangaReadingStatus::PLAN_TO_READ + ]; + } +} \ No newline at end of file diff --git a/src/API/Anilist/AnilistRequestBuilder.php b/src/API/Anilist/AnilistRequestBuilder.php new file mode 100644 index 00000000..493cc0b2 --- /dev/null +++ b/src/API/Anilist/AnilistRequestBuilder.php @@ -0,0 +1,49 @@ + + * @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\API\Anilist; + +use const Aviat\AnimeClient\USER_AGENT; + +use Aviat\AnimeClient\API\APIRequestBuilder; + +final class AnilistRequestBuilder extends APIRequestBuilder { + + /** + * The base url for api requests + * @var string $base_url + */ + protected $baseUrl = 'https://kitsu.io/api/edge/'; + + /** + * Valid HTTP request methods + * @var array + */ + protected $validMethods = ['POST']; + + /** + * HTTP headers to send with every request + * + * @var array + */ + protected $defaultHeaders = [ + 'User-Agent' => USER_AGENT, + 'Accept' => 'application/vnd.api+json', + 'Content-Type' => 'application/vnd.api+json', + 'CLIENT_ID' => 'dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd', + 'CLIENT_SECRET' => '54d7307928f63414defd96399fc31ba847961ceaecef3a5fd93144e960c0e151', + ]; +} \ No newline at end of file diff --git a/src/API/Anilist/AnilistTrait.php b/src/API/Anilist/AnilistTrait.php new file mode 100644 index 00000000..c4ae953e --- /dev/null +++ b/src/API/Anilist/AnilistTrait.php @@ -0,0 +1,179 @@ + + * @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\API\MAL; + +use function Amp\Promise\wait; + +use Aviat\AnimeClient\API\{ + Anilist, + HummingbirdClient +}; + +trait AnilistTrait { + + /** + * The request builder for the MAL API + * @var AnilistRequestBuilder + */ + protected $requestBuilder; + + /** + * The base url for api requests + * @var string $base_url + */ + protected $baseUrl = Anilist::BASE_URL; + + /** + * HTTP headers to send with every request + * + * @var array + */ + protected $defaultHeaders = [ + 'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip', + 'Content-type' => 'application/json', + 'User-Agent' => "Tim's Anime Client/4.0" + ]; + + /** + * Set the request builder object + * + * @param MALRequestBuilder $requestBuilder + * @return self + */ + public function setRequestBuilder($requestBuilder): self + { + $this->requestBuilder = $requestBuilder; + return $this; + } + + /** + * Create a request object + * + * @param string $type + * @param string $url + * @param array $options + * @return \Amp\Artax\Response + */ + public function setUpRequest(string $type, string $url, array $options = []) + { + $config = $this->container->get('config'); + + $request = $this->requestBuilder + ->newRequest($type, $url) + ->setBasicAuth($config->get(['mal','username']), $config->get(['mal','password'])); + + if (array_key_exists('query', $options)) + { + $request = $request->setQuery($options['query']); + } + + if (array_key_exists('body', $options)) + { + $request = $request->setBody($options['body']); + } + + return $request->getFullRequest(); + } + + /** + * Make a request + * + * @param string $type + * @param string $url + * @param array $options + * @return \Amp\Artax\Response + */ + private function getResponse(string $type, string $url, array $options = []) + { + $logger = NULL; + if ($this->getContainer()) + { + $logger = $this->container->getLogger('mal-request'); + } + + $request = $this->setUpRequest($type, $url, $options); + $response = wait((new HummingbirdClient)->request($request)); + + $logger->debug('MAL api response', [ + 'status' => $response->getStatus(), + 'reason' => $response->getReason(), + 'body' => $response->getBody(), + 'headers' => $response->getHeaders(), + 'requestHeaders' => $request->getHeaders(), + ]); + + return $response; + } + + /** + * Make a request + * + * @param string $type + * @param string $url + * @param array $options + * @return array + */ + private function request(string $type, string $url, array $options = []): array + { + $logger = NULL; + if ($this->getContainer()) + { + $logger = $this->container->getLogger('anilist-request'); + } + + $response = $this->getResponse($type, $url, $options); + + if ((int) $response->getStatus() > 299 OR (int) $response->getStatus() < 200) + { + if ($logger) + { + $logger->warning('Non 200 response for api call', (array)$response->getBody()); + } + } + + return XML::toArray(wait($response->getBody())); + } + + /** + * Remove some boilerplate for post requests + * + * @param mixed ...$args + * @return array + */ + protected function postRequest(...$args): array + { + $logger = NULL; + if ($this->getContainer()) + { + $logger = $this->container->getLogger('anilist-request'); + } + + $response = $this->getResponse('POST', ...$args); + $validResponseCodes = [200, 201]; + + if ( ! \in_array((int) $response->getStatus(), $validResponseCodes, TRUE)) + { + if ($logger) + { + $logger->warning('Non 201 response for POST api call', (array)$response->getBody()); + } + } + + return XML::toArray($response->getBody()); + } +} \ No newline at end of file diff --git a/src/API/Anilist/ListItem.php b/src/API/Anilist/ListItem.php new file mode 100644 index 00000000..7aa5a4cb --- /dev/null +++ b/src/API/Anilist/ListItem.php @@ -0,0 +1,109 @@ + + * @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\API\Anilist; + +use Amp\Artax\{FormBody, Request}; +use Aviat\AnimeClient\API\{ + XML +}; +use Aviat\AnimeClient\Types\AbstractType; +use Aviat\Ion\Di\ContainerAware; + +/** + * CRUD operations for MAL list items + */ +final class ListItem { + use ContainerAware; + use AnilistTrait; + + /** + * Create a list item + * + * @param array $data + * @param string $type + * @return Request + */ + public function create(array $data, string $type = 'anime'): Request + { + $id = $data['id']; + $createData = [ + 'id' => $id, + 'data' => XML::toXML([ + 'entry' => $data['data'] + ]) + ]; + + $config = $this->container->get('config'); + + return $this->requestBuilder->newRequest('POST', "{$type}list/add/{$id}.xml") + ->setFormFields($createData) + ->setBasicAuth($config->get(['mal','username']), $config->get(['mal', 'password'])) + ->getFullRequest(); + } + + /** + * Delete a list item + * + * @param string $id + * @param string $type + * @return Request + */ + public function delete(string $id, string $type = 'anime'): Request + { + $config = $this->container->get('config'); + + return $this->requestBuilder->newRequest('DELETE', "{$type}list/delete/{$id}.xml") + ->setFormFields([ + 'id' => $id + ]) + ->setBasicAuth($config->get(['mal','username']), $config->get(['mal', 'password'])) + ->getFullRequest(); + + // return $response->getBody() === 'Deleted' + } + + public function get(string $id): array + { + return []; + } + + /** + * Update a list item + * + * @param string $id + * @param AbstractType $data + * @param string $type + * @return Request + */ + public function update(string $id, AbstractType $data, string $type = 'anime'): Request + { + $config = $this->container->get('config'); + + $xml = XML::toXML(['entry' => $data]); + $body = new FormBody(); + $body->addField('id', $id); + $body->addField('data', $xml); + + return $this->requestBuilder->newRequest('POST', "{$type}list/update/{$id}.xml") + ->setFormFields([ + 'id' => $id, + 'data' => $xml + ]) + ->setBasicAuth($config->get(['mal','username']), $config->get(['mal', 'password'])) + ->getFullRequest(); + } +} \ No newline at end of file diff --git a/src/API/Anilist/Model.php b/src/API/Anilist/Model.php new file mode 100644 index 00000000..cb8b0582 --- /dev/null +++ b/src/API/Anilist/Model.php @@ -0,0 +1,23 @@ + + * @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\API\Anilist; + +/** + * Anilist API Model + */ +final class Model { +} \ No newline at end of file diff --git a/src/API/Enum/AnimeWatchingStatus/Anilist.php b/src/API/Enum/AnimeWatchingStatus/Anilist.php new file mode 100644 index 00000000..6a8ee915 --- /dev/null +++ b/src/API/Enum/AnimeWatchingStatus/Anilist.php @@ -0,0 +1,31 @@ + + * @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\API\Enum\AnimeWatchingStatus; + +use Aviat\Ion\Enum; + +/** + * Possible values for watching status for the current anime + */ +final class Anilist extends Enum { + const WATCHING = 'CURRENT'; + const COMPLETED = 'COMPLETED'; + const ON_HOLD = 'PAUSED'; + const DROPPED = 'DROPPED'; + const PLAN_TO_WATCH = 'PLANNING'; + const REPEATING = 'REPEATING'; +} \ No newline at end of file diff --git a/src/API/Enum/MangaReadingStatus/Anilist.php b/src/API/Enum/MangaReadingStatus/Anilist.php new file mode 100644 index 00000000..c2466045 --- /dev/null +++ b/src/API/Enum/MangaReadingStatus/Anilist.php @@ -0,0 +1,31 @@ + + * @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\API\Enum\MangaReadingStatus; + +use Aviat\Ion\Enum; + +/** + * Possible values for watching status for the current anime + */ +final class Anilist extends Enum { + const WATCHING = 'CURRENT'; + const COMPLETED = 'COMPLETED'; + const ON_HOLD = 'PAUSED'; + const DROPPED = 'DROPPED'; + const PLAN_TO_WATCH = 'PLANNING'; + const REPEATING = 'REPEATING'; +} \ No newline at end of file diff --git a/src/API/Kitsu.php b/src/API/Kitsu.php index 6f372bde..48d5866d 100644 --- a/src/API/Kitsu.php +++ b/src/API/Kitsu.php @@ -143,7 +143,10 @@ final class Kitsu { */ public static function parseStreamingLinks(array $included): array { - if ( ! array_key_exists('streamingLinks', $included)) + if ( + ( ! array_key_exists('streamingLinks', $included)) || + count($included['streamingLinks']) === 0 + ) { return []; } @@ -152,7 +155,16 @@ final class Kitsu { foreach ($included['streamingLinks'] as $streamingLink) { - $host = parse_url($streamingLink['url'], \PHP_URL_HOST); + $url = $streamingLink['url']; + + // 'Fix' links that start with the hostname, + // rather than a protocol + if (strpos($url, '//') === FALSE) + { + $url = '//' . $url; + } + + $host = parse_url($url, \PHP_URL_HOST); $links[] = [ 'meta' => static::getServiceMetaData($host), @@ -182,17 +194,7 @@ final class Kitsu { if (count($anime['relationships']['streamingLinks']) > 0) { - foreach ($anime['relationships']['streamingLinks'] as $streamingLink) - { - $host = parse_url($streamingLink['url'], \PHP_URL_HOST); - - $links[] = [ - 'meta' => static::getServiceMetaData($host), - 'link' => $streamingLink['url'], - 'subs' => $streamingLink['subs'], - 'dubs' => $streamingLink['dubs'] - ]; - } + return static::parseStreamingLinks($anime['relationships']); } return $links; @@ -243,10 +245,9 @@ final class Kitsu { foreach($existingTitles as $existing) { $isSubset = mb_substr_count($existing, $title) > 0; - $diff = levenshtein($existing, $title); - $onlydifferentCase = (mb_strtolower($existing) === mb_strtolower($title)); + $diff = levenshtein(mb_strtolower($existing), mb_strtolower($title)); - if ($diff <= 3 OR $isSubset OR $onlydifferentCase OR mb_strlen($title) > 55 OR mb_strlen($existing) > 60) + if ($diff <= 4 || $isSubset || mb_strlen($title) > 40 || mb_strlen($existing) > 40) { return FALSE; } diff --git a/src/API/Kitsu/Transformer/AnimeTransformer.php b/src/API/Kitsu/Transformer/AnimeTransformer.php index bb5059c6..40d494c6 100644 --- a/src/API/Kitsu/Transformer/AnimeTransformer.php +++ b/src/API/Kitsu/Transformer/AnimeTransformer.php @@ -39,8 +39,8 @@ final class AnimeTransformer extends AbstractTransformer { $item['genres'] = array_column($genres, 'title') ?? []; sort($item['genres']); - $titles = Kitsu::filterTitles($item); - $title = array_shift($titles); + $title = $item['canonicalTitle']; + $titles = array_diff($item['titles'], [$title]); return new Anime([ 'age_rating' => $item['ageRating'], diff --git a/src/API/MAL/MALRequestBuilder.php b/src/API/MAL/MALRequestBuilder.php index 40171c4a..9888a12e 100644 --- a/src/API/MAL/MALRequestBuilder.php +++ b/src/API/MAL/MALRequestBuilder.php @@ -16,6 +16,8 @@ namespace Aviat\AnimeClient\API\MAL; +use const Aviat\AnimeClient\USER_AGENT; + use Aviat\AnimeClient\API\{ APIRequestBuilder, MAL as M @@ -38,7 +40,7 @@ final class MALRequestBuilder extends APIRequestBuilder { 'Accept' => 'text/xml', 'Accept-Encoding' => 'gzip', 'Content-type' => 'application/x-www-form-urlencoded', - 'User-Agent' => "Tim's Anime Client/4.0" + 'User-Agent' => USER_AGENT, ]; /** diff --git a/src/API/Mapping/AnimeWatchingStatus.php b/src/API/Mapping/AnimeWatchingStatus.php index 8771881b..37fa3f88 100644 --- a/src/API/Mapping/AnimeWatchingStatus.php +++ b/src/API/Mapping/AnimeWatchingStatus.php @@ -16,7 +16,7 @@ namespace Aviat\AnimeClient\API\Mapping; -use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\{Kitsu, MAL, Route, Title}; +use Aviat\AnimeClient\API\Enum\AnimeWatchingStatus\{Anilist, Kitsu, MAL, Route, Title}; use Aviat\Ion\Enum; /** @@ -24,6 +24,22 @@ use Aviat\Ion\Enum; * and url route segments */ final class AnimeWatchingStatus extends Enum { + const ANILIST_TO_KITSU = [ + Anilist::WATCHING => Kitsu::WATCHING, + Anilist::PLAN_TO_WATCH => Kitsu::PLAN_TO_WATCH, + Anilist::COMPLETED => Kitsu::COMPLETED, + Anilist::ON_HOLD => Kitsu::ON_HOLD, + Anilist::DROPPED => Kitsu::DROPPED + ]; + + const KITSU_TO_ANILIST = [ + Kitsu::WATCHING => Anilist::WATCHING, + Kitsu::PLAN_TO_WATCH => Anilist::PLAN_TO_WATCH, + Kitsu::COMPLETED => Anilist::COMPLETED, + Kitsu::ON_HOLD => Anilist::ON_HOLD, + Kitsu::DROPPED => Anilist::DROPPED + ]; + const KITSU_TO_MAL = [ Kitsu::WATCHING => MAL::WATCHING, Kitsu::PLAN_TO_WATCH => MAL::PLAN_TO_WATCH, diff --git a/src/API/Mapping/MangaReadingStatus.php b/src/API/Mapping/MangaReadingStatus.php index 4d9080d4..1e182af6 100644 --- a/src/API/Mapping/MangaReadingStatus.php +++ b/src/API/Mapping/MangaReadingStatus.php @@ -16,7 +16,7 @@ namespace Aviat\AnimeClient\API\Mapping; -use Aviat\AnimeClient\API\Enum\MangaReadingStatus\{Kitsu, MAL, Title, Route}; +use Aviat\AnimeClient\API\Enum\MangaReadingStatus\{Anilist, Kitsu, MAL, Title, Route}; use Aviat\Ion\Enum; /** @@ -24,6 +24,23 @@ use Aviat\Ion\Enum; * and url route segments */ final class MangaReadingStatus extends Enum { + const ANILIST_TO_KITSU = [ + Anilist::READING => Kitsu::READING, + Anilist::PLAN_TO_READ => Kitsu::PLAN_TO_READ, + Anilist::COMPLETED => Kitsu::COMPLETED, + Anilist::ON_HOLD => Kitsu::ON_HOLD, + Anilist::DROPPED => Kitsu::DROPPED + ]; + + const KITSU_TO_ANILIST = [ + Kitsu::READING => Anilist::READING, + Kitsu::PLAN_TO_READ => Anilist::PLAN_TO_READ, + Kitsu::COMPLETED => Anilist::COMPLETED, + Kitsu::ON_HOLD => Anilist::ON_HOLD, + Kitsu::DROPPED => Anilist::DROPPED + ]; + + const KITSU_TO_MAL = [ Kitsu::READING => MAL::READING, Kitsu::PLAN_TO_READ => MAL::PLAN_TO_READ, diff --git a/src/Controller/Index.php b/src/Controller/Index.php index a797cf2c..ab7050a8 100644 --- a/src/Controller/Index.php +++ b/src/Controller/Index.php @@ -71,6 +71,24 @@ final class Index extends BaseController { 'message' => $message ], $view); } + + /** + * Redirect to Anilist to start Oauth flow + */ + public function anilistRedirect() + { + + } + + /** + * Oauth callback for Anilist API + */ + public function anilistCallback() + { + $this->outputHTML('blank', [ + 'title' => 'Oauth!' + ]); + } /** * Attempt login authentication diff --git a/src/Controller/Manga.php b/src/Controller/Manga.php index 0c1ad65d..9f984308 100644 --- a/src/Controller/Manga.php +++ b/src/Controller/Manga.php @@ -20,6 +20,7 @@ use Aviat\AnimeClient\Controller; use Aviat\AnimeClient\API\Kitsu\Transformer\MangaListTransformer; use Aviat\AnimeClient\API\Mapping\MangaReadingStatus; use Aviat\AnimeClient\Model\Manga as MangaModel; +use Aviat\AnimeClient\Types\MangaFormItem; use Aviat\Ion\Di\ContainerInterface; use Aviat\Ion\{Json, StringWrapper}; @@ -200,7 +201,7 @@ final class Manga extends Controller { // large form-based updates $transformer = new MangaListTransformer(); $post_data = $transformer->untransform($data); - $full_result = $this->model->updateLibraryItem($post_data); + $full_result = $this->model->updateLibraryItem(new MangaFormItem($post_data)); if ($full_result['statusCode'] === 200) { @@ -234,7 +235,7 @@ final class Manga extends Controller { $data = $this->request->getParsedBody(); } - $response = $this->model->updateLibraryItem($data); + $response = $this->model->updateLibraryItem(new MangaFormItem($data)); $this->cache->clear(); $this->outputJSON($response['body'], $response['statusCode']); diff --git a/src/Model/Manga.php b/src/Model/Manga.php index 2cee710a..e902f8b6 100644 --- a/src/Model/Manga.php +++ b/src/Model/Manga.php @@ -71,12 +71,18 @@ class Manga extends API { { if ($status === 'All') { - return $this->kitsuModel->getFullOrganizedMangaList(); + $data = $this->kitsuModel->getFullOrganizedMangaList(); + foreach($data as &$section) + { + $this->sortByName($section, 'manga'); + } + + return $data; } $APIstatus = MangaReadingStatus::TITLE_TO_KITSU[$status]; - $data = - $this->mapByStatus($this->kitsuModel->getMangaList($APIstatus)); + $data = $this->mapByStatus($this->kitsuModel->getMangaList($APIstatus)); + $this->sortByName($data[$status], 'manga'); return $data[$status]; } @@ -228,11 +234,6 @@ class Manga extends API { unset($entry); - foreach ($output as &$val) - { - $this->sortByName($val, 'manga'); - } - return $output; } } diff --git a/src/constants.php b/src/constants.php index 3a606455..69142d9a 100644 --- a/src/constants.php +++ b/src/constants.php @@ -23,4 +23,5 @@ const DEFAULT_LIST_CONTROLLER = Controller\Anime::class; const ERROR_MESSAGE_METHOD = 'errorPage'; const NOT_FOUND_METHOD = 'notFound'; const SESSION_SEGMENT = 'Aviat\AnimeClient\Auth'; -const SRC_DIR = __DIR__; \ No newline at end of file +const SRC_DIR = __DIR__; +const USER_AGENT = "Tim's Anime Client/4.0"; \ No newline at end of file