refactor: flatten sound storage
This commit is contained in:
@@ -4,7 +4,7 @@ from pathlib import Path
|
||||
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
SOUNDS_DIR = REPO_ROOT / "sounds" / "bundled"
|
||||
SOUNDS_DIR = REPO_ROOT / "sounds"
|
||||
|
||||
|
||||
def wav_peak_amplitude(path: Path) -> int:
|
||||
|
||||
@@ -53,7 +53,7 @@ def test_build_global_completion_payload_uses_global_event_kind():
|
||||
|
||||
assert payload.event_kind == "global"
|
||||
assert payload.status == "failure"
|
||||
assert payload.sound_id == "bundled:global-failure.wav"
|
||||
assert payload.sound_id == "global-failure.wav"
|
||||
|
||||
|
||||
def test_resolve_global_completion_payload_normalizes_error_status():
|
||||
@@ -73,7 +73,7 @@ def test_resolve_global_completion_payload_normalizes_error_status():
|
||||
|
||||
assert payload is not None
|
||||
assert payload.status == "failure"
|
||||
assert payload.sound_id == "custom:uploaded.wav"
|
||||
assert payload.sound_id == "uploaded.wav"
|
||||
assert payload.volume == 0.45
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ def test_reinstall_updates_callbacks_after_noop_install():
|
||||
assert result == "done"
|
||||
assert emitted_payloads[0].event_kind == "global"
|
||||
assert emitted_payloads[0].status == "success"
|
||||
assert emitted_payloads[0].sound_id == "bundled:global-success.wav"
|
||||
assert emitted_payloads[0].sound_id == "global-success.wav"
|
||||
assert emitted_payloads[0].volume == 0.65
|
||||
assert len(emitted_payloads) == 1
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ def test_notification_payload_includes_status_and_sound_id():
|
||||
)
|
||||
|
||||
assert payload.status == "failure"
|
||||
assert payload.sound_id == "bundled:buzz.wav"
|
||||
assert payload.sound_id == "buzz.wav"
|
||||
assert payload.volume == 0.8
|
||||
assert payload.source == "global"
|
||||
|
||||
@@ -31,7 +31,7 @@ def test_notification_policy_prefers_node_override():
|
||||
node_overrides={"success_sound": "node-success.wav"},
|
||||
)
|
||||
|
||||
assert payload.sound_id == "bundled:node-success.wav"
|
||||
assert payload.sound_id == "node-success.wav"
|
||||
|
||||
|
||||
def test_invalid_custom_sound_does_not_fallback():
|
||||
@@ -52,11 +52,11 @@ def test_resolve_sound_id_uses_global_value_without_override():
|
||||
global_settings={"failure_sound": "global-failure.wav"},
|
||||
node_overrides=None,
|
||||
)
|
||||
== "bundled:global-failure.wav"
|
||||
== "global-failure.wav"
|
||||
)
|
||||
|
||||
|
||||
def test_notification_policy_preserves_source_aware_sound_id():
|
||||
def test_notification_policy_normalizes_legacy_prefixed_sound_id():
|
||||
payload = build_notification_payload(
|
||||
event_kind="node",
|
||||
status="failure",
|
||||
@@ -64,4 +64,4 @@ def test_notification_policy_preserves_source_aware_sound_id():
|
||||
node_overrides={"failure_sound": "custom:alert.wav"},
|
||||
)
|
||||
|
||||
assert payload.sound_id == "custom:alert.wav"
|
||||
assert payload.sound_id == "alert.wav"
|
||||
|
||||
@@ -130,5 +130,5 @@ def test_ping_node_execute_emits_runtime_notification_when_enabled():
|
||||
assert output is not None
|
||||
assert len(emitted_payloads) == 1
|
||||
assert emitted_payloads[0].status == "success"
|
||||
assert emitted_payloads[0].sound_id == "bundled:ding.wav"
|
||||
assert emitted_payloads[0].sound_id == "ding.wav"
|
||||
assert emitted_payloads[0].volume == 0.35
|
||||
|
||||
@@ -20,124 +20,102 @@ from comfyui_ping.sounds import MAX_UPLOAD_BYTES
|
||||
|
||||
|
||||
def test_build_sound_catalog_payload_returns_sound_list():
|
||||
payload = build_sound_catalog_payload(
|
||||
bundled=["ping-success.wav"],
|
||||
custom=["custom.wav"],
|
||||
)
|
||||
payload = build_sound_catalog_payload(["ping-success.wav", "custom.wav"])
|
||||
|
||||
assert payload == {
|
||||
"sounds": [
|
||||
{"name": "ping-success.wav", "source": "bundled"},
|
||||
{"name": "custom.wav", "source": "custom"},
|
||||
{"name": "ping-success.wav"},
|
||||
{"name": "custom.wav"},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def test_list_sounds_route_payload_returns_structured_catalog(tmp_path: Path):
|
||||
bundled_dir = tmp_path / "bundled"
|
||||
custom_dir = tmp_path / "custom"
|
||||
sounds_dir = tmp_path / "sounds"
|
||||
legacy_custom_dir = tmp_path / "legacy"
|
||||
bundled_dir.mkdir()
|
||||
custom_dir.mkdir()
|
||||
(bundled_dir / "ping-success.wav").write_bytes(b"bundled")
|
||||
(custom_dir / "custom.wav").write_bytes(b"custom")
|
||||
sounds_dir.mkdir()
|
||||
(sounds_dir / "ping-success.wav").write_bytes(b"bundled")
|
||||
(sounds_dir / "custom.wav").write_bytes(b"custom")
|
||||
|
||||
from comfyui_ping.routes import list_sounds_route_payload
|
||||
|
||||
payload = list_sounds_route_payload(
|
||||
bundled_dir=bundled_dir,
|
||||
custom_dir=custom_dir,
|
||||
sounds_dir=sounds_dir,
|
||||
legacy_custom_dir=legacy_custom_dir,
|
||||
)
|
||||
|
||||
assert payload == {
|
||||
"sounds": [
|
||||
{"name": "ping-success.wav", "source": "bundled"},
|
||||
{"name": "custom.wav", "source": "custom"},
|
||||
{"name": "custom.wav"},
|
||||
{"name": "ping-success.wav"},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def test_resolve_sound_path_uses_requested_source():
|
||||
bundled_dir = REPO_ROOT / "sounds" / "bundled"
|
||||
custom_dir = REPO_ROOT / "sounds" / "custom"
|
||||
def test_resolve_sound_path_uses_flat_directory():
|
||||
sounds_dir = REPO_ROOT / "sounds"
|
||||
legacy_custom_dir = REPO_ROOT / "input" / "ping-unused-test"
|
||||
custom_dir.mkdir(parents=True, exist_ok=True)
|
||||
custom_file = custom_dir / "ping-success.wav"
|
||||
custom_file = sounds_dir / "temp-flat-route-test.wav"
|
||||
custom_file.write_bytes(b"custom")
|
||||
|
||||
try:
|
||||
bundled_path = resolve_sound_path(
|
||||
filename="ping-success.wav",
|
||||
source="bundled",
|
||||
bundled_dir=bundled_dir,
|
||||
custom_dir=custom_dir,
|
||||
legacy_custom_dir=legacy_custom_dir,
|
||||
)
|
||||
custom_path = resolve_sound_path(
|
||||
filename="ping-success.wav",
|
||||
source="custom",
|
||||
bundled_dir=bundled_dir,
|
||||
custom_dir=custom_dir,
|
||||
filename="temp-flat-route-test.wav",
|
||||
sounds_dir=sounds_dir,
|
||||
legacy_custom_dir=legacy_custom_dir,
|
||||
)
|
||||
finally:
|
||||
custom_file.unlink(missing_ok=True)
|
||||
|
||||
assert bundled_path == bundled_dir / "ping-success.wav"
|
||||
assert custom_path == custom_file
|
||||
|
||||
|
||||
def test_list_sounds_route_payload_migrates_legacy_custom_uploads(tmp_path: Path):
|
||||
bundled_dir = tmp_path / "sounds" / "bundled"
|
||||
custom_dir = tmp_path / "sounds" / "custom"
|
||||
sounds_dir = tmp_path / "sounds"
|
||||
legacy_custom_dir = tmp_path / "input" / "ping"
|
||||
bundled_dir.mkdir(parents=True)
|
||||
sounds_dir.mkdir(parents=True)
|
||||
legacy_custom_dir.mkdir(parents=True)
|
||||
(bundled_dir / "ping-success.wav").write_bytes(b"bundled")
|
||||
(sounds_dir / "ping-success.wav").write_bytes(b"bundled")
|
||||
(legacy_custom_dir / "ringtone5.mp3").write_bytes(b"legacy")
|
||||
|
||||
from comfyui_ping.routes import list_sounds_route_payload
|
||||
|
||||
payload = list_sounds_route_payload(
|
||||
bundled_dir=bundled_dir,
|
||||
custom_dir=custom_dir,
|
||||
sounds_dir=sounds_dir,
|
||||
legacy_custom_dir=legacy_custom_dir,
|
||||
)
|
||||
|
||||
assert payload == {
|
||||
"sounds": [
|
||||
{"name": "ping-success.wav", "source": "bundled"},
|
||||
{"name": "ringtone5.mp3", "source": "custom"},
|
||||
{"name": "ping-success.wav"},
|
||||
{"name": "ringtone5.mp3"},
|
||||
],
|
||||
}
|
||||
assert (custom_dir / "ringtone5.mp3").read_bytes() == b"legacy"
|
||||
assert (sounds_dir / "ringtone5.mp3").read_bytes() == b"legacy"
|
||||
assert (legacy_custom_dir / "ringtone5.mp3").exists() is False
|
||||
|
||||
|
||||
def test_list_sounds_route_payload_skips_legacy_files_promoted_to_bundled(
|
||||
def test_list_sounds_route_payload_skips_duplicate_legacy_files(
|
||||
tmp_path: Path,
|
||||
):
|
||||
bundled_dir = tmp_path / "sounds" / "bundled"
|
||||
custom_dir = tmp_path / "sounds" / "custom"
|
||||
sounds_dir = tmp_path / "sounds"
|
||||
legacy_custom_dir = tmp_path / "input" / "ping"
|
||||
bundled_dir.mkdir(parents=True)
|
||||
sounds_dir.mkdir(parents=True)
|
||||
legacy_custom_dir.mkdir(parents=True)
|
||||
(bundled_dir / "ping-ringtone.wav").write_bytes(b"bundled")
|
||||
(sounds_dir / "ping-ringtone.wav").write_bytes(b"bundled")
|
||||
(legacy_custom_dir / "ping-ringtone.wav").write_bytes(b"legacy")
|
||||
|
||||
from comfyui_ping.routes import list_sounds_route_payload
|
||||
|
||||
payload = list_sounds_route_payload(
|
||||
bundled_dir=bundled_dir,
|
||||
custom_dir=custom_dir,
|
||||
sounds_dir=sounds_dir,
|
||||
legacy_custom_dir=legacy_custom_dir,
|
||||
)
|
||||
|
||||
assert payload == {
|
||||
"sounds": [{"name": "ping-ringtone.wav", "source": "bundled"}],
|
||||
"sounds": [{"name": "ping-ringtone.wav"}],
|
||||
}
|
||||
assert (custom_dir / "ping-ringtone.wav").exists() is False
|
||||
assert (sounds_dir / "ping-ringtone.wav").read_bytes() == b"bundled"
|
||||
assert (legacy_custom_dir / "ping-ringtone.wav").exists() is False
|
||||
|
||||
|
||||
@@ -146,7 +124,7 @@ def test_save_uploaded_sound_rejects_invalid_extension(tmp_path: Path):
|
||||
save_uploaded_sound(
|
||||
filename="not-a-sound.txt",
|
||||
data=b"bad",
|
||||
custom_dir=tmp_path,
|
||||
sounds_dir=tmp_path,
|
||||
legacy_custom_dir=tmp_path / "legacy",
|
||||
)
|
||||
except ValueError as exc:
|
||||
@@ -160,7 +138,7 @@ def test_save_uploaded_sound_rejects_oversized_file(tmp_path: Path):
|
||||
save_uploaded_sound(
|
||||
filename="too-large.wav",
|
||||
data=b"0" * (MAX_UPLOAD_BYTES + 1),
|
||||
custom_dir=tmp_path / "custom",
|
||||
sounds_dir=tmp_path / "sounds",
|
||||
legacy_custom_dir=tmp_path / "legacy",
|
||||
)
|
||||
except ValueError as exc:
|
||||
@@ -169,58 +147,33 @@ def test_save_uploaded_sound_rejects_oversized_file(tmp_path: Path):
|
||||
raise AssertionError("save_uploaded_sound should reject oversized files")
|
||||
|
||||
|
||||
def test_save_uploaded_sound_rejects_bundled_name_collision(tmp_path: Path):
|
||||
bundled_dir = tmp_path / "bundled"
|
||||
def test_save_uploaded_sound_rejects_existing_filename(tmp_path: Path):
|
||||
sounds_dir = tmp_path / "sounds"
|
||||
legacy_custom_dir = tmp_path / "legacy"
|
||||
bundled_dir.mkdir()
|
||||
(bundled_dir / "ping-success.wav").write_bytes(b"bundled")
|
||||
sounds_dir.mkdir()
|
||||
(sounds_dir / "ping-success.wav").write_bytes(b"existing")
|
||||
|
||||
try:
|
||||
save_uploaded_sound(
|
||||
filename="ping-success.wav",
|
||||
data=b"custom",
|
||||
custom_dir=tmp_path / "custom",
|
||||
bundled_dir=bundled_dir,
|
||||
sounds_dir=sounds_dir,
|
||||
legacy_custom_dir=legacy_custom_dir,
|
||||
)
|
||||
except ValueError as exc:
|
||||
assert str(exc) == "Filename collides with bundled sound"
|
||||
assert str(exc) == "Filename already exists"
|
||||
else:
|
||||
raise AssertionError("save_uploaded_sound should reject bundled name collisions")
|
||||
|
||||
|
||||
def test_save_uploaded_sound_rejects_existing_custom_filename(tmp_path: Path):
|
||||
custom_dir = tmp_path / "custom"
|
||||
legacy_custom_dir = tmp_path / "legacy"
|
||||
custom_dir.mkdir()
|
||||
(custom_dir / "custom.wav").write_bytes(b"old")
|
||||
|
||||
try:
|
||||
save_uploaded_sound(
|
||||
filename="custom.wav",
|
||||
data=b"new",
|
||||
custom_dir=custom_dir,
|
||||
bundled_dir=tmp_path / "bundled",
|
||||
legacy_custom_dir=legacy_custom_dir,
|
||||
)
|
||||
except ValueError as exc:
|
||||
assert str(exc) == "Filename already exists in custom sounds"
|
||||
else:
|
||||
raise AssertionError("save_uploaded_sound should reject existing custom filenames")
|
||||
raise AssertionError("save_uploaded_sound should reject existing filenames")
|
||||
|
||||
|
||||
def test_resolve_sound_path_rejects_non_files(tmp_path: Path):
|
||||
bundled_dir = tmp_path / "bundled"
|
||||
custom_dir = tmp_path / "custom"
|
||||
sounds_dir = tmp_path / "sounds"
|
||||
legacy_custom_dir = tmp_path / "legacy"
|
||||
(bundled_dir / "ping-success.wav").mkdir(parents=True)
|
||||
custom_dir.mkdir()
|
||||
(sounds_dir / "ping-success.wav").mkdir(parents=True)
|
||||
|
||||
path = resolve_sound_path(
|
||||
filename="ping-success.wav",
|
||||
source="bundled",
|
||||
bundled_dir=bundled_dir,
|
||||
custom_dir=custom_dir,
|
||||
sounds_dir=sounds_dir,
|
||||
legacy_custom_dir=legacy_custom_dir,
|
||||
)
|
||||
|
||||
@@ -293,18 +246,15 @@ class FakeRequest:
|
||||
|
||||
def test_attach_sound_routes_registers_live_handlers(tmp_path: Path):
|
||||
routes = FakeRoutes()
|
||||
bundled_dir = tmp_path / "bundled"
|
||||
custom_dir = tmp_path / "custom"
|
||||
sounds_dir = tmp_path / "sounds"
|
||||
legacy_custom_dir = tmp_path / "legacy"
|
||||
bundled_dir.mkdir()
|
||||
custom_dir.mkdir()
|
||||
(bundled_dir / "ping-success.wav").write_bytes(b"bundled")
|
||||
sounds_dir.mkdir()
|
||||
(sounds_dir / "ping-success.wav").write_bytes(b"bundled")
|
||||
|
||||
attach_sound_routes(
|
||||
routes=routes,
|
||||
web_module=FakeWeb,
|
||||
bundled_dir=bundled_dir,
|
||||
custom_dir=custom_dir,
|
||||
sounds_dir=sounds_dir,
|
||||
legacy_custom_dir=legacy_custom_dir,
|
||||
)
|
||||
|
||||
@@ -315,7 +265,7 @@ def test_attach_sound_routes_registers_live_handlers(tmp_path: Path):
|
||||
list_handler = routes.handlers[("GET", SOUND_CATALOG_ROUTE)]
|
||||
list_response = run(list_handler(FakeRequest()))
|
||||
assert list_response.payload == {
|
||||
"sounds": [{"name": "ping-success.wav", "source": "bundled"}]
|
||||
"sounds": [{"name": "ping-success.wav"}]
|
||||
}
|
||||
|
||||
upload_handler = routes.handlers[("POST", SOUND_UPLOAD_ROUTE)]
|
||||
@@ -334,8 +284,8 @@ def test_attach_sound_routes_registers_live_handlers(tmp_path: Path):
|
||||
assert upload_response.status == 201
|
||||
assert upload_response.payload == {
|
||||
"sounds": [
|
||||
{"name": "ping-success.wav", "source": "bundled"},
|
||||
{"name": "custom.wav", "source": "custom"},
|
||||
{"name": "custom.wav"},
|
||||
{"name": "ping-success.wav"},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -344,10 +294,9 @@ def test_attach_sound_routes_registers_live_handlers(tmp_path: Path):
|
||||
serve_handler(
|
||||
FakeRequest(
|
||||
match_info={
|
||||
"source": "custom",
|
||||
"filename": "custom.wav",
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
assert serve_response.path == custom_dir / "custom.wav"
|
||||
assert serve_response.path == sounds_dir / "custom.wav"
|
||||
|
||||
@@ -12,15 +12,12 @@ from comfyui_ping.sounds import (
|
||||
)
|
||||
|
||||
|
||||
def test_list_sounds_returns_bundled_and_custom_entries():
|
||||
sounds = list_available_sounds(
|
||||
bundled=["ping-success.wav"],
|
||||
custom=["my.wav"],
|
||||
)
|
||||
def test_list_sounds_returns_flat_entries():
|
||||
sounds = list_available_sounds(["ping-success.wav", "my.wav"])
|
||||
|
||||
assert sounds == [
|
||||
{"name": "ping-success.wav", "source": "bundled"},
|
||||
{"name": "my.wav", "source": "custom"},
|
||||
{"name": "ping-success.wav"},
|
||||
{"name": "my.wav"},
|
||||
]
|
||||
|
||||
|
||||
@@ -35,21 +32,18 @@ def test_accepts_expected_audio_extensions():
|
||||
|
||||
|
||||
def test_bundled_sound_files_exist():
|
||||
assert (REPO_ROOT / "sounds" / "bundled" / "ping-success.wav").exists()
|
||||
assert (REPO_ROOT / "sounds" / "bundled" / "ping-failure.wav").exists()
|
||||
assert (REPO_ROOT / "sounds" / "bundled" / "ping-ringtone.wav").exists()
|
||||
assert (REPO_ROOT / "sounds" / "bundled" / "notification-soft.wav").exists()
|
||||
assert (REPO_ROOT / "sounds" / "bundled" / "beep-ping.wav").exists()
|
||||
assert (REPO_ROOT / "sounds" / "bundled" / "harmonic-beep.wav").exists()
|
||||
assert (REPO_ROOT / "sounds" / "ping-success.wav").exists()
|
||||
assert (REPO_ROOT / "sounds" / "ping-failure.wav").exists()
|
||||
assert (REPO_ROOT / "sounds" / "ping-ringtone.wav").exists()
|
||||
assert (REPO_ROOT / "sounds" / "notification-soft.wav").exists()
|
||||
assert (REPO_ROOT / "sounds" / "beep-ping.wav").exists()
|
||||
assert (REPO_ROOT / "sounds" / "harmonic-beep.wav").exists()
|
||||
|
||||
|
||||
def test_catalog_preserves_duplicate_names_by_source():
|
||||
sounds = list_available_sounds(
|
||||
bundled=["ping-success.wav"],
|
||||
custom=["ping-success.wav"],
|
||||
)
|
||||
def test_catalog_preserves_duplicate_names():
|
||||
sounds = list_available_sounds(["ping-success.wav", "ping-success.wav"])
|
||||
|
||||
assert sounds == [
|
||||
{"name": "ping-success.wav", "source": "bundled"},
|
||||
{"name": "ping-success.wav", "source": "custom"},
|
||||
{"name": "ping-success.wav"},
|
||||
{"name": "ping-success.wav"},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user