Files
SaraView/Backend/BookReader.py
T
2026-09-19 14:53:01 +02:00

86 lines
2.3 KiB
Python

from __future__ import annotations
import importlib.util
import tomllib
from pathlib import Path
from types import ModuleType
from typing import Any
from Core import Config
CachedSaraTagCore: ModuleType | None = None
CachedSaraTagCoreLoaded = False
def GetSaraTagCore() -> ModuleType | None:
"""Load SaraTag's Core.py directly by file path, under a private module
name, so it never collides with SaraView's own Core module in sys.modules.
Cached after the first successful load.
"""
global CachedSaraTagCore, CachedSaraTagCoreLoaded
if CachedSaraTagCoreLoaded:
return CachedSaraTagCore
CachedSaraTagCoreLoaded = True
SaraTagConfig = Config.get("SaraTag", {})
if not SaraTagConfig.get("Enabled", False):
return None
CoreModulePath = SaraTagConfig.get("CoreModulePath")
if not CoreModulePath:
return None
CoreFilePath = Path(CoreModulePath).expanduser().resolve() / "Core.py"
if not CoreFilePath.is_file():
return None
ModuleSpec = importlib.util.spec_from_file_location("SaraTagCore", CoreFilePath)
if ModuleSpec is None or ModuleSpec.loader is None:
return None
SaraTagCoreModule = importlib.util.module_from_spec(ModuleSpec)
ModuleSpec.loader.exec_module(SaraTagCoreModule)
CachedSaraTagCore = SaraTagCoreModule
return CachedSaraTagCore
def ReadBookForFile(FilePath: Path) -> dict[str, Any] | None:
"""Return a file's resolved Book (tag values + Lexicon definitions), or
None if SaraTag integration is disabled or the file has no Book.
"""
SaraTagCore = GetSaraTagCore()
if SaraTagCore is None:
return None
BookPath = SaraTagCore.GetBookPath(FilePath)
if not BookPath.is_file():
return None
with BookPath.open("rb") as BookFile:
Metadata = tomllib.load(BookFile)
ParentValue = Metadata.get("Parent")
Definitions: dict[str, Any] = {}
if isinstance(ParentValue, str):
try:
LexiconPath = SaraTagCore.ResolveBookLexiconPath(FilePath.parent, ParentValue)
Definitions = SaraTagCore.ResolveLexiconTags(LexiconPath)
except Exception:
Definitions = {}
Tags = {Key: Value for Key, Value in Metadata.items() if Key != "Parent"}
return {"Parent": ParentValue, "Tags": Tags, "Definitions": Definitions}