Scene Manager: request publishes missing on this site

- Request (globe) on casting rows and loaded assets whose latest publish
  is not on this site, and Request Missing for all of them, through the
  new wtdcmds command wtd_request_revisions. Requested publishes show
  "requested, waiting for the download".
- The version picker requests a version that is not on this site.
- A 404 explains that the session is gone or wtdcmds is too old.
- Fake server: car (vehicles) with a publish not on this site,
  wtd_request_revisions and /_test/download; 45 checks.
- Tested live: car_paul modeling.blend v001 -> Requested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
NDemaerschalkandClaude Opus 5.5 committed 2026-10-27 11:45:17 +01:00
1 parent 9ee7710479
commit 9fe38ce58a
8 files changed
+197 -19

No files matched your search

+32 -4
View File
@@ -33,6 +33,8 @@ SERVER_FILE = os.path.join(WORKDIR, "kabaret", "server.json")
config.LIBREFLOW_SERVER_FILE = SERVER_FILE
SHOT = "/melvile/films/f01/sequences/s010/shots/p010"
BOB_FILE = "/melvile/asset_types/main_character/assets/bob/tasks/rigging/files/rig_blend"
CAR = "/melvile/asset_types/vehicles/assets/car"
CAR_FILE = CAR + "/tasks/rigging/files/car_blend"
FAILED = []
@@ -92,7 +94,7 @@ scene.wtd_scene_manager.context_oid = SHOT
pump()
check("shot context validated", sm.context_label(SHOT) == ("shot: f01 / s010 / p010", True))
errors = {a["name"]: a["error"] for a in sm.STATE.casting.get(SHOT, {}).get("assets", [])}
check("casting read", set(errors) == {"bob", "tree", "rock", "lamp", "ghost"}, str(errors))
check("casting read", set(errors) == {"bob", "tree", "rock", "lamp", "car", "ghost"}, str(errors))
print("Load")
bpy.ops.wtd_scene.load()
@@ -112,12 +114,31 @@ bpy.ops.wtd_scene.load()
pump()
check("load again adds nothing", message().startswith("Nothing new to load"), message())
print("Request")
check("car can be requested", sm.missing_files(scene) == [CAR_FILE], str(sm.missing_files(scene)))
bpy.ops.wtd_scene.request()
pump()
check("car v001 requested", message() == "Requested car v001", message())
check("nothing left to request", sm.missing_files(scene) == [])
calls = fake("/_test/calls", {})
check("request sent to Libreflow", ["wtd_request_revisions", {"revision_oids": [CAR_FILE + "/history/revisions/v001"]}] in calls)
fake("/_test/download", {"revision_oid": CAR_FILE + "/history/revisions/v001"})
bpy.ops.wtd_scene.refresh()
pump()
bpy.ops.wtd_scene.load(asset_oid=CAR)
pump()
check("car loaded once downloaded", loaded().get("car", (None,))[0] == "v001", message())
print("Versions")
check("bob is the latest", sm.version_status(bpy.data.libraries["bob"])[0] == "LATEST")
fake("/_test/publish", {"file_oid": BOB_FILE, "name": "v003", "available": False})
sm.refresh_versions()
pump()
check("v003 not on this site: pending", sm.version_status(bpy.data.libraries["bob"])[0] == "PENDING")
bpy.ops.wtd_scene.request(file_oid=BOB_FILE)
pump()
status = sm.version_status(bpy.data.libraries["bob"])
check("v003 requested", status == ("PENDING", "v003 requested, waiting for the download"), str(status))
fake(
"/_test/publish",
{"file_oid": BOB_FILE, "name": "v004", "available": True, "path": os.path.join(WORKDIR, "lib", "bob", "v001", "rig.blend")},
@@ -137,6 +158,13 @@ sm._REVISION_ITEMS[:] = [(r["name"], r["name"], "", "NONE", i) for i, r in enume
bpy.ops.wtd_scene.pick_revision("EXEC_DEFAULT", library="bob", revision="v002")
check("rolled back to v002", loaded()["bob"][0] == "v002")
check("unavailable v003 refused", bpy.ops.wtd_scene.pick_revision("EXEC_DEFAULT", library="bob", revision="v003") == {"CANCELLED"})
fake("/_test/publish", {"file_oid": BOB_FILE, "name": "v005", "available": False})
sm.STATE.revisions[BOB_FILE] = ipc.call("wtd_get_revisions", None, file_oid=BOB_FILE)
sm._REVISION_ITEMS[:] = [(r["name"], r["name"], "", "NONE", i) for i, r in enumerate(sm.STATE.revisions[BOB_FILE])]
bpy.ops.wtd_scene.pick_revision("EXEC_DEFAULT", library="bob", revision="v005")
pump()
check("picking a version not on this site requests it", message() == "Requested bob v005", message())
check("still on v002", loaded()["bob"][0] == "v002")
print("Remove")
bpy.ops.wtd_scene.remove(instance="COL_bob.001")
@@ -148,10 +176,10 @@ bpy.ops.wtd_scene.remove(selected=True)
check("selected instance removed", loaded()["tree"][1] == [])
bpy.ops.wtd_scene.remove("EXEC_DEFAULT", library="rock")
check("whole asset removed", "rock" not in bpy.data.libraries)
check("its indirect library removed too", set(bpy.data.libraries.keys()) == {"bob", "tree"}, str(bpy.data.libraries.keys()))
check("its indirect library removed too", set(bpy.data.libraries.keys()) == {"bob", "car", "tree"}, str(bpy.data.libraries.keys()))
bpy.ops.wtd_scene.load()
pump()
check("load restores what is missing", {k: len(v[1]) for k, v in loaded().items()} == {"bob": 2, "rock": 1, "tree": 1})
check("load restores what is missing", {k: len(v[1]) for k, v in loaded().items()} == {"bob": 2, "car": 1, "rock": 1, "tree": 1})
print("Ambiguous file")
try:
@@ -188,7 +216,7 @@ path = os.path.join(WORKDIR, "scene_manager_test.blend")
bpy.ops.wm.save_as_mainfile(filepath=path)
bpy.ops.wm.open_mainfile(filepath=path)
sm._on_load_post()
check("everything found after reopening", set(loaded()) == {"bob", "lamp", "rock", "tree"})
check("everything found after reopening", set(loaded()) == {"bob", "car", "lamp", "rock", "tree"})
sm.connect(bpy.context.scene)
pump()
check("versions checked again", sm.version_status(bpy.data.libraries["bob"])[0] == "UPDATE")