Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b56ee937d | |||
| 7b3d57b94a | |||
| be7b610111 | |||
| 3e93a7c9c1 | |||
| bc78b83f8d | |||
| c5bcaeb1d4 | |||
| e39182ba91 | |||
| 965b747594 | |||
| 937e3c6270 |
@@ -3,6 +3,7 @@ FROM dunglas/frankenphp:php8.4
|
||||
ENV SERVER_NAME=":80"
|
||||
ENV CADDY_GLOBAL_OPTIONS="auto_https off"
|
||||
ENV APP_RUNTIME="Runtime\\FrankenPhpSymfony\\Runtime"
|
||||
ENV APP_VERSION="0.0.1"
|
||||
|
||||
RUN install-php-extensions \
|
||||
pdo_mysql \
|
||||
|
||||
@@ -12,6 +12,7 @@ export default class extends Controller {
|
||||
filename: String,
|
||||
mediaType: String,
|
||||
imdbId: String,
|
||||
episodeId: String
|
||||
}
|
||||
|
||||
download() {
|
||||
@@ -27,6 +28,7 @@ export default class extends Controller {
|
||||
filename: this.filenameValue,
|
||||
mediaType: this.mediaTypeValue,
|
||||
imdbId: this.imdbIdValue,
|
||||
episodeId: this.episodeIdValue
|
||||
})
|
||||
})
|
||||
.then(res => res.json())
|
||||
|
||||
@@ -48,6 +48,7 @@ export default class extends Controller {
|
||||
this.options.forEach((option) => option.querySelector('.download-btn').dataset['title'] = this.titleValue);
|
||||
this.options[0].querySelector('input[type="checkbox"]').checked = true;
|
||||
} else {
|
||||
this.countTarget.innerText = 0;
|
||||
this.episodeSelectorTarget.disabled = true;
|
||||
}
|
||||
this.loadingIconOutlet.increaseCount();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
twig:
|
||||
globals:
|
||||
version: '%app.version%'
|
||||
file_name_pattern: '*.twig'
|
||||
date:
|
||||
format: 'm/d/Y'
|
||||
|
||||
@@ -22,8 +22,11 @@ parameters:
|
||||
app.cache.redis.host.default: 'redis://redis'
|
||||
|
||||
# Various configs
|
||||
app.default.version: '0.dev'
|
||||
app.default.timezone: 'America/Chicago'
|
||||
|
||||
app.version: '%env(default:app.default.version:APP_VERSION)%'
|
||||
|
||||
services:
|
||||
# default configuration for services in *this* file
|
||||
_defaults:
|
||||
|
||||
@@ -4,6 +4,9 @@ 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 \
|
||||
|
||||
@@ -4,6 +4,9 @@ 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 \
|
||||
|
||||
@@ -4,6 +4,9 @@ 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 \
|
||||
|
||||
@@ -26,6 +26,9 @@ class DownloadMediaInput implements InputInterface
|
||||
#[SourceRequest('imdbId')]
|
||||
public string $imdbId,
|
||||
|
||||
#[SourceRequest('episodeId', nullify: true)]
|
||||
public ?string $episodeId = null,
|
||||
|
||||
public ?int $userId = null,
|
||||
|
||||
public ?int $downloadId = null,
|
||||
|
||||
@@ -11,6 +11,7 @@ use App\Download\Action\Input\PauseDownloadInput;
|
||||
use App\Download\Action\Input\ResumeDownloadInput;
|
||||
use App\Download\Framework\Repository\DownloadRepository;
|
||||
use App\Util\Broadcaster;
|
||||
use Nihilarr\PTN;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
@@ -28,6 +29,13 @@ class ApiController extends AbstractController
|
||||
public function download(
|
||||
DownloadMediaInput $input,
|
||||
): Response {
|
||||
$ptn = (object) new Ptn()->parse($input->filename);
|
||||
if ($input->mediaType === "tvshows" &&
|
||||
!property_exists($ptn, 'episode') && !property_exists($ptn, 'season')
|
||||
) {
|
||||
$input->filename = $input->episodeId . '_' . $input->filename;
|
||||
}
|
||||
|
||||
$download = $this->downloadRepository->insert(
|
||||
$this->getUser(),
|
||||
$input->url,
|
||||
|
||||
@@ -61,10 +61,10 @@ readonly class MonitorTvShowHandler implements HandlerInterface
|
||||
// Dispatch Episode commands for each missing Episode
|
||||
foreach ($episodesInShow as $episode) {
|
||||
// Only monitor future episodes
|
||||
$episodeInFuture = $this->episodeInFuture($episode);
|
||||
$this->logger->info('> [MonitorTvShowHandler] Episode is in future for season ' . $episode['season_number'] . ' episode ' . $episode['episode_number'] . ' for title: ' . $monitor->getTitle() . ' ? ' . (true === $episodeInFuture ? 'YES' : 'NO'));
|
||||
$episodeInFuture = $this->episodeReleasedAfterMonitorCreated($monitor->getCreatedAt(), $episode);
|
||||
$this->logger->info('> [MonitorTvShowHandler] Episode released after monitor started for season ' . $episode['season_number'] . ' episode ' . $episode['episode_number'] . ' for title: ' . $monitor->getTitle() . ' ? ' . (true === $episodeInFuture ? 'YES' : 'NO'));
|
||||
if (false === $episodeInFuture) {
|
||||
$this->logger->info('> [MonitorTvShowHandler] Episode not in future for title: ' . 'for season ' . $episode['season_number'] . ' episode ' . $episode['episode_number'] . ', skipping');
|
||||
$this->logger->info('> [MonitorTvShowHandler] Episode released after monitor started for title: ' . 'for season ' . $episode['season_number'] . ' episode ' . $episode['episode_number'] . ', skipping');
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -125,11 +125,11 @@ readonly class MonitorTvShowHandler implements HandlerInterface
|
||||
);
|
||||
}
|
||||
|
||||
private function episodeInFuture(array $episodeInShow): bool
|
||||
private function episodeReleasedAfterMonitorCreated(string|DateTimeImmutable $monitorStartDate, array $episodeInShow): bool
|
||||
{
|
||||
static $today = Carbon::today();
|
||||
$monitorStartDate = Carbon::parse($monitorStartDate)->setTime(0, 0);
|
||||
$episodeAirDate = Carbon::parse($episodeInShow['air_date']);
|
||||
return $episodeAirDate > $today;
|
||||
return $episodeAirDate >= $monitorStartDate;
|
||||
}
|
||||
|
||||
private function episodeExists(array $episodeInShow, Map $downloadedEpisodes): bool
|
||||
|
||||
@@ -4,7 +4,10 @@ namespace App\Twig\Extensions;
|
||||
|
||||
use App\Monitor\Framework\Entity\Monitor;
|
||||
use App\Monitor\Service\MediaFiles;
|
||||
use App\Torrentio\Action\Result\GetTvShowOptionsResult;
|
||||
use App\Torrentio\Result\TorrentioResult;
|
||||
use ChrisUllyott\FileSize;
|
||||
use Tmdb\Model\Tv\Episode;
|
||||
use Twig\Attribute\AsTwigFilter;
|
||||
use Twig\Attribute\AsTwigFunction;
|
||||
|
||||
@@ -45,4 +48,15 @@ class UtilExtension
|
||||
$path
|
||||
);
|
||||
}
|
||||
|
||||
#[AsTwigFilter('episode_id_from_results')]
|
||||
public function episodeId($result): ?string
|
||||
{
|
||||
if (!$result instanceof GetTvShowOptionsResult) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return "S". str_pad($result->season, 2, "0", STR_PAD_LEFT) .
|
||||
"E". str_pad($result->episode, 2, "0", STR_PAD_LEFT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,13 +38,13 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="sticky inset-x-0 bottom-0 border-t border-orange-500">
|
||||
<a href="#" class="nav-foot flex items-center gap-2 p-4 bg-orange-500 hover:bg-opacity-80 bg-clip-padding backdrop-filter backdrop-blur-md bg-opacity-60">
|
||||
<div class="sticky inset-x-0 bottom-0 border-t border-b border-orange-500 bg-orange-500 hover:bg-opacity-80 bg-clip-padding backdrop-filter backdrop-blur-md bg-opacity-60 flex flex-col">
|
||||
<a href="#" class="nav-foot flex items-center gap-2 pt-4 px-4">
|
||||
<span class="rounded-full p-2 border-orange-500 border-2">
|
||||
<twig:ux:icon name="ri:user-line" width="30" class="text-gray-50"/>
|
||||
</span>
|
||||
|
||||
<div>
|
||||
<div class="flex flex-col text-white">
|
||||
<p class="text-xs">
|
||||
{% if app.user.name %}
|
||||
<strong class="block font-medium text-white">{{ app.user.name }}</strong>
|
||||
@@ -54,5 +54,8 @@
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
<p class="px-4 pt-1 inline-flex justify-center">
|
||||
<small class="text-white text-xs">v{{ version|default('0.0') }}</small>
|
||||
</p>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<button class="py-1 px-1.5 mr-1 grow-0 font-bold text-xs bg-green-600 rounded-lg hover:cursor-pointer hover:bg-green-700 text-white"
|
||||
{{ stimulus_action('tv-results', 'toggleList', 'click') }}
|
||||
>
|
||||
<span {{ stimulus_target('tv-results', 'count') }}>0</span> results
|
||||
<span {{ stimulus_target('tv-results', 'count') }}>-</span> results
|
||||
</button>
|
||||
|
||||
<small class="py-1 px-1.5 mr-1 grow-0 font-bold bg-gray-700 rounded-lg font-normal text-white" title="Air date {{ episode['name'] }}">
|
||||
|
||||
@@ -15,11 +15,5 @@
|
||||
</twig:Card>
|
||||
</div>
|
||||
|
||||
<div class="p-2">
|
||||
<twig:Card title="Upcoming Episodes" >
|
||||
<twig:UpcomingEpisodes />
|
||||
</twig:Card>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for result in results.results %}
|
||||
<tr class="bg-white border-b dark:bg-slate-700 dark:border-gray-600 border-gray-200" data-provider="{{ result.provider }}" data-languages="{{ result.languages|json_encode }}" {% if "tvshows" == results.media.mediaType %} data-season="{{ results.season }} {% endif %}">
|
||||
<tr class="bg-white border-b dark:bg-slate-700 dark:border-gray-600 border-gray-200" data-provider="{{ result.provider }}" data-languages="{{ result.languages|json_encode }}" {% if "tvshows" == results.media.mediaType %} data-season="{{ results.season }}"{% endif %}>
|
||||
<td id="size" class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-800 dark:text-gray-50">
|
||||
{{ result.size }}
|
||||
</td>
|
||||
@@ -60,7 +60,8 @@
|
||||
title: results.media.title,
|
||||
filename: result.filename,
|
||||
mediaType: results.media.mediaType,
|
||||
imdbId: results.media.imdbId
|
||||
imdbId: results.media.imdbId,
|
||||
episodeId: results|episode_id_from_results
|
||||
}) }}
|
||||
{{ stimulus_action('download_button', 'download', 'click') }}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user