anki-parser / main.py
rafael1994s's picture
Update main.py
f320da1 verified
from fastapi import FastAPI, UploadFile, File
import zipfile
import sqlite3
import os
import shutil
app = FastAPI()
@app.post("/parse")
async def parse_anki(file: UploadFile = File(...)):
temp_filename = "deck.apkg"
with open(temp_filename, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
try:
with zipfile.ZipFile(temp_filename, 'r') as z:
# Anki21 — это более современный формат БД
db_files = [f for f in z.namelist() if 'anki2' in f]
if not db_files:
return {"success": False, "error": "No database found in apkg"}
# Берем последний (обычно collection.anki21)
db_name = sorted(db_files)[-1]
z.extract(db_name, path="./")
conn = sqlite3.connect(db_name)
# Включаем Row factory, чтобы получать данные в виде словарей
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
# 1. Извлекаем карточки со всеми параметрами обучения
cursor.execute("""
SELECT
id, nid, did as deck_id, type, queue,
due, ivl as interval, factor as ease, reps, lapses
FROM cards
""")
cards = [dict(row) for row in cursor.fetchall()]
# 2. Извлекаем историю повторений (revlog)
cursor.execute("""
SELECT
id as time_ms, cid as card_id, ease,
ivl as interval, lastIvl as last_interval,
factor, time as duration_ms, type
FROM revlog
""")
revlog = [dict(row) for row in cursor.fetchall()]
# 3. Извлекаем заметки (текст), чтобы связать с картами через nid
cursor.execute("SELECT id, flds FROM notes")
notes = {row['id']: row['flds'].split('\x1f') for row in cursor.fetchall()}
conn.close()
# Чистим за собой временные файлы
if os.path.exists(db_name):
os.remove(db_name)
return {
"success": True,
"cards_count": len(cards),
"cards": cards,
"revlog": revlog,
"notes": notes
}
except Exception as e:
return {"success": False, "error": str(e)}