import { promises as fs } from "fs"; import { dirname } from "path"; import { Episode, fetchAllEpisodes } from "./database.js"; import path from "node:path"; import fsSync from "node:fs"; import { config } from "./config.js"; function escapeXml(text: string): string { return text .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } function createItemXml(episode: Episode): string { const fileUrl = `${config.podcast.baseUrl}/podcast_audio/${path.basename(episode.audioPath)}`; const pubDate = new Date(episode.createdAt).toUTCString(); let fileSize = 0; try { const audioPath = path.join(config.paths.podcastAudioDir, episode.audioPath); if (fsSync.existsSync(audioPath)) { fileSize = fsSync.statSync(audioPath).size; } } catch (error) { console.warn(`Could not get file size for ${episode.audioPath}:`, error); } return ` <![CDATA[${escapeXml(episode.title)}]]> ${escapeXml(config.podcast.author)} ${escapeXml(config.podcast.categories)} ${config.podcast.language} ${config.podcast.ttl} ${escapeXml(fileUrl)} ${pubDate} `; } export async function updatePodcastRSS(): Promise { try { const episodes: Episode[] = await fetchAllEpisodes(); const lastBuildDate = new Date().toUTCString(); const itemsXml = episodes.map(createItemXml).join("\n"); const outputPath = path.join(config.paths.publicDir, "podcast.xml"); // Create RSS XML content const rssXml = ` ${escapeXml(config.podcast.title)} ${escapeXml(config.podcast.link)} ${config.podcast.language} ${lastBuildDate} ${config.podcast.ttl} ${escapeXml(config.podcast.author)} ${escapeXml(config.podcast.categories)}${itemsXml} `; // Ensure directory exists await fs.mkdir(dirname(outputPath), { recursive: true }); await fs.writeFile(outputPath, rssXml); console.log(`RSS feed updated with ${episodes.length} episodes`); } catch (error) { console.error("Error updating podcast RSS:", error); throw error; } }