[#2] tv processing progress, credits
This commit is contained in:
@@ -35,4 +35,14 @@ class Show extends Model
|
|||||||
'vote_average',
|
'vote_average',
|
||||||
'vote_count',
|
'vote_count',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public function castList()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(Person::class, 'show_cast', 'show_id', 'person_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function crewList()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(Person::class, 'show_crew', 'show_id', 'person_id');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class ShowAlternativeTitle extends Model
|
||||||
|
{
|
||||||
|
protected $fillable = [
|
||||||
|
'iso',
|
||||||
|
'title',
|
||||||
|
'show_id',
|
||||||
|
'type',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -3,8 +3,12 @@
|
|||||||
namespace App\Service\MediaProcessing;
|
namespace App\Service\MediaProcessing;
|
||||||
|
|
||||||
use App\Models\Episode;
|
use App\Models\Episode;
|
||||||
|
use App\Models\ItemToFetchJobs;
|
||||||
|
use App\Models\Person;
|
||||||
use App\Models\Season;
|
use App\Models\Season;
|
||||||
use App\Models\Show;
|
use App\Models\Show;
|
||||||
|
use App\Models\ShowAlternativeTitle;
|
||||||
|
use App\Service\TMDBApi\PersonApi;
|
||||||
use App\Service\TMDBApi\ShowsApi;
|
use App\Service\TMDBApi\ShowsApi;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use function PHPUnit\Framework\containsIdentical;
|
use function PHPUnit\Framework\containsIdentical;
|
||||||
@@ -12,10 +16,14 @@ use function PHPUnit\Framework\containsIdentical;
|
|||||||
class ShowProcessingService implements ProcessingInterface
|
class ShowProcessingService implements ProcessingInterface
|
||||||
{
|
{
|
||||||
private ShowsApi $showsApi;
|
private ShowsApi $showsApi;
|
||||||
|
private PersonApi $personApi;
|
||||||
|
|
||||||
public function __construct(ShowsApi $showsApi)
|
public function __construct(
|
||||||
{
|
ShowsApi $showsApi,
|
||||||
|
PersonApi $personApi
|
||||||
|
) {
|
||||||
$this->showsApi = $showsApi;
|
$this->showsApi = $showsApi;
|
||||||
|
$this->personApi = $personApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function process($item, $job)
|
public function process($item, $job)
|
||||||
@@ -51,12 +59,51 @@ class ShowProcessingService implements ProcessingInterface
|
|||||||
$this->processSeasons($show, $tmdbShow['seasons']);
|
$this->processSeasons($show, $tmdbShow['seasons']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo remove jobs from db
|
$this->removeElementFromRemainingJobs($item->tmdb_id, ItemToFetchJobs::JOB_DETAILS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getAlternativeTitles()
|
private function getAlternativeTitles($item)
|
||||||
{
|
{
|
||||||
|
$tmdbAlternativeTitles = $this->showsApi->getAlternativeTitles($item->tmdb_id);
|
||||||
|
|
||||||
|
if (empty($tmdbAlternativeTitles) ||empty($tmdbAlternativeTitles['results'])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$show = Show::where('tmdb_id', $item->tmdb_id)->first();
|
||||||
|
|
||||||
|
foreach ($tmdbAlternativeTitles['results'] as $tmdbAlternativeTitle) {
|
||||||
|
$alternativeTitle = ShowAlternativeTitle::where('show_id', $show->id)
|
||||||
|
->where('iso', $tmdbAlternativeTitle['iso_3166_1'])
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (!$alternativeTitle) {
|
||||||
|
ShowAlternativeTitle::create([
|
||||||
|
'iso' => $tmdbAlternativeTitle['iso_3166_1'],
|
||||||
|
'title' => $tmdbAlternativeTitle['title'],
|
||||||
|
'show_id' => $show->id,
|
||||||
|
'type' => $tmdbAlternativeTitle['type'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->removeElementFromRemainingJobs($item->tmdb_id, ItemToFetchJobs::JOB_ALTERNVATIVE_TITLES);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getCredits($item)
|
||||||
|
{
|
||||||
|
$tmdbCredits = $this->showsApi->getCredits($item->tmdb_id);
|
||||||
|
|
||||||
|
if (empty($tmdbCredits)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$show = Show::where('tmdb_id', $item->tmdb_id)->first();
|
||||||
|
|
||||||
|
$this->processCast($show, $tmdbCredits['cast'] ?? []);
|
||||||
|
$this->processCrew($show, $tmdbCredits['crew'] ?? []);
|
||||||
|
|
||||||
|
$this->removeElementFromRemainingJobs($item->tmdb_id, ItemToFetchJobs::JOB_CREDITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processSeasons(Show $show, array $seasons)
|
private function processSeasons(Show $show, array $seasons)
|
||||||
@@ -99,4 +146,132 @@ class ShowProcessingService implements ProcessingInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function removeElementFromRemainingJobs(int $tmdbId, string $job)
|
||||||
|
{
|
||||||
|
$itemToFetchJobs = ItemToFetchJobs::where('tmdb_id', $tmdbId)->first();
|
||||||
|
|
||||||
|
$remainingJobs = $itemToFetchJobs->remaining_jobs;
|
||||||
|
|
||||||
|
if (is_string($remainingJobs)) {
|
||||||
|
$remainingJobs = json_decode($remainingJobs, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$remainingJobKey = array_search($job, $remainingJobs);
|
||||||
|
|
||||||
|
unset($remainingJobs[$remainingJobKey]);
|
||||||
|
|
||||||
|
if (empty($remainingJobs)) {
|
||||||
|
$itemToFetchJobs->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
$itemToFetchJobs->remaining_jobs = $remainingJobs;
|
||||||
|
$itemToFetchJobs->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processCast($show, array $credits)
|
||||||
|
{
|
||||||
|
if (empty($credits)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($credits as $castPerson) {
|
||||||
|
$person = Person::where('tmdb_id', $castPerson['id'])->first();
|
||||||
|
|
||||||
|
if (!$person) {
|
||||||
|
$personData = [
|
||||||
|
'adult' => $castPerson['adult'],
|
||||||
|
'tmdb_id' => $castPerson['id'],
|
||||||
|
'gender' => $castPerson['gender'],
|
||||||
|
'name' => $castPerson['name'],
|
||||||
|
'slug' => Str::slug($castPerson['name']),
|
||||||
|
'popularity' => $castPerson['popularity'],
|
||||||
|
'profile_path' => $castPerson['profile_path'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$tmdbPerson = $this->personApi->getPerson($castPerson['id']);
|
||||||
|
|
||||||
|
if (!empty($tmdbPerson)) {
|
||||||
|
$personData = array_merge($personData, [
|
||||||
|
'biography' => $tmdbPerson['biography'],
|
||||||
|
'birtday' => $tmdbPerson['birthday'],
|
||||||
|
'deathday' => $tmdbPerson['deathday'],
|
||||||
|
'homepage' => $tmdbPerson['homepage'],
|
||||||
|
'imdb_id' => $tmdbPerson['imdb_id'],
|
||||||
|
'known_for_department' => $tmdbPerson['known_for_department'] ? json_encode($tmdbPerson['known_for_department']) : null,
|
||||||
|
'also_known_as' => $tmdbPerson['also_known_as'] ? json_encode($tmdbPerson['also_known_as']) : null,
|
||||||
|
'place_of_birth' => $tmdbPerson['place_of_birth'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$person = Person::create($personData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($show->whereHas('castList', function ($query) use ($person) {
|
||||||
|
$query->where('tmdb_id', '=', $person->tmdb_id);
|
||||||
|
})->exists()) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
$show->castList()->attach($person, [
|
||||||
|
'known_for_department' => $castPerson['known_for_department'],
|
||||||
|
'character' => $castPerson['character'],
|
||||||
|
'tmdb_cast_id' => $castPerson['cast_id'],
|
||||||
|
'order' => $castPerson['order'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processCrew($show, array $credits)
|
||||||
|
{
|
||||||
|
if (empty($credits)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($credits as $crewPerson) {
|
||||||
|
$person = Person::where('tmdb_id', $crewPerson['id'])->first();
|
||||||
|
|
||||||
|
if (!$person) {
|
||||||
|
$personData = [
|
||||||
|
'adult' => $crewPerson['adult'],
|
||||||
|
'tmdb_id' => $crewPerson['id'],
|
||||||
|
'gender' => $crewPerson['gender'],
|
||||||
|
'name' => $crewPerson['name'],
|
||||||
|
'slug' => Str::slug($crewPerson['name']),
|
||||||
|
'popularity' => $crewPerson['popularity'],
|
||||||
|
'profile_path' => $crewPerson['profile_path'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$tmdbPerson = $this->personApi->getPerson($crewPerson['id']);
|
||||||
|
|
||||||
|
if (!empty($tmdbPerson)) {
|
||||||
|
$personData = array_merge($personData, [
|
||||||
|
'biography' => $tmdbPerson['biography'],
|
||||||
|
'birtday' => $tmdbPerson['birthday'],
|
||||||
|
'deathday' => $tmdbPerson['deathday'],
|
||||||
|
'homepage' => $tmdbPerson['homepage'],
|
||||||
|
'imdb_id' => $tmdbPerson['imdb_id'],
|
||||||
|
'known_for_department' => $tmdbPerson['known_for_department'] ? json_encode($tmdbPerson['known_for_department']) : null,
|
||||||
|
'also_known_as' => $tmdbPerson['also_known_as'] ? json_encode($tmdbPerson['also_known_as']) : null,
|
||||||
|
'place_of_birth' => $tmdbPerson['place_of_birth'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$person = Person::create($personData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($show->whereHas('crewList', function ($query) use ($person) {
|
||||||
|
$query->where('tmdb_id', '=', $person->tmdb_id);
|
||||||
|
})->exists()) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
$show->crewList()->attach($person, [
|
||||||
|
'known_for_department' => json_encode($crewPerson['known_for_department']),
|
||||||
|
'job' => $crewPerson['job'],
|
||||||
|
'department' => $crewPerson['department'],
|
||||||
|
'tmdb_cast_id' => $crewPerson['credit_id'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?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_alternative_titles', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('iso', 5)->nullable();
|
||||||
|
$table->string('title', 500)->nullable();
|
||||||
|
$table->integer('show_id')->unsigned()->nullable();
|
||||||
|
$table->string('type', 255)->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('show_alternative_titles');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?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_cast', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->bigInteger('show_id')->nullable(false);
|
||||||
|
$table->bigInteger('person_id')->nullable(false);
|
||||||
|
$table->string('known_for_department', 500)->nullable();
|
||||||
|
$table->string('character', 500)->nullable();
|
||||||
|
$table->string('tmdb_cast_id', 500);
|
||||||
|
$table->integer('order')->nullable();
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('show_cast');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?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_crew', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('show_id')->nullable(false);
|
||||||
|
$table->unsignedBigInteger('person_id')->nullable(false);
|
||||||
|
$table->string('known_for_department', 500);
|
||||||
|
$table->string('job', 500);
|
||||||
|
$table->string('department', 500);
|
||||||
|
$table->string('tmdb_cast_id', 500);
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('show_crew');
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user