Files

134 lines
4.2 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.
from __future__ import annotations
import importlib.util
import os
import shutil
import sys
from dataclasses import dataclass
from pathlib import Path
from copienator.platform import find_executable, windows_filename_problems
@dataclass(frozen=True)
class DiagnosticCheck:
name: str
ok: bool
detail: str
required: bool = True
def module_available(module: str) -> bool:
try:
return importlib.util.find_spec(module) is not None
except (ImportError, ModuleNotFoundError, ValueError):
return False
def collect_diagnostics(
show_personal_steps: bool,
api_key_override: str = "",
evaluation: Path | None = None,
) -> list[DiagnosticCheck]:
checks = [
DiagnosticCheck(
"Système",
os.name == "nt"
or sys.platform.startswith("linux")
or sys.platform == "darwin",
f"{sys.platform} — Linux, Windows et macOS sont pris en charge",
),
DiagnosticCheck("Python", True, sys.executable),
]
modules = {
"numpy": "numpy",
"pandas": "pandas",
"matplotlib": "matplotlib",
"Pillow": "PIL",
"pydantic": "pydantic",
"pypdf": "pypdf",
"pdf2image": "pdf2image",
"reportlab": "reportlab",
"img2pdf": "img2pdf",
"PyMuPDF": "pymupdf",
"ftfy": "ftfy",
"ezodf": "ezodf",
"Google GenAI": "google.genai",
}
checks.extend(
DiagnosticCheck(label, module_available(module), f"Module Python : {module}")
for label, module in modules.items()
)
programs = (
("Poppler", ("pdftoppm", "pdftocairo"), True),
("LaTeX", ("pdflatex",), True),
("PDF Arranger", ("pdf-arranger", "pdfarranger"), False),
)
for label, candidates, required in programs:
executable = find_executable(*candidates)
if label == "PDF Arranger" and not executable and sys.platform == "darwin":
system_open = Path("/usr/bin/open")
opener = find_executable("open") or (
str(system_open) if system_open.is_file() else None
)
executable = f"{opener} (Aperçu)" if opener else None
detail = executable or "Introuvable dans PATH"
checks.append(DiagnosticCheck(label, executable is not None, detail, required))
api_key = api_key_override.strip() or os.environ.get("GEMINI_API_KEY")
checks.append(
DiagnosticCheck(
"Clé Gemini",
bool(api_key),
"GEMINI_API_KEY est définie" if api_key else "À saisir dans le GUI ou dans lenvironnement",
)
)
if evaluation and (evaluation / "labels").is_file():
labels = [
line.strip()
for line in (evaluation / "labels").read_text(encoding="utf-8").splitlines()
if line.strip()
]
unsafe = [label for label in labels if windows_filename_problems(label)]
detail = (
"Tous les labels sont utilisables comme noms de fichiers"
if not unsafe
else "Caractères Windows interdits : " + ", ".join(unsafe[:3])
)
if len(unsafe) > 3:
detail += f" (+{len(unsafe) - 3})"
checks.append(
DiagnosticCheck(
"Labels compatibles Windows",
not unsafe,
detail,
os.name == "nt",
)
)
if show_personal_steps:
checks.append(
DiagnosticCheck(
"gestion_classe",
shutil.which("gestion_classe") is not None,
shutil.which("gestion_classe") or "Introuvable dans PATH",
False,
)
)
try:
from copienator.configuration import CURRENT_SCORE_ODS_PATH, FINAL_SCORE_ODS_PATH
for label, configured_path in (
("ODS courant", CURRENT_SCORE_ODS_PATH),
("ODS final", FINAL_SCORE_ODS_PATH),
):
path = Path(configured_path).expanduser()
checks.append(DiagnosticCheck(label, path.is_file(), str(path), False))
except ImportError:
checks.append(DiagnosticCheck("Configuration personnelle", False, "Variables absentes", False))
return checks