diff --git a/src/Monitor/Action/Handler/MonitorTvEpisodeHandler.php b/src/Monitor/Action/Handler/MonitorTvEpisodeHandler.php index 4e50d8b..1b46df1 100644 --- a/src/Monitor/Action/Handler/MonitorTvEpisodeHandler.php +++ b/src/Monitor/Action/Handler/MonitorTvEpisodeHandler.php @@ -4,13 +4,13 @@ namespace App\Monitor\Action\Handler; use App\Download\Action\Command\DownloadMediaCommand; use App\Monitor\Action\Command\MonitorMovieCommand; -use App\Monitor\Action\Result\MonitorMovieResult; use App\Monitor\Action\Result\MonitorTvEpisodeResult; use App\Monitor\Framework\Repository\MonitorRepository; use App\Monitor\Service\MonitorOptionEvaluator; use App\Tmdb\Tmdb; use App\Torrentio\Action\Command\GetTvShowOptionsCommand; use App\Torrentio\Action\Handler\GetTvShowOptionsHandler; +use App\User\Dto\UserPreferencesFactory; use Carbon\Carbon; use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; @@ -35,59 +35,65 @@ readonly class MonitorTvEpisodeHandler implements HandlerInterface public function handle(CommandInterface $command): ResultInterface { - $this->logger->info('> [MonitorTvEpisodeHandler] Executing MonitorTvEpisodeHandler'); - $monitor = $this->monitorRepository->find($command->movieMonitorId); + try { + $monitor = $this->monitorRepository->find($command->movieMonitorId); + $this->logger->info('> [MonitorTvEpisodeHandler] Executing MonitorTvEpisodeHandler for ' . $monitor->getTitle() . ' season ' . $monitor->getSeason() . ' episode ' . $monitor->getEpisode()); - $episodeData = $this->tmdb->episodeDetails($monitor->getTmdbId(), $monitor->getSeason(), $monitor->getEpisode()); - if (Carbon::createFromTimestamp($episodeData->episodeAirDate) > Carbon::now()) { - $this->logger->info('> [MonitorTvEpisodeHandler] Episode has not aired yet, skipping for now'); - return new MonitorTvEpisodeResult( - status: 'OK', - result: [ - 'message' => 'No change', - 'monitor' => $monitor, - ] + $episodeData = $this->tmdb->episodeDetails($monitor->getTmdbId(), $monitor->getSeason(), $monitor->getEpisode()); + if (Carbon::createFromTimestamp($episodeData->episodeAirDate) > Carbon::today('UTC')) { + $this->logger->info('> [MonitorTvEpisodeHandler] ...Episode has not aired yet, skipping for now'); + return new MonitorTvEpisodeResult( + status: 'OK', + result: [ + 'message' => 'No change', + 'monitor' => $monitor, + ] + ); + } + + $monitor->setStatus('In Progress'); + $this->monitorRepository->getEntityManager()->flush(); + + $results = $this->getTvShowOptionsHandler->handle( + new GetTvShowOptionsCommand( + $monitor->getTmdbId(), + $monitor->getImdbId(), + $monitor->getSeason(), + $monitor->getEpisode() + ) ); - } - $monitor->setStatus('In Progress'); - $this->monitorRepository->getEntityManager()->flush(); + $this->logger->info('> [MonitorTvEpisodeHandler] ...Found ' . count($results->results) . ' total download options, beginning evaluation'); - $this->logger->info('> [MonitorTvEpisodeHandler] Searching for "' . $monitor->getTitle() . '" season ' . $monitor->getSeason() . ' episode ' . $monitor->getEpisode() . ' download options'); - $results = $this->getTvShowOptionsHandler->handle( - new GetTvShowOptionsCommand( - $monitor->getTmdbId(), - $monitor->getImdbId(), - $monitor->getSeason(), - $monitor->getEpisode() - ) - ); + $result = $this->monitorOptionEvaluator->evaluateOptions($monitor, $results->results); - $this->logger->info('> [MonitorTvEpisodeHandler] Found ' . count($results->results) . ' download options'); + if (null !== $result) { + $this->logger->info('> [MonitorTvEpisodeHandler] ...Found 1 matching result found: dispatching DownloadMediaCommand for "' . $result->title . '"', ['filter' => UserPreferencesFactory::createFromUser($monitor->getUser())]); + $this->bus->dispatch(new DownloadMediaCommand( + $result->url, + $monitor->getTitle(), + $result->filename, + 'tvshows', + $monitor->getImdbId(), + $monitor->getUser()->getId(), + )); + $monitor->setStatus('Complete'); + $monitor->setDownloadedAt(new DateTimeImmutable()); + } else { + $this->logger->info('> [MonitorTvEpisodeHandler] ...Found 0 matching results found, monitor will run at next interval'); + $monitor->setStatus('Active'); + } - $result = $this->monitorOptionEvaluator->evaluateOptions($monitor, $results->results); - - if (null !== $result) { - $this->logger->info('> [MonitorTvEpisodeHandler] 1 matching result found: dispatching DownloadMediaCommand for "' . $result->title . '"'); - $this->bus->dispatch(new DownloadMediaCommand( - $result->url, - $monitor->getTitle(), - $result->filename, - 'tvshows', - $monitor->getImdbId(), - $monitor->getUser()->getId(), - )); - $monitor->setStatus('Complete'); - $monitor->setDownloadedAt(new DateTimeImmutable()); - } else { - $this->logger->info('> [MonitorTvEpisodeHandler] 0 matching results found, monitor will run at next interval'); + $monitor->setLastSearch(new DateTimeImmutable()); + $monitor->setSearchCount($monitor->getSearchCount() + 1); + $this->entityManager->flush(); + } catch (\Throwable $exception) { + $this->logger->error('> [MonitorTvEpisodeHandler] ...Exception thrown: ' . $exception->getMessage()); + $this->logger->error($exception->getMessage()); $monitor->setStatus('Active'); + $this->monitorRepository->getEntityManager()->flush(); } - $monitor->setLastSearch(new DateTimeImmutable()); - $monitor->setSearchCount($monitor->getSearchCount() + 1); - $this->entityManager->flush(); - return new MonitorTvEpisodeResult( status: 'OK', result: [ diff --git a/src/Monitor/Action/Handler/MonitorTvShowHandler.php b/src/Monitor/Action/Handler/MonitorTvShowHandler.php index 6ea264c..c988ed8 100644 --- a/src/Monitor/Action/Handler/MonitorTvShowHandler.php +++ b/src/Monitor/Action/Handler/MonitorTvShowHandler.php @@ -61,26 +61,27 @@ readonly class MonitorTvShowHandler implements HandlerInterface // Dispatch Episode commands for each missing Episode foreach ($episodesInShow as $episode) { // Only monitor future episodes + $this->logger->info('> [MonitorTvShowHandler] Evaluating "' . $monitor->getTitle() . '", season "' . $episode['season_number'] . '" episode "' . $episode['episode_number'] . '"'); $episodeInFuture = $this->episodeReleasedAfterMonitorCreated($monitor->getCreatedAt(), $episode); - $this->logger->info('> [MonitorTvShowHandler] Episode released after monitor started for season ' . $episode['season_number'] . ' episode ' . $episode['episode_number'] . ' for title: ' . $monitor->getTitle() . ' ? ' . (true === $episodeInFuture ? 'YES' : 'NO')); + $this->logger->info('> [MonitorTvShowHandler] ...Released after monitor started? ' . (true === $episodeInFuture ? 'YES' : 'NO')); if (false === $episodeInFuture) { - $this->logger->info('> [MonitorTvShowHandler] Episode released after monitor started for title: ' . 'for season ' . $episode['season_number'] . ' episode ' . $episode['episode_number'] . ', skipping'); + $this->logger->info('> [MonitorTvShowHandler] ...Skipping'); continue; } // Check if the episode is already downloaded $episodeExists = $this->episodeExists($episode, $downloadedEpisodes); - $this->logger->info('> [MonitorTvShowHandler] Episode exists for season ' . $episode['season_number'] . ' episode ' . $episode['episode_number'] . ' for title: ' . $monitor->getTitle() . ' ? ' . (true === $episodeExists ? 'YES' : 'NO')); + $this->logger->info('> [MonitorTvShowHandler] ...Episode exists? ' . (true === $episodeExists ? 'YES' : 'NO')); if (true === $episodeExists) { - $this->logger->info('> [MonitorTvShowHandler] Episode exists for title: ' . $monitor->getTitle() . ', skipping'); + $this->logger->info('> [MonitorTvShowHandler] ...Skipping'); continue; } // Check for existing monitors $monitorExists = $this->monitorExists($monitor, $episode); - $this->logger->info('> [MonitorTvShowHandler] Monitor exists for season ' . $episode['season_number'] . ' episode ' . $episode['episode_number'] . ' for title: ' . $monitor->getTitle() . ' ? ' . (true === $monitorExists ? 'YES' : 'NO')); + $this->logger->info('> [MonitorTvShowHandler] ...Monitor exists? ' . (true === $monitorExists ? 'YES' : 'NO')); if (true === $monitorExists) { - $this->logger->info('> [MonitorTvShowHandler] Monitor exists for title: ' . $monitor->getTitle() . ', skipping'); + $this->logger->info('> [MonitorTvShowHandler] ...Skipping'); continue; } @@ -106,7 +107,7 @@ readonly class MonitorTvShowHandler implements HandlerInterface // Immediately run the monitor $command = new MonitorTvEpisodeCommand($episodeMonitor->getId()); $this->monitorTvEpisodeHandler->handle($command); - $this->logger->info('> [MonitorTvShowHandler] Dispatching MonitorTvEpisodeCommand for season ' . $episodeMonitor->getSeason() . ' episode ' . $episodeMonitor->getEpisode() . ' for title: ' . $monitor->getTitle()); + $this->logger->info('> [MonitorTvShowHandler] ...Dispatching MonitorTvEpisodeCommand'); } } diff --git a/src/User/Dto/UserPreferences.php b/src/User/Dto/UserPreferences.php new file mode 100644 index 0000000..3c9be5a --- /dev/null +++ b/src/User/Dto/UserPreferences.php @@ -0,0 +1,15 @@ +getUserPreference('resolution')->getPreferenceValue(), + codec: $user->getUserPreference('codec')->getPreferenceValue(), + language: $user->getUserPreference('language')->getPreferenceValue(), + provider: $user->getUserPreference('provider')->getPreferenceValue(), + quality: $user->getUserPreference('quality')->getPreferenceValue(), + ); + } +} diff --git a/src/User/Framework/Entity/User.php b/src/User/Framework/Entity/User.php index 60eec6d..ef3f1f1 100644 --- a/src/User/Framework/Entity/User.php +++ b/src/User/Framework/Entity/User.php @@ -153,13 +153,14 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface return $this->userPreferences; } - public function getUserPreference(string $preferenceName) + public function getUserPreference(string $preferenceName): ?UserPreference { foreach ($this->userPreferences as $userPreference) { if ($userPreference->getPreference()->getName() === $preferenceName) { - return $userPreference->getPreference(); + return $userPreference; } } + return null; } public function hasUserPreference(string $preferenceName): bool