diff --git a/settings/psalm.xml b/settings/psalm.xml index ecee9f91..d95ddba4 100644 --- a/settings/psalm.xml +++ b/settings/psalm.xml @@ -5,7 +5,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config ../vendor/vimeo/psalm/config.xsd" - cacheDirectory="../tmp/cache/psalm" > diff --git a/settings/routes.php b/settings/routes.php index d6db5873..2ff226cd 100644 --- a/settings/routes.php +++ b/settings/routes.php @@ -47,16 +47,6 @@ '/{username:[a-zA-Z0-9]+}/movies', [\Movary\HttpController\MoviesController::class, 'renderPage'] ); - $routeCollector->addRoute( - 'POST', - '/refresh-trakt', - [\Movary\HttpController\SyncTraktController::class, 'execute'] - ); - $routeCollector->addRoute( - 'POST', - '/refresh-tmdb', - [\Movary\HttpController\SyncTmdbController::class, 'execute'] - ); $routeCollector->addRoute( 'POST', '/login', diff --git a/src/Api/Tmdb/Cache/TmdbImageCache.php b/src/Api/Tmdb/Cache/TmdbImageCache.php index 9f3f86fd..aeb1d9f6 100644 --- a/src/Api/Tmdb/Cache/TmdbImageCache.php +++ b/src/Api/Tmdb/Cache/TmdbImageCache.php @@ -4,6 +4,7 @@ use Movary\Api\Tmdb\TmdbUrlGenerator; use Movary\Application\Service\ImageCacheService; +use Movary\ValueObject\Job; class TmdbImageCache { @@ -14,10 +15,33 @@ public function __construct( ) { } + public function cacheAllImagesByMovieId(int $movieId, bool $forceRefresh = false) : void + { + $this->cacheImages('movie', $forceRefresh, [$movieId]); + + $statement = $this->pdo->prepare( + "SELECT DISTINCT (id) + FROM ( + SELECT id + FROM person + JOIN movie_cast cast on person.id = cast.person_id + WHERE cast.movie_id = ? + UNION + SELECT id + FROM person + JOIN movie_crew crew on person.id = crew.person_id + WHERE crew.movie_id = ? + ) personIdTable" + ); + $statement->execute([$movieId, $movieId]); + + $this->cacheImages('person', $forceRefresh, array_column($statement->fetchAll(), 'id')); + } + /** * @return int Count of newly cached images */ - public function cacheMovieImages(bool $forceRefresh = false) : int + public function cacheAllMovieImages(bool $forceRefresh = false) : int { return $this->cacheImages('movie', $forceRefresh); } @@ -25,7 +49,7 @@ public function cacheMovieImages(bool $forceRefresh = false) : int /** * @return int Count of newly cached images */ - public function cachePersonImages(bool $forceRefresh = false) : int + public function cacheAllPersonImages(bool $forceRefresh = false) : int { return $this->cacheImages('person', $forceRefresh); } @@ -33,36 +57,62 @@ public function cachePersonImages(bool $forceRefresh = false) : int public function deleteCache() : void { $this->imageCacheService->deleteImages(); + $this->pdo->prepare('UPDATE movie SET poster_path = null')->execute(); + $this->pdo->prepare('UPDATE person SET poster_path = null')->execute(); + } + + public function executeJob(Job $job) : void + { + $movieIds = $job->getParameters()['movieIds'] ?? []; + + foreach ($movieIds as $movieId) { + $this->cacheAllImagesByMovieId($movieId); + } } /** - * @return int Count of newly cached images + * @return bool True if image cache was re/generated, false otherwise */ - private function cacheImages(string $tableName, bool $forceRefresh) : int + private function cacheImageDataByTableName(array $data, string $tableName, bool $forceRefresh = false) : bool { - $cachedImages = 0; + if ($data['tmdb_poster_path'] === null) { + return false; + } - $statement = $this->pdo->prepare("SELECT id, tmdb_poster_path FROM $tableName"); - $statement->execute(); + $cachedImagePublicPath = $this->imageCacheService->cacheImage( + $this->tmdbUrlGenerator->generateImageUrl($data['tmdb_poster_path']), + $forceRefresh + ); - foreach ($statement->getIterator() as $row) { - if ($row['tmdb_poster_path'] === null) { - continue; - } + if ($cachedImagePublicPath === null) { + return false; + } - $cachedImagePublicPath = $this->imageCacheService->cacheImage( - $this->tmdbUrlGenerator->generateImageUrl($row['tmdb_poster_path']), - $forceRefresh - ); + $payload = [$cachedImagePublicPath, $data['id']]; - if ($cachedImagePublicPath === null) { - continue; - } + return $this->pdo->prepare("UPDATE $tableName SET poster_path = ? WHERE id = ?")->execute($payload); + } - $payload = [$cachedImagePublicPath, $row['id']]; - $this->pdo->prepare("UPDATE $tableName SET poster_path = ? WHERE id = ?")->execute($payload); + /** + * @return int Count of re/generated cached images + */ + private function cacheImages(string $tableName, bool $forceRefresh, array $filerIds = []) : int + { + $cachedImages = 0; + + $query = "SELECT id, tmdb_poster_path FROM $tableName"; + if (count($filerIds) > 0) { + $placeholders = str_repeat('?, ', count($filerIds)); + $query .= ' WHERE id IN (' . trim($placeholders, ', ') . ')'; + } - $cachedImages++; + $statement = $this->pdo->prepare($query); + $statement->execute($filerIds); + + foreach ($statement->getIterator() as $row) { + if ($this->cacheImageDataByTableName($row, $tableName, $forceRefresh) === true) { + $cachedImages++; + } } return $cachedImages; diff --git a/src/Application/Service/ImageCacheService.php b/src/Application/Service/ImageCacheService.php index b6e9be8d..9f22a3b5 100644 --- a/src/Application/Service/ImageCacheService.php +++ b/src/Application/Service/ImageCacheService.php @@ -55,6 +55,6 @@ public function cacheImage(Url $imageUrl, bool $forceRefresh = false) : ?string public function deleteImages() : void { - $this->fileUtil->deleteDirectoryRecursively(self::CACHE_DIR); + $this->fileUtil->deleteDirectoryContent(self::CACHE_DIR); } } diff --git a/src/Application/Service/Tmdb/SyncMovie.php b/src/Application/Service/Tmdb/SyncMovie.php index 5a48fa6a..311336ad 100644 --- a/src/Application/Service/Tmdb/SyncMovie.php +++ b/src/Application/Service/Tmdb/SyncMovie.php @@ -6,6 +6,7 @@ use Movary\Api\Tmdb; use Movary\Application\Movie; use Movary\ValueObject\Date; +use Movary\Worker\JobScheduler; class SyncMovie { @@ -14,7 +15,8 @@ public function __construct( private readonly Movie\Api $movieApi, private readonly GenreConverter $genreConverter, private readonly ProductionCompanyConverter $productionCompanyConverter, - private readonly Connection $dbConnection + private readonly Connection $dbConnection, + private readonly JobScheduler $jobScheduler, ) { } @@ -40,7 +42,11 @@ public function syncMovie(int $tmdbId) : Movie\Entity tmdbPosterPath: $tmdbMovie->getPosterPath(), imdbId: $tmdbMovie->getImdbId(), ); + + $this->jobScheduler->storeMovieIdForTmdbImageCacheJob($movie->getId()); } else { + $originalPosterPath = $movie->getPosterPath(); + $movie = $this->movieApi->updateDetails( movieId: $movie->getId(), tagline: $tmdbMovie->getTagline(), @@ -53,6 +59,10 @@ public function syncMovie(int $tmdbId) : Movie\Entity tmdbPosterPath: $tmdbMovie->getPosterPath(), imdbId: $movie->getImdbId(), ); + + if ($originalPosterPath !== $movie->getPosterPath()) { + $this->jobScheduler->storeMovieIdForTmdbImageCacheJob($movie->getId()); + } } $this->movieApi->updateGenres($movie->getId(), $this->genreConverter->getMovaryGenresFromTmdbMovie($tmdbMovie)); diff --git a/src/Command/ImdbSync.php b/src/Command/ImdbSync.php index 21a2c8e0..a2c5ecac 100644 --- a/src/Command/ImdbSync.php +++ b/src/Command/ImdbSync.php @@ -4,7 +4,7 @@ use Movary\Application\Service\Imdb\SyncMovies; use Movary\ValueObject\JobStatus; -use Movary\Worker\Service; +use Movary\Worker\JobScheduler; use Psr\Log\LoggerInterface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -20,7 +20,7 @@ class ImdbSync extends Command public function __construct( private readonly SyncMovies $syncMovieDetails, - private readonly Service $workerService, + private readonly JobScheduler $jobScheduler, private readonly LoggerInterface $logger, ) { parent::__construct(); @@ -47,7 +47,7 @@ protected function execute(InputInterface $input, OutputInterface $output) : int $this->syncMovieDetails->syncMovies($maxAgeInHours, $movieCountSyncThreshold); - $this->workerService->addImdbSyncJob(JobStatus::createDone()); + $this->jobScheduler->addImdbSyncJob(JobStatus::createDone()); $this->generateOutput($output, 'Syncing imdb movie ratings done.'); } catch (\Throwable $t) { diff --git a/src/Command/TmdbImageCacheRefresh.php b/src/Command/TmdbImageCacheRefresh.php index 3e8a27f7..563993d1 100644 --- a/src/Command/TmdbImageCacheRefresh.php +++ b/src/Command/TmdbImageCacheRefresh.php @@ -80,7 +80,7 @@ private function cacheMovieImages(OutputInterface $output, bool $forceRefresh = { $this->generateOutput($output, 'Caching movie images...'); - $cachedImageCount = $this->imageCacheService->cacheMovieImages($forceRefresh); + $cachedImageCount = $this->imageCacheService->cacheAllMovieImages($forceRefresh); $this->generateOutput($output, "Cached [$cachedImageCount] movie images."); } @@ -89,7 +89,7 @@ private function cachePersonImages(OutputInterface $output, bool $forceRefresh = { $this->generateOutput($output, 'Caching person images...'); - $cachedImageCount = $this->imageCacheService->cachePersonImages($forceRefresh); + $cachedImageCount = $this->imageCacheService->cacheAllPersonImages($forceRefresh); $this->generateOutput($output, "Cached [$cachedImageCount] person images."); } diff --git a/src/Command/TmdbSync.php b/src/Command/TmdbSync.php index 03a73ec8..45f1caf3 100644 --- a/src/Command/TmdbSync.php +++ b/src/Command/TmdbSync.php @@ -4,7 +4,7 @@ use Movary\Application\Service\Tmdb\SyncMovies; use Movary\ValueObject\JobStatus; -use Movary\Worker\Service; +use Movary\Worker\JobScheduler; use Psr\Log\LoggerInterface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -20,7 +20,7 @@ class TmdbSync extends Command public function __construct( private readonly SyncMovies $syncMovieDetails, - private readonly Service $workerService, + private readonly JobScheduler $jobScheduler, private readonly LoggerInterface $logger, ) { parent::__construct(); @@ -47,7 +47,7 @@ protected function execute(InputInterface $input, OutputInterface $output) : int $this->syncMovieDetails->syncMovies($maxAgeInHours, $movieCountSyncThreshold); - $this->workerService->addTmdbSyncJob(JobStatus::createDone()); + $this->jobScheduler->addTmdbSyncJob(JobStatus::createDone()); $this->generateOutput($output, 'Syncing movie meta data done.'); } catch (\Throwable $t) { diff --git a/src/Command/TraktImport.php b/src/Command/TraktImport.php index 2ecf643e..6725e548 100644 --- a/src/Command/TraktImport.php +++ b/src/Command/TraktImport.php @@ -7,7 +7,7 @@ use Movary\Application\Service\Trakt\ImportRatings; use Movary\Application\Service\Trakt\ImportWatchedMovies; use Movary\ValueObject\JobStatus; -use Movary\Worker\Service; +use Movary\Worker\JobScheduler; use Psr\Log\LoggerInterface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -30,7 +30,7 @@ class TraktImport extends Command public function __construct( private readonly ImportRatings $importRatings, private readonly ImportWatchedMovies $importWatchedMovies, - private readonly Service $workerService, + private readonly JobScheduler $jobScheduler, private readonly LoggerInterface $logger, ) { parent::__construct(); @@ -39,11 +39,11 @@ public function __construct( protected function configure() : void { $this->setDescription('Import trakt.tv movie history and rating with local database.') - ->addOption(self::OPTION_NAME_USER_ID, [], InputOption::VALUE_REQUIRED, 'Id of user to import to.') - ->addOption(self::OPTION_NAME_HISTORY, [], InputOption::VALUE_NONE, 'Import movie history.') - ->addOption(self::OPTION_NAME_RATINGS, [], InputOption::VALUE_NONE, 'Import movie ratings.') - ->addOption(self::OPTION_NAME_OVERWRITE, [], InputOption::VALUE_NONE, 'Overwrite local data.') - ->addOption(self::OPTION_NAME_IGNORE_CACHE, [], InputOption::VALUE_NONE, 'Ignore trakt cache and force import everything.'); + ->addOption(self::OPTION_NAME_USER_ID, [], InputOption::VALUE_REQUIRED, 'Id of user to import to.') + ->addOption(self::OPTION_NAME_HISTORY, [], InputOption::VALUE_NONE, 'Import movie history.') + ->addOption(self::OPTION_NAME_RATINGS, [], InputOption::VALUE_NONE, 'Import movie ratings.') + ->addOption(self::OPTION_NAME_OVERWRITE, [], InputOption::VALUE_NONE, 'Overwrite local data.') + ->addOption(self::OPTION_NAME_IGNORE_CACHE, [], InputOption::VALUE_NONE, 'Ignore trakt cache and force import everything.'); } protected function execute(InputInterface $input, OutputInterface $output) : int @@ -96,7 +96,7 @@ private function importHistory(OutputInterface $output, int $userId, bool $overw $this->importWatchedMovies->execute($userId, $overwriteExistingData, $ignoreCache); - $this->workerService->addTraktImportHistoryJob($userId, JobStatus::createDone()); + $this->jobScheduler->addTraktImportHistoryJob($userId, JobStatus::createDone()); $this->generateOutput($output, 'Importing history done.'); } @@ -107,7 +107,7 @@ private function importRatings(OutputInterface $output, int $userId, bool $overw $this->importRatings->execute($userId, $overwriteExistingData); - $this->workerService->addTraktImportRatingsJob($userId, JobStatus::createDone()); + $this->jobScheduler->addTraktImportRatingsJob($userId, JobStatus::createDone()); $this->generateOutput($output, 'Importing ratings ratings.'); } diff --git a/src/HttpController/JobController.php b/src/HttpController/JobController.php index 5a1d421d..c6bb290b 100644 --- a/src/HttpController/JobController.php +++ b/src/HttpController/JobController.php @@ -9,6 +9,7 @@ use Movary\ValueObject\Http\Request; use Movary\ValueObject\Http\Response; use Movary\ValueObject\Http\StatusCode; +use Movary\Worker\JobScheduler; use Movary\Worker\Service; use Twig\Environment; @@ -17,6 +18,7 @@ class JobController public function __construct( private readonly Authentication $authenticationService, private readonly Service $workerService, + private readonly JobScheduler $jobScheduler, private readonly ImportHistoryFileValidator $letterboxdImportHistoryFileValidator, private readonly ImportRatingsFileValidator $letterboxdImportRatingsFileValidator, private readonly Environment $twig, @@ -67,7 +69,7 @@ public function scheduleLetterboxdHistoryImport(Request $request) : Response ); } - $this->workerService->addLetterboxdImportHistoryJob($userId, $targetFile); + $this->jobScheduler->addLetterboxdImportHistoryJob($userId, $targetFile); $_SESSION['letterboxdHistorySyncSuccessful'] = true; @@ -111,7 +113,7 @@ public function scheduleLetterboxdRatingsImport(Request $request) : Response ); } - $this->workerService->addLetterboxdImportRatingsJob($userId, $targetFile); + $this->jobScheduler->addLetterboxdImportRatingsJob($userId, $targetFile); $_SESSION['letterboxdRatingsSyncSuccessful'] = true; @@ -128,7 +130,7 @@ public function scheduleTraktHistorySync() : Response return Response::createFoundRedirect('/'); } - $this->workerService->addTraktImportHistoryJob($this->authenticationService->getCurrentUserId()); + $this->jobScheduler->addTraktImportHistoryJob($this->authenticationService->getCurrentUserId()); $_SESSION['scheduledTraktHistoryImport'] = true; @@ -145,7 +147,7 @@ public function scheduleTraktRatingsSync() : Response return Response::createFoundRedirect('/'); } - $this->workerService->addTraktImportRatingsJob($this->authenticationService->getCurrentUserId()); + $this->jobScheduler->addTraktImportRatingsJob($this->authenticationService->getCurrentUserId()); $_SESSION['scheduledTraktRatingsImport'] = true; diff --git a/src/HttpController/SyncTmdbController.php b/src/HttpController/SyncTmdbController.php deleted file mode 100644 index 457fd6b0..00000000 --- a/src/HttpController/SyncTmdbController.php +++ /dev/null @@ -1,23 +0,0 @@ -authenticationService->isUserAuthenticated() === false) { - return Response::createFoundRedirect('/'); - } - - throw new \RuntimeException('Not implemented yet'); - } -} diff --git a/src/HttpController/SyncTraktController.php b/src/HttpController/SyncTraktController.php deleted file mode 100644 index d8430a08..00000000 --- a/src/HttpController/SyncTraktController.php +++ /dev/null @@ -1,23 +0,0 @@ -authenticationService->isUserAuthenticated() === false) { - return Response::createFoundRedirect('/'); - } - - throw new \RuntimeException('Not implemented yet'); - } -} diff --git a/src/Util/File.php b/src/Util/File.php index 7c09cc2b..0e59cfc9 100644 --- a/src/Util/File.php +++ b/src/Util/File.php @@ -23,7 +23,7 @@ public function createFile(string $filename, string $data) : void file_put_contents($filename, $data); } - public function deleteDirectoryRecursively(string $path) : void + public function deleteDirectoryContent(string $path) : void { $files = glob(rtrim($path, '/') . '/*'); @@ -33,7 +33,26 @@ public function deleteDirectoryRecursively(string $path) : void foreach ($files as $file) { if (is_dir($file) === true) { - $this->deleteDirectoryRecursively($file); + $this->deleteDirectoryContentRecursively($file); + + continue; + } + + unlink($file); + } + } + + public function deleteDirectoryContentRecursively(string $path) : void + { + $files = glob(rtrim($path, '/') . '/*'); + + if ($files === false) { + throw new \RuntimeException('Could not get files in directory: ' . $path); + } + + foreach ($files as $file) { + if (is_dir($file) === true) { + $this->deleteDirectoryContentRecursively($file); continue; } diff --git a/src/ValueObject/JobType.php b/src/ValueObject/JobType.php index 2b0a251f..f3b70084 100644 --- a/src/ValueObject/JobType.php +++ b/src/ValueObject/JobType.php @@ -10,6 +10,8 @@ class JobType private const TYPE_LETTERBOXD_IMPORT_RATINGS = 'letterboxd_import_ratings'; + private const TYPE_TMDB_IMAGE_CHACHE = 'tmdb_image_cache'; + private const TYPE_TMDB_SYNC = 'tmdb_sync'; private const TYPE_TRAKT_IMPORT_HISTORY = 'trakt_import_history'; @@ -21,6 +23,7 @@ private function __construct(private readonly string $type) if (in_array($this->type, [ self::TYPE_LETTERBOXD_IMPORT_HISTORY, self::TYPE_LETTERBOXD_IMPORT_RATINGS, + self::TYPE_TMDB_IMAGE_CHACHE, self::TYPE_TMDB_SYNC, self::TYPE_TRAKT_IMPORT_HISTORY, self::TYPE_TRAKT_IMPORT_RATINGS, @@ -50,6 +53,11 @@ public static function createLetterboxdImportRatings() : self return new self(self::TYPE_LETTERBOXD_IMPORT_RATINGS); } + public static function createTmdbImageCache() : self + { + return new self(self::TYPE_TMDB_IMAGE_CHACHE); + } + public static function createTmdbSync() : self { return new self(self::TYPE_TMDB_SYNC); @@ -80,6 +88,11 @@ public function isOfTypeLetterboxdImportRankings() : bool return $this->type === self::TYPE_LETTERBOXD_IMPORT_RATINGS; } + public function isOfTypeTmdbImageCache() : bool + { + return $this->type === self::TYPE_TMDB_IMAGE_CHACHE; + } + public function isOfTypeTmdbSync() : bool { return $this->type === self::TYPE_TMDB_SYNC; diff --git a/src/Worker/JobScheduler.php b/src/Worker/JobScheduler.php new file mode 100644 index 00000000..1ed6e51d --- /dev/null +++ b/src/Worker/JobScheduler.php @@ -0,0 +1,71 @@ +scheduledMovieIdsForImageCacheJob) === 0) { + return; + } + + $this->addTmdbImageCacheJob(array_keys($this->scheduledMovieIdsForImageCacheJob)); + } + + public function addImdbSyncJob(JobStatus $jobStatus) : void + { + $this->repository->addJob(JobType::createImdbSync(), $jobStatus); + } + + public function addLetterboxdImportHistoryJob(int $userId, string $importFile) : void + { + $this->repository->addJob(JobType::createLetterboxdImportHistory(), JobStatus::createWaiting(), $userId, ['importFile' => $importFile]); + } + + public function addLetterboxdImportRatingsJob(int $userId, string $importFile) : void + { + $this->repository->addJob(JobType::createLetterboxdImportRatings(), JobStatus::createWaiting(), $userId, ['importFile' => $importFile]); + } + + public function addTmdbImageCacheJob(array $movieIds = []) : void + { + $this->repository->addJob(JobType::createTmdbImageCache(), JobStatus::createWaiting(), parameters: ['movieIds' => $movieIds]); + } + + public function addTmdbSyncJob(JobStatus $jobStatus) : void + { + $this->repository->addJob(JobType::createTmdbSync(), $jobStatus); + } + + public function addTraktImportHistoryJob(int $userId, ?JobStatus $jobStatus = null) : void + { + $this->repository->addJob(JobType::createTraktImportHistory(), $jobStatus ?? JobStatus::createWaiting(), $userId); + } + + public function addTraktImportRatingsJob(int $userId, ?JobStatus $jobStatus = null) : void + { + $this->repository->addJob(JobType::createTraktImportRatings(), $jobStatus ?? JobStatus::createWaiting(), $userId); + } + + public function storeMovieIdForTmdbImageCacheJob(int $movieId) : void + { + if (count($this->scheduledMovieIdsForImageCacheJob) >= self::IMAGE_CACHE_MOVIE_ID_BATCH_LIMIT) { + $this->addTmdbImageCacheJob(array_keys($this->scheduledMovieIdsForImageCacheJob)); + $this->scheduledMovieIdsForImageCacheJob = []; + } + + $this->scheduledMovieIdsForImageCacheJob[$movieId] = true; + } +} diff --git a/src/Worker/Service.php b/src/Worker/Service.php index 5d152655..bc10328e 100644 --- a/src/Worker/Service.php +++ b/src/Worker/Service.php @@ -2,6 +2,7 @@ namespace Movary\Worker; +use Movary\Api\Tmdb\Cache\TmdbImageCache; use Movary\Application\Service\Letterboxd; use Movary\Application\Service\Tmdb\SyncMovies; use Movary\Application\Service\Trakt; @@ -21,39 +22,10 @@ public function __construct( private readonly Letterboxd\ImportHistory $letterboxdImportHistory, private readonly SyncMovies $tmdbSyncMovies, private readonly Api $userApi, + private readonly TmdbImageCache $tmdbImageCache, ) { } - public function addLetterboxdImportHistoryJob(int $userId, string $importFile) : void - { - $this->repository->addJob(JobType::createLetterboxdImportHistory(), JobStatus::createWaiting(), $userId, ['importFile' => $importFile]); - } - - public function addLetterboxdImportRatingsJob(int $userId, string $importFile) : void - { - $this->repository->addJob(JobType::createLetterboxdImportRatings(), JobStatus::createWaiting(), $userId, ['importFile' => $importFile]); - } - - public function addTmdbSyncJob(JobStatus $jobStatus) : void - { - $this->repository->addJob(JobType::createTmdbSync(), $jobStatus); - } - - public function addImdbSyncJob(JobStatus $jobStatus) : void - { - $this->repository->addJob(JobType::createImdbSync(), $jobStatus); - } - - public function addTraktImportHistoryJob(int $userId, ?JobStatus $jobStatus = null) : void - { - $this->repository->addJob(JobType::createTraktImportHistory(), $jobStatus ?? JobStatus::createWaiting(), $userId); - } - - public function addTraktImportRatingsJob(int $userId, ?JobStatus $jobStatus = null) : void - { - $this->repository->addJob(JobType::createTraktImportRatings(), $jobStatus ?? JobStatus::createWaiting(), $userId); - } - public function fetchJobsForStatusPage(int $userId) : array { $jobs = $this->repository->fetchJobs($userId); @@ -104,6 +76,7 @@ public function processJob(Job $job) : void match (true) { $job->getType()->isOfTypeLetterboxdImportRankings() => $this->letterboxdImportRatings->executeJob($job), $job->getType()->isOfTypeLetterboxdImportHistory() => $this->letterboxdImportHistory->executeJob($job), + $job->getType()->isOfTypeTmdbImageCache() => $this->tmdbImageCache->executeJob($job), $job->getType()->isOfTypeTraktImportRatings() => $this->traktSyncRatings->executeJob($job), $job->getType()->isOfTypeTraktImportHistory() => $this->traktSyncWatchedMovies->executeJob($job), $job->getType()->isOfTypeTmdbSync() => $this->tmdbSyncMovies->syncMovies(),