feat: 添加译文功能 + Attention Is All You Need 中文译本

This commit is contained in:
2026-06-02 11:27:30 +00:00
parent d5ba6f2847
commit bcdbc62681
5 changed files with 21 additions and 1 deletions

View File

@@ -464,6 +464,24 @@ def download_single_pdf(arxiv_id: str):
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
return {"ok": False, "arxiv_id": arxiv_id, "status": "timeout"} return {"ok": False, "arxiv_id": arxiv_id, "status": "timeout"}
# ─── Routes: Translated PDFs ────────────────────────────
TRANSLATED_DIR = PAPERS_DIR / "translated"
@app.get("/api/translated/{arxiv_id}")
def check_translation(arxiv_id: str):
"""Check if translation exists for a paper"""
fn = f"{arxiv_id}.pdf"
return {"arxiv_id": arxiv_id, "exists": (TRANSLATED_DIR / fn).exists()}
@app.get("/papers/translated/{arxiv_id}.pdf")
def serve_translated(arxiv_id: str):
"""Serve translated PDF from cache"""
fp = TRANSLATED_DIR / f"{arxiv_id}.pdf"
if not fp.exists():
raise HTTPException(status_code=404, detail="Translation not found")
return FileResponse(fp, media_type="application/pdf",
headers={"Content-Disposition": "inline"})
# ─── Health ───────────────────────────────────────────── # ─── Health ─────────────────────────────────────────────
@app.get("/api/health") @app.get("/api/health")
def health(): def health():

Binary file not shown.

View File

@@ -5,4 +5,4 @@ pydantic>=2.10
python-multipart>=0.0.19 python-multipart>=0.0.19
aiofiles>=24.0 aiofiles>=24.0
tqdm>=4.66 tqdm>=4.66
PyMuPDF>=1.24 fpdf2>=2.7

View File

@@ -151,6 +151,7 @@ function renderPaper(p) {
const links = []; const links = [];
if (pdfUrl) links.push(`<button class="paper-link" data-pdf="${encodeURIComponent(pdfUrl)}" data-title="${encodeURIComponent(p.title)}" onclick="openPdfBtn(this)">📄 阅读</button>`); if (pdfUrl) links.push(`<button class="paper-link" data-pdf="${encodeURIComponent(pdfUrl)}" data-title="${encodeURIComponent(p.title)}" onclick="openPdfBtn(this)">📄 阅读</button>`);
else if (p.arxiv) links.push(`<a class="paper-link" href="https://arxiv.org/abs/${p.arxiv}" target="_blank">📋 arXiv</a>`); else if (p.arxiv) links.push(`<a class="paper-link" href="https://arxiv.org/abs/${p.arxiv}" target="_blank">📋 arXiv</a>`);
if (p.arxiv) links.push(`<a class="paper-link trans-btn" href="/papers/translated/${p.arxiv}.pdf" target="_blank" title="中文译文">📖 译文</a>`);
return `<div class="paper-item"><div class="paper-year">${p.year||'—'}</div><div class="paper-body" id="${id}"> return `<div class="paper-item"><div class="paper-year">${p.year||'—'}</div><div class="paper-body" id="${id}">
<div class="paper-title">${p.title}</div> <div class="paper-title">${p.title}</div>
<div class="paper-meta"><span>${p.authors||''}</span>${p.venue?`<span class="paper-venue">${p.venue}</span>`:''}${tags}</div> <div class="paper-meta"><span>${p.authors||''}</span>${p.venue?`<span class="paper-venue">${p.venue}</span>`:''}${tags}</div>

View File

@@ -183,6 +183,7 @@ function renderPaper(p) {
const links = []; const links = [];
if (pdfUrl) links.push(`<button class="paper-link" data-pdf="${encodeURIComponent(pdfUrl)}" data-title="${encodeURIComponent(p.title)}" onclick="openPdfBtn(this)">📄 阅读</button>`); if (pdfUrl) links.push(`<button class="paper-link" data-pdf="${encodeURIComponent(pdfUrl)}" data-title="${encodeURIComponent(p.title)}" onclick="openPdfBtn(this)">📄 阅读</button>`);
else if (p.arxiv) links.push(`<a class="paper-link" href="https://arxiv.org/abs/${p.arxiv}" target="_blank">📋 arXiv</a>`); else if (p.arxiv) links.push(`<a class="paper-link" href="https://arxiv.org/abs/${p.arxiv}" target="_blank">📋 arXiv</a>`);
if (p.arxiv) links.push(`<a class="paper-link trans-btn" href="/papers/translated/${p.arxiv}.pdf" target="_blank" title="中文译文">📖 译文</a>`);
return `<div class="paper-item"><div class="paper-year">${p.year||'—'}</div><div class="paper-body" id="${id}"> return `<div class="paper-item"><div class="paper-year">${p.year||'—'}</div><div class="paper-body" id="${id}">
<div class="paper-title">${p.title}</div> <div class="paper-title">${p.title}</div>
<div class="paper-meta"><span>${p.authors||''}</span>${p.venue?`<span class="paper-venue">${p.venue}</span>`:''}${tags}</div> <div class="paper-meta"><span>${p.authors||''}</span>${p.venue?`<span class="paper-venue">${p.venue}</span>`:''}${tags}</div>