mirror of
https://github.com/jikan-me/jikan-rest.git
synced 2025-02-20 11:23:35 +08:00
multiple fixes
- updated api docs - fixed top reviews endpoint - fixed reviews parsing - added "contextual" boolean query string parameters, so params without value can be interpreted as "boolean". E.g. ?sfw or ?kid in the url would add "true" value to their corresponding field in the DTO - fixed typesense issues
This commit is contained in:
parent
bcb87084c5
commit
0211fc4128
@ -211,7 +211,7 @@ class Anime extends JikanApiSearchableModel
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => (string) $this->mal_id,
|
'id' => (string) $this->mal_id,
|
||||||
'mal_id' => (string) $this->mal_id,
|
'mal_id' => (int) $this->mal_id,
|
||||||
'start_date' => $this->convertToTimestamp($this->aired['from']),
|
'start_date' => $this->convertToTimestamp($this->aired['from']),
|
||||||
'end_date' => $this->convertToTimestamp($this->aired['to']),
|
'end_date' => $this->convertToTimestamp($this->aired['to']),
|
||||||
'title' => $this->title,
|
'title' => $this->title,
|
||||||
|
25
app/Casts/ContextualBooleanCast.php
Normal file
25
app/Casts/ContextualBooleanCast.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Casts;
|
||||||
|
|
||||||
|
use Spatie\LaravelData\Casts\Cast;
|
||||||
|
use Spatie\LaravelData\Support\DataProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class ensures that "?sfw" and "?kids" boolean type query string parameters in the url would be interpreted as "true"
|
||||||
|
*/
|
||||||
|
final class ContextualBooleanCast implements Cast
|
||||||
|
{
|
||||||
|
|
||||||
|
public function cast(DataProperty $property, mixed $value, array $context): mixed
|
||||||
|
{
|
||||||
|
$propertyName = $property->name;
|
||||||
|
|
||||||
|
if (array_key_exists($propertyName, $context) && $context[$propertyName] === "")
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ use Spatie\LaravelData\Exceptions\CannotCastEnum;
|
|||||||
use Spatie\LaravelData\Support\DataProperty;
|
use Spatie\LaravelData\Support\DataProperty;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class EnumCast implements Cast
|
final class EnumCast implements Cast
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
protected ?string $type = null
|
protected ?string $type = null
|
||||||
|
@ -71,7 +71,7 @@ class Character extends JikanApiSearchableModel
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => (string) $this->mal_id,
|
'id' => (string) $this->mal_id,
|
||||||
'mal_id' => (string) $this->mal_id,
|
'mal_id' => (int) $this->mal_id,
|
||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
'name_kanji' => $this->name_kanji,
|
'name_kanji' => $this->name_kanji,
|
||||||
'member_favorites' => $this->member_favorites
|
'member_favorites' => $this->member_favorites
|
||||||
|
@ -78,7 +78,7 @@ class Club extends JikanApiSearchableModel
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => (string) $this->mal_id,
|
'id' => (string) $this->mal_id,
|
||||||
'mal_id' => (string) $this->mal_id,
|
'mal_id' => (int) $this->mal_id,
|
||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
'category' => $this->category,
|
'category' => $this->category,
|
||||||
'created' => $this->convertToTimestamp($this->created),
|
'created' => $this->convertToTimestamp($this->created),
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
namespace App\Dto;
|
namespace App\Dto;
|
||||||
|
|
||||||
|
use App\Casts\ContextualBooleanCast;
|
||||||
use App\Casts\EnumCast;
|
use App\Casts\EnumCast;
|
||||||
|
use App\Dto\Concerns\PreparesData;
|
||||||
use App\Enums\MediaReviewsSortEnum;
|
use App\Enums\MediaReviewsSortEnum;
|
||||||
use App\Rules\Attributes\EnumValidation;
|
use App\Rules\Attributes\EnumValidation;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
@ -17,15 +19,17 @@ use Spatie\LaravelData\Optional;
|
|||||||
*/
|
*/
|
||||||
final class AnimeReviewsLookupCommand extends LookupDataCommand
|
final class AnimeReviewsLookupCommand extends LookupDataCommand
|
||||||
{
|
{
|
||||||
|
use PreparesData;
|
||||||
|
|
||||||
#[Numeric, Min(1)]
|
#[Numeric, Min(1)]
|
||||||
public int|Optional $page = 1;
|
public int|Optional $page = 1;
|
||||||
|
|
||||||
#[WithCast(EnumCast::class, MediaReviewsSortEnum::class), EnumValidation(MediaReviewsSortEnum::class)]
|
#[WithCast(EnumCast::class, MediaReviewsSortEnum::class), EnumValidation(MediaReviewsSortEnum::class)]
|
||||||
public MediaReviewsSortEnum|Optional $sort;
|
public MediaReviewsSortEnum|Optional $sort;
|
||||||
|
|
||||||
#[BooleanType]
|
#[BooleanType, WithCast(ContextualBooleanCast::class)]
|
||||||
public bool|Optional $spoilers;
|
public bool|Optional $spoilers;
|
||||||
|
|
||||||
#[BooleanType]
|
#[BooleanType, WithCast(ContextualBooleanCast::class)]
|
||||||
public bool|Optional $preliminary;
|
public bool|Optional $preliminary;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use Spatie\LaravelData\Optional;
|
|||||||
|
|
||||||
trait HasLimitParameter
|
trait HasLimitParameter
|
||||||
{
|
{
|
||||||
use MapsDefaultLimitParameter;
|
use PreparesData;
|
||||||
|
|
||||||
#[IntegerType, Min(1), MaxLimitWithFallback]
|
#[IntegerType, Min(1), MaxLimitWithFallback]
|
||||||
public int|Optional $limit;
|
public int|Optional $limit;
|
||||||
|
16
app/Dto/Concerns/HasSfwParameter.php
Normal file
16
app/Dto/Concerns/HasSfwParameter.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Dto\Concerns;
|
||||||
|
|
||||||
|
use App\Casts\ContextualBooleanCast;
|
||||||
|
use Spatie\LaravelData\Attributes\Validation\BooleanType;
|
||||||
|
use Spatie\LaravelData\Attributes\WithCast;
|
||||||
|
use Spatie\LaravelData\Optional;
|
||||||
|
|
||||||
|
trait HasSfwParameter
|
||||||
|
{
|
||||||
|
use PreparesData;
|
||||||
|
|
||||||
|
#[BooleanType, WithCast(ContextualBooleanCast::class)]
|
||||||
|
public bool|Optional $sfw = false;
|
||||||
|
}
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Dto\Concerns;
|
|
||||||
|
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
use Illuminate\Support\Env;
|
|
||||||
|
|
||||||
trait MapsDefaultLimitParameter
|
|
||||||
{
|
|
||||||
public static function prepareForPipeline(Collection $properties): Collection
|
|
||||||
{
|
|
||||||
if (!$properties->has("limit"))
|
|
||||||
{
|
|
||||||
/** @noinspection PhpUndefinedFieldInspection */
|
|
||||||
$properties->put("limit", Env::get("MAX_RESULTS_PER_PAGE",
|
|
||||||
property_exists(static::class, "defaultLimit") ? static::$defaultLimit : 25));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $properties;
|
|
||||||
}
|
|
||||||
}
|
|
51
app/Dto/Concerns/PreparesData.php
Normal file
51
app/Dto/Concerns/PreparesData.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Dto\Concerns;
|
||||||
|
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Support\Env;
|
||||||
|
use \ReflectionClass;
|
||||||
|
use Spatie\LaravelData\Support\DataConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A trait for preparing the incoming data before passing it through the data pipeline.
|
||||||
|
* All preparation logic lives here.
|
||||||
|
* https://spatie.be/docs/laravel-data/v2/advanced-usage/pipeline
|
||||||
|
*/
|
||||||
|
trait PreparesData
|
||||||
|
{
|
||||||
|
public static function prepareForPipeline(Collection $properties): Collection
|
||||||
|
{
|
||||||
|
// let's always set the limit parameter to the globally configured default value
|
||||||
|
if (property_exists(static::class, "limit") && !$properties->has("limit")) {
|
||||||
|
/** @noinspection PhpUndefinedFieldInspection */
|
||||||
|
$properties->put("limit", Env::get("MAX_RESULTS_PER_PAGE",
|
||||||
|
property_exists(static::class, "defaultLimit") ? static::$defaultLimit : 25));
|
||||||
|
}
|
||||||
|
|
||||||
|
// we want to cast "true" and "false" string values to boolean before validation, so let's take all properties
|
||||||
|
// of the class which are bool or bool|Optional type, and using their name read the values from the incoming
|
||||||
|
// collection, and if they are present have such a value, convert them.
|
||||||
|
$dataClass = app(DataConfig::class)->getDataClass(static::class);
|
||||||
|
foreach ($dataClass->properties as $property) {
|
||||||
|
if (!$property->type->acceptsType("bool")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// the name can be different in the $properties variable, so let's check if there is an input name mapping
|
||||||
|
// for the property and use that instead if present.
|
||||||
|
$propertyRawName = $property->inputMappedName ?? $property->name;
|
||||||
|
if ($properties->has($propertyRawName)) {
|
||||||
|
$propertyVal = $properties->get($propertyRawName);
|
||||||
|
if ($propertyVal === "true") {
|
||||||
|
$propertyVal = true;
|
||||||
|
}
|
||||||
|
if ($propertyVal === "false") {
|
||||||
|
$propertyVal = false;
|
||||||
|
}
|
||||||
|
$properties->put($propertyRawName, $propertyVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $properties;
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,9 @@
|
|||||||
namespace App\Dto;
|
namespace App\Dto;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Casts\ContextualBooleanCast;
|
||||||
use App\Casts\EnumCast;
|
use App\Casts\EnumCast;
|
||||||
|
use App\Dto\Concerns\PreparesData;
|
||||||
use App\Enums\MediaReviewsSortEnum;
|
use App\Enums\MediaReviewsSortEnum;
|
||||||
use App\Rules\Attributes\EnumValidation;
|
use App\Rules\Attributes\EnumValidation;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
@ -18,15 +20,17 @@ use Spatie\LaravelData\Optional;
|
|||||||
*/
|
*/
|
||||||
final class MangaReviewsLookupCommand extends LookupDataCommand
|
final class MangaReviewsLookupCommand extends LookupDataCommand
|
||||||
{
|
{
|
||||||
|
use PreparesData;
|
||||||
|
|
||||||
#[Numeric, Min(1)]
|
#[Numeric, Min(1)]
|
||||||
public int|Optional $page = 1;
|
public int|Optional $page = 1;
|
||||||
|
|
||||||
#[WithCast(EnumCast::class, MediaReviewsSortEnum::class), EnumValidation(MediaReviewsSortEnum::class)]
|
#[WithCast(EnumCast::class, MediaReviewsSortEnum::class), EnumValidation(MediaReviewsSortEnum::class)]
|
||||||
public MediaReviewsSortEnum|Optional $sort;
|
public MediaReviewsSortEnum|Optional $sort;
|
||||||
|
|
||||||
#[BooleanType]
|
#[BooleanType, WithCast(ContextualBooleanCast::class)]
|
||||||
public bool|Optional $spoilers;
|
public bool|Optional $spoilers;
|
||||||
|
|
||||||
#[BooleanType]
|
#[BooleanType, WithCast(ContextualBooleanCast::class)]
|
||||||
public bool|Optional $preliminary;
|
public bool|Optional $preliminary;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Dto;
|
namespace App\Dto;
|
||||||
|
|
||||||
|
use App\Dto\Concerns\HasSfwParameter;
|
||||||
use Carbon\CarbonImmutable;
|
use Carbon\CarbonImmutable;
|
||||||
use Illuminate\Validation\Validator;
|
use Illuminate\Validation\Validator;
|
||||||
use Spatie\LaravelData\Attributes\MapInputName;
|
use Spatie\LaravelData\Attributes\MapInputName;
|
||||||
@ -22,6 +23,8 @@ use Spatie\LaravelData\Transformers\DateTimeInterfaceTransformer;
|
|||||||
|
|
||||||
class MediaSearchCommand extends SearchCommand
|
class MediaSearchCommand extends SearchCommand
|
||||||
{
|
{
|
||||||
|
use HasSfwParameter;
|
||||||
|
|
||||||
#[MapInputName("min_score"), MapOutputName("min_score"), Between(0.00, 10.00), Numeric]
|
#[MapInputName("min_score"), MapOutputName("min_score"), Between(0.00, 10.00), Numeric]
|
||||||
public float|Optional $minScore;
|
public float|Optional $minScore;
|
||||||
|
|
||||||
@ -31,8 +34,6 @@ class MediaSearchCommand extends SearchCommand
|
|||||||
#[Between(1.00, 9.99), Numeric, Prohibits(["min_score", "max_score"])]
|
#[Between(1.00, 9.99), Numeric, Prohibits(["min_score", "max_score"])]
|
||||||
public float|Optional $score;
|
public float|Optional $score;
|
||||||
|
|
||||||
public bool|Optional $sfw;
|
|
||||||
|
|
||||||
public string|Optional $genres;
|
public string|Optional $genres;
|
||||||
|
|
||||||
#[MapInputName("genres_exclude"), MapOutputName("genres_exclude")]
|
#[MapInputName("genres_exclude"), MapOutputName("genres_exclude")]
|
||||||
|
@ -3,11 +3,14 @@
|
|||||||
namespace App\Dto;
|
namespace App\Dto;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Casts\ContextualBooleanCast;
|
||||||
use App\Casts\EnumCast;
|
use App\Casts\EnumCast;
|
||||||
use App\Concerns\HasRequestFingerprint;
|
use App\Concerns\HasRequestFingerprint;
|
||||||
use App\Contracts\DataRequest;
|
use App\Contracts\DataRequest;
|
||||||
use App\Dto\Concerns\HasLimitParameter;
|
use App\Dto\Concerns\HasLimitParameter;
|
||||||
use App\Dto\Concerns\HasPageParameter;
|
use App\Dto\Concerns\HasPageParameter;
|
||||||
|
use App\Dto\Concerns\HasSfwParameter;
|
||||||
|
use App\Dto\Concerns\PreparesData;
|
||||||
use App\Enums\AnimeScheduleFilterEnum;
|
use App\Enums\AnimeScheduleFilterEnum;
|
||||||
use App\Rules\Attributes\EnumValidation;
|
use App\Rules\Attributes\EnumValidation;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
@ -22,14 +25,11 @@ use Spatie\LaravelData\Optional;
|
|||||||
*/
|
*/
|
||||||
final class QueryAnimeSchedulesCommand extends Data implements DataRequest
|
final class QueryAnimeSchedulesCommand extends Data implements DataRequest
|
||||||
{
|
{
|
||||||
use HasLimitParameter, HasRequestFingerprint, HasPageParameter;
|
use HasLimitParameter, HasRequestFingerprint, HasPageParameter, PreparesData, HasSfwParameter;
|
||||||
|
|
||||||
#[BooleanType]
|
#[BooleanType, WithCast(ContextualBooleanCast::class)]
|
||||||
public bool|Optional $kids = false;
|
public bool|Optional $kids = false;
|
||||||
|
|
||||||
#[BooleanType]
|
|
||||||
public bool|Optional $sfw = false;
|
|
||||||
|
|
||||||
#[WithCast(EnumCast::class, AnimeScheduleFilterEnum::class), EnumValidation(AnimeScheduleFilterEnum::class)]
|
#[WithCast(EnumCast::class, AnimeScheduleFilterEnum::class), EnumValidation(AnimeScheduleFilterEnum::class)]
|
||||||
public ?AnimeScheduleFilterEnum $filter;
|
public ?AnimeScheduleFilterEnum $filter;
|
||||||
|
|
||||||
|
@ -3,16 +3,14 @@
|
|||||||
namespace App\Dto;
|
namespace App\Dto;
|
||||||
|
|
||||||
use App\Contracts\DataRequest;
|
use App\Contracts\DataRequest;
|
||||||
|
use App\Dto\Concerns\HasSfwParameter;
|
||||||
use App\Http\Resources\V4\AnimeResource;
|
use App\Http\Resources\V4\AnimeResource;
|
||||||
use Spatie\LaravelData\Attributes\Validation\BooleanType;
|
|
||||||
use Spatie\LaravelData\Data;
|
use Spatie\LaravelData\Data;
|
||||||
use Spatie\LaravelData\Optional;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @implements DataRequest<AnimeResource>
|
* @implements DataRequest<AnimeResource>
|
||||||
*/
|
*/
|
||||||
final class QueryRandomAnimeCommand extends Data implements DataRequest
|
final class QueryRandomAnimeCommand extends Data implements DataRequest
|
||||||
{
|
{
|
||||||
#[BooleanType]
|
use HasSfwParameter;
|
||||||
public bool|Optional $sfw;
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Dto;
|
namespace App\Dto;
|
||||||
|
|
||||||
use App\Contracts\DataRequest;
|
use App\Contracts\DataRequest;
|
||||||
|
use App\Dto\Concerns\HasSfwParameter;
|
||||||
use App\Http\Resources\V4\MangaResource;
|
use App\Http\Resources\V4\MangaResource;
|
||||||
use Spatie\LaravelData\Attributes\Validation\BooleanType;
|
use Spatie\LaravelData\Attributes\Validation\BooleanType;
|
||||||
use Spatie\LaravelData\Data;
|
use Spatie\LaravelData\Data;
|
||||||
@ -13,6 +14,5 @@ use Spatie\LaravelData\Optional;
|
|||||||
*/
|
*/
|
||||||
final class QueryRandomMangaCommand extends Data implements DataRequest
|
final class QueryRandomMangaCommand extends Data implements DataRequest
|
||||||
{
|
{
|
||||||
#[BooleanType]
|
use HasSfwParameter;
|
||||||
public bool|Optional $sfw;
|
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
namespace App\Dto;
|
namespace App\Dto;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Casts\ContextualBooleanCast;
|
||||||
use App\Casts\EnumCast;
|
use App\Casts\EnumCast;
|
||||||
use App\Concerns\HasRequestFingerprint;
|
use App\Concerns\HasRequestFingerprint;
|
||||||
use App\Contracts\DataRequest;
|
use App\Contracts\DataRequest;
|
||||||
use App\Dto\Concerns\HasPageParameter;
|
use App\Dto\Concerns\HasPageParameter;
|
||||||
|
use App\Dto\Concerns\PreparesData;
|
||||||
use App\Enums\MediaReviewsSortEnum;
|
use App\Enums\MediaReviewsSortEnum;
|
||||||
use App\Http\Resources\V4\ResultsResource;
|
use App\Http\Resources\V4\ResultsResource;
|
||||||
use App\Rules\Attributes\EnumValidation;
|
use App\Rules\Attributes\EnumValidation;
|
||||||
@ -20,14 +22,14 @@ use Spatie\LaravelData\Optional;
|
|||||||
*/
|
*/
|
||||||
abstract class QueryReviewsCommand extends Data implements DataRequest
|
abstract class QueryReviewsCommand extends Data implements DataRequest
|
||||||
{
|
{
|
||||||
use HasRequestFingerprint, HasPageParameter;
|
use HasRequestFingerprint, HasPageParameter, PreparesData;
|
||||||
|
|
||||||
#[WithCast(EnumCast::class, MediaReviewsSortEnum::class), EnumValidation(MediaReviewsSortEnum::class)]
|
#[WithCast(EnumCast::class, MediaReviewsSortEnum::class), EnumValidation(MediaReviewsSortEnum::class)]
|
||||||
public MediaReviewsSortEnum|Optional $sort;
|
public MediaReviewsSortEnum|Optional $sort;
|
||||||
|
|
||||||
#[BooleanType]
|
#[BooleanType, WithCast(ContextualBooleanCast::class)]
|
||||||
public bool|Optional $spoilers;
|
public bool|Optional $spoilers;
|
||||||
|
|
||||||
#[BooleanType]
|
#[BooleanType, WithCast(ContextualBooleanCast::class)]
|
||||||
public bool|Optional $preliminary;
|
public bool|Optional $preliminary;
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,31 @@
|
|||||||
|
|
||||||
namespace App\Dto;
|
namespace App\Dto;
|
||||||
|
|
||||||
|
use App\Casts\ContextualBooleanCast;
|
||||||
|
use App\Casts\EnumCast;
|
||||||
use App\Concerns\HasRequestFingerprint;
|
use App\Concerns\HasRequestFingerprint;
|
||||||
use App\Contracts\DataRequest;
|
use App\Contracts\DataRequest;
|
||||||
|
use App\Dto\Concerns\PreparesData;
|
||||||
|
use App\Enums\TopAnimeFilterEnum;
|
||||||
|
use App\Enums\TopReviewsTypeEnum;
|
||||||
|
use App\Rules\Attributes\EnumValidation;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Spatie\LaravelData\Attributes\WithCast;
|
||||||
|
use Spatie\LaravelData\Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @implements DataRequest<JsonResponse>
|
* @implements DataRequest<JsonResponse>
|
||||||
*/
|
*/
|
||||||
final class QueryTopReviewsCommand extends QueryTopItemsCommand implements DataRequest
|
final class QueryTopReviewsCommand extends QueryTopItemsCommand implements DataRequest
|
||||||
{
|
{
|
||||||
use HasRequestFingerprint;
|
use HasRequestFingerprint, PreparesData;
|
||||||
|
|
||||||
|
#[WithCast(EnumCast::class, TopAnimeFilterEnum::class), EnumValidation(TopReviewsTypeEnum::class)]
|
||||||
|
public TopReviewsTypeEnum|Optional $type;
|
||||||
|
|
||||||
|
#[WithCast(ContextualBooleanCast::class)]
|
||||||
|
public bool|Optional $spoilers;
|
||||||
|
|
||||||
|
#[WithCast(ContextualBooleanCast::class)]
|
||||||
|
public bool|Optional $preliminary;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ use Spatie\Enum\Laravel\Enum;
|
|||||||
* @method static self episodes()
|
* @method static self episodes()
|
||||||
* @method static self score()
|
* @method static self score()
|
||||||
* @method static self scored_by()
|
* @method static self scored_by()
|
||||||
* @method static self rank
|
* @method static self rank()
|
||||||
* @method static self popularity()
|
* @method static self popularity()
|
||||||
* @method static self members()
|
* @method static self members()
|
||||||
* @method static self favorites()
|
* @method static self favorites()
|
||||||
|
@ -3,14 +3,21 @@
|
|||||||
namespace App\Enums;
|
namespace App\Enums;
|
||||||
|
|
||||||
use Jikan\Helper\Constants as JikanConstants;
|
use Jikan\Helper\Constants as JikanConstants;
|
||||||
|
use Spatie\Enum\Laravel\Enum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @method static self any()
|
* @method static self any()
|
||||||
* @method static self male()
|
* @method static self male()
|
||||||
* @method static self female()
|
* @method static self female()
|
||||||
* @method static self nonbinary()
|
* @method static self nonbinary()
|
||||||
|
* @OA\Schema(
|
||||||
|
* schema="users_search_query_gender",
|
||||||
|
* description="Users Search Query Gender.",
|
||||||
|
* type="string",
|
||||||
|
* enum={"any","male","female","nonbinary"}
|
||||||
|
* )
|
||||||
*/
|
*/
|
||||||
final class GenderEnum extends \Spatie\Enum\Laravel\Enum
|
final class GenderEnum extends Enum
|
||||||
{
|
{
|
||||||
protected static function labels(): array
|
protected static function labels(): array
|
||||||
{
|
{
|
||||||
|
20
app/Enums/TopReviewsTypeEnum.php
Normal file
20
app/Enums/TopReviewsTypeEnum.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
|
||||||
|
|
||||||
|
use Spatie\Enum\Laravel\Enum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method static self anime()
|
||||||
|
* @method static self manga()
|
||||||
|
* @OA\Schema(
|
||||||
|
* schema="top_reviews_type_enum",
|
||||||
|
* description="The type of reviews to filter by. Defaults to anime.",
|
||||||
|
* type="string",
|
||||||
|
* enum={"anime","manga"}
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
final class TopReviewsTypeEnum extends Enum
|
||||||
|
{
|
||||||
|
}
|
@ -3,12 +3,13 @@
|
|||||||
namespace App\Features;
|
namespace App\Features;
|
||||||
|
|
||||||
use App\Dto\QueryTopReviewsCommand;
|
use App\Dto\QueryTopReviewsCommand;
|
||||||
|
use App\Enums\TopReviewsTypeEnum;
|
||||||
use App\Support\CachedData;
|
use App\Support\CachedData;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Jikan\Helper\Constants;
|
use Jikan\Helper\Constants;
|
||||||
use Jikan\MyAnimeList\MalClient;
|
use Jikan\MyAnimeList\MalClient;
|
||||||
use Jikan\Request\Reviews\RecentReviewsRequest;
|
use Jikan\Request\Reviews\ReviewsRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @extends RequestHandlerWithScraperCache<QueryTopReviewsCommand, JsonResponse>
|
* @extends RequestHandlerWithScraperCache<QueryTopReviewsCommand, JsonResponse>
|
||||||
@ -25,9 +26,12 @@ final class QueryTopReviewsHandler extends RequestHandlerWithScraperCache
|
|||||||
|
|
||||||
protected function getScraperData(string $requestFingerPrint, Collection $requestParams): CachedData
|
protected function getScraperData(string $requestFingerPrint, Collection $requestParams): CachedData
|
||||||
{
|
{
|
||||||
|
$type = $requestParams->get("type", TopReviewsTypeEnum::anime()->value);
|
||||||
|
$spoilers = $requestParams->get("spoilers", true);
|
||||||
|
$preliminary = $requestParams->get("preliminary", true);
|
||||||
return $this->scraperService->findList(
|
return $this->scraperService->findList(
|
||||||
$requestFingerPrint,
|
$requestFingerPrint,
|
||||||
fn (MalClient $jikan, ?int $page = null) => $jikan->getRecentReviews(new RecentReviewsRequest(Constants::RECENT_REVIEW_BEST_VOTED, $page)),
|
fn (MalClient $jikan, ?int $page = null) => $jikan->getReviews(new ReviewsRequest($type, $page, $spoilers, $preliminary)),
|
||||||
$requestParams->get("page"));
|
$requestParams->get("page"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ class GenreAnime extends JikanApiSearchableModel
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => (string) $this->mal_id,
|
'id' => (string) $this->mal_id,
|
||||||
'mal_id' => (string) $this->mal_id,
|
'mal_id' => (int) $this->mal_id,
|
||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
'count' => $this->count
|
'count' => $this->count
|
||||||
];
|
];
|
||||||
|
@ -59,7 +59,7 @@ class GenreManga extends JikanApiSearchableModel
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => (string) $this->mal_id,
|
'id' => (string) $this->mal_id,
|
||||||
'mal_id' => (string) $this->mal_id,
|
'mal_id' => (int) $this->mal_id,
|
||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
'count' => $this->count
|
'count' => $this->count
|
||||||
];
|
];
|
||||||
|
@ -2,33 +2,12 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\V4DB;
|
namespace App\Http\Controllers\V4DB;
|
||||||
|
|
||||||
use App\Anime;
|
|
||||||
use App\Character;
|
|
||||||
use App\Dto\QueryRandomAnimeCommand;
|
use App\Dto\QueryRandomAnimeCommand;
|
||||||
use App\Dto\QueryRandomCharacterCommand;
|
use App\Dto\QueryRandomCharacterCommand;
|
||||||
use App\Dto\QueryRandomMangaCommand;
|
use App\Dto\QueryRandomMangaCommand;
|
||||||
use App\Dto\QueryRandomPersonCommand;
|
use App\Dto\QueryRandomPersonCommand;
|
||||||
use App\Dto\QueryRandomUserCommand;
|
use App\Dto\QueryRandomUserCommand;
|
||||||
use App\Http\HttpHelper;
|
|
||||||
use App\Http\HttpResponse;
|
|
||||||
use App\Http\Resources\V4\AnimeCollection;
|
|
||||||
use App\Http\Resources\V4\AnimeResource;
|
|
||||||
use App\Http\Resources\V4\CharacterCollection;
|
|
||||||
use App\Http\Resources\V4\CharacterResource;
|
|
||||||
use App\Http\Resources\V4\CommonResource;
|
|
||||||
use App\Http\Resources\V4\MangaCollection;
|
|
||||||
use App\Http\Resources\V4\MangaResource;
|
|
||||||
use App\Http\Resources\V4\PersonCollection;
|
|
||||||
use App\Http\Resources\V4\PersonResource;
|
|
||||||
use App\Http\Resources\V4\ProfileResource;
|
|
||||||
use App\Http\Resources\V4\ResultsResource;
|
|
||||||
use App\Http\Resources\V4\UserCollection;
|
|
||||||
use App\Manga;
|
|
||||||
use App\Person;
|
|
||||||
use App\Profile;
|
|
||||||
use App\User;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use MongoDB\BSON\UTCDateTime;
|
|
||||||
|
|
||||||
class RandomController extends Controller
|
class RandomController extends Controller
|
||||||
{
|
{
|
||||||
|
@ -28,7 +28,7 @@ class TopController extends Controller
|
|||||||
* name="filter",
|
* name="filter",
|
||||||
* in="query",
|
* in="query",
|
||||||
* required=false,
|
* required=false,
|
||||||
* @OA\Schema(ref="#/components/schemas/top_anime_filter)
|
* @OA\Schema(ref="#/components/schemas/top_anime_filter")
|
||||||
* ),
|
* ),
|
||||||
*
|
*
|
||||||
* @OA\Parameter(
|
* @OA\Parameter(
|
||||||
@ -82,7 +82,7 @@ class TopController extends Controller
|
|||||||
* name="filter",
|
* name="filter",
|
||||||
* in="query",
|
* in="query",
|
||||||
* required=false,
|
* required=false,
|
||||||
* @OA\Schema(ref="#/components/schemas/top_manga_filter)
|
* @OA\Schema(ref="#/components/schemas/top_manga_filter")
|
||||||
* ),
|
* ),
|
||||||
*
|
*
|
||||||
* @OA\Parameter(ref="#/components/parameters/page"),
|
* @OA\Parameter(ref="#/components/parameters/page"),
|
||||||
@ -168,6 +168,29 @@ class TopController extends Controller
|
|||||||
*
|
*
|
||||||
* @OA\Parameter(ref="#/components/parameters/page"),
|
* @OA\Parameter(ref="#/components/parameters/page"),
|
||||||
*
|
*
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="type",
|
||||||
|
* in="query",
|
||||||
|
* required=false,
|
||||||
|
* @OA\Schema(ref="#/components/schemas/top_reviews_type_enum")
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="preliminary",
|
||||||
|
* in="query",
|
||||||
|
* required=false,
|
||||||
|
* description="Whether the results include preliminary reviews or not. Defaults to true.",
|
||||||
|
* @OA\Schema(type="boolean")
|
||||||
|
* ),
|
||||||
|
*
|
||||||
|
* @OA\Parameter(
|
||||||
|
* name="spoilers",
|
||||||
|
* in="query",
|
||||||
|
* required=false,
|
||||||
|
* description="Whether the results include reviews with spoilers or not. Defaults to true.",
|
||||||
|
* @OA\Schema(type="boolean")
|
||||||
|
* ),
|
||||||
|
*
|
||||||
* @OA\Response(
|
* @OA\Response(
|
||||||
* response="200",
|
* response="200",
|
||||||
* description="Returns top reviews",
|
* description="Returns top reviews",
|
||||||
|
@ -38,32 +38,16 @@ class HttpHelper
|
|||||||
return (int) str_replace('v', '', $request->segment(1));
|
return (int) str_replace('v', '', $request->segment(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function serializeEmptyObjects(string $requestType, array $data)
|
public static function serializeEmptyObjects(string $requestType, array $data): array
|
||||||
{
|
{
|
||||||
if (!($requestType === 'anime' || $requestType === 'manga')) {
|
if (!($requestType === 'anime' || $requestType === 'manga')) {
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($data['related']) && \count($data['related']) === 0) {
|
return self::serializeEmptyObjectsControllerLevel($data);
|
||||||
$data['related'] = new \stdClass();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($data['related'])) {
|
|
||||||
$related = $data['related'];
|
|
||||||
$data['related'] = [];
|
|
||||||
|
|
||||||
foreach ($related as $relation => $items) {
|
|
||||||
$data['related'][] = [
|
|
||||||
'relation' => $relation,
|
|
||||||
'entry' => $items
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function serializeEmptyObjectsControllerLevel(array $data)
|
public static function serializeEmptyObjectsControllerLevel(array $data): array
|
||||||
{
|
{
|
||||||
if (isset($data['related']) && \count($data['related']) === 0) {
|
if (isset($data['related']) && \count($data['related']) === 0) {
|
||||||
$data['related'] = new \stdClass();
|
$data['related'] = new \stdClass();
|
||||||
|
@ -94,12 +94,12 @@ class ReviewsResource extends JsonResource
|
|||||||
* ),
|
* ),
|
||||||
* @OA\Property (
|
* @OA\Property (
|
||||||
* property="is_spoiler",
|
* property="is_spoiler",
|
||||||
* type="bool",
|
* type="boolean",
|
||||||
* description="The review contains spoiler"
|
* description="The review contains spoiler"
|
||||||
* ),
|
* ),
|
||||||
* @OA\Property (
|
* @OA\Property (
|
||||||
* property="is_preliminary",
|
* property="is_preliminary",
|
||||||
* type="bool",
|
* type="boolean",
|
||||||
* description="The review was made before the entry was completed"
|
* description="The review was made before the entry was completed"
|
||||||
* ),
|
* ),
|
||||||
* ),
|
* ),
|
||||||
@ -190,12 +190,12 @@ class ReviewsResource extends JsonResource
|
|||||||
* ),
|
* ),
|
||||||
* @OA\Property (
|
* @OA\Property (
|
||||||
* property="is_spoiler",
|
* property="is_spoiler",
|
||||||
* type="bool",
|
* type="boolean",
|
||||||
* description="The review contains spoiler"
|
* description="The review contains spoiler"
|
||||||
* ),
|
* ),
|
||||||
* @OA\Property (
|
* @OA\Property (
|
||||||
* property="is_preliminary",
|
* property="is_preliminary",
|
||||||
* type="bool",
|
* type="boolean",
|
||||||
* description="The review was made before the entry was completed"
|
* description="The review was made before the entry was completed"
|
||||||
* ),
|
* ),
|
||||||
* @OA\Property(
|
* @OA\Property(
|
||||||
|
@ -21,7 +21,7 @@ class JikanApiModel extends \Jenssegers\Mongodb\Eloquent\Model
|
|||||||
/** @noinspection PhpUnused */
|
/** @noinspection PhpUnused */
|
||||||
public function scopeRandom(Builder $query, int $numberOfRandomItems = 1): Collection
|
public function scopeRandom(Builder $query, int $numberOfRandomItems = 1): Collection
|
||||||
{
|
{
|
||||||
return $query->raw(fn(\MongoDB\Collection $collection) => $collection->aggregate([
|
return $query->raw(fn(\Jenssegers\Mongodb\Collection $collection) => $collection->aggregate([
|
||||||
['$sample' => ['size' => $numberOfRandomItems]]
|
['$sample' => ['size' => $numberOfRandomItems]]
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ class Magazine extends JikanApiSearchableModel
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => (string) $this->mal_id,
|
'id' => (string) $this->mal_id,
|
||||||
'mal_id' => (string) $this->mal_id,
|
'mal_id' => (int) $this->mal_id,
|
||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
'count' => $this->count
|
'count' => $this->count
|
||||||
];
|
];
|
||||||
|
@ -121,7 +121,7 @@ class Manga extends JikanApiSearchableModel
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => (string) $this->mal_id,
|
'id' => (string) $this->mal_id,
|
||||||
'mal_id' => (string) $this->mal_id,
|
'mal_id' => (int) $this->mal_id,
|
||||||
'start_date' => $this->convertToTimestamp($this->published['from']),
|
'start_date' => $this->convertToTimestamp($this->published['from']),
|
||||||
'end_date' => $this->convertToTimestamp($this->published['to']),
|
'end_date' => $this->convertToTimestamp($this->published['to']),
|
||||||
'title' => $this->title,
|
'title' => $this->title,
|
||||||
|
@ -76,7 +76,7 @@ class Person extends JikanApiSearchableModel
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => (string) $this->mal_id,
|
'id' => (string) $this->mal_id,
|
||||||
'mal_id' => (string) $this->mal_id,
|
'mal_id' => (int) $this->mal_id,
|
||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
'given_name' => $this->given_name,
|
'given_name' => $this->given_name,
|
||||||
'family_name' => $this->family_name,
|
'family_name' => $this->family_name,
|
||||||
|
@ -59,9 +59,12 @@ class Producers extends JikanApiSearchableModel
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => (string) $this->mal_id,
|
'id' => (string) $this->mal_id,
|
||||||
'mal_id' => (string) $this->mal_id,
|
'mal_id' => (int) $this->mal_id,
|
||||||
'url' => !is_null($this->url) ? collect(explode('/', $this->url))->last() : '',
|
'url' => !is_null($this->url) ? $this->url : '',
|
||||||
'titles' => !is_null($this->titles) ? $this->titles : ['']
|
'titles' => !is_null($this->titles) ? collect($this->titles)->map(fn ($x) => $x["title"])->toArray() : [''],
|
||||||
|
'established' => $this->convertToTimestamp($this->established),
|
||||||
|
'favorites' => $this->favorites,
|
||||||
|
'count' => $this->count
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ use Jikan\Request\User\UserProfileRequest;
|
|||||||
class Profile extends JikanApiSearchableModel
|
class Profile extends JikanApiSearchableModel
|
||||||
{
|
{
|
||||||
use FilteredByLetter;
|
use FilteredByLetter;
|
||||||
protected array $filters = ["order_by", "sort", "letter"];
|
protected array $filters = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
@ -61,7 +61,7 @@ class Profile extends JikanApiSearchableModel
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'id' => (string) $this->mal_id,
|
'id' => (string) $this->mal_id,
|
||||||
'mal_id' => (string) $this->mal_id,
|
'mal_id' => (int) $this->mal_id,
|
||||||
'username' => $this->username
|
'username' => $this->username
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -39,3 +39,18 @@ if (!function_exists('rescue')) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!function_exists('to_boolean')) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert to boolean
|
||||||
|
*
|
||||||
|
* @param $booleable
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
function to_boolean($booleable): bool
|
||||||
|
{
|
||||||
|
return filter_var($booleable, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -2982,6 +2982,53 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/seasons/now": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"seasons"
|
||||||
|
],
|
||||||
|
"operationId": "getSeasonNow",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/parameters/page"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/parameters/limit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "filter",
|
||||||
|
"in": "query",
|
||||||
|
"description": "Entry types",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"tv",
|
||||||
|
"movie",
|
||||||
|
"ova",
|
||||||
|
"special",
|
||||||
|
"ona",
|
||||||
|
"music"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Returns current seasonal anime",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/anime_search"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Error: Bad request. When required parameters were not supplied."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/seasons/{year}/{season}": {
|
"/seasons/{year}/{season}": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -3023,6 +3070,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$ref": "#/components/parameters/page"
|
"$ref": "#/components/parameters/page"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/parameters/limit"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@ -3042,34 +3092,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/seasons/now": {
|
|
||||||
"get": {
|
|
||||||
"tags": [
|
|
||||||
"seasons"
|
|
||||||
],
|
|
||||||
"operationId": "getSeasonNow",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"$ref": "#/components/parameters/page"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "Returns current seasonal anime",
|
|
||||||
"content": {
|
|
||||||
"application/json": {
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/components/schemas/anime_search"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"400": {
|
|
||||||
"description": "Error: Bad request. When required parameters were not supplied."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/seasons": {
|
"/seasons": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -3118,6 +3140,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"$ref": "#/components/parameters/page"
|
"$ref": "#/components/parameters/page"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/parameters/limit"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@ -3157,13 +3182,22 @@
|
|||||||
"in": "query",
|
"in": "query",
|
||||||
"required": false,
|
"required": false,
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string",
|
"$ref": "#/components/schemas/top_anime_filter"
|
||||||
"enum": [
|
}
|
||||||
"airing",
|
},
|
||||||
"upcoming",
|
{
|
||||||
"bypopularity",
|
"name": "rating",
|
||||||
"favorite"
|
"in": "query",
|
||||||
]
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/anime_search_query_rating"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sfw",
|
||||||
|
"in": "query",
|
||||||
|
"description": "Filter out Adult entries",
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3210,13 +3244,7 @@
|
|||||||
"in": "query",
|
"in": "query",
|
||||||
"required": false,
|
"required": false,
|
||||||
"schema": {
|
"schema": {
|
||||||
"type": "string",
|
"$ref": "#/components/schemas/top_manga_filter"
|
||||||
"enum": [
|
|
||||||
"publishing",
|
|
||||||
"upcoming",
|
|
||||||
"bypopularity",
|
|
||||||
"favorite"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3314,6 +3342,32 @@
|
|||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"$ref": "#/components/parameters/page"
|
"$ref": "#/components/parameters/page"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "type",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/top_reviews_type_enum"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "preliminary",
|
||||||
|
"in": "query",
|
||||||
|
"description": "Whether the results include preliminary reviews or not. Defaults to true.",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "spoilers",
|
||||||
|
"in": "query",
|
||||||
|
"description": "Whether the results include reviews with spoilers or not. Defaults to true.",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@ -3974,11 +4028,6 @@
|
|||||||
"watch"
|
"watch"
|
||||||
],
|
],
|
||||||
"operationId": "getWatchRecentEpisodes",
|
"operationId": "getWatchRecentEpisodes",
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"$ref": "#/components/parameters/limit"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Returns Recently Added Episodes",
|
"description": "Returns Recently Added Episodes",
|
||||||
@ -4002,11 +4051,6 @@
|
|||||||
"watch"
|
"watch"
|
||||||
],
|
],
|
||||||
"operationId": "getWatchPopularEpisodes",
|
"operationId": "getWatchPopularEpisodes",
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"$ref": "#/components/parameters/limit"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Returns Popular Episodes",
|
"description": "Returns Popular Episodes",
|
||||||
@ -4030,6 +4074,11 @@
|
|||||||
"watch"
|
"watch"
|
||||||
],
|
],
|
||||||
"operationId": "getWatchRecentPromos",
|
"operationId": "getWatchRecentPromos",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/parameters/page"
|
||||||
|
}
|
||||||
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Returns Recently Added Promotional Videos",
|
"description": "Returns Recently Added Promotional Videos",
|
||||||
@ -4053,11 +4102,6 @@
|
|||||||
"watch"
|
"watch"
|
||||||
],
|
],
|
||||||
"operationId": "getWatchPopularPromos",
|
"operationId": "getWatchPopularPromos",
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"$ref": "#/components/parameters/limit"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Returns Popular Promotional Videos",
|
"description": "Returns Popular Promotional Videos",
|
||||||
@ -4078,6 +4122,231 @@
|
|||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
"schemas": {
|
"schemas": {
|
||||||
|
"anime_search_query_orderby": {
|
||||||
|
"description": "Available Anime order_by properties",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"mal_id",
|
||||||
|
"title",
|
||||||
|
"type",
|
||||||
|
"rating",
|
||||||
|
"start_date",
|
||||||
|
"end_date",
|
||||||
|
"episodes",
|
||||||
|
"score",
|
||||||
|
"scored_by",
|
||||||
|
"rank",
|
||||||
|
"popularity",
|
||||||
|
"members",
|
||||||
|
"favorites"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"anime_search_query_rating": {
|
||||||
|
"description": "Available Anime audience ratings<br><br><b>Ratings</b><br><ul><li>G - All Ages</li><li>PG - Children</li><li>PG-13 - Teens 13 or older</li><li>R - 17+ (violence & profanity)</li><li>R+ - Mild Nudity</li><li>Rx - Hentai</li></ul>",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"g",
|
||||||
|
"pg",
|
||||||
|
"pg13",
|
||||||
|
"r17",
|
||||||
|
"r",
|
||||||
|
"rx"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"anime_search_query_status": {
|
||||||
|
"description": "Available Anime statuses",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"airing",
|
||||||
|
"complete",
|
||||||
|
"upcoming"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"anime_search_query_type": {
|
||||||
|
"description": "Available Anime types",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"tv",
|
||||||
|
"movie",
|
||||||
|
"ova",
|
||||||
|
"special",
|
||||||
|
"ona",
|
||||||
|
"music"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"characters_search_query_orderby": {
|
||||||
|
"description": "Available Character order_by properties",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"mal_id",
|
||||||
|
"name",
|
||||||
|
"favorites"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"club_search_query_category": {
|
||||||
|
"description": "Club Search Query Category",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"anime",
|
||||||
|
"manga",
|
||||||
|
"actors_and_artists",
|
||||||
|
"characters",
|
||||||
|
"cities_and_neighborhoods",
|
||||||
|
"companies",
|
||||||
|
"conventions",
|
||||||
|
"games",
|
||||||
|
"japan",
|
||||||
|
"music",
|
||||||
|
"other",
|
||||||
|
"schools"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"club_search_query_orderby": {
|
||||||
|
"description": "Club Search Query OrderBy",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"mal_id",
|
||||||
|
"name",
|
||||||
|
"members_count",
|
||||||
|
"created"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"club_search_query_type": {
|
||||||
|
"description": "Club Search Query Type",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"public",
|
||||||
|
"private",
|
||||||
|
"secret"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"users_search_query_gender": {
|
||||||
|
"description": "Users Search Query Gender.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"any",
|
||||||
|
"male",
|
||||||
|
"female",
|
||||||
|
"nonbinary"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"genre_query_filter": {
|
||||||
|
"description": "Filter genres by type",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"genres",
|
||||||
|
"explicit_genres",
|
||||||
|
"themes",
|
||||||
|
"demographics"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"magazines_query_orderby": {
|
||||||
|
"description": "Order by magazine data",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"mal_id",
|
||||||
|
"name",
|
||||||
|
"count"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"manga_search_query_orderby": {
|
||||||
|
"description": "Available Manga order_by properties",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"mal_id",
|
||||||
|
"title",
|
||||||
|
"start_date",
|
||||||
|
"end_date",
|
||||||
|
"chapters",
|
||||||
|
"volumes",
|
||||||
|
"score",
|
||||||
|
"scored_by",
|
||||||
|
"rank",
|
||||||
|
"popularity",
|
||||||
|
"members",
|
||||||
|
"favorites"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"manga_search_query_status": {
|
||||||
|
"description": "Available Manga statuses",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"publishing",
|
||||||
|
"complete",
|
||||||
|
"hiatus",
|
||||||
|
"discontinued",
|
||||||
|
"upcoming"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"manga_search_query_type": {
|
||||||
|
"description": "Available Manga types",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"manga",
|
||||||
|
"novel",
|
||||||
|
"lightnovel",
|
||||||
|
"oneshot",
|
||||||
|
"doujin",
|
||||||
|
"manhwa",
|
||||||
|
"manhua"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"people_search_query_orderby": {
|
||||||
|
"description": "Available People order_by properties",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"mal_id",
|
||||||
|
"name",
|
||||||
|
"birthday",
|
||||||
|
"favorites"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"producers_query_orderby": {
|
||||||
|
"description": "Producers Search Query Order By",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"mal_id",
|
||||||
|
"count",
|
||||||
|
"favorites",
|
||||||
|
"established"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"search_query_sort": {
|
||||||
|
"description": "Search query sort direction",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"desc",
|
||||||
|
"asc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"top_anime_filter": {
|
||||||
|
"description": "Top items filter types",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"airing",
|
||||||
|
"upcoming",
|
||||||
|
"bypopularity",
|
||||||
|
"favorite"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"top_manga_filter": {
|
||||||
|
"description": "Top items filter types",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"publishing",
|
||||||
|
"upcoming",
|
||||||
|
"bypopularity",
|
||||||
|
"favorite"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"top_reviews_type_enum": {
|
||||||
|
"description": "The type of reviews to filter by. Defaults to anime.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"anime",
|
||||||
|
"manga"
|
||||||
|
]
|
||||||
|
},
|
||||||
"anime_episodes": {
|
"anime_episodes": {
|
||||||
"description": "Anime Episodes Resource",
|
"description": "Anime Episodes Resource",
|
||||||
"allOf": [
|
"allOf": [
|
||||||
@ -4231,15 +4500,6 @@
|
|||||||
},
|
},
|
||||||
"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": [
|
||||||
@ -4320,14 +4580,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"search_query_sort": {
|
|
||||||
"description": "Characters Search Query Sort",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"desc",
|
|
||||||
"asc"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"users_search": {
|
"users_search": {
|
||||||
"description": "User Results",
|
"description": "User Results",
|
||||||
"allOf": [
|
"allOf": [
|
||||||
@ -4364,16 +4616,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"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": {
|
||||||
@ -4590,167 +4832,6 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"anime_search_query_type": {
|
|
||||||
"description": "Available Anime types",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"tv",
|
|
||||||
"movie",
|
|
||||||
"ova",
|
|
||||||
"special",
|
|
||||||
"ona",
|
|
||||||
"music"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"anime_search_query_status": {
|
|
||||||
"description": "Available Anime statuses",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"airing",
|
|
||||||
"complete",
|
|
||||||
"upcoming"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"anime_search_query_rating": {
|
|
||||||
"description": "Available Anime audience ratings<br><br><b>Ratings</b><br><ul><li>G - All Ages</li><li>PG - Children</li><li>PG-13 - Teens 13 or older</li><li>R - 17+ (violence & profanity)</li><li>R+ - Mild Nudity</li><li>Rx - Hentai</li></ul>",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"g",
|
|
||||||
"pg",
|
|
||||||
"pg13",
|
|
||||||
"r17",
|
|
||||||
"r",
|
|
||||||
"rx"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"anime_search_query_orderby": {
|
|
||||||
"description": "Available Anime order_by properties",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"mal_id",
|
|
||||||
"title",
|
|
||||||
"type",
|
|
||||||
"rating",
|
|
||||||
"start_date",
|
|
||||||
"end_date",
|
|
||||||
"episodes",
|
|
||||||
"score",
|
|
||||||
"scored_by",
|
|
||||||
"rank",
|
|
||||||
"popularity",
|
|
||||||
"members",
|
|
||||||
"favorites"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"characters_search_query_orderby": {
|
|
||||||
"description": "Available Character order_by properties",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"mal_id",
|
|
||||||
"name",
|
|
||||||
"favorites"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"club_search_query_type": {
|
|
||||||
"description": "Club Search Query Type",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"public",
|
|
||||||
"private",
|
|
||||||
"secret"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"club_search_query_category": {
|
|
||||||
"description": "Club Search Query Category",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"anime",
|
|
||||||
"manga",
|
|
||||||
"actors_and_artists",
|
|
||||||
"characters",
|
|
||||||
"cities_and_neighborhoods",
|
|
||||||
"companies",
|
|
||||||
"conventions",
|
|
||||||
"games",
|
|
||||||
"japan",
|
|
||||||
"music",
|
|
||||||
"other",
|
|
||||||
"schools"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"club_search_query_orderby": {
|
|
||||||
"description": "Club Search Query OrderBy",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"mal_id",
|
|
||||||
"title",
|
|
||||||
"members_count",
|
|
||||||
"pictures_count",
|
|
||||||
"created"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"manga_search_query_type": {
|
|
||||||
"description": "Available Manga types",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"manga",
|
|
||||||
"novel",
|
|
||||||
"lightnovel",
|
|
||||||
"oneshot",
|
|
||||||
"doujin",
|
|
||||||
"manhwa",
|
|
||||||
"manhua"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"manga_search_query_status": {
|
|
||||||
"description": "Available Manga statuses",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"publishing",
|
|
||||||
"complete",
|
|
||||||
"hiatus",
|
|
||||||
"discontinued",
|
|
||||||
"upcoming"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"manga_search_query_orderby": {
|
|
||||||
"description": "Available Manga order_by properties",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"mal_id",
|
|
||||||
"title",
|
|
||||||
"start_date",
|
|
||||||
"end_date",
|
|
||||||
"chapters",
|
|
||||||
"volumes",
|
|
||||||
"score",
|
|
||||||
"scored_by",
|
|
||||||
"rank",
|
|
||||||
"popularity",
|
|
||||||
"members",
|
|
||||||
"favorites"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"people_search_query_orderby": {
|
|
||||||
"description": "Available People order_by properties",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"mal_id",
|
|
||||||
"name",
|
|
||||||
"birthday",
|
|
||||||
"favorites"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"users_search_query_gender": {
|
|
||||||
"description": "Users Search Query Gender",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"any",
|
|
||||||
"male",
|
|
||||||
"female",
|
|
||||||
"nonbinary"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"anime_characters": {
|
"anime_characters": {
|
||||||
"description": "Anime Characters Resource",
|
"description": "Anime Characters Resource",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -6649,16 +6730,6 @@
|
|||||||
},
|
},
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"genre_query_filter": {
|
|
||||||
"description": "Filter genres by type",
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"genres",
|
|
||||||
"explicit_genres",
|
|
||||||
"themes",
|
|
||||||
"demographics"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"genre": {
|
"genre": {
|
||||||
"description": "Genre Resource",
|
"description": "Genre Resource",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -8564,11 +8635,11 @@
|
|||||||
},
|
},
|
||||||
"is_spoiler": {
|
"is_spoiler": {
|
||||||
"description": "The review contains spoiler",
|
"description": "The review contains spoiler",
|
||||||
"type": "bool"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"is_preliminary": {
|
"is_preliminary": {
|
||||||
"description": "The review was made before the entry was completed",
|
"description": "The review was made before the entry was completed",
|
||||||
"type": "bool"
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"type": "object"
|
"type": "object"
|
||||||
@ -8646,11 +8717,11 @@
|
|||||||
},
|
},
|
||||||
"is_spoiler": {
|
"is_spoiler": {
|
||||||
"description": "The review contains spoiler",
|
"description": "The review contains spoiler",
|
||||||
"type": "bool"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"is_preliminary": {
|
"is_preliminary": {
|
||||||
"description": "The review was made before the entry was completed",
|
"description": "The review was made before the entry was completed",
|
||||||
"type": "bool"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"episodes_watched": {
|
"episodes_watched": {
|
||||||
"description": "Number of episodes watched",
|
"description": "Number of episodes watched",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user