fix: pull assembly dependencies recursively before opening #19

Merged
forbes merged 1 commits from fix/pull-assembly-dependencies into main 2026-02-11 19:12:23 +00:00

View File

@@ -1062,6 +1062,65 @@ class SiloPullDialog:
return None
def _pull_dependencies(part_number, progress_callback=None):
"""Recursively pull all BOM children that have files on the server.
Returns list of (part_number, dest_path) tuples for successfully pulled files.
Skips children that already exist locally.
"""
pulled = []
try:
bom = _client.get_bom(part_number)
except Exception as e:
FreeCAD.Console.PrintWarning(f"Could not fetch BOM for {part_number}: {e}\n")
return pulled
for entry in bom:
child_pn = entry.get("child_part_number")
if not child_pn:
continue
# Skip if already exists locally
existing = find_file_by_part_number(child_pn)
if existing and existing.exists():
FreeCAD.Console.PrintMessage(f" {child_pn}: already exists at {existing}\n")
# Still recurse — this child may itself be an assembly with missing deps
_pull_dependencies(child_pn, progress_callback)
continue
# Check if this child has a file on the server
try:
latest = _client.latest_file_revision(child_pn)
except Exception:
latest = None
if not latest or not latest.get("file_key"):
FreeCAD.Console.PrintMessage(f" {child_pn}: no file on server, skipping\n")
continue
# Determine destination path
child_desc = entry.get("child_description", "")
dest_path = get_cad_file_path(child_pn, child_desc)
dest_path.parent.mkdir(parents=True, exist_ok=True)
rev_num = latest["revision_number"]
FreeCAD.Console.PrintMessage(f" Pulling {child_pn} rev {rev_num}...\n")
try:
ok = _client._download_file(
child_pn, rev_num, str(dest_path), progress_callback=progress_callback
)
if ok:
pulled.append((child_pn, dest_path))
except Exception as e:
FreeCAD.Console.PrintWarning(f" Failed to pull {child_pn}: {e}\n")
# Recurse into child (it may be a sub-assembly)
_pull_dependencies(child_pn, progress_callback)
return pulled
class Silo_Pull:
"""Download from MinIO / sync from database."""
@@ -1189,6 +1248,17 @@ class Silo_Pull:
FreeCAD.Console.PrintMessage(f"Pulled revision {rev_num} of {part_number}\n")
# Pull assembly dependencies before opening so links resolve
if item.get("item_type") == "assembly":
progress.setLabelText(f"Pulling dependencies for {part_number}...")
progress.setValue(0)
progress.show()
dep_pulled = _pull_dependencies(part_number, progress_callback=on_progress)
progress.setValue(100)
progress.close()
if dep_pulled:
FreeCAD.Console.PrintMessage(f"Pulled {len(dep_pulled)} dependency file(s)\n")
# Close existing document if open, then reopen
if doc and doc.FileName == str(dest_path):
FreeCAD.closeDocument(doc.Name)