Update
This commit is contained in:
		
							
								
								
									
										19
									
								
								server.ts
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								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) => {
 | 
					app.get("/api/episodes-with-feed-info", async (c) => {
 | 
				
			||||||
  try {
 | 
					  try {
 | 
				
			||||||
    const { fetchEpisodesWithFeedInfo } = await import(
 | 
					    const { fetchEpisodesWithFeedInfo } = await import(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,6 @@
 | 
				
			|||||||
import { promises as fs } from "fs";
 | 
					import { promises as fs } from "fs";
 | 
				
			||||||
import { dirname } from "path";
 | 
					import { dirname } from "path";
 | 
				
			||||||
import {
 | 
					import { fetchEpisodesWithFeedInfo } from "./database.js";
 | 
				
			||||||
  Episode,
 | 
					 | 
				
			||||||
  fetchAllEpisodes,
 | 
					 | 
				
			||||||
  performDatabaseIntegrityFixes,
 | 
					 | 
				
			||||||
} from "./database.js";
 | 
					 | 
				
			||||||
import path from "node:path";
 | 
					import path from "node:path";
 | 
				
			||||||
import fsSync from "node:fs";
 | 
					import fsSync from "node:fs";
 | 
				
			||||||
import { config } from "./config.js";
 | 
					import { config } from "./config.js";
 | 
				
			||||||
@@ -18,7 +14,7 @@ function escapeXml(text: string): string {
 | 
				
			|||||||
    .replace(/'/g, "'");
 | 
					    .replace(/'/g, "'");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function createItemXml(episode: Episode): string {
 | 
					function createItemXml(episode: any): string {
 | 
				
			||||||
  const fileUrl = `${config.podcast.baseUrl}/podcast_audio/${path.basename(episode.audioPath)}`;
 | 
					  const fileUrl = `${config.podcast.baseUrl}/podcast_audio/${path.basename(episode.audioPath)}`;
 | 
				
			||||||
  const pubDate = new Date(episode.createdAt).toUTCString();
 | 
					  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);
 | 
					    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 `
 | 
					  return `
 | 
				
			||||||
    <item>
 | 
					    <item>
 | 
				
			||||||
      <title><![CDATA[${escapeXml(episode.title)}]]></title>
 | 
					      <title><![CDATA[${escapeXml(episode.title)}]]></title>
 | 
				
			||||||
      <description><![CDATA[${escapeXml(episode.title)}]]></description>
 | 
					      <description><![CDATA[${escapeXml(description)}]]></description>
 | 
				
			||||||
      <author>${escapeXml(config.podcast.author)}</author>
 | 
					      <author>${escapeXml(config.podcast.author)}</author>
 | 
				
			||||||
      <category>${escapeXml(config.podcast.categories)}</category>
 | 
					      <category>${escapeXml(config.podcast.categories)}</category>
 | 
				
			||||||
      <language>${config.podcast.language}</language>
 | 
					      <language>${config.podcast.language}</language>
 | 
				
			||||||
@@ -46,15 +60,17 @@ function createItemXml(episode: Episode): string {
 | 
				
			|||||||
      <enclosure url="${escapeXml(fileUrl)}" length="${fileSize}" type="audio/mpeg" />
 | 
					      <enclosure url="${escapeXml(fileUrl)}" length="${fileSize}" type="audio/mpeg" />
 | 
				
			||||||
      <guid>${escapeXml(fileUrl)}</guid>
 | 
					      <guid>${escapeXml(fileUrl)}</guid>
 | 
				
			||||||
      <pubDate>${pubDate}</pubDate>
 | 
					      <pubDate>${pubDate}</pubDate>
 | 
				
			||||||
 | 
					      ${episode.articleLink ? `<link>${escapeXml(episode.articleLink)}</link>` : ""}
 | 
				
			||||||
    </item>`;
 | 
					    </item>`;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export async function updatePodcastRSS(): Promise<void> {
 | 
					export async function updatePodcastRSS(): Promise<void> {
 | 
				
			||||||
  try {
 | 
					  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
 | 
					    // Filter episodes to only include those with valid audio files
 | 
				
			||||||
    const validEpisodes = episodes.filter((episode) => {
 | 
					    const validEpisodes = episodesWithFeedInfo.filter((episode) => {
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        const audioPath = path.join(
 | 
					        const audioPath = path.join(
 | 
				
			||||||
          config.paths.podcastAudioDir,
 | 
					          config.paths.podcastAudioDir,
 | 
				
			||||||
@@ -68,7 +84,7 @@ export async function updatePodcastRSS(): Promise<void> {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    console.log(
 | 
					    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();
 | 
					    const lastBuildDate = new Date().toUTCString();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user