Compare commits

...

5 Commits

18 changed files with 114 additions and 23 deletions

14
.dockerignore Normal file
View File

@@ -0,0 +1,14 @@
.git
.idea
.phpunit.cache
.php-cs-fixer.cache
.env.test
.gitignore
bolt.db
bash
build.xml
deploy.compose.yml
phpstan.dist.neon
phpunit.dist.xml
nomad.deploy.hcl
deployment.properties

View File

@@ -32,7 +32,7 @@ parameters:
app.cache.redis.host.default: 'redis://redis' app.cache.redis.host.default: 'redis://redis'
# Various configs # Various configs
app.default.version: '0.dev' app.default.version: '0.0.0-dev'
app.default.timezone: 'America/Chicago' app.default.timezone: 'America/Chicago'
# Auth # Auth

View File

@@ -10,6 +10,7 @@ templates
var var
vendor vendor
build.xml build.xml
.git
.env .env
.env.local .env.local
composer.json composer.json

View File

@@ -1,6 +1,6 @@
FROM code.caldwell.digital/home/torsearch-base:php8.4 FROM code.caldwell.digital/home/torsearch-base:php8.4
ARG APP_VERSION="0.dev" ARG APP_VERSION="0.0.0-dev"
ENV APP_VERSION="${APP_VERSION}" ENV APP_VERSION="${APP_VERSION}"
COPY . /app COPY . /app

View File

@@ -11,6 +11,4 @@ RUN install-php-extensions \
gd \ gd \
intl \ intl \
zip \ zip \
opcache && \ opcache
apt install -y wget && \
apt clean && apt autoremove

View File

@@ -0,0 +1,19 @@
ARG FRANKENPHP_TAG
FROM dunglas/frankenphp:${FRANKENPHP_TAG}
ENV SERVER_NAME=":80"
ENV CADDY_GLOBAL_OPTIONS="auto_https off"
ENV APP_RUNTIME="Runtime\\FrankenPhpSymfony\\Runtime"
ARG APP_VERSION="0.dev"
ENV APP_VERSION="${APP_VERSION}"
RUN install-php-extensions \
pdo_mysql \
gd \
intl \
zip \
opcache
RUN apk add --no-cache wget

View File

@@ -1,6 +1,9 @@
ARG APP_VERSION FROM code.caldwell.digital/home/torsearch-base-worker:php8.4-alpine
FROM code.caldwell.digital/home/torsearch-app:${APP_VERSION} ARG APP_VERSION="0.0.0-dev"
ENV APP_VERSION="${APP_VERSION}"
COPY . /app
ENTRYPOINT [ "php", "/app/bin/console", "messenger:consume", "scheduler_monitor" ] ENTRYPOINT [ "php", "/app/bin/console", "messenger:consume", "scheduler_monitor" ]

View File

@@ -1,10 +1,9 @@
ARG APP_VERSION FROM code.caldwell.digital/home/torsearch-base-worker:php8.4-alpine
FROM code.caldwell.digital/home/torsearch-app:${APP_VERSION} ARG APP_VERSION="0.0.0-dev"
ENV APP_VERSION="${APP_VERSION}"
RUN apt install -y wget && \ COPY . /app
apt autoremove && \
apt clean
ENTRYPOINT [ "php", "/app/bin/console", "messenger:consume", "async" ] ENTRYPOINT [ "php", "/app/bin/console", "messenger:consume", "async" ]

View File

@@ -2,16 +2,25 @@
namespace App\Base; namespace App\Base;
use App\Base\Dto\AppVersionDto;
use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
final class ConfigResolver final class ConfigResolver
{ {
const SEMVER_REGEX = '/^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/';
private array $messages = []; private array $messages = [];
public function __construct( public function __construct(
private readonly DenormalizerInterface $denormalizer,
#[Autowire(param: 'app.url')] #[Autowire(param: 'app.url')]
private readonly ?string $appUrl = null, private readonly ?string $appUrl = null,
#[Autowire(param: 'app.version')]
private readonly ?string $appVersion = null,
#[Autowire(param: 'app.debrid.real_debrid.key')] #[Autowire(param: 'app.debrid.real_debrid.key')]
private readonly ?string $realDebridApiKey = null, private readonly ?string $realDebridApiKey = null,
@@ -92,6 +101,13 @@ final class ConfigResolver
return $this->authOidcBypassFormLogin; return $this->authOidcBypassFormLogin;
} }
public function getAppVersion(): AppVersionDto
{
$matches = [];
preg_match(self::SEMVER_REGEX, $this->appVersion, $matches);
return $this->denormalizer->denormalize($matches, AppVersionDto::class);
}
public function getAuthConfig(): array public function getAuthConfig(): array
{ {
return [ return [

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Base\Dto;
use Symfony\Component\Serializer\Attribute\SerializedPath;
class AppVersionDto
{
#[SerializedPath('[1]')]
public string|int $major = 0;
#[SerializedPath('[2]')]
public string|int $minor = 0;
#[SerializedPath('[3]')]
public string|int $patch = 0;
#[SerializedPath('[4]')]
public ?string $pre = null;
#[SerializedPath('[5]')]
public ?string $build = null;
public function __toString()
{
return 'v' . $this->major . '.' . $this->minor . '.' . $this->patch . ($this->pre ? '-' . $this->pre : '') . ($this->build ? '+' . $this->build : '');
}
}

View File

@@ -2,12 +2,14 @@
namespace App\Base\Framework\Controller; namespace App\Base\Framework\Controller;
use App\Monitor\Action\Command\MonitorTvShowCommand;
use App\Monitor\Action\Handler\MonitorTvShowHandler; use App\Monitor\Action\Handler\MonitorTvShowHandler;
use App\Tmdb\TmdbClient; use App\Tmdb\TmdbClient;
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\Mailer\MailerInterface; use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Mime\Email; use Symfony\Component\Mime\Email;
use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Routing\Attribute\Route;
@@ -46,8 +48,9 @@ final class IndexController extends AbstractController
} }
#[Route('/test')] #[Route('/test')]
public function monitorTvShow(): Response public function monitorTvShow(MonitorTvShowHandler $handler): Response
{ {
// $handler->handle(new MonitorTvShowCommand(82));
return $this->render('index/test.html.twig', []); return $this->render('index/test.html.twig', []);
} }
} }

View File

@@ -17,7 +17,7 @@ class Torrentio
$results = $this->client->get($imdbCode, $cacheTags); $results = $this->client->get($imdbCode, $cacheTags);
if (true === $parseResults) { if (true === $parseResults) {
return $this->parse($results); return $this->parse($results, $imdbCode);
} }
return $results; return $results;
@@ -33,13 +33,13 @@ class Torrentio
} }
if (true === $parseResults) { if (true === $parseResults) {
return $this->parse($results); return $this->parse($results, $imdbId);
} }
return $results; return $results;
} }
public function parse(array $data): array public function parse(array $data, string $imdbId): array
{ {
$results = []; $results = [];
foreach ($data['streams'] as $stream) { foreach ($data['streams'] as $stream) {
@@ -59,7 +59,8 @@ class Torrentio
$result = ResultFactory::map( $result = ResultFactory::map(
$stream['url'], $stream['url'],
$stream['title'], $stream['title'],
$bingeGroup $bingeGroup,
$imdbId
); );
$results[] = $result; $results[] = $result;

View File

@@ -18,7 +18,8 @@ class ResultFactory
public static function map( public static function map(
string $url, string $url,
string $title, string $title,
string $bingeGroup = "-" string $bingeGroup = "-",
string $imdbId = "-",
) { ) {
$ptn = (object) (new PTN())->parse($title); $ptn = (object) (new PTN())->parse($title);
return new TorrentioResult( return new TorrentioResult(
@@ -40,7 +41,8 @@ class ResultFactory
self::setLanguages($title), self::setLanguages($title),
self::setLanguageFlags($title), self::setLanguageFlags($title),
false, false,
uniqid() uniqid(),
$imdbId,
); );
} }

View File

@@ -23,6 +23,7 @@ class TorrentioResult
public ?array $languages = [], public ?array $languages = [],
public ?string $languageFlags = "-", public ?string $languageFlags = "-",
public ?bool $selected = false, public ?bool $selected = false,
public ?string $localId = "-" public ?string $localId = "-",
public ?string $imdbId = "-",
) {} ) {}
} }

View File

@@ -2,10 +2,13 @@
namespace App\Twig\Extensions; namespace App\Twig\Extensions;
use App\Base\ConfigResolver;
use App\Base\Dto\AppVersionDto;
use App\Base\Service\MediaFiles; use App\Base\Service\MediaFiles;
use App\Torrentio\Action\Result\GetTvShowOptionsResult; use App\Torrentio\Action\Result\GetTvShowOptionsResult;
use App\Twig\Dto\EpisodeIdDto; use App\Twig\Dto\EpisodeIdDto;
use ChrisUllyott\FileSize; use ChrisUllyott\FileSize;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Twig\Attribute\AsTwigFilter; use Twig\Attribute\AsTwigFilter;
use Twig\Attribute\AsTwigFunction; use Twig\Attribute\AsTwigFunction;
@@ -13,9 +16,16 @@ class UtilExtension
{ {
public function __construct( public function __construct(
private readonly ConfigResolver $config,
private readonly MediaFiles $mediaFiles, private readonly MediaFiles $mediaFiles,
) {} ) {}
#[AsTwigFunction('app_version')]
public function app_version(): AppVersionDto
{
return $this->config->getAppVersion();
}
#[AsTwigFunction('uniqid')] #[AsTwigFunction('uniqid')]
public function uniqid(): string public function uniqid(): string
{ {

View File

@@ -20,7 +20,7 @@
{% block body %}{% endblock %} {% block body %}{% endblock %}
<div class="mt-2 inline-flex gap-4 justify-between text-white"> <div class="mt-2 inline-flex gap-4 justify-between text-white">
<a class="text-sm" href="{{ path('app_login') }}">Sign In</a> <a class="text-sm" href="{{ path('app_login') }}">Sign In</a>
<span class="text-sm">v{{ version }}</span> <span class="text-sm">{{ app_version() }}</span>
</div> </div>
</div> </div>
</body> </body>

View File

@@ -55,7 +55,7 @@
</div> </div>
</a> </a>
<p class="px-4 pt-1 inline-flex justify-center"> <p class="px-4 pt-1 inline-flex justify-center">
<small class="text-white text-xs">v{{ version|default('0.0') }}</small> <small class="text-white text-xs">{{ app_version() }}</small>
</p> </p>
</div> </div>
</nav> </nav>

View File

@@ -52,7 +52,7 @@
provider="{{ result.provider }}" provider="{{ result.provider }}"
languages="{{ result.languages|json_encode }}" languages="{{ result.languages|json_encode }}"
media-type="{{ results.media.mediaType }}" media-type="{{ results.media.mediaType }}"
imdb-id="{{ results.media.imdbId }}" imdb-id="{{ result.imdbId }}"
filename="{{ result.filename }}" filename="{{ result.filename }}"
data-local-id="{{ result.localId }}" data-local-id="{{ result.localId }}"
{% if "tvshows" == results.media.mediaType %} {% if "tvshows" == results.media.mediaType %}