Initial commit: WordLoop 单词学习应用
Vue 前端 + FastAPI 后端,含部署脚本与词典数据。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
"""离线翻译词典导入脚本。
|
||||
|
||||
用法(在 backend 目录下):
|
||||
python -m scripts.import_dictionary
|
||||
python -m scripts.import_dictionary --file data/dictionary.json
|
||||
python -m scripts.import_dictionary --file /path/to/words.csv
|
||||
python -m scripts.import_dictionary --file data/dictionary.json --source seed
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import csv
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
BACKEND_DIR = Path(__file__).resolve().parent.parent
|
||||
DEFAULT_FILE = BACKEND_DIR / "data" / "dictionary.json"
|
||||
|
||||
sys.path.insert(0, str(BACKEND_DIR))
|
||||
|
||||
from database import SessionLocal # noqa: E402
|
||||
from scripts.dictionary_importer import upsert_entries # noqa: E402
|
||||
|
||||
|
||||
def load_json(path: Path) -> list[dict]:
|
||||
data = json.loads(path.read_text(encoding="utf-8"))
|
||||
if isinstance(data, list):
|
||||
return data
|
||||
if isinstance(data, dict) and "entries" in data:
|
||||
return data["entries"]
|
||||
raise ValueError(f"无法解析 JSON 格式: {path}")
|
||||
|
||||
|
||||
def load_csv(path: Path) -> list[dict]:
|
||||
with path.open(encoding="utf-8-sig", newline="") as f:
|
||||
reader = csv.DictReader(f)
|
||||
return list(reader)
|
||||
|
||||
|
||||
def load_entries(path: Path) -> list[dict]:
|
||||
suffix = path.suffix.lower()
|
||||
if suffix == ".json":
|
||||
return load_json(path)
|
||||
if suffix == ".csv":
|
||||
return load_csv(path)
|
||||
raise ValueError(f"不支持的文件格式: {suffix},请使用 .json 或 .csv")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="导入离线翻译词典到 dictionary_entries 表")
|
||||
parser.add_argument(
|
||||
"--file",
|
||||
type=Path,
|
||||
default=DEFAULT_FILE,
|
||||
help=f"JSON 或 CSV 文件路径(默认: {DEFAULT_FILE.name})",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--source",
|
||||
type=str,
|
||||
default=None,
|
||||
help="数据来源标记,如 seed / ecdict / custom",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
path = args.file if args.file.is_absolute() else BACKEND_DIR / args.file
|
||||
if not path.exists():
|
||||
print(f"错误: 文件不存在 {path}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
raw_rows = load_entries(path)
|
||||
session = SessionLocal()
|
||||
try:
|
||||
total = upsert_entries(session, raw_rows, args.source)
|
||||
finally:
|
||||
session.close()
|
||||
print(f"导入完成: 文件={path.name}, 处理={total} 条")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user