Compare commits
3 Commits
v0.25.2
...
dev-php85-
| Author | SHA1 | Date | |
|---|---|---|---|
| 0964abdf37 | |||
| 3b0ba81ce3 | |||
| dc2845d74d |
15
Dockerfile
15
Dockerfile
@@ -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 SERVER_NAME=":80"
|
||||||
ENV CADDY_GLOBAL_OPTIONS="auto_https off"
|
ENV CADDY_GLOBAL_OPTIONS="auto_https off"
|
||||||
ENV APP_RUNTIME="Runtime\\FrankenPhpSymfony\\Runtime"
|
ENV APP_RUNTIME="Runtime\\FrankenPhpSymfony\\Runtime"
|
||||||
ENV APP_VERSION="0.0.1"
|
ENV APP_VERSION="0.0.1"
|
||||||
|
ENV SERVER_ROOT="/app/public"
|
||||||
|
|
||||||
RUN install-php-extensions \
|
#RUN install-php-extensions \
|
||||||
pdo_mysql \
|
# pdo_mysql \
|
||||||
gd \
|
# gd \
|
||||||
intl \
|
# intl \
|
||||||
zip \
|
# zip \
|
||||||
opcache
|
# opcache
|
||||||
|
|
||||||
RUN apt update && apt install -y wget
|
RUN apt update && apt install -y wget
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ services:
|
|||||||
- mercure_data:/data
|
- mercure_data:/data
|
||||||
- mercure_config:/config
|
- mercure_config:/config
|
||||||
tty: true
|
tty: true
|
||||||
|
ports:
|
||||||
|
- "8001:80"
|
||||||
|
command: "frankenphp php-server --root=/app/public"
|
||||||
environment:
|
environment:
|
||||||
TZ: America/Chicago
|
TZ: America/Chicago
|
||||||
MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
|
MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
frankenphp {
|
frankenphp {
|
||||||
{$FRANKENPHP_CONFIG}
|
{$FRANKENPHP_CONFIG}
|
||||||
|
num_threads 10
|
||||||
|
max_threads 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
60
public/test.php
Normal file
60
public/test.php
Normal 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";
|
||||||
|
|
||||||
@@ -11,9 +11,9 @@ readonly class MediaFileDto
|
|||||||
public string $size,
|
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(),
|
path: $fileInfo->getRealPath(),
|
||||||
filename: $fileInfo->getFilename(),
|
filename: $fileInfo->getFilename(),
|
||||||
extension: $fileInfo->getExtension(),
|
extension: $fileInfo->getExtension(),
|
||||||
|
|||||||
@@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
namespace App\Tmdb;
|
namespace App\Tmdb;
|
||||||
|
|
||||||
|
use \Async;
|
||||||
use Aimeos\Map;
|
use Aimeos\Map;
|
||||||
use App\Base\Enum\MediaType;
|
use App\Base\Enum\MediaType;
|
||||||
use App\ValueObject\ResultFactory;
|
use App\ValueObject\ResultFactory;
|
||||||
use Psr\Cache\CacheItemPoolInterface;
|
use Psr\Cache\CacheItemPoolInterface;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Symfony\Contracts\Cache\ItemInterface;
|
use Symfony\Contracts\Cache\ItemInterface;
|
||||||
@@ -42,6 +44,7 @@ class Tmdb
|
|||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly CacheItemPoolInterface $cache,
|
private readonly CacheItemPoolInterface $cache,
|
||||||
private readonly EventDispatcherInterface $eventDispatcher,
|
private readonly EventDispatcherInterface $eventDispatcher,
|
||||||
|
private readonly LoggerInterface $logger,
|
||||||
#[Autowire(env: 'TMDB_API')] string $apiKey,
|
#[Autowire(env: 'TMDB_API')] string $apiKey,
|
||||||
) {
|
) {
|
||||||
$this->client = new Client(
|
$this->client = new Client(
|
||||||
@@ -214,7 +217,6 @@ class Tmdb
|
|||||||
if ($season['episode_count'] <= 0 || $season['name'] === 'Specials') {
|
if ($season['episode_count'] <= 0 || $season['name'] === 'Specials') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$series['episodes'][$season['season_number']] = Map::from(
|
$series['episodes'][$season['season_number']] = Map::from(
|
||||||
$client->getApi()->getSeason($series['id'], $season['season_number'])['episodes']
|
$client->getApi()->getSeason($series['id'], $season['season_number'])['episodes']
|
||||||
)->map(function ($data) {
|
)->map(function ($data) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Torrentio\Action\Handler;
|
namespace App\Torrentio\Action\Handler;
|
||||||
|
|
||||||
use App\Base\Service\MediaFiles;
|
use App\Base\Service\MediaFiles;
|
||||||
|
use App\Library\Dto\MediaFileDto;
|
||||||
use App\Tmdb\Tmdb;
|
use App\Tmdb\Tmdb;
|
||||||
use App\Torrentio\Action\Command\GetTvShowOptionsCommand;
|
use App\Torrentio\Action\Command\GetTvShowOptionsCommand;
|
||||||
use App\Torrentio\Action\Result\GetTvShowOptionsResult;
|
use App\Torrentio\Action\Result\GetTvShowOptionsResult;
|
||||||
@@ -28,7 +29,7 @@ class GetTvShowOptionsHandler implements HandlerInterface
|
|||||||
|
|
||||||
return new GetTvShowOptionsResult(
|
return new GetTvShowOptionsResult(
|
||||||
media: $media,
|
media: $media,
|
||||||
file: $file,
|
file: MediaFileDto::fromSplFileInfo($file),
|
||||||
season: $command->season,
|
season: $command->season,
|
||||||
episode: $command->episode,
|
episode: $command->episode,
|
||||||
results: $this->torrentio->fetchEpisodeResults(
|
results: $this->torrentio->fetchEpisodeResults(
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
|
|
||||||
namespace App\Torrentio\Action\Result;
|
namespace App\Torrentio\Action\Result;
|
||||||
|
|
||||||
|
use App\Library\Dto\MediaFileDto;
|
||||||
use App\Tmdb\TmdbResult;
|
use App\Tmdb\TmdbResult;
|
||||||
use OneToMany\RichBundle\Contract\ResultInterface;
|
use OneToMany\RichBundle\Contract\ResultInterface;
|
||||||
use Symfony\Component\Finder\SplFileInfo;
|
|
||||||
|
|
||||||
class GetTvShowOptionsResult implements ResultInterface
|
class GetTvShowOptionsResult implements ResultInterface
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public TmdbResult $media,
|
public TmdbResult $media,
|
||||||
public bool|SplFileInfo $file,
|
public MediaFileDto|false $file,
|
||||||
public string $season,
|
public string $season,
|
||||||
public string $episode,
|
public string $episode,
|
||||||
public array $results
|
public array $results
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use OneToMany\RichBundle\Contract\ResultInterface;
|
|||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\HttpKernel\Attribute\Cache;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
use Symfony\Contracts\Cache\CacheInterface;
|
use Symfony\Contracts\Cache\CacheInterface;
|
||||||
use Symfony\Contracts\Cache\ItemInterface;
|
use Symfony\Contracts\Cache\ItemInterface;
|
||||||
@@ -26,6 +27,7 @@ final class WebController extends AbstractController
|
|||||||
private readonly Broadcaster $broadcaster,
|
private readonly Broadcaster $broadcaster,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
#[Cache(expires: 3600, public: false, mustRevalidate: true)]
|
||||||
#[Route('/torrentio/movies/{tmdbId}/{imdbId}', name: 'app_torrentio_movies')]
|
#[Route('/torrentio/movies/{tmdbId}/{imdbId}', name: 'app_torrentio_movies')]
|
||||||
public function movieOptions(GetMovieOptionsInput $input, CacheInterface $cache, Request $request): Response
|
public function movieOptions(GetMovieOptionsInput $input, CacheInterface $cache, Request $request): Response
|
||||||
{
|
{
|
||||||
@@ -35,9 +37,10 @@ final class WebController extends AbstractController
|
|||||||
$input->imdbId
|
$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));
|
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
||||||
$results = $this->getMovieOptionsHandler->handle($input->toCommand());
|
return $this->getMovieOptionsHandler->handle($input->toCommand());
|
||||||
|
});
|
||||||
|
|
||||||
if ($request->headers->get('Turbo-Frame')) {
|
if ($request->headers->get('Turbo-Frame')) {
|
||||||
return $this->sendFragmentResponse($results, $request);
|
return $this->sendFragmentResponse($results, $request);
|
||||||
@@ -46,7 +49,6 @@ final class WebController extends AbstractController
|
|||||||
return $this->render('torrentio/movies.html.twig', [
|
return $this->render('torrentio/movies.html.twig', [
|
||||||
'results' => $results,
|
'results' => $results,
|
||||||
]);
|
]);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/torrentio/tvshows/{tmdbId}/{imdbId}/{season?}/{episode?}', name: 'app_torrentio_tvshows')]
|
#[Route('/torrentio/tvshows/{tmdbId}/{imdbId}/{season?}/{episode?}', name: 'app_torrentio_tvshows')]
|
||||||
@@ -61,9 +63,10 @@ final class WebController extends AbstractController
|
|||||||
);
|
);
|
||||||
|
|
||||||
try {
|
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));
|
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
||||||
$results = $this->getTvShowOptionsHandler->handle($input->toCommand());
|
return $this->getTvShowOptionsHandler->handle($input->toCommand());
|
||||||
|
});
|
||||||
|
|
||||||
if ($request->headers->get('Turbo-Frame')) {
|
if ($request->headers->get('Turbo-Frame')) {
|
||||||
return $this->sendFragmentResponse($results, $request);
|
return $this->sendFragmentResponse($results, $request);
|
||||||
@@ -72,7 +75,6 @@ final class WebController extends AbstractController
|
|||||||
return $this->render('torrentio/tvshows.html.twig', [
|
return $this->render('torrentio/tvshows.html.twig', [
|
||||||
'results' => $results,
|
'results' => $results,
|
||||||
]);
|
]);
|
||||||
});
|
|
||||||
} catch (TorrentioRateLimitException $exception) {
|
} catch (TorrentioRateLimitException $exception) {
|
||||||
$this->broadcaster->alert('Warning', 'Torrentio has rate limited your requests. Please wait a few minutes before trying again.', 'warning');
|
$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',
|
return $this->render('bare.html.twig',
|
||||||
|
|||||||
Reference in New Issue
Block a user