feat: download movie to dedicated directory

This commit is contained in:
2025-05-19 22:28:00 -05:00
parent 4638f3765a
commit 3074b2d5f1
5 changed files with 71 additions and 15 deletions

View File

@@ -37,8 +37,6 @@ readonly class DownloadMediaHandler implements HandlerInterface
$download = $this->downloadRepository->find($command->downloadId); $download = $this->downloadRepository->find($command->downloadId);
} }
dump($download);
try { try {
$this->downloadRepository->updateStatus($download->getId(), 'In Progress'); $this->downloadRepository->updateStatus($download->getId(), 'In Progress');

View File

@@ -10,11 +10,11 @@ use App\Message\DownloadTvShowMessage;
interface DownloaderInterface interface DownloaderInterface
{ {
/** /**
* @param string $baseDir * @param string $mediaType
* @param string $title * @param string $title
* @param string $url * @param string $url
* @return void * @return void
* Downloads the requested file. * Downloads the requested file.
*/ */
public function download(string $baseDir, string $title, string $url, ?int $downloadId): void; public function download(string $mediaType, string $title, string $url, ?int $downloadId): void;
} }

View File

@@ -3,6 +3,7 @@
namespace App\Download\Downloader; namespace App\Download\Downloader;
use App\Download\Framework\Entity\Download; use App\Download\Framework\Entity\Download;
use App\Monitor\Service\MediaFiles;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Process\Exception\ProcessFailedException; use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process; use Symfony\Component\Process\Process;
@@ -11,25 +12,26 @@ class ProcessDownloader implements DownloaderInterface
{ {
public function __construct( public function __construct(
private EntityManagerInterface $entityManager, private EntityManagerInterface $entityManager,
private MediaFiles $mediaFiles,
) {} ) {}
/** /**
* @inheritDoc * @inheritDoc
*/ */
public function download(string $baseDir, string $title, string $url, ?int $downloadId): void public function download(string $mediaType, string $title, string $url, ?int $downloadId): void
{ {
/** @var Download $downloadEntity */ /** @var Download $downloadEntity */
$downloadEntity = $this->entityManager->getRepository(Download::class)->find($downloadId); $downloadEntity = $this->entityManager->getRepository(Download::class)->find($downloadId);
$downloadEntity->setProgress(0); $downloadEntity->setProgress(0);
$this->entityManager->flush(); $this->entityManager->flush();
$process = new Process([ $downloadPreferences = $downloadEntity->getUser()->getDownloadPreferences();
'/bin/sh', $path = $this->getDownloadPath($mediaType, $title, $downloadPreferences);
'/var/www/bash/app/wget_download.sh',
$baseDir, $process = (new Process([
$title, 'wget',
$url $url
]); ]))->setWorkingDirectory($path);
$process->setTimeout(1800); // 30 min $process->setTimeout(1800); // 30 min
$process->setIdleTimeout(600); // 10 min $process->setIdleTimeout(600); // 10 min
@@ -61,4 +63,20 @@ class ProcessDownloader implements DownloaderInterface
$this->entityManager->flush(); $this->entityManager->flush();
} }
public function getDownloadPath(string $mediaType, string $title, array $downloadPreferences): string
{
if ($mediaType === 'movies') {
if ((bool) $downloadPreferences['movie_folder']->getPreferenceValue() === true) {
return $this->mediaFiles->createMovieDirectory($title);
}
return $this->mediaFiles->getMoviesPath();
}
if ($mediaType === 'tvshows') {
return $this->mediaFiles->createTvShowDirectory($title);
}
throw new \Exception("There is no download path for media type: $mediaType");
}
} }

View File

@@ -17,8 +17,6 @@ class ApiController extends AbstractController
public function __construct( public function __construct(
#[Autowire(service: 'twig')] #[Autowire(service: 'twig')]
private readonly Environment $renderer, private readonly Environment $renderer,
private readonly HubInterface $hub,
private readonly Security $security,
) {} ) {}
#[Route('/api/monitor', name: 'api_monitor', methods: ['POST'])] #[Route('/api/monitor', name: 'api_monitor', methods: ['POST'])]
@@ -28,12 +26,12 @@ class ApiController extends AbstractController
HubInterface $hub, HubInterface $hub,
) { ) {
$command = $input->toCommand(); $command = $input->toCommand();
$command->userId = $this->security->getUser()->getId(); $command->userId = $this->getUser()->getId();
$response = $handler->handle($command); $response = $handler->handle($command);
$hub->publish(new Update( $hub->publish(new Update(
'alerts', 'alerts',
$this->renderer->render('Alert.stream.html.twig', [ $this->renderer->render('broadcast/Alert.stream.html.twig', [
'alert_id' => uniqid(), 'alert_id' => uniqid(),
'title' => 'Success', 'title' => 'Success',
'message' => "New monitor added for {$input->title}", 'message' => "New monitor added for {$input->title}",

View File

@@ -32,6 +32,17 @@ class MediaFiles
$this->filesystem = $filesystem; $this->filesystem = $filesystem;
} }
public function getPathByType(string $mediaType): string
{
if ('movies' === $mediaType) {
return $this->moviesPath;
} elseif ('tvshows' === $mediaType) {
return $this->tvShowsPath;
}
throw new \Exception(sprintf('A path for media type %s does not exist.', $mediaType));
}
public function getMoviesPath(): string public function getMoviesPath(): string
{ {
return $this->moviesPath; return $this->moviesPath;
@@ -83,4 +94,35 @@ class MediaFiles
return Map::from($results); return Map::from($results);
} }
public function createMovieDirectory(string $path): string
{
$path = $this->moviesPath . DIRECTORY_SEPARATOR . $path;
if (false === $this->filesystem->exists($path)) {
$this->filesystem->mkdir($path);
}
return $path;
}
public function createTvShowDirectory(string $path): string
{
$path = $this->tvShowsPath . DIRECTORY_SEPARATOR . $path;
if (false === $this->filesystem->exists($path)) {
$this->filesystem->mkdir($path);
}
return $path;
}
public function createDirectory(string $path): string
{
if (false === $this->filesystem->exists($path)) {
$this->filesystem->mkdir($path);
}
return $path;
}
} }