Add searching feature

This commit is contained in:
2025-06-08 21:53:45 +09:00
parent cd0e4065fc
commit b7f3ca6a27
16 changed files with 564 additions and 194 deletions

View File

@@ -3,10 +3,10 @@ import fsSync from "node:fs";
import path from "node:path";
import { dirname } from "path";
import { config } from "./config.js";
import {
fetchEpisodesWithFeedInfo,
getEpisodesByCategory,
fetchEpisodesByFeedId
import {
fetchEpisodesByFeedId,
fetchEpisodesWithFeedInfo,
getEpisodesByCategory,
} from "./database.js";
function escapeXml(text: string): string {
@@ -86,14 +86,14 @@ function filterValidEpisodes(episodes: any[]): any[] {
// Generate RSS XML from episodes
function generateRSSXml(
episodes: any[],
title: string,
description: string,
link?: string
episodes: any[],
title: string,
description: string,
link?: string,
): string {
const lastBuildDate = new Date().toUTCString();
const itemsXml = episodes.map(createItemXml).join("\n");
return `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
@@ -121,9 +121,9 @@ export async function updatePodcastRSS(): Promise<void> {
const outputPath = path.join(config.paths.publicDir, "podcast.xml");
const rssXml = generateRSSXml(
validEpisodes,
config.podcast.title,
config.podcast.description
validEpisodes,
config.podcast.title,
config.podcast.description,
);
// Ensure directory exists
@@ -151,7 +151,7 @@ export async function generateCategoryRSS(category: string): Promise<string> {
const title = `${config.podcast.title} - ${category}`;
const description = `${config.podcast.description} カテゴリ: ${category}`;
return generateRSSXml(validEpisodes, title, description);
} catch (error) {
console.error(`Error generating category RSS for "${category}":`, error);
@@ -162,9 +162,15 @@ export async function generateCategoryRSS(category: string): Promise<string> {
export async function saveCategoryRSS(category: string): Promise<void> {
try {
const rssXml = await generateCategoryRSS(category);
const safeCategory = category.replace(/[^a-zA-Z0-9\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FAF]/g, "_");
const outputPath = path.join(config.paths.publicDir, `podcast_category_${safeCategory}.xml`);
const safeCategory = category.replace(
/[^a-zA-Z0-9\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FAF]/g,
"_",
);
const outputPath = path.join(
config.paths.publicDir,
`podcast_category_${safeCategory}.xml`,
);
// Ensure directory exists
await fs.mkdir(dirname(outputPath), { recursive: true });
await fs.writeFile(outputPath, rssXml);
@@ -187,10 +193,11 @@ export async function generateFeedRSS(feedId: string): Promise<string> {
);
// Use feed info for RSS metadata if available
const feedTitle = validEpisodes.length > 0 ? validEpisodes[0].feedTitle : "Unknown Feed";
const feedTitle =
validEpisodes.length > 0 ? validEpisodes[0].feedTitle : "Unknown Feed";
const title = `${config.podcast.title} - ${feedTitle}`;
const description = `${config.podcast.description} フィード: ${feedTitle}`;
return generateRSSXml(validEpisodes, title, description);
} catch (error) {
console.error(`Error generating feed RSS for "${feedId}":`, error);
@@ -201,8 +208,11 @@ export async function generateFeedRSS(feedId: string): Promise<string> {
export async function saveFeedRSS(feedId: string): Promise<void> {
try {
const rssXml = await generateFeedRSS(feedId);
const outputPath = path.join(config.paths.publicDir, `podcast_feed_${feedId}.xml`);
const outputPath = path.join(
config.paths.publicDir,
`podcast_feed_${feedId}.xml`,
);
// Ensure directory exists
await fs.mkdir(dirname(outputPath), { recursive: true });
await fs.writeFile(outputPath, rssXml);