fix: scopes downloads and monitors to users

This commit is contained in:
2025-05-11 16:27:53 -05:00
parent 6817bd8c80
commit 8aba35fee1
13 changed files with 34 additions and 40 deletions

View File

@@ -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,

View File

@@ -15,6 +15,7 @@ class DownloadMediaCommand implements CommandInterface
public string $filename,
public string $mediaType,
public string $imdbId,
public int $userId,
public ?int $downloadId = null,
) {}
}

View File

@@ -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');

View File

@@ -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
);
}
}

View File

@@ -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<Download>
@@ -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')

View File

@@ -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,

View File

@@ -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)

View File

@@ -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<MonitorMovieCommand> */
@@ -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(

View File

@@ -58,6 +58,7 @@ readonly class MonitorTvEpisodeHandler implements HandlerInterface
$result->filename,
'tvshows',
$monitor->getImdbId(),
$monitor->getUser()->getId(),
));
$monitor->setStatus('Complete');
$monitor->setDownloadedAt(new DateTimeImmutable());

View File

@@ -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,

View File

@@ -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',

View File

@@ -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']]);