224 lines
5.9 KiB
PHP
224 lines
5.9 KiB
PHP
<?php
|
|
|
|
namespace App\Monitor\Service;
|
|
|
|
use Aimeos\Map;
|
|
use App\Download\Framework\Entity\Download;
|
|
use Nihilarr\PTN;
|
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
|
use Symfony\Component\Filesystem\Filesystem;
|
|
use Symfony\Component\Finder\Finder;
|
|
use Symfony\Component\Finder\SplFileInfo;
|
|
|
|
class MediaFiles
|
|
{
|
|
private Finder $finder;
|
|
|
|
private string $basePath;
|
|
|
|
private string $moviesPath;
|
|
|
|
private string $tvShowsPath;
|
|
|
|
private Filesystem $filesystem;
|
|
|
|
public function __construct(
|
|
#[Autowire(param: 'media.base_path')]
|
|
string $basePath,
|
|
|
|
#[Autowire(param: 'media.movies_path')]
|
|
string $moviesPath,
|
|
|
|
#[Autowire(param: 'media.tvshows_path')]
|
|
string $tvShowsPath,
|
|
|
|
Filesystem $filesystem,
|
|
) {
|
|
$this->finder = new Finder();
|
|
$this->basePath = $basePath;
|
|
$this->moviesPath = $moviesPath;
|
|
$this->tvShowsPath = $tvShowsPath;
|
|
$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 getBasePath(): string
|
|
{
|
|
return $this->basePath;
|
|
}
|
|
|
|
public function getMoviesPath(): string
|
|
{
|
|
return $this->moviesPath;
|
|
}
|
|
|
|
public function getTvShowsPath(): string
|
|
{
|
|
return $this->tvShowsPath;
|
|
}
|
|
|
|
public function getMovieDirs(): Map
|
|
{
|
|
$results = [];
|
|
foreach ($this->finder->in($this->moviesPath)->directories() as $file) {
|
|
$results[] = $file;
|
|
}
|
|
|
|
return Map::from($results);
|
|
}
|
|
|
|
public function getTvShowDirs(): Map
|
|
{
|
|
$results = [];
|
|
foreach ($this->finder->in($this->tvShowsPath)->directories() as $file) {
|
|
$results[] = $file;
|
|
}
|
|
|
|
return Map::from($results);
|
|
}
|
|
|
|
public function getEpisodes(string $path, bool $onlyFilenames = true): Map
|
|
{
|
|
if (!str_starts_with($path, $this->tvShowsPath)) {
|
|
$path = $this->tvShowsPath . DIRECTORY_SEPARATOR . $path;
|
|
}
|
|
|
|
if (false === $this->filesystem->exists($path)) {
|
|
$this->filesystem->mkdir($path);
|
|
}
|
|
|
|
$results = [];
|
|
foreach ($this->finder->in($path)->files() as $file) {
|
|
if ($onlyFilenames) {
|
|
$results[] = $file->getRelativePathname();
|
|
} else {
|
|
$results[] = $file;
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
public function episodeExists(string $tvshowTitle, int $seasonNumber, int $episodeNumber)
|
|
{
|
|
$existingEpisodes = $this->getEpisodes($tvshowTitle, false);
|
|
|
|
if ($existingEpisodes->isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
/** @var SplFileInfo $episode */
|
|
foreach ($existingEpisodes as $episode) {
|
|
$ptn = (object) (new PTN())->parse($episode->getFilename());
|
|
|
|
if (!property_exists($ptn, 'season') || !property_exists($ptn, 'episode')) {
|
|
continue;
|
|
}
|
|
|
|
if ($ptn->season === $seasonNumber && $ptn->episode === $episodeNumber) {
|
|
return $episode;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function movieExists(string $title)
|
|
{
|
|
$filepath = $this->moviesPath . DIRECTORY_SEPARATOR . $title;
|
|
$directoryExists = $this->filesystem->exists($filepath);
|
|
|
|
if (false === $directoryExists) {
|
|
return false;
|
|
}
|
|
|
|
if (false === $this->finder->in($filepath)->files()->hasResults()) {
|
|
return false;
|
|
}
|
|
|
|
$files = Map::from($this->finder->in($filepath)->files())->filter(function (SplFileInfo $file) {
|
|
$validExtensions = ['mkv', 'mp4', 'mpeg'];
|
|
return in_array($file->getExtension(), $validExtensions);
|
|
})->values();
|
|
|
|
if (false === $files->isEmpty()) {
|
|
return $files[0];
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function getDownloadPath(Download $download): string
|
|
{
|
|
$basePath = $this->getBasePath();
|
|
|
|
if ($download->getMediaType() === 'movies') {
|
|
$basePath = $this->getMoviesPath();
|
|
if ($download->getUser()->hasUserPreference('movie_folder')) {
|
|
$basePath .= DIRECTORY_SEPARATOR . $download->getTitle();
|
|
}
|
|
} elseif ($download->getMediaType() === 'tvshows') {
|
|
$basePath = $this->getTvShowsPath() . DIRECTORY_SEPARATOR . $download->getTitle();
|
|
}
|
|
|
|
$filepath = $basePath . DIRECTORY_SEPARATOR . $download->getFilename();
|
|
|
|
if (false === $this->filesystem->exists($filepath)) {
|
|
throw new \Exception(sprintf('File %s does not exist.', $filepath));
|
|
}
|
|
|
|
return $filepath;
|
|
}
|
|
|
|
public function renameFile(string $oldFile, string $newFile)
|
|
{
|
|
$this->filesystem->rename($oldFile, $newFile);
|
|
}
|
|
|
|
public function setFilePermissions(string $filepath, int $permissions)
|
|
{
|
|
$this->filesystem->chmod($filepath, $permissions);
|
|
}
|
|
}
|