diff --git a/assets/controllers/movie_results_controller.js b/assets/controllers/movie_results_controller.js index fa31122..d2db38a 100644 --- a/assets/controllers/movie_results_controller.js +++ b/assets/controllers/movie_results_controller.js @@ -20,8 +20,10 @@ export default class extends Controller { options = [] optionsLoaded = false + resultCountEl = null async connect() { + this.resultCountEl = document.querySelector('#movie_results_count'); await this.setOptions(); } @@ -36,6 +38,7 @@ export default class extends Controller { this.options.forEach((option) => option.querySelector('.download-btn').dataset['title'] = this.titleValue); this.dispatch('optionsLoaded', {detail: {options: this.options}}) this.loadingIconOutlet.toggleIcon(); + this.resultCountEl.innerText = this.options.length; }); } } @@ -102,5 +105,6 @@ export default class extends Controller { count = count + 1; } }); + this.resultCountEl.innerText = count; } } diff --git a/src/Library/Action/Handler/LibrarySearchHandler.php b/src/Library/Action/Handler/LibrarySearchHandler.php index 34c578e..0c918e3 100644 --- a/src/Library/Action/Handler/LibrarySearchHandler.php +++ b/src/Library/Action/Handler/LibrarySearchHandler.php @@ -5,6 +5,8 @@ namespace App\Library\Action\Handler; use App\Base\Service\MediaFiles; use App\Library\Action\Command\LibrarySearchCommand; use App\Library\Action\Result\LibrarySearchResult; +use App\Library\Dto\MediaFileDto; +use Nihilarr\PTN; use OneToMany\RichBundle\Contract\CommandInterface; use OneToMany\RichBundle\Contract\HandlerInterface; use OneToMany\RichBundle\Contract\ResultInterface; @@ -16,6 +18,7 @@ class LibrarySearchHandler implements HandlerInterface { private array $searchTypes = [ 'episode_by_title' => 'episodeByTitle', + 'movie_by_title' => 'movieByTitle', ]; public function __construct( @@ -31,6 +34,14 @@ class LibrarySearchHandler implements HandlerInterface private function getSearchType(CommandInterface $command): ?string { + if (!is_null($command->title) && + is_null($command->imdbId) && + is_null($command->season) && + is_null($command->episode) + ) { + return 'movie_by_title'; + } + if ((!is_null($command->title) || is_null($command->imdbId)) && !is_null($command->season) && !is_null($command->episode) @@ -47,14 +58,26 @@ class LibrarySearchHandler implements HandlerInterface (int) $command->season, (int) $command->episode, ); - $exists = $result instanceof \SplFileInfo; - return new LibrarySearchResult( input: $command, exists: $exists, - file: true === $exists ? $result->getFileInfo() : null, + file: true === $exists ? MediaFileDto::fromSplFileInfo($result) : null, + ptn: true === $exists ? (object) new PTN()->parse($result->getFilename()) : null, + ); + } + + private function movieByTitle(CommandInterface $command): ?LibrarySearchResult + { + $result = $this->mediaFiles->movieExists($command->title); + $exists = $result instanceof \SplFileInfo; + + return new LibrarySearchResult( + input: $command, + exists: $exists, + file: true === $exists ? MediaFileDto::fromSplFileInfo($result) : null, + ptn: true === $exists ? (object) new PTN()->parse($result->getFilename()) : null, ); } } diff --git a/src/Library/Action/Result/LibrarySearchResult.php b/src/Library/Action/Result/LibrarySearchResult.php index 87435ae..eec88d7 100644 --- a/src/Library/Action/Result/LibrarySearchResult.php +++ b/src/Library/Action/Result/LibrarySearchResult.php @@ -2,6 +2,7 @@ namespace App\Library\Action\Result; +use App\Library\Dto\MediaFileDto; use OneToMany\RichBundle\Contract\ResultInterface; class LibrarySearchResult implements ResultInterface @@ -9,7 +10,7 @@ class LibrarySearchResult implements ResultInterface public function __construct( public object|array $input, public bool $exists, - public ?\SplFileInfo $file = null, + public ?MediaFileDto $file = null, public ?object $ptn = null, ) {} } diff --git a/src/Library/Dto/MediaFileDto.php b/src/Library/Dto/MediaFileDto.php new file mode 100644 index 0000000..9296d47 --- /dev/null +++ b/src/Library/Dto/MediaFileDto.php @@ -0,0 +1,23 @@ +getRealPath(), + filename: $fileInfo->getFilename(), + extension: $fileInfo->getExtension(), + size: $fileInfo->getSize(), + ); + } +} diff --git a/src/Search/Framework/Controller/WebController.php b/src/Search/Framework/Controller/WebController.php index 0b43234..5daada6 100644 --- a/src/Search/Framework/Controller/WebController.php +++ b/src/Search/Framework/Controller/WebController.php @@ -37,7 +37,8 @@ final class WebController extends AbstractController public function result( GetMediaInfoInput $input, ?int $season = null, - ): Response { + ): Response + { $result = $this->getMediaInfoHandler->handle($input->toCommand()); return $this->render('search/result.html.twig', [ @@ -52,32 +53,4 @@ final class WebController extends AbstractController ] ]); } - - private function warmDownloadOptionCache(TmdbResult $result) - { - if ($result->mediaType === 'tvshows') { - // dispatches a job to get the download options - // for each episode and load them in cache - foreach ($result->episodes as $season => $episodes) { - // Only do the first 2 seasons, so we reduce - // getting rate-limited by Torrentio - if ($season > 2) { - return; - } - foreach ($episodes as $episode) { - $this->bus->dispatch(new GetTvShowOptionsCommand( - tmdbId: $result->tmdbId, - imdbId: $result->imdbId, - season: $season, - episode: $episode['episode_number'], - )); - } - } - } elseif ($result->mediaType === 'movies') { - $this->bus->dispatch(new GetMovieOptionsCommand( - $result->tmdbId, - $result->imdbId, - )); - } - } } diff --git a/src/Tmdb/Tmdb.php b/src/Tmdb/Tmdb.php index 03f4715..f36dc01 100644 --- a/src/Tmdb/Tmdb.php +++ b/src/Tmdb/Tmdb.php @@ -301,6 +301,7 @@ class Tmdb description: $data['overview'], year: (new \DateTime($data['release_date']))->format('Y'), mediaType: "movies", + episodeAirDate: (new \DateTime($data['release_date']))->format('m/d/Y'), ); } diff --git a/templates/search/fragments.html.twig b/templates/search/fragments.html.twig index cd70cf0..390af7c 100644 --- a/templates/search/fragments.html.twig +++ b/templates/search/fragments.html.twig @@ -6,7 +6,7 @@