diff --git a/server.ts b/server.ts
index 14102c7..f75da21 100644
--- a/server.ts
+++ b/server.ts
@@ -266,6 +266,25 @@ app.get("/api/feeds/:feedId/episodes", async (c) => {
}
});
+app.get("/api/episode-with-source/:episodeId", async (c) => {
+ try {
+ const episodeId = c.req.param("episodeId");
+ const { fetchEpisodeWithSourceInfo } = await import(
+ "./services/database.js"
+ );
+ const episode = await fetchEpisodeWithSourceInfo(episodeId);
+
+ if (!episode) {
+ return c.json({ error: "Episode not found" }, 404);
+ }
+
+ return c.json({ episode });
+ } catch (error) {
+ console.error("Error fetching episode with source info:", error);
+ return c.json({ error: "Failed to fetch episode with source info" }, 500);
+ }
+});
+
app.get("/api/episodes-with-feed-info", async (c) => {
try {
const { fetchEpisodesWithFeedInfo } = await import(
diff --git a/services/podcast.ts b/services/podcast.ts
index 1c4cacc..61628cb 100644
--- a/services/podcast.ts
+++ b/services/podcast.ts
@@ -1,10 +1,6 @@
import { promises as fs } from "fs";
import { dirname } from "path";
-import {
- Episode,
- fetchAllEpisodes,
- performDatabaseIntegrityFixes,
-} from "./database.js";
+import { fetchEpisodesWithFeedInfo } from "./database.js";
import path from "node:path";
import fsSync from "node:fs";
import { config } from "./config.js";
@@ -18,7 +14,7 @@ function escapeXml(text: string): string {
.replace(/'/g, "'");
}
-function createItemXml(episode: Episode): string {
+function createItemXml(episode: any): string {
const fileUrl = `${config.podcast.baseUrl}/podcast_audio/${path.basename(episode.audioPath)}`;
const pubDate = new Date(episode.createdAt).toUTCString();
@@ -35,10 +31,28 @@ function createItemXml(episode: Episode): string {
console.warn(`Could not get file size for ${episode.audioPath}:`, error);
}
+ // Build enhanced description with feed and article info
+ let description = episode.title;
+ if (episode.feedTitle || episode.articleTitle || episode.articleLink) {
+ description += "\n\n";
+ if (episode.feedTitle) {
+ description += `フィード: ${episode.feedTitle}\n`;
+ }
+ if (episode.articleTitle && episode.articleTitle !== episode.title) {
+ description += `元記事: ${episode.articleTitle}\n`;
+ }
+ if (episode.articlePubDate) {
+ description += `記事公開日: ${new Date(episode.articlePubDate).toLocaleString("ja-JP")}\n`;
+ }
+ if (episode.articleLink) {
+ description += `元記事URL: ${episode.articleLink}`;
+ }
+ }
+
return `
-
-
+
${escapeXml(config.podcast.author)}
${escapeXml(config.podcast.categories)}
${config.podcast.language}
@@ -46,15 +60,17 @@ function createItemXml(episode: Episode): string {
${escapeXml(fileUrl)}
${pubDate}
+ ${episode.articleLink ? `${escapeXml(episode.articleLink)}` : ""}
`;
}
export async function updatePodcastRSS(): Promise {
try {
- const episodes: Episode[] = await fetchAllEpisodes();
+ // Use episodes with feed info for enhanced descriptions
+ const episodesWithFeedInfo = await fetchEpisodesWithFeedInfo();
// Filter episodes to only include those with valid audio files
- const validEpisodes = episodes.filter((episode) => {
+ const validEpisodes = episodesWithFeedInfo.filter((episode) => {
try {
const audioPath = path.join(
config.paths.podcastAudioDir,
@@ -68,7 +84,7 @@ export async function updatePodcastRSS(): Promise {
});
console.log(
- `Found ${episodes.length} episodes, ${validEpisodes.length} with valid audio files`,
+ `Found ${episodesWithFeedInfo.length} episodes, ${validEpisodes.length} with valid audio files`,
);
const lastBuildDate = new Date().toUTCString();