mirror of
https://github.com/jikan-me/jikan-rest.git
synced 2025-02-20 11:23:35 +08:00
refactor v4 Anime response
This commit is contained in:
parent
74906bd46a
commit
009f4e5247
177
app/Anime.php
Normal file
177
app/Anime.php
Normal file
@ -0,0 +1,177 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Jenssegers\Mongodb\Eloquent\Model;
|
||||
use Jikan\Helper\Media;
|
||||
use Jikan\Helper\Parser;
|
||||
use Jikan\Jikan;
|
||||
use Jikan\Model\Common\YoutubeMeta;
|
||||
|
||||
class Anime extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'mal_id','url','image_url','title','title_english','title_japanese','title_synonyms','type','source','episodes','status','airing','aired','duration','rating','score','scored_by','rank','popularity','members','favorites','synopsis','background','premiered','broadcast','related','producers','licensors','studios','genres','opening_themes','ending_themes'
|
||||
];
|
||||
|
||||
/**
|
||||
* The accessors to append to the model's array form.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $appends = ['trailer', 'season', 'year', 'themes'];
|
||||
|
||||
protected $mainDataRequest = true;
|
||||
protected $databaseStoreAvailability = true;
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'anime';
|
||||
|
||||
/**
|
||||
* The primary key associated with the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
// protected $primaryKey = 'mal_id';
|
||||
//
|
||||
// const CREATED_AT = 'creation_date';
|
||||
// const UPDATED_AT = 'last_update';
|
||||
|
||||
/**
|
||||
* The attributes excluded from the model's JSON form.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = [
|
||||
'_id', 'expiresAt', 'request_hash', 'trailer_url', 'premiered', 'opening_themes', 'ending_themes'
|
||||
];
|
||||
|
||||
public function setRelatedAttribute($value)
|
||||
{
|
||||
$this->attributes['related'] = $this->getRelatedAttribute();
|
||||
}
|
||||
|
||||
public function getRelatedAttribute()
|
||||
{
|
||||
// Fix JSON response for empty related object
|
||||
if (\count($this->attributes['related']) === 0) {
|
||||
$this->attributes['related'] = new \stdClass();
|
||||
}
|
||||
|
||||
if (!is_object($this->attributes['related']) && !empty($this->attributes['related'])) {
|
||||
$relation = [];
|
||||
foreach ($this->attributes['related'] as $relationType => $related) {
|
||||
$relation[] = [
|
||||
'relation' => $relationType,
|
||||
'items' => $related
|
||||
];
|
||||
}
|
||||
$this->attributes['related'] = $relation;
|
||||
}
|
||||
|
||||
return $this->attributes['related'];
|
||||
}
|
||||
|
||||
public function setTrailerAttribute($value)
|
||||
{
|
||||
$this->attributes['trailer'] = $this->getTrailerAttribute();
|
||||
}
|
||||
|
||||
public function getTrailerAttribute()
|
||||
{
|
||||
$youtubeId = Media::youtubeIdFromUrl($this->attributes['trailer_url']);
|
||||
$youtubeUrl = Media::generateYoutubeUrlFromId($youtubeId);
|
||||
|
||||
return [
|
||||
'youtube_id' => $youtubeId,
|
||||
'url' => $youtubeUrl,
|
||||
'embed_url' => $this->attributes['trailer_url']
|
||||
];
|
||||
}
|
||||
|
||||
public function setSeasonAttribute($value)
|
||||
{
|
||||
$this->attributes['season'] = $this->getSeasonAttribute();
|
||||
}
|
||||
|
||||
public function getSeasonAttribute()
|
||||
{
|
||||
$premiered = $this->attributes['premiered'];
|
||||
|
||||
if (empty($premiered)
|
||||
|| is_null($premiered)
|
||||
|| !preg_match('~(Winter|Spring|Summer|Fall|)\s([\d+]{4})~', $premiered)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return explode(' ', $premiered)[0];
|
||||
}
|
||||
|
||||
public function setYearAttribute($value)
|
||||
{
|
||||
$this->attributes['year'] = $this->getYearAttribute();
|
||||
}
|
||||
|
||||
public function getYearAttribute()
|
||||
{
|
||||
$premiered = $this->attributes['premiered'];
|
||||
|
||||
if (empty($premiered)
|
||||
|| is_null($premiered)
|
||||
|| !preg_match('~(Winter|Spring|Summer|Fall|)\s([\d+]{4})~', $premiered)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (int) explode(' ', $premiered)[1];
|
||||
}
|
||||
|
||||
public function setBroadcastAttribute($value)
|
||||
{
|
||||
$this->attributes['year'] = $this->getBroadcastAttribute();
|
||||
}
|
||||
|
||||
public function getBroadcastAttribute()
|
||||
{
|
||||
$broadcastStr = $this->attributes['broadcast'];
|
||||
|
||||
if (is_null($broadcastStr)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (preg_match('~(.*) at (.*) \(~', $broadcastStr, $matches)) {
|
||||
return [
|
||||
'day' => $matches[1],
|
||||
'time' => $matches[2],
|
||||
'timezone' => 'Asia/Tokyo',
|
||||
'string' => $broadcastStr
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setThemesAttribute($value)
|
||||
{
|
||||
$this->attributes['themes'] = $this->getThemesAttribute();
|
||||
}
|
||||
|
||||
public function getThemesAttribute()
|
||||
{
|
||||
return [
|
||||
'opening' => $this->attributes['opening_themes'],
|
||||
'ending' => $this->attributes['ending_themes'],
|
||||
];
|
||||
}
|
||||
}
|
132
app/Http/Controllers/V4DB/AnimeController.php
Normal file
132
app/Http/Controllers/V4DB/AnimeController.php
Normal file
@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\V4DB;
|
||||
|
||||
use App\Anime;
|
||||
use App\Http\HttpHelper;
|
||||
use App\Http\HttpResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Jikan\Request\Anime\AnimeCharactersAndStaffRequest;
|
||||
use Jikan\Request\Anime\AnimeEpisodeRequest;
|
||||
use Jikan\Request\Anime\AnimeEpisodesRequest;
|
||||
use Jikan\Request\Anime\AnimeForumRequest;
|
||||
use Jikan\Request\Anime\AnimeMoreInfoRequest;
|
||||
use Jikan\Request\Anime\AnimeNewsRequest;
|
||||
use Jikan\Request\Anime\AnimePicturesRequest;
|
||||
use Jikan\Request\Anime\AnimeRecentlyUpdatedByUsersRequest;
|
||||
use Jikan\Request\Anime\AnimeRecommendationsRequest;
|
||||
use Jikan\Request\Anime\AnimeRequest;
|
||||
use Jikan\Request\Anime\AnimeReviewsRequest;
|
||||
use Jikan\Request\Anime\AnimeStatsRequest;
|
||||
use Jikan\Request\Anime\AnimeVideosRequest;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
|
||||
class AnimeController extends Controller
|
||||
{
|
||||
public function main(Request $request, int $id)
|
||||
{
|
||||
|
||||
return new \App\Http\Resources\V4\AnimeResource(
|
||||
Anime::query()
|
||||
->where('mal_id', $id)
|
||||
->get([
|
||||
'mal_id','url','image_url','trailer_url','title','title_english','title_japanese','title_synonyms','type','source','episodes','status','airing','aired','duration','rating','score','scored_by','rank','popularity','members','favorites','synopsis','background','premiered','broadcast','related','producers','licensors','studios','genres','opening_themes','ending_themes'
|
||||
])
|
||||
->first()
|
||||
);
|
||||
|
||||
return response()->json($result);
|
||||
|
||||
$result = DB::table('anime')
|
||||
->where('mal_id', $id)
|
||||
->get([
|
||||
'mal_id','url','image_url','trailer_url','title','title_english','title_japanese','title_synonyms','type','source','episodes','status','airing','aired','duration','rating','score','scored_by','rank','popularity','members','favorites','synopsis','background','premiered','broadcast','related','producers','licensors','studios','genres','opening_themes','ending_themes'
|
||||
]);
|
||||
|
||||
$response = $result->toArray();
|
||||
|
||||
if (!empty($response)) {
|
||||
$response = $response[0];
|
||||
|
||||
return response(
|
||||
$this->prepareResponse($request, $response)
|
||||
);
|
||||
}
|
||||
|
||||
return HttpResponse::notFound($request);
|
||||
}
|
||||
|
||||
public function characters_staff(int $id)
|
||||
{
|
||||
$anime = $this->jikan->getAnimeCharactersAndStaff(new AnimeCharactersAndStaffRequest($id));
|
||||
return response($this->serializer->serialize($anime, 'json'));
|
||||
}
|
||||
|
||||
public function episode(int $id, int $episodeId)
|
||||
{
|
||||
$anime = $this->jikan->getAnimeEpisode(new AnimeEpisodeRequest($id, $episodeId));
|
||||
return response($this->serializer->serialize($anime, 'json'));
|
||||
}
|
||||
|
||||
public function episodes(int $id)
|
||||
{
|
||||
$page = $_GET['page'] ?? 1;
|
||||
$anime = $this->jikan->getAnimeEpisodes(new AnimeEpisodesRequest($id, $page));
|
||||
return response($this->serializer->serialize($anime, 'json'));
|
||||
}
|
||||
|
||||
public function news(int $id)
|
||||
{
|
||||
$anime = ['articles' => $this->jikan->getNewsList(new AnimeNewsRequest($id))];
|
||||
return response($this->serializer->serialize($anime, 'json'));
|
||||
}
|
||||
|
||||
public function forum(int $id)
|
||||
{
|
||||
$anime = ['topics' => $this->jikan->getAnimeForum(new AnimeForumRequest($id))];
|
||||
return response($this->serializer->serialize($anime, 'json'));
|
||||
}
|
||||
|
||||
public function videos(int $id)
|
||||
{
|
||||
$anime = $this->jikan->getAnimeVideos(new AnimeVideosRequest($id));
|
||||
return response($this->serializer->serialize($anime, 'json'));
|
||||
}
|
||||
|
||||
public function pictures(int $id)
|
||||
{
|
||||
$anime = ['pictures' => $this->jikan->getAnimePictures(new AnimePicturesRequest($id))];
|
||||
return response($this->serializer->serialize($anime, 'json'));
|
||||
}
|
||||
|
||||
public function stats(int $id)
|
||||
{
|
||||
$anime = $this->jikan->getAnimeStats(new AnimeStatsRequest($id));
|
||||
return response($this->serializer->serialize($anime, 'json'));
|
||||
}
|
||||
|
||||
public function moreInfo(int $id)
|
||||
{
|
||||
$anime = ['moreinfo' => $this->jikan->getAnimeMoreInfo(new AnimeMoreInfoRequest($id))];
|
||||
return response(json_encode($anime));
|
||||
}
|
||||
|
||||
public function recommendations(int $id)
|
||||
{
|
||||
$anime = ['recommendations' => $this->jikan->getAnimeRecommendations(new AnimeRecommendationsRequest($id))];
|
||||
return response($this->serializer->serialize($anime, 'json'));
|
||||
}
|
||||
|
||||
public function userupdates(int $id, int $page = 1)
|
||||
{
|
||||
$anime = ['users' => $this->jikan->getAnimeRecentlyUpdatedByUsers(new AnimeRecentlyUpdatedByUsersRequest($id, $page))];
|
||||
return response($this->serializer->serialize($anime, 'json'));
|
||||
}
|
||||
|
||||
public function reviews(int $id, int $page = 1)
|
||||
{
|
||||
$anime = ['reviews' => $this->jikan->getAnimeReviews(new AnimeReviewsRequest($id, $page))];
|
||||
return response($this->serializer->serialize($anime, 'json'));
|
||||
}
|
||||
}
|
53
app/Http/Resources/V4/AnimeResource.php
Normal file
53
app/Http/Resources/V4/AnimeResource.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\V4;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class AnimeResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'mal_id' => $this->mal_id,
|
||||
'url' => $this->url,
|
||||
'image_url' => $this->image_url,
|
||||
'trailer' => $this->trailer,
|
||||
'title' => $this->title,
|
||||
'title_english' => $this->title_english,
|
||||
'title_japanese' => $this->title_japanese,
|
||||
'title_synonyms' => $this->title_synonyms,
|
||||
'type' => $this->type,
|
||||
'source' => $this->source,
|
||||
'episodes' => $this->episodes,
|
||||
'status' => $this->status,
|
||||
'airing' => $this->airing,
|
||||
'aired' => $this->aired,
|
||||
'duration' => $this->duration,
|
||||
'rating' => $this->rating,
|
||||
'scored' => $this->score,
|
||||
'scored_by' => $this->scored_by,
|
||||
'rank' => $this->rank,
|
||||
'popularity' => $this->popularity,
|
||||
'members' => $this->members,
|
||||
'favorites' => $this->favorites,
|
||||
'synopsis' => $this->synopsis,
|
||||
'background' => $this->background,
|
||||
'season' => $this->season,
|
||||
'year' => $this->year,
|
||||
'broadcast' => $this->broadcast,
|
||||
'related' => $this->related,
|
||||
'producers' => $this->producers,
|
||||
'licensors' => $this->licensors,
|
||||
'studios' => $this->studios,
|
||||
'genres' => $this->genres,
|
||||
'themes' => $this->themes
|
||||
];
|
||||
}
|
||||
}
|
56
database/migrations/2020_06_07_230022_create_anime_table.php
Normal file
56
database/migrations/2020_06_07_230022_create_anime_table.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateAnimeTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function up()
|
||||
{
|
||||
Schema::create('anime', function (Blueprint $table) {
|
||||
$table->unique(['request_hash' => 1], 'request_hash');
|
||||
$table->unique(['mal_id' => 1], 'mal_id');
|
||||
$table->string('url');
|
||||
$table->string('image_url');
|
||||
$table->string('trailer_url');
|
||||
$table->index('title');
|
||||
$table->index('title_english');
|
||||
$table->index('title_japanese');
|
||||
$table->enum('type', ['TV', 'Movie', 'OVA', 'Special', 'ONA', 'Music']);
|
||||
$table->index('source');
|
||||
$table->integer('episodes')->index('episodes');
|
||||
$table->string('status')->index();
|
||||
$table->boolean('airing');
|
||||
$table->string('duration');
|
||||
$table->string('rating')->index('rating');
|
||||
$table->float('score')->index('score');
|
||||
$table->integer('rank')->index('rank')->nullable();
|
||||
$table->integer('popularity')->index('popularity');
|
||||
$table->integer('members')->index('members');
|
||||
$table->integer('favorites')->index('favorites');
|
||||
$table->string('synopsis')->nullable();
|
||||
$table->string('background')->nullable();
|
||||
$table->index('genres');
|
||||
$table->index(['aired.from' => 1], 'start_date');
|
||||
$table->index(['aired.to' => 1], 'end_date');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('anime');
|
||||
}
|
||||
}
|
@ -71,10 +71,6 @@ $router->group(
|
||||
'uses' => 'AnimeController@videos'
|
||||
]);
|
||||
|
||||
$router->get('/pictures', [
|
||||
'uses' => 'AnimeController@pictures'
|
||||
]);
|
||||
|
||||
$router->get('/statistics', [
|
||||
'uses' => 'AnimeController@stats'
|
||||
]);
|
||||
@ -97,6 +93,10 @@ $router->group(
|
||||
}
|
||||
);
|
||||
|
||||
$router->get('/manga', [
|
||||
'uses' => 'SearchController@manga'
|
||||
]);
|
||||
|
||||
$router->group(
|
||||
[
|
||||
'prefix' => 'manga/{id:[0-9]+}'
|
||||
@ -119,7 +119,7 @@ $router->group(
|
||||
]);
|
||||
|
||||
$router->get('/pictures', [
|
||||
'uses' => 'MangaController@pictures'
|
||||
'uses' => 'MangaController@media'
|
||||
]);
|
||||
|
||||
$router->get('/statistics', [
|
||||
@ -144,6 +144,9 @@ $router->group(
|
||||
}
|
||||
);
|
||||
|
||||
$router->get('/characters', [
|
||||
'uses' => 'SearchController@characters'
|
||||
]);
|
||||
$router->group(
|
||||
[
|
||||
'prefix' => 'characters/{id:[0-9]+}'
|
||||
@ -154,11 +157,14 @@ $router->group(
|
||||
]);
|
||||
|
||||
$router->get('/pictures', [
|
||||
'uses' => 'CharacterController@pictures'
|
||||
'uses' => 'CharacterController@media'
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
$router->get('/people', [
|
||||
'uses' => 'SearchController@people'
|
||||
]);
|
||||
$router->group(
|
||||
[
|
||||
'prefix' => 'people/{id:[0-9]+}'
|
||||
@ -169,7 +175,7 @@ $router->group(
|
||||
]);
|
||||
|
||||
$router->get('/pictures', [
|
||||
'uses' => 'PersonController@pictures'
|
||||
'uses' => 'PersonController@media'
|
||||
]);
|
||||
}
|
||||
);
|
||||
@ -188,7 +194,7 @@ $router->group(
|
||||
'uses' => 'SeasonController@main'
|
||||
]);
|
||||
|
||||
$router->get('/later', [
|
||||
$router->get('/upcoming', [
|
||||
'uses' => 'SeasonController@later'
|
||||
]);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user