feat: init rssKeeper - RSS 抓取、管理与检索系统
完整功能包括: - FastAPI 后端 + SQLite + FTS5 全文搜索 - RSS 源管理、自动发现、OPML 导入导出 - 文章抓取、去重、分类、全文检索 - RSS 源健康度监控 - Vue 3 + Element Plus 暗色主题 Web UI - 对外 REST API 供 AI 分析调用 - Docker + docker-compose 部署
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
"""rssKeeper - FastAPI 入口"""
|
||||
import os
|
||||
from contextlib import asynccontextmanager
|
||||
from fastapi import FastAPI
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.responses import FileResponse
|
||||
from starlette.middleware.cors import CORSMiddleware
|
||||
from database import init_db, SessionLocal
|
||||
from scheduler import init_feed_jobs, stop_scheduler
|
||||
from routers import feeds, articles, dashboard, external_api
|
||||
import config
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
"""应用生命周期管理"""
|
||||
# 启动时:初始化数据库 + 注册定时任务
|
||||
init_db()
|
||||
db = SessionLocal()
|
||||
try:
|
||||
init_feed_jobs(db)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
yield
|
||||
|
||||
# 关闭时:停止调度器
|
||||
stop_scheduler()
|
||||
|
||||
|
||||
app = FastAPI(
|
||||
title="rssKeeper",
|
||||
description="RSS 抓取、管理与检索系统",
|
||||
version="1.0.0",
|
||||
lifespan=lifespan,
|
||||
)
|
||||
|
||||
# CORS
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
# API 路由
|
||||
app.include_router(feeds.router, prefix=config.API_PREFIX)
|
||||
app.include_router(articles.router, prefix=config.API_PREFIX)
|
||||
app.include_router(dashboard.router, prefix=config.API_PREFIX)
|
||||
app.include_router(external_api.router, prefix=config.EXTERNAL_API_PREFIX)
|
||||
|
||||
|
||||
@app.get("/api/health")
|
||||
def health_check():
|
||||
"""健康检查"""
|
||||
return {"status": "ok", "service": "rssKeeper"}
|
||||
|
||||
|
||||
# 静态文件服务(前端构建产物)
|
||||
static_dir = os.path.join(config.BASE_DIR, "static")
|
||||
if os.path.exists(static_dir):
|
||||
app.mount("/static", StaticFiles(directory=static_dir), name="static")
|
||||
|
||||
@app.get("/{full_path:path}")
|
||||
async def serve_spa(full_path: str):
|
||||
"""Vue SPA 路由回退"""
|
||||
# API 路由不走这里
|
||||
if full_path.startswith("api/") or full_path.startswith("docs") or full_path.startswith("openapi.json"):
|
||||
return {"detail": "Not found"}
|
||||
|
||||
index_path = os.path.join(static_dir, "index.html")
|
||||
if os.path.exists(index_path):
|
||||
return FileResponse(index_path)
|
||||
return {"detail": "Frontend not built"}
|
||||
Reference in New Issue
Block a user