Merge pull request #285 from jikan-me/feature/new-reviews

Feature+Fix: Update Reviews API
This commit is contained in:
Irfan 2022-11-25 17:13:48 +05:00 committed by GitHub
commit 0d714d7beb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 3444 additions and 1026 deletions

View File

@ -14,6 +14,7 @@ use Jikan\Exception\ParserException;
use Laravel\Lumen\Exceptions\Handler as ExceptionHandler; use Laravel\Lumen\Exceptions\Handler as ExceptionHandler;
use Predis\Connection\ConnectionException; use Predis\Connection\ConnectionException;
use Symfony\Component\HttpClient\Exception\TimeoutException; use Symfony\Component\HttpClient\Exception\TimeoutException;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\HttpException;
@ -95,6 +96,27 @@ class Handler extends ExceptionHandler
], 500); ], 500);
} }
// BadRequestException from Controllers
if ($e instanceof BadRequestException) {
return response()
->json([
'status' => 400,
'type' => 'BadRequestException',
'message' => $e->getMessage(),
'error' => null
], 400);
}
if ($e instanceof ValidationException) {
return response()
->json([
'status' => 400,
'type' => 'BadRequestException',
'message' => $e->getMessage(),
'error' => null
], 400);
}
// BadResponseException from Jikan PHP API // BadResponseException from Jikan PHP API
// This is basically the response MyAnimeList returns to Jikan // This is basically the response MyAnimeList returns to Jikan
if ($e instanceof BadResponseException) { if ($e instanceof BadResponseException) {

View File

@ -0,0 +1,22 @@
<?php
namespace App\Helpers;
use App\Providers\SerializerFactory;
class ScraperHelper
{
/**
* @param object|array $response
* @return array
*/
public static function getSerializedJSON(object|array $response): array
{
return \json_decode(
SerializerFactory::createV4()
->serialize($response, 'json'),
true
);
}
}

View File

@ -22,6 +22,7 @@ use App\Http\Resources\V4\AnimeVideosResource;
use App\Http\Resources\V4\ForumResource; use App\Http\Resources\V4\ForumResource;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Jikan\Helper\Constants;
use Jikan\Request\Anime\AnimeCharactersAndStaffRequest; use Jikan\Request\Anime\AnimeCharactersAndStaffRequest;
use Jikan\Request\Anime\AnimeEpisodeRequest; use Jikan\Request\Anime\AnimeEpisodeRequest;
use Jikan\Request\Anime\AnimeEpisodesRequest; use Jikan\Request\Anime\AnimeEpisodesRequest;
@ -38,6 +39,7 @@ use Jikan\Request\Anime\AnimeVideosEpisodesRequest;
use Jikan\Request\Anime\AnimeVideosRequest; use Jikan\Request\Anime\AnimeVideosRequest;
use Laravel\Lumen\Http\ResponseFactory; use Laravel\Lumen\Http\ResponseFactory;
use MongoDB\BSON\UTCDateTime; use MongoDB\BSON\UTCDateTime;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class AnimeController extends Controller class AnimeController extends Controller
@ -1110,9 +1112,27 @@ class AnimeController extends Controller
|| $this->isExpired($request, $results) || $this->isExpired($request, $results)
) { ) {
$page = $request->get('page') ?? 1; $page = $request->get('page') ?? 1;
$anime = $this->jikan->getAnimeReviews(new AnimeReviewsRequest($id, $page)); $sort = $request->get('sort') ?? Constants::REVIEWS_SORT_MOST_VOTED;
$response = \json_decode($this->serializer->serialize($anime, 'json'), true);
if (!in_array($sort, [Constants::REVIEWS_SORT_MOST_VOTED, Constants::REVIEWS_SORT_NEWEST, Constants::REVIEWS_SORT_OLDEST])) {
throw new BadRequestException('Invalid sort for reviews. Please refer to the documentation: https://docs.api.jikan.moe/');
}
$spoilers = $request->get('spoilers') ?? false;
$preliminary = $request->get('preliminary') ?? false;
$anime = $this->jikan
->getAnimeReviews(
new AnimeReviewsRequest(
$id,
$page,
$sort,
$spoilers,
$preliminary
)
);
$response = \json_decode($this->serializer->serialize($anime, 'json'), true);
$results = $this->updateCache($request, $results, $response); $results = $this->updateCache($request, $results, $response);
} }

