wip-feat: dispatches monitor commands for episodes, seasons, & shows

This commit is contained in:
2025-05-06 00:00:45 -05:00
parent 9166b4bbc8
commit 527adb73c1
33 changed files with 795 additions and 147 deletions

View File

@@ -0,0 +1,23 @@
<?php
namespace App\Download\Framework\Controller;
use App\Download\Action\Handler\AddMonitorHandler;
use App\Download\Action\Input\AddMonitorInput;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Attribute\Route;
class ApiController extends AbstractController
{
#[Route('/monitor', name: 'app_add_movie_monitor', methods: ['POST'])]
public function addMonitor(
AddMonitorInput $input,
AddMonitorHandler $handler,
) {
$response = $handler->handle($input->toCommand());
return $this->json([
'status' => 200,
'message' => $response
]);
}
}

View File

@@ -2,13 +2,13 @@
namespace App\Download\Framework\Entity;
use App\Download\Framework\Repository\MovieMonitorRepository;
use App\Download\Framework\Repository\MonitorRepository;
use App\User\Framework\Entity\User;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: MovieMonitorRepository::class)]
class MovieMonitor
#[ORM\Entity(repositoryClass: MonitorRepository::class)]
class Monitor
{
#[ORM\Id]
#[ORM\GeneratedValue]
@@ -28,6 +28,15 @@ class MovieMonitor
#[ORM\Column(length: 255)]
private ?string $tmdbId = null;
#[ORM\Column(length: 255)]
private ?string $monitorType = null;
#[ORM\Column(nullable: true)]
private ?int $season = null;
#[ORM\Column(nullable: true)]
private ?int $episode = null;
#[ORM\Column(length: 255)]
private ?string $status = null;
@@ -155,4 +164,40 @@ class MovieMonitor
return $this;
}
public function getMonitorType(): ?string
{
return $this->monitorType;
}
public function setMonitorType(string $monitorType): static
{
$this->monitorType = $monitorType;
return $this;
}
public function getSeason(): ?int
{
return $this->season;
}
public function setSeason(?int $season): static
{
$this->season = $season;
return $this;
}
public function getEpisode(): ?int
{
return $this->episode;
}
public function setEpisode(?int $episode): static
{
$this->episode = $episode;
return $this;
}
}

View File

@@ -2,18 +2,18 @@
namespace App\Download\Framework\Repository;
use App\Download\Framework\Entity\MovieMonitor;
use App\Download\Framework\Entity\Monitor;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<MovieMonitor>
* @extends ServiceEntityRepository<Monitor>
*/
class MovieMonitorRepository extends ServiceEntityRepository
class MonitorRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, MovieMonitor::class);
parent::__construct($registry, Monitor::class);
}
// /**

View File

@@ -0,0 +1,39 @@
<?php
namespace App\Download\Framework\Scheduler;
use App\Download\Action\Handler\MonitorMovieHandler;
use App\Download\Action\Handler\MonitorTvSeasonHandler;
use App\Download\Framework\Repository\MonitorRepository;
use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Scheduler\Attribute\AsCronTask;
#[AsCronTask('* * * * *', schedule: 'monitor')]
class MonitorDispatcher
{
public function __construct(
private readonly LoggerInterface $logger,
private readonly MonitorRepository $monitorRepository,
private readonly MessageBusInterface $bus,
) {}
public function __invoke() {
$this->logger->info('[MonitorDispatcher] Executing MovieMonitorDispatcher');
$monitorHandlers = [
'movie' => MonitorMovieHandler::class,
'tvepisode' => MonitorTvSeasonHandler::class,
'tvseason' => MonitorTvSeasonHandler::class,
'tvshow' => MonitorTvSeasonHandler::class,
];
$monitors = $this->monitorRepository->findBy(['status' => ['New', 'In Progress']]);
foreach ($monitors as $monitor) {
$handler = $monitorHandlers[$monitor->getMonitorType()];
$this->logger->info('[MonitorDispatcher] Dispatching ' . $handler . ' for ' . $monitor->getTitle());
$this->bus->dispatch(new $handler($monitor->getId()));
}
}
}

View File

@@ -1,29 +0,0 @@
<?php
namespace App\Download\Framework\Scheduler;
use App\Download\Action\Command\MonitorMovieCommand;
use App\Download\Framework\Repository\MovieMonitorRepository;
use Psr\Log\LoggerInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Scheduler\Attribute\AsCronTask;
#[AsCronTask('* * * * *', schedule: 'movie_monitor')]
class MovieMonitorDispatcher
{
public function __construct(
private readonly LoggerInterface $logger,
private readonly MovieMonitorRepository $movieMonitorRepository,
private readonly MessageBusInterface $bus,
) {}
public function __invoke() {
$this->logger->info('[MovieMonitorDispatcher] Executing MovieMonitorDispatcher');
$monitors = $this->movieMonitorRepository->findBy(['status' => ['New', 'In Progress']]);
foreach ($monitors as $monitor) {
$this->logger->info('[MovieMonitorDispatcher] Dispatching MovieMonitorCommand for ' . $monitor->getTitle());
$this->bus->dispatch(new MonitorMovieCommand($monitor->getId()));
}
}
}