Files
torsearch/src/Torrentio/Framework/Controller/WebController.php

103 lines
3.8 KiB
PHP

<?php
namespace App\Torrentio\Framework\Controller;
use App\Base\Service\Broadcaster;
use App\Torrentio\Action\Handler\GetMovieOptionsHandler;
use App\Torrentio\Action\Handler\GetTvShowOptionsHandler;
use App\Torrentio\Action\Input\GetMovieOptionsInput;
use App\Torrentio\Action\Input\GetTvShowOptionsInput;
use App\Torrentio\Exception\TorrentioRateLimitException;
use Carbon\Carbon;
use OneToMany\RichBundle\Contract\ResultInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\Cache;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
use Symfony\UX\Turbo\TurboBundle;
final class WebController extends AbstractController
{
public function __construct(
private readonly GetMovieOptionsHandler $getMovieOptionsHandler,
private readonly GetTvShowOptionsHandler $getTvShowOptionsHandler,
private readonly Broadcaster $broadcaster,
) {}
#[Cache(expires: 3600, public: false, mustRevalidate: true)]
#[Route('/torrentio/movies/{tmdbId}/{imdbId}', name: 'app_torrentio_movies')]
public function movieOptions(GetMovieOptionsInput $input, CacheInterface $cache, Request $request): Response
{
$cacheId = sprintf(
"page.torrentio.movies.%s.%s",
$input->tmdbId,
$input->imdbId
);
$results = $cache->get($cacheId, function (ItemInterface $item) use ($input, $request) {
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
return $this->getMovieOptionsHandler->handle($input->toCommand());
});
if ($request->headers->get('Turbo-Frame')) {
return $this->sendFragmentResponse($results, $request);
}
return $this->render('torrentio/movies.html.twig', [
'results' => $results,
]);
}
#[Route('/torrentio/tvshows/{tmdbId}/{imdbId}/{season?}/{episode?}', name: 'app_torrentio_tvshows')]
public function tvShowOptions(GetTvShowOptionsInput $input, CacheInterface $cache, Request $request): Response
{
$cacheId = sprintf(
"page.torrentio.tvshows.%s.%s.%s.%s",
$input->tmdbId,
$input->imdbId,
$input->season,
$input->episode,
);
try {
$results = $cache->get($cacheId, function (ItemInterface $item) use ($input) {
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
return $this->getTvShowOptionsHandler->handle($input->toCommand());
});
if ($request->headers->get('Turbo-Frame')) {
return $this->sendFragmentResponse($results, $request);
}
return $this->render('torrentio/tvshows.html.twig', [
'results' => $results,
]);
} catch (TorrentioRateLimitException $exception) {
$this->broadcaster->alert('Warning', 'Torrentio has rate limited your requests. Please wait a few minutes before trying again.', 'warning');
return $this->render('bare.html.twig',
[],
new Response('Too many requests',
Response::HTTP_TOO_MANY_REQUESTS,
['Retry-After' => 4000]
)
);
}
}
private function sendFragmentResponse(ResultInterface $result, Request $request): Response
{
$request->setRequestFormat(TurboBundle::STREAM_FORMAT);
return $this->renderBlock(
'torrentio/fragments.html.twig',
$request->query->get('block'),
[
'results' => $result,
'target' => $request->query->get('target')
]
);
}
}