[#2] work on tv series processing
This commit is contained in:
@@ -27,4 +27,9 @@ class Episode extends Model
|
||||
'show_id',
|
||||
'season_id',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'crew' => 'array',
|
||||
'guest_stars' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -18,5 +18,8 @@ class ExternalId extends Model
|
||||
'facebook_id',
|
||||
'instagram_id',
|
||||
'twitter_id',
|
||||
'tvdb_id',
|
||||
'freebase_id',
|
||||
'tvrage_id',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -45,4 +45,14 @@ class Show extends Model
|
||||
{
|
||||
return $this->belongsToMany(Person::class, 'show_crew', 'show_id', 'person_id');
|
||||
}
|
||||
|
||||
public function images()
|
||||
{
|
||||
return $this->belongsToMany(Image::class, 'show_images', 'show_id', 'image_id');
|
||||
}
|
||||
|
||||
public function videos()
|
||||
{
|
||||
return $this->belongsToMany(Video::class, 'show_videos', 'show_id', 'video_id');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
namespace App\Service\MediaProcessing;
|
||||
|
||||
use App\Models\Episode;
|
||||
use App\Models\ExternalId;
|
||||
use App\Models\Image;
|
||||
use App\Models\ItemToFetchJobs;
|
||||
use App\Models\Person;
|
||||
use App\Models\Season;
|
||||
use App\Models\Show;
|
||||
use App\Models\ShowAlternativeTitle;
|
||||
use App\Models\Video;
|
||||
use App\Service\TMDBApi\PersonApi;
|
||||
use App\Service\TMDBApi\ShowsApi;
|
||||
use Illuminate\Support\Str;
|
||||
@@ -48,10 +51,13 @@ class ShowProcessingService implements ProcessingInterface
|
||||
if ($show) {
|
||||
return;
|
||||
}
|
||||
|
||||
//dd($tmdbShow);
|
||||
$tmdbShow['slug'] = Str::slug($tmdbShow['name'].'-'.$tmdbShow['tmdb_id']);
|
||||
$tmdbShow['first_air_date'] = $tmdbShow['first_air_date'] ? new \DateTime($tmdbShow['first_air_date']) : null;
|
||||
$tmdbShow['last_air_date'] = $tmdbShow['last_air_date'] ? new \DateTime($tmdbShow['last_air_date']) : null;
|
||||
$tmdbShow['episode_run_time'] = reset($tmdbShow['episode_run_time']);
|
||||
$tmdbShow['languages'] = json_encode($tmdbShow['languages']);
|
||||
$tmdbShow['origin_country'] = reset($tmdbShow['origin_country']);
|
||||
|
||||
$show = Show::create($tmdbShow);
|
||||
|
||||
@@ -59,6 +65,11 @@ class ShowProcessingService implements ProcessingInterface
|
||||
$this->processSeasons($show, $tmdbShow['seasons']);
|
||||
}
|
||||
|
||||
// @todo process genres
|
||||
// @todo process networks
|
||||
// @todo process production countries
|
||||
// @todo process production companies
|
||||
|
||||
$this->removeElementFromRemainingJobs($item->tmdb_id, ItemToFetchJobs::JOB_DETAILS);
|
||||
}
|
||||
|
||||
@@ -106,6 +117,117 @@ class ShowProcessingService implements ProcessingInterface
|
||||
$this->removeElementFromRemainingJobs($item->tmdb_id, ItemToFetchJobs::JOB_CREDITS);
|
||||
}
|
||||
|
||||
private function getExternalIds($item)
|
||||
{
|
||||
$tmdbExternalIds = $this->showsApi->getExternalIds($item->tmdb_id);
|
||||
|
||||
if (empty($tmdbExternalIds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$show = Show::where('tmdb_id', $item->tmdb_id)->first();
|
||||
|
||||
if (!$show) {
|
||||
return;
|
||||
}
|
||||
|
||||
$externalId = ExternalId::where('entity_id', $show->id)
|
||||
->where('entity_type', ExternalId::TYPE_SHOW)
|
||||
->first();
|
||||
|
||||
if (!$externalId) {
|
||||
$externalIds['tmdb_id'] = $tmdbExternalIds['id'];
|
||||
//$externalIds['show_id'] = $show->id;
|
||||
unset($externalIds['id']);
|
||||
|
||||
$externalIds['entity_id'] = $show->id;
|
||||
$externalIds['entity_type'] = ExternalId::TYPE_SHOW;
|
||||
|
||||
ExternalId::create($externalIds);
|
||||
}
|
||||
|
||||
$this->removeElementFromRemainingJobs($item->tmdb_id, ItemToFetchJobs::JOB_EXTERNAL_IDS);
|
||||
}
|
||||
|
||||
private function getImages($item)
|
||||
{
|
||||
$tmdbImages = $this->showsApi->getImages($item->tmdb_id);
|
||||
|
||||
if (empty($tmdbImages)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$show = Show::where('tmdb_id', $item->tmdb_id)->first();
|
||||
|
||||
foreach ($tmdbImages as $type => $images) {
|
||||
if (!is_array($images)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($images as $image) {
|
||||
$imageExists = Image::where('type', $type)
|
||||
->where('file_path', $image['file_path'])
|
||||
->first();
|
||||
|
||||
if (!$imageExists) {
|
||||
$image['iso'] = $image['iso_639_1'];
|
||||
$image['type'] = $type;
|
||||
$imageExists = Image::create($image);
|
||||
}
|
||||
|
||||
if ($show->whereHas('images', function ($query) use ($imageExists) {
|
||||
$query->where('type', $imageExists->type)
|
||||
->where('file_path', $imageExists->file_path);
|
||||
})->exists()) {
|
||||
return;
|
||||
} else {
|
||||
$show->images()->attach($imageExists);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->removeElementFromRemainingJobs($item->tmdb_id, ItemToFetchJobs::JOB_IMAGES);
|
||||
}
|
||||
|
||||
private function getVideos($item)
|
||||
{
|
||||
$show = Show::where('tmdb_id', $item->tmdb_id)->first();
|
||||
|
||||
$tmdbVideos = $this->showsApi->getVideos($item->tmdb_id);
|
||||
|
||||
if (empty($tmdbVideos) || empty($tmdbVideos['results'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($tmdbVideos['results'] as $tmdbVideo) {
|
||||
$videoExists = Video::where('tmdb_id', $tmdbVideo['id'])->first();
|
||||
|
||||
if (!$videoExists) {
|
||||
$videoExists = Video::create([
|
||||
'iso_639' => $tmdbVideo['iso_639_1'],
|
||||
'iso_3166' => $tmdbVideo['iso_3166_1'],
|
||||
'name' => $tmdbVideo['name'],
|
||||
'key' => $tmdbVideo['key'],
|
||||
'site' => $tmdbVideo['site'],
|
||||
'size' => $tmdbVideo['size'],
|
||||
'type' => $tmdbVideo['type'],
|
||||
'official' => $tmdbVideo['official'],
|
||||
'published_at' => $tmdbVideo['published_at'] ? new \DateTime($tmdbVideo['published_at']) : null,
|
||||
'tmdb_id' => $tmdbVideo['id'],
|
||||
]);
|
||||
}
|
||||
|
||||
if ($show->whereHas('videos', function ($query) use ($show) {
|
||||
$query->where('show_id', $show->id);
|
||||
})->exists()) {
|
||||
return;
|
||||
} else {
|
||||
$show->videos()->attach($videoExists);
|
||||
}
|
||||
}
|
||||
|
||||
$this->removeElementFromRemainingJobs($item->tmdb_id, ItemToFetchJobs::JOB_VIDEOS);
|
||||
}
|
||||
|
||||
private function processSeasons(Show $show, array $seasons)
|
||||
{
|
||||
foreach ($seasons as $season) {
|
||||
@@ -114,6 +236,7 @@ class ShowProcessingService implements ProcessingInterface
|
||||
->first();
|
||||
|
||||
if (!$showSeason) {
|
||||
$season['show_id'] = $show->id;
|
||||
$showSeason = Season::create($season);
|
||||
|
||||
$tmdbSeasonDetails = $this->showsApi->getSeasonDetails($show->tmdb_id, $season['season_number']);
|
||||
@@ -139,6 +262,11 @@ class ShowProcessingService implements ProcessingInterface
|
||||
$tmdbEpisode['tmdb_id'] = $tmdbEpisode['id'];
|
||||
$tmdbEpisode['slug'] = Str::slug($tmdbEpisode['name']);
|
||||
$tmdbEpisode['tmdb_show_id'] = $tmdbEpisode['show_id'];
|
||||
$tmdbEpisode['season_id'] = $season->id;
|
||||
// $tmdbEpisode['crew'] = $tmdbEpisode['crew'];
|
||||
// $tmdbEpisode['guest_stars'] = $tmdbEpisode['guest_stars'];
|
||||
|
||||
|
||||
$tmdbEpisode['show_id'] = $show->id;
|
||||
$tmdbEpisode['tmdb_id'] = $season->id;
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ return new class extends Migration
|
||||
$table->string('facebook_id')->nullable();
|
||||
$table->string('instagram_id')->nullable();
|
||||
$table->string('twitter_id')->nullable();
|
||||
$table->string('tvdb_id')->nullable();
|
||||
$table->string('freebase_id')->nullable();
|
||||
$table->string('tvrage_id')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ return new class extends Migration
|
||||
$table->id();
|
||||
$table->date('air_date')->nullable();
|
||||
$table->integer('episode_count')->nullable();
|
||||
$table->bigInteger('tmdb_id');
|
||||
$table->bigInteger('tmdb_id')->nullable();
|
||||
$table->string('name')->nullable();
|
||||
$table->string('slug')->nullable();
|
||||
$table->text('overview')->nullable();
|
||||
|
||||
@@ -23,7 +23,7 @@ return new class extends Migration
|
||||
$table->string('production_code')->nullable();
|
||||
$table->integer('runtime')->nullable();
|
||||
$table->integer('season_number')->nullable();
|
||||
$table->show_id('tmdb_show_id')->nullable();
|
||||
$table->bigInteger('tmdb_show_id')->nullable();
|
||||
$table->string('still_path', 500)->nullable();
|
||||
$table->decimal('vote_average', 10, 2)->nullable();
|
||||
$table->integer('vote_count')->nullable();
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('show_images', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('show_id');
|
||||
$table->unsignedBigInteger('image_id');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('show_images');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('show_videos', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('show_id');
|
||||
$table->unsignedBigInteger('video_id');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('show_videos');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user