Add searching feature
This commit is contained in:
@ -218,7 +218,9 @@ function initializeDatabase(): Database {
|
||||
|
||||
// Ensure the category column exists in episodes
|
||||
const episodeInfos = db.prepare("PRAGMA table_info(episodes);").all();
|
||||
const hasEpisodeCategory = episodeInfos.some((col: any) => col.name === "category");
|
||||
const hasEpisodeCategory = episodeInfos.some(
|
||||
(col: any) => col.name === "category",
|
||||
);
|
||||
|
||||
if (!hasEpisodeCategory) {
|
||||
db.exec("ALTER TABLE episodes ADD COLUMN category TEXT DEFAULT NULL;");
|
||||
@ -581,6 +583,88 @@ export async function fetchEpisodeWithSourceInfo(
|
||||
}
|
||||
}
|
||||
|
||||
// Search episodes with feed information
|
||||
export async function searchEpisodesWithFeedInfo(
|
||||
query: string,
|
||||
category?: string,
|
||||
): Promise<EpisodeWithFeedInfo[]> {
|
||||
try {
|
||||
let whereClause = `
|
||||
WHERE f.active = 1
|
||||
AND (
|
||||
e.title LIKE ?
|
||||
OR e.description LIKE ?
|
||||
OR a.title LIKE ?
|
||||
OR a.description LIKE ?
|
||||
OR a.content LIKE ?
|
||||
)
|
||||
`;
|
||||
|
||||
const searchPattern = `%${query}%`;
|
||||
const params = [
|
||||
searchPattern,
|
||||
searchPattern,
|
||||
searchPattern,
|
||||
searchPattern,
|
||||
searchPattern,
|
||||
];
|
||||
|
||||
if (category) {
|
||||
whereClause += " AND f.category = ?";
|
||||
params.push(category);
|
||||
}
|
||||
|
||||
const stmt = db.prepare(`
|
||||
SELECT
|
||||
e.id,
|
||||
e.title,
|
||||
e.description,
|
||||
e.audio_path as audioPath,
|
||||
e.duration,
|
||||
e.file_size as fileSize,
|
||||
e.category,
|
||||
e.created_at as createdAt,
|
||||
e.article_id as articleId,
|
||||
a.title as articleTitle,
|
||||
a.link as articleLink,
|
||||
a.pub_date as articlePubDate,
|
||||
f.id as feedId,
|
||||
f.title as feedTitle,
|
||||
f.url as feedUrl,
|
||||
f.category as feedCategory
|
||||
FROM episodes e
|
||||
JOIN articles a ON e.article_id = a.id
|
||||
JOIN feeds f ON a.feed_id = f.id
|
||||
${whereClause}
|
||||
ORDER BY e.created_at DESC
|
||||
`);
|
||||
|
||||
const rows = stmt.all(...params) as any[];
|
||||
|
||||
return rows.map((row) => ({
|
||||
id: row.id,
|
||||
title: row.title,
|
||||
description: row.description,
|
||||
audioPath: row.audioPath,
|
||||
duration: row.duration,
|
||||
fileSize: row.fileSize,
|
||||
category: row.category,
|
||||
createdAt: row.createdAt,
|
||||
articleId: row.articleId,
|
||||
articleTitle: row.articleTitle,
|
||||
articleLink: row.articleLink,
|
||||
articlePubDate: row.articlePubDate,
|
||||
feedId: row.feedId,
|
||||
feedTitle: row.feedTitle,
|
||||
feedUrl: row.feedUrl,
|
||||
feedCategory: row.feedCategory,
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error("Error searching episodes with feed info:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAllFeedsIncludingInactive(): Promise<Feed[]> {
|
||||
try {
|
||||
const stmt = db.prepare("SELECT * FROM feeds ORDER BY created_at DESC");
|
||||
@ -1309,7 +1393,9 @@ export async function deleteEpisode(episodeId: string): Promise<boolean> {
|
||||
}
|
||||
|
||||
// Episode category management functions
|
||||
export async function getEpisodesByCategory(category?: string): Promise<EpisodeWithFeedInfo[]> {
|
||||
export async function getEpisodesByCategory(
|
||||
category?: string,
|
||||
): Promise<EpisodeWithFeedInfo[]> {
|
||||
try {
|
||||
let stmt;
|
||||
let rows;
|
||||
@ -1458,7 +1544,10 @@ export async function getEpisodeCategoryStats(): Promise<{
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateEpisodeCategory(episodeId: string, category: string): Promise<boolean> {
|
||||
export async function updateEpisodeCategory(
|
||||
episodeId: string,
|
||||
category: string,
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
const stmt = db.prepare("UPDATE episodes SET category = ? WHERE id = ?");
|
||||
const result = stmt.run(category, episodeId);
|
||||
@ -1519,10 +1608,7 @@ export async function migrateEpisodesWithCategories(): Promise<void> {
|
||||
// Add a small delay to avoid rate limiting
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`❌ Failed to classify episode ${episode.title}:`,
|
||||
error,
|
||||
);
|
||||
console.error(`❌ Failed to classify episode ${episode.title}:`, error);
|
||||
errorCount++;
|
||||
|
||||
// Set a default category for failed classifications
|
||||
|
Reference in New Issue
Block a user