Initial commit: WordLoop 单词学习应用

Vue 前端 + FastAPI 后端,含部署脚本与词典数据。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
John
2026-06-04 14:30:53 -07:00
commit bd7635986a
66 changed files with 5495 additions and 0 deletions
+83
View File
@@ -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()