Revert "Update"

This reverts commit 7e17e30925.
This commit is contained in:
2025-06-07 10:38:38 +09:00
parent 1ce50794fb
commit 5af943e8bd

102
server.ts
View File

@ -2,11 +2,11 @@ import { Hono } from "hono";
import { serve } from "@hono/node-server"; import { serve } from "@hono/node-server";
import path from "path"; import path from "path";
import { config, validateConfig } from "./services/config.js"; import { config, validateConfig } from "./services/config.js";
import { import {
fetchAllEpisodes, fetchAllEpisodes,
fetchEpisodesWithArticles, fetchEpisodesWithArticles,
getAllFeeds, getAllFeeds,
getFeedByUrl, getFeedByUrl
} from "./services/database.js"; } from "./services/database.js";
import { batchProcess, addNewFeedUrl } from "./scripts/fetch_and_generate.js"; import { batchProcess, addNewFeedUrl } from "./scripts/fetch_and_generate.js";
@ -35,34 +35,30 @@ app.get("/api/feeds", async (c) => {
app.post("/api/feeds", async (c) => { app.post("/api/feeds", async (c) => {
try { try {
const { feedUrl } = await c.req.json<{ feedUrl: string }>(); const { feedUrl } = await c.req.json<{ feedUrl: string }>();
if ( if (!feedUrl || typeof feedUrl !== "string" || !feedUrl.startsWith('http')) {
!feedUrl ||
typeof feedUrl !== "string" ||
!feedUrl.startsWith("http")
) {
return c.json({ error: "Valid feed URL is required" }, 400); return c.json({ error: "Valid feed URL is required" }, 400);
} }
console.log(" Adding new feed URL:", feedUrl); console.log(" Adding new feed URL:", feedUrl);
// Check if feed already exists // Check if feed already exists
const existingFeed = await getFeedByUrl(feedUrl); const existingFeed = await getFeedByUrl(feedUrl);
if (existingFeed) { if (existingFeed) {
return c.json({ return c.json({
result: "EXISTS", result: "EXISTS",
message: "Feed URL already exists", message: "Feed URL already exists",
feed: existingFeed, feed: existingFeed
}); });
} }
// Add new feed // Add new feed
await addNewFeedUrl(feedUrl); await addNewFeedUrl(feedUrl);
return c.json({ return c.json({
result: "CREATED", result: "CREATED",
message: "Feed URL added successfully", message: "Feed URL added successfully",
feedUrl, feedUrl
}); });
} catch (error) { } catch (error) {
console.error("Error adding feed:", error); console.error("Error adding feed:", error);
@ -93,18 +89,18 @@ app.get("/api/episodes/simple", async (c) => {
app.post("/api/episodes/:id/regenerate", async (c) => { app.post("/api/episodes/:id/regenerate", async (c) => {
try { try {
const id = c.req.param("id"); const id = c.req.param("id");
if (!id || id.trim() === "") { if (!id || id.trim() === "") {
return c.json({ error: "Episode ID is required" }, 400); return c.json({ error: "Episode ID is required" }, 400);
} }
console.log("🔄 Regeneration requested for episode ID:", id); console.log("🔄 Regeneration requested for episode ID:", id);
// TODO: Implement regeneration logic // TODO: Implement regeneration logic
return c.json({ return c.json({
result: "PENDING", result: "PENDING",
episodeId: id, episodeId: id,
status: "pending", status: "pending",
message: "Regeneration feature will be implemented in a future update", message: "Regeneration feature will be implemented in a future update"
}); });
} catch (error) { } catch (error) {
console.error("Error requesting regeneration:", error); console.error("Error requesting regeneration:", error);
@ -117,14 +113,14 @@ app.get("/api/stats", async (c) => {
try { try {
const feeds = await getAllFeeds(); const feeds = await getAllFeeds();
const episodes = await fetchAllEpisodes(); const episodes = await fetchAllEpisodes();
const stats = { const stats = {
totalFeeds: feeds.length, totalFeeds: feeds.length,
activeFeeds: feeds.filter((f) => f.active).length, activeFeeds: feeds.filter(f => f.active).length,
totalEpisodes: episodes.length, totalEpisodes: episodes.length,
lastUpdated: new Date().toISOString(), lastUpdated: new Date().toISOString()
}; };
return c.json(stats); return c.json(stats);
} catch (error) { } catch (error) {
console.error("Error fetching stats:", error); console.error("Error fetching stats:", error);
@ -135,16 +131,16 @@ app.get("/api/stats", async (c) => {
app.post("/api/batch/trigger", async (c) => { app.post("/api/batch/trigger", async (c) => {
try { try {
console.log("🚀 Manual batch process triggered via API"); console.log("🚀 Manual batch process triggered via API");
// Run batch process in background // Run batch process in background
runBatchProcess().catch((error) => { runBatchProcess().catch(error => {
console.error("❌ Manual batch process failed:", error); console.error("❌ Manual batch process failed:", error);
}); });
return c.json({ return c.json({
result: "TRIGGERED", result: "TRIGGERED",
message: "Batch process started in background", message: "Batch process started in background",
timestamp: new Date().toISOString(), timestamp: new Date().toISOString()
}); });
} catch (error) { } catch (error) {
console.error("Error triggering batch process:", error); console.error("Error triggering batch process:", error);
@ -159,7 +155,7 @@ app.get("/assets/*", async (c) => {
try { try {
const filePath = path.join(config.paths.frontendBuildDir, c.req.path); const filePath = path.join(config.paths.frontendBuildDir, c.req.path);
const file = Bun.file(filePath); const file = Bun.file(filePath);
if (await file.exists()) { if (await file.exists()) {
const contentType = filePath.endsWith(".js") const contentType = filePath.endsWith(".js")
? "application/javascript" ? "application/javascript"
@ -179,18 +175,15 @@ app.get("/assets/*", async (c) => {
app.get("/podcast_audio/*", async (c) => { app.get("/podcast_audio/*", async (c) => {
try { try {
const audioFileName = c.req.path.substring("/podcast_audio/".length); const audioFileName = c.req.path.substring("/podcast_audio/".length);
// Basic security check // Basic security check
if (audioFileName.includes("..") || audioFileName.includes("/")) { if (audioFileName.includes("..") || audioFileName.includes("/")) {
return c.notFound(); return c.notFound();
} }
const audioFilePath = path.join( const audioFilePath = path.join(config.paths.podcastAudioDir, audioFileName);
config.paths.podcastAudioDir,
audioFileName,
);
const file = Bun.file(audioFilePath); const file = Bun.file(audioFilePath);
if (await file.exists()) { if (await file.exists()) {
const blob = await file.arrayBuffer(); const blob = await file.arrayBuffer();
return c.body(blob, 200, { "Content-Type": "audio/mpeg" }); return c.body(blob, 200, { "Content-Type": "audio/mpeg" });
@ -206,7 +199,7 @@ app.get("/podcast.xml", async (c) => {
try { try {
const filePath = path.join(config.paths.publicDir, "podcast.xml"); const filePath = path.join(config.paths.publicDir, "podcast.xml");
const file = Bun.file(filePath); const file = Bun.file(filePath);
if (await file.exists()) { if (await file.exists()) {
const blob = await file.arrayBuffer(); const blob = await file.arrayBuffer();
return c.body(blob, 200, { return c.body(blob, 200, {
@ -214,7 +207,7 @@ app.get("/podcast.xml", async (c) => {
"Cache-Control": "public, max-age=3600", // Cache for 1 hour "Cache-Control": "public, max-age=3600", // Cache for 1 hour
}); });
} }
console.warn("podcast.xml not found"); console.warn("podcast.xml not found");
return c.notFound(); return c.notFound();
} catch (error) { } catch (error) {
@ -225,13 +218,10 @@ app.get("/podcast.xml", async (c) => {
// Legacy endpoint - redirect to new one // Legacy endpoint - redirect to new one
app.post("/api/add-feed", async (c) => { app.post("/api/add-feed", async (c) => {
return c.json( return c.json({
{ error: "This endpoint is deprecated. Use POST /api/feeds instead.",
error: "This endpoint is deprecated. Use POST /api/feeds instead.", newEndpoint: "POST /api/feeds"
newEndpoint: "POST /api/feeds", }, 410);
},
410,
);
}); });
// Frontend fallback routes // Frontend fallback routes
@ -239,12 +229,12 @@ async function serveIndex(c: any) {
try { try {
const indexPath = path.join(config.paths.frontendBuildDir, "index.html"); const indexPath = path.join(config.paths.frontendBuildDir, "index.html");
const file = Bun.file(indexPath); const file = Bun.file(indexPath);
if (await file.exists()) { if (await file.exists()) {
const blob = await file.arrayBuffer(); const blob = await file.arrayBuffer();
return c.body(blob, 200, { "Content-Type": "text/html; charset=utf-8" }); return c.body(blob, 200, { "Content-Type": "text/html; charset=utf-8" });
} }
console.error(`index.html not found at ${indexPath}`); console.error(`index.html not found at ${indexPath}`);
return c.text("Frontend not built. Run 'bun run build:frontend'", 404); return c.text("Frontend not built. Run 'bun run build:frontend'", 404);
} catch (error) { } catch (error) {
@ -275,9 +265,9 @@ function scheduleFirstBatchProcess() {
function scheduleSixHourlyBatchProcess() { function scheduleSixHourlyBatchProcess() {
const SIX_HOURS_MS = 6 * 60 * 60 * 1000; // 6 hours in milliseconds const SIX_HOURS_MS = 6 * 60 * 60 * 1000; // 6 hours in milliseconds
console.log( console.log(
`🕕 Next batch process scheduled in 6 hours (${new Date(Date.now() + SIX_HOURS_MS).toLocaleString()})`, `🕕 Next batch process scheduled in 6 hours (${new Date(Date.now() + SIX_HOURS_MS).toLocaleString()})`
); );
setTimeout(async () => { setTimeout(async () => {
@ -295,7 +285,7 @@ function scheduleSixHourlyBatchProcess() {
async function runBatchProcess(): Promise<void> { async function runBatchProcess(): Promise<void> {
try { try {
Bun.spawn(["bun", "run", "scripts/fetch_and_generate.ts"]); await batchProcess();
} catch (error) { } catch (error) {
console.error("Batch process failed:", error); console.error("Batch process failed:", error);
throw error; throw error;
@ -312,7 +302,7 @@ serve(
console.log(`🌟 Server is running on http://localhost:${info.port}`); console.log(`🌟 Server is running on http://localhost:${info.port}`);
console.log(`📡 Using configuration from: ${config.paths.projectRoot}`); console.log(`📡 Using configuration from: ${config.paths.projectRoot}`);
console.log(`🗄️ Database: ${config.paths.dbPath}`); console.log(`🗄️ Database: ${config.paths.dbPath}`);
// Schedule batch processes // Schedule batch processes
scheduleFirstBatchProcess(); scheduleFirstBatchProcess();
scheduleSixHourlyBatchProcess(); scheduleSixHourlyBatchProcess();