From 26d339e546411a25a480434e70958c9381e8859a Mon Sep 17 00:00:00 2001 From: Timothy J Warren Date: Tue, 7 Mar 2017 17:51:08 -0500 Subject: [PATCH] Add back 'All' menu item for anime --- app/appConf/menus.php | 4 +- src/API/Kitsu/Model.php | 91 +++++++++++++++++++++++++++++++++++++--- src/Controller/Anime.php | 2 +- src/Model/Anime.php | 15 ++++++- 4 files changed, 102 insertions(+), 10 deletions(-) diff --git a/app/appConf/menus.php b/app/appConf/menus.php index 9b520b9e..9ff73ea0 100644 --- a/app/appConf/menus.php +++ b/app/appConf/menus.php @@ -24,7 +24,7 @@ return [ 'on_hold' => '/on_hold', 'dropped' => '/dropped', 'completed' => '/completed', - //'all' => '/all' + 'all' => '/all' ] ], 'manga_list' => [ @@ -35,7 +35,7 @@ return [ 'on_hold' => '/on_hold', 'dropped' => '/dropped', 'completed' => '/completed', - //'all' => '/all' + 'all' => '/all' ] ] ]; \ No newline at end of file diff --git a/src/API/Kitsu/Model.php b/src/API/Kitsu/Model.php index 02bd5e60..daec100a 100644 --- a/src/API/Kitsu/Model.php +++ b/src/API/Kitsu/Model.php @@ -16,11 +16,15 @@ namespace Aviat\AnimeClient\API\Kitsu; -use Amp\Artax\Request; +use function Amp\{all, wait}; + +use Amp\Artax\{Client, Request}; use Aviat\AnimeClient\API\{ CacheTrait, + Enum\AnimeWatchingStatus\Title, JsonAPI, - Kitsu as K + Kitsu as K, + Mapping\AnimeWatchingStatus }; use Aviat\AnimeClient\API\Kitsu\Transformer\{ AnimeTransformer, @@ -39,6 +43,8 @@ class Model { use ContainerAware; use KitsuTrait; + const FULL_TRANSFORMED_LIST_CACHE_KEY = 'FullOrganizedAnimeList'; + /** * Class to map anime list items * to a common format used by @@ -235,13 +241,14 @@ class Model { } /** - * Get and transform the entirety of the user's anime list + * Get the full anime list in paginated form * * @param int $limit * @param int $offset + * @param string $include * @return Request */ - public function getFullAnimeList(int $limit = 100, int $offset = 0): Request + public function getPagedAnimeList(int $limit = 100, int $offset = 0, $include='anime.mappings'): Request { $options = [ 'query' => [ @@ -249,7 +256,7 @@ class Model { 'user_id' => $this->getUserIdByUsername($this->getUsername()), 'media_type' => 'Anime' ], - 'include' => 'anime.mappings', + 'include' => $include, 'page' => [ 'offset' => $offset, 'limit' => $limit @@ -260,6 +267,41 @@ class Model { return $this->setUpRequest('GET', 'library-entries', $options); } + + /** + * Get the full anime list + * + * @param string $include + * @return Request + */ + public function getFullAnimeList($include = 'anime.mappings') + { + $count = $this->getAnimeListCount(); + $size = 75; + $pages = ceil($count / $size); + + $requests = []; + + // Set up requests + for ($i = 0; $i < $pages; $i++) + { + $offset = $i * $size; + $requests[] = $this->getPagedAnimeList($size, $offset, $include); + } + + $promiseArray = (new Client())->requestMulti($requests); + + $responses = wait(all($promiseArray)); + $output = []; + + foreach($responses as $response) + { + $data = Json::decode($response->getBody()); + $output = array_merge_recursive($output, $data); + } + + return $output; + } /** * Get the raw (unorganized) anime list for the configured user @@ -290,6 +332,45 @@ class Model { return $this->getRequest('library-entries', $options); } + public function getFullOrganizedAnimeList(): array + { + + $cacheItem = $this->cache->getItem(self::FULL_TRANSFORMED_LIST_CACHE_KEY); + + if ( ! $cacheItem->isHit()) + { + $output = [ + Title::WATCHING => [], + Title::PLAN_TO_WATCH => [], + Title::ON_HOLD => [], + Title::DROPPED => [], + Title::COMPLETED => [] + ]; + $statusMap = AnimeWatchingStatus::KITSU_TO_TITLE; + + $data = $this->getFullAnimeList('media,media.genres,media.mappings,anime.streamingLinks'); + $included = JsonAPI::organizeIncludes($data['included']); + $included = JsonAPI::inlineIncludedRelationships($included, 'anime'); + + foreach($data['data'] as $i => &$item) + { + $item['included'] = $included; + } + $transformed = $this->animeListTransformer->transformCollection($data['data']); + + foreach($transformed as $item) + { + $key = $statusMap[$item['watching_status']]; + $output[$key][] = $item; + } + + $cacheItem->set($output); + $cacheItem->save(); + } + + return $cacheItem->get(); + } + /** * Get the anime list for the configured user * diff --git a/src/Controller/Anime.php b/src/Controller/Anime.php index a8b2b511..78bd3173 100644 --- a/src/Controller/Anime.php +++ b/src/Controller/Anime.php @@ -93,7 +93,7 @@ class Anime extends BaseController { $data = ($type !== 'all') ? $this->model->getList(AnimeWatchingStatus::ROUTE_TO_KITSU[$type]) - : $this->model->get_all_lists(); + : $this->model->getAllLists(); $this->outputHTML('anime/' . $viewMap[$view], [ 'title' => $title, diff --git a/src/Model/Anime.php b/src/Model/Anime.php index b012c81d..27b1edbb 100644 --- a/src/Model/Anime.php +++ b/src/Model/Anime.php @@ -79,6 +79,18 @@ class Anime extends API { return $output; } + public function getAllLists() + { + $data = $this->kitsuModel->getFullOrganizedAnimeList(); + + foreach($data as $section => &$list) + { + $this->sortByName($list, 'anime'); + } + + return $data; + } + /** * Get information about an anime from its slug * @@ -200,5 +212,4 @@ class Anime extends API { return count($results[1]) > 0; } -} -// End of AnimeModel.php \ No newline at end of file +} \ No newline at end of file