View File

@ -36,7 +36,7 @@ class Controller extends BaseController
* ) * )
* ), * ),
* @OA\Server( * @OA\Server(
* description="Jikan REST API Beta", * description="Jikan REST API",
* url="https://api.jikan.moe/v4", * url="https://api.jikan.moe/v4",
* ), * ),
* @OA\ExternalDocumentation( * @OA\ExternalDocumentation(
@ -49,12 +49,12 @@ class Controller extends BaseController
/** /**
* @var Serializer * @var Serializer
*/ */
protected $serializer; protected Serializer $serializer;
/** /**
* @var MalClient * @var MalClient
*/ */
protected $jikan; protected MalClient $jikan;
/** /**
* @var Request * @var Request
@ -64,16 +64,16 @@ class Controller extends BaseController
/** /**
* @var array * @var array
*/ */
private $response; private array $response;
protected $expired = false; protected bool $expired = false;
protected $fingerprint; protected string $fingerprint;
/** /**
* AnimeController constructor. * AnimeController constructor.
* *
* @param Serializer $serializer * @param Request $request
* @param MalClient $jikan * @param MalClient $jikan
*/ */
public function __construct(Request $request, MalClient $jikan) public function __construct(Request $request, MalClient $jikan)

View File

@ -2,38 +2,28 @@
namespace App\Http\Controllers\V4DB; namespace App\Http\Controllers\V4DB;
use App\Anime; use App\Helpers\ScraperHelper;
use App\Http\HttpHelper; use App\Http\HttpHelper;
use App\Http\HttpResponse; use App\Http\HttpResponse;
use App\Http\Resources\V4\AnimeCharactersResource; use App\Http\QueryBuilder\Scraper\Query;
use App\Http\Resources\V4\AnimeForumResource; use App\Http\QueryBuilder\Scraper\QueryResolver;
use App\Http\QueryBuilder\Scraper\ScraperHandler;
use App\Http\Resources\V4\ExternalLinksResource; use App\Http\Resources\V4\ExternalLinksResource;
use App\Http\Resources\V4\MangaRelationsResource; use App\Http\Resources\V4\MangaRelationsResource;
use App\Http\Resources\V4\ResultsResource; use App\Http\Resources\V4\ResultsResource;
use App\Http\Resources\V4\ReviewsResource; use App\Http\Resources\V4\ReviewsResource;
use App\Http\Resources\V4\UserUpdatesResource;
use App\Http\Resources\V4\RecommendationsResource; use App\Http\Resources\V4\RecommendationsResource;
use App\Http\Resources\V4\MoreInfoResource; use App\Http\Resources\V4\MoreInfoResource;
use App\Http\Resources\V4\AnimeNewsResource;
use App\Http\Resources\V4\AnimeStatisticsResource;
use App\Http\Resources\V4\ForumResource; use App\Http\Resources\V4\ForumResource;
use App\Http\Resources\V4\MangaCharactersResource; use App\Http\Resources\V4\MangaCharactersResource;
use App\Http\Resources\V4\MangaStatisticsResource; use App\Http\Resources\V4\MangaStatisticsResource;
use App\Http\Resources\V4\NewsResource;
use App\Http\Resources\V4\PicturesResource; use App\Http\Resources\V4\PicturesResource;
use App\Http\Validation\ValidationTypeEnum;
use App\Manga; use App\Manga;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Jikan\Request\Anime\AnimeCharactersAndStaffRequest; use Jikan\Exception\BadResponseException;
use Jikan\Request\Anime\AnimeForumRequest; use Jikan\Helper\Constants;
use Jikan\Request\Anime\AnimeMoreInfoRequest;
use Jikan\Request\Anime\AnimeNewsRequest;
use Jikan\Request\Anime\AnimePicturesRequest;
use Jikan\Request\Anime\AnimeRecentlyUpdatedByUsersRequest;
use Jikan\Request\Anime\AnimeRecommendationsRequest;
use Jikan\Request\Anime\AnimeReviewsRequest;
use Jikan\Request\Anime\AnimeStatsRequest;
use Jikan\Request\Manga\MangaCharactersRequest; use Jikan\Request\Manga\MangaCharactersRequest;
use Jikan\Request\Manga\MangaForumRequest; use Jikan\Request\Manga\MangaForumRequest;
use Jikan\Request\Manga\MangaMoreInfoRequest; use Jikan\Request\Manga\MangaMoreInfoRequest;
@ -41,11 +31,10 @@ use Jikan\Request\Manga\MangaNewsRequest;
use Jikan\Request\Manga\MangaPicturesRequest; use Jikan\Request\Manga\MangaPicturesRequest;
use Jikan\Request\Manga\MangaRecentlyUpdatedByUsersRequest; use Jikan\Request\Manga\MangaRecentlyUpdatedByUsersRequest;
use Jikan\Request\Manga\MangaRecommendationsRequest; use Jikan\Request\Manga\MangaRecommendationsRequest;
use Jikan\Request\Manga\MangaRequest;
use Jikan\Request\Manga\MangaReviewsRequest; use Jikan\Request\Manga\MangaReviewsRequest;
use Jikan\Request\Manga\MangaStatsRequest; use Jikan\Request\Manga\MangaStatsRequest;
use MongoDB\BSON\UTCDateTime; use MongoDB\BSON\UTCDateTime;
use mysql_xdevapi\Result; use Symfony\Component\HttpFoundation\Exception\BadRequestException;
class MangaController extends Controller class MangaController extends Controller
{ {
@ -442,7 +431,7 @@ class MangaController extends Controller
* @OA\Property( * @OA\Property(
* property="data", * property="data",
* type="array", * type="array",
* *
* @OA\Items( * @OA\Items(
* type="object", * type="object",
* ref="#/components/schemas/manga_images" * ref="#/components/schemas/manga_images"
@ -693,7 +682,7 @@ class MangaController extends Controller
} }
/** /**
* @OA\Get( * @OA\Get(
* path="/manga/{id}/reviews", * path="/manga/{id}/reviews",
* operationId="getMangaReviews", * operationId="getMangaReviews",
* tags={"manga"}, * tags={"manga"},
@ -719,9 +708,20 @@ class MangaController extends Controller
* description="Error: Bad request. When required parameters were not supplied.", * description="Error: Bad request. When required parameters were not supplied.",
* ), * ),
* ) * )
* @throws \Exception
*/ */
public function reviews(Request $request, int $id) public function reviews(Request $request, int $id)
{ {
$validation = $this->validate($request, [
'page' => 'nullable|numeric',
'sort' => 'nullable|string'
]);
$page = $request->get('page') ?? 1;
$spoilers = $request->get('spoilers') ?? false;
$preliminary = $request->get('preliminary') ?? false;
$sort = $request->get('sort');
$results = DB::table($this->getRouteTable($request)) $results = DB::table($this->getRouteTable($request))
->where('request_hash', $this->fingerprint) ->where('request_hash', $this->fingerprint)
->get(); ->get();
@ -730,9 +730,19 @@ class MangaController extends Controller
$results->isEmpty() $results->isEmpty()
|| $this->isExpired($request, $results) || $this->isExpired($request, $results)
) { ) {
$page = $request->get('page') ?? 1;
$manga = $this->jikan->getMangaReviews(new MangaReviewsRequest($id, $page)); $response = ScraperHelper::getSerializedJSON(
$response = \json_decode($this->serializer->serialize($manga, 'json'), true); app('JikanParser')
->getMangaReviews(
new MangaReviewsRequest(
$id,
$page,
in_array($sort, [Constants::REVIEWS_SORT_MOST_VOTED, Constants::REVIEWS_SORT_NEWEST, Constants::REVIEWS_SORT_OLDEST]) ? $sort : Constants::REVIEWS_SORT_MOST_VOTED,
$spoilers,
$preliminary
)
)
);
$results = $this->updateCache($request, $results, $response); $results = $this->updateCache($request, $results, $response);
} }

View File

@ -9,7 +9,9 @@ use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Jikan\Helper\Constants; use Jikan\Helper\Constants;
use Jikan\Request\Reviews\RecentReviewsRequest; use Jikan\Request\Reviews\RecentReviewsRequest;
use Jikan\Request\Reviews\ReviewsRequest;
use MongoDB\BSON\UTCDateTime; use MongoDB\BSON\UTCDateTime;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
class ReviewsController extends Controller class ReviewsController extends Controller
{ {
@ -73,7 +75,26 @@ class ReviewsController extends Controller
|| $this->isExpired($request, $results) || $this->isExpired($request, $results)
) { ) {
$page = $request->get('page') ?? 1; $page = $request->get('page') ?? 1;
$anime = $this->jikan->getRecentReviews(new RecentReviewsRequest(Constants::RECENT_REVIEW_ANIME, $page)); $sort = $request->get('sort') ?? Constants::REVIEWS_SORT_MOST_VOTED;
if (!in_array($sort, [Constants::REVIEWS_SORT_MOST_VOTED, Constants::REVIEWS_SORT_NEWEST, Constants::REVIEWS_SORT_OLDEST])) {
throw new BadRequestException('Invalid sort for reviews. Please refer to the documentation: https://docs.api.jikan.moe/');
}
$spoilers = $request->get('spoilers') ?? false;
$preliminary = $request->get('preliminary') ?? false;
$anime = $this->jikan
->getReviews(
new ReviewsRequest(
Constants::ANIME,
$page,
$sort,
$spoilers,
$preliminary
)
);
$response = \json_decode($this->serializer->serialize($anime, 'json'), true); $response = \json_decode($this->serializer->serialize($anime, 'json'), true);
$results = $this->updateCache($request, $results, $response); $results = $this->updateCache($request, $results, $response);
@ -149,9 +170,27 @@ class ReviewsController extends Controller
|| $this->isExpired($request, $results) || $this->isExpired($request, $results)
) { ) {
$page = $request->get('page') ?? 1; $page = $request->get('page') ?? 1;
$anime = $this->jikan->getRecentReviews(new RecentReviewsRequest(Constants::RECENT_REVIEW_MANGA, $page)); $sort = $request->get('sort') ?? Constants::REVIEWS_SORT_MOST_VOTED;
$response = \json_decode($this->serializer->serialize($anime, 'json'), true);
if (!in_array($sort, [Constants::REVIEWS_SORT_MOST_VOTED, Constants::REVIEWS_SORT_NEWEST, Constants::REVIEWS_SORT_OLDEST])) {
throw new BadRequestException('Invalid sort for reviews. Please refer to the documentation: https://docs.api.jikan.moe/');
}
$spoilers = $request->get('spoilers') ?? false;
$preliminary = $request->get('preliminary') ?? false;
$anime = $this->jikan
->getReviews(
new ReviewsRequest(
Constants::MANGA,
$page,
$sort,
$spoilers,
$preliminary
)
);
$response = \json_decode($this->serializer->serialize($anime, 'json'), true);
$results = $this->updateCache($request, $results, $response); $results = $this->updateCache($request, $results, $response);
} }

View File

@ -641,6 +641,14 @@ class SearchController extends ControllerWithQueryBuilderProvider
} }
/** /**
*
* @OA\Schema(
* schema="producers_query_orderby",
* description="Producers Search Query Order By",
* type="string",
* enum={"mal_id", "count", "favorites", "established"}
* )
*
* @OA\Get( * @OA\Get(
* path="/producers", * path="/producers",
* operationId="getProducers", * operationId="getProducers",

View File

@ -14,6 +14,7 @@ use App\Http\Resources\V4\UserProfileMangaListResource;
use App\Profile; use App\Profile;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Jikan\Helper\Constants;
use Jikan\Request\User\RecentlyOnlineUsersRequest; use Jikan\Request\User\RecentlyOnlineUsersRequest;
use Jikan\Request\User\UserAnimeListRequest; use Jikan\Request\User\UserAnimeListRequest;
use Jikan\Request\User\UserClubsRequest; use Jikan\Request\User\UserClubsRequest;
@ -23,6 +24,7 @@ use Jikan\Request\User\UserMangaListRequest;
use Jikan\Request\User\UserRecommendationsRequest; use Jikan\Request\User\UserRecommendationsRequest;
use Jikan\Request\User\UserReviewsRequest; use Jikan\Request\User\UserReviewsRequest;
use MongoDB\BSON\UTCDateTime; use MongoDB\BSON\UTCDateTime;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
/** /**
* Class Controller * Class Controller
@ -964,9 +966,16 @@ class UserController extends Controller
|| $this->isExpired($request, $results) || $this->isExpired($request, $results)
) { ) {
$page = $request->get('page') ?? 1; $page = $request->get('page') ?? 1;
$data = $this->jikan->getUserReviews(new UserReviewsRequest($username, $page));
$response = \json_decode($this->serializer->serialize($data, 'json'), true);
$data = $this->jikan
->getUserReviews(
new UserReviewsRequest(
$username,
$page,
)
);
$response = \json_decode($this->serializer->serialize($data, 'json'), true);
$results = $this->updateCache($request, $results, $response); $results = $this->updateCache($request, $results, $response);
} }

View File

@ -19,17 +19,57 @@ class ReviewsResource extends JsonResource
* @OA\Property( * @OA\Property(
* property="url", * property="url",
* type="string", * type="string",
* description="MyAnimeList URL" * description="MyAnimeList review URL"
* ), * ),
* @OA\Property( * @OA\Property(
* property="type", * property="type",
* type="string", * type="string",
* description="Entry Type" * description="Entry type"
* ), * ),
* @OA\Property( * @OA\Property(
* property="votes", * property="reactions",
* type="integer", * type="object",
* description="Number of user votes on the Review" * description="User reaction count on the review",
* @OA\Property(
* property="overall",
* type="integer",
* description="Overall reaction count"
* ),
* @OA\Property(
* property="nice",
* type="integer",
* description="Nice reaction count"
* ),
* @OA\Property(
* property="love_it",
* type="integer",
* description="Love it reaction count"
* ),
* @OA\Property(
* property="funny",
* type="integer",
* description="Funny reaction count"
* ),
* @OA\Property(
* property="confusing",
* type="integer",
* description="Confusing reaction count"
* ),
* @OA\Property(
* property="informative",
* type="integer",
* description="Informative reaction count"
* ),
* @OA\Property(
* property="well_written",
* type="integer",
* description="Well written reaction count"
* ),
* @OA\Property(
* property="creative",
* type="integer",
* description="Creative reaction count"
* )
* ), * ),
* @OA\Property( * @OA\Property(
* property="date", * property="date",
@ -37,44 +77,30 @@ class ReviewsResource extends JsonResource
* description="Review created date ISO8601" * description="Review created date ISO8601"
* ), * ),
* @OA\Property( * @OA\Property(
* property="chapters_read",
* type="integer",
* description="Number of chapters read by the reviewer"
* ),
* @OA\Property(
* property="review", * property="review",
* type="string", * type="string",
* description="Review content" * description="Review content"
* ), * ),
* @OA\Property( * @OA\Property(
* property="scores", * property="score",
* type="object", * type="integer",
* description="Review Scores breakdown", * description="Number of user votes on the Review"
* @OA\Property( * ),
* property="overall", * @OA\Property (
* type="integer", * property="tags",
* description="Overall Score" * type="array",
* ), * description="Review tags",
* @OA\Property( * @OA\Items(type="string"),
* property="story", * ),
* type="integer", * @OA\Property (
* description="Story Score" * property="is_spoiler",
* ), * type="bool",
* @OA\Property( * description="The review contains spoiler"
* property="art", * ),
* type="integer", * @OA\Property (
* description="Art Score" * property="is_preliminary",
* ), * type="bool",
* @OA\Property( * description="The review was made before the entry was completed"
* property="character",
* type="integer",
* description="Character Score"
* ),
* @OA\Property(
* property="enjoyment",
* type="integer",
* description="Enjoyment Score"
* ),
* ), * ),
* ), * ),
* *
@ -89,17 +115,57 @@ class ReviewsResource extends JsonResource
* @OA\Property( * @OA\Property(
* property="url", * property="url",
* type="string", * type="string",
* description="MyAnimeList URL" * description="MyAnimeList review URL"
* ), * ),
* @OA\Property( * @OA\Property(
* property="type", * property="type",
* type="string", * type="string",
* description="Entry Type" * description="Entry type"
* ), * ),
* @OA\Property( * @OA\Property(
* property="votes", * property="reactions",
* type="integer", * type="object",
* description="Number of user votes on the Review" * description="User reaction count on the review",
* @OA\Property(
* property="overall",
* type="integer",
* description="Overall reaction count"
* ),
* @OA\Property(
* property="nice",
* type="integer",
* description="Nice reaction count"
* ),
* @OA\Property(
* property="love_it",
* type="integer",
* description="Love it reaction count"
* ),
* @OA\Property(
* property="funny",
* type="integer",
* description="Funny reaction count"
* ),
* @OA\Property(
* property="confusing",
* type="integer",
* description="Confusing reaction count"
* ),
* @OA\Property(
* property="informative",
* type="integer",
* description="Informative reaction count"
* ),
* @OA\Property(
* property="well_written",
* type="integer",
* description="Well written reaction count"
* ),
* @OA\Property(
* property="creative",
* type="integer",
* description="Creative reaction count"
* )
* ), * ),
* @OA\Property( * @OA\Property(
* property="date", * property="date",
@ -112,45 +178,31 @@ class ReviewsResource extends JsonResource
* description="Review content" * description="Review content"
* ), * ),
* @OA\Property( * @OA\Property(
* property="score",
* type="integer",
* description="Number of user votes on the Review"
* ),
* @OA\Property (
* property="tags",
* type="array",
* description="Review tags",
* @OA\Items(type="string"),
* ),
* @OA\Property (
* property="is_spoiler",
* type="bool",
* description="The review contains spoiler"
* ),
* @OA\Property (
* property="is_preliminary",
* type="bool",
* description="The review was made before the entry was completed"
* ),
* @OA\Property(
* property="episodes_watched", * property="episodes_watched",
* type="integer", * type="integer",
* description="Number of episodes watched" * description="Number of episodes watched"
* ), * ),
* @OA\Property(
* property="scores",
* type="object",
* description="Review Scores breakdown",
* @OA\Property(
* property="overall",
* type="integer",
* description="Overall Score"
* ),
* @OA\Property(
* property="story",
* type="integer",
* description="Story Score"
* ),
* @OA\Property(
* property="animation",
* type="integer",
* description="Animation Score"
* ),
* @OA\Property(
* property="sound",
* type="integer",
* description="Sound Score"
* ),
* @OA\Property(
* property="character",
* type="integer",
* description="Character Score"
* ),
* @OA\Property(
* property="enjoyment",
* type="integer",
* description="Enjoyment Score"
* ),
* ),
* ), * ),
* *
* *
@ -233,4 +285,4 @@ class ReviewsResource extends JsonResource
'data' => $this['results'], 'data' => $this['results'],
]; ];
} }
} }

View File

@ -21,7 +21,7 @@
"flipbox/lumen-generator": "^9.0", "flipbox/lumen-generator": "^9.0",
"illuminate/redis": "^9.0", "illuminate/redis": "^9.0",
"jenssegers/mongodb": "^3.8", "jenssegers/mongodb": "^3.8",
"jikan-me/jikan": "^3", "jikan-me/jikan": "^4",
"jms/serializer": "^3.0", "jms/serializer": "^3.0",
"laravel/legacy-factories": "^1.1", "laravel/legacy-factories": "^1.1",
"laravel/lumen-framework": "^9.0", "laravel/lumen-framework": "^9.0",

3775
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -4199,6 +4199,15 @@
}, },
"type": "object" "type": "object"
}, },
"magazines_query_orderby": {
"description": "Order by magazine data",
"type": "string",
"enum": [
"mal_id",
"name",
"count"
]
},
"manga_news": { "manga_news": {
"description": "Manga News Resource", "description": "Manga News Resource",
"allOf": [ "allOf": [
@ -4323,6 +4332,16 @@
} }
] ]
}, },
"producers_query_orderby": {
"description": "Producers Search Query Order By",
"type": "string",
"enum": [
"mal_id",
"count",
"favorites",
"established"
]
},
"seasons": { "seasons": {
"description": "List of available seasons", "description": "List of available seasons",
"properties": { "properties": {
@ -4638,15 +4657,6 @@
"created" "created"
] ]
}, },
"magazines_query_orderby": {
"description": "Order by magazine data",
"type": "string",
"enum": [
"mal_id",
"name",
"count"
]
},
"manga_search_query_type": { "manga_search_query_type": {
"description": "Available Manga types", "description": "Available Manga types",
"type": "string", "type": "string",
@ -4699,17 +4709,6 @@
"favorites" "favorites"
] ]
}, },
"producers_query_orderby": {
"description": "Order by producers data",
"type": "string",
"enum": [
"mal_id",
"name",
"count",
"favorites",
"established"
]
},
"users_search_query_gender": { "users_search_query_gender": {
"description": "Users Search Query Gender", "description": "Users Search Query Gender",
"type": "string", "type": "string",
@ -8467,54 +8466,77 @@
"type": "integer" "type": "integer"
}, },
"url": { "url": {
"description": "MyAnimeList URL", "description": "MyAnimeList review URL",
"type": "string" "type": "string"
}, },
"type": { "type": {
"description": "Entry Type", "description": "Entry type",
"type": "string" "type": "string"
}, },
"votes": { "reactions": {
"description": "Number of user votes on the Review", "description": "User reaction count on the review",
"type": "integer" "properties": {
"overall": {
"description": "Overall reaction count",
"type": "integer"
},
"nice": {
"description": "Nice reaction count",
"type": "integer"
},
"love_it": {
"description": "Love it reaction count",
"type": "integer"
},
"funny": {
"description": "Funny reaction count",
"type": "integer"
},
"confusing": {
"description": "Confusing reaction count",
"type": "integer"
},
"informative": {
"description": "Informative reaction count",
"type": "integer"
},
"well_written": {
"description": "Well written reaction count",
"type": "integer"
},
"creative": {
"description": "Creative reaction count",
"type": "integer"
}
},
"type": "object"
}, },
"date": { "date": {
"description": "Review created date ISO8601", "description": "Review created date ISO8601",
"type": "string" "type": "string"
}, },
"chapters_read": {
"description": "Number of chapters read by the reviewer",
"type": "integer"
},
"review": { "review": {
"description": "Review content", "description": "Review content",
"type": "string" "type": "string"
}, },
"scores": { "score": {
"description": "Review Scores breakdown", "description": "Number of user votes on the Review",
"properties": { "type": "integer"
"overall": { },
"description": "Overall Score", "tags": {
"type": "integer" "description": "Review tags",
}, "type": "array",
"story": { "items": {
"description": "Story Score", "type": "string"
"type": "integer" }
}, },
"art": { "is_spoiler": {
"description": "Art Score", "description": "The review contains spoiler",
"type": "integer" "type": "bool"
}, },
"character": { "is_preliminary": {
"description": "Character Score", "description": "The review was made before the entry was completed",
"type": "integer" "type": "bool"
},
"enjoyment": {
"description": "Enjoyment Score",
"type": "integer"
}
},
"type": "object"
} }
}, },
"type": "object" "type": "object"
@ -8526,16 +8548,50 @@
"type": "integer" "type": "integer"
}, },
"url": { "url": {
"description": "MyAnimeList URL", "description": "MyAnimeList review URL",
"type": "string" "type": "string"
}, },
"type": { "type": {
"description": "Entry Type", "description": "Entry type",
"type": "string" "type": "string"
}, },
"votes": { "reactions": {
"description": "Number of user votes on the Review", "description": "User reaction count on the review",
"type": "integer" "properties": {
"overall": {
"description": "Overall reaction count",
"type": "integer"
},
"nice": {
"description": "Nice reaction count",
"type": "integer"
},
"love_it": {
"description": "Love it reaction count",
"type": "integer"
},
"funny": {
"description": "Funny reaction count",
"type": "integer"
},
"confusing": {
"description": "Confusing reaction count",
"type": "integer"
},
"informative": {
"description": "Informative reaction count",
"type": "integer"
},
"well_written": {
"description": "Well written reaction count",
"type": "integer"
},
"creative": {
"description": "Creative reaction count",
"type": "integer"
}
},
"type": "object"
}, },
"date": { "date": {
"description": "Review created date ISO8601", "description": "Review created date ISO8601",
@ -8545,39 +8601,28 @@
"description": "Review content", "description": "Review content",
"type": "string" "type": "string"
}, },
"score": {
"description": "Number of user votes on the Review",
"type": "integer"
},
"tags": {
"description": "Review tags",
"type": "array",
"items": {
"type": "string"
}
},
"is_spoiler": {
"description": "The review contains spoiler",
"type": "bool"
},
"is_preliminary": {
"description": "The review was made before the entry was completed",
"type": "bool"
},
"episodes_watched": { "episodes_watched": {
"description": "Number of episodes watched", "description": "Number of episodes watched",
"type": "integer" "type": "integer"
},
"scores": {
"description": "Review Scores breakdown",
"properties": {
"overall": {
"description": "Overall Score",
"type": "integer"
},
"story": {
"description": "Story Score",
"type": "integer"
},
"animation": {
"description": "Animation Score",
"type": "integer"
},
"sound": {
"description": "Sound Score",
"type": "integer"
},
"character": {
"description": "Character Score",
"type": "integer"
},
"enjoyment": {
"description": "Enjoyment Score",
"type": "integer"
}
},
"type": "object"
} }
}, },
"type": "object" "type": "object"

View File

@ -406,9 +406,14 @@ class AnimeControllerV4Test extends TestCase
[ [
'mal_id', 'mal_id',
'url', 'url',
'votes', 'type',
'reactions',
'date', 'date',
'review', 'review',
'score',
'tags',
'is_spoiler',
'is_preliminary',
'episodes_watched', 'episodes_watched',
'scores' => [ 'scores' => [
'overall', 'overall',
@ -508,7 +513,7 @@ class AnimeControllerV4Test extends TestCase
] ]
]); ]);
$this->get('/v4/anime/1/userupdates?page=100') $this->get('/v4/anime/1/userupdates?page=200')
->seeStatusCode(404); ->seeStatusCode(404);
} }

View File

@ -228,9 +228,14 @@ class MangaControllerV4Test extends TestCase
[ [
'mal_id', 'mal_id',
'url', 'url',
'votes', 'type',
'reactions',
'date', 'date',
'review', 'review',
'score',
'tags',
'is_spoiler',
'is_preliminary',
'chapters_read', 'chapters_read',
'scores' => [ 'scores' => [
'overall', 'overall',
@ -331,7 +336,7 @@ class MangaControllerV4Test extends TestCase
] ]
]); ]);
$this->get('/v4/manga/1/userupdates?page=100') $this->get('/v4/manga/1/userupdates?page=200')
->seeStatusCode(404); ->seeStatusCode(404);
} }

View File

@ -112,7 +112,6 @@ class PersonControllerTest extends TestCase
'images' => [ 'images' => [
'jpg' => [ 'jpg' => [
'image_url', 'image_url',
'small_image_url',
], ],
'webp' => [ 'webp' => [
'image_url', 'image_url',

View File

@ -17,18 +17,14 @@ class ReviewsControllerTest extends TestCase
'mal_id', 'mal_id',
'url', 'url',
'type', 'type',
'votes', 'reactions',
'date', 'date',
'review', 'review',
'score',
'tags',
'is_spoiler',
'is_preliminary',
'episodes_watched', 'episodes_watched',
'scores' => [
'overall',
'story',
'animation',
'sound',
'character',
'enjoyment',
],
'entry' => [ 'entry' => [
'mal_id', 'mal_id',
'url', 'url',
@ -77,17 +73,14 @@ class ReviewsControllerTest extends TestCase
'mal_id', 'mal_id',
'url', 'url',
'type', 'type',
'votes', 'reactions',
'date', 'date',
'review', 'review',
'score',
'tags',
'is_spoiler',
'is_preliminary',
'chapters_read', 'chapters_read',
'scores' => [
'overall',
'story',
'art',
'character',
'enjoyment',
],
'entry' => [ 'entry' => [
'mal_id', 'mal_id',
'url', 'url',
@ -121,4 +114,4 @@ class ReviewsControllerTest extends TestCase
] ]
]); ]);
} }
} }

View File

@ -274,9 +274,13 @@ class UserControllerTest extends TestCase
'mal_id', 'mal_id',
'url', 'url',
'type', 'type',
'votes', 'reactions',
'date', 'date',
'review', 'review',
'score',
'tags',
'is_spoiler',
'is_preliminary',
'entry' => [ 'entry' => [
'mal_id', 'mal_id',
'url', 'url',