416 lines
15 KiB
PHP
416 lines
15 KiB
PHP
<?php
|
|
|
|
namespace App\Service\MediaProcessing;
|
|
|
|
use App\Models\Genre;
|
|
use App\Models\Image;
|
|
use App\Models\ItemToFetchJobs;
|
|
use App\Models\Keyword;
|
|
use App\Models\Movie;
|
|
use App\Models\MovieAlternativeTitle;
|
|
use App\Models\MovieCollection;
|
|
use App\Models\Person;
|
|
use App\Models\ReleaseDate;
|
|
use App\Service\TMDBApi\MoviesApi;
|
|
use App\Service\TMDBApi\PersonApi;
|
|
use Illuminate\Support\Str;
|
|
|
|
class MovieProcessingService implements ProcessingInterface
|
|
{
|
|
private MoviesApi $moviesApi;
|
|
private PersonApi $personApi;
|
|
|
|
public function __construct(
|
|
MoviesApi $moviesApi,
|
|
PersonApi $personApi
|
|
) {
|
|
$this->moviesApi = $moviesApi;
|
|
$this->personApi = $personApi;
|
|
}
|
|
|
|
public function process($item, $job)
|
|
{
|
|
$methodName = "get".ucfirst($job);
|
|
|
|
if (!method_exists($this, $methodName)) {
|
|
// @todo maybe raise an exception here
|
|
return;
|
|
}
|
|
|
|
$this->$methodName($item);
|
|
}
|
|
|
|
private function getDetails($item)
|
|
{
|
|
$tmdbMovie = $this->moviesApi->getMovie($item->tmdb_id);
|
|
$tmdbMovie['tmdb_id'] = $tmdbMovie['id'];
|
|
|
|
$movie = Movie::where('tmdb_id', $tmdbMovie['tmdb_id'])->first();
|
|
|
|
if($movie) {
|
|
return;
|
|
}
|
|
|
|
$tmdbMovie['slug'] = Str::slug($tmdbMovie['title']);
|
|
|
|
$movieId = Movie::create($tmdbMovie);
|
|
|
|
if (!empty($tmdbMovie['belongs_to_collection'])) {
|
|
$this->processMovieCollection($movieId->id, $tmdbMovie['belongs_to_collection']);
|
|
}
|
|
|
|
if (!empty($tmdbMovie['genres'])) {
|
|
$this->processMovieGenres($movieId->id, $tmdbMovie['genres']);
|
|
}
|
|
|
|
$this->removeElementFromRemainingJobs($tmdbMovie['id'], 'Details');
|
|
}
|
|
|
|
private function getAlternativeTitles($item)
|
|
{
|
|
$alternativeTitles = $this->moviesApi->getAlternativeTitles($item->tmdb_id);
|
|
|
|
if (empty($alternativeTitles) || !isset($alternativeTitles['titles'])) {
|
|
return;
|
|
}
|
|
|
|
$movie = Movie::where('tmdb_id', $item->tmdb_id)->first();
|
|
|
|
foreach ($alternativeTitles['titles'] as $alternativeTitle) {
|
|
$alternativeTitleExists = MovieAlternativeTitle::where('movie_id', $movie->id)
|
|
->where('iso', $alternativeTitle['iso_3166_1'])
|
|
->first();
|
|
|
|
if (!$alternativeTitleExists) {
|
|
MovieAlternativeTitle::create([
|
|
'iso' => $alternativeTitle['iso_3166_1'],
|
|
'movie_id' => $movie->id,
|
|
'title' => $alternativeTitle['title'],
|
|
'type' => $alternativeTitle['type'],
|
|
]);
|
|
}
|
|
}
|
|
|
|
$this->removeElementFromRemainingJobs($item->tmdb_id, ItemToFetchJobs::JOB_ALTERNVATIVE_TITLES);
|
|
}
|
|
|
|
private function getCredits($item)
|
|
{
|
|
$tmdbCredits = $this->moviesApi->getCredits($item->tmdb_id);
|
|
|
|
if (empty($tmdbCredits)) {
|
|
return;
|
|
}
|
|
|
|
$movie = Movie::where('tmdb_id', $item->tmdb_id)->first();
|
|
|
|
$this->processCast($movie, $tmdbCredits['cast'] ?? []);
|
|
$this->processCrew($movie, $tmdbCredits['crew'] ?? []);
|
|
|
|
$this->removeElementFromRemainingJobs($item->tmdb_id, ItemToFetchJobs::JOB_CREDITS);
|
|
}
|
|
|
|
private function getImages($item)
|
|
{
|
|
$tmdbImages = $this->moviesApi->getImages($item->tmdb_id);
|
|
|
|
if (empty($tmdbImages)) {
|
|
return;
|
|
}
|
|
|
|
$movie = Movie::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 ($movie->whereHas('images', function ($query) use ($imageExists) {
|
|
$query->where('type', $imageExists->type)
|
|
->where('file_path', $imageExists->file_path);
|
|
})->exists()) {
|
|
echo "Movie has image | ";
|
|
return;
|
|
} else {
|
|
echo "Movie does not have image | ";
|
|
$movie->images()->attach($imageExists);
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->removeElementFromRemainingJobs($item->tmdb_id, ItemToFetchJobs::JOB_IMAGES);
|
|
}
|
|
|
|
private function getKeywords($item)
|
|
{
|
|
$tmdbKeywords = $this->moviesApi->getKeywords($item->tmdb_id);
|
|
|
|
if (empty($tmdbKeywords) || !isset($tmdbKeywords['keywords'])) {
|
|
return;
|
|
}
|
|
|
|
$movie = Movie::where('tmdb_id', $item->tmdb_id)->first();
|
|
|
|
foreach ($tmdbKeywords['keywords'] as $tmdbKeyword) {
|
|
$existingKeyword = Keyword::where('tmdb_id', $tmdbKeyword['id'])->first();
|
|
|
|
if (!$existingKeyword) {
|
|
$existingKeyword = Keyword::create([
|
|
'name' => $tmdbKeyword['name'],
|
|
'tmdb_id' => $tmdbKeyword['id'],
|
|
]);
|
|
}
|
|
|
|
if ($movie->whereHas('keywords', function ($query) use ($existingKeyword) {
|
|
$query->where('tmdb_id', $existingKeyword->tmdb_id);
|
|
})->exists()) {
|
|
echo "Movie has keyword | ";
|
|
return;
|
|
} else {
|
|
echo "Movie does not have keyword | ";
|
|
$movie->keywords()->attach($existingKeyword);
|
|
}
|
|
}
|
|
|
|
$this->removeElementFromRemainingJobs($item->tmdb_id, ItemToFetchJobs::JOB_KEYWORDS);
|
|
}
|
|
|
|
private function getReleases($item)
|
|
{
|
|
$tmdbReleases = $this->moviesApi->getReleases($item->tmdb_id);
|
|
|
|
if (empty($tmdbReleases) || !isset($tmdbReleases['countries'])) {
|
|
echo "[E] Movie ".$item->tmdb_id ." Releases ".json_encode($tmdbReleases)."\n\n";
|
|
return;
|
|
}
|
|
|
|
$movie = Movie::where('tmdb_id', $item->tmdb_id)->first();
|
|
|
|
echo "Movie ".$movie->id ." Releases ".json_encode($tmdbReleases)."\n\n";
|
|
|
|
foreach ($tmdbReleases['countries'] as $tmdbRelease) {
|
|
$existingReleaseDate = ReleaseDate::where('iso_3166', $tmdbRelease['iso_3166_1'])
|
|
->where('release_date', $tmdbRelease['release_date'])
|
|
->where('certification', $tmdbRelease['certification'])
|
|
->first();
|
|
|
|
|
|
if (!$existingReleaseDate) {
|
|
$existingReleaseDate = ReleaseDate::create([
|
|
'iso_3166' => $tmdbRelease['iso_3166_1'],
|
|
'certification' => $tmdbRelease['certification'],
|
|
'descriptors' => $tmdbRelease['descriptors'] ? json_encode($tmdbRelease['descriptors']) : null,
|
|
'release_date' => $tmdbRelease['release_date'],
|
|
]);
|
|
}
|
|
|
|
if ($movie->whereHas('releaseDates', function ($query) use ($movie) {
|
|
$query->where('movie_id', $movie->id);
|
|
})->exists()) {
|
|
echo "Movie has release date | ";
|
|
return;
|
|
} else {
|
|
echo "Movie does not have release date | ";
|
|
$movie->releaseDates()->attach($existingReleaseDate);
|
|
}
|
|
}
|
|
|
|
$this->removeElementFromRemainingJobs($item->tmdb_id, ItemToFetchJobs::JOB_RELEASES);
|
|
}
|
|
|
|
private function processMovieCollection(int $movieId, $belongsToCollection)
|
|
{
|
|
$movieCollection = MovieCollection::where('tmdb_id', $belongsToCollection['id'])->first();
|
|
|
|
if (!$movieCollection) {
|
|
$movieCollection = MovieCollection::create([
|
|
'name' => $belongsToCollection['name'],
|
|
'slug' => Str::slug($belongsToCollection['name']),
|
|
'poster_path' => $belongsToCollection['poster_path'],
|
|
'backdrop_path' => $belongsToCollection['backdrop_path'],
|
|
'tmdb_id' => $belongsToCollection['id'],
|
|
]);
|
|
}
|
|
|
|
$movie = Movie::find($movieId);
|
|
|
|
if ($movie->whereHas('collections', function ($query) use ($movieCollection) {
|
|
$query->where('tmdb_id', '=', $movieCollection->tmdb_id);
|
|
})->exists()) {
|
|
echo "Movie is in the collection";
|
|
return;
|
|
} else {
|
|
echo "Movie is not in the collection";
|
|
$movie->collections()->attach($movieCollection);
|
|
}
|
|
|
|
}
|
|
|
|
private function processMovieGenres(int $movieId, array $tmdbGenres)
|
|
{
|
|
foreach ($tmdbGenres as $tmdbGenre) {
|
|
$genre = Genre::where('name', $tmdbGenre['name'])
|
|
->where('tmdb_id', $tmdbGenre['id'])
|
|
->first();
|
|
|
|
if (!$genre) {
|
|
$genre = Genre::create([
|
|
'name' => $tmdbGenre['name'],
|
|
'slug' => Str::slug($tmdbGenre['name']),
|
|
'tmdb_id' => $tmdbGenre['id'],
|
|
'type' => Genre::TYPE_MOVIE,
|
|
]);
|
|
}
|
|
|
|
$movie = Movie::find($movieId);
|
|
|
|
if ($movie->whereHas('genres', function ($query) use ($genre) {
|
|
$query->where('tmdb_id', '=', $genre->tmdb_id);
|
|
})->exists()) {
|
|
echo "Movie is in the genre";
|
|
return;
|
|
} else {
|
|
echo "Movie is not in the genre";
|
|
$movie->genres()->attach($genre);
|
|
}
|
|
}
|
|
}
|
|
|
|
private function removeElementFromRemainingJobs(int $tmdbId, string $job)
|
|
{
|
|
$itemToFetchJobs = ItemToFetchJobs::where('tmdb_id', $tmdbId)->first();
|
|
|
|
$remainingJobs = $itemToFetchJobs->remaining_jobs;
|
|
$remainingJobKey = array_search($job, $remainingJobs);
|
|
|
|
unset($remainingJobs[$remainingJobKey]);
|
|
|
|
if (empty($remainingJobs)) {
|
|
$itemToFetchJobs->delete();
|
|
}
|
|
|
|
$itemToFetchJobs->remaining_jobs = $remainingJobs;
|
|
$itemToFetchJobs->save();
|
|
}
|
|
|
|
private function processCast($movie, array $castList)
|
|
{
|
|
if (empty($castList)) {
|
|
return;
|
|
}
|
|
|
|
foreach ($castList 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 ($movie->whereHas('castList', function ($query) use ($person) {
|
|
$query->where('tmdb_id', '=', $person->tmdb_id);
|
|
})->exists()) {
|
|
echo "Person is in cast | ";
|
|
return;
|
|
} else {
|
|
echo "Person is not in cast |";
|
|
$movie->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($movie, array $crewList)
|
|
{
|
|
if (empty($crewList)) {
|
|
return;
|
|
}
|
|
|
|
foreach ($crewList 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 ($movie->whereHas('crewList', function ($query) use ($person) {
|
|
$query->where('tmdb_id', '=', $person->tmdb_id);
|
|
})->exists()) {
|
|
echo "Person is in crew | ";
|
|
return;
|
|
} else {
|
|
echo "Person is not in crew |";
|
|
$movie->castList()->attach($person, [
|
|
'known_for_department' => json_encode($crewPerson['known_for_department']),
|
|
'job' => $crewPerson['job'],
|
|
'department' => $crewPerson['department'],
|
|
'tmdb_cast_id' => $crewPerson['credit_id'],
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|