Compare commits

..

2 Commits

Author SHA1 Message Date
87e72ec55e fix: adds ImdbMatcher 2025-07-25 21:35:29 -05:00
23a88ec6bb fix: search by imdb id 2025-07-24 23:31:03 -05:00
8 changed files with 89 additions and 8 deletions

View File

@@ -12,6 +12,11 @@ export default class extends Controller {
const autocompleteController = this.application.getControllerForElementAndIdentifier(this.element, 'symfony--ux-autocomplete--autocomplete') const autocompleteController = this.application.getControllerForElementAndIdentifier(this.element, 'symfony--ux-autocomplete--autocomplete')
window.location.href = `/search?term=${autocompleteController.tomSelect.lastValue}` window.location.href = `/search?term=${autocompleteController.tomSelect.lastValue}`
} }
document.querySelector("#search-button").addEventListener('click', (event) => {
event.preventDefault();
const autocompleteController = this.application.getControllerForElementAndIdentifier(this.element, 'symfony--ux-autocomplete--autocomplete')
window.location.href = `/search?term=${autocompleteController.tomSelect.lastQuery}`
});
this.element.addEventListener('autocomplete:pre-connect', this._onPreConnect); this.element.addEventListener('autocomplete:pre-connect', this._onPreConnect);
this.element.addEventListener('autocomplete:connect', this._onConnect); this.element.addEventListener('autocomplete:connect', this._onConnect);
} }

View File

@@ -0,0 +1,11 @@
<?php
namespace App\Base\Util;
class ImdbMatcher
{
public static function isMatch(string $imdbId): bool
{
return preg_match('/^tt\d{7}$/', $imdbId);
}
}

View File

@@ -2,6 +2,8 @@
namespace App\Search\Action\Handler; namespace App\Search\Action\Handler;
use App\Base\Util\ImdbMatcher;
use App\Search\Action\Result\RedirectToMediaResult;
use App\Search\Action\Result\SearchResult; use App\Search\Action\Result\SearchResult;
use App\Tmdb\Tmdb; use App\Tmdb\Tmdb;
use OneToMany\RichBundle\Contract\CommandInterface; use OneToMany\RichBundle\Contract\CommandInterface;
@@ -17,6 +19,13 @@ class SearchHandler implements HandlerInterface
public function handle(CommandInterface $command): ResultInterface public function handle(CommandInterface $command): ResultInterface
{ {
if (ImdbMatcher::isMatch($command->term)) {
$result = $this->tmdb->findByImdbId($command->term);
return new RedirectToMediaResult(
imdbId: $result->imdbId,
mediaType: $result->mediaType,
);
}
return new SearchResult( return new SearchResult(
term: $command->term, term: $command->term,
results: $this->tmdb->search($command->term) results: $this->tmdb->search($command->term)

View File

@@ -0,0 +1,13 @@
<?php
namespace App\Search\Action\Result;
use OneToMany\RichBundle\Contract\ResultInterface;
class RedirectToMediaResult implements ResultInterface
{
public function __construct(
public string $imdbId,
public string $mediaType,
) {}
}

View File

@@ -6,6 +6,7 @@ use App\Search\Action\Handler\GetMediaInfoHandler;
use App\Search\Action\Handler\SearchHandler; use App\Search\Action\Handler\SearchHandler;
use App\Search\Action\Input\GetMediaInfoInput; use App\Search\Action\Input\GetMediaInfoInput;
use App\Search\Action\Input\SearchInput; use App\Search\Action\Input\SearchInput;
use App\Search\Action\Result\RedirectToMediaResult;
use App\Tmdb\TmdbResult; use App\Tmdb\TmdbResult;
use App\Torrentio\Action\Command\GetMovieOptionsCommand; use App\Torrentio\Action\Command\GetMovieOptionsCommand;
use App\Torrentio\Action\Command\GetTvShowOptionsCommand; use App\Torrentio\Action\Command\GetTvShowOptionsCommand;
@@ -28,6 +29,13 @@ final class WebController extends AbstractController
): Response { ): Response {
$results = $this->searchHandler->handle($searchInput->toCommand()); $results = $this->searchHandler->handle($searchInput->toCommand());
if ($results instanceof RedirectToMediaResult) {
return $this->redirectToRoute('app_search_result', [
'mediaType' => $results->mediaType,
'imdbId' => $results->imdbId,
]);
}
return $this->render('search/results.html.twig', [ return $this->render('search/results.html.twig', [
'results' => $results, 'results' => $results,
]); ]);

View File

@@ -2,6 +2,7 @@
namespace App\Tmdb\Framework\Controller; namespace App\Tmdb\Framework\Controller;
use App\Base\Util\ImdbMatcher;
use App\Tmdb\Tmdb; use App\Tmdb\Tmdb;
use App\Tmdb\TmdbResult; use App\Tmdb\TmdbResult;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -17,17 +18,28 @@ class ApiController extends AbstractController
$results = []; $results = [];
$term = $request->query->get('query') ?? null; $term = $request->query->get('query') ?? null;
$term = trim($term);
if (null !== $term) { if (null !== $term) {
$tmdbResults = $tmdb->search($term); if (ImdbMatcher::isMatch($term)) {
$tmdbResult = $tmdb->findByImdbId($term);
foreach ($tmdbResults as $tmdbResult) { $results = [
/** @var TmdbResult $tmdbResult */ [
$results[] = [ 'data' => $tmdbResult,
'data' => $tmdbResult, 'text' => $tmdbResult->title,
'text' => $tmdbResult->title, 'value' => "$tmdbResult->mediaType|$tmdbResult->imdbId",
'value' => "$tmdbResult->mediaType|$tmdbResult->imdbId", ]
]; ];
} else {
$tmdbResults = $tmdb->search($term);
foreach ($tmdbResults as $tmdbResult) {
/** @var TmdbResult $tmdbResult */
$results[] = [
'data' => $tmdbResult,
'text' => $tmdbResult->title,
'value' => "$tmdbResult->mediaType|$tmdbResult->imdbId",
];
}
} }
} }

View File

@@ -185,6 +185,28 @@ class Tmdb
throw new \Exception("No results found for $id"); throw new \Exception("No results found for $id");
} }
public function findByImdbId(string $imdbId)
{
$finder = new Find($this->client);
$result = $finder->findBy($imdbId, ['external_source' => 'imdb_id']);
if (count($result['movie_results']) > 0) {
$result = $result['movie_results'][0];
$mediaType = MediaType::Movie->value;
} elseif (count($result['tv_results']) > 0) {
$result = $result['tv_results'][0];
$mediaType = MediaType::TvShow->value;
} elseif (count($result['tv_episode_results']) > 0) {
$result = $result['tv_episode_results'][0];
$mediaType = MediaType::TvShow->value;
}
$result['media_type'] = $mediaType;
$result = $this->mediaDetails($imdbId, $result['media_type']);
return $result;
}
public function movieDetails(string $id) public function movieDetails(string $id)
{ {
$client = new MovieRepository($this->client); $client = new MovieRepository($this->client);

View File

@@ -20,6 +20,7 @@
> >
</select> </select>
<button <button
id="search-button"
class="absolute top-1 right-1 flex items-center rounded class="absolute top-1 right-1 flex items-center rounded
bg-green-600 py-1 px-2.5 border border-transparent text-center bg-green-600 py-1 px-2.5 border border-transparent text-center
text-sm text-white transition-all text-sm text-white transition-all