89 lines
2.9 KiB
Python
89 lines
2.9 KiB
Python
"""电子书种子:把 res/ 下已有的三本书挂到教材上。
|
||
|
||
幂等:只补不覆盖,管理员在后台重新上传的文件不会被种子冲掉。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from pathlib import Path
|
||
|
||
from sqlalchemy.orm import Session
|
||
|
||
from database import REPO_ROOT
|
||
from models import Textbook
|
||
from services import ebooks as store
|
||
|
||
RES_ROOT = REPO_ROOT / "res"
|
||
|
||
# res/ 里的文件名带书目后缀,展示时用干净的名称
|
||
PRINCETON = {
|
||
"name": "普林斯顿微积分读本(修订版)",
|
||
"author": "阿德里安·班纳 (Adrian Banner)",
|
||
"publisher": "人民邮电出版社",
|
||
"grade": "高中至大学先修",
|
||
"description": "面向微积分入门的系统辅导书,覆盖极限、导数、积分与级数,"
|
||
"按考点组织,适合自学与考前查漏补缺。",
|
||
"resource": "普林斯顿微积分读本(修订版)",
|
||
"display": "普林斯顿微积分读本(修订版).epub",
|
||
}
|
||
|
||
# 已有教材 → res/ 中的 PDF(按教材名前缀匹配)
|
||
PDF_LINKS = [
|
||
("函数和图像", "函数和图像", "函数和图像(盖尔范德中学生数学思维丛书).pdf"),
|
||
("三角函数", "三角函数", "三角函数(盖尔范德中学生数学思维丛书).pdf"),
|
||
]
|
||
|
||
|
||
def _find_resource(prefix: str, suffix: str) -> Path | None:
|
||
"""res/ 下的文件名带作者与来源后缀,只按标题前缀匹配。"""
|
||
if not RES_ROOT.is_dir():
|
||
return None
|
||
for path in sorted(RES_ROOT.iterdir()):
|
||
if (
|
||
path.is_file()
|
||
and path.suffix.lower() == suffix
|
||
and path.name.startswith(prefix)
|
||
):
|
||
return path
|
||
return None
|
||
|
||
|
||
def ensure_ebooks(db: Session) -> None:
|
||
created = False
|
||
textbook = (
|
||
db.query(Textbook).filter(Textbook.name == PRINCETON["name"]).first()
|
||
)
|
||
if textbook is None:
|
||
position = (
|
||
db.query(Textbook).count()
|
||
)
|
||
textbook = Textbook(
|
||
name=PRINCETON["name"],
|
||
author=PRINCETON["author"],
|
||
publisher=PRINCETON["publisher"],
|
||
grade=PRINCETON["grade"],
|
||
description=PRINCETON["description"],
|
||
position=position,
|
||
)
|
||
db.add(textbook)
|
||
db.commit()
|
||
created = True
|
||
if created:
|
||
epub = _find_resource(PRINCETON["resource"], ".epub")
|
||
if epub is not None and not textbook.ebook_file:
|
||
store.attach_local_file(
|
||
db, textbook, epub, display_name=PRINCETON["display"]
|
||
)
|
||
|
||
for name_prefix, file_prefix, display in PDF_LINKS:
|
||
textbook = (
|
||
db.query(Textbook)
|
||
.filter(Textbook.name.startswith(name_prefix))
|
||
.first()
|
||
)
|
||
if textbook is None or textbook.ebook_file:
|
||
continue
|
||
pdf = _find_resource(file_prefix, ".pdf")
|
||
if pdf is None:
|
||
continue
|
||
store.attach_local_file(db, textbook, pdf, display_name=display)
|