Add EXIF writing and machine metadata support

This commit is contained in:
2026-04-24 18:21:37 -04:00
parent f2193011ca
commit e8d3bf7180
11 changed files with 577 additions and 12 deletions
+29 -4
View File
@@ -14,11 +14,12 @@ from typing import Any
class RunStats:
"""Accumulated counters for one or more machines."""
scans_fetched: int = 0 # metadata fetched from server this run
scans_fetched: int = 0 # scan detail page fetched (metadata), not tiles/mosaics
scans_skipped: int = 0 # metadata.json already on disk; no HTTP request
scans_failed: int = 0 # fetch error or missing grid params
scans_failed: int = 0 # metadata fetch error or missing grid params
metadata_written: int = 0 # new metadata.json files created
mosaics_downloaded: int = 0
mosaics_failed: int = 0 # mosaic URL attempted but 0 bytes / HTTP error
tiles_downloaded: int = 0
def merge(self, other: "RunStats") -> None:
@@ -27,10 +28,12 @@ class RunStats:
self.scans_failed += other.scans_failed
self.metadata_written += other.metadata_written
self.mosaics_downloaded += other.mosaics_downloaded
self.mosaics_failed += other.mosaics_failed
self.tiles_downloaded += other.tiles_downloaded
from tqdm import tqdm
from spruce.exif import write_mosaic_exif
from spruce.paths import machine_dir_name, tile_dest, mosaic_dest, _extract_date
from spruce.progress import ProgressTracker, CsvWriter
from spruce.session import MachineSession
@@ -50,6 +53,7 @@ def _download_mosaic(
mosaic_path: Path,
progress: ProgressTracker,
machine: dict[str, Any],
config: dict[str, Any],
dry_run: bool,
) -> bool:
"""Download the scan mosaic if not already done. Returns True if downloaded."""
@@ -62,6 +66,13 @@ def _download_mosaic(
log.info("[%s] Downloading mosaic for scan %d", machine["label"], scan_id)
size = sess.download_file(url, mosaic_path)
if size:
if config.get("write_exif", True):
mmeta: dict[str, Any] | None = config.get("machine_metadata", {}).get(
machine["label"]
)
write_mosaic_exif(
mosaic_path, scan_meta, machine, scan_id, mmeta
)
progress.mark_done(url)
progress.save()
log.info(
@@ -283,10 +294,24 @@ def process_scan(
mosaic_just_downloaded = False
else:
mosaic_just_downloaded = _download_mosaic(
sess, scan_meta, scan_id, mosaic_path, progress, machine, dry_run
sess,
scan_meta,
scan_id,
mosaic_path,
progress,
machine,
config,
dry_run,
)
if mosaic_just_downloaded:
if not metadata_only and mosaic_just_downloaded:
stats.mosaics_downloaded += 1
elif (
not metadata_only
and not dry_run
and not mosaic_already_done
and not mosaic_just_downloaded
):
stats.mosaics_failed += 1
# Write scan-level CSV row only if this scan hasn't been recorded before.
if mosaic_already_done and not metadata_only: