Rewire public controllers to support playlist sourced media.
This commit is contained in:
parent
d08235a8da
commit
b0ab0916ae
|
@ -8,6 +8,7 @@ use App\Container\EntityManagerAwareTrait;
|
|||
use App\Controller\Api\Traits\CanSearchResults;
|
||||
use App\Controller\SingleActionInterface;
|
||||
use App\Entity\ApiGenerator\PodcastEpisodeApiGenerator;
|
||||
use App\Entity\Enums\PodcastSources;
|
||||
use App\Entity\PodcastEpisode;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
|
@ -33,11 +34,16 @@ final class ListEpisodesAction implements SingleActionInterface
|
|||
->from(PodcastEpisode::class, 'e')
|
||||
->join('e.podcast', 'p')
|
||||
->leftJoin('e.media', 'pm')
|
||||
->leftJoin('e.playlist_media', 'sm')
|
||||
->where('e.podcast = :podcast')
|
||||
->setParameter('podcast', $podcast)
|
||||
->andWhere('e.publish_at IS NULL OR e.publish_at <= :publishTime')
|
||||
->setParameter('publishTime', time())
|
||||
->andWhere('pm.id IS NOT NULL')
|
||||
->andWhere(
|
||||
'(p.source = :sourceManual AND pm.id IS NOT NULL) OR (p.source = :sourcePlaylist AND sm.id IS NOT NULL)'
|
||||
)
|
||||
->setParameter('sourceManual', PodcastSources::Manual->value)
|
||||
->setParameter('sourcePlaylist', PodcastSources::Playlist->value)
|
||||
->orderBy('e.publish_at', 'DESC');
|
||||
|
||||
$queryBuilder = $this->searchQueryBuilder(
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace App\Controller\Api\Stations\Podcasts\Episodes\Media;
|
|||
use App\Controller\SingleActionInterface;
|
||||
use App\Entity\Api\Error;
|
||||
use App\Entity\Api\Status;
|
||||
use App\Entity\Enums\PodcastSources;
|
||||
use App\Entity\PodcastEpisode;
|
||||
use App\Entity\PodcastMedia;
|
||||
use App\Entity\Repository\PodcastEpisodeRepository;
|
||||
|
@ -14,6 +15,7 @@ use App\Http\Response;
|
|||
use App\Http\ServerRequest;
|
||||
use App\OpenApi;
|
||||
use App\Utilities\Types;
|
||||
use InvalidArgumentException;
|
||||
use OpenApi\Attributes as OA;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
@ -59,12 +61,14 @@ final class DeleteMediaAction implements SingleActionInterface
|
|||
Response $response,
|
||||
array $params
|
||||
): ResponseInterface {
|
||||
$episodeId = Types::string($params['episode_id'] ?? null);
|
||||
$podcast = $request->getPodcast();
|
||||
|
||||
$episode = $this->episodeRepo->fetchEpisodeForPodcast(
|
||||
$request->getPodcast(),
|
||||
$episodeId
|
||||
);
|
||||
if ($podcast->getSource() !== PodcastSources::Manual) {
|
||||
throw new InvalidArgumentException('Media cannot be manually set on this podcast.');
|
||||
}
|
||||
|
||||
$episodeId = Types::string($params['episode_id'] ?? null);
|
||||
$episode = $this->episodeRepo->fetchEpisodeForPodcast($podcast, $episodeId);
|
||||
|
||||
if (!($episode instanceof PodcastEpisode)) {
|
||||
return $response->withStatus(404)
|
||||
|
|
|
@ -6,9 +6,11 @@ namespace App\Controller\Api\Stations\Podcasts\Episodes\Media;
|
|||
|
||||
use App\Controller\SingleActionInterface;
|
||||
use App\Entity\Api\Error;
|
||||
use App\Entity\Enums\PodcastSources;
|
||||
use App\Entity\PodcastEpisode;
|
||||
use App\Entity\PodcastMedia;
|
||||
use App\Entity\Repository\PodcastEpisodeRepository;
|
||||
use App\Entity\StationMedia;
|
||||
use App\Flysystem\StationFilesystems;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
|
@ -68,26 +70,46 @@ final class GetMediaAction implements SingleActionInterface
|
|||
$episodeId = Types::string($params['episode_id'] ?? null);
|
||||
|
||||
$station = $request->getStation();
|
||||
$podcast = $request->getPodcast();
|
||||
|
||||
$episode = $this->episodeRepo->fetchEpisodeForPodcast(
|
||||
$request->getPodcast(),
|
||||
$podcast,
|
||||
$episodeId
|
||||
);
|
||||
|
||||
if ($episode instanceof PodcastEpisode) {
|
||||
$podcastMedia = $episode->getMedia();
|
||||
switch ($podcast->getSource()) {
|
||||
case PodcastSources::Playlist:
|
||||
$playlistMedia = $episode->getPlaylistMedia();
|
||||
|
||||
if ($podcastMedia instanceof PodcastMedia) {
|
||||
$fsPodcasts = $this->stationFilesystems->getPodcastsFilesystem($station);
|
||||
if ($playlistMedia instanceof StationMedia) {
|
||||
$fsMedia = $this->stationFilesystems->getMediaFilesystem($station);
|
||||
|
||||
$path = $podcastMedia->getPath();
|
||||
set_time_limit(600);
|
||||
return $response->streamFilesystemFile(
|
||||
$fsMedia,
|
||||
$playlistMedia->getPath()
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
if ($fsPodcasts->fileExists($path)) {
|
||||
return $response->streamFilesystemFile(
|
||||
$fsPodcasts,
|
||||
$path,
|
||||
$podcastMedia->getOriginalName()
|
||||
);
|
||||
}
|
||||
case PodcastSources::Manual:
|
||||
$podcastMedia = $episode->getMedia();
|
||||
|
||||
if ($podcastMedia instanceof PodcastMedia) {
|
||||
$fsPodcasts = $this->stationFilesystems->getPodcastsFilesystem($station);
|
||||
|
||||
$path = $podcastMedia->getPath();
|
||||
|
||||
if ($fsPodcasts->fileExists($path)) {
|
||||
return $response->streamFilesystemFile(
|
||||
$fsPodcasts,
|
||||
$path,
|
||||
$podcastMedia->getOriginalName()
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace App\Controller\Api\Stations\Podcasts\Episodes\Media;
|
|||
use App\Controller\SingleActionInterface;
|
||||
use App\Entity\Api\Error;
|
||||
use App\Entity\Api\Status;
|
||||
use App\Entity\Enums\PodcastSources;
|
||||
use App\Entity\Repository\PodcastEpisodeRepository;
|
||||
use App\Flysystem\StationFilesystems;
|
||||
use App\Http\Response;
|
||||
|
@ -14,6 +15,7 @@ use App\Http\ServerRequest;
|
|||
use App\OpenApi;
|
||||
use App\Service\Flow;
|
||||
use App\Utilities\Types;
|
||||
use InvalidArgumentException;
|
||||
use OpenApi\Attributes as OA;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
|
@ -60,20 +62,22 @@ final class PostMediaAction implements SingleActionInterface
|
|||
Response $response,
|
||||
array $params
|
||||
): ResponseInterface {
|
||||
$episodeId = Types::stringOrNull($params['episode_id'] ?? null, true);
|
||||
|
||||
$podcast = $request->getPodcast();
|
||||
$station = $request->getStation();
|
||||
|
||||
if ($podcast->getSource() !== PodcastSources::Manual) {
|
||||
throw new InvalidArgumentException('Media cannot be manually set on this podcast.');
|
||||
}
|
||||
|
||||
$episodeId = Types::stringOrNull($params['episode_id'] ?? null, true);
|
||||
|
||||
$flowResponse = Flow::process($request, $response, $station->getRadioTempDir());
|
||||
if ($flowResponse instanceof ResponseInterface) {
|
||||
return $flowResponse;
|
||||
}
|
||||
|
||||
if (null !== $episodeId) {
|
||||
$episode = $this->episodeRepo->fetchEpisodeForPodcast(
|
||||
$request->getPodcast(),
|
||||
$episodeId
|
||||
);
|
||||
$episode = $this->episodeRepo->fetchEpisodeForPodcast($podcast, $episodeId);
|
||||
|
||||
if (null === $episode) {
|
||||
return $response->withStatus(404)
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace App\Entity\Repository;
|
||||
|
||||
use App\Doctrine\Repository;
|
||||
use App\Entity\Enums\PodcastSources;
|
||||
use App\Entity\Podcast;
|
||||
use App\Entity\Station;
|
||||
use App\Exception\StorageLocationFullException;
|
||||
|
@ -47,11 +48,15 @@ final class PodcastRepository extends Repository
|
|||
SELECT DISTINCT p.id
|
||||
FROM App\Entity\PodcastEpisode pe
|
||||
JOIN pe.podcast p
|
||||
JOIN pe.media pm
|
||||
WHERE pm.id IS NOT NULL
|
||||
AND (pe.publish_at IS NULL OR pe.publish_at <= :time)
|
||||
LEFT JOIN pe.media pm
|
||||
LEFT JOIN pe.playlist_media sm
|
||||
WHERE
|
||||
((p.source = :sourceManual AND pm.id IS NOT NULL) OR (p.source = :sourcePlaylist AND sm.id IS NOT NULL))
|
||||
AND (pe.publish_at IS NULL OR pe.publish_at <= :time)
|
||||
DQL
|
||||
)->setParameter('time', time())
|
||||
->setParameter('sourceManual', PodcastSources::Manual->value)
|
||||
->setParameter('sourcePlaylist', PodcastSources::Playlist->value)
|
||||
->enableResultCache(60, 'podcast_ids_' . $station->getIdRequired())
|
||||
->getSingleColumnResult();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue