From b95e8f379479d6a4d966e817c3ea280f133edfb1 Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Wed, 11 Jun 2025 10:24:58 -0500 Subject: [PATCH] fix: tvshow monitor --- .../Action/Handler/MonitorTvShowHandler.php | 99 ++++++++++++------- src/Twig/Components/MonitorList.php | 2 +- 2 files changed, 66 insertions(+), 35 deletions(-) diff --git a/src/Monitor/Action/Handler/MonitorTvShowHandler.php b/src/Monitor/Action/Handler/MonitorTvShowHandler.php index 795b7e1..ab2b5ea 100644 --- a/src/Monitor/Action/Handler/MonitorTvShowHandler.php +++ b/src/Monitor/Action/Handler/MonitorTvShowHandler.php @@ -38,13 +38,21 @@ readonly class MonitorTvShowHandler implements HandlerInterface // Check current episodes $downloadedEpisodes = $this->mediaFiles ->getEpisodes($monitor->getTitle()) - ->map(fn($episode) => (object) (new PTN())->parse($episode)); + ->map(fn($episode) => (object) (new PTN())->parse($episode)) + ->filter(fn ($episode) => + property_exists($episode, 'episode') + && property_exists($episode, 'season') + && null !== $episode->episode + && null !== $episode->season + ) + ; $this->logger->info('> [MonitorTvShowHandler] Found ' . count($downloadedEpisodes) . ' downloaded episodes for title: ' . $monitor->getTitle()); // Compare against list from TMDB $episodesInShow = Map::from( $this->tmdb->tvDetails($monitor->getTmdbId())->episodes )->flat(1); + $this->logger->info('> [MonitorTvShowHandler] Found ' . count($episodesInShow) . ' episodes for title: ' . $monitor->getTitle()); if ($downloadedEpisodes->count() !== $episodesInShow->count()) { @@ -54,40 +62,43 @@ readonly class MonitorTvShowHandler implements HandlerInterface // Dispatch Episode commands for each missing Episode foreach ($episodesInShow as $episode) { - $monitorCheck = $this->monitorRepository->findOneBy([ - 'imdbId' => $monitor->getImdbId(), - 'title' => $monitor->getTitle(), - 'monitorType' => 'tvepisode', - 'season' => $monitor->getSeason(), - 'episode' => $episode['episode_number'], - 'status' => ['New', 'Active', 'In Progress'] - ]); - - $this->logger->info('> [MonitorTvShowHandler] Monitor exists for season ' . $monitor->getSeason() . ' episode ' . $episode['episode_number'] . ' for title: ' . $monitor->getTitle() . ' ? ' . (null !== $monitorCheck ? 'YES' : 'NO')); - - if (!array_key_exists($episode['episode_number'], $downloadedEpisodes->toArray()) - && null === $monitorCheck - ) { - $episodeMonitor = (new Monitor()) - ->setParent($monitor) - ->setUser($monitor->getUser()) - ->setTmdbId($monitor->getTmdbId()) - ->setImdbId($monitor->getImdbId()) - ->setTitle($monitor->getTitle()) - ->setMonitorType('tvepisode') - ->setSeason($monitor->getSeason()) - ->setEpisode($episode['episode_number']) - ->setCreatedAt(new DateTimeImmutable()) - ->setSearchCount(0) - ->setStatus('New'); - - $this->monitorRepository->getEntityManager()->persist($episodeMonitor); - $this->monitorRepository->getEntityManager()->flush(); - - $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()); + // 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')); + if (true === $episodeExists) { + $this->logger->info('> [MonitorTvShowHandler] Episode exists for title: ' . $monitor->getTitle() . ', 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')); + if (true === $monitorExists) { + $this->logger->info('> [MonitorTvShowHandler] Monitor exists for title: ' . $monitor->getTitle() . ', skipping'); + continue; + } + + // Create the monitor + $episodeMonitor = (new Monitor()) + ->setParent($monitor) + ->setUser($monitor->getUser()) + ->setTmdbId($monitor->getTmdbId()) + ->setImdbId($monitor->getImdbId()) + ->setTitle($monitor->getTitle()) + ->setMonitorType('tvepisode') + ->setSeason($episode['season_number']) + ->setEpisode($episode['episode_number']) + ->setCreatedAt(new DateTimeImmutable()) + ->setSearchCount(0) + ->setStatus('New'); + + $this->monitorRepository->getEntityManager()->persist($episodeMonitor); + $this->monitorRepository->getEntityManager()->flush(); + + // 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()); } } else { $monitor->setStatus('Complete'); @@ -104,4 +115,24 @@ readonly class MonitorTvShowHandler implements HandlerInterface ] ); } + + private function episodeExists(array $episodeInShow, Map $downloadedEpisodes): bool + { + return $downloadedEpisodes->filter( + fn (object $episode) => $episode->episode === $episodeInShow['episode_number'] + && $episode->season === $episodeInShow['season_number'] + )->count() > 0; + } + + private function monitorExists(Monitor $monitor, array $episode): bool + { + return $this->monitorRepository->findOneBy([ + 'imdbId' => $monitor->getImdbId(), + 'title' => $monitor->getTitle(), + 'monitorType' => 'tvepisode', + 'season' => $episode['season_number'], + 'episode' => $episode['episode_number'], + 'status' => ['New', 'Active', 'In Progress'] + ]) !== null; + } } diff --git a/src/Twig/Components/MonitorList.php b/src/Twig/Components/MonitorList.php index a30ff08..8e91acc 100644 --- a/src/Twig/Components/MonitorList.php +++ b/src/Twig/Components/MonitorList.php @@ -48,7 +48,7 @@ final class MonitorList extends AbstractController return $this->asPaginator($this->monitorRepository->createQueryBuilder('m') ->andWhere('m.status IN (:statuses)') ->andWhere('(m.title LIKE :term OR m.imdbId LIKE :term OR m.monitorType LIKE :term OR m.status LIKE :term)') - ->setParameter('statuses', ['New', 'In Progress']) + ->setParameter('statuses', ['New', 'In Progress', 'Active']) ->setParameter('term', '%'.$this->term.'%') ->orderBy('m.id', 'DESC') ->getQuery()