searchHandler = $searchHandler; $this->getTvShowOptionsHandler = $getTvShowOptionsHandler; $this->getMovieOptionsHandler = $getMovieOptionsHandler; $this->userRepository = $userRepository; $this->downloadRepository = $downloadRepository; $this->downloadMediaHandler = $downloadMediaHandler; $this->bus = $bus; } protected function configure() { $this->addArgument('term', InputArgument::REQUIRED); $this->addOption('local', 'l', InputOption::VALUE_NONE, 'Perform the download locally instead of submitting it to the queue.'); } public function run(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); $command = new CommandInput($input->getArgument('term')); // Perform search $mediaOptions = $this->searchHandler->handle($command); // Render results and ask the User to pick one $mediaChoice = $this->askToChooseMediaOption($io, $output, $mediaOptions); // Find download options based on the User's choice $downloadOptions = $this->fetchDownloadOptions($mediaChoice); // Render results and ask the User to pick one $downloadChoice = $this->askToChooseDownloadOption($io, $output, $downloadOptions); // Have user confirm download action $confirmation = $this->askToConfirmDownload($io, $output, $downloadChoice); // Begin download or submit to the queue if (true === $confirmation) { $downloadLocally = $input->getOption('local'); $this->submitDownload($io, $mediaChoice, $downloadChoice, $downloadLocally); } else { $io->success('No results found.'); } $io->success('Success!'); return Command::SUCCESS; } private function askToChooseMediaOption(SymfonyStyle $io, OutputInterface $output, SearchResult $result): TmdbResult { $table = new Table($output) ->setHeaders(['ID', 'Title', 'Year', 'IMDb ID', 'Description']) ->setRows( Map::from($result->results) ->map(fn ($result, $index) => [$index, $result->title, $result->year, $result->imdbId, substr($result->description, 0, 80) . '...']) ->toArray() ); $table->render(); $question = new Question('Enter the ID of the correct result: '); $choiceId = $io->askQuestion($question); $choice = $result->results[$choiceId]; $io->info('You chose: ' . $choice->title); $io->table( ['ID', 'Title', 'Year', 'IMDb ID', 'Description'], [ [$choiceId, $choice->title, $choice->year, $choice->imdbId, substr($choice->description, 0, 80) . '...'], ] ); return $choice; } private function fetchDownloadOptions(TmdbResult $result): array { $handlers = [ 'movies' => $this->getMovieOptionsHandler, 'tvshows' => $this->getTvShowOptionsHandler, ]; $handler = $handlers[$result->mediaType]; if ("movies" === $result->mediaType) { $command = new GetMovieOptionsCommand( $result->tmdbId, $result->imdbId ); } else { $command = new GetTvShowOptionsCommand( $result->tmdbId, $result->imdbId, 1, 1 ); } $result = $handler->handle($command); return $result->results; } private function askToChooseDownloadOption(SymfonyStyle $io, OutputInterface $output, array $options): TorrentioResult { $table = new Table($output) ->setHeaders(['ID', 'Size', 'Resolution', 'Codec', 'Seeders', 'Provider', 'Language']) ->setRows( Map::from($options) ->map(fn (TorrentioResult $result, $index) => [$index, $result->size, $result->resolution, $result->codec, $result->seeders, $result->provider, implode(', ', $result->languages)]) ->toArray() ); $table->render(); $question = new Question('Enter the ID of the item to download: '); $choiceId = $io->askQuestion($question); $choice = $options[$choiceId]; $io->info('You chose: ' . $choice->title); return $choice; } private function askToConfirmDownload(SymfonyStyle $io, OutputInterface $output, TorrentioResult $downloadOption): bool { $question = new ChoiceQuestion('Are you sure you want to download the above file?', ['yes', 'no']); $choice = $io->askQuestion($question); return $choice === 'yes'; } private function submitDownload(SymfonyStyle $io, TmdbResult $mediaChoice, TorrentioResult $downloadOption, bool $downloadLocally = false): void { $io->writeln('> Adding download record'); $user = $this->userRepository->find(1); $download = $this->downloadRepository->insert( $user, $downloadOption->url, $downloadOption->title, $downloadOption->filename, $mediaChoice->imdbId, $mediaChoice->mediaType, ); $io->writeln('> Download record added: ' . $download->getId()); $downloadCommand = new DownloadMediaCommand( $download->getUrl(), $download->getTitle(), $download->getFilename(), $download->getMEdiaType(), $download->getImdbId(), $download->getUser()->getId(), $download->getId() ); if (true === $downloadLocally) { $io->writeln('> Beginning local download'); $this->downloadMediaHandler->handle($downloadCommand); } else { $io->writeln('> Submitting download to queue'); $this->bus->dispatch($downloadCommand); } $io->writeln('> Download added to queue'); } }