import os import sys import json import ezodf from pathlib import Path # Configuration ODS_PATH = "/home/sebastien/Rust/gestion_classe/Staging/current_eval.ods" TARGET_DIR_NAME = "A Rendre" def main(): if len(sys.argv) < 2: # Default to current directory if not provided, or raise error work_dir = os.getcwd() else: work_dir = os.path.abspath(sys.argv[1]) all_labels = [l for l in (Path(work_dir) / "labels").read_text().split("\n") if l!=""] a_rendre_path = os.path.join(work_dir, TARGET_DIR_NAME) if not os.path.isdir(a_rendre_path): print(f"Error: Directory '{TARGET_DIR_NAME}' not found in {work_dir}") sys.exit(1) if not os.path.exists(ODS_PATH): print(f"Error: ODS file not found at {ODS_PATH}") sys.exit(1) print(f"Opening ODS file: {ODS_PATH}...") try: doc = ezodf.opendoc(ODS_PATH) except Exception as e: print(f"Failed to open ODS: {e}") sys.exit(1) # Assuming the data is in the first sheet sheet = doc.sheets[0] # Map Student Names to Column Indices # User specified: Names are in the second line (index 1) # User specified: Ignore first 3 columns (0, 1, 2) name_row_index = 1 name_to_col = {} for col_idx in range(3, sheet.ncols()): cell = sheet[name_row_index, col_idx] if cell.value: # Normalize name: strip spaces name = str(cell.value).strip() name_to_col[name] = col_idx print(f"Found {len(name_to_col)} students in ODS.") # Iterate over folders in "A Rendre" for item in os.listdir(a_rendre_path): student_dir = os.path.join(a_rendre_path, item) # Check if it is a directory and has a name (ignoring the (ID) suffix if present from previous script) # The directory name might be "Name" or "Name (ID)". # The ODS usually contains just "Name". if not os.path.isdir(student_dir): continue # Extract strict name for ODS matching (remove potential ID suffix if added by previous tool) # Assuming the ODS name matches the folder name prefix # If folder is "Doe John (123)", ODS likely has "Doe John" or "Doe John (123)"? # Based on previous prompt, ODS has "AMELOT Gautier". # We try exact match first, then simplified match. json_path = os.path.join(student_dir, "score.json") if not os.path.exists(json_path): continue with open(json_path, 'r', encoding='utf-8') as f: try: scores_data = json.load(f) except json.JSONDecodeError: print(f"Error decoding JSON for {item}") continue # Determine Column Index col_idx = name_to_col.get(item) # If not found exact match, try stripping ID suffix e.g. "Name (123)" -> "Name" if col_idx is None and '(' in item: clean_name = item.rsplit('(', 1)[0].strip() col_idx = name_to_col.get(clean_name) if col_idx is None: print(f"Skipping '{item}': Name not found in ODS columns.") continue # Sort keys naturally (Ex 2 comes before Ex 10) # sorted_keys = natsorted(scores_data.keys()) # Start filling from Row 2 (index 2), immediately below the name line start_row = 2 # for i, key in enumerate(scores_data.keys()): for i, key in enumerate(all_labels): row_idx = start_row + i # Ensure we don't go out of bounds if row_idx >= sheet.nrows(): sheet.append_rows(1) if key in scores_data: val_str = str(scores_data[key]) else: val_str = "" # Logic: if "" -> "NT" new_val = "NT" if val_str == "" else val_str cell = sheet[row_idx, col_idx] current_val = cell.value # Conflict Detection # Normalize current ODS value to string for comparison # ODS might store 2.0 as float 2.0. JSON has "2.0". is_different = False if current_val is not None and current_val != "": # specific check to handle float/string mismatch (2.0 vs "2.0") try: if float(str(current_val)) != float(str(new_val)): is_different = True except ValueError: # If conversion fails (e.g. comparing "NT" to "2.0"), compare strings if str(current_val).strip() != str(new_val).strip(): is_different = True if is_different: print(f"DEBUG: Conflict for {item} at {key} (Row {row_idx}). " f"Existing: '{current_val}' vs New: '{new_val}'. Overwriting.") # Set value # Try to set as float if it looks like a number, otherwise string if new_val == "NT": cell.set_value(new_val) else: try: cell.set_value(float(new_val)) except ValueError: cell.set_value(new_val) print("Saving ODS file...") doc.save() print("Done.") if __name__ == "__main__": main()