diff --git a/Script.org b/Script.org index cbb5597..b793201 100644 --- a/Script.org +++ b/Script.org @@ -357,7 +357,14 @@ OU - `python -m copienator read-grouped --update-score Interro` pour mettre à jour les scores dans les images. 4. (gestion perso) - + =gestion_classe ne= pour créer l'interro puis + + =gestion_classe ne INT05 --defaults= pour créer l'interro sans saisie + (nom du fichier dans Staging, sans suffixe ; semaine suivante pour ce type, + sans duplication ni saisie des notes). Ajouter =--week 3= pour imposer la + semaine, notamment pour la première évaluation de ce type. Dans l'interface, + « Créer l'interro dans gestion_classe » propose le nom du dossier et une + semaine facultative, puis exécute cette commande. Un fichier absent ou un + type inconnu provoque une erreur. =gestion_classe ne= reste interactif. + Puis + =gestion_classe we= (set barème here) + =python -m copienator update-ods Interro= ou =python -m copienator update-ods Interro --sum= (en l'absence de barème) diff --git a/copienator_gui/app.py b/copienator_gui/app.py index 6363180..badfc2f 100644 --- a/copienator_gui/app.py +++ b/copienator_gui/app.py @@ -1117,8 +1117,6 @@ class CopienatorApp(tk.Tk): self.run_button.configure(text="Make modifications" if step.id == "modify_annotations" else "Enregistrer la sélection" if step.id == "refaire_selection" else ("Marquer terminée" if step.is_manual else "Exécuter")) if step.id == "remove_copy": self.run_button.configure(text="Supprimer la copie sélectionnée") - if step.id == "personal_create": - self.run_button.configure(text="Marquer Réussie") if step.id == "personal_read": self.run_button.configure(text="Marquer réussie") self.skip_button.configure(state="normal" if step.optional else "disabled") @@ -1815,7 +1813,7 @@ class CopienatorApp(tk.Tk): except (OSError, ValueError, TypeError) as exc: messagebox.showerror("Sélection à vérifier", str(exc)) return - if (step.is_manual or step.id == "personal_create" + if (step.is_manual or (step.id == "personal_read" and review_command is None)): self._mark_step("success") if step.id == "general_remarks": diff --git a/copienator_gui/workflow.py b/copienator_gui/workflow.py index 5dcd15f..7990a62 100644 --- a/copienator_gui/workflow.py +++ b/copienator_gui/workflow.py @@ -777,9 +777,15 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]: "personal_create", "Étapes personnelles", "Créer l’interro dans gestion_classe", - "Copiez la commande gestion_classe ne et exécutez-la dans un terminal, " - "puis cliquez sur « Marquer Réussie ».", - (CommandVariant("default", "gestion_classe ne", "gestion_classe", "external", ("ne",)),), + "Crée l’évaluation avec les valeurs par défaut : semaine suivante pour ce type, " + "sans duplication ni saisie des notes. Pour la première évaluation de ce type, indiquez la semaine.", + (CommandVariant("default", "gestion_classe ne", "gestion_classe", "external", ("ne", "--defaults"), fixed_args_before_positionals=True),), + arguments=( + arg_evaluation_name(), + ArgumentSpec("week", "Semaine (facultatif)", "int", "--week", + help="Laissez vide pour utiliser la dernière semaine de ce type + 1. " + "Obligatoire pour la première évaluation de ce type (0 à 255)."), + ), personal=True, ), StepDefinition( @@ -850,8 +856,11 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]: "personal_deploy", "Étapes personnelles", "Déployer et publier les copies", - "Étape manuelle : déployer miqmacs-copies-assets et la section `Interro` (inutile : mettre à jour les copies depuis l’administration).", - (manual("deploy"),), + "Publie toutes les copies puis exécute la procédure « L’interro » de deploy.org. " + "Prérequis : récupérer les PDF de Staging et exporter MPSI depuis index.org. " + "Après modification de deploy.org, régénérez manuellement le script dans Emacs (C-c C-v t).", + (CommandVariant("deploy", "Publier les copies et l’interro", "bash", "external", + (str(Path.home() / "Scripts" / "deploy-copies-interro.sh"),)),), personal=True, ), StepDefinition( diff --git a/tests/test_gui_convenience.py b/tests/test_gui_convenience.py index eda3a41..ccc128d 100644 --- a/tests/test_gui_convenience.py +++ b/tests/test_gui_convenience.py @@ -64,6 +64,50 @@ class GuiConvenienceTests(unittest.TestCase): self.assertEqual(command[-2:], ['repair-orientation', str(self.evaluation)]) self.assertEqual(self.app.active_step_id, 'labels') + def test_personal_deploy_runs_generated_script_and_tracks_result(self): + from copienator_gui.workflow import build_workflow + step = next(step for step in build_workflow(True) if step.id == "personal_deploy") + self.app.step_by_id[step.id] = step + self.app.current_step = step + self.app._render_step() + self.assertEqual(self.app.run_button.cget("text"), "Exécuter") + with patch.object(self.app.runner, "start") as start, \ + patch.object(self.app, "_move_selection_from"): + self.app.run_button.invoke() + self.assertEqual(start.call_args.args[0], + ["bash", str(Path.home() / "Scripts" / "deploy-copies-interro.sh")]) + self.assertNotEqual(self.app.state_store.step(step.id)["status"], "success") + self.app._finish_process(1, False) + self.assertNotEqual(self.app.state_store.step(step.id)["status"], "success") + self.app.run_button.invoke() + self.app._finish_process(0, False) + self.assertEqual(self.app.state_store.step(step.id)["status"], "success") + + def test_personal_create_executes_with_defaults_and_tracks_result(self): + from copienator_gui.workflow import build_workflow + step = next(step for step in build_workflow(True) if step.id == "personal_create") + self.app.step_by_id[step.id] = step + self.app.current_step = step + self.app._render_step() + self.assertEqual(self.app.run_button.cget("text"), "Exécuter") + self.assertEqual(self.app.arg_vars["evaluation_name"].get(), self.evaluation.name) + self.assertEqual(self.app.arg_vars["week"].get(), "") + with patch.object(self.app.runner, "start") as start, \ + patch.object(self.app, "_move_selection_from"): + self.app.run_button.invoke() + self.assertEqual(start.call_args.args[0], + ["gestion_classe", "ne", "--defaults", self.evaluation.name]) + self.assertNotEqual(self.app.state_store.step(step.id)["status"], "success") + self.app._finish_process(1, False) + self.assertNotEqual(self.app.state_store.step(step.id)["status"], "success") + self.app.arg_vars["evaluation_name"].set("DS02VB custom") + self.app.arg_vars["week"].set("3") + self.app.run_button.invoke() + self.assertEqual(start.call_args.args[0], + ["gestion_classe", "ne", "--defaults", "DS02VB custom", "--week", "3"]) + self.app._finish_process(0, False) + self.assertEqual(self.app.state_store.step(step.id)["status"], "success") + def test_personal_review_commands_require_explicit_completion(self): from copienator_gui.workflow import build_workflow step = next(step for step in build_workflow(True) if step.id == "personal_read")