"""Last exported overall marks, keyed by stable copy ID rather than student name.""" from pathlib import Path from copienator import read_json, configuration from copienator.return_identity import return_folders, RETURN_FOLDER_PATTERN FINAL_SCORES_FILE = Path('.copienator') / 'final_scores.json' def exported_scores(root: Path, repository: Path) -> dict[str, str]: saved = root / FINAL_SCORES_FILE if saved.is_file(): data = read_json(saved) return {str(int(cid)): entry['score'] for cid, entry in data.get('copies', {}).items() if cid.isdecimal() and isinstance(entry, dict) and isinstance(entry.get('score'), str)} # Older exports have no machine-readable overall mark. Only use their ODS # when it predates the exported media; a newer sheet may contain other marks. output = Path(configuration.FINAL_SCORE_OUTPUT_DIR).expanduser() ods = Path(configuration.FINAL_SCORE_ODS_PATH).expanduser() output = output if output.is_absolute() else repository / output ods = ods if ods.is_absolute() else repository / ods if not ods.is_file() or not (output / root.name).is_dir(): return {} candidates = {} for cid, folder in return_folders(root).items(): name = RETURN_FOLDER_PATTERN.fullmatch(folder.name)['name'] media = [p for p in (output / root.name / name).glob('*') if p.suffix.lower() in ('.jpg', '.pdf') and p.is_file()] if media and ods.stat().st_mtime_ns <= min(p.stat().st_mtime_ns for p in media): candidates[str(cid)] = name if not candidates: return {} try: import pandas as pd from copienator.commands.add_final_score import get_rounded_score sheet = pd.read_excel(ods, engine='odf', header=None) values = dict(zip(sheet[0], sheet[1])) result = {} for cid, name in candidates.items(): score = get_rounded_score(values.get(name)) if score is not None: result[cid] = str(score) return result except (OSError, ValueError, KeyError, ImportError, OverflowError): return {}