Standardisation 9

This commit is contained in:
2026-08-20 15:23:45 +02:00
parent b19d3b0db6
commit 3a8d0fe3ff
4 changed files with 183 additions and 71 deletions
+54 -20
View File
@@ -1,16 +1,26 @@
import sys
import os
from __future__ import annotations
import argparse
import glob
import json
import urllib.request
import os
import re
import subprocess
import tempfile
import shutil
import urllib.request
from collections.abc import Sequence
from uuid import uuid4
from copienator import (
CliError,
EvaluationWorkspace,
ExitCode,
evaluation_parser,
execute,
workspace_from_args,
)
from platform_utils import WindowsLabelError, validate_windows_labels
from utils import compile_to_pdf
def fetch_and_save_sub_text(ex_id, indices, label, text_path):
"""Fetches text for a specific sub-question and saves it to Text/{label}.tex"""
qinds = ",".join(map(str, indices))
@@ -29,6 +39,7 @@ def fetch_and_save_sub_text(ex_id, indices, label, text_path):
compile_to_pdf(content, pdf_file)
except Exception as e:
print(f"Error fetching sub-text from {url}: {e}")
raise
def fetch_and_save_sub_sol(ex_id, indices, label, sol_path):
"""Fetches text for a specific sub-question and saves it to Text/{label}.tex"""
@@ -48,6 +59,7 @@ def fetch_and_save_sub_sol(ex_id, indices, label, sol_path):
compile_to_pdf(content, pdf_file)
except Exception as e:
print(f"Error fetching sub-text from {url}: {e}")
raise
ROMANS_CAP = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"]
@@ -127,18 +139,21 @@ def save_split_content(text, path, base_fname, problem):
f.write(chunk)
def process_directory(directory):
def process_directory(workspace: EvaluationWorkspace) -> ExitCode:
directory = str(workspace.root)
# Find the first .tex file in the directory
tex_files = glob.glob(os.path.join(directory, "*.tex"))
if not tex_files:
print(f"No .tex file found in {directory}. Looking in /Staging/Interro/")
int_name = directory[:-1] if directory.endswith("/") else directory
int_name = directory.removesuffix("/")
tex_path = os.path.join(os.path.expanduser("~"), "Prépa/Staging/Interro", f"{int_name}.tex")
if os.path.exists(tex_path):
tex_file = tex_path
else:
print("Not found in ", tex_path)
return
raise CliError(
f"No .tex input found in {workspace.root}",
ExitCode.INVALID_WORKSPACE,
)
else:
tex_file = tex_files[0]
@@ -153,8 +168,10 @@ def process_directory(directory):
for p in paths.values():
os.makedirs(p, exist_ok=True)
labels_file = os.path.join(directory, "labels")
labels_file = workspace.labels_file
labels_staging = labels_file.with_name(f".{labels_file.name}.{uuid4().hex}.tmp")
current_ex_num = 1
had_errors = False
# Read entirely to allow chunking
with open(tex_file, 'r', encoding='utf-8') as f_in:
@@ -162,8 +179,11 @@ def process_directory(directory):
# Split by the specific SHEETINFO tag
blocks = content.split("%%SHEETINFO :")
if len(blocks) == 1:
print(f"No SHEETINFO blocks found in {tex_file}")
return ExitCode.PARTIAL
with open(labels_file, 'w', encoding='utf-8') as f_labels:
with open(labels_staging, 'w', encoding='utf-8') as f_labels:
# Skip blocks[0] (content before first SHEETINFO)
for block in blocks[1:]:
parts_line = block.split("\n", 1)
@@ -177,6 +197,7 @@ def process_directory(directory):
try:
data = json.loads(json_str)
block_labels = []
# Construct 'ids' parameter
ex_id = str(data['id'])
selection = data.get('select')
@@ -193,7 +214,7 @@ def process_directory(directory):
if not indexes:
label = f"Ex {current_ex_num}"
validate_windows_labels([label])
f_labels.write(f"{label}\n")
block_labels.append(label)
fetch_and_save_sub_text(ids, [], label, paths['Text2'])
fetch_and_save_sub_sol(ids, [], label, paths['Sol2'])
else:
@@ -201,7 +222,7 @@ def process_directory(directory):
suffix = format_indices(item['indices'], problem)
label = f"Ex {current_ex_num}" + (f" : {suffix}" if suffix else "")
validate_windows_labels([label])
f_labels.write(f"{label}\n")
block_labels.append(label)
fetch_and_save_sub_text(ids, item['indices'], label, paths['Text2'])
fetch_and_save_sub_sol(ids, item['indices'], label, paths['Sol2'])
@@ -244,18 +265,31 @@ def process_directory(directory):
save_split_content(s_text, paths['Sol'], base_filename, problem)
save_split_content(p_text, paths['Persp'], base_filename, problem)
for label in block_labels:
f_labels.write(f"{label}\n")
current_ex_num += 1
except WindowsLabelError:
labels_staging.unlink(missing_ok=True)
raise
except json.JSONDecodeError:
print(f"Error decoding JSON in block: {json_str}")
except Exception as e:
had_errors = True
except Exception as e: # noqa: BLE001 - one malformed exercise is partial
print(f"Error processing block {ex_id if 'ex_id' in locals() else 'unknown'}: {e}")
had_errors = True
labels_staging.replace(labels_file)
return ExitCode.PARTIAL if had_errors else ExitCode.SUCCESS
def build_parser() -> argparse.ArgumentParser:
return evaluation_parser("Generate statement metadata from SHEETINFO blocks")
def main(argv: Sequence[str] | None = None) -> int:
parser = build_parser()
return execute(parser, argv, lambda args: process_directory(workspace_from_args(args)))
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python script.py <Dir>")
sys.exit(1)
process_directory(sys.argv[1])
raise SystemExit(main())