Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2315b995e0 | ||
|
|
83401f2a7a | ||
|
|
50bcb4e1df | ||
|
|
ea569b480d |
5
.env
5
.env
@@ -62,3 +62,8 @@ NTFY_DSN=
|
||||
###> sentry/sentry-symfony ###
|
||||
SENTRY_DSN=
|
||||
###< sentry/sentry-symfony ###
|
||||
|
||||
# TMDB 'with_original_language' option
|
||||
# - only include media originally
|
||||
# produced in this language
|
||||
TMDB_ORIGINAL_LANGUAGE=en
|
||||
|
||||
@@ -5,18 +5,18 @@ when@prod:
|
||||
|
||||
options:
|
||||
release: '%app.version%'
|
||||
traces_sample_rate: 1
|
||||
profiles_sample_rate: 1
|
||||
traces_sample_rate: 0
|
||||
profiles_sample_rate: 0
|
||||
attach_stacktrace: true
|
||||
|
||||
tracing:
|
||||
enabled: true
|
||||
dbal: # DB queries
|
||||
enabled: true
|
||||
cache: # cache pools
|
||||
enabled: true
|
||||
twig: # templating engine
|
||||
enabled: true
|
||||
# tracing:
|
||||
# enabled: true
|
||||
# dbal: # DB queries
|
||||
# enabled: true
|
||||
# cache: # cache pools
|
||||
# enabled: true
|
||||
# twig: # templating engine
|
||||
# enabled: true
|
||||
|
||||
services:
|
||||
# (Optionally) Configure the breadcrumb handler as a service (needed for the breadcrumb Monolog handler)
|
||||
|
||||
@@ -50,7 +50,7 @@ final class IndexController extends AbstractController
|
||||
#[Route('/test')]
|
||||
public function monitorTvShow(MonitorTvShowHandler $handler): Response
|
||||
{
|
||||
// $handler->handle(new MonitorTvShowCommand(82));
|
||||
throw new \Exception('Test');
|
||||
return $this->render('index/test.html.twig', []);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,14 +46,14 @@ readonly class DownloadSeasonHandler implements HandlerInterface
|
||||
|
||||
$downloadCommands = [];
|
||||
foreach ($episodesInSeason as $episode) {
|
||||
$this->logger->info('> [DownloadTvSeasonHandler] ...Evaluating episode ' . $episode['episode_number']);
|
||||
$this->logger->info('> [DownloadTvSeasonHandler] ...Evaluating episode ' . $episode->episodeNumber);
|
||||
|
||||
$results = $this->getTvShowOptionsHandler->handle(
|
||||
new GetTvShowOptionsCommand(
|
||||
$series->tmdbId,
|
||||
$command->imdbId,
|
||||
$command->season,
|
||||
$episode['episode_number']
|
||||
$episode->episodeNumber
|
||||
)
|
||||
);
|
||||
|
||||
@@ -67,7 +67,7 @@ readonly class DownloadSeasonHandler implements HandlerInterface
|
||||
|
||||
if (null !== $result) {
|
||||
$this->logger->info('> [DownloadTvSeasonHandler] ......Found 1 matching result');
|
||||
$this->logger->info('> [DownloadTvSeasonHandler] ......Dispatching DownloadMediaCommand for "' . $series->title . '" season ' . $command->season . ' episode ' . $episode['episode_number']);
|
||||
$this->logger->info('> [DownloadTvSeasonHandler] ......Dispatching DownloadMediaCommand for "' . $series->title . '" season ' . $command->season . ' episode ' . $episode->episodeNumber);
|
||||
$downloadCommand = new DownloadMediaCommand(
|
||||
$result->url,
|
||||
$series->title,
|
||||
@@ -99,10 +99,10 @@ readonly class DownloadSeasonHandler implements HandlerInterface
|
||||
->filter(fn ($episode) =>
|
||||
property_exists($episode, 'episode')
|
||||
&& property_exists($episode, 'season')
|
||||
&& null !== $episode->episode
|
||||
&& null !== $episode->episodeNumber
|
||||
&& null !== $episode->season
|
||||
)
|
||||
->rekey(fn($episode) => $episode->episode);
|
||||
->rekey(fn($episode) => $episode->episodeNumber);
|
||||
$this->logger->info('> [MonitorTvSeasonHandler] Found ' . count($downloadedEpisodes) . ' downloaded episodes for title: ' . $monitor->getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
59
src/Download/Action/Handler/MonitorHandlerTrait.php
Normal file
59
src/Download/Action/Handler/MonitorHandlerTrait.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Download\Action\Handler;
|
||||
|
||||
use Aimeos\Map;
|
||||
use App\Monitor\Framework\Entity\Monitor;
|
||||
use App\Monitor\Framework\Repository\MonitorRepository;
|
||||
use App\Tmdb\Dto\TmdbEpisodeDto;
|
||||
use App\Tmdb\TmdbClient;
|
||||
use Carbon\Carbon;
|
||||
use DateTimeImmutable;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
trait MonitorHandlerTrait
|
||||
{
|
||||
private MonitorRepository $monitorRepository;
|
||||
private LoggerInterface $logger;
|
||||
private TmdbClient $tmdb;
|
||||
|
||||
private function episodeReleasedAfterMonitorCreated(
|
||||
string|DateTimeImmutable $monitorStartDate,
|
||||
TmdbEpisodeDto $episodeInShow
|
||||
): bool {
|
||||
$monitorStartDate = Carbon::parse($monitorStartDate)->setTime(0, 0);
|
||||
$episodeAirDate = Carbon::parse($episodeInShow->airDate);
|
||||
return $episodeAirDate >= $monitorStartDate;
|
||||
}
|
||||
|
||||
private function episodeExists(TmdbEpisodeDto $episodeInShow, Map $downloadedEpisodes): bool
|
||||
{
|
||||
return $downloadedEpisodes->filter(
|
||||
fn(object $episode) => $episode->episode === $episodeInShow->episodeNumber
|
||||
&& $episode->season === $episodeInShow->seasonNumber
|
||||
)->count() > 0;
|
||||
}
|
||||
|
||||
private function monitorExists(Monitor $monitor, TmdbEpisodeDto $episode): bool
|
||||
{
|
||||
return $this->monitorRepository->findOneBy([
|
||||
'imdbId' => $monitor->getImdbId(),
|
||||
'title' => $monitor->getTitle(),
|
||||
'monitorType' => 'tvepisode',
|
||||
'season' => $episode->seasonNumber,
|
||||
'episode' => $episode->episodeNumber,
|
||||
'status' => ['New', 'Active', 'In Progress']
|
||||
]) !== null;
|
||||
}
|
||||
|
||||
private function refreshData(Monitor $monitor)
|
||||
{
|
||||
if (null === $monitor->getPoster()) {
|
||||
$this->logger->info('> [MonitorTvShowHandler] Refreshing poster for "' . $monitor->getTitle() . '"');
|
||||
$poster = $this->tmdb->tvshowDetails($monitor->getImdbId())->poster;
|
||||
if (null !== $poster && "" !== $poster) {
|
||||
$monitor->setPoster($poster);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ use Tmdb\Event\Listener\Request\ApiTokenRequestListener;
|
||||
use Tmdb\Event\Listener\Request\ContentTypeJsonRequestListener;
|
||||
use Tmdb\Event\Listener\Request\UserAgentRequestListener;
|
||||
use Tmdb\Event\RequestEvent;
|
||||
use Tmdb\Repository\DiscoverRepository;
|
||||
use Tmdb\Repository\MovieRepository;
|
||||
use Tmdb\Repository\SearchRepository;
|
||||
use Tmdb\Repository\TvEpisodeRepository;
|
||||
@@ -30,6 +31,7 @@ use Tmdb\Token\Api\BearerToken;
|
||||
class TmdbClient
|
||||
{
|
||||
const POSTER_IMG_PATH = "https://image.tmdb.org/t/p/w500";
|
||||
const APPEND_TO_RESPONSE = 'external_ids,credits,watch/providers';
|
||||
|
||||
protected Client $client;
|
||||
protected MovieRepository $movieRepository;
|
||||
@@ -38,6 +40,8 @@ class TmdbClient
|
||||
protected TvEpisodeRepository $tvEpisodeRepository;
|
||||
protected SearchRepository $searchRepository;
|
||||
|
||||
protected DiscoverRepository $discoverRepository;
|
||||
|
||||
protected array $mediaTypeMap = [
|
||||
MediaType::Movie->value => MediaType::Movie->value,
|
||||
MediaType::TvShow->value => MediaType::TvShow->value,
|
||||
@@ -48,11 +52,14 @@ class TmdbClient
|
||||
|
||||
protected $repos = [];
|
||||
|
||||
private ?string $originalLanguage = 'en';
|
||||
|
||||
public function __construct(
|
||||
private readonly SerializerInterface $serializer,
|
||||
private readonly CacheItemPoolInterface $cache,
|
||||
private readonly EventDispatcherInterface $eventDispatcher,
|
||||
#[Autowire(env: 'TMDB_API')] string $apiKey,
|
||||
#[Autowire(env: 'TMDB_ORIGINAL_LANGUAGE')] ?string $originalLanguage = null,
|
||||
) {
|
||||
$this->client = new Client(
|
||||
[
|
||||
@@ -74,7 +81,7 @@ class TmdbClient
|
||||
'hydration' => [
|
||||
'event_listener_handles_hydration' => false,
|
||||
'only_for_specified_models' => []
|
||||
]
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
@@ -107,11 +114,14 @@ class TmdbClient
|
||||
$this->tvSeasonRepository = new TvSeasonRepository($this->client);
|
||||
$this->tvEpisodeRepository = new TvEpisodeRepository($this->client);
|
||||
$this->searchRepository = new SearchRepository($this->client);
|
||||
$this->discoverRepository = new DiscoverRepository($this->client);
|
||||
|
||||
$this->repos = [
|
||||
MediaType::Movie->value => $this->movieRepository,
|
||||
MediaType::TvShow->value => $this->tvRepository,
|
||||
MediaType::TvEpisode->value => $this->tvEpisodeRepository,
|
||||
];
|
||||
$this->originalLanguage = $originalLanguage;
|
||||
}
|
||||
|
||||
public function search(string $term): TmdbResult|Map
|
||||
@@ -133,7 +143,7 @@ class TmdbClient
|
||||
{
|
||||
$tmdbId = $this->findByImdbId($imdbId)['id'];
|
||||
return $this->parseResult(
|
||||
$this->movieRepository->getApi()->getMovie($tmdbId, ['append_to_response' => 'external_ids,credits']),
|
||||
$this->movieRepository->getApi()->getMovie($tmdbId, ['append_to_response' => static::APPEND_TO_RESPONSE]),
|
||||
MediaType::Movie->value,
|
||||
$imdbId
|
||||
);
|
||||
@@ -142,7 +152,7 @@ class TmdbClient
|
||||
public function tvshowDetails(string $imdbId): ?TmdbResult
|
||||
{
|
||||
$tmdbId = $this->findByImdbId($imdbId)['id'];
|
||||
$media = $this->tvRepository->getApi()->getTvShow($tmdbId, ['append_to_response' => 'external_ids,credits']);
|
||||
$media = $this->tvRepository->getApi()->getTvShow($tmdbId, ['append_to_response' => static::APPEND_TO_RESPONSE]);
|
||||
|
||||
$media['seasons'] = Map::from($media['seasons'])->filter(function ($data) {
|
||||
return $data['season_number'] !== 0 &&
|
||||
@@ -163,7 +173,7 @@ class TmdbClient
|
||||
|
||||
public function tvSeasonDetails(string $tmdbId, int $season): array
|
||||
{
|
||||
$result = $this->tvSeasonRepository->getApi()->getSeason($tmdbId, $season, ['append_to_response' => 'external_ids,credits']);
|
||||
$result = $this->tvSeasonRepository->getApi()->getSeason($tmdbId, $season, ['append_to_response' => static::APPEND_TO_RESPONSE]);
|
||||
$result['episodes'] = Map::from($result['episodes'])->map(function ($data) {
|
||||
$data['still_path'] = self::POSTER_IMG_PATH . $data['still_path'];
|
||||
$data['poster'] = $data['still_path'];
|
||||
@@ -174,7 +184,7 @@ class TmdbClient
|
||||
|
||||
public function tvEpisodeDetails(string $tmdbId, string $showImdbId, int $season, int $episode): TmdbResult|TmdbEpisodeDto|null
|
||||
{
|
||||
$result = $this->tvEpisodeRepository->getApi()->getEpisode($tmdbId, $season, $episode, ['append_to_response' => 'external_ids,credits']);
|
||||
$result = $this->tvEpisodeRepository->getApi()->getEpisode($tmdbId, $season, $episode, ['append_to_response' => static::APPEND_TO_RESPONSE]);
|
||||
return $this->parseResult(
|
||||
$result,
|
||||
MediaType::TvEpisode->value,
|
||||
@@ -193,7 +203,10 @@ class TmdbClient
|
||||
|
||||
public function popularMovies(int $resultCount = 6): Map
|
||||
{
|
||||
$results = $this->movieRepository->getApi()->getPopular();
|
||||
$results = $this->discoverRepository->getApi()->discoverMovies([
|
||||
'with_original_language' => $this->originalLanguage,
|
||||
'append_to_response' => 'external_ids,watch/providers',
|
||||
]);
|
||||
$results['results'] = Map::from($results['results'])->map(function ($result) {
|
||||
$result['media_type'] = MediaType::Movie->value;
|
||||
return $result;
|
||||
@@ -206,7 +219,10 @@ class TmdbClient
|
||||
|
||||
public function popularTvShows(int $resultCount = 6): Map
|
||||
{
|
||||
$results = $this->tvRepository->getApi()->getPopular();
|
||||
$results = $this->discoverRepository->getApi()->discoverTv([
|
||||
'with_original_language' => $this->originalLanguage,
|
||||
'append_to_response' => 'external_ids,watch/providers',
|
||||
]);
|
||||
$results['results'] = Map::from($results['results'])->map(function ($result) {
|
||||
$result['media_type'] = MediaType::TvShow->value;
|
||||
return $result;
|
||||
|
||||
Reference in New Issue
Block a user