fix: Generate feeds for series in addition to podcast #19
27
lib/nrk.ts
27
lib/nrk.ts
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,6 +88,7 @@ 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;
|
||||||
|
try {
|
||||||
const feedContent = await buildFeed(seriesId);
|
const feedContent = await buildFeed(seriesId);
|
||||||
|
|
||||||
return new Response(feedContent, {
|
return new Response(feedContent, {
|
||||||
|
|
@ -95,4 +96,13 @@ export const handler = async (_req: Request, ctx: FreshContext): Promise<Respons
|
||||||
"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",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue