Files

47 lines
2.1 KiB
Python

"""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 {}