Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ca89eff236 | |||
| 53da7a746b | |||
| 981699bc13 | |||
| 52f460ff62 | |||
| a42e0d4d1a | |||
| 3e4a2d9bb1 | |||
| af8a30826c | |||
| 09e1c75826 | |||
| f1b8b34359 | |||
| 6f9db68664 | |||
| aeb706b5af |
14
.dockerignore
Normal file
14
.dockerignore
Normal 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
|
||||||
7
bash/build_base.sh
Executable file
7
bash/build_base.sh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
# torsearch-app is built from this base, and torsearch-worker & torsearch-scheduler are built from torsearch-app
|
||||||
|
# This image is used to speed up build times
|
||||||
|
export FRANKENPHP_TAG=php8.4
|
||||||
|
|
||||||
|
docker buildx build --platform=linux/amd64 -f docker/Dockerfile.base -t code.caldwell.digital/home/torsearch-base:${FRANKENPHP_TAG} -t code.caldwell.digital/home/torsearch-base:latest --build-arg "FRANKENPHP_TAG=${FRANKENPHP_TAG}" .
|
||||||
|
docker push code.caldwell.digital/home/torsearch-base:${FRANKENPHP_TAG}
|
||||||
|
docker push code.caldwell.digital/home/torsearch-base:latest
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ services:
|
|||||||
app:
|
app:
|
||||||
image: registry.caldwell.digital/home/torsearch-app:${TAG}
|
image: registry.caldwell.digital/home/torsearch-app:${TAG}
|
||||||
ports:
|
ports:
|
||||||
- '8001:80'
|
- "${SWARM_PORT}:80"
|
||||||
environment:
|
environment:
|
||||||
MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
|
MERCURE_PUBLISHER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
|
||||||
MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
|
MERCURE_SUBSCRIBER_JWT_KEY: '!ChangeThisMercureHubJWTSecretKey!'
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ templates
|
|||||||
var
|
var
|
||||||
vendor
|
vendor
|
||||||
build.xml
|
build.xml
|
||||||
|
.git
|
||||||
.env
|
.env
|
||||||
.env.local
|
.env.local
|
||||||
composer.json
|
composer.json
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
FROM code.caldwell.digital/torsearch/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
|
||||||
|
|||||||
14
docker/Dockerfile.base.app
Normal file
14
docker/Dockerfile.base.app
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
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"
|
||||||
|
|
||||||
|
RUN install-php-extensions \
|
||||||
|
pdo_mysql \
|
||||||
|
gd \
|
||||||
|
intl \
|
||||||
|
zip \
|
||||||
|
opcache
|
||||||
19
docker/Dockerfile.base.worker
Normal file
19
docker/Dockerfile.base.worker
Normal 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
|
||||||
@@ -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" ]
|
||||||
|
|
||||||
|
|||||||
@@ -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", "async" ]
|
ENTRYPOINT [ "php", "/app/bin/console", "messenger:consume", "async" ]
|
||||||
|
|
||||||
|
|||||||
@@ -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 [
|
||||||
|
|||||||
24
src/Base/Dto/AppVersionDto.php
Normal file
24
src/Base/Dto/AppVersionDto.php
Normal 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 : '');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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', []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ readonly class MonitorTvEpisodeHandler implements HandlerInterface
|
|||||||
$monitor = $this->monitorRepository->find($command->movieMonitorId);
|
$monitor = $this->monitorRepository->find($command->movieMonitorId);
|
||||||
$this->logger->info('> [MonitorTvEpisodeHandler] Executing MonitorTvEpisodeHandler for ' . $monitor->getTitle() . ' season ' . $monitor->getSeason() . ' episode ' . $monitor->getEpisode());
|
$this->logger->info('> [MonitorTvEpisodeHandler] Executing MonitorTvEpisodeHandler for ' . $monitor->getTitle() . ' season ' . $monitor->getSeason() . ' episode ' . $monitor->getEpisode());
|
||||||
|
|
||||||
$episodeData = $this->tmdb->episodeDetails($monitor->getTmdbId(), $monitor->getSeason(), $monitor->getEpisode());
|
$episodeData = $this->tmdb->tvEpisodeDetails($monitor->getTmdbId(), $monitor->getSeason(), $monitor->getEpisode());
|
||||||
|
|
||||||
if (null === $monitor->getAirDate() && null !== $episodeData->episodeAirDate && "" !== $episodeData->episodeAirDate) {
|
if (null === $monitor->getAirDate() && null !== $episodeData->episodeAirDate && "" !== $episodeData->episodeAirDate) {
|
||||||
$monitor->setAirDate(Carbon::parse($episodeData->episodeAirDate));
|
$monitor->setAirDate(Carbon::parse($episodeData->episodeAirDate));
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use App\Monitor\Action\Command\MonitorTvEpisodeCommand;
|
|||||||
use App\Monitor\Action\Result\MonitorTvShowResult;
|
use App\Monitor\Action\Result\MonitorTvShowResult;
|
||||||
use App\Monitor\Framework\Entity\Monitor;
|
use App\Monitor\Framework\Entity\Monitor;
|
||||||
use App\Monitor\Framework\Repository\MonitorRepository;
|
use App\Monitor\Framework\Repository\MonitorRepository;
|
||||||
|
use App\Tmdb\Dto\TmdbEpisodeDto;
|
||||||
use App\Tmdb\TmdbClient;
|
use App\Tmdb\TmdbClient;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
@@ -61,8 +62,9 @@ readonly class MonitorTvShowHandler implements HandlerInterface
|
|||||||
if ($downloadedEpisodes->count() !== $episodesInShow->count()) {
|
if ($downloadedEpisodes->count() !== $episodesInShow->count()) {
|
||||||
// Dispatch Episode commands for each missing Episode
|
// Dispatch Episode commands for each missing Episode
|
||||||
foreach ($episodesInShow as $episode) {
|
foreach ($episodesInShow as $episode) {
|
||||||
|
/** @var TmdbEpisodeDto $episode */
|
||||||
// Only monitor future episodes
|
// Only monitor future episodes
|
||||||
$this->logger->info('> [MonitorTvShowHandler] Evaluating "' . $monitor->getTitle() . '", season "' . $episode['season_number'] . '" episode "' . $episode['episode_number'] . '"');
|
$this->logger->info('> [MonitorTvShowHandler] Evaluating "' . $monitor->getTitle() . '", season "' . $episode->seasonNumber . '" episode "' . $episode->episodeNumber . '"');
|
||||||
$episodeInFuture = $this->episodeReleasedAfterMonitorCreated($monitor->getCreatedAt(), $episode);
|
$episodeInFuture = $this->episodeReleasedAfterMonitorCreated($monitor->getCreatedAt(), $episode);
|
||||||
$this->logger->info('> [MonitorTvShowHandler] ...Released after monitor started? ' . (true === $episodeInFuture ? 'YES' : 'NO'));
|
$this->logger->info('> [MonitorTvShowHandler] ...Released after monitor started? ' . (true === $episodeInFuture ? 'YES' : 'NO'));
|
||||||
if (false === $episodeInFuture) {
|
if (false === $episodeInFuture) {
|
||||||
@@ -94,9 +96,9 @@ readonly class MonitorTvShowHandler implements HandlerInterface
|
|||||||
->setImdbId($monitor->getImdbId())
|
->setImdbId($monitor->getImdbId())
|
||||||
->setTitle($monitor->getTitle())
|
->setTitle($monitor->getTitle())
|
||||||
->setMonitorType('tvepisode')
|
->setMonitorType('tvepisode')
|
||||||
->setSeason($episode['season_number'])
|
->setSeason($episode->seasonNumber)
|
||||||
->setEpisode($episode['episode_number'])
|
->setEpisode($episode->episodeNumber)
|
||||||
->setAirDate($episode['air_date'] !== null && $episode['air_date'] !== "" ? Carbon::parse($episode['air_date']) : null)
|
->setAirDate($episode->airDate !== null && $episode->airDate !== "" ? Carbon::parse($episode->airDate) : null)
|
||||||
->setCreatedAt(new DateTimeImmutable())
|
->setCreatedAt(new DateTimeImmutable())
|
||||||
->setSearchCount(0)
|
->setSearchCount(0)
|
||||||
->setStatus('New');
|
->setStatus('New');
|
||||||
@@ -128,29 +130,29 @@ readonly class MonitorTvShowHandler implements HandlerInterface
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function episodeReleasedAfterMonitorCreated(string|DateTimeImmutable $monitorStartDate, array $episodeInShow): bool
|
private function episodeReleasedAfterMonitorCreated(string|DateTimeImmutable $monitorStartDate, TmdbEpisodeDto $episodeInShow): bool
|
||||||
{
|
{
|
||||||
$monitorStartDate = Carbon::parse($monitorStartDate)->setTime(0, 0);
|
$monitorStartDate = Carbon::parse($monitorStartDate)->setTime(0, 0);
|
||||||
$episodeAirDate = Carbon::parse($episodeInShow['air_date']);
|
$episodeAirDate = Carbon::parse($episodeInShow->airDate);
|
||||||
return $episodeAirDate >= $monitorStartDate;
|
return $episodeAirDate >= $monitorStartDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function episodeExists(array $episodeInShow, Map $downloadedEpisodes): bool
|
private function episodeExists(TmdbEpisodeDto $episodeInShow, Map $downloadedEpisodes): bool
|
||||||
{
|
{
|
||||||
return $downloadedEpisodes->filter(
|
return $downloadedEpisodes->filter(
|
||||||
fn (object $episode) => $episode->episode === $episodeInShow['episode_number']
|
fn (object $episode) => $episode->episode === $episodeInShow->episodeNumber
|
||||||
&& $episode->season === $episodeInShow['season_number']
|
&& $episode->season === $episodeInShow->seasonNumber
|
||||||
)->count() > 0;
|
)->count() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function monitorExists(Monitor $monitor, array $episode): bool
|
private function monitorExists(Monitor $monitor, TmdbEpisodeDto $episode): bool
|
||||||
{
|
{
|
||||||
return $this->monitorRepository->findOneBy([
|
return $this->monitorRepository->findOneBy([
|
||||||
'imdbId' => $monitor->getImdbId(),
|
'imdbId' => $monitor->getImdbId(),
|
||||||
'title' => $monitor->getTitle(),
|
'title' => $monitor->getTitle(),
|
||||||
'monitorType' => 'tvepisode',
|
'monitorType' => 'tvepisode',
|
||||||
'season' => $episode['season_number'],
|
'season' => $episode->seasonNumber,
|
||||||
'episode' => $episode['episode_number'],
|
'episode' => $episode->episodeNumber,
|
||||||
'status' => ['New', 'Active', 'In Progress']
|
'status' => ['New', 'Active', 'In Progress']
|
||||||
]) !== null;
|
]) !== null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 = "-",
|
||||||
) {}
|
) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 %}
|
||||||
|
|||||||
Reference in New Issue
Block a user