diff --git a/app/appConf/routes.php b/app/appConf/routes.php index 48f3a357..0af207ef 100644 --- a/app/appConf/routes.php +++ b/app/appConf/routes.php @@ -51,6 +51,10 @@ $routes = [ 'action' => 'add', 'verb' => 'post', ], + 'anime.random' => [ + 'path' => '/anime/details/random', + 'action' => 'random', + ], 'anime.details' => [ 'path' => '/anime/details/{id}', 'action' => 'details', @@ -84,6 +88,10 @@ $routes = [ 'action' => 'delete', 'verb' => 'post', ], + 'manga.random' => [ + 'path' => '/manga/details/random', + 'action' => 'random', + ], 'manga.details' => [ 'path' => '/manga/details/{id}', 'action' => 'details', diff --git a/src/AnimeClient/API/Kitsu/Model.php b/src/AnimeClient/API/Kitsu/Model.php index 4d3740e2..a3505567 100644 --- a/src/AnimeClient/API/Kitsu/Model.php +++ b/src/AnimeClient/API/Kitsu/Model.php @@ -256,6 +256,15 @@ final class Model { return $this->animeTransformer->transform($baseData); } + public function getRandomAnime(): Anime + { + $baseData = $this->requestBuilder->runQuery('RandomMedia', [ + 'type' => 'ANIME' + ]); + + return $this->animeTransformer->transform($baseData); + } + /** * Get information about a particular anime * @@ -392,6 +401,15 @@ final class Model { return $this->mangaTransformer->transform($baseData); } + public function getRandomManga(): MangaPage + { + $baseData = $this->requestBuilder->runQuery('RandomMedia', [ + 'type' => 'MANGA' + ]); + + return $this->mangaTransformer->transform($baseData); + } + /** * Get information about a particular manga * diff --git a/src/AnimeClient/API/Kitsu/Queries/RandomMedia.graphql b/src/AnimeClient/API/Kitsu/Queries/RandomMedia.graphql new file mode 100644 index 00000000..11edbdf8 --- /dev/null +++ b/src/AnimeClient/API/Kitsu/Queries/RandomMedia.graphql @@ -0,0 +1,134 @@ +query ($type: MediaTypeEnum!) { + randomMedia(mediaType: $type, ageRatings: [G,PG,R]) { + id + ageRating + ageRatingGuide + posterImage { + original { + height + name + url + width + } + views { + height + name + url + width + } + } + categories(first: 100) { + nodes { + title + } + } + characters(first: 100) { + nodes { + character { + id + names { + alternatives + canonical + localized + } + image { + original { + height + name + url + width + } + } + slug + } + role + } + pageInfo { + endCursor + hasNextPage + hasPreviousPage + startCursor + } + } + description + startDate + endDate + sfw + slug + mappings(first: 10) { + nodes { + externalId + externalSite + } + } + staff(first: 100) { + nodes { + person { + id + birthday + image { + original { + height + name + url + width + } + views { + height + name + url + width + } + } + names { + alternatives + canonical + localized + } + slug + } + role + } + pageInfo { + endCursor + hasNextPage + hasPreviousPage + startCursor + } + } + status + titles { + alternatives + canonical + canonicalLocale + localized + } + ...on Anime { + episodeCount + episodeLength + totalLength + season + streamingLinks(first: 10) { + nodes { + dubs + subs + regions + streamer { + id + siteName + } + url + } + } + subtype + totalLength + youtubeTrailerVideoId + } + ...on Manga { + chapterCount + volumeCount + subtype + } + } + +} diff --git a/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php index 3a007c17..3f2b7fa8 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/AnimeTransformer.php @@ -34,9 +34,7 @@ final class AnimeTransformer extends AbstractTransformer { */ public function transform($item): AnimePage { - $base = array_key_exists('findAnimeBySlug', $item['data']) - ? $item['data']['findAnimeBySlug'] - : $item['data']['findAnimeById']; + $base = $item['data']['findAnimeBySlug'] ?? $item['data']['findAnimeById'] ?? $item['data']['randomMedia']; $characters = []; $links = []; $staff = []; diff --git a/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php b/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php index 350a4486..e643ec1e 100644 --- a/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php +++ b/src/AnimeClient/API/Kitsu/Transformer/MangaTransformer.php @@ -34,10 +34,7 @@ final class MangaTransformer extends AbstractTransformer { */ public function transform($item): MangaPage { - $base = array_key_exists('findMangaBySlug', $item['data']) - ? $item['data']['findMangaBySlug'] - : $item['data']['findMangaById']; - + $base = $item['data']['findMangaBySlug'] ?? $item['data']['findMangaById'] ?? $item['data']['randomMedia']; $characters = []; $links = []; $staff = []; diff --git a/src/AnimeClient/Controller/Anime.php b/src/AnimeClient/Controller/Anime.php index 41326edc..5b8acee6 100644 --- a/src/AnimeClient/Controller/Anime.php +++ b/src/AnimeClient/Controller/Anime.php @@ -348,5 +348,43 @@ final class Anime extends BaseController { ); } } + + public function random() + { + try + { + $data = $this->model->getRandomAnime(); + + if ($data->isEmpty()) + { + $this->notFound( + $this->config->get('whose_list') . + "'s Anime List · Anime · " . + 'Anime not found', + 'Anime Not Found' + ); + + return; + } + + $this->outputHTML('anime/details', [ + 'title' => $this->formatTitle( + $this->config->get('whose_list') . "'s Anime List", + 'Anime', + $data->title + ), + 'data' => $data, + ]); + } + catch (TypeError $e) + { + $this->notFound( + $this->config->get('whose_list') . + "'s Anime List · Anime · " . + 'Anime not found', + 'Anime Not Found' + ); + } + } } // End of AnimeController.php \ No newline at end of file diff --git a/src/AnimeClient/Controller/Manga.php b/src/AnimeClient/Controller/Manga.php index 824d474f..3fe27ce2 100644 --- a/src/AnimeClient/Controller/Manga.php +++ b/src/AnimeClient/Controller/Manga.php @@ -338,5 +338,43 @@ final class Manga extends Controller { 'staff' => $staff, ]); } + + /** + * View details of a random manga + * + * @throws ContainerException + * @throws NotFoundException + * @throws InvalidArgumentException + * @throws Throwable + * @return void + */ + public function random(): void + { + $data = $this->model->getRandomManga(); + $staff = []; + $characters = []; + + if ($data->isEmpty()) + { + $this->notFound( + $this->config->get('whose_list') . + "'s Manga List · Manga · " . + 'Manga not found', + 'Manga Not Found' + ); + return; + } + + $this->outputHTML('manga/details', [ + 'title' => $this->formatTitle( + $this->config->get('whose_list') . "'s Manga List", + 'Manga', + $data['title'] + ), + 'characters' => $characters, + 'data' => $data, + 'staff' => $staff, + ]); + } } // End of MangaController.php diff --git a/src/AnimeClient/Model/Anime.php b/src/AnimeClient/Model/Anime.php index fbae9f3f..3458b6b3 100644 --- a/src/AnimeClient/Model/Anime.php +++ b/src/AnimeClient/Model/Anime.php @@ -83,6 +83,16 @@ class Anime extends API { return $this->kitsuModel->getAnime($slug); } + /** + * Get information about a random anime + * + * @return AnimeType + */ + public function getRandomAnime(): AnimeType + { + return $this->kitsuModel->getRandomAnime(); + } + /** * Get anime by its kitsu id * diff --git a/src/AnimeClient/Model/Manga.php b/src/AnimeClient/Model/Manga.php index 1784305b..3ef516ad 100644 --- a/src/AnimeClient/Model/Manga.php +++ b/src/AnimeClient/Model/Manga.php @@ -68,6 +68,16 @@ class Manga extends API { return $this->kitsuModel->getManga($manga_id); } + /** + * Get the details of a random manga + * + * @return MangaPage + */ + public function getRandomManga(): MangaPage + { + return $this->kitsuModel->getRandomManga(); + } + /** * Get anime by its kitsu id *