Files
Copies/copienator/configuration.py
T

93 lines
3.3 KiB
Python

from __future__ import annotations
import importlib.util
import os
from pathlib import Path
from types import ModuleType
def _user_config_path() -> Path | None:
explicit = os.environ.get("COPIENATOR_CONFIG", "").strip()
if explicit:
return Path(explicit).expanduser().resolve()
local = Path.cwd() / "config.py"
return local.resolve() if local.is_file() else None
def _load_user_config(path: Path) -> ModuleType:
if not path.is_file():
raise FileNotFoundError(f"Copienator configuration not found: {path}")
spec = importlib.util.spec_from_file_location("_copienator_user_config", path)
if spec is None or spec.loader is None:
raise ImportError(f"Could not load Copienator configuration: {path}")
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def _settings(path: Path | None) -> dict[str, object]:
import default_config
values = {
name: getattr(default_config, name)
for name in dir(default_config)
if not name.startswith("_")
}
if path is not None:
# Preserve compatibility defaults for older personal configurations.
values.update(THINKING_LEVEL_FOR_LABEL="medium", THINKING_LEVEL_PRO="high")
module = _load_user_config(path)
values.update({
name: getattr(module, name)
for name in dir(module)
if not name.startswith("_")
})
# Historically the name recognizer inherited the label model when omitted.
if not hasattr(module, "MODEL_FOR_NAME_ID"):
values["MODEL_FOR_NAME_ID"] = values["MODEL_FOR_LABEL_ID"]
values["PAGE_SPLITTER_KB"] = {
"reverse_pages": "i",
"add_secondary_splitter": "<Insert>",
"delete_secondary_splitter": "<Delete>",
**values["PAGE_SPLITTER_KB"],
}
return values
CONFIG_PATH = _user_config_path()
_global_settings = _settings(CONFIG_PATH)
globals().update(_global_settings)
LOCAL_CONFIG_PATH: Path | None = None
_evaluation_overrides: set[str] = set()
def use_evaluation(root: str | Path | None) -> None:
"""Apply selected evaluation settings, resetting any previous overrides."""
global LOCAL_CONFIG_PATH, _evaluation_overrides
path = Path(root).expanduser().resolve() / "config.py" if root is not None else None
values = dict(_global_settings)
overrides = {}
if path is not None and path.is_file() and path != CONFIG_PATH:
module = _load_user_config(path)
overrides = {
name: getattr(module, name)
for name in dir(module)
if name.isupper() and name in _global_settings
}
values.update(overrides)
else:
path = None
for name in ("ANNOTATION_MAX_HEIGHT_PX", "ANNOTATION_MAX_PIXELS"):
if type(values[name]) is not int or values[name] <= 0:
raise ValueError(f"{name} must be a positive integer (pixels)")
values["PAGE_SPLITTER_KB"] = {
"reverse_pages": "i",
"add_secondary_splitter": "<Insert>",
"delete_secondary_splitter": "<Delete>",
**values["PAGE_SPLITTER_KB"],
}
for name in _evaluation_overrides | overrides.keys():
globals()[name] = values[name]
_evaluation_overrides = set(overrides)
LOCAL_CONFIG_PATH = path