wip: working tv season & episode monitors

This commit is contained in:
2025-06-10 21:19:13 -05:00
parent 15648e711b
commit 8cc81fea19
7 changed files with 239 additions and 71 deletions

View File

@@ -3,9 +3,9 @@
namespace App\Monitor\Action\Handler;
use Aimeos\Map;
use App\Monitor\Action\Command\MonitorMovieCommand;
use App\Monitor\Action\Command\MonitorTvEpisodeCommand;
use App\Monitor\Action\Result\MonitorMovieResult;
use App\Monitor\Action\Command\MonitorTvSeasonCommand;
use App\Monitor\Action\Result\MonitorTvSeasonResult;
use App\Monitor\Framework\Entity\Monitor;
use App\Monitor\Framework\Repository\MonitorRepository;
use App\Monitor\Service\MediaFiles;
@@ -17,16 +17,14 @@ use OneToMany\RichBundle\Contract\CommandInterface;
use OneToMany\RichBundle\Contract\HandlerInterface;
use OneToMany\RichBundle\Contract\ResultInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\MessageBusInterface;
/** @implements HandlerInterface<MonitorMovieCommand> */
/** @implements HandlerInterface<MonitorTvSeasonCommand> */
readonly class MonitorTvSeasonHandler implements HandlerInterface
{
public function __construct(
private MonitorRepository $monitorRepository,
private EntityManagerInterface $entityManager,
private MediaFiles $mediaFiles,
private MessageBusInterface $bus,
private LoggerInterface $logger,
private Tmdb $tmdb,
private MonitorTvEpisodeHandler $monitorTvEpisodeHandler,
@@ -46,54 +44,62 @@ readonly class MonitorTvSeasonHandler implements HandlerInterface
// Compare against list from TMDB
$episodesInSeason = Map::from(
$this->tmdb->tvDetails($monitor->getTmdbId())
->episodes[$monitor->getSeason()]
$this->tmdb->tvDetails($monitor->getTmdbId())->episodes[$monitor->getSeason()]
)->rekey(fn($episode) => $episode['episode_number']);
$this->logger->info('> [MonitorTvSeasonHandler] Found ' . count($episodesInSeason) . ' episodes in season ' . $monitor->getSeason() . ' for title: ' . $monitor->getTitle());
// Dispatch Episode commands for each missing Episode
foreach ($episodesInSeason 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']
]);
if ($downloadedEpisodes->count() !== $episodesInSeason->count()) {
// Since $monitor has children monitors, set the status
// to Active, so it will be re-executed.
$monitor->setStatus('Active');
$this->logger->info('> [MonitorTvSeasonHandler] Monitor exists for season ' . $monitor->getSeason() . ' episode ' . $episode['episode_number'] . ' for title: ' . $monitor->getTitle() . ' ? ' . (null !== $monitorCheck ? 'YES' : 'NO'));
// Dispatch Episode commands for each missing Episode
foreach ($episodesInSeason 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']
]);
if (!array_key_exists($episode['episode_number'], $downloadedEpisodes->toArray())
&& null === $monitorCheck
) {
$episodeMonitor = (new 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->logger->info('> [MonitorTvSeasonHandler] Monitor exists for season ' . $monitor->getSeason() . ' episode ' . $episode['episode_number'] . ' for title: ' . $monitor->getTitle() . ' ? ' . (null !== $monitorCheck ? 'YES' : 'NO'));
$this->monitorRepository->getEntityManager()->persist($episodeMonitor);
$this->monitorRepository->getEntityManager()->flush();
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');
$command = new MonitorTvEpisodeCommand($episodeMonitor->getId());
$this->monitorTvEpisodeHandler->handle($command);
$this->logger->info('> [MonitorTvSeasonHandler] Dispatching MonitorTvEpisodeCommand for season ' . $episodeMonitor->getSeason() . ' episode ' . $episodeMonitor->getEpisode() . ' for title: ' . $monitor->getTitle());
$this->monitorRepository->getEntityManager()->persist($episodeMonitor);
$this->monitorRepository->getEntityManager()->flush();
$command = new MonitorTvEpisodeCommand($episodeMonitor->getId());
$this->monitorTvEpisodeHandler->handle($command);
$this->logger->info('> [MonitorTvSeasonHandler] Dispatching MonitorTvEpisodeCommand for season ' . $episodeMonitor->getSeason() . ' episode ' . $episodeMonitor->getEpisode() . ' for title: ' . $monitor->getTitle());
}
}
} else {
$monitor->setStatus('Complete');
}
$monitor->setLastSearch(new DateTimeImmutable());
$monitor->setSearchCount($monitor->getSearchCount() + 1);
$monitor->setStatus('Complete');
$this->entityManager->flush();
return new MonitorMovieResult(
return new MonitorTvSeasonResult(
status: 'OK',
result: [
'monitor' => $monitor,