From 8aba35fee1e544d53bc7c4f40ec599972a0bd3af Mon Sep 17 00:00:00 2001 From: Brock H Caldwell Date: Sun, 11 May 2025 16:27:53 -0500 Subject: [PATCH] fix: scopes downloads and monitors to users --- .../controllers/download_button_controller.js | 2 +- src/Controller/DownloadController.php | 2 ++ .../Action/Command/DownloadMediaCommand.php | 1 + .../Action/Handler/DownloadMediaHandler.php | 4 ++- .../Action/Input/DownloadMediaInput.php | 3 ++ .../Repository/DownloadRepository.php | 34 +++---------------- .../Action/Command/AddMonitorCommand.php | 2 +- .../Action/Handler/AddMonitorHandler.php | 2 +- .../Action/Handler/MonitorMovieHandler.php | 9 +++-- .../Handler/MonitorTvEpisodeHandler.php | 1 + src/Monitor/Action/Input/AddMonitorInput.php | 4 +-- .../Framework/Controller/ApiController.php | 6 +++- .../Framework/Scheduler/MonitorDispatcher.php | 4 +-- 13 files changed, 34 insertions(+), 40 deletions(-) diff --git a/assets/controllers/download_button_controller.js b/assets/controllers/download_button_controller.js index 7459173..8b0a612 100644 --- a/assets/controllers/download_button_controller.js +++ b/assets/controllers/download_button_controller.js @@ -26,7 +26,7 @@ export default class extends Controller { title: this.element.dataset['title'], filename: this.filenameValue, mediaType: this.mediaTypeValue, - imdbId: this.imdbIdValue + imdbId: this.imdbIdValue, }) }) .then(res => res.json()) diff --git a/src/Controller/DownloadController.php b/src/Controller/DownloadController.php index 18579e4..fbf9f60 100644 --- a/src/Controller/DownloadController.php +++ b/src/Controller/DownloadController.php @@ -6,6 +6,7 @@ use App\Download\Action\Input\DownloadMediaInput; use App\Download\Framework\Repository\DownloadRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Mercure\HubInterface; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Attribute\Route; @@ -21,6 +22,7 @@ class DownloadController extends AbstractController DownloadMediaInput $input, ): Response { $download = $this->downloadRepository->insert( + $this->getUser(), $input->url, $input->title, $input->filename, diff --git a/src/Download/Action/Command/DownloadMediaCommand.php b/src/Download/Action/Command/DownloadMediaCommand.php index 98b27ca..6be1482 100644 --- a/src/Download/Action/Command/DownloadMediaCommand.php +++ b/src/Download/Action/Command/DownloadMediaCommand.php @@ -15,6 +15,7 @@ class DownloadMediaCommand implements CommandInterface public string $filename, public string $mediaType, public string $imdbId, + public int $userId, public ?int $downloadId = null, ) {} } \ No newline at end of file diff --git a/src/Download/Action/Handler/DownloadMediaHandler.php b/src/Download/Action/Handler/DownloadMediaHandler.php index 9d1ceeb..6207f51 100644 --- a/src/Download/Action/Handler/DownloadMediaHandler.php +++ b/src/Download/Action/Handler/DownloadMediaHandler.php @@ -6,6 +6,7 @@ use App\Download\Action\Command\DownloadMediaCommand; use App\Download\Action\Result\DownloadMediaResult; use App\Download\Framework\Repository\DownloadRepository; use App\Download\Downloader\DownloaderInterface; +use App\User\Framework\Repository\UserRepository; use OneToMany\RichBundle\Contract\CommandInterface; use OneToMany\RichBundle\Contract\HandlerInterface; use OneToMany\RichBundle\Contract\ResultInterface; @@ -17,12 +18,14 @@ readonly class DownloadMediaHandler implements HandlerInterface public function __construct( private DownloaderInterface $downloader, private DownloadRepository $downloadRepository, + private UserRepository $userRepository, ) {} public function handle(CommandInterface $command): ResultInterface { if (null === $command->downloadId) { $download = $this->downloadRepository->insert( + $this->userRepository->find($command->userId), $command->url, $command->title, $command->filename, @@ -34,7 +37,6 @@ readonly class DownloadMediaHandler implements HandlerInterface $download = $this->downloadRepository->find($command->downloadId); } - try { $this->downloadRepository->updateStatus($download->getId(), 'In Progress'); diff --git a/src/Download/Action/Input/DownloadMediaInput.php b/src/Download/Action/Input/DownloadMediaInput.php index c7acce5..37b17cb 100644 --- a/src/Download/Action/Input/DownloadMediaInput.php +++ b/src/Download/Action/Input/DownloadMediaInput.php @@ -26,6 +26,8 @@ class DownloadMediaInput implements InputInterface #[SourceRequest('imdbId')] public string $imdbId, + public ?int $userId = null, + public ?int $downloadId = null, ) {} @@ -38,6 +40,7 @@ class DownloadMediaInput implements InputInterface $this->mediaType, $this->imdbId, $this->downloadId, + $this->userId ); } } \ No newline at end of file diff --git a/src/Download/Framework/Repository/DownloadRepository.php b/src/Download/Framework/Repository/DownloadRepository.php index 7ee24d1..ba46138 100644 --- a/src/Download/Framework/Repository/DownloadRepository.php +++ b/src/Download/Framework/Repository/DownloadRepository.php @@ -3,11 +3,12 @@ namespace App\Download\Framework\Repository; use App\Download\Framework\Entity\Download; -use App\ValueObject\DownloadRequest; +use App\User\Framework\Entity\User; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; use Knp\Component\Pager\Paginator; use Knp\Component\Pager\PaginatorInterface; +use Symfony\Component\Security\Core\User\UserInterface; /** * @extends ServiceEntityRepository @@ -51,6 +52,7 @@ class DownloadRepository extends ServiceEntityRepository } public function insert( + UserInterface $user, string $url, string $title, string $filename, @@ -59,7 +61,9 @@ class DownloadRepository extends ServiceEntityRepository string $batchId, string $status = 'New' ): Download { + /** @var User $user */ $download = (new Download()) + ->setUser($user) ->setUrl($url) ->setTitle($title) ->setFilename($filename) @@ -75,22 +79,6 @@ class DownloadRepository extends ServiceEntityRepository return $download; } - public function insertFromDownloadRequest(DownloadRequest $request): Download - { - $download = (new Download()) - ->setUrl($request->downloadUrl) - ->setTitle($request->seriesName) - ->setFilename($request->filename) - ->setImdbId($request->imdbCode) - ->setMediaType($request->mediaType) - ->setStatus('New'); - - $this->getEntityManager()->persist($download); - $this->getEntityManager()->flush(); - - return $download; - } - public function updateStatus(int $id, string $status): Download { $download = $this->find($id); @@ -106,18 +94,6 @@ class DownloadRepository extends ServiceEntityRepository $this->getEntityManager()->flush(); } - public function getPendingByBatchId(string $batchId): ?array - { - $query = $this->createQueryBuilder('d') - ->andWhere('d.status IN (:statuses)') - ->andWhere('d.batchId = :batchId') - ->setParameter('statuses', ['New', 'In Progress']) - ->setParameter('batchId', $batchId) - ->getQuery(); - - return $query->getResult(); - } - public function latest(int $limit = 1) { return $this->createQueryBuilder('d') diff --git a/src/Monitor/Action/Command/AddMonitorCommand.php b/src/Monitor/Action/Command/AddMonitorCommand.php index 3f6f5a6..eab8dfe 100644 --- a/src/Monitor/Action/Command/AddMonitorCommand.php +++ b/src/Monitor/Action/Command/AddMonitorCommand.php @@ -7,7 +7,7 @@ use OneToMany\RichBundle\Contract\CommandInterface; class AddMonitorCommand implements CommandInterface { public function __construct( - public string $userEmail, + public string $userId, public string $title, public string $imdbId, public string $tmdbId, diff --git a/src/Monitor/Action/Handler/AddMonitorHandler.php b/src/Monitor/Action/Handler/AddMonitorHandler.php index 0aed8b6..36e4205 100644 --- a/src/Monitor/Action/Handler/AddMonitorHandler.php +++ b/src/Monitor/Action/Handler/AddMonitorHandler.php @@ -22,7 +22,7 @@ readonly class AddMonitorHandler implements HandlerInterface public function handle(CommandInterface $command): ResultInterface { - $user = $this->userRepository->findOneBy(['email' => $command->userEmail]); + $user = $this->userRepository->find($command->userId); $monitor = (new Monitor()) ->setUser($user) ->setTmdbId($command->tmdbId) diff --git a/src/Monitor/Action/Handler/MonitorMovieHandler.php b/src/Monitor/Action/Handler/MonitorMovieHandler.php index 8257a9d..02232e2 100644 --- a/src/Monitor/Action/Handler/MonitorMovieHandler.php +++ b/src/Monitor/Action/Handler/MonitorMovieHandler.php @@ -2,9 +2,10 @@ namespace App\Monitor\Action\Handler; -use App\Monitor\Action\Command\DownloadMediaCommand; +use App\Download\Action\Command\DownloadMediaCommand; use App\Monitor\Action\Command\MonitorMovieCommand; use App\Monitor\Action\Result\MonitorMovieResult; +use App\Monitor\Framework\Entity\Monitor; use App\Monitor\Framework\Repository\MonitorRepository; use App\Monitor\Service\MonitorOptionEvaluator; use App\Torrentio\Action\Command\GetMovieOptionsCommand; @@ -15,6 +16,7 @@ use OneToMany\RichBundle\Contract\CommandInterface; use OneToMany\RichBundle\Contract\HandlerInterface; use OneToMany\RichBundle\Contract\ResultInterface; use Psr\Log\LoggerInterface; +use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\Messenger\MessageBusInterface; /** @implements HandlerInterface */ @@ -27,11 +29,13 @@ readonly class MonitorMovieHandler implements HandlerInterface private EntityManagerInterface $entityManager, private MessageBusInterface $bus, private LoggerInterface $logger, + private Security $security, ) {} public function handle(CommandInterface $command): ResultInterface { $this->logger->info('> [MonitorMovieHandler] Executing MonitorMovieHandler'); + /** @var Monitor $monitor */ $monitor = $this->movieMonitorRepository->find($command->movieMonitorId); $monitor->setStatus('In Progress'); @@ -51,6 +55,7 @@ readonly class MonitorMovieHandler implements HandlerInterface $result->filename, 'movies', $monitor->getImdbId(), + $monitor->getUser()->getId(), )); $monitor->setStatus('Complete'); $monitor->setDownloadedAt(new DateTimeIMmutable()); @@ -59,7 +64,7 @@ readonly class MonitorMovieHandler implements HandlerInterface } $monitor->setLastSearch(new DateTimeImmutable()); - $monitor->setSearchCount($monitor->getSearchCount() + 1); + $monitor->incrementSearchCount(); $this->entityManager->flush(); return new MonitorMovieResult( diff --git a/src/Monitor/Action/Handler/MonitorTvEpisodeHandler.php b/src/Monitor/Action/Handler/MonitorTvEpisodeHandler.php index ab99ec7..774ccb5 100644 --- a/src/Monitor/Action/Handler/MonitorTvEpisodeHandler.php +++ b/src/Monitor/Action/Handler/MonitorTvEpisodeHandler.php @@ -58,6 +58,7 @@ readonly class MonitorTvEpisodeHandler implements HandlerInterface $result->filename, 'tvshows', $monitor->getImdbId(), + $monitor->getUser()->getId(), )); $monitor->setStatus('Complete'); $monitor->setDownloadedAt(new DateTimeImmutable()); diff --git a/src/Monitor/Action/Input/AddMonitorInput.php b/src/Monitor/Action/Input/AddMonitorInput.php index 72cdaf6..58d8260 100644 --- a/src/Monitor/Action/Input/AddMonitorInput.php +++ b/src/Monitor/Action/Input/AddMonitorInput.php @@ -12,7 +12,7 @@ class AddMonitorInput implements InputInterface { public function __construct( #[SourceSecurity] - public string $userEmail, + public int|string $userId, #[SourceRequest('tmdbId')] public string $tmdbId, @@ -36,7 +36,7 @@ class AddMonitorInput implements InputInterface public function toCommand(): CommandInterface { return new AddMonitorCommand( - $this->userEmail, + $this->userId, $this->title, $this->imdbId, $this->tmdbId, diff --git a/src/Monitor/Framework/Controller/ApiController.php b/src/Monitor/Framework/Controller/ApiController.php index 42c5b3e..d8d41bb 100644 --- a/src/Monitor/Framework/Controller/ApiController.php +++ b/src/Monitor/Framework/Controller/ApiController.php @@ -5,6 +5,7 @@ namespace App\Monitor\Framework\Controller; use App\Monitor\Action\Handler\AddMonitorHandler; use App\Monitor\Action\Input\AddMonitorInput; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Bundle\SecurityBundle\Security; use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\Mercure\HubInterface; use Symfony\Component\Mercure\Update; @@ -17,6 +18,7 @@ class ApiController extends AbstractController #[Autowire(service: 'twig')] private readonly Environment $renderer, private readonly HubInterface $hub, + private readonly Security $security, ) {} #[Route('/api/monitor', name: 'api_monitor', methods: ['POST'])] @@ -25,7 +27,9 @@ class ApiController extends AbstractController AddMonitorHandler $handler, HubInterface $hub, ) { - $response = $handler->handle($input->toCommand()); + $command = $input->toCommand(); + $command->userId = $this->security->getUser()->getId(); + $response = $handler->handle($command); $hub->publish(new Update( 'alerts', diff --git a/src/Monitor/Framework/Scheduler/MonitorDispatcher.php b/src/Monitor/Framework/Scheduler/MonitorDispatcher.php index bdba0c7..e8b0ce0 100644 --- a/src/Monitor/Framework/Scheduler/MonitorDispatcher.php +++ b/src/Monitor/Framework/Scheduler/MonitorDispatcher.php @@ -11,7 +11,7 @@ use Psr\Log\LoggerInterface; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Scheduler\Attribute\AsCronTask; -#[AsCronTask('*/10 * * * *', schedule: 'monitor')] +#[AsCronTask('* * * * *', schedule: 'monitor')] class MonitorDispatcher { public function __construct( @@ -27,7 +27,7 @@ class MonitorDispatcher 'movie' => MonitorMovieCommand::class, 'tvepisode' => MonitorTvEpisodeCommand::class, 'tvseason' => MonitorTvSeasonCommand::class, - 'tvshow' => MonitorTvShowCommand::class, + 'tvshows' => MonitorTvShowCommand::class, ]; $monitors = $this->monitorRepository->findBy(['status' => ['New', 'Active']]);