Add content to RSS feed items

This commit is contained in:
Bad Manners 2024-04-02 22:48:48 -03:00
parent 37db38b613
commit e859109ade
4 changed files with 172 additions and 18 deletions

View file

@ -1,12 +1,17 @@
import rss, { type RSSFeedItem } from "@astrojs/rss";
import type { APIRoute } from "astro";
import { getCollection } from "astro:content";
import { getCollection, type CollectionEntry } from "astro:content";
import sanitizeHtml from "sanitize-html";
import { marked } from "marked";
import { decode as tinyDecode } from "tiny-decode";
import { t } from "../i18n";
import type { Lang } from "../content/config";
type FeedItem = RSSFeedItem & {
pubDate: Date;
};
const MAX_ITEMS = 10;
const MAX_ITEMS = 8;
function toNoonUTCDate(date: Date) {
const adjustedDate = new Date(date);
@ -14,6 +19,15 @@ function toNoonUTCDate(date: Date) {
return adjustedDate;
}
const getLinkForUser = (user: CollectionEntry<"users">, lang: Lang) => {
const userName = user.data.nameLang[lang] || user.data.name;
if (user.data.preferredLink) {
const link = user.data.links[user.data.preferredLink]!;
return `<a href="${typeof link === "string" ? link : link[0]}">${userName}</a>`
}
return userName;
}
export const GET: APIRoute = async ({ site }) => {
const stories = (await getCollection("stories", (story) => !story.data.isDraft))
.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime())
@ -21,30 +35,44 @@ export const GET: APIRoute = async ({ site }) => {
const games = (await getCollection("games", (game) => !game.data.isDraft))
.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime())
.slice(0, MAX_ITEMS);
const users = await getCollection("users");
return rss({
title: "Gallery | Bad Manners",
description: "Stories, games, and (possibly) more by Bad Manners",
site: site as URL,
items: [
stories.map<FeedItem>((story) => ({
title: `New story! "${story.data.title}"`,
pubDate: toNoonUTCDate(story.data.pubDate),
link: `/stories/${story.slug}`,
await Promise.all(stories.map<Promise<FeedItem>>(async ({ data, slug, body }) => ({
title: `New story! "${data.title}"`,
pubDate: toNoonUTCDate(data.pubDate),
link: `/stories/${slug}`,
description:
`Word count: ${story.data.wordCount}. ${story.data.contentWarning} ${story.data.descriptionPlaintext || story.data.description}`
`Word count: ${data.wordCount}. ${data.contentWarning} ${data.descriptionPlaintext || data.description}`
.replaceAll(/[\n ]+/g, " ")
.trim(),
categories: ["story"],
})),
games.map<FeedItem>((game) => ({
title: `New game! "${game.data.title}"`,
pubDate: toNoonUTCDate(game.data.pubDate),
link: `/games/${game.slug}`,
description: `${game.data.contentWarning} ${game.data.descriptionPlaintext || game.data.description}`
content: sanitizeHtml(`<h1>${data.title}</h1><p>${t(data.lang, "story/authors", [data.authors].flatMap((authorArray => {
if (!Array.isArray(authorArray)) {
authorArray = [authorArray]
}
return authorArray.map(author => getLinkForUser(users.find(user => user.id === author.id)!, data.lang));
})))}</p>${data.requester ? `<p>${t(data.lang, "export_story/request_for", getLinkForUser(users.find(user => user.id === data.requester!.id)!, data.lang))}</p>` : ""}${data.commissioner ? `<p>${t(data.lang, "export_story/commissioned_by", getLinkForUser(users.find(user => user.id === data.commissioner!.id)!, data.lang))}</p>` : ""}<hr>${tinyDecode(await marked(body))}`),
}))),
await Promise.all(games.map<Promise<FeedItem>>(async ({ data, slug, body }) => ({
title: `New game! "${data.title}"`,
pubDate: toNoonUTCDate(data.pubDate),
link: `/games/${slug}`,
description: `${data.contentWarning} ${data.descriptionPlaintext || data.description}`
.replaceAll(/[\n ]+/g, " ")
.trim(),
categories: ["game"],
})),
content: sanitizeHtml(`<h1>${data.title}</h1><p>${t(data.lang, "story/authors", [data.authors].flatMap((authorArray => {
if (!Array.isArray(authorArray)) {
authorArray = [authorArray]
}
return authorArray.map(author => getLinkForUser(users.find(user => user.id === author.id)!, data.lang));
})))}</p><hr>${tinyDecode(await marked(body))}`),
}))),
]
.flat()
.sort((a, b) => b.pubDate.getTime() - a.pubDate.getTime())

View file

@ -3,7 +3,7 @@ import { type CollectionEntry, getCollection } from "astro:content";
import { Image } from "astro:assets";
import GalleryLayout from "../layouts/GalleryLayout.astro";
const MAX_ITEMS = 5;
const MAX_ITEMS = 8;
interface LatestItemsEntry {
type: string;