feat(tower): routines staging push and delta
Add compute_delta_named, routines_staging_files, compute_routines_delta so routines.json goes last in the push delta. Generalize push_file with subdir param (default podcasts, compat preserved). Fix test_delta.py: compute_delta lives in lisael_content, not lisael_server.
This commit is contained in:
+20
-3
@@ -385,9 +385,26 @@ def compute_delta(staging, have):
|
||||
files.append("manifest.json")
|
||||
return files
|
||||
|
||||
def push_file(ip, name):
|
||||
data = open(os.path.join(STAGING, name), "rb").read()
|
||||
url = f"http://{ip}:{BOX_PORT}/put?name=podcasts/{name}"
|
||||
def compute_delta_named(staging, have, manifest_name):
|
||||
haveset = set(have)
|
||||
files = [f for f in staging if f != manifest_name and f not in haveset]
|
||||
if files and manifest_name in staging:
|
||||
files.append(manifest_name)
|
||||
return files
|
||||
|
||||
def routines_staging_files():
|
||||
if not os.path.isdir(STAGING_ROUTINES):
|
||||
return []
|
||||
return sorted(f for f in os.listdir(STAGING_ROUTINES)
|
||||
if not f.startswith(".") and f != ".cache.json")
|
||||
|
||||
def compute_routines_delta(have):
|
||||
return compute_delta_named(routines_staging_files(), have, "routines.json")
|
||||
|
||||
def push_file(ip, name, subdir="podcasts"):
|
||||
src_dir = STAGING_ROUTINES if subdir == "routines" else STAGING
|
||||
data = open(os.path.join(src_dir, name), "rb").read()
|
||||
url = f"http://{ip}:{BOX_PORT}/put?name={subdir}/{name}"
|
||||
with urllib.request.urlopen(urllib.request.Request(url, data=data, method="POST"),
|
||||
timeout=300) as r:
|
||||
return r.status
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
from lisael_server import compute_delta
|
||||
from lisael_content import compute_delta
|
||||
|
||||
def test_delta():
|
||||
stg = ["oli_01.m4a", "oli.bin", "bestioles_01.mp3", "manifest.json"]
|
||||
|
||||
@@ -139,6 +139,50 @@ def test_build_routine_manifest_regen_on_emoji_change():
|
||||
if os.path.exists(C.ROUTINES_JSON):
|
||||
os.remove(C.ROUTINES_JSON)
|
||||
|
||||
def test_routines_delta_manifest_last():
|
||||
os.makedirs(C.STAGING_ROUTINES, exist_ok=True)
|
||||
for f in ("matin.bin", "matin_01.bin", "matin_01.mp3", "routines.json"):
|
||||
open(os.path.join(C.STAGING_ROUTINES, f), "wb").close()
|
||||
d = C.compute_routines_delta([])
|
||||
assert d[-1] == "routines.json" # manifest always last
|
||||
assert set(d[:-1]) == {"matin.bin", "matin_01.bin", "matin_01.mp3"}
|
||||
# box already has assets -> only manifest moves if assets changed; here all present
|
||||
assert C.compute_routines_delta(["matin.bin", "matin_01.bin", "matin_01.mp3"]) == []
|
||||
|
||||
|
||||
def test_push_file_url_construction():
|
||||
"""push_file builds the correct URL with subdir in the path."""
|
||||
captured = {}
|
||||
class FakeResp:
|
||||
status = 200
|
||||
def __enter__(self): return self
|
||||
def __exit__(self, *a): pass
|
||||
|
||||
def fake_urlopen(req, timeout=None):
|
||||
captured["url"] = req.full_url
|
||||
return FakeResp()
|
||||
|
||||
orig = C.urllib.request.urlopen
|
||||
try:
|
||||
C.urllib.request.urlopen = fake_urlopen
|
||||
# Create dummy files in each staging dir
|
||||
os.makedirs(C.STAGING, exist_ok=True)
|
||||
os.makedirs(C.STAGING_ROUTINES, exist_ok=True)
|
||||
open(os.path.join(C.STAGING, "test.mp3"), "wb").close()
|
||||
open(os.path.join(C.STAGING_ROUTINES, "routines.json"), "wb").close()
|
||||
# default subdir = podcasts
|
||||
C.push_file("127.0.0.1", "test.mp3")
|
||||
assert "podcasts/test.mp3" in captured["url"]
|
||||
# explicit routines subdir
|
||||
C.push_file("127.0.0.1", "routines.json", subdir="routines")
|
||||
assert "routines/routines.json" in captured["url"]
|
||||
# explicit podcasts subdir same as default
|
||||
C.push_file("127.0.0.1", "test.mp3", subdir="podcasts")
|
||||
assert "podcasts/test.mp3" in captured["url"]
|
||||
finally:
|
||||
C.urllib.request.urlopen = orig
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
for name, fn in sorted(globals().items()):
|
||||
if name.startswith("test_"):
|
||||
|
||||
Reference in New Issue
Block a user