fix: Generate feeds for series in addition to podcast #19

Merged
timharek merged 4 commits from bugfix-allow-series into main 2024-04-02 14:27:00 +00:00
2 changed files with 41 additions and 10 deletions

View File

@ -22,12 +22,19 @@ const nrkAPI = `https://psapi.nrk.no`;
async function withDownloadLink( async function withDownloadLink(
episode: PodcastEpisodesSingle, episode: PodcastEpisodesSingle,
type: catalogComponents["schemas"]["Type"],
): Promise<OriginalEpisode> { ): Promise<OriginalEpisode> {
// getting stream link // getting stream link
const [playbackStatus, playbackResponse] = await get<Manifest>( let [playbackStatus, playbackResponse] = await get<Manifest>(
`${nrkAPI}/playback/manifest/podcast/${episode.episodeId}`, `${nrkAPI}/playback/manifest/podcast/${episode.episodeId}`,
); );
if (type === "series") {
[playbackStatus, playbackResponse] = await get<Manifest>(
`${nrkAPI}/playback/manifest/program/${episode.episodeId}`,
);
}
if (playbackStatus === OK && playbackResponse) { if (playbackStatus === OK && playbackResponse) {
return { ...episode, url: playbackResponse.playable.assets[0].url }; return { ...episode, url: playbackResponse.playable.assets[0].url };
} else { } else {
@ -46,7 +53,7 @@ export const nrkRadio = {
throw `Something went wrong with ${query} - got status ${status}`; throw `Something went wrong with ${query} - got status ${status}`;
}, },
getSerieData: async (seriesId: string) => { getSerieData: async (seriesId: string) => {
const [ let [
[episodeStatus, episodeResponse], [episodeStatus, episodeResponse],
[seriesStatus, serieResponse], [seriesStatus, serieResponse],
] = await Promise.all([ ] = await Promise.all([
@ -58,12 +65,26 @@ export const nrkRadio = {
), ),
]); ]);
if (episodeStatus !== OK || seriesStatus !== OK) {
[
[episodeStatus, episodeResponse],
[seriesStatus, serieResponse],
] = await Promise.all([
get<catalogComponents["schemas"]["EpisodesHalResource"]>(
`https://psapi.nrk.no/radio/catalog/series/${seriesId}/episodes`,
),
get<catalogComponents["schemas"]["SeriesHalResource"]>(
`https://psapi.nrk.no/radio/catalog/series/${seriesId}`,
),
]);
}
if ( if (
episodeStatus === OK && seriesStatus === OK && episodeStatus === OK && seriesStatus === OK &&
serieResponse?.series && episodeResponse?._embedded.episodes?.length serieResponse?.series && episodeResponse?._embedded.episodes?.length
) { ) {
const episodes = await Promise.all( const episodes = await Promise.all(
episodeResponse._embedded.episodes.map((episode) => withDownloadLink(episode)), episodeResponse._embedded.episodes.map((episode) => withDownloadLink(episode, serieResponse.type)),
); );
return { return {
...serieResponse.series, ...serieResponse.series,

View File

@ -30,7 +30,7 @@ function toItemTag(seriesId: string, episode: OriginalEpisode) {
async function buildFeed(seriesId: string) { async function buildFeed(seriesId: string) {
const serie = await nrkRadio.getSerieData(seriesId); const serie = await nrkRadio.getSerieData(seriesId);
const imageUrl = serie.squareImage.at(-1)?.url; const imageUrl = serie.squareImage?.at(-1)?.url ?? "";
const linkValue = `https://radio.nrk.no/podkast/${serie.id}`; const linkValue = `https://radio.nrk.no/podkast/${serie.id}`;
// Quickly adapted from https://raw.githubusercontent.com/olaven/paperpod/1cde9abd3174b26e126aa74fc5a3b63fd078c0fd/packages/converter/src/rss.ts // Quickly adapted from https://raw.githubusercontent.com/olaven/paperpod/1cde9abd3174b26e126aa74fc5a3b63fd078c0fd/packages/converter/src/rss.ts
@ -88,11 +88,21 @@ async function buildFeed(seriesId: string) {
export const handler = async (_req: Request, ctx: FreshContext): Promise<Response> => { export const handler = async (_req: Request, ctx: FreshContext): Promise<Response> => {
const seriesId = ctx.params.seriesId; const seriesId = ctx.params.seriesId;
const feedContent = await buildFeed(seriesId); try {
const feedContent = await buildFeed(seriesId);
return new Response(feedContent, { return new Response(feedContent, {
headers: { headers: {
"Content-Type": "application/xml", "Content-Type": "application/xml",
}, },
}); });
} catch (error) {
console.error(error);
return new Response(JSON.stringify({ message: "Could not generate feed" }), {
status: 500,
headers: {
"Content-Type": "application/json",
},
});
}
}; };