Bnot : split large copies into pieces.
This commit is contained in:
1 parent
834ffe32f2
commit
1959c5d3bb
10 files changed
+333
-52
No files matched your search
@@ -26,6 +26,7 @@ from copienator import (
|
||||
workspace_from_target,
|
||||
)
|
||||
from copienator.annotation_data import load_annotation_data
|
||||
from copienator.annotation_documents import MAX_HEIGHT_PX, copy_documents
|
||||
from copienator.commands import annotating
|
||||
from copienator.commands.import_annotations import clear_import_directory
|
||||
from copienator.filesystem import staged_directory
|
||||
@@ -143,7 +144,11 @@ class CheckboxRenderer:
|
||||
|
||||
|
||||
def _output_complete(output_dir: Path) -> bool:
|
||||
return all((output_dir / name).is_file() for name in EXPECTED_OUTPUTS)
|
||||
return all(
|
||||
(document / name).is_file()
|
||||
for document in copy_documents(output_dir)
|
||||
for name in EXPECTED_OUTPUTS
|
||||
)
|
||||
|
||||
|
||||
def _render_student(
|
||||
@@ -197,7 +202,6 @@ def _render_student(
|
||||
"label": label,
|
||||
"header_height": header_height,
|
||||
"layout": final_image.info.get('annotation_layout', annotating.layout_for(None)),
|
||||
"img_h": final_image.height,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -205,6 +209,46 @@ def _render_student(
|
||||
print(f"Warning: no annotations could be rendered for Copie{student_id}")
|
||||
return "partial"
|
||||
|
||||
batches = []
|
||||
start = 0
|
||||
height = 0
|
||||
for index, image in enumerate(label_images):
|
||||
if image.height > MAX_HEIGHT_PX:
|
||||
raise CliError(
|
||||
f"Copie{student_id} ({bnote_entries[index]['label']}) is "
|
||||
f"{image.height} px high; a single answer cannot be split and "
|
||||
f"the maximum document height is {MAX_HEIGHT_PX} px."
|
||||
)
|
||||
if height + image.height > MAX_HEIGHT_PX:
|
||||
batches.append((start, index))
|
||||
start = index
|
||||
height = 0
|
||||
height += image.height
|
||||
batches.append((start, len(label_images)))
|
||||
|
||||
with staged_directory(output_dir) as staging:
|
||||
parts = []
|
||||
for index, (start, end) in enumerate(batches, start=1):
|
||||
destination = staging
|
||||
if len(batches) > 1:
|
||||
name = f"Part{index}"
|
||||
parts.append(name)
|
||||
destination /= name
|
||||
_save_document(destination, label_images[start:end],
|
||||
checkbox_groups[start:end], bnote_entries[start:end])
|
||||
if parts:
|
||||
atomic_write_json(staging / "bnote.json", {
|
||||
"parts": parts, "images": bnote_entries,
|
||||
})
|
||||
return "partial" if problems else "success"
|
||||
|
||||
|
||||
def _save_document(
|
||||
output_dir: Path,
|
||||
label_images: list[Image.Image],
|
||||
checkbox_groups: list[list[dict[str, Any]]],
|
||||
bnote_entries: list[dict[str, Any]],
|
||||
) -> None:
|
||||
max_width = max(image.width for image in label_images)
|
||||
total_height = sum(image.height for image in label_images)
|
||||
concatenated = Image.new("RGB", (max_width, total_height), "white")
|
||||
@@ -216,7 +260,6 @@ def _render_student(
|
||||
concatenated.paste(image, (0, current_y))
|
||||
bnote_entries[index]["hmin"] = current_y
|
||||
bnote_entries[index]["hmax"] = current_y + image.height
|
||||
del bnote_entries[index]["img_h"]
|
||||
for item in checkboxes:
|
||||
box = item.get("final_box") or item.get("rel_box")
|
||||
item["global_box"] = [
|
||||
@@ -228,25 +271,24 @@ def _render_student(
|
||||
checkbox_map.append(item)
|
||||
current_y += image.height
|
||||
|
||||
with staged_directory(output_dir) as staging:
|
||||
atomic_write_json(
|
||||
staging / "bnote.json",
|
||||
{"width": max_width, "height": total_height, "images": bnote_entries},
|
||||
)
|
||||
atomic_write_json(staging / "checkboxes.json", checkbox_map)
|
||||
reference = staging / "Reference.jpg"
|
||||
concatenated.save(reference, quality=90)
|
||||
pdf_path = staging / "Concat.pdf"
|
||||
pdf_canvas = canvas.Canvas(str(pdf_path), pagesize=(max_width, total_height))
|
||||
pdf_canvas.drawImage(
|
||||
str(reference),
|
||||
0,
|
||||
0,
|
||||
width=max_width,
|
||||
height=total_height,
|
||||
)
|
||||
pdf_canvas.save()
|
||||
return "partial" if problems else "success"
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
atomic_write_json(
|
||||
output_dir / "bnote.json",
|
||||
{"width": max_width, "height": total_height, "images": bnote_entries},
|
||||
)
|
||||
atomic_write_json(output_dir / "checkboxes.json", checkbox_map)
|
||||
reference = output_dir / "Reference.jpg"
|
||||
concatenated.save(reference, quality=90)
|
||||
pdf_path = output_dir / "Concat.pdf"
|
||||
pdf_canvas = canvas.Canvas(str(pdf_path), pagesize=(max_width, total_height))
|
||||
pdf_canvas.drawImage(
|
||||
str(reference),
|
||||
0,
|
||||
0,
|
||||
width=max_width,
|
||||
height=total_height,
|
||||
)
|
||||
pdf_canvas.save()
|
||||
|
||||
|
||||
def _copy_id_from_target(workspace: EvaluationWorkspace, target: Path) -> str | None:
|
||||
|
||||
Reference in new issue
Block a user