Initial commit for finalisation web interface
This commit is contained in:
1 parent
b295f871a7
commit
c36642e8de
33 files changed
+2745
-138
No files matched your search
@@ -0,0 +1,58 @@
|
||||
from decimal import Decimal, InvalidOperation
|
||||
from pathlib import Path
|
||||
from copienator import atomic_update_json, read_json
|
||||
|
||||
def read_scores(path: Path) -> dict:
|
||||
scores = read_json(annotation_score_for_return(path))
|
||||
if not isinstance(scores, dict):
|
||||
raise ValueError(f"score.json doit contenir un objet JSON : {path}")
|
||||
return scores
|
||||
|
||||
|
||||
def set_score(path: Path, label: str, value: str) -> str:
|
||||
try:
|
||||
number = Decimal(value.strip().replace(",", "."))
|
||||
except InvalidOperation:
|
||||
raise ValueError("Le score doit être un nombre.") from None
|
||||
if not number.is_finite() or number < 0:
|
||||
raise ValueError("Le score doit être un nombre positif ou nul.")
|
||||
previous = ""
|
||||
|
||||
def update(scores):
|
||||
nonlocal previous
|
||||
if not isinstance(scores, dict) or label not in scores:
|
||||
raise ValueError(f"Label absent de score.json : {label}")
|
||||
previous = str(scores[label])
|
||||
scores[label] = str(number)
|
||||
|
||||
# A Rendre/score.json is often a symlink to the annotation score file.
|
||||
# Resolve it before atomic replacement so the link continues to work.
|
||||
atomic_update_json(annotation_score_for_return(path).resolve(strict=True), update, default_factory=dict)
|
||||
return previous
|
||||
|
||||
|
||||
|
||||
def annotation_score_for_return(path: Path) -> Path:
|
||||
"""Resolve fallback return copies as well as symlinks to their source scores."""
|
||||
if path.is_symlink() or path.parent.parent.name != 'A Rendre':
|
||||
return path.resolve()
|
||||
from copienator.return_identity import RETURN_FOLDER_PATTERN
|
||||
match = RETURN_FOLDER_PATTERN.fullmatch(path.parent.name)
|
||||
if not match:
|
||||
return path
|
||||
root = path.parent.parent.parent
|
||||
cid = match['copy_id']
|
||||
sources = read_json(root / '.copienator' / 'return_sources.json', default={})
|
||||
mode = sources.get(str(int(cid)))
|
||||
modes = (mode,) if mode in ('Bnot', 'BGnot', 'Anot') else ('Bnot', 'BGnot', 'Anot')
|
||||
candidates = [p for m in modes for p in (root / m).glob('Copie*/score.json')
|
||||
if p.parent.name[5:].isdigit() and int(p.parent.name[5:]) == int(cid)]
|
||||
if len(candidates) > 1:
|
||||
raise ValueError('Source des scores ambiguë : relancez la préparation de A Rendre dans le mode souhaité.')
|
||||
return candidates[0] if candidates else path
|
||||
|
||||
|
||||
def remember_return_source(root: Path, copy_id: str, source: Path):
|
||||
path = root / '.copienator' / 'return_sources.json'
|
||||
path.parent.mkdir(exist_ok=True)
|
||||
atomic_update_json(path, lambda data: data.update({str(int(copy_id)): source.parent.name}), default_factory=dict)
|
||||
Reference in new issue
Block a user