wip: mostly working tmdb client
This commit is contained in:
@@ -2,11 +2,8 @@
|
||||
|
||||
namespace App\Base\Framework\Controller;
|
||||
|
||||
use App\Monitor\Action\Command\MonitorTvShowCommand;
|
||||
use App\Monitor\Action\Handler\MonitorTvShowHandler;
|
||||
use App\Tmdb\Tmdb;
|
||||
use App\Tmdb\TmdbClient;
|
||||
use App\User\Framework\Entity\User;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
@@ -18,7 +15,6 @@ final class IndexController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly TmdbClient $tmdb,
|
||||
private readonly MonitorTvShowHandler $monitorTvShowHandler,
|
||||
) {}
|
||||
|
||||
#[Route('/', name: 'app_index')]
|
||||
|
||||
@@ -3,13 +3,14 @@
|
||||
namespace App\Download\Action\Handler;
|
||||
|
||||
use Aimeos\Map;
|
||||
use App\Base\Enum\MediaType;
|
||||
use App\Base\Service\MediaFiles;
|
||||
use App\Download\Action\Command\DownloadMediaCommand;
|
||||
use App\Download\Action\Command\DownloadSeasonCommand;
|
||||
use App\Download\Action\Result\DownloadMediaResult;
|
||||
use App\Download\Action\Result\DownloadSeasonResult;
|
||||
use App\Download\DownloadOptionEvaluator;
|
||||
use App\Tmdb\Tmdb;
|
||||
use App\Tmdb\TmdbClient;
|
||||
use App\Torrentio\Action\Command\GetTvShowOptionsCommand;
|
||||
use App\Torrentio\Action\Handler\GetTvShowOptionsHandler;
|
||||
use App\User\Dto\UserPreferencesFactory;
|
||||
@@ -27,7 +28,7 @@ readonly class DownloadSeasonHandler implements HandlerInterface
|
||||
public function __construct(
|
||||
private MediaFiles $mediaFiles,
|
||||
private LoggerInterface $logger,
|
||||
private Tmdb $tmdb,
|
||||
private TmdbClient $tmdb,
|
||||
private MessageBusInterface $bus,
|
||||
private DownloadOptionEvaluator $downloadOptionEvaluator,
|
||||
private GetTvShowOptionsHandler $getTvShowOptionsHandler,
|
||||
@@ -36,7 +37,8 @@ readonly class DownloadSeasonHandler implements HandlerInterface
|
||||
|
||||
public function handle(CommandInterface $command): ResultInterface
|
||||
{
|
||||
$series = $this->tmdb->mediaDetails($command->imdbId, $command->mediaType);
|
||||
$series = $this->tmdb->tvshowDetails($command->imdbId);
|
||||
|
||||
$this->logger->info('> [DownloadTvSeasonHandler] Executing DownloadTvSeasonHandler for "' . $series->title . '" season ' . $command->season);
|
||||
|
||||
$episodesInSeason = Map::from($series->episodes[$command->season]);
|
||||
|
||||
@@ -9,7 +9,7 @@ use App\Download\Framework\Repository\DownloadRepository;
|
||||
use App\Monitor\Action\Command\MonitorMovieCommand;
|
||||
use App\Monitor\Action\Result\MonitorTvEpisodeResult;
|
||||
use App\Monitor\Framework\Repository\MonitorRepository;
|
||||
use App\Tmdb\Tmdb;
|
||||
use App\Tmdb\TmdbClient;
|
||||
use App\Torrentio\Action\Command\GetTvShowOptionsCommand;
|
||||
use App\Torrentio\Action\Handler\GetTvShowOptionsHandler;
|
||||
use App\User\Dto\UserPreferencesFactory;
|
||||
@@ -32,7 +32,7 @@ readonly class MonitorTvEpisodeHandler implements HandlerInterface
|
||||
private MessageBusInterface $bus,
|
||||
private LoggerInterface $logger,
|
||||
private MonitorRepository $monitorRepository,
|
||||
private Tmdb $tmdb,
|
||||
private TmdbClient $tmdb,
|
||||
private DownloadRepository $downloadRepository,
|
||||
) {}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use App\Monitor\Action\Command\MonitorTvSeasonCommand;
|
||||
use App\Monitor\Action\Result\MonitorTvSeasonResult;
|
||||
use App\Monitor\Framework\Entity\Monitor;
|
||||
use App\Monitor\Framework\Repository\MonitorRepository;
|
||||
use App\Tmdb\Tmdb;
|
||||
use App\Tmdb\TmdbClient;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use App\Base\Util\PTN;
|
||||
@@ -26,7 +26,7 @@ readonly class MonitorTvSeasonHandler implements HandlerInterface
|
||||
private EntityManagerInterface $entityManager,
|
||||
private MediaFiles $mediaFiles,
|
||||
private LoggerInterface $logger,
|
||||
private Tmdb $tmdb,
|
||||
private TmdbClient $tmdb,
|
||||
private MonitorTvEpisodeHandler $monitorTvEpisodeHandler,
|
||||
) {}
|
||||
|
||||
@@ -50,7 +50,7 @@ readonly class MonitorTvSeasonHandler implements HandlerInterface
|
||||
|
||||
// Compare against list from TMDB
|
||||
$episodesInSeason = Map::from(
|
||||
$this->tmdb->tvDetails($monitor->getTmdbId())->episodes[$monitor->getSeason()]
|
||||
$this->tmdb->tvshowDetails($monitor->getImdbId())->episodes[$monitor->getSeason()]
|
||||
)->rekey(fn($episode) => $episode['episode_number']);
|
||||
$this->logger->info('> [MonitorTvSeasonHandler] Found ' . count($episodesInSeason) . ' episodes in season ' . $monitor->getSeason() . ' for title: ' . $monitor->getTitle());
|
||||
|
||||
|
||||
@@ -9,9 +9,8 @@ use App\Monitor\Action\Command\MonitorTvEpisodeCommand;
|
||||
use App\Monitor\Action\Result\MonitorTvShowResult;
|
||||
use App\Monitor\Framework\Entity\Monitor;
|
||||
use App\Monitor\Framework\Repository\MonitorRepository;
|
||||
use App\Tmdb\Tmdb;
|
||||
use App\Tmdb\TmdbClient;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonImmutable;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use App\Base\Util\PTN;
|
||||
@@ -29,7 +28,7 @@ readonly class MonitorTvShowHandler implements HandlerInterface
|
||||
private MonitorTvEpisodeHandler $monitorTvEpisodeHandler,
|
||||
private MediaFiles $mediaFiles,
|
||||
private LoggerInterface $logger,
|
||||
private Tmdb $tmdb,
|
||||
private TmdbClient $tmdb,
|
||||
) {}
|
||||
|
||||
public function handle(CommandInterface $command): ResultInterface
|
||||
@@ -53,7 +52,7 @@ readonly class MonitorTvShowHandler implements HandlerInterface
|
||||
|
||||
// Compare against list from TMDB
|
||||
$episodesInShow = Map::from(
|
||||
$this->tmdb->tvDetails($monitor->getTmdbId())->episodes
|
||||
$this->tmdb->tvshowDetails($monitor->getImdbId())->episodes
|
||||
)->flat(1);
|
||||
|
||||
$this->logger->info('> [MonitorTvShowHandler] Found ' . count($episodesInShow) . ' episodes for title: ' . $monitor->getTitle());
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
|
||||
namespace App\Search\Action\Handler;
|
||||
|
||||
use Aimeos\Map;
|
||||
use App\Base\Enum\MediaType;
|
||||
use App\Search\Action\Command\GetMediaInfoCommand;
|
||||
use App\Search\Action\Result\GetMediaInfoResult;
|
||||
use App\Tmdb\Tmdb;
|
||||
use App\Tmdb\TmdbClient;
|
||||
use App\Tmdb\TmdbResult;
|
||||
use OneToMany\RichBundle\Contract\CommandInterface;
|
||||
|
||||
@@ -2,10 +2,8 @@
|
||||
|
||||
namespace App\Search\Action\Handler;
|
||||
|
||||
use App\Base\Util\ImdbMatcher;
|
||||
use App\Search\Action\Result\RedirectToMediaResult;
|
||||
use App\Search\Action\Result\SearchResult;
|
||||
use App\Tmdb\Tmdb;
|
||||
use App\Tmdb\TmdbClient;
|
||||
use App\Tmdb\TmdbResult;
|
||||
use OneToMany\RichBundle\Contract\CommandInterface;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace App\Tmdb\Framework\Controller;
|
||||
|
||||
use App\Base\Util\ImdbMatcher;
|
||||
use App\Tmdb\Tmdb;
|
||||
use App\Tmdb\TmdbClient;
|
||||
use App\Tmdb\TmdbResult;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
@@ -23,7 +22,7 @@ class ApiController extends AbstractController
|
||||
|
||||
if (null !== $term) {
|
||||
if (ImdbMatcher::isMatch($term)) {
|
||||
$tmdbResult = $tmdb->findByImdbId($term);
|
||||
$tmdbResult = $tmdb->search($term);
|
||||
$results = [
|
||||
[
|
||||
'data' => $tmdbResult,
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tmdb;
|
||||
|
||||
use Tmdb\Event\HydrationEvent;
|
||||
|
||||
class HydrationListener extends \Tmdb\Event\Listener\HydrationListener
|
||||
{
|
||||
public function hydrateSubject(HydrationEvent $event)
|
||||
{
|
||||
dump($event);
|
||||
dd('hre');
|
||||
}
|
||||
}
|
||||
@@ -8,23 +8,19 @@ use App\Base\Util\ImdbMatcher;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\ObjectMapper\ObjectMapper;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
use Tmdb\Api\Find;
|
||||
use Tmdb\Client;
|
||||
use Tmdb\Event\BeforeRequestEvent;
|
||||
use Tmdb\Event\HydrationEvent;
|
||||
use Tmdb\Event\Listener\Psr6CachedRequestListener;
|
||||
use Tmdb\Event\Listener\Request\AcceptJsonRequestListener;
|
||||
use Tmdb\Event\Listener\Request\ApiTokenRequestListener;
|
||||
use Tmdb\Event\Listener\Request\ContentTypeJsonRequestListener;
|
||||
use Tmdb\Event\Listener\Request\UserAgentRequestListener;
|
||||
use Tmdb\Event\RequestEvent;
|
||||
use Tmdb\Model\Movie;
|
||||
use Tmdb\Model\Tv;
|
||||
use Tmdb\Repository\MovieRepository;
|
||||
use Tmdb\Repository\SearchRepository;
|
||||
use Tmdb\Repository\TvEpisodeRepository;
|
||||
use Tmdb\Repository\TvRepository;
|
||||
use Tmdb\Repository\TvSeasonRepository;
|
||||
use Tmdb\Token\Api\ApiToken;
|
||||
@@ -38,6 +34,7 @@ class TmdbClient
|
||||
protected MovieRepository $movieRepository;
|
||||
protected TvRepository $tvRepository;
|
||||
protected TvSeasonRepository $tvSeasonRepository;
|
||||
protected TvEpisodeRepository $tvEpisodeRepository;
|
||||
protected SearchRepository $searchRepository;
|
||||
|
||||
public function __construct(
|
||||
@@ -97,6 +94,7 @@ class TmdbClient
|
||||
$this->movieRepository = new MovieRepository($this->client);
|
||||
$this->tvRepository = new TvRepository($this->client);
|
||||
$this->tvSeasonRepository = new TvSeasonRepository($this->client);
|
||||
$this->tvEpisodeRepository = new TvEpisodeRepository($this->client);
|
||||
$this->searchRepository = new SearchRepository($this->client);
|
||||
}
|
||||
|
||||
@@ -136,6 +134,8 @@ class TmdbClient
|
||||
strtolower($data['name']) !== 'specials';
|
||||
})->map(function ($data) use ($media) {
|
||||
return $this->tvSeasonDetails($media['id'], $data['season_number'])['episodes'];
|
||||
})->rekey(function ($data) {
|
||||
return $data[1]['season_number'];
|
||||
})->toArray();
|
||||
|
||||
return $this->parseResult(
|
||||
@@ -152,10 +152,20 @@ class TmdbClient
|
||||
$data['still_path'] = self::POSTER_IMG_PATH . $data['still_path'];
|
||||
$data['poster'] = $data['still_path'];
|
||||
return $data;
|
||||
})->toArray();
|
||||
})->rekey(fn ($data) => $data['episode_number'])->toArray();
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function tvEpisodeDetails(string $tmdbId, int $season, int $episode): ?TmdbResult
|
||||
{
|
||||
$result = $this->tvEpisodeRepository->getApi()->getEpisode($tmdbId, $season, $episode, ['append_to_response' => 'external_ids']);
|
||||
return $this->parseResult(
|
||||
$result,
|
||||
MediaType::TvEpisode->value,
|
||||
$result['external_ids']['imdb_id']
|
||||
);
|
||||
}
|
||||
|
||||
public function relatedMedia(string $tmdbId, string $mediaType, int $resultCount = 6): Map
|
||||
{
|
||||
$repos = [
|
||||
|
||||
@@ -28,7 +28,7 @@ class TmdbResultDenormalizer implements DenormalizerInterface
|
||||
MediaType::TvShow->value => 'parseTvShow',
|
||||
'movie' => 'parseMovie',
|
||||
'tv' => 'parseTvShow',
|
||||
'tvepisodes' => 'parseEpisode',
|
||||
'tvepisode' => 'parseEpisode',
|
||||
];
|
||||
|
||||
$denormalized = $this->normalizer->denormalize($data, TmdbResult::class, $format, $context);
|
||||
@@ -79,7 +79,7 @@ class TmdbResultDenormalizer implements DenormalizerInterface
|
||||
}
|
||||
|
||||
$result->premiereDate = $airDate;
|
||||
$result->episodeAirDate = $airDate;
|
||||
$result->episodeAirDate = $airDate->format('m/d/Y');
|
||||
$result->poster = (null !== $data['still_path']) ? self::POSTER_IMG_PATH . $data['still_path'] : null;
|
||||
$result->year = (null !== $airDate) ? $airDate->format('Y') : null;
|
||||
$result->mediaType = "tvshows";
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace App\Torrentio\Action\Handler;
|
||||
|
||||
use App\Base\Service\MediaFiles;
|
||||
use App\Tmdb\Tmdb;
|
||||
use App\Tmdb\TmdbClient;
|
||||
use App\Torrentio\Action\Result\GetMovieOptionsResult;
|
||||
use App\Torrentio\Client\Torrentio;
|
||||
use OneToMany\RichBundle\Contract\CommandInterface;
|
||||
@@ -13,14 +13,14 @@ use OneToMany\RichBundle\Contract\ResultInterface;
|
||||
class GetMovieOptionsHandler implements HandlerInterface
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Tmdb $tmdb,
|
||||
private readonly TmdbClient $tmdb,
|
||||
private readonly Torrentio $torrentio,
|
||||
private readonly MediaFiles $mediaFiles
|
||||
) {}
|
||||
|
||||
public function handle(CommandInterface $command): ResultInterface
|
||||
{
|
||||
$media = $this->tmdb->mediaDetails($command->imdbId, 'movies');
|
||||
$media = $this->tmdb->movieDetails($command->imdbId);
|
||||
return new GetMovieOptionsResult(
|
||||
media: $media,
|
||||
file: $this->mediaFiles->movieExists($media->title),
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
namespace App\Torrentio\Action\Handler;
|
||||
|
||||
use App\Base\Enum\MediaType;
|
||||
use App\Base\Service\MediaFiles;
|
||||
use App\Library\Dto\MediaFileDto;
|
||||
use App\Tmdb\Tmdb;
|
||||
use App\Tmdb\TmdbClient;
|
||||
use App\Torrentio\Action\Command\GetTvShowOptionsCommand;
|
||||
use App\Torrentio\Action\Result\GetTvShowOptionsResult;
|
||||
use App\Torrentio\Client\Torrentio;
|
||||
@@ -16,15 +17,15 @@ use OneToMany\RichBundle\Contract\ResultInterface;
|
||||
class GetTvShowOptionsHandler implements HandlerInterface
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Tmdb $tmdb,
|
||||
private readonly TmdbClient $tmdb,
|
||||
private readonly Torrentio $torrentio,
|
||||
private readonly MediaFiles $mediaFiles,
|
||||
) {}
|
||||
|
||||
public function handle(CommandInterface $command): ResultInterface
|
||||
{
|
||||
$media = $this->tmdb->episodeDetails($command->tmdbId, $command->season, $command->episode);
|
||||
$parentShow = $this->tmdb->mediaDetails($command->imdbId, 'tvshows');
|
||||
$media = $this->tmdb->tvEpisodeDetails($command->tmdbId, $command->season, $command->episode);
|
||||
$parentShow = $this->tmdb->tvshowDetails($command->imdbId);
|
||||
$file = $this->mediaFiles->episodeExists($parentShow->title, $command->season, $command->episode);
|
||||
|
||||
return new GetTvShowOptionsResult(
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Twig\Components;
|
||||
|
||||
use Aimeos\Map;
|
||||
use App\Monitor\Factory\UpcomingEpisodeDto;
|
||||
use App\Monitor\Framework\Entity\Monitor;
|
||||
use App\Tmdb\Tmdb;
|
||||
use Carbon\CarbonImmutable;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
|
||||
use Tmdb\Model\Tv\Episode;
|
||||
|
||||
#[AsTwigComponent]
|
||||
final class UpcomingEpisodes extends AbstractController
|
||||
{
|
||||
// Get active monitors
|
||||
// Search TMDB for upcoming episodes
|
||||
|
||||
|
||||
public function __construct(
|
||||
private readonly Tmdb $tmdb,
|
||||
) {}
|
||||
|
||||
public function getUpcomingEpisodes(int $limit = 5): array
|
||||
{
|
||||
$upcomingEpisodes = new Map();
|
||||
$monitors = $this->getMonitors();
|
||||
foreach ($monitors as $monitor) {
|
||||
$upcomingEpisodes->merge($this->getNextEpisodes($monitor));
|
||||
}
|
||||
|
||||
return $upcomingEpisodes->slice(0, $limit)->toArray();
|
||||
}
|
||||
|
||||
private function getMonitors()
|
||||
{
|
||||
$user = $this->getUser();
|
||||
return $user->getMonitors()->filter(
|
||||
fn (Monitor $monitor) => null === $monitor->getParent() && $monitor->isActive()
|
||||
) ?? [];
|
||||
}
|
||||
|
||||
private function getNextEpisodes(Monitor $monitor): Map
|
||||
{
|
||||
$today = CarbonImmutable::now();
|
||||
$seriesInfo = $this->tmdb->tvDetails($monitor->getTmdbId());
|
||||
|
||||
switch ($monitor->getMonitorType()) {
|
||||
case "tvseason":
|
||||
$episodes = Map::from($seriesInfo->episodes[$monitor->getSeason()])
|
||||
->filter(function (array $episode) use ($today) {
|
||||
$airDate = CarbonImmutable::parse($episode['air_date']);
|
||||
return $airDate->lte($today);
|
||||
})
|
||||
;
|
||||
break;
|
||||
case "tvshows":
|
||||
$episodes = [];
|
||||
foreach ($seriesInfo->episodes as $season => $episodeList) {
|
||||
$episodes = array_merge($episodes, $episodeList);
|
||||
}
|
||||
$episodes = Map::from($episodes)
|
||||
->filter(function (array $episode) use ($today) {
|
||||
$airDate = CarbonImmutable::parse($episode['air_date']);
|
||||
return $airDate->gte($today);
|
||||
})
|
||||
;
|
||||
break;
|
||||
}
|
||||
|
||||
return $episodes->map(function (array $episode) use ($monitor) {
|
||||
return new UpcomingEpisodeDto(
|
||||
$monitor->getTitle(),
|
||||
$episode['air_date'],
|
||||
$episode['name'],
|
||||
$episode['episode_number'],
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ use App\Monitor\Action\Handler\MonitorTvShowHandler;
|
||||
use App\Monitor\Action\Result\MonitorTvShowResult;
|
||||
use App\Monitor\Framework\Entity\Monitor;
|
||||
use App\Monitor\Framework\Repository\MonitorRepository;
|
||||
use App\Tmdb\Tmdb;
|
||||
use App\Tmdb\TmdbClient;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@@ -22,7 +22,7 @@ class MonitorTvShowHandlerTest extends TestCase
|
||||
private MonitorTvEpisodeHandler $episodeHandler;
|
||||
private MediaFiles $mediaFiles;
|
||||
private LoggerInterface $logger;
|
||||
private Tmdb $tmdb;
|
||||
private TmdbClient $tmdb;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
@@ -31,7 +31,7 @@ class MonitorTvShowHandlerTest extends TestCase
|
||||
$this->episodeHandler = $this->createMock(MonitorTvEpisodeHandler::class);
|
||||
$this->mediaFiles = $this->createMock(MediaFiles::class);
|
||||
$this->logger = $this->createMock(LoggerInterface::class);
|
||||
$this->tmdb = $this->createMock(Tmdb::class);
|
||||
$this->tmdb = $this->createMock(TmdbClient::class);
|
||||
|
||||
$this->handler = new MonitorTvShowHandler(
|
||||
$this->monitorRepository,
|
||||
|
||||
Reference in New Issue
Block a user