mirror of
https://github.com/jikan-me/jikan-rest.git
synced 2025-02-20 11:23:35 +08:00
merged master into feature/scout-typesense
This commit is contained in:
commit
aeae202f3c
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,7 +4,6 @@ Homestead.json
|
||||
Homestead.yaml
|
||||
.env
|
||||
composer.phar
|
||||
composer.lock
|
||||
.php_cs.cache
|
||||
.phpunit.result.cache
|
||||
.env.v4
|
||||
|
@ -41,14 +41,14 @@ For any additional help, join our [Discord server](http://discord.jikan.moe/).
|
||||
| Language | Wrappers |
|
||||
|------------|----------|
|
||||
| JavaScript | [JikanJS](https://github.com/zuritor/jikanjs) by Zuritor<br>🆕 **(v4)** [JikanJS](https://github.com/mateoaranda/jikanjs) by Mateo Aranda |
|
||||
| Java | [Jikan4java](https://github.com/Doomsdayrs/Jikan4java) by Doomsdayrs<br>[reactive-jikan](https://github.com/SandroHc/reactive-jikan) by Sandro Marques<br>[Jaikan](https://github.com/ShindouMihou/Jaikan) by ShindouMihou |
|
||||
| Java | [Jikan4java](https://github.com/Doomsdayrs/Jikan4java) by Doomsdayrs<br>🆕 **(v4)** [reactive-jikan](https://github.com/SandroHc/reactive-jikan) by Sandro Marques<br>🆕 **(v4)** [Jaikan](https://github.com/ShindouMihou/Jaikan) by ShindouMihou |
|
||||
| Python | [JikanPy](https://github.com/abhinavk99/jikanpy) by Abhinav Kasamsetty |
|
||||
| Node.js | [jikan-node](https://github.com/xy137/jikan-node) by xy137<br>[jikan-nodejs](https://github.com/ribeirogab/jikan-nodejs) by ribeirogab<br>🆕 **(v4)** [Jikan4JS](https://github.com/rizzzigit/jikan4.js) by RizzziGit<br>🆕 **(v4)** [jikan-api.js](https://github.com/OpenianDevelopment/jikan-api.js) by OpenianDev |
|
||||
| TypeScript | [jikants](https://github.com/Julien-Broyard/jikants) by Julien Broyard<br>[jikan-client](https://github.com/javi11/jikan-client) by Javier Blanco |
|
||||
| PHP | [jikan-php](https://github.com/janvernieuwe/jikan-jikanPHP) by Jan Vernieuwe |
|
||||
| .NET | 🆕 **(v4)** [Jikan.net](https://github.com/Ervie/jikan.net) by Ervie |
|
||||
| Elixir | [JikanEx](https://github.com/seanbreckenridge/jikan_ex) by Sean Breckenridge |
|
||||
| Go | [jikan-go](https://github.com/darenliang/jikan-go) by Daren Liang<br>[jikan2go](https://github.com/nokusukun/jikan2go) by nokusukun |
|
||||
| Go | 🆕 **(v4)** [jikan-go](https://github.com/darenliang/jikan-go) by Daren Liang<br>[jikan2go](https://github.com/nokusukun/jikan2go) by nokusukun |
|
||||
| Ruby | [Jikan.rb](https://github.com/Zerocchi/jikan.rb) by Zerocchi |
|
||||
| Dart | [jikan-dart](https://github.com/charafau/jikan-dart) by Rafal Wachol |
|
||||
| Kotlin | [JikanKt](https://github.com/GSculerlor/JikanKt) by Ganedra Afrasya |
|
||||
|
@ -19,7 +19,7 @@ class AnimeIndexer extends Command
|
||||
*`
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'indexer:anime
|
||||
protected $signature = 'indexer:anime
|
||||
{--failed : Run only entries that failed to index last time}
|
||||
{--resume : Resume from the last position}
|
||||
{--reverse : Start from the end of the array}
|
||||
@ -150,7 +150,7 @@ class AnimeIndexer extends Command
|
||||
true
|
||||
);
|
||||
|
||||
$this->ids = $ids['sfw'] + $ids['nsfw']; // merge
|
||||
$ids = array_merge($ids['sfw'], $ids['nsfw']);
|
||||
Storage::put('indexer/anime_mal_id.json', json_encode($this->ids));
|
||||
|
||||
return json_decode(Storage::get('indexer/anime_mal_id.json'));
|
||||
|
93
app/Console/Commands/Indexer/AnimeSweepIndexer.php
Normal file
93
app/Console/Commands/Indexer/AnimeSweepIndexer.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands\Indexer;
|
||||
|
||||
use App\Exceptions\Console\CommandAlreadyRunningException;
|
||||
use App\Exceptions\Console\FileNotFoundException;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
/**
|
||||
* Class AnimeSweepIndexer
|
||||
*
|
||||
* @package App\Console\Commands\Indexer
|
||||
*/
|
||||
class AnimeSweepIndexer extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*`
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'indexer:anime-sweep';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Delete all removed anime';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->info("Info: Delete removed MAL IDs\n\n");
|
||||
|
||||
echo "Loading MAL IDs\n";
|
||||
$malIds = array_fill_keys($this->fetchMalIds(), null);
|
||||
|
||||
echo "Loading MAL IDs from local DB\n";
|
||||
$results = DB::table('anime')->select('mal_id', '_id')->get();
|
||||
|
||||
echo "Compare MAL IDs\n";
|
||||
$remove = [];
|
||||
|
||||
foreach ($results as $result) {
|
||||
if (!array_key_exists($result['mal_id'], $malIds)) {
|
||||
echo "Removing https://myanimelist.net/anime/".$result['mal_id']."\n";
|
||||
$remove[] = $result['_id'];
|
||||
}
|
||||
}
|
||||
|
||||
echo "\n\n".count($remove);
|
||||
|
||||
echo "Delete removed MAL IDs\n";
|
||||
DB::table('anime')->whereIn('_id', $remove)->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @url https://github.com/seanbreckenridge/mal-id-cache
|
||||
*/
|
||||
private function fetchMalIds(): array
|
||||
{
|
||||
$this->info("Fetching MAL ID Cache https://raw.githubusercontent.com/seanbreckenridge/mal-id-cache/master/cache/anime_cache.json...\n");
|
||||
|
||||
$ids = json_decode(
|
||||
file_get_contents('https://raw.githubusercontent.com/seanbreckenridge/mal-id-cache/master/cache/anime_cache.json'),
|
||||
true
|
||||
);
|
||||
|
||||
$ids = array_merge($ids['sfw'], $ids['nsfw']);
|
||||
Storage::put('indexer/anime_mal_id_sweep.json', json_encode($ids));
|
||||
|
||||
return json_decode(Storage::get('indexer/anime_mal_id_sweep.json'));
|
||||
}
|
||||
}
|
@ -48,42 +48,6 @@ class CommonIndexer extends Command
|
||||
|
||||
echo "Note: If an entry already exists, it will be updated instead.\n\n";
|
||||
|
||||
/**
|
||||
* Producers
|
||||
*/
|
||||
echo "Indexing Producers...\n";
|
||||
$results = \json_decode(
|
||||
app('SerializerV4')->serialize(
|
||||
app('JikanParser')
|
||||
->getProducers(new ProducersRequest()),
|
||||
'json'
|
||||
),
|
||||
true
|
||||
)['producers'];
|
||||
|
||||
if (HttpHelper::hasError($results)) {
|
||||
echo "FAILED: {$results->original['error']}\n";
|
||||
return;
|
||||
}
|
||||
|
||||
$itemCount = count($results);
|
||||
echo "Parsed {$itemCount} producers\n";
|
||||
foreach ($results as $i => $item) {
|
||||
$result = DB::table('producers')
|
||||
->updateOrInsert(
|
||||
[
|
||||
'mal_id' => $item['mal_id']
|
||||
],
|
||||
[
|
||||
'mal_id' => $item['mal_id'],
|
||||
'name' => $item['name'],
|
||||
'url' => $item['url'],
|
||||
'count' => $item['count']
|
||||
]
|
||||
);
|
||||
echo "Indexing {$i}/{$itemCount} \r";
|
||||
}
|
||||
|
||||
/**
|
||||
* Magazines
|
||||
*/
|
||||
|
@ -19,7 +19,7 @@ class MangaIndexer extends Command
|
||||
*`
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'indexer:manga
|
||||
protected $signature = 'indexer:manga
|
||||
{--failed : Run only entries that failed to index last time}
|
||||
{--resume : Resume from the last position}
|
||||
{--reverse : Start from the end of the array}
|
||||
@ -150,7 +150,7 @@ class MangaIndexer extends Command
|
||||
true
|
||||
);
|
||||
|
||||
$this->ids = $ids['sfw'] + $ids['nsfw']; // merge
|
||||
$ids = array_merge($ids['sfw'], $ids['nsfw']);
|
||||
Storage::put('indexer/manga_mal_id.json', json_encode($this->ids));
|
||||
|
||||
return json_decode(Storage::get('indexer/manga_mal_id.json'));
|
||||
|
90
app/Console/Commands/Indexer/MangaSweepIndexer.php
Normal file
90
app/Console/Commands/Indexer/MangaSweepIndexer.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands\Indexer;
|
||||
|
||||
use App\Exceptions\Console\CommandAlreadyRunningException;
|
||||
use App\Exceptions\Console\FileNotFoundException;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
/**
|
||||
* Class MangaSweepIndexer
|
||||
*
|
||||
* @package App\Console\Commands\Indexer
|
||||
*/
|
||||
class MangaSweepIndexer extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*`
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'indexer:manga-sweep';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Delete all removed manga';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->info("Info: Delete removed MAL IDs\n\n");
|
||||
|
||||
echo "Loading MAL IDs\n";
|
||||
$malIds = array_fill_keys($this->fetchMalIds(), null);
|
||||
|
||||
echo "Loading MAL IDs from local DB\n";
|
||||
$results = DB::table('manga')->select('mal_id', '_id')->get();
|
||||
|
||||
echo "Compare MAL IDs\n";
|
||||
$remove = [];
|
||||
|
||||
foreach ($results as $result) {
|
||||
if (!array_key_exists($result['mal_id'], $malIds)) {
|
||||
$remove[] = $result['_id'];
|
||||
}
|
||||
}
|
||||
|
||||
echo "Delete removed MAL IDs\n";
|
||||
DB::table('manga')->whereIn('_id', $remove)->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @url https://github.com/seanbreckenridge/mal-id-cache
|
||||
*/
|
||||
private function fetchMalIds(): array
|
||||
{
|
||||
$this->info("Fetching MAL ID Cache https://raw.githubusercontent.com/seanbreckenridge/mal-id-cache/master/cache/manga_cache.json...\n");
|
||||
|
||||
$ids = json_decode(
|
||||
file_get_contents('https://raw.githubusercontent.com/seanbreckenridge/mal-id-cache/master/cache/manga_cache.json'),
|
||||
true
|
||||
);
|
||||
|
||||
$ids = array_merge($ids['sfw'], $ids['nsfw']);
|
||||
Storage::put('indexer/manga_mal_id_sweep.json', json_encode($ids));
|
||||
|
||||
return json_decode(Storage::get('indexer/manga_mal_id_sweep.json'));
|
||||
}
|
||||
}
|
178
app/Console/Commands/Indexer/ProducersIndexer.php
Normal file
178
app/Console/Commands/Indexer/ProducersIndexer.php
Normal file
@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands\Indexer;
|
||||
|
||||
use App\Exceptions\Console\FileNotFoundException;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Jikan\Request\Producer\ProducersRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Class ProducersIndexer
|
||||
* @package App\Console\Commands\Indexer
|
||||
*/
|
||||
class ProducersIndexer extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*`
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'indexer:producers
|
||||
{--failed : Run only entries that failed to index last time}
|
||||
{--resume : Resume from the last position}
|
||||
{--reverse : Start from the end of the array}
|
||||
{--index=0 : Start from a specific index}
|
||||
{--delay=3 : Set a delay between requests}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Index all producers';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private array $ids;
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$failed = $this->option('failed') ?? false;
|
||||
$resume = $this->option('resume') ?? false;
|
||||
$reverse = $this->option('reverse') ?? false;
|
||||
$delay = $this->option('delay') ?? 3;
|
||||
$index = $this->option('index') ?? 0;
|
||||
|
||||
$index = (int)$index;
|
||||
$delay = (int)$delay;
|
||||
|
||||
$this->info("Info: ProducersIndexer scrapes available MAL IDs and updates/indexes them\n\n");
|
||||
|
||||
if ($failed && Storage::exists('indexer/indexer_producers.save')) {
|
||||
$this->ids = $this->loadFailedMalIds();
|
||||
}
|
||||
|
||||
if (!$failed) {
|
||||
$this->ids = $this->fetchMalIds();
|
||||
}
|
||||
|
||||
// start from the end
|
||||
if ($reverse) {
|
||||
$this->ids = array_reverse($this->ids);
|
||||
}
|
||||
|
||||
// Resume
|
||||
if ($resume && Storage::exists('indexer/indexer_producers.save')) {
|
||||
$index = (int)Storage::get('indexer/indexer_producers.save');
|
||||
|
||||
$this->info("Resuming from index: {$index}");
|
||||
}
|
||||
|
||||
// check if index even exists
|
||||
if ($index > 0 && !isset($this->ids[$index])) {
|
||||
$index = 0;
|
||||
$this->warn('Invalid index; set back to 0');
|
||||
}
|
||||
|
||||
// initialize and index
|
||||
Storage::put('indexer/indexer_producers.save', 0);
|
||||
|
||||
echo "Loading MAL IDs\n";
|
||||
$count = count($this->ids);
|
||||
$failedIds = [];
|
||||
$success = [];
|
||||
|
||||
echo "{$count} entries available\n";
|
||||
for ($i = $index; $i <= ($count - 1); $i++) {
|
||||
$id = $this->ids[$i];
|
||||
|
||||
$url = env('APP_URL') . "/v4/producers/{$id}";
|
||||
|
||||
echo "Indexing/Updating " . ($i + 1) . "/{$count} {$url} [MAL ID: {$id}] \n";
|
||||
|
||||
try {
|
||||
$response = json_decode(file_get_contents($url), true);
|
||||
|
||||
if (isset($response['error']) && $response['status'] != 404) {
|
||||
echo "[SKIPPED] Failed to fetch {$url} - {$response['error']}\n";
|
||||
$failedIds[] = $id;
|
||||
Storage::put('indexer/indexer_producers.failed', json_encode($failedIds));
|
||||
}
|
||||
|
||||
sleep($delay);
|
||||
} catch (\Exception $e) {
|
||||
echo "[SKIPPED] Failed to fetch {$url}\n";
|
||||
$failedIds[] = $id;
|
||||
Storage::put('indexer/indexer_producers.failed', json_encode($failedIds));
|
||||
}
|
||||
|
||||
$success[] = $id;
|
||||
Storage::put('indexer/indexer_producers.save', $i);
|
||||
}
|
||||
|
||||
Storage::delete('indexer/indexer_producers.save');
|
||||
|
||||
echo "---------\nIndexing complete\n";
|
||||
echo count($success) . " entries indexed or updated\n";
|
||||
echo count($failedIds) . " entries failed to index or update. Re-run with --failed to requeue failed entries only\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function fetchMalIds() : array
|
||||
{
|
||||
$this->info("Scraping Producer MAL IDs from https://myanimelist.net/anime/producer...\n");
|
||||
|
||||
$producers = \json_decode(
|
||||
app('SerializerV4')->serialize(
|
||||
app('JikanParser')
|
||||
->getProducers(new ProducersRequest()),
|
||||
'json'
|
||||
),
|
||||
true
|
||||
)['producers'];
|
||||
|
||||
foreach ($producers as $producer) {
|
||||
$this->ids[] = $producer['mal_id'];
|
||||
}
|
||||
|
||||
Storage::put('indexer/producers_mal_id.json', json_encode($this->ids));
|
||||
|
||||
return json_decode(Storage::get('indexer/producers_mal_id.json'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
private function loadFailedMalIds() : array
|
||||
{
|
||||
if (!Storage::exists('indexer/indexer_producers.failed')) {
|
||||
throw new FileNotFoundException('"indexer/indexer_producers.failed" does not exist');
|
||||
}
|
||||
|
||||
return json_decode(Storage::get('indexer/indexer_producers.failed'));
|
||||
}
|
||||
|
||||
}
|
11
app/Console/Kernel.php
Executable file → Normal file
11
app/Console/Kernel.php
Executable file → Normal file
@ -5,11 +5,14 @@ namespace App\Console;
|
||||
use App\Console\Commands\ClearQueuedJobs;
|
||||
use App\Console\Commands\CacheRemove;
|
||||
use App\Console\Commands\Indexer\AnimeIndexer;
|
||||
use App\Console\Commands\Indexer\AnimeSweepIndexer;
|
||||
use App\Console\Commands\Indexer\AnimeScheduleIndexer;
|
||||
use App\Console\Commands\Indexer\CommonIndexer;
|
||||
use App\Console\Commands\Indexer\CurrentSeasonIndexer;
|
||||
use App\Console\Commands\Indexer\GenreIndexer;
|
||||
use App\Console\Commands\Indexer\MangaIndexer;
|
||||
use App\Console\Commands\Indexer\MangaSweepIndexer;
|
||||
use App\Console\Commands\Indexer\ProducersIndexer;
|
||||
use App\Console\Commands\ManageMicrocaching;
|
||||
use App\Console\Commands\ModifyCacheDriver;
|
||||
use App\Console\Commands\ModifyCacheMethod;
|
||||
@ -34,7 +37,10 @@ class Kernel extends ConsoleKernel
|
||||
ManageMicrocaching::class,
|
||||
AnimeIndexer::class,
|
||||
MangaIndexer::class,
|
||||
GenreIndexer::class
|
||||
GenreIndexer::class,
|
||||
ProducersIndexer::class,
|
||||
AnimeSweepIndexer::class,
|
||||
MangaSweepIndexer::class,
|
||||
];
|
||||
|
||||
/**
|
||||
@ -60,5 +66,8 @@ class Kernel extends ConsoleKernel
|
||||
|
||||
$schedule->command('indexer:genres')
|
||||
->daily();
|
||||
|
||||
$schedule->command('indexer:producers')
|
||||
->daily();
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ use Jikan\Request\Anime\AnimeRecommendationsRequest;
|
||||
use Jikan\Request\Anime\AnimeRequest;
|
||||
use Jikan\Request\Anime\AnimeReviewsRequest;
|
||||
use Jikan\Request\Anime\AnimeStatsRequest;
|
||||
use Jikan\Request\Anime\AnimeVideosEpisodesRequest;
|
||||
use Jikan\Request\Anime\AnimeVideosRequest;
|
||||
use Laravel\Lumen\Http\ResponseFactory;
|
||||
use MongoDB\BSON\UTCDateTime;
|
||||
@ -701,6 +702,105 @@ class AnimeController extends Controller
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/anime/{id}/videos/episodes",
|
||||
* operationId="getAnimeVideosEpisodes",
|
||||
* tags={"anime"},
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="id",
|
||||
* in="path",
|
||||
* required=true,
|
||||
* @OA\Schema(type="integer")
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(ref="#/components/parameters/page"),
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="200",
|
||||
* description="Returns episode videos related to the entry",
|
||||
* @OA\JsonContent(
|
||||
* ref="#/components/schemas/anime_videos_episodes"
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="400",
|
||||
* description="Error: Bad request. When required parameters were not supplied.",
|
||||
* ),
|
||||
* ),
|
||||
*
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="anime_videos_episodes",
|
||||
* description="Anime Videos Episodes Resource",
|
||||
*
|
||||
* allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/pagination"),
|
||||
* @OA\Schema(
|
||||
* @OA\Property(
|
||||
* property="data",
|
||||
* type="array",
|
||||
* @OA\Items(
|
||||
* type="object",
|
||||
* @OA\Property(
|
||||
* property="mal_id",
|
||||
* type="integer",
|
||||
* description="MyAnimeList ID or Episode Number"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="title",
|
||||
* type="string",
|
||||
* description="Episode Title"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="episode",
|
||||
* type="string",
|
||||
* description="Episode Subtitle"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="url",
|
||||
* type="string",
|
||||
* description="Episode Page URL",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="images",
|
||||
* ref="#/components/schemas/common_images"
|
||||
* ),
|
||||
* ),
|
||||
* ),
|
||||
* ),
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
public function videosEpisodes(Request $request, int $id)
|
||||
{
|
||||
$results = DB::table($this->getRouteTable($request))
|
||||
->where('request_hash', $this->fingerprint)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$page = $request->get('page') ?? 1;
|
||||
$anime = $this->jikan->getAnimeVideosEpisodes(new AnimeVideosEpisodesRequest($id, $page));
|
||||
$response = \json_decode($this->serializer->serialize($anime, 'json'), true);
|
||||
|
||||
$results = $this->updateCache($request, $results, $response);
|
||||
}
|
||||
|
||||
$response = (new AnimeEpisodesResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/anime/{id}/pictures",
|
||||
|
@ -14,6 +14,32 @@ class MagazineController extends ControllerWithQueryBuilderProvider
|
||||
* tags={"magazines"},
|
||||
*
|
||||
* @OA\Parameter(ref="#/components/parameters/page"),
|
||||
* @OA\Parameter(ref="#/components/parameters/limit"),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="q",
|
||||
* in="query",
|
||||
* @OA\Schema(type="string")
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="order_by",
|
||||
* in="query",
|
||||
* @OA\Schema(ref="#/components/schemas/magazines_query_orderby")
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="sort",
|
||||
* in="query",
|
||||
* @OA\Schema(ref="#/components/schemas/search_query_sort")
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="letter",
|
||||
* in="query",
|
||||
* description="Return entries starting with the given letter",
|
||||
* @OA\Schema(type="string")
|
||||
* ),
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="200",
|
||||
@ -35,7 +61,7 @@ class MagazineController extends ControllerWithQueryBuilderProvider
|
||||
* enum={"mal_id", "name", "count"}
|
||||
* )
|
||||
*/
|
||||
public function main(Request $request)
|
||||
public function main(Request $request): MagazineCollection
|
||||
{
|
||||
return $this->preparePaginatedResponse(MagazineCollection::class, "magazine", $request);
|
||||
}
|
||||
|
@ -2,35 +2,279 @@
|
||||
|
||||
namespace App\Http\Controllers\V4DB;
|
||||
|
||||
use App\Anime;
|
||||
use App\Http\Resources\V4\ExternalLinksResource;
|
||||
use App\Producers;
|
||||
use App\Http\HttpHelper;
|
||||
use App\Http\HttpResponse;
|
||||
use App\Http\QueryBuilder\SearchQueryBuilderProducer;
|
||||
use App\Http\Resources\V4\AnimeCollection;
|
||||
use App\Http\Resources\V4\ProducerCollection;
|
||||
use Illuminate\Http\Request;
|
||||
use Jikan\Model\Producer\Producer;
|
||||
use MongoDB\BSON\UTCDateTime;
|
||||
|
||||
class ProducerController extends ControllerWithQueryBuilderProvider
|
||||
class ProducerController extends Controller
|
||||
{
|
||||
|
||||
private $request;
|
||||
const MAX_RESULTS_PER_PAGE = 100;
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/producers",
|
||||
* operationId="getProducers",
|
||||
* path="/producers/{id}",
|
||||
* operationId="getProducerById",
|
||||
* tags={"producers"},
|
||||
*
|
||||
* @OA\Parameter(ref="#/components/parameters/page"),
|
||||
* @OA\Parameter(
|
||||
* name="id",
|
||||
* in="path",
|
||||
* required=true,
|
||||
* @OA\Schema(type="integer")
|
||||
* ),
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="200",
|
||||
* description="Returns producers collection",
|
||||
* description="Returns producer resource",
|
||||
* @OA\JsonContent(
|
||||
* ref="#/components/schemas/producers"
|
||||
* @OA\Property(
|
||||
* property="data",
|
||||
* ref="#/components/schemas/producer"
|
||||
* )
|
||||
* )
|
||||
* ),
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="400",
|
||||
* description="Error: Bad request. When required parameters were not supplied.",
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function main(Request $request)
|
||||
public function main(Request $request, int $id)
|
||||
{
|
||||
return $this->preparePaginatedResponse(ProducerCollection::class, "producer", $request);
|
||||
$results = Producers::query()
|
||||
->where('mal_id', $id)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$response = Producers::scrape($id);
|
||||
|
||||
if (HttpHelper::hasError($response)) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
$meta = [
|
||||
'createdAt' => new UTCDateTime(),
|
||||
'modifiedAt' => new UTCDateTime(),
|
||||
'request_hash' => $this->fingerprint
|
||||
];
|
||||
}
|
||||
$meta['modifiedAt'] = new UTCDateTime();
|
||||
|
||||
$response = $meta + $response;
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
Producers::query()
|
||||
->insert($response);
|
||||
}
|
||||
|
||||
if ($this->isExpired($request, $results)) {
|
||||
Producers::query()
|
||||
->where('mal_id', $id)
|
||||
->update($response);
|
||||
}
|
||||
|
||||
$results = Producers::query()
|
||||
->where('mal_id', $id)
|
||||
->get();
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
$response = (new \App\Http\Resources\V4\ProducerResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/producers/{id}/full",
|
||||
* operationId="getProducerFullById",
|
||||
* tags={"producers"},
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="id",
|
||||
* in="path",
|
||||
* required=true,
|
||||
* @OA\Schema(type="integer")
|
||||
* ),
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="200",
|
||||
* description="Returns producer resource",
|
||||
* @OA\JsonContent(
|
||||
* @OA\Property(
|
||||
* property="data",
|
||||
* ref="#/components/schemas/producer_full"
|
||||
* )
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="400",
|
||||
* description="Error: Bad request. When required parameters were not supplied.",
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function full(Request $request, int $id)
|
||||
{
|
||||
$results = Producers::query()
|
||||
->where('mal_id', $id)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$response = Producers::scrape($id);
|
||||
|
||||
if (HttpHelper::hasError($response)) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
$meta = [
|
||||
'createdAt' => new UTCDateTime(),
|
||||
'modifiedAt' => new UTCDateTime(),
|
||||
'request_hash' => $this->fingerprint
|
||||
];
|
||||
}
|
||||
$meta['modifiedAt'] = new UTCDateTime();
|
||||
|
||||
$response = $meta + $response;
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
Producers::query()
|
||||
->insert($response);
|
||||
}
|
||||
|
||||
if ($this->isExpired($request, $results)) {
|
||||
Producers::query()
|
||||
->where('mal_id', $id)
|
||||
->update($response);
|
||||
}
|
||||
|
||||
$results = Producers::query()
|
||||
->where('mal_id', $id)
|
||||
->get();
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
$response = (new \App\Http\Resources\V4\ProducerFullResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/producers/{id}/external",
|
||||
* operationId="getProducerExternal",
|
||||
* tags={"producers"},
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="id",
|
||||
* in="path",
|
||||
* required=true,
|
||||
* @OA\Schema(type="integer")
|
||||
* ),
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="200",
|
||||
* description="Returns producer's external links",
|
||||
* @OA\JsonContent(
|
||||
* ref="#/components/schemas/external_links"
|
||||
* )
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="400",
|
||||
* description="Error: Bad request. When required parameters were not supplied.",
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function external(Request $request, int $id)
|
||||
{
|
||||
$results = Producers::query()
|
||||
->where('mal_id', $id)
|
||||
->get();
|
||||
|
||||
if (
|
||||
$results->isEmpty()
|
||||
|| $this->isExpired($request, $results)
|
||||
) {
|
||||
$response = Producers::scrape($id);
|
||||
|
||||
if (HttpHelper::hasError($response)) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
$meta = [
|
||||
'createdAt' => new UTCDateTime(),
|
||||
'modifiedAt' => new UTCDateTime(),
|
||||
'request_hash' => $this->fingerprint
|
||||
];
|
||||
}
|
||||
$meta['modifiedAt'] = new UTCDateTime();
|
||||
|
||||
$response = $meta + $response;
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
Producers::query()
|
||||
->insert($response);
|
||||
}
|
||||
|
||||
if ($this->isExpired($request, $results)) {
|
||||
Producers::query()
|
||||
->where('mal_id', $id)
|
||||
->update($response);
|
||||
}
|
||||
|
||||
$results = Producers::query()
|
||||
->where('mal_id', $id)
|
||||
->get();
|
||||
}
|
||||
|
||||
if ($results->isEmpty()) {
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
$response = (new ExternalLinksResource(
|
||||
$results->first()
|
||||
))->response();
|
||||
|
||||
return $this->prepareResponse(
|
||||
$response,
|
||||
$results,
|
||||
$request
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use App\Http\Resources\V4\CharacterCollection;
|
||||
use App\Http\Resources\V4\ClubCollection;
|
||||
use App\Http\Resources\V4\MangaCollection;
|
||||
use App\Http\Resources\V4\PersonCollection;
|
||||
use App\Http\Resources\V4\ProducerCollection;
|
||||
use App\Http\Resources\V4\ResultsResource;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
@ -638,4 +639,57 @@ class SearchController extends ControllerWithQueryBuilderProvider
|
||||
{
|
||||
return $this->preparePaginatedResponse(ClubCollection::class, "club", $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @OA\Get(
|
||||
* path="/producers",
|
||||
* operationId="getProducers",
|
||||
* tags={"producers"},
|
||||
*
|
||||
* @OA\Parameter(ref="#/components/parameters/page"),
|
||||
* @OA\Parameter(ref="#/components/parameters/limit"),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="q",
|
||||
* in="query",
|
||||
* @OA\Schema(type="string")
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="order_by",
|
||||
* in="query",
|
||||
* @OA\Schema(ref="#/components/schemas/producers_query_orderby")
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="sort",
|
||||
* in="query",
|
||||
* @OA\Schema(ref="#/components/schemas/search_query_sort")
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="letter",
|
||||
* in="query",
|
||||
* description="Return entries starting with the given letter",
|
||||
* @OA\Schema(type="string")
|
||||
* ),
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="200",
|
||||
* description="Returns producers collection",
|
||||
* @OA\JsonContent(
|
||||
* ref="#/components/schemas/producers"
|
||||
* )
|
||||
* ),
|
||||
*
|
||||
* @OA\Response(
|
||||
* response="400",
|
||||
* description="Error: Bad request. When required parameters were not supplied.",
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function producers(Request $request)
|
||||
{
|
||||
return $this->preparePaginatedResponse(ProducerCollection::class, "producer", $request);
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +1,39 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace App\Http\QueryBuilder;
|
||||
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Jenssegers\Mongodb\Eloquent\Builder;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class SearchQueryBuilderAnime
|
||||
* @package App\Http\QueryBuilder
|
||||
*/
|
||||
class TopQueryBuilderManga implements SearchQueryBuilderInterface
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const MAP_TYPES = [
|
||||
'manga' => 'Manga',
|
||||
'novels' => 'Novel',
|
||||
'lightnovels' => 'Light Novel',
|
||||
'oneshots' => 'One-shot',
|
||||
'doujin' => 'Doujinshi',
|
||||
'manhwa' => 'Manhwa',
|
||||
'manhua' => 'Manhua'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const MAP_FILTER = [
|
||||
'publishing', 'upcoming', 'bypopularity', 'favorite'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param Builder $builder
|
||||
@ -42,15 +43,15 @@
|
||||
{
|
||||
$mangaType = self::mapType($request->get('type'));
|
||||
$filterType = self::mapFilter($request->get('filter'));
|
||||
|
||||
|
||||
$results = $results
|
||||
->where('type', '!=', 'Doujinshi');
|
||||
|
||||
|
||||
if (!is_null($mangaType)) {
|
||||
$results = $results
|
||||
->where('type', $mangaType);
|
||||
}
|
||||
|
||||
|
||||
if (!is_null($filterType) && $filterType === 'publishing') {
|
||||
$results = $results
|
||||
->where('publishing', true)
|
||||
@ -60,14 +61,14 @@
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
|
||||
if (!is_null($filterType) && $filterType === 'bypopularity') {
|
||||
$results = $results
|
||||
->orderBy('members', 'desc');
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
|
||||
if (!is_null($filterType) && $filterType === 'favorite') {
|
||||
$results = $results
|
||||
->orderBy('favorites', 'desc');
|
||||
@ -82,7 +83,7 @@
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|null $type
|
||||
* @return string|null
|
||||
@ -92,12 +93,12 @@
|
||||
if (is_null($type)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
$type = strtolower($type);
|
||||
|
||||
|
||||
return self::MAP_TYPES[$type] ?? null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|null $filter
|
||||
* @return string|null
|
||||
@ -105,11 +106,11 @@
|
||||
public static function mapFilter(?string $filter = null) : ?string
|
||||
{
|
||||
$filter = strtolower($filter);
|
||||
|
||||
|
||||
if (!\in_array($filter, self::MAP_FILTER)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return $filter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,11 @@ class AnimeEpisodesResource extends JsonResource
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'last_visible_page' => $this['last_visible_page'] ?? 1,
|
||||
'has_next_page' => $this['has_next_page'] ?? false,
|
||||
'results' => $this['results']
|
||||
'pagination' => [
|
||||
'last_visible_page' => $this['last_visible_page'] ?? 1,
|
||||
'has_next_page' => $this['has_next_page'] ?? false,
|
||||
],
|
||||
'data' => $this['results'],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,8 +39,9 @@ class AnimeFullResource extends JsonResource
|
||||
* type="array",
|
||||
* description="All titles",
|
||||
* @OA\Items(
|
||||
* type="string"
|
||||
* )
|
||||
* type="object",
|
||||
* ref="#/components/schemas/title",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="title",
|
||||
|
@ -39,8 +39,9 @@ class AnimeResource extends JsonResource
|
||||
* type="array",
|
||||
* description="All titles",
|
||||
* @OA\Items(
|
||||
* type="string"
|
||||
* )
|
||||
* type="object",
|
||||
* ref="#/components/schemas/title",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="title",
|
||||
|
@ -70,6 +70,38 @@ class AnimeVideosResource extends JsonResource
|
||||
* ),
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="music_videos",
|
||||
* type="array",
|
||||
* @OA\Items(
|
||||
* type="object",
|
||||
*
|
||||
* @OA\Property(
|
||||
* property="title",
|
||||
* type="string",
|
||||
* description="Title"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="video",
|
||||
* ref="#/components/schemas/trailer"
|
||||
* ),
|
||||
* @OA\Property (
|
||||
* type="object",
|
||||
* property="meta",
|
||||
*
|
||||
* @OA\Property (
|
||||
* property="title",
|
||||
* type="string",
|
||||
* nullable=true
|
||||
* ),
|
||||
* @OA\Property (
|
||||
* property="author",
|
||||
* type="string",
|
||||
* nullable=true
|
||||
* ),
|
||||
* ),
|
||||
* ),
|
||||
* ),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
@ -77,7 +109,8 @@ class AnimeVideosResource extends JsonResource
|
||||
{
|
||||
return [
|
||||
'promo' => $this['promo'],
|
||||
'episodes' => $this['episodes']
|
||||
'episodes' => $this['episodes'],
|
||||
'music_videos' => $this['music_videos'],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,13 +11,13 @@ class CommonResource extends JsonResource
|
||||
* schema="trailer",
|
||||
* type="object",
|
||||
* description="Youtube Details",
|
||||
*
|
||||
*
|
||||
* allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/trailer_base"),
|
||||
* @OA\Schema(ref="#/components/schemas/trailer_images"),
|
||||
* }
|
||||
* }
|
||||
* ),
|
||||
*
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="trailer_base",
|
||||
* type="object",
|
||||
@ -42,7 +42,7 @@ class CommonResource extends JsonResource
|
||||
* nullable=true
|
||||
* ),
|
||||
* ),
|
||||
*
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="trailer_images",
|
||||
* type="object",
|
||||
@ -684,6 +684,21 @@ class CommonResource extends JsonResource
|
||||
* ),
|
||||
* ),
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="title",
|
||||
* type="object",
|
||||
* @OA\Property(
|
||||
* property="type",
|
||||
* type="string",
|
||||
* description="Title type",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="title",
|
||||
* type="string",
|
||||
* description="Title value",
|
||||
* ),
|
||||
* ),
|
||||
*
|
||||
*
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -26,34 +26,6 @@ class MagazineCollection extends ResourceCollection
|
||||
* schema="magazines",
|
||||
* description="Magazine Collection Resource",
|
||||
*
|
||||
* @OA\Parameter(ref="#/components/parameters/page"),
|
||||
* @OA\Parameter(ref="#/components/parameters/limit"),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="q",
|
||||
* in="query",
|
||||
* @OA\Schema(type="string")
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="order_by",
|
||||
* in="query",
|
||||
* @OA\Schema(ref="#/components/schemas/magazines_query_orderby")
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="sort",
|
||||
* in="query",
|
||||
* @OA\Schema(ref="#/components/schemas/search_query_sort")
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="letter",
|
||||
* in="query",
|
||||
* description="Return entries starting with the given letter",
|
||||
* @OA\Schema(type="string")
|
||||
* ),
|
||||
*
|
||||
* allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/pagination"),
|
||||
* @OA\Schema(
|
||||
@ -76,7 +48,13 @@ class MagazineCollection extends ResourceCollection
|
||||
{
|
||||
$this->pagination = [
|
||||
'last_visible_page' => $resource->lastPage(),
|
||||
'has_next_page' => $resource->hasMorePages()
|
||||
'has_next_page' => $resource->hasMorePages(),
|
||||
'current_page' => $resource->currentPage(),
|
||||
'items' => [
|
||||
'count' => $resource->count(),
|
||||
'total' => $resource->total(),
|
||||
'per_page' => $resource->perPage(),
|
||||
],
|
||||
];
|
||||
|
||||
$this->collection = $resource->getCollection();
|
||||
@ -104,4 +82,4 @@ class MagazineCollection extends ResourceCollection
|
||||
unset($jsonResponse['links'],$jsonResponse['meta']);
|
||||
$response->setContent(json_encode($jsonResponse));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,8 +35,9 @@ class MangaFullResource extends JsonResource
|
||||
* type="array",
|
||||
* description="All Titles",
|
||||
* @OA\Items(
|
||||
* type="string"
|
||||
* )
|
||||
* type="object",
|
||||
* ref="#/components/schemas/title",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="title",
|
||||
@ -70,7 +71,7 @@ class MangaFullResource extends JsonResource
|
||||
* @OA\Property(
|
||||
* property="type",
|
||||
* type="string",
|
||||
* enum={"Manga", "Novel", "One-shot", "Doujinshi", "Manhua", "Manhwa", "OEL"},
|
||||
* enum={"Manga", "Novel", "Light Novel", "One-shot", "Doujinshi", "Manhua", "Manhwa", "OEL"},
|
||||
* description="Manga Type",
|
||||
* nullable=true
|
||||
* ),
|
||||
@ -105,12 +106,14 @@ class MangaFullResource extends JsonResource
|
||||
* property="score",
|
||||
* type="number",
|
||||
* format="float",
|
||||
* description="Score"
|
||||
* description="Score",
|
||||
* nullable=true
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="scored_by",
|
||||
* type="integer",
|
||||
* description="Number of users"
|
||||
* description="Number of users",
|
||||
* nullable=true
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="rank",
|
||||
|
@ -35,8 +35,9 @@ class MangaResource extends JsonResource
|
||||
* type="array",
|
||||
* description="All Titles",
|
||||
* @OA\Items(
|
||||
* type="string"
|
||||
* )
|
||||
* type="object",
|
||||
* ref="#/components/schemas/title",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="title",
|
||||
@ -61,7 +62,7 @@ class MangaResource extends JsonResource
|
||||
* @OA\Property(
|
||||
* property="type",
|
||||
* type="string",
|
||||
* enum={"Manga", "Novel", "One-shot", "Doujinshi", "Manhua", "Manhwa", "OEL"},
|
||||
* enum={"Manga", "Novel", "Light Novel", "One-shot", "Doujinshi", "Manhua", "Manhwa", "OEL"},
|
||||
* description="Manga Type",
|
||||
* nullable=true
|
||||
* ),
|
||||
@ -96,12 +97,14 @@ class MangaResource extends JsonResource
|
||||
* property="score",
|
||||
* type="number",
|
||||
* format="float",
|
||||
* description="Score"
|
||||
* description="Score",
|
||||
* nullable=true
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="scored_by",
|
||||
* type="integer",
|
||||
* description="Number of users"
|
||||
* description="Number of users",
|
||||
* nullable=true
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="rank",
|
||||
|
@ -24,35 +24,7 @@ class ProducerCollection extends ResourceCollection
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="producers",
|
||||
* description="Producer Collection Resource",
|
||||
*
|
||||
* @OA\Parameter(ref="#/components/parameters/page"),
|
||||
* @OA\Parameter(ref="#/components/parameters/limit"),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="q",
|
||||
* in="query",
|
||||
* @OA\Schema(type="string")
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="order_by",
|
||||
* in="query",
|
||||
* @OA\Schema(ref="#/components/schemas/producers_query_orderby")
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="sort",
|
||||
* in="query",
|
||||
* @OA\Schema(ref="#/components/schemas/search_query_sort")
|
||||
* ),
|
||||
*
|
||||
* @OA\Parameter(
|
||||
* name="letter",
|
||||
* in="query",
|
||||
* description="Return entries starting with the given letter",
|
||||
* @OA\Schema(type="string")
|
||||
* ),
|
||||
* description="Producers Collection Resource",
|
||||
*
|
||||
* allOf={
|
||||
* @OA\Schema(ref="#/components/schemas/pagination"),
|
||||
@ -75,7 +47,13 @@ class ProducerCollection extends ResourceCollection
|
||||
{
|
||||
$this->pagination = [
|
||||
'last_visible_page' => $resource->lastPage(),
|
||||
'has_next_page' => $resource->hasMorePages()
|
||||
'has_next_page' => $resource->hasMorePages(),
|
||||
'current_page' => $resource->currentPage(),
|
||||
'items' => [
|
||||
'count' => $resource->count(),
|
||||
'total' => $resource->total(),
|
||||
'per_page' => $resource->perPage(),
|
||||
],
|
||||
];
|
||||
|
||||
$this->collection = $resource->getCollection();
|
||||
@ -103,4 +81,4 @@ class ProducerCollection extends ResourceCollection
|
||||
unset($jsonResponse['links'],$jsonResponse['meta']);
|
||||
$response->setContent(json_encode($jsonResponse));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
98
app/Http/Resources/V4/ProducerFullResource.php
Normal file
98
app/Http/Resources/V4/ProducerFullResource.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\V4;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ProducerFullResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="producer_full",
|
||||
* description="Producers Resource",
|
||||
* @OA\Property(
|
||||
* property="mal_id",
|
||||
* type="integer",
|
||||
* description="MyAnimeList ID"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="url",
|
||||
* type="string",
|
||||
* description="MyAnimeList URL"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="titles",
|
||||
* type="array",
|
||||
* description="All titles",
|
||||
* @OA\Items(
|
||||
* type="object",
|
||||
* ref="#/components/schemas/title",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="images",
|
||||
* type="object",
|
||||
* ref="#/components/schemas/common_images",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="favorites",
|
||||
* type="integer",
|
||||
* description="Producers's member favorites count"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="count",
|
||||
* type="integer",
|
||||
* description="Producers's anime count"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="established",
|
||||
* type="string",
|
||||
* description="Established Date ISO8601",
|
||||
* nullable=true
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="about",
|
||||
* type="string",
|
||||
* description="About the Producer",
|
||||
* nullable=true
|
||||
* ),
|
||||
*
|
||||
* @OA\Property(
|
||||
* property="external",
|
||||
* type="array",
|
||||
*
|
||||
* @OA\Items(
|
||||
* type="object",
|
||||
*
|
||||
* @OA\Property(
|
||||
* property="name",
|
||||
* type="string",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="url",
|
||||
* type="string",
|
||||
* ),
|
||||
* ),
|
||||
* ),
|
||||
* ),
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'mal_id' => $this->mal_id,
|
||||
'url' => $this->url,
|
||||
'titles' => $this->titles,
|
||||
'images' => $this->images,
|
||||
'favorites' => $this->favorites ?? null,
|
||||
'established' => $this->established ?? null,
|
||||
'about' => $this->about ?? null,
|
||||
'count' => $this->count ?? null,
|
||||
'external' => $this->external_links ?? null
|
||||
];
|
||||
}
|
||||
}
|
@ -14,36 +14,66 @@ class ProducerResource extends JsonResource
|
||||
*
|
||||
* @OA\Schema(
|
||||
* schema="producer",
|
||||
* description="Producer Resource",
|
||||
* description="Producers Resource",
|
||||
* @OA\Property(
|
||||
* property="mal_id",
|
||||
* type="integer",
|
||||
* description="MyAnimeList ID"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="name",
|
||||
* type="string",
|
||||
* description="Producer Name"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="url",
|
||||
* type="string",
|
||||
* description="MyAnimeList URL"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="titles",
|
||||
* type="array",
|
||||
* description="All titles",
|
||||
* @OA\Items(
|
||||
* type="object",
|
||||
* ref="#/components/schemas/title",
|
||||
* ),
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="images",
|
||||
* type="object",
|
||||
* ref="#/components/schemas/common_images",
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="favorites",
|
||||
* type="integer",
|
||||
* description="Producers's member favorites count"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="count",
|
||||
* type="integer",
|
||||
* description="Producer's anime count"
|
||||
* description="Producers's anime count"
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="established",
|
||||
* type="string",
|
||||
* description="Established Date ISO8601",
|
||||
* nullable=true
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="about",
|
||||
* type="string",
|
||||
* description="About the Producer",
|
||||
* nullable=true
|
||||
* ),
|
||||
* ),
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'mal_id' => $this->mal_id,
|
||||
'name' => $this->name,
|
||||
'url' => $this->url,
|
||||
'count' => $this->count
|
||||
'titles' => $this->titles,
|
||||
'images' => $this->images,
|
||||
'favorites' => $this->favorites ?? null,
|
||||
'established' => $this->established ?? null,
|
||||
'about' => $this->about ?? null,
|
||||
'count' => $this->count ?? null
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,8 @@ class UserUpdatesResource extends JsonResource
|
||||
* @OA\Property(
|
||||
* property="score",
|
||||
* type="integer",
|
||||
* description="User Score"
|
||||
* description="User Score",
|
||||
* nullable=true
|
||||
* ),
|
||||
* @OA\Property(
|
||||
* property="status",
|
||||
@ -127,4 +128,4 @@ class UserUpdatesResource extends JsonResource
|
||||
{
|
||||
return $this['users'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,13 +3,9 @@
|
||||
namespace App;
|
||||
|
||||
use Jenssegers\Mongodb\Eloquent\Model;
|
||||
use Jikan\Request\Producer\ProducersRequest;
|
||||
use Jikan\Request\Producer\ProducerRequest;
|
||||
|
||||
/**
|
||||
* Class Magazine
|
||||
* @package App
|
||||
*/
|
||||
class Producer extends Model
|
||||
class Producers extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
@ -18,7 +14,7 @@ class Producer extends Model
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'mal_id', 'name', 'url', 'count'
|
||||
'mal_id', 'url', 'images', 'titles', 'established', 'favorites', 'about', 'external', 'count'
|
||||
];
|
||||
|
||||
/**
|
||||
@ -28,27 +24,26 @@ class Producer extends Model
|
||||
*/
|
||||
protected $table = 'producers';
|
||||
|
||||
|
||||
/**
|
||||
* The attributes excluded from the model's JSON form.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = [
|
||||
'_id', 'expiresAt'
|
||||
'_id', 'request_hash', 'expiresAt'
|
||||
];
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function scrape() : array
|
||||
public static function scrape(int $id)
|
||||
{
|
||||
$data = app('JikanParser')->getProducers(new ProducersRequest());
|
||||
$data = app('JikanParser')->getProducer(new ProducerRequest($id));
|
||||
|
||||
return json_decode(
|
||||
$data = json_decode(
|
||||
app('SerializerV4')
|
||||
->serialize($data, 'json'),
|
||||
true
|
||||
);
|
||||
unset($data['results'], $data['has_next_page'], $data['last_visible_page']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
2538
composer.lock
generated
2538
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -41,6 +41,10 @@ return [
|
||||
'table_name' => 'anime_videos',
|
||||
'ttl' => env('CACHE_DEFAULT_EXPIRE')
|
||||
],
|
||||
'AnimeController@videosEpisodes' => [
|
||||
'table_name' => 'anime_videos_episodes',
|
||||
'ttl' => env('CACHE_DEFAULT_EXPIRE')
|
||||
],
|
||||
'AnimeController@pictures' => [
|
||||
'table_name' => 'anime_pictures',
|
||||
'ttl' => env('CACHE_DEFAULT_EXPIRE')
|
||||
@ -186,11 +190,7 @@ return [
|
||||
* Producers
|
||||
*/
|
||||
'ProducerController@main' => [
|
||||
'table_name' => 'common',
|
||||
'ttl' => env('CACHE_PRODUCERS_EXPIRE')
|
||||
],
|
||||
'ProducerController@resource' => [
|
||||
'table_name' => 'common',
|
||||
'table_name' => 'producers',
|
||||
'ttl' => env('CACHE_DEFAULT_EXPIRE')
|
||||
],
|
||||
|
||||
@ -333,6 +333,10 @@ return [
|
||||
'table_name' => 'common',
|
||||
'ttl' => env('CACHE_SEARCH_EXPIRE')
|
||||
],
|
||||
'SearchController@producers' => [
|
||||
'table_name' => 'common',
|
||||
'ttl' => env('CACHE_SEARCH_EXPIRE')
|
||||
],
|
||||
|
||||
'ClubController@main' => [
|
||||
'table_name' => 'clubs',
|
||||
@ -378,4 +382,4 @@ return [
|
||||
'ttl' => env('CACHE_DEFAULT_EXPIRE')
|
||||
],
|
||||
|
||||
];
|
||||
];
|
||||
|
@ -17,6 +17,9 @@ class CreateProducersTable extends Migration
|
||||
$table->unique(['mal_id' => 1], 'mal_id');
|
||||
$table->index('count', 'count');
|
||||
$table->index('name', 'name');
|
||||
$table->index('titles', 'titles');
|
||||
$table->index('established', 'established');
|
||||
$table->index('favorites', 'favorites');
|
||||
|
||||
$table->index(
|
||||
[
|
||||
|
@ -67,6 +67,10 @@ $router->group(
|
||||
'uses' => 'AnimeController@videos'
|
||||
]);
|
||||
|
||||
$router->get('/videos/episodes', [
|
||||
'uses' => 'AnimeController@videosEpisodes'
|
||||
]);
|
||||
|
||||
$router->get('/pictures', [
|
||||
'uses' => 'AnimeController@pictures'
|
||||
]);
|
||||
@ -275,7 +279,34 @@ $router->group(
|
||||
],
|
||||
function() use ($router) {
|
||||
$router->get('/', [
|
||||
'uses' => 'ProducerController@main',
|
||||
'uses' => 'SearchController@producers',
|
||||
]);
|
||||
|
||||
$router->get('/{id:[0-9]+}', [
|
||||
'uses' => 'ProducerController@main'
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
$router->get('/producers', [
|
||||
'uses' => 'SearchController@producers'
|
||||
]);
|
||||
|
||||
$router->group(
|
||||
[
|
||||
'prefix' => 'producers/{id:[0-9]+}'
|
||||
],
|
||||
function () use ($router) {
|
||||
$router->get('/', [
|
||||
'uses' => 'ProducerController@main'
|
||||
]);
|
||||
|
||||
$router->get('/full', [
|
||||
'uses' => 'ProducerController@full'
|
||||
]);
|
||||
|
||||
$router->get('/external', [
|
||||
'uses' => 'ProducerController@external'
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
@ -361,6 +361,42 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/anime/{id}/videos/episodes": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"anime"
|
||||
],
|
||||
"operationId": "getAnimeVideosEpisodes",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/parameters/page"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Returns episode videos related to the entry",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/anime_videos_episodes"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Error: Bad request. When required parameters were not supplied."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/anime/{id}/pictures": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@ -1130,6 +1166,38 @@
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/components/parameters/page"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/parameters/limit"
|
||||
},
|
||||
{
|
||||
"name": "q",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "order_by",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/magazines_query_orderby"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sort",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/search_query_sort"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "letter",
|
||||
"in": "query",
|
||||
"description": "Return entries starting with the given letter",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@ -1827,24 +1895,105 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/producers": {
|
||||
"/producers/{id}": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"producers"
|
||||
],
|
||||
"operationId": "getProducers",
|
||||
"operationId": "getProducerById",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/components/parameters/page"
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Returns producers collection",
|
||||
"description": "Returns producer resource",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/producers"
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/producer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Error: Bad request. When required parameters were not supplied."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/producers/{id}/full": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"producers"
|
||||
],
|
||||
"operationId": "getProducerFullById",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Returns producer resource",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/producer_full"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Error: Bad request. When required parameters were not supplied."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/producers/{id}/external": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"producers"
|
||||
],
|
||||
"operationId": "getProducerExternal",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Returns producer's external links",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/external_links"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2773,6 +2922,66 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/producers": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"producers"
|
||||
],
|
||||
"operationId": "getProducers",
|
||||
"parameters": [
|
||||
{
|
||||
"$ref": "#/components/parameters/page"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/parameters/limit"
|
||||
},
|
||||
{
|
||||
"name": "q",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "order_by",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/producers_query_orderby"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sort",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/search_query_sort"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "letter",
|
||||
"in": "query",
|
||||
"description": "Return entries starting with the given letter",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Returns producers collection",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/producers"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Error: Bad request. When required parameters were not supplied."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/seasons/{year}/{season}": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@ -3914,6 +4123,46 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"anime_videos_episodes": {
|
||||
"description": "Anime Videos Episodes Resource",
|
||||
"allOf": [
|
||||
{
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"properties": {
|
||||
"mal_id": {
|
||||
"description": "MyAnimeList ID or Episode Number",
|
||||
"type": "integer"
|
||||
},
|
||||
"title": {
|
||||
"description": "Episode Title",
|
||||
"type": "string"
|
||||
},
|
||||
"episode": {
|
||||
"description": "Episode Subtitle",
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"description": "Episode Page URL",
|
||||
"type": "string"
|
||||
},
|
||||
"images": {
|
||||
"$ref": "#/components/schemas/common_images"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/pagination"
|
||||
}
|
||||
]
|
||||
},
|
||||
"character_pictures": {
|
||||
"description": "Character Pictures",
|
||||
"properties": {
|
||||
@ -4456,7 +4705,9 @@
|
||||
"enum": [
|
||||
"mal_id",
|
||||
"name",
|
||||
"count"
|
||||
"count",
|
||||
"favorites",
|
||||
"established"
|
||||
]
|
||||
},
|
||||
"users_search_query_gender": {
|
||||
@ -4631,7 +4882,7 @@
|
||||
"description": "All titles",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"$ref": "#/components/schemas/title"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
@ -4934,7 +5185,7 @@
|
||||
"description": "All titles",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"$ref": "#/components/schemas/title"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
@ -5292,6 +5543,34 @@
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"music_videos": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"description": "Title",
|
||||
"type": "string"
|
||||
},
|
||||
"video": {
|
||||
"$ref": "#/components/schemas/trailer"
|
||||
},
|
||||
"meta": {
|
||||
"properties": {
|
||||
"title": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"author": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
@ -6229,6 +6508,19 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"title": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"description": "Title type",
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"description": "Title value",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"external_links": {
|
||||
"description": "External links",
|
||||
"properties": {
|
||||
@ -6461,7 +6753,7 @@
|
||||
"description": "All Titles",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"$ref": "#/components/schemas/title"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
@ -6495,6 +6787,7 @@
|
||||
"enum": [
|
||||
"Manga",
|
||||
"Novel",
|
||||
"Light Novel",
|
||||
"One-shot",
|
||||
"Doujinshi",
|
||||
"Manhua",
|
||||
@ -6534,11 +6827,13 @@
|
||||
"score": {
|
||||
"description": "Score",
|
||||
"type": "number",
|
||||
"format": "float"
|
||||
"format": "float",
|
||||
"nullable": true
|
||||
},
|
||||
"scored_by": {
|
||||
"description": "Number of users",
|
||||
"type": "integer"
|
||||
"type": "integer",
|
||||
"nullable": true
|
||||
},
|
||||
"rank": {
|
||||
"description": "Ranking",
|
||||
@ -6663,7 +6958,7 @@
|
||||
"description": "All Titles",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
"$ref": "#/components/schemas/title"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
@ -6689,6 +6984,7 @@
|
||||
"enum": [
|
||||
"Manga",
|
||||
"Novel",
|
||||
"Light Novel",
|
||||
"One-shot",
|
||||
"Doujinshi",
|
||||
"Manhua",
|
||||
@ -6728,11 +7024,13 @@
|
||||
"score": {
|
||||
"description": "Score",
|
||||
"type": "number",
|
||||
"format": "float"
|
||||
"format": "float",
|
||||
"nullable": true
|
||||
},
|
||||
"scored_by": {
|
||||
"description": "Number of users",
|
||||
"type": "integer"
|
||||
"type": "integer",
|
||||
"nullable": true
|
||||
},
|
||||
"rank": {
|
||||
"description": "Ranking",
|
||||
@ -7213,7 +7511,7 @@
|
||||
"type": "object"
|
||||
},
|
||||
"producers": {
|
||||
"description": "Producer Collection Resource",
|
||||
"description": "Producers Collection Resource",
|
||||
"allOf": [
|
||||
{
|
||||
"properties": {
|
||||
@ -7231,24 +7529,100 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"producer": {
|
||||
"description": "Producer Resource",
|
||||
"producer_full": {
|
||||
"description": "Producers Resource",
|
||||
"properties": {
|
||||
"mal_id": {
|
||||
"description": "MyAnimeList ID",
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"description": "Producer Name",
|
||||
"url": {
|
||||
"description": "MyAnimeList URL",
|
||||
"type": "string"
|
||||
},
|
||||
"titles": {
|
||||
"description": "All titles",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/title"
|
||||
}
|
||||
},
|
||||
"images": {
|
||||
"$ref": "#/components/schemas/common_images"
|
||||
},
|
||||
"favorites": {
|
||||
"description": "Producers's member favorites count",
|
||||
"type": "integer"
|
||||
},
|
||||
"count": {
|
||||
"description": "Producers's anime count",
|
||||
"type": "integer"
|
||||
},
|
||||
"established": {
|
||||
"description": "Established Date ISO8601",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"about": {
|
||||
"description": "About the Producer",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"external": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"producer": {
|
||||
"description": "Producers Resource",
|
||||
"properties": {
|
||||
"mal_id": {
|
||||
"description": "MyAnimeList ID",
|
||||
"type": "integer"
|
||||
},
|
||||
"url": {
|
||||
"description": "MyAnimeList URL",
|
||||
"type": "string"
|
||||
},
|
||||
"count": {
|
||||
"description": "Producer's anime count",
|
||||
"titles": {
|
||||
"description": "All titles",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/title"
|
||||
}
|
||||
},
|
||||
"images": {
|
||||
"$ref": "#/components/schemas/common_images"
|
||||
},
|
||||
"favorites": {
|
||||
"description": "Producers's member favorites count",
|
||||
"type": "integer"
|
||||
},
|
||||
"count": {
|
||||
"description": "Producers's anime count",
|
||||
"type": "integer"
|
||||
},
|
||||
"established": {
|
||||
"description": "Established Date ISO8601",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"about": {
|
||||
"description": "About the Producer",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
@ -8353,7 +8727,8 @@
|
||||
},
|
||||
"score": {
|
||||
"description": "User Score",
|
||||
"type": "integer"
|
||||
"type": "integer",
|
||||
"nullable": true
|
||||
},
|
||||
"status": {
|
||||
"description": "User list status",
|
||||
|
Loading…
x
Reference in New Issue
Block a user