"""Local project file management for ODS workbooks. Mirrors the FreeCAD file path pattern from ``pkg/freecad/silo_commands.py``. Project ODS files live at:: ~/projects/sheets/{PROJECT_CODE}/{PROJECT_CODE}.ods The ``SILO_PROJECTS_DIR`` env var (shared with the FreeCAD workbench) controls the base directory. """ import os from pathlib import Path from typing import Optional from . import settings as _settings def get_sheets_dir() -> Path: """Return the base directory for ODS project sheets.""" return _settings.get_projects_dir() / "sheets" def get_project_sheet_path(project_code: str) -> Path: """Canonical path for a project workbook. Example: ``~/projects/sheets/3DX10/3DX10.ods`` """ return get_sheets_dir() / project_code / f"{project_code}.ods" def ensure_project_dir(project_code: str) -> Path: """Create the project sheet directory if needed and return its path.""" d = get_sheets_dir() / project_code d.mkdir(parents=True, exist_ok=True) return d def project_sheet_exists(project_code: str) -> bool: """Check whether a project workbook already exists locally.""" return get_project_sheet_path(project_code).is_file() def save_project_sheet(project_code: str, ods_bytes: bytes) -> Path: """Write ODS bytes to the canonical project path. Returns the Path written to. """ ensure_project_dir(project_code) path = get_project_sheet_path(project_code) with open(path, "wb") as f: f.write(ods_bytes) return path def read_project_sheet(project_code: str) -> Optional[bytes]: """Read ODS bytes from the canonical project path, or None.""" path = get_project_sheet_path(project_code) if not path.is_file(): return None with open(path, "rb") as f: return f.read() def list_project_sheets() -> list: """Return a list of (project_code, path) tuples for all local sheets.""" sheets_dir = get_sheets_dir() results = [] if not sheets_dir.is_dir(): return results for entry in sorted(sheets_dir.iterdir()): if entry.is_dir(): ods = entry / f"{entry.name}.ods" if ods.is_file(): results.append((entry.name, ods)) return results