*/ readonly class MonitorTvEpisodeHandler implements HandlerInterface { public function __construct( private GetTvShowOptionsHandler $getTvShowOptionsHandler, private DownloadOptionEvaluator $downloadOptionEvaluator, private EntityManagerInterface $entityManager, private MessageBusInterface $bus, private LoggerInterface $logger, private MonitorRepository $monitorRepository, private Tmdb $tmdb, ) {} public function handle(CommandInterface $command): ResultInterface { 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::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() ) ); $this->logger->info('> [MonitorTvEpisodeHandler] ...Found ' . count($results->results) . ' total download options, beginning evaluation'); $result = $this->downloadOptionEvaluator->evaluateOptions($results->results, UserPreferencesFactory::createFromUser($monitor->getUser())); if (null !== $result) { $this->logger->info('> [MonitorTvEpisodeHandler] ...Found 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] ...Found 0 matching results found, monitor will run at next interval'); $monitor->setStatus('Active'); } } catch (\Throwable $exception) { $this->logger->error('> [MonitorTvEpisodeHandler] ...Exception thrown: ' . $exception->getMessage()); $this->logger->error($exception->getMessage()); $monitor->setStatus('Active'); } $monitor->setLastSearch(new DateTimeImmutable()); $monitor->setSearchCount($monitor->getSearchCount() + 1); $this->monitorRepository->getEntityManager()->flush(); return new MonitorTvEpisodeResult( status: 'OK', result: [ 'monitor' => $monitor, ] ); } }