Compare commits

..

3 Commits

9 changed files with 104 additions and 33 deletions

View File

@@ -1,16 +1,17 @@
FROM dunglas/frankenphp:php8.4
FROM registry.caldwell.digital/home/frankenphp:1.9.0-php8.5.0-ubuntu
ENV SERVER_NAME=":80"
ENV CADDY_GLOBAL_OPTIONS="auto_https off"
ENV APP_RUNTIME="Runtime\\FrankenPhpSymfony\\Runtime"
ENV APP_VERSION="0.0.1"
ENV SERVER_ROOT="/app/public"
RUN install-php-extensions \
pdo_mysql \
gd \
intl \
zip \
opcache
#RUN install-php-extensions \
# pdo_mysql \
# gd \
# intl \
# zip \
# opcache
RUN apt update && apt install -y wget

View File

@@ -23,6 +23,9 @@ services:
- mercure_data:/data
- mercure_config:/config
tty: true
ports:
- "8001:80"
command: "frankenphp php-server --root=/app/public"
environment:
TZ: America/Chicago
MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'

View File

@@ -3,6 +3,8 @@
frankenphp {
{$FRANKENPHP_CONFIG}
num_threads 10
max_threads 20
}
}

60
public/test.php Normal file
View File

@@ -0,0 +1,60 @@
<?php
require_once '../vendor/autoload.php';
use App\Torrentio\Result\ResultFactory;
$realDebridKey = "";
$tasks = [];
$results = [];
$start = microtime(true);
for ($i = 1; $i <= 20; $i++) {
$tasks[] = \Async\spawn(function () use ($i, &$results, &$realDebridKey) {
$baseUrl = "https://torrentio.strem.fun/providers%253Dyts%252Ceztv%252Crarbg%252C1337x%252Cthepiratebay%252Ckickasstorrents%252Ctorrentgalaxy%252Cmagnetdl%252Chorriblesubs%252Cnyaasi%7Csort%253Dqualitysize%7Cqualityfilter%253D480p%252Cscr%252Ccam%7Crealdebrid={$realDebridKey}/stream/movie/tt0412142:1:$i.json";
$options = \json_decode(file_get_contents($baseUrl), true);
foreach ($options['streams'] as $stream) {
if (!str_starts_with($stream['url'], "https")) {
continue;
}
if (
array_key_exists('behaviorHints', $stream) &&
array_key_exists('bingeGroup', $stream['behaviorHints'])
) {
$bingeGroup = $stream['behaviorHints']['bingeGroup'];
} else {
$bingeGroup = '-';
}
$result = ResultFactory::map(
$stream['url'],
$stream['title'],
$bingeGroup
);
$results[] = $result;
}
});
}
\Async\awaitAll($tasks);
$end = microtime(true) - $start;
dd($end, $results);
//
//
//// Spawn multiple concurrent coroutines
//Async\spawn(function() {
// echo "Starting coroutine 1\n";
// sleep(2); // Non-blocking in async context
// echo "Coroutine 1 completed\n";
//});
//
//Async\spawn(function() {
// echo "Starting coroutine 2\n";
// sleep(1); // Non-blocking in async context
// echo "Coroutine 2 completed\n";
//});
//
//echo "All coroutines started\n";

View File

@@ -11,9 +11,9 @@ readonly class MediaFileDto
public string $size,
) {}
public static function fromSplFileInfo(\SplFileInfo $fileInfo): self
public static function fromSplFileInfo(\SplFileInfo|false $fileInfo): self|false
{
return new static(
return false === $fileInfo ? false : new static(
path: $fileInfo->getRealPath(),
filename: $fileInfo->getFilename(),
extension: $fileInfo->getExtension(),

View File

@@ -2,10 +2,12 @@
namespace App\Tmdb;
use \Async;
use Aimeos\Map;
use App\Base\Enum\MediaType;
use App\ValueObject\ResultFactory;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\Cache\ItemInterface;
@@ -42,6 +44,7 @@ class Tmdb
public function __construct(
private readonly CacheItemPoolInterface $cache,
private readonly EventDispatcherInterface $eventDispatcher,
private readonly LoggerInterface $logger,
#[Autowire(env: 'TMDB_API')] string $apiKey,
) {
$this->client = new Client(
@@ -214,7 +217,6 @@ class Tmdb
if ($season['episode_count'] <= 0 || $season['name'] === 'Specials') {
continue;
}
$series['episodes'][$season['season_number']] = Map::from(
$client->getApi()->getSeason($series['id'], $season['season_number'])['episodes']
)->map(function ($data) {

View File

@@ -3,6 +3,7 @@
namespace App\Torrentio\Action\Handler;
use App\Base\Service\MediaFiles;
use App\Library\Dto\MediaFileDto;
use App\Tmdb\Tmdb;
use App\Torrentio\Action\Command\GetTvShowOptionsCommand;
use App\Torrentio\Action\Result\GetTvShowOptionsResult;
@@ -28,7 +29,7 @@ class GetTvShowOptionsHandler implements HandlerInterface
return new GetTvShowOptionsResult(
media: $media,
file: $file,
file: MediaFileDto::fromSplFileInfo($file),
season: $command->season,
episode: $command->episode,
results: $this->torrentio->fetchEpisodeResults(

View File

@@ -2,15 +2,15 @@
namespace App\Torrentio\Action\Result;
use App\Library\Dto\MediaFileDto;
use App\Tmdb\TmdbResult;
use OneToMany\RichBundle\Contract\ResultInterface;
use Symfony\Component\Finder\SplFileInfo;
class GetTvShowOptionsResult implements ResultInterface
{
public function __construct(
public TmdbResult $media,
public bool|SplFileInfo $file,
public MediaFileDto|false $file,
public string $season,
public string $episode,
public array $results

View File

@@ -13,6 +13,7 @@ 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;
@@ -26,6 +27,7 @@ final class WebController extends AbstractController
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
{
@@ -35,18 +37,18 @@ final class WebController extends AbstractController
$input->imdbId
);
return $cache->get($cacheId, function (ItemInterface $item) use ($input, $request) {
$results = $cache->get($cacheId, function (ItemInterface $item) use ($input, $request) {
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
$results = $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,
]);
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')]
@@ -61,18 +63,18 @@ final class WebController extends AbstractController
);
try {
return $cache->get($cacheId, function (ItemInterface $item) use ($input, $request) {
$results = $cache->get($cacheId, function (ItemInterface $item) use ($input) {
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
$results = $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,
]);
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',