d48029a407
A pragmatic GEDCOM parser + mapper: import reads INDI/FAM/SOUR and creates people, names, life events, partnership + qualified parent-child relationships, marriage events, places (deduped), sources, and citations from SOUR refs — returning a mapping report (counts + unmapped tags). Export serializes the tree back to GEDCOM (families derived from the edge model). Import is additive (no merge) and runs inline for now. Round-trip test passes; 29 tests total. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Justin Paul <justin@jpaul.me>
38 lines
1.4 KiB
Python
38 lines
1.4 KiB
Python
import uuid
|
|
|
|
from fastapi import APIRouter, File, Response, UploadFile
|
|
|
|
from app.api.deps import CurrentUser, SessionDep
|
|
from app.schemas.gedcom import ImportReport
|
|
from app.services import gedcom, tree_service
|
|
|
|
router = APIRouter(prefix="/trees", tags=["gedcom"])
|
|
|
|
|
|
@router.post("/{tree_id}/gedcom/import", response_model=ImportReport)
|
|
async def import_gedcom(
|
|
tree_id: uuid.UUID,
|
|
session: SessionDep,
|
|
current: CurrentUser,
|
|
file: UploadFile = File(...),
|
|
) -> ImportReport:
|
|
# NOTE: additive — records are created as new; existing people are not merged.
|
|
tree = await tree_service.get_tree(session, viewer_id=current.id, tree_id=tree_id)
|
|
text = (await file.read()).decode("utf-8", errors="replace")
|
|
report = await gedcom.import_gedcom(session, actor=current, tree=tree, text=text)
|
|
return ImportReport(**report)
|
|
|
|
|
|
@router.get("/{tree_id}/gedcom/export")
|
|
async def export_gedcom(
|
|
tree_id: uuid.UUID, session: SessionDep, current: CurrentUser
|
|
) -> Response:
|
|
tree = await tree_service.get_tree(session, viewer_id=current.id, tree_id=tree_id)
|
|
text = await gedcom.export_gedcom(session, viewer_id=current.id, tree=tree)
|
|
safe = "".join(c for c in tree.name if c.isalnum() or c in " -_").strip() or "tree"
|
|
return Response(
|
|
content=text,
|
|
media_type="text/plain",
|
|
headers={"Content-Disposition": f'attachment; filename="{safe}.ged"'},
|
|
)
|