Add JMDict Japanese dictionary support

This commit is contained in:
2025-06-11 23:03:17 +09:00
parent a77a8aa9bd
commit 71d3f1912d
6 changed files with 681 additions and 126 deletions

View File

@ -341,27 +341,35 @@ export async function fetchActiveFeeds(): Promise<Feed[]> {
// Get paginated active feeds with total count
export async function fetchActiveFeedsPaginated(
page: number = 1,
limit: number = 10,
category?: string
): Promise<{ feeds: Feed[]; total: number; page: number; limit: number; totalPages: number }> {
page = 1,
limit = 10,
category?: string,
): Promise<{
feeds: Feed[];
total: number;
page: number;
limit: number;
totalPages: number;
}> {
try {
const offset = (page - 1) * limit;
// Build query conditions
let whereCondition = "WHERE active = 1";
const params: any[] = [];
if (category) {
whereCondition += " AND category = ?";
params.push(category);
}
// Get total count
const countStmt = db.prepare(`SELECT COUNT(*) as count FROM feeds ${whereCondition}`);
const countStmt = db.prepare(
`SELECT COUNT(*) as count FROM feeds ${whereCondition}`,
);
const countResult = countStmt.get(...params) as { count: number };
const total = countResult.count;
// Get paginated feeds
const feedsStmt = db.prepare(`
SELECT * FROM feeds
@ -369,9 +377,9 @@ export async function fetchActiveFeedsPaginated(
ORDER BY created_at DESC
LIMIT ? OFFSET ?
`);
const rows = feedsStmt.all(...params, limit, offset) as any[];
const feeds = rows.map((row) => ({
id: row.id,
url: row.url,
@ -382,15 +390,15 @@ export async function fetchActiveFeedsPaginated(
createdAt: row.created_at,
active: Boolean(row.active),
}));
const totalPages = Math.ceil(total / limit);
return {
feeds,
total,
page,
limit,
totalPages
totalPages,
};
} catch (error) {
console.error("Error getting paginated feeds:", error);
@ -456,22 +464,28 @@ export async function fetchEpisodesWithFeedInfo(): Promise<
// Get episodes with feed information for enhanced display (paginated)
export async function fetchEpisodesWithFeedInfoPaginated(
page: number = 1,
limit: number = 10,
category?: string
): Promise<{ episodes: EpisodeWithFeedInfo[]; total: number; page: number; limit: number; totalPages: number }> {
page = 1,
limit = 10,
category?: string,
): Promise<{
episodes: EpisodeWithFeedInfo[];
total: number;
page: number;
limit: number;
totalPages: number;
}> {
try {
const offset = (page - 1) * limit;
// Build query conditions
let whereCondition = "WHERE f.active = 1";
const params: any[] = [];
if (category) {
whereCondition += " AND e.category = ?";
params.push(category);
}
// Get total count
const countStmt = db.prepare(`
SELECT COUNT(*) as count
@ -482,7 +496,7 @@ export async function fetchEpisodesWithFeedInfoPaginated(
`);
const countResult = countStmt.get(...params) as { count: number };
const total = countResult.count;
// Get paginated episodes
const episodesStmt = db.prepare(`
SELECT
@ -509,9 +523,9 @@ export async function fetchEpisodesWithFeedInfoPaginated(
ORDER BY e.created_at DESC
LIMIT ? OFFSET ?
`);
const rows = episodesStmt.all(...params, limit, offset) as any[];
const episodes = rows.map((row) => ({
id: row.id,
title: row.title,
@ -530,15 +544,15 @@ export async function fetchEpisodesWithFeedInfoPaginated(
feedUrl: row.feedUrl,
feedCategory: row.feedCategory,
}));
const totalPages = Math.ceil(total / limit);
return {
episodes,
total,
page,
limit,
totalPages
totalPages,
};
} catch (error) {
console.error("Error fetching paginated episodes with feed info:", error);
@ -1636,7 +1650,9 @@ export async function updateEpisodeCategory(
// Category cleanup functions
export async function deleteFeedCategory(category: string): Promise<number> {
try {
const stmt = db.prepare("UPDATE feeds SET category = NULL WHERE category = ?");
const stmt = db.prepare(
"UPDATE feeds SET category = NULL WHERE category = ?",
);
const result = stmt.run(category);
return result.changes;
} catch (error) {
@ -1647,7 +1663,9 @@ export async function deleteFeedCategory(category: string): Promise<number> {
export async function deleteEpisodeCategory(category: string): Promise<number> {
try {
const stmt = db.prepare("UPDATE episodes SET category = NULL WHERE category = ?");
const stmt = db.prepare(
"UPDATE episodes SET category = NULL WHERE category = ?",
);
const result = stmt.run(category);
return result.changes;
} catch (error) {
@ -1656,15 +1674,17 @@ export async function deleteEpisodeCategory(category: string): Promise<number> {
}
}
export async function deleteCategoryFromBoth(category: string): Promise<{feedChanges: number, episodeChanges: number}> {
export async function deleteCategoryFromBoth(
category: string,
): Promise<{ feedChanges: number; episodeChanges: number }> {
try {
db.exec("BEGIN TRANSACTION");
const feedChanges = await deleteFeedCategory(category);
const episodeChanges = await deleteEpisodeCategory(category);
db.exec("COMMIT");
return { feedChanges, episodeChanges };
} catch (error) {
db.exec("ROLLBACK");
@ -1673,21 +1693,25 @@ export async function deleteCategoryFromBoth(category: string): Promise<{feedCha
}
}
export async function getAllUsedCategories(): Promise<{feedCategories: string[], episodeCategories: string[], allCategories: string[]}> {
export async function getAllUsedCategories(): Promise<{
feedCategories: string[];
episodeCategories: string[];
allCategories: string[];
}> {
try {
// Get feed categories
const feedCatStmt = db.prepare(
"SELECT DISTINCT category FROM feeds WHERE category IS NOT NULL AND category != '' ORDER BY category"
"SELECT DISTINCT category FROM feeds WHERE category IS NOT NULL AND category != '' ORDER BY category",
);
const feedCatRows = feedCatStmt.all() as any[];
const feedCategories = feedCatRows.map(row => row.category);
const feedCategories = feedCatRows.map((row) => row.category);
// Get episode categories
const episodeCatStmt = db.prepare(
"SELECT DISTINCT category FROM episodes WHERE category IS NOT NULL AND category != '' ORDER BY category"
"SELECT DISTINCT category FROM episodes WHERE category IS NOT NULL AND category != '' ORDER BY category",
);
const episodeCatRows = episodeCatStmt.all() as any[];
const episodeCategories = episodeCatRows.map(row => row.category);
const episodeCategories = episodeCatRows.map((row) => row.category);
// Get all unique categories
const allCategoriesSet = new Set([...feedCategories, ...episodeCategories]);
@ -1696,7 +1720,7 @@ export async function getAllUsedCategories(): Promise<{feedCategories: string[],
return {
feedCategories,
episodeCategories,
allCategories
allCategories,
};
} catch (error) {
console.error("Error getting all used categories:", error);
@ -1704,19 +1728,27 @@ export async function getAllUsedCategories(): Promise<{feedCategories: string[],
}
}
export async function getCategoryCounts(category: string): Promise<{feedCount: number, episodeCount: number}> {
export async function getCategoryCounts(
category: string,
): Promise<{ feedCount: number; episodeCount: number }> {
try {
// Count feeds with this category
const feedCountStmt = db.prepare("SELECT COUNT(*) as count FROM feeds WHERE category = ?");
const feedCountStmt = db.prepare(
"SELECT COUNT(*) as count FROM feeds WHERE category = ?",
);
const feedCountResult = feedCountStmt.get(category) as { count: number };
// Count episodes with this category
const episodeCountStmt = db.prepare("SELECT COUNT(*) as count FROM episodes WHERE category = ?");
const episodeCountResult = episodeCountStmt.get(category) as { count: number };
const episodeCountStmt = db.prepare(
"SELECT COUNT(*) as count FROM episodes WHERE category = ?",
);
const episodeCountResult = episodeCountStmt.get(category) as {
count: number;
};
return {
feedCount: feedCountResult.count,
episodeCount: episodeCountResult.count
episodeCount: episodeCountResult.count,
};
} catch (error) {
console.error("Error getting category counts:", error);