Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ccce0303c3 | |||
| 9eaa120257 | |||
| d6cbb53da6 |
@@ -29,3 +29,11 @@ controllersMonitor:
|
||||
type: attribute
|
||||
defaults:
|
||||
schemes: ['https']
|
||||
|
||||
controllersTorrentio:
|
||||
resource:
|
||||
path: ../src/Torrentio/Framework/Controller
|
||||
namespace: App\Torrentio\Framework\Controller
|
||||
type: attribute
|
||||
defaults:
|
||||
schemes: ['https']
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Monitor\Framework\Entity;
|
||||
|
||||
use App\Monitor\Framework\Repository\MonitorRepository;
|
||||
use App\User\Framework\Entity\User;
|
||||
use Carbon\Carbon;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
@@ -148,7 +149,7 @@ class Monitor
|
||||
|
||||
public function getLastSearch(): ?\DateTimeInterface
|
||||
{
|
||||
return $this->lastSearch;
|
||||
return Carbon::parse($this->lastSearch);
|
||||
}
|
||||
|
||||
public function setLastSearch(?\DateTimeInterface $lastSearch): static
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Monitor\Action\Command\MonitorTvEpisodeCommand;
|
||||
use App\Monitor\Action\Command\MonitorTvSeasonCommand;
|
||||
use App\Monitor\Action\Command\MonitorTvShowCommand;
|
||||
use App\Monitor\Framework\Repository\MonitorRepository;
|
||||
use Carbon\Carbon;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
use Symfony\Component\Scheduler\Attribute\AsCronTask;
|
||||
@@ -23,6 +24,8 @@ class MonitorDispatcher
|
||||
public function __invoke() {
|
||||
$this->logger->info('[MonitorDispatcher] Executing MonitorDispatcher');
|
||||
|
||||
$this->cleanupStuckMonitors();
|
||||
|
||||
$monitorHandlers = [
|
||||
'movie' => MonitorMovieCommand::class,
|
||||
'tvepisode' => MonitorTvEpisodeCommand::class,
|
||||
@@ -41,4 +44,18 @@ class MonitorDispatcher
|
||||
$this->bus->dispatch(new $command($monitor->getId()));
|
||||
}
|
||||
}
|
||||
|
||||
private function cleanupStuckMonitors(): void
|
||||
{
|
||||
$hoursStuck = 4;
|
||||
$monitors = $this->monitorRepository->findBy(['status' => 'In Progress']);
|
||||
foreach ($monitors as $monitor) {
|
||||
// Reset the status to active so it will be executed again
|
||||
if ($monitor->getLastSearch()->diffInHours(Carbon::today()) > $hoursStuck) {
|
||||
$this->logger->info('[MonitorDispatcher] Cleaning up monitor: ' . $monitor->getId() . ' (' . $monitor->getTitle() . '), resetting status to \'Active\' from \''. $monitor->getStatus() .'\' after being stuck for ' . $hoursStuck . ' hours.');
|
||||
$monitor->setStatus('Active');
|
||||
}
|
||||
}
|
||||
$this->monitorRepository->getEntityManager()->flush();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ class Torrentio
|
||||
]);
|
||||
}
|
||||
|
||||
public function search(string $imdbCode, string $type, array $filter = []): array
|
||||
public function search(string $imdbCode, string $type, bool $parseResults = true): array
|
||||
{
|
||||
$cacheKey = "torrentio.{$imdbCode}";
|
||||
|
||||
@@ -56,10 +56,14 @@ class Torrentio
|
||||
return [];
|
||||
});
|
||||
|
||||
return $this->parse($results, $filter);
|
||||
if (true === $parseResults) {
|
||||
return $this->parse($results);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function fetchEpisodeResults(string $imdbId, int $season, int $episode): array
|
||||
public function fetchEpisodeResults(string $imdbId, int $season, int $episode, bool $parseResults = true): array
|
||||
{
|
||||
$cacheKey = "torrentio.$imdbId.$season.$episode";
|
||||
$results = $this->cache->get($cacheKey, function (ItemInterface $item) use ($imdbId, $season, $episode) {
|
||||
@@ -86,18 +90,15 @@ class Torrentio
|
||||
throw new TorrentioRateLimitException();
|
||||
}
|
||||
|
||||
return $this->parse($results, []);
|
||||
}
|
||||
|
||||
public function parse(array $data, array $filter): array
|
||||
{
|
||||
$ruleEngine = new RuleEngine();
|
||||
foreach ($filter as $rule => $value) {
|
||||
if ('resolution' === $rule) {
|
||||
$ruleEngine->addRule(new Resolution($value));
|
||||
}
|
||||
if (true === $parseResults) {
|
||||
return $this->parse($results);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function parse(array $data): array
|
||||
{
|
||||
$results = [];
|
||||
foreach ($data['streams'] as $stream) {
|
||||
if (!str_starts_with($stream['url'], "https")) {
|
||||
@@ -119,9 +120,7 @@ class Torrentio
|
||||
$bingeGroup
|
||||
);
|
||||
|
||||
if ($ruleEngine->validateAll($result)) {
|
||||
$results[] = $result;
|
||||
}
|
||||
$results[] = $result;
|
||||
}
|
||||
|
||||
return $results;
|
||||
|
||||
116
src/Torrentio/Framework/Controller/ApiController.php
Normal file
116
src/Torrentio/Framework/Controller/ApiController.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace App\Torrentio\Framework\Controller;
|
||||
|
||||
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\Client\Torrentio;
|
||||
use App\Torrentio\Exception\TorrentioRateLimitException;
|
||||
use App\Util\Broadcaster;
|
||||
use Carbon\Carbon;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
|
||||
final class ApiController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly GetMovieOptionsHandler $getMovieOptionsHandler,
|
||||
private readonly GetTvShowOptionsHandler $getTvShowOptionsHandler,
|
||||
private readonly Broadcaster $broadcaster,
|
||||
private readonly Torrentio $torrentio,
|
||||
) {}
|
||||
|
||||
#[Route('/api/torrentio/{imdbId}/{season?}/{episode?}', name: 'api_torrentio')]
|
||||
public function api(string $imdbId, ?int $season, ?int $episode): Response
|
||||
{
|
||||
if (null !== $season && null !== $episode) {
|
||||
return $this->json(
|
||||
$this->torrentio->fetchEpisodeResults($imdbId, $season, $episode, false)
|
||||
);
|
||||
}
|
||||
return $this->json(
|
||||
$this->torrentio->search($imdbId, 'movies', false),
|
||||
);
|
||||
}
|
||||
|
||||
#[Route('/torrentio/movies/{tmdbId}/{imdbId}', name: 'app_torrentio_movies')]
|
||||
public function movieOptions(GetMovieOptionsInput $input, CacheInterface $cache): Response
|
||||
{
|
||||
$cacheId = sprintf(
|
||||
"page.torrentio.movies.%s.%s",
|
||||
$input->tmdbId,
|
||||
$input->imdbId
|
||||
);
|
||||
|
||||
return $cache->get($cacheId, function (ItemInterface $item) use ($input) {
|
||||
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
||||
$results = $this->getMovieOptionsHandler->handle($input->toCommand());
|
||||
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): Response
|
||||
{
|
||||
$cacheId = sprintf(
|
||||
"page.torrentio.tvshows.%s.%s.%s.%s",
|
||||
$input->tmdbId,
|
||||
$input->imdbId,
|
||||
$input->season,
|
||||
$input->episode,
|
||||
);
|
||||
|
||||
try {
|
||||
// return $cache->get($cacheId, function (ItemInterface $item) use ($input) {
|
||||
// $item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
||||
$results = $this->getTvShowOptionsHandler->handle($input->toCommand());
|
||||
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]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[Route('/torrentio/tvshows/clear/{tmdbId}/{imdbId}/{season?}/{episode?}', name: 'app_clear_torrentio_tvshows')]
|
||||
public function clearTvShowOptions(GetTvShowOptionsInput $input, CacheInterface $cache, Request $request): Response
|
||||
{
|
||||
$cacheId = sprintf(
|
||||
"page.torrentio.tvshows.%s.%s.%s.%s",
|
||||
$input->tmdbId,
|
||||
$input->imdbId,
|
||||
$input->season,
|
||||
$input->episode,
|
||||
);
|
||||
$cache->delete($cacheId);
|
||||
|
||||
$this->broadcaster->alert(
|
||||
title: 'Success',
|
||||
message: 'Torrentio cache Cleared.'
|
||||
);
|
||||
|
||||
return $cache->get($cacheId, function (ItemInterface $item) use ($input) {
|
||||
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
||||
$results = $this->getTvShowOptionsHandler->handle($input->toCommand());
|
||||
return $this->render('torrentio/tvshows.html.twig', [
|
||||
'results' => $results,
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
namespace App\Torrentio\Framework\Controller;
|
||||
|
||||
use App\Torrentio\Action\Handler\GetMovieOptionsHandler;
|
||||
use App\Torrentio\Action\Handler\GetTvShowOptionsHandler;
|
||||
@@ -16,7 +16,7 @@ use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
|
||||
final class TorrentioController extends AbstractController
|
||||
final class WebController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly GetMovieOptionsHandler $getMovieOptionsHandler,
|
||||
@@ -54,13 +54,13 @@ final class TorrentioController extends AbstractController
|
||||
);
|
||||
|
||||
try {
|
||||
return $cache->get($cacheId, function (ItemInterface $item) use ($input) {
|
||||
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
||||
// return $cache->get($cacheId, function (ItemInterface $item) use ($input) {
|
||||
// $item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
||||
$results = $this->getTvShowOptionsHandler->handle($input->toCommand());
|
||||
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',
|
||||
Reference in New Issue
Block a user