Restructuration de l'application
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
from copienator_gui.app import CopienatorApp
|
||||
|
||||
|
||||
def personal_steps_enabled() -> bool:
|
||||
try:
|
||||
from copienator.configuration import SHOW_PERSONAL_STEPS
|
||||
except (ImportError, AttributeError):
|
||||
return False
|
||||
return bool(SHOW_PERSONAL_STEPS)
|
||||
|
||||
|
||||
def main(argv=None) -> int:
|
||||
parser = argparse.ArgumentParser(description="Interface graphique du workflow Copienator")
|
||||
parser.add_argument("evaluation", nargs="?", type=Path, help="Dossier d’évaluation à ouvrir")
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
repository = Path.cwd().resolve()
|
||||
evaluation = args.evaluation.resolve() if args.evaluation else None
|
||||
app = CopienatorApp(repository, personal_steps_enabled(), evaluation)
|
||||
app.mainloop()
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -8,7 +8,7 @@ from tkinter import filedialog, messagebox, ttk
|
||||
from typing import Any
|
||||
|
||||
from copienator import ExitCode
|
||||
from platform_utils import WindowsLabelError, open_path, validate_windows_labels
|
||||
from copienator.platform import WindowsLabelError, open_path, validate_windows_labels
|
||||
|
||||
from .diagnostics import collect_diagnostics
|
||||
from .runner import ProcessRunner
|
||||
@@ -71,7 +71,7 @@ def detected_annotation_directories(evaluation: Path) -> tuple[str, ...]:
|
||||
|
||||
def plotting_shortcut_lines() -> list[str]:
|
||||
try:
|
||||
from config import PLOTTING_KB
|
||||
from copienator.configuration import PLOTTING_KB
|
||||
except (ImportError, AttributeError):
|
||||
from default_config import PLOTTING_KB
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import sys
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
from platform_utils import windows_filename_problems
|
||||
from copienator.platform import windows_filename_problems
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -111,7 +111,7 @@ def collect_diagnostics(
|
||||
)
|
||||
)
|
||||
try:
|
||||
from config import CURRENT_SCORE_ODS_PATH, FINAL_SCORE_ODS_PATH
|
||||
from copienator.configuration import CURRENT_SCORE_ODS_PATH, FINAL_SCORE_ODS_PATH
|
||||
|
||||
for label, configured_path in (
|
||||
("ODS courant", CURRENT_SCORE_ODS_PATH),
|
||||
|
||||
+33
-33
@@ -90,8 +90,8 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Analyser l’énoncé",
|
||||
"Détecte les questions, leurs groupes, le corrigé et les indications de barème.",
|
||||
(
|
||||
python("gemini", "Analyse avec Gemini", "gemini_for_enonce.py"),
|
||||
python("personal", "Alternative enonce_info.py", "enonce_info.py"),
|
||||
python("gemini", "Analyse avec Gemini", "statement"),
|
||||
python("personal", "Alternative personnelle", "statement-personal"),
|
||||
),
|
||||
arguments=(
|
||||
arg_target("Dossier de l’évaluation"),
|
||||
@@ -124,7 +124,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
CommandVariant(
|
||||
"rotate",
|
||||
"Rotation",
|
||||
"copies_tools.py",
|
||||
"copies",
|
||||
"python",
|
||||
("rotate",),
|
||||
fixed_args_before_positionals=True,
|
||||
@@ -142,7 +142,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
CommandVariant(
|
||||
"rename",
|
||||
"Renommage",
|
||||
"copies_tools.py",
|
||||
"copies",
|
||||
"python",
|
||||
("rename",),
|
||||
fixed_args_before_positionals=True,
|
||||
@@ -155,7 +155,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Prétraitement des copies",
|
||||
"Séparer et réordonner les pages",
|
||||
"Ouvre l’outil interactif de découpage A3 vers A4. La cible peut être un dossier ou un PDF.",
|
||||
(python("default", "Séparation des pages", "page_splitter.py"),),
|
||||
(python("default", "Séparation des pages", "page-split"),),
|
||||
arguments=(arg_target(),),
|
||||
artifacts=("Copies", "Copies Originales"),
|
||||
),
|
||||
@@ -164,7 +164,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Prétraitement des copies",
|
||||
"Découper la marge des labels",
|
||||
"Produit les images de la partie gauche des copies. Une copie précise peut être ciblée.",
|
||||
(python("default", "Découpe", "cutleft.py"),),
|
||||
(python("default", "Découpe", "crop-labels"),),
|
||||
arguments=(
|
||||
arg_target(),
|
||||
ArgumentSpec("fullpage", "Toujours utiliser la page entière", "bool", "--fullpage"),
|
||||
@@ -177,7 +177,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Labels et regroupement",
|
||||
"Détecter les labels avec Gemini",
|
||||
"Identifie les labels dans les images produites par la découpe gauche.",
|
||||
(python("default", "Détection des labels", "gemini_for_labels.py"),),
|
||||
(python("default", "Détection des labels", "labels"),),
|
||||
arguments=(
|
||||
arg_target(),
|
||||
ArgumentSpec("overwrite", "Régénérer les résultats", "bool", "--overwrite"),
|
||||
@@ -190,7 +190,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Labels et regroupement",
|
||||
"Vérifier visuellement les labels",
|
||||
"Ouvre la fenêtre de vérification. La cible peut être toute l’évaluation ou une copie.",
|
||||
(python("default", "Vérification", "plotting.py"),),
|
||||
(python("default", "Vérification", "review-labels"),),
|
||||
arguments=(arg_target(),),
|
||||
requires=("labels", "Cutleft"),
|
||||
artifacts=("Copies/Copie*.json",),
|
||||
@@ -200,7 +200,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Labels et regroupement",
|
||||
"Découper les réponses par question",
|
||||
"Découpe les copies à partir des coordonnées de labels vérifiées.",
|
||||
(python("default", "Découpage", "splitting_int.py"),),
|
||||
(python("default", "Découpage", "split-answers"),),
|
||||
arguments=(arg_target(),),
|
||||
requires=("Copies",),
|
||||
artifacts=("Copies/Copie*/*",),
|
||||
@@ -211,7 +211,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Labels et regroupement",
|
||||
"Regrouper les réponses",
|
||||
"Regroupe les réponses portant le même label pour préparer les requêtes.",
|
||||
(python("default", "Regroupement", "grouping.py"),),
|
||||
(python("default", "Regroupement", "group-answers"),),
|
||||
arguments=(arg_target("Dossier de l’évaluation"),),
|
||||
requires=("Copies",),
|
||||
artifacts=("Par label",),
|
||||
@@ -222,7 +222,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Labels et regroupement",
|
||||
"Vérifier les groupes produits",
|
||||
"Vérifie que chaque réponse PDF apparaît dans les métadonnées des groupes.",
|
||||
(python("default", "Vérification des groupes", "verify_groups.py"),),
|
||||
(python("default", "Vérification des groupes", "verify-groups"),),
|
||||
arguments=(arg_target("Dossier de l’évaluation"),),
|
||||
optional=True,
|
||||
requires=("Copies", "Par label"),
|
||||
@@ -233,17 +233,17 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Lancer ou intégrer la correction",
|
||||
"Choisir une correction immédiate, batch, hybride, une recorrection, ou l’intégration d’un batch.",
|
||||
(
|
||||
python("live", "Correction immédiate", "correction.py"),
|
||||
python("batch", "Préparer toutes les requêtes batch", "correction.py", fixed_args=("--batch",)),
|
||||
python("hybrid", "Batch à partir d’un label", "correction.py"),
|
||||
python("refaire", "Recorrection depuis refaire.json", "correction.py", fixed_args=("--refaire",)),
|
||||
python("live", "Correction immédiate", "correct"),
|
||||
python("batch", "Préparer toutes les requêtes batch", "correct", fixed_args=("--batch",)),
|
||||
python("hybrid", "Batch à partir d’un label", "correct"),
|
||||
python("refaire", "Recorrection depuis refaire.json", "correct", fixed_args=("--refaire",)),
|
||||
python(
|
||||
"integrate",
|
||||
"Intégrer les résultats batch",
|
||||
"correction.py",
|
||||
"correct",
|
||||
fixed_args=("--deal-with-batched",),
|
||||
),
|
||||
python("reset", "Réinitialiser les corrections", "correction.py", fixed_args=("--reset",), dangerous=True),
|
||||
python("reset", "Réinitialiser les corrections", "correct", fixed_args=("--reset",), dangerous=True),
|
||||
),
|
||||
arguments=(
|
||||
arg_target("Évaluation ou image Group_X.jpg"),
|
||||
@@ -259,7 +259,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Correction",
|
||||
"Envoyer les batchs",
|
||||
"Envoie à Gemini les fichiers JSONL produits par le mode batch.",
|
||||
(python("default", "Envoi", "submit_batches.py"),),
|
||||
(python("default", "Envoi", "batch-submit"),),
|
||||
arguments=(arg_target("Dossier de l’évaluation"),),
|
||||
optional=True,
|
||||
artifacts=("batch_jobs.json",),
|
||||
@@ -270,7 +270,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Correction",
|
||||
"Consulter l’état des batchs",
|
||||
"Affiche les jobs Gemini en cours. L’identifiant de téléchargement est facultatif.",
|
||||
(python("default", "État des batchs", "batch_status.py"),),
|
||||
(python("default", "État des batchs", "batch-status"),),
|
||||
arguments=(ArgumentSpec("download", "Télécharger le job", "text", "--download"),),
|
||||
optional=True,
|
||||
skip_for_live_correction=True,
|
||||
@@ -280,7 +280,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Correction",
|
||||
"Récupérer les résultats batch",
|
||||
"Télécharge et rassemble les réponses des jobs terminés.",
|
||||
(python("default", "Récupération", "fetch_batched_results.py"),),
|
||||
(python("default", "Récupération", "batch-fetch"),),
|
||||
arguments=(arg_target("Dossier de l’évaluation"),),
|
||||
optional=True,
|
||||
skip_for_live_correction=True,
|
||||
@@ -290,7 +290,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Correction",
|
||||
"Nettoyer la correction",
|
||||
"Corrige certains problèmes d’encodage et prépare le texte pour LaTeX.",
|
||||
(python("default", "Post-correction", "post-correction.py"),),
|
||||
(python("default", "Post-correction", "post-correction"),),
|
||||
arguments=(arg_target("Dossier de l’évaluation"),),
|
||||
requires=("correction.json",),
|
||||
),
|
||||
@@ -299,7 +299,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Correction",
|
||||
"Résoudre les conflits manuels",
|
||||
"Étape conditionnelle, uniquement si manual_resolutions.txt contient des conflits à traiter.",
|
||||
(python("default", "Résolution", "resolve_manual.py"),),
|
||||
(python("default", "Résolution", "resolve-manual"),),
|
||||
arguments=(arg_target("Dossier de l’évaluation"),),
|
||||
optional=True,
|
||||
requires=("manual_resolutions.txt", "correction.json"),
|
||||
@@ -311,9 +311,9 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Générer les copies annotées",
|
||||
"Les trois modes sont exclusifs pour un parcours donné.",
|
||||
(
|
||||
python("simple", "Annotations simples (Anot)", "annotating.py"),
|
||||
python("checks", "Annotations avec cases (Bnot)", "annotating_with_checks.py"),
|
||||
python("grouped", "Annotations groupées (BGnot)", "annotating_by_label.py"),
|
||||
python("simple", "Annotations simples (Anot)", "annotate-simple"),
|
||||
python("checks", "Annotations avec cases (Bnot)", "annotate-checks"),
|
||||
python("grouped", "Annotations groupées (BGnot)", "annotate-grouped"),
|
||||
),
|
||||
arguments=(
|
||||
arg_target("Dossier de l’évaluation"),
|
||||
@@ -328,7 +328,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Génération des annotations",
|
||||
"Exporter",
|
||||
"Exporte les annotations vers le dossier EXPORT_DIR défini dans config.py.",
|
||||
(python("default", "Export", "export.py"),),
|
||||
(python("default", "Export", "export"),),
|
||||
arguments=(
|
||||
arg_target("Dossier de l’évaluation"),
|
||||
ArgumentSpec(
|
||||
@@ -355,7 +355,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Correction manuscrite",
|
||||
"Importer les annotations manuscrites",
|
||||
"Copie les PDF présents dans IMPORT_DIR vers l’évaluation.",
|
||||
(python("default", "Import", "import.py"),),
|
||||
(python("default", "Import", "import"),),
|
||||
arguments=(
|
||||
arg_target("Dossier de l’évaluation"),
|
||||
ArgumentSpec(
|
||||
@@ -375,8 +375,8 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Lire les annotations manuscrites",
|
||||
"Le mode doit correspondre au mode choisi lors de la génération des annotations.",
|
||||
(
|
||||
python("standard", "Lecture Bnot", "reading_annotations.py"),
|
||||
python("grouped", "Lecture BGnot", "reading_grouped_annotations.py"),
|
||||
python("standard", "Lecture Bnot", "read-annotations"),
|
||||
python("grouped", "Lecture BGnot", "read-grouped"),
|
||||
),
|
||||
arguments=(
|
||||
arg_target("Dossier de l’évaluation"),
|
||||
@@ -389,7 +389,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Finalisation",
|
||||
"Attribuer les noms et préparer A Rendre",
|
||||
"Crée le dossier A Rendre à partir du dossier d’annotations choisi.",
|
||||
(python("default", "Attribution des noms", "giving_names.py"),),
|
||||
(python("default", "Attribution des noms", "giving-names"),),
|
||||
arguments=(
|
||||
arg_target("Dossier de l’évaluation"),
|
||||
ArgumentSpec(
|
||||
@@ -424,7 +424,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Étapes personnelles",
|
||||
"Mettre à jour le fichier ODS",
|
||||
"Transfère les scores, avec la possibilité de n’écrire que leur somme.",
|
||||
(python("default", "Mise à jour ODS", "update_ods.py"),),
|
||||
(python("default", "Mise à jour ODS", "update-ods"),),
|
||||
arguments=(
|
||||
arg_target("Dossier de l’évaluation"),
|
||||
ArgumentSpec("sum", "Écrire seulement la somme", "bool", "--sum"),
|
||||
@@ -452,7 +452,7 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"Étapes personnelles",
|
||||
"Ajouter le score final",
|
||||
"Génère les fichiers de diffusion avec le score final.",
|
||||
(python("default", "Score final", "add_final_score.py"),),
|
||||
(python("default", "Score final", "add-final-score"),),
|
||||
arguments=(arg_target("Dossier de l’évaluation"),),
|
||||
personal=True,
|
||||
),
|
||||
@@ -494,7 +494,7 @@ def build_command(
|
||||
|
||||
program_path = repository / variant.program
|
||||
if variant.kind == "python":
|
||||
command = [sys.executable, "-u", str(program_path)]
|
||||
command = [sys.executable, "-u", "-m", "copienator", variant.program]
|
||||
elif variant.kind == "shell":
|
||||
command = [str(program_path)]
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user