multi fce stuff

This commit is contained in:
Olive Vaughn 2026-09-29 02:34:53 -04:00
parent 49ece8dee6
commit ddabfbeaa8
32 changed files with 1309 additions and 700 deletions

View file

@ -433,12 +433,23 @@ def analysis_detail(request, key):
try:
keys = _body(request).get("source_blocks")
roles = {"source/dense", "source/detected", "source/crops"}
if not isinstance(keys, list) or len(keys) != len(roles) or len(set(keys)) != len(roles):
raise Bad("an analysis needs one block for each source role")
if (not isinstance(keys, list) or not keys
or not all(isinstance(k, str) for k in keys) or len(set(keys)) != len(keys)):
raise Bad("an analysis needs distinct source block keys")
blocks = list(Block.objects.filter(key__in=keys))
if (len(blocks) != len(roles) or {b.role for b in blocks} != roles
or any(b.analysis_id != key for b in blocks)):
raise Bad("source blocks must have distinct source roles and name this analysis")
if len(blocks) != len(keys) or any(b.analysis_id != key for b in blocks):
raise Bad("source blocks must exist and name this analysis")
by_subject = {}
for block in blocks:
subjects = json.loads(block.descriptor).get("features", [])
if (not isinstance(subjects, list) or len(subjects) > 1
or any(not isinstance(s, str) or not s for s in subjects)):
raise Bad("a source block must name one subject")
# Older single-face analyses used an empty feature list.
by_subject.setdefault(tuple(subjects), []).append(block.role)
if any(len(found) != len(roles) or set(found) != roles
for found in by_subject.values()):
raise Bad("each subject needs one block for each source role")
with transaction.atomic():
row = Analysis.objects.select_for_update().get(key=key)
current = set(row.source_blocks.values_list("key", flat=True))