@ -10,11 +10,6 @@ interface Episode {
|
|||||||
audioLength: string
|
audioLength: string
|
||||||
guid: string
|
guid: string
|
||||||
link: string
|
link: string
|
||||||
feedTitle?: string
|
|
||||||
feedUrl?: string
|
|
||||||
articleTitle?: string
|
|
||||||
articleLink?: string
|
|
||||||
articlePubDate?: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EpisodeWithFeedInfo {
|
interface EpisodeWithFeedInfo {
|
||||||
@ -86,12 +81,12 @@ function EpisodeList() {
|
|||||||
audioPath: episode.audioUrl,
|
audioPath: episode.audioUrl,
|
||||||
createdAt: episode.pubDate,
|
createdAt: episode.pubDate,
|
||||||
articleId: episode.guid,
|
articleId: episode.guid,
|
||||||
articleTitle: episode.articleTitle || episode.title,
|
articleTitle: episode.title,
|
||||||
articleLink: episode.articleLink || episode.link,
|
articleLink: episode.link,
|
||||||
articlePubDate: episode.articlePubDate || episode.pubDate,
|
articlePubDate: episode.pubDate,
|
||||||
feedId: '',
|
feedId: '',
|
||||||
feedTitle: episode.feedTitle || 'RSS Feed',
|
feedTitle: 'RSS Feed',
|
||||||
feedUrl: episode.feedUrl || ''
|
feedUrl: ''
|
||||||
}))
|
}))
|
||||||
setEpisodes(convertedEpisodes)
|
setEpisodes(convertedEpisodes)
|
||||||
}
|
}
|
||||||
|
14
server.ts
14
server.ts
@ -147,12 +147,7 @@ app.get("/api/episodes-from-xml", async (c) => {
|
|||||||
audioUrl: item.enclosure?.[0]?.$?.url || '',
|
audioUrl: item.enclosure?.[0]?.$?.url || '',
|
||||||
audioLength: item.enclosure?.[0]?.$?.length || '0',
|
audioLength: item.enclosure?.[0]?.$?.length || '0',
|
||||||
guid: item.guid?.[0] || '',
|
guid: item.guid?.[0] || '',
|
||||||
link: item.link?.[0] || '',
|
link: item.link?.[0] || ''
|
||||||
feedTitle: item['source:feedTitle']?.[0] || '',
|
|
||||||
feedUrl: item['source:feedUrl']?.[0] || '',
|
|
||||||
articleTitle: item['source:articleTitle']?.[0] || '',
|
|
||||||
articleLink: item['source:articleLink']?.[0] || '',
|
|
||||||
articlePubDate: item['source:articlePubDate']?.[0] || ''
|
|
||||||
};
|
};
|
||||||
episodes.push(episode);
|
episodes.push(episode);
|
||||||
}
|
}
|
||||||
@ -214,12 +209,7 @@ app.get("/api/episode/:episodeId", async (c) => {
|
|||||||
audioUrl: targetItem.enclosure?.[0]?.$?.url || '',
|
audioUrl: targetItem.enclosure?.[0]?.$?.url || '',
|
||||||
audioLength: targetItem.enclosure?.[0]?.$?.length || '0',
|
audioLength: targetItem.enclosure?.[0]?.$?.length || '0',
|
||||||
guid: targetItem.guid?.[0] || '',
|
guid: targetItem.guid?.[0] || '',
|
||||||
link: targetItem.link?.[0] || '',
|
link: targetItem.link?.[0] || ''
|
||||||
feedTitle: targetItem['source:feedTitle']?.[0] || '',
|
|
||||||
feedUrl: targetItem['source:feedUrl']?.[0] || '',
|
|
||||||
articleTitle: targetItem['source:articleTitle']?.[0] || '',
|
|
||||||
articleLink: targetItem['source:articleLink']?.[0] || '',
|
|
||||||
articlePubDate: targetItem['source:articlePubDate']?.[0] || ''
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return c.json({ episode });
|
return c.json({ episode });
|
||||||
|
@ -722,6 +722,16 @@ export async function saveEpisode(
|
|||||||
createdAt,
|
createdAt,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
performDatabaseIntegrityFixes(db);
|
||||||
|
console.log(`Episode saved: ${episode}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
"Error performing integrity fixes after saving feed:",
|
||||||
|
error,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error saving episode:", error);
|
console.error("Error saving episode:", error);
|
||||||
|
@ -3,7 +3,6 @@ import { dirname } from "path";
|
|||||||
import {
|
import {
|
||||||
Episode,
|
Episode,
|
||||||
fetchAllEpisodes,
|
fetchAllEpisodes,
|
||||||
fetchEpisodesWithFeedInfo,
|
|
||||||
performDatabaseIntegrityFixes,
|
performDatabaseIntegrityFixes,
|
||||||
} from "./database.js";
|
} from "./database.js";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
@ -19,7 +18,7 @@ function escapeXml(text: string): string {
|
|||||||
.replace(/'/g, "'");
|
.replace(/'/g, "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
function createItemXml(episode: any): string {
|
function createItemXml(episode: Episode): 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();
|
||||||
|
|
||||||
@ -47,17 +46,12 @@ function createItemXml(episode: any): 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>
|
||||||
<source:feedTitle><![CDATA[${escapeXml(episode.feedTitle || '')}]]></source:feedTitle>
|
|
||||||
<source:feedUrl>${escapeXml(episode.feedUrl || '')}</source:feedUrl>
|
|
||||||
<source:articleTitle><![CDATA[${escapeXml(episode.articleTitle || '')}]]></source:articleTitle>
|
|
||||||
<source:articleLink>${escapeXml(episode.articleLink || '')}</source:articleLink>
|
|
||||||
<source:articlePubDate>${episode.articlePubDate || ''}</source:articlePubDate>
|
|
||||||
</item>`;
|
</item>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updatePodcastRSS(): Promise<void> {
|
export async function updatePodcastRSS(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const episodes = await fetchEpisodesWithFeedInfo();
|
const episodes: Episode[] = await fetchAllEpisodes();
|
||||||
|
|
||||||
// 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 = episodes.filter((episode) => {
|
||||||
@ -83,7 +77,7 @@ export async function updatePodcastRSS(): Promise<void> {
|
|||||||
|
|
||||||
// Create RSS XML content
|
// Create RSS XML content
|
||||||
const rssXml = `<?xml version="1.0" encoding="UTF-8"?>
|
const rssXml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<rss version="2.0" xmlns:source="http://source.example.com/podcast">
|
<rss version="2.0">
|
||||||
<channel>
|
<channel>
|
||||||
<title>${escapeXml(config.podcast.title)}</title>
|
<title>${escapeXml(config.podcast.title)}</title>
|
||||||
<link>${escapeXml(config.podcast.link)}</link>
|
<link>${escapeXml(config.podcast.link)}</link>
|
||||||
|
Reference in New Issue
Block a user