plate-config-app/app/services/commands_service.py

85 lines
2.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Сервис загрузки справочника команд платы из .csv файлов.
Папка commands/ лежит рядом с исполняемым файлом (или рядом с main.py
при разработке). Каждый .csv файл содержит набор команд с колонками,
разделёнными точкой с запятой:
command;name;description
"""
from __future__ import annotations
import csv
import sys
from dataclasses import dataclass, field
from pathlib import Path
@dataclass
class Command:
"""Одна команда платы."""
code: str
name: str
description: str
@dataclass
class CommandSet:
"""Набор команд из одного CSV-файла."""
set_name: str
commands: list[Command] = field(default_factory=list)
def _get_commands_dir() -> Path:
"""Определить путь к папке commands/.
При запуске из .exe (PyInstaller) — рядом с exe-файлом.
При запуске из исходников — рядом с корнем проекта.
"""
if getattr(sys, "frozen", False):
base = Path(sys.executable).parent
else:
base = Path(__file__).resolve().parent.parent.parent
return base / "commands"
def load_command_set(path: Path) -> CommandSet | None:
"""Загрузить один .csv файл. Возвращает None при ошибке."""
try:
text = path.read_text(encoding="utf-8")
except Exception:
return None
commands: list[Command] = []
reader = csv.reader(text.splitlines(), delimiter=";")
for i, row in enumerate(reader):
if len(row) < 3:
continue
code, name, description = row[0].strip(), row[1].strip(), row[2].strip()
# Пропускаем заголовок
if i == 0 and code.lower() == "command":
continue
if not code:
continue
commands.append(Command(code=code, name=name, description=description))
return CommandSet(set_name=path.stem, commands=commands)
def load_all_command_sets() -> list[CommandSet]:
"""Загрузить все .csv файлы из папки commands/."""
commands_dir = _get_commands_dir()
if not commands_dir.is_dir():
return []
sets: list[CommandSet] = []
for csv_file in sorted(commands_dir.glob("*.csv")):
cs = load_command_set(csv_file)
if cs is not None and cs.commands:
sets.append(cs)
return sets
def get_commands_dir() -> Path:
"""Публичный доступ к пути папки (для UI «Открыть папку»)."""
return _get_commands_dir()