From 0fa72f6328c9f5cf83c7a61fc24b45a5c5351235 Mon Sep 17 00:00:00 2001 From: Henry Orozco Date: Fri, 20 Dec 2024 13:28:13 -0600 Subject: [PATCH] feat: add playlist RSS --- package-lock.json | 16 +++--- .../library/playlist/detail.graphql | 13 +++++ src/containers/library/playlist/detail.tsx | 6 ++- src/lib/routes/playlists.ts | 1 + .../playlists/[playlist]/feed.xml/index.ts | 50 +++++++++++++++++++ 5 files changed, 78 insertions(+), 8 deletions(-) create mode 100644 src/pages/[language]/playlists/[playlist]/feed.xml/index.ts diff --git a/package-lock.json b/package-lock.json index 0920ccfef..cc17004d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4782,10 +4782,11 @@ "dev": true }, "node_modules/@graphql-tools/utils": { - "version": "10.6.2", - "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.6.2.tgz", - "integrity": "sha512-ABZHTpwiVR8oE2//NI/nnU3nNhbBpqMlMYyCF5cnqjLfhlyOdFfoRuhYEATEsmMfDg0ijGreULywK/SmepVGfw==", + "version": "10.6.4", + "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.6.4.tgz", + "integrity": "sha512-itCgjwVxbO+3uI/K73G9heedG8KelNFzgn368rUhPjTrkJX6NyLQwT5EMq/A8tvazMXyJYdtnN5nD+tT4DUpbQ==", "dev": true, + "license": "MIT", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "cross-inspect": "1.0.1", @@ -11204,9 +11205,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001686", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001686.tgz", - "integrity": "sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==", + "version": "1.0.30001690", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", "funding": [ { "type": "opencollective", @@ -11220,7 +11221,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/capital-case": { "version": "1.0.4", diff --git a/src/containers/library/playlist/detail.graphql b/src/containers/library/playlist/detail.graphql index edb154868..06964c4a9 100644 --- a/src/containers/library/playlist/detail.graphql +++ b/src/containers/library/playlist/detail.graphql @@ -39,3 +39,16 @@ query getPlaylistPageData($id: ID!) { } } } + +query getPlaylistFeedData($id: ID!) { + playlist(id: $id) { + id + title + summary + recordings(offset: 0, first: 1500) { + nodes { + ...generateFeed + } + } + } +} diff --git a/src/containers/library/playlist/detail.tsx b/src/containers/library/playlist/detail.tsx index 937594ed0..9c2063127 100644 --- a/src/containers/library/playlist/detail.tsx +++ b/src/containers/library/playlist/detail.tsx @@ -91,7 +91,11 @@ function PlaylistDetail({ playlist }: Must): JSX.Element { /> ) : ( ({ playlist: (playlistId: string | number) => node(`${r}/${playlistId}`, (r) => ({ + feed: node(`${r}/feed.xml`), items: (canonicalPath: string) => node(`${r}/items/${canonicalPath.split('/').slice(3).join('/')}`), })), diff --git a/src/pages/[language]/playlists/[playlist]/feed.xml/index.ts b/src/pages/[language]/playlists/[playlist]/feed.xml/index.ts new file mode 100644 index 000000000..3a61b2c83 --- /dev/null +++ b/src/pages/[language]/playlists/[playlist]/feed.xml/index.ts @@ -0,0 +1,50 @@ +import { GetServerSidePropsContext, GetServerSidePropsResult } from 'next'; + +import { generateFeed, sendRSSHeaders } from '~lib/generateFeed'; +import { getPlaylistFeedData } from '~src/containers/library/playlist/__generated__/detail'; +import root from '~src/lib/routes'; + +export default (): void => void 0; + +export async function getServerSideProps({ + params, + res, +}: GetServerSidePropsContext<{ language: string; playlist: string }>): Promise< + GetServerSidePropsResult> +> { + const id = params?.playlist as string; + const languageRoute = params?.language as string; + + const { playlist } = await getPlaylistFeedData({ + id, + }).catch(() => ({ + playlist: null, + })); + + if (!playlist) { + return { + notFound: true, + }; + } + + if (res) { + sendRSSHeaders(res); + + const feed = await generateFeed( + languageRoute, + { + link: root.lang(languageRoute).playlists.playlist(id).get(), + title: playlist.title, + description: playlist.summary, + }, + playlist.recordings.nodes || [], + ); + res.write(feed); + + res.end(); + } + + return { + props: {}, + }; +}