90 lines
3.0 KiB
Python
90 lines
3.0 KiB
Python
"""Сервис загрузки конфигураций подсветки из .lm файлов (TOML-формат).
|
||
|
||
Папка light_modes/ лежит рядом с исполняемым файлом (или рядом с main.py
|
||
при разработке). Каждый .lm файл описывает один игровой проект и содержит:
|
||
- base_command — базовая команда (например "85", "8")
|
||
- has_duration — (опционально) true если формат XXYY (XX=эффект, YY=время)
|
||
- [[effects]] — список эффектов с полями code (int) и name (str)
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import sys
|
||
import tomllib
|
||
from dataclasses import dataclass, field
|
||
from pathlib import Path
|
||
|
||
|
||
@dataclass
|
||
class LightEffect:
|
||
"""Один эффект подсветки."""
|
||
code: int
|
||
name: str
|
||
|
||
|
||
@dataclass
|
||
class LightMode:
|
||
"""Конфигурация подсветки для одного игрового проекта."""
|
||
project_name: str
|
||
base_command: str
|
||
has_duration: bool = False
|
||
effects: list[LightEffect] = field(default_factory=list)
|
||
|
||
|
||
def _get_light_modes_dir() -> Path:
|
||
"""Определить путь к папке light_modes/.
|
||
|
||
При запуске из .exe (PyInstaller) — рядом с exe-файлом.
|
||
При запуске из исходников — рядом с корнем проекта.
|
||
"""
|
||
if getattr(sys, "frozen", False):
|
||
base = Path(sys.executable).parent
|
||
else:
|
||
base = Path(__file__).resolve().parent.parent.parent
|
||
return base / "light_modes"
|
||
|
||
|
||
def load_light_mode(path: Path) -> LightMode | None:
|
||
"""Загрузить один .lm файл. Возвращает None при ошибке."""
|
||
try:
|
||
data = tomllib.loads(path.read_text(encoding="utf-8"))
|
||
except Exception:
|
||
return None
|
||
|
||
base_command = data.get("base_command", "")
|
||
has_duration = data.get("has_duration", False)
|
||
effects: list[LightEffect] = []
|
||
|
||
for entry in data.get("effects", []):
|
||
code = entry.get("code")
|
||
name = entry.get("name", "")
|
||
if code is not None:
|
||
effects.append(LightEffect(code=int(code), name=str(name)))
|
||
|
||
project_name = path.stem # имя файла без расширения
|
||
return LightMode(
|
||
project_name=project_name,
|
||
base_command=str(base_command),
|
||
has_duration=bool(has_duration),
|
||
effects=effects,
|
||
)
|
||
|
||
|
||
def load_all_light_modes() -> list[LightMode]:
|
||
"""Загрузить все .lm файлы из папки light_modes/."""
|
||
modes_dir = _get_light_modes_dir()
|
||
if not modes_dir.is_dir():
|
||
return []
|
||
|
||
modes: list[LightMode] = []
|
||
for lm_file in sorted(modes_dir.glob("*.lm")):
|
||
mode = load_light_mode(lm_file)
|
||
if mode is not None:
|
||
modes.append(mode)
|
||
return modes
|
||
|
||
|
||
def get_light_modes_dir() -> Path:
|
||
"""Публичный доступ к пути папки (для UI «Открыть папку»)."""
|
||
return _get_light_modes_dir()
|