From f7813da81fdc40a1179d986e341cd66d9e9a55e0 Mon Sep 17 00:00:00 2001 From: olaven Date: Sun, 7 Apr 2024 19:12:01 +0200 Subject: [PATCH] moved parse function to nrk.ts --- lib/caching.ts | 15 ++---- lib/nrk/nrk.ts | 52 +++++++++++++++---- lib/parse.ts | 31 ----------- .../feeds/[seriesId]/[episodeId]/chapters.ts | 4 +- routes/index.tsx | 8 +-- 5 files changed, 52 insertions(+), 58 deletions(-) delete mode 100644 lib/parse.ts diff --git a/lib/caching.ts b/lib/caching.ts index 41a20a7..67e4ac1 100644 --- a/lib/caching.ts +++ b/lib/caching.ts @@ -1,27 +1,22 @@ import { nrkRadio } from "./nrk/nrk.ts"; -import { parse } from "./parse.ts"; import { Series, storage } from "./storage.ts"; import * as datetime from "datetime"; const SYNC_INTERVAL_HOURS = 1; async function initialFetch(options: { id: string }) { - const fromNrk = await nrkRadio.getSerieData(options.id); - const parsed = parse.series(fromNrk); - - const stored = storage.write(parsed); + const series = await nrkRadio.getSeries(options.id); + const stored = storage.write(series); if (!stored) { throw new Error(`Failed to store series ${options.id}`); } - return parsed; + return series; } async function updateFetch(existingSeries: Series) { - const fromNrk = await nrkRadio.getSerieData(existingSeries.id); - const parsed = parse.series(fromNrk); - - const newEpisodes = parsed.episodes.filter((episode) => { + const series = await nrkRadio.getSeries(existingSeries.id); + const newEpisodes = series.episodes.filter((episode) => { return !existingSeries.episodes.find((serieEpisode) => serieEpisode.id === episode.id); }); diff --git a/lib/nrk/nrk.ts b/lib/nrk/nrk.ts index 75328b7..e18af3d 100644 --- a/lib/nrk/nrk.ts +++ b/lib/nrk/nrk.ts @@ -2,28 +2,54 @@ import { get, OK } from "https://deno.land/x/kall@v0.1.0/mod.ts"; import { components as searchComponents } from "./nrk-search.ts"; import { components as catalogComponents } from "./nrk-catalog.ts"; import { external as playbackComponents } from "./nrk-playback.ts"; +import { Series } from "../storage.ts"; type ArrayElement = A extends readonly (infer T)[] ? T : never; type PodcastEpisodes = catalogComponents["schemas"]["EpisodesHalResource"]; type Podcast = catalogComponents["schemas"]["SeriesHalResource"]; type PodcastEpisodesSingle = catalogComponents["schemas"]["EpisodeHalResource"]; -export type Serie = catalogComponents["schemas"]["SeriesViewModel"]; -export type OriginalEpisode = PodcastEpisodesSingle & { url: string }; -export type PodcastEpisode = catalogComponents["schemas"]["PodcastEpisodeHalResource"]; -export type SearchResultList = searchComponents["schemas"]["seriesResult"]["results"]; -export type SearchResult = ArrayElement & { +export type NrkSerie = catalogComponents["schemas"]["SeriesViewModel"]; +export type NrkOriginalEpisode = PodcastEpisodesSingle & { url: string }; +export type NrkPodcastEpisode = catalogComponents["schemas"]["PodcastEpisodeHalResource"]; +export type NrkSearchResultList = searchComponents["schemas"]["seriesResult"]["results"]; +export type SearchResult = ArrayElement & { description?: string; }; type Manifest = playbackComponents["schemas/playback-channel.json"]["components"]["schemas"]["PlayableManifest"]; +type NrkSerieData = Awaited>; + +function parseSeries(nrkSeries: NrkSerieData): Series { + const imageUrl = nrkSeries.squareImage?.at(-1)?.url ?? ""; + + return { + id: nrkSeries.id, + title: nrkSeries.titles.title, + subtitle: nrkSeries.titles.subtitle ?? null, + link: `https://radio.nrk.no/podkast/${nrkSeries.id}`, + imageUrl: imageUrl, + lastFetchedAt: new Date(), + episodes: nrkSeries.episodes.map((episode) => { + return { + id: episode.id, + title: episode.titles.title, + subtitle: episode.titles.subtitle ?? null, + url: episode.url, + shareLink: episode._links.share?.href ?? "", + date: new Date(episode.date), + durationInSeconds: episode.durationInSeconds, + }; + }), + }; +} const nrkAPI = `https://psapi.nrk.no`; async function withDownloadLink( episode: PodcastEpisodesSingle, type: catalogComponents["schemas"]["Type"], -): Promise { +): Promise { // getting stream link let [playbackStatus, playbackResponse] = await get( `${nrkAPI}/playback/manifest/podcast/${episode.episodeId}`, @@ -43,7 +69,7 @@ async function withDownloadLink( } export const nrkRadio = { - search: async (query: string): Promise => { + search: async (query: string): Promise => { const [status, response] = await get< searchComponents["schemas"]["searchresult"] >(`${nrkAPI}/radio/search/search?q=${query}`); @@ -52,7 +78,7 @@ export const nrkRadio = { } throw `Something went wrong with ${query} - got status ${status}`; }, - getSerieData: async (seriesId: string) => { + getSeries: async (seriesId: string) => { let [ [episodeStatus, episodeResponse], [seriesStatus, serieResponse], @@ -86,16 +112,20 @@ export const nrkRadio = { const episodes = await Promise.all( episodeResponse._embedded.episodes.map((episode) => withDownloadLink(episode, serieResponse.type)), ); - return { + + const serieData = { ...serieResponse.series, episodes, }; + + const parsedSeries = parseSeries(serieData); + return parsedSeries; } throw `Error getting episodes for ${seriesId}: EpisodeStatus: ${episodeStatus}. SerieStatus: ${seriesStatus}`; }, - getEpisode: async (seriesId: string, episodeId: string): Promise => { + getEpisode: async (seriesId: string, episodeId: string): Promise => { const url = `${nrkAPI}/radio/catalog/podcast/${seriesId}/episodes/${episodeId}`; - const [status, episode] = await get(url); + const [status, episode] = await get(url); if (status === OK && episode) { return episode; } diff --git a/lib/parse.ts b/lib/parse.ts deleted file mode 100644 index 878594c..0000000 --- a/lib/parse.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { nrkRadio } from "./nrk/nrk.ts"; -import { Series } from "./storage.ts"; - -type NrkSerieData = Awaited>; -function series(nrkSeries: NrkSerieData): Series { - const imageUrl = nrkSeries.squareImage?.at(-1)?.url ?? ""; - - return { - id: nrkSeries.id, - title: nrkSeries.titles.title, - subtitle: nrkSeries.titles.subtitle ?? null, - link: `https://radio.nrk.no/podkast/${nrkSeries.id}`, - imageUrl: imageUrl, - lastFetchedAt: new Date(), - episodes: nrkSeries.episodes.map((episode) => { - return { - id: episode.id, - title: episode.titles.title, - subtitle: episode.titles.subtitle ?? null, - url: episode.url, - shareLink: episode._links.share?.href ?? "", - date: new Date(episode.date), - durationInSeconds: episode.durationInSeconds, - }; - }), - }; -} - -export const parse = { - series, -}; diff --git a/routes/api/feeds/[seriesId]/[episodeId]/chapters.ts b/routes/api/feeds/[seriesId]/[episodeId]/chapters.ts index 1af97ac..013fa7f 100644 --- a/routes/api/feeds/[seriesId]/[episodeId]/chapters.ts +++ b/routes/api/feeds/[seriesId]/[episodeId]/chapters.ts @@ -1,13 +1,13 @@ import { FreshContext } from "$fresh/server.ts"; import { parse, toSeconds } from "https://esm.sh/iso8601-duration@2.1.1"; -import { nrkRadio, PodcastEpisode } from "../../../../../lib/nrk/nrk.ts"; +import { NrkPodcastEpisode, nrkRadio } from "../../../../../lib/nrk/nrk.ts"; type Chapter = { title: string | undefined; startTime: number | undefined; }; -function toChapters(episode: PodcastEpisode): Chapter[] | null { +function toChapters(episode: NrkPodcastEpisode): Chapter[] | null { if (!episode.indexPoints) { return null; } diff --git a/routes/index.tsx b/routes/index.tsx index 8af430f..30f6828 100644 --- a/routes/index.tsx +++ b/routes/index.tsx @@ -5,20 +5,20 @@ import Header from "../components/Header.tsx"; import Search from "../components/Search.tsx"; import SeriesCard from "../components/SeriesCard.tsx"; import { CSS, render } from "$gfm"; -import { nrkRadio, SearchResultList } from "../lib/nrk/nrk.ts"; +import { nrkRadio, NrkSearchResultList } from "../lib/nrk/nrk.ts"; interface HandlerData { query: string; origin: string; rawMarkdown: string; - result?: SearchResultList; + result?: NrkSearchResultList; } export const handler: Handlers = { async GET(request, ctx) { const url = new URL(request.url); const query = url.searchParams.get("query"); - let result: SearchResultList | undefined; + let result: NrkSearchResultList | undefined; if (query) { result = await nrkRadio.search(query); } @@ -57,7 +57,7 @@ export default function Home({ data }: PageProps) { ); } -function SearchResult({ result, origin }: { result: SearchResultList; origin: string }) { +function SearchResult({ result, origin }: { result: NrkSearchResultList; origin: string }) { if (!result) { return null; }