chore: update project config, services, templates and styling
This commit is contained in:
+3
-3
@@ -16,14 +16,14 @@ HTTP_TIMEOUT_SECONDS=30
|
|||||||
HTTP_MAX_RETRIES=3
|
HTTP_MAX_RETRIES=3
|
||||||
HTTP_USER_AGENT=hf-daily-papers-local/0.1
|
HTTP_USER_AGENT=hf-daily-papers-local/0.1
|
||||||
|
|
||||||
# ─── AI 总结(Phase 2 使用)──────────────
|
# ─── AI 总结 ──────────────────────────────
|
||||||
PI_BIN=/home/rainbus/.local/share/mise/installs/pi/latest/pi
|
PI_BIN=/home/rainbus/.local/share/mise/installs/pi/latest/pi
|
||||||
SUMMARY_SKILL=daily-paper-summary
|
SUMMARY_SKILL=daily-paper-summary
|
||||||
SUMMARY_CONCURRENCY=3
|
SUMMARY_CONCURRENCY=3
|
||||||
SUMMARY_TIMEOUT_SECONDS=300
|
SUMMARY_TIMEOUT_SECONDS=300
|
||||||
SUMMARY_MAX_RETRIES=1
|
SUMMARY_MAX_RETRIES=1
|
||||||
|
|
||||||
# ─── 调度(Phase 4 使用)─────────────────
|
# ─── 调度 ─────────────────────────────────
|
||||||
SCHEDULER_ENABLED=false
|
SCHEDULER_ENABLED=false
|
||||||
SCHEDULE_HOUR=8
|
SCHEDULE_HOUR=8
|
||||||
SCHEDULE_MINUTE=0
|
SCHEDULE_MINUTE=0
|
||||||
@@ -32,7 +32,7 @@ APP_WORKERS=1
|
|||||||
# ─── 数据库 ─────────────────────────────
|
# ─── 数据库 ─────────────────────────────
|
||||||
DATABASE_URL=sqlite:///data/db/papers.db
|
DATABASE_URL=sqlite:///data/db/papers.db
|
||||||
|
|
||||||
# ─── 语义搜索(Phase 5 增强,暂留空)─────
|
# ─── 语义搜索 ─────────────────────────────
|
||||||
CHROMA_ENABLED=false
|
CHROMA_ENABLED=false
|
||||||
CHROMA_DIR=data/chroma
|
CHROMA_DIR=data/chroma
|
||||||
EMBED_API_BASE=
|
EMBED_API_BASE=
|
||||||
|
|||||||
+3
-3
@@ -26,14 +26,14 @@ class Settings(BaseSettings):
|
|||||||
HTTP_MAX_RETRIES: int = 3
|
HTTP_MAX_RETRIES: int = 3
|
||||||
HTTP_USER_AGENT: str = "hf-daily-papers-local/0.1"
|
HTTP_USER_AGENT: str = "hf-daily-papers-local/0.1"
|
||||||
|
|
||||||
# AI 总结(Phase 2)
|
# AI 总结
|
||||||
PI_BIN: str = ""
|
PI_BIN: str = ""
|
||||||
SUMMARY_SKILL: str = "daily-paper-summary"
|
SUMMARY_SKILL: str = "daily-paper-summary"
|
||||||
SUMMARY_CONCURRENCY: int = 3
|
SUMMARY_CONCURRENCY: int = 3
|
||||||
SUMMARY_TIMEOUT_SECONDS: int = 300
|
SUMMARY_TIMEOUT_SECONDS: int = 300
|
||||||
SUMMARY_MAX_RETRIES: int = 1
|
SUMMARY_MAX_RETRIES: int = 1
|
||||||
|
|
||||||
# 调度(Phase 4)
|
# 调度
|
||||||
SCHEDULER_ENABLED: bool = False
|
SCHEDULER_ENABLED: bool = False
|
||||||
SCHEDULE_HOUR: int = 8
|
SCHEDULE_HOUR: int = 8
|
||||||
SCHEDULE_MINUTE: int = 0
|
SCHEDULE_MINUTE: int = 0
|
||||||
@@ -42,7 +42,7 @@ class Settings(BaseSettings):
|
|||||||
# 数据库
|
# 数据库
|
||||||
DATABASE_URL: str = "sqlite:///data/db/papers.db"
|
DATABASE_URL: str = "sqlite:///data/db/papers.db"
|
||||||
|
|
||||||
# 语义搜索(Phase 5)
|
# 语义搜索
|
||||||
CHROMA_ENABLED: bool = False
|
CHROMA_ENABLED: bool = False
|
||||||
CHROMA_DIR: str = "data/chroma"
|
CHROMA_DIR: str = "data/chroma"
|
||||||
EMBED_API_BASE: str = ""
|
EMBED_API_BASE: str = ""
|
||||||
|
|||||||
+1
-1
@@ -72,7 +72,7 @@ def create_app() -> FastAPI:
|
|||||||
# 静态文件
|
# 静态文件
|
||||||
app.mount("/static", StaticFiles(directory="app/static"), name="static")
|
app.mount("/static", StaticFiles(directory="app/static"), name="static")
|
||||||
|
|
||||||
# Phase 5: 论文图片静态服务
|
# 论文图片静态服务
|
||||||
papers_images_dir = os.path.join("data", "papers")
|
papers_images_dir = os.path.join("data", "papers")
|
||||||
os.makedirs(papers_images_dir, exist_ok=True)
|
os.makedirs(papers_images_dir, exist_ok=True)
|
||||||
app.mount("/papers", StaticFiles(directory=papers_images_dir), name="papers")
|
app.mount("/papers", StaticFiles(directory=papers_images_dir), name="papers")
|
||||||
|
|||||||
+4
-4
@@ -101,10 +101,10 @@ def paper_detail(arxiv_id: str, request: Request, db: Session = Depends(get_db))
|
|||||||
if paper.summary_status:
|
if paper.summary_status:
|
||||||
summary_state = paper.summary_status.status
|
summary_state = paper.summary_status.status
|
||||||
|
|
||||||
# Phase 5: 相似论文推荐
|
# 相似论文推荐
|
||||||
similar_papers = _get_similar_papers(db, arxiv_id, top_k=6)
|
similar_papers = _get_similar_papers(db, arxiv_id, top_k=6)
|
||||||
|
|
||||||
# Phase 5: 图片画廊
|
# 图片画廊
|
||||||
images = _get_paper_images(arxiv_id)
|
images = _get_paper_images(arxiv_id)
|
||||||
|
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
@@ -121,7 +121,7 @@ def paper_detail(arxiv_id: str, request: Request, db: Session = Depends(get_db))
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# ── 相似论文 API (Phase 5) ────────────────────────────────────────────
|
# ── 相似论文 API ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
@router.get("/api/similar/{arxiv_id}")
|
@router.get("/api/similar/{arxiv_id}")
|
||||||
@@ -213,7 +213,7 @@ def _get_similar_papers(db: Session, arxiv_id: str, top_k: int = 6) -> list[dict
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
# ── 图片画廊 (Phase 5) ────────────────────────────────────────────────
|
# ── 图片画廊 ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
def _get_paper_images(arxiv_id: str) -> list[dict]:
|
def _get_paper_images(arxiv_id: str) -> list[dict]:
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ async def delete_papers_by_date_range(
|
|||||||
{"paper_id": paper_id},
|
{"paper_id": paper_id},
|
||||||
)
|
)
|
||||||
|
|
||||||
# 1.5 Phase 5: 从 ChromaDB 删除语义索引
|
# 1.5 从 ChromaDB 删除语义索引
|
||||||
try:
|
try:
|
||||||
from app.services.embedder import delete_paper
|
from app.services.embedder import delete_paper
|
||||||
|
|
||||||
|
|||||||
@@ -252,13 +252,13 @@ async def _do_summarize_one(db: Session, paper: Paper) -> dict:
|
|||||||
status.raw_output_saved = True
|
status.raw_output_saved = True
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
# Phase 5: LaTeX 图片提取(可选增强,失败不影响总结)
|
# LaTeX 图片提取(可选增强,失败不影响总结)
|
||||||
try:
|
try:
|
||||||
await extract_images_from_source(arxiv_id)
|
await extract_images_from_source(arxiv_id)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.warning("Failed to extract images for %s", arxiv_id, exc_info=True)
|
logger.warning("Failed to extract images for %s", arxiv_id, exc_info=True)
|
||||||
|
|
||||||
# Phase 5: 同步写入语义索引(失败仅 log)
|
# 同步写入语义索引(失败仅 log)
|
||||||
try:
|
try:
|
||||||
from app.services.embedder import index_paper
|
from app.services.embedder import index_paper
|
||||||
|
|
||||||
|
|||||||
@@ -722,7 +722,7 @@ mark {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Search Mode Toggle (Phase 5) ─────────────────────────────── */
|
/* ── Search Mode Toggle ───────────────────────────────────────── */
|
||||||
.search-mode-toggle {
|
.search-mode-toggle {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
@@ -751,7 +751,7 @@ mark {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Similarity Score (Phase 5) ────────────────────────────────── */
|
/* ── Similarity Score ──────────────────────────────────────────── */
|
||||||
.similarity-score {
|
.similarity-score {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
@@ -761,7 +761,7 @@ mark {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Similar Papers (Phase 5) ──────────────────────────────────── */
|
/* ── Similar Papers ────────────────────────────────────────────── */
|
||||||
.similar-papers {
|
.similar-papers {
|
||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
padding-top: 24px;
|
padding-top: 24px;
|
||||||
@@ -796,7 +796,7 @@ mark {
|
|||||||
color: var(--ink-light);
|
color: var(--ink-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Trends Dashboard (Phase 5) ────────────────────────────────── */
|
/* ── Trends Dashboard ──────────────────────────────────────────── */
|
||||||
.trends-page h1 {
|
.trends-page h1 {
|
||||||
font-family: var(--font-body);
|
font-family: var(--font-body);
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
@@ -832,7 +832,7 @@ mark {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Compare Page (Phase 5) ────────────────────────────────────── */
|
/* ── Compare Page ──────────────────────────────────────────────── */
|
||||||
.compare-page h1 {
|
.compare-page h1 {
|
||||||
font-family: var(--font-body);
|
font-family: var(--font-body);
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
@@ -880,7 +880,7 @@ mark {
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Image Gallery (Phase 5) ───────────────────────────────────── */
|
/* ── Image Gallery ─────────────────────────────────────────────── */
|
||||||
.image-gallery {
|
.image-gallery {
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ endblock %} {% block content %}
|
|||||||
<h2>Abstract</h2>
|
<h2>Abstract</h2>
|
||||||
<p class="abstract-en">{{ paper.abstract }}</p>
|
<p class="abstract-en">{{ paper.abstract }}</p>
|
||||||
</section>
|
</section>
|
||||||
{% endif %} {# Phase 5: 图片画廊 #} {% if paper_images %}
|
{% endif %} {# 图片画廊 #} {% if paper_images %}
|
||||||
<section class="image-gallery">
|
<section class="image-gallery">
|
||||||
<h2>论文图片</h2>
|
<h2>论文图片</h2>
|
||||||
<div class="gallery-grid">
|
<div class="gallery-grid">
|
||||||
@@ -135,7 +135,7 @@ endblock %} {% block content %}
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{% endif %} {# Phase 5: 相似论文推荐 #} {% if similar_papers %}
|
{% endif %} {# 相似论文推荐 #} {% if similar_papers %}
|
||||||
<section class="similar-papers">
|
<section class="similar-papers">
|
||||||
<h2>相似论文推荐</h2>
|
<h2>相似论文推荐</h2>
|
||||||
{% for sp in similar_papers %}
|
{% for sp in similar_papers %}
|
||||||
|
|||||||
Reference in New Issue
Block a user