Files
tono/backend/nodes/note.py
2026-04-01 23:16:46 -07:00

77 lines
2.1 KiB
Python

from __future__ import annotations
import re
from pathlib import Path
from backend.node_registry import register_node
from backend.data_types import DataTable
from backend.nodes.helpers import _import_ibw_loader
def _parse_ibw_note(note_bytes: bytes) -> list[dict]:
try:
text = note_bytes.decode("utf-8", errors="replace")
except Exception:
return []
rows = []
for line in text.splitlines():
line = line.strip()
if not line:
continue
match = re.match(r'^([^:=]+)[=:](.+)$', line)
if not match:
continue
key = match.group(1).strip()
value = match.group(2).strip()
if not key:
continue
rows.append({"key": key, "value": value})
return rows
@register_node(display_name="Note")
class Note:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"filename": ("FILE_PICKER", {"default": "", "hide_when_input_connected": "path"}),
},
"optional": {
"path": ("FILE_PATH", {"label": "path"}),
},
}
OUTPUTS = (
('DATA_TABLE', 'note'),
)
FUNCTION = "load"
DESCRIPTION = (
"Read the Note metadata from an .ibw file and display all entries "
"as a table of key/value pairs."
)
def load(self, filename: str = "", path: str | None = None) -> tuple:
selected = str(path).strip() if path is not None else str(filename).strip()
if not selected:
raise ValueError("No file selected.")
path_obj = Path(selected)
if not path_obj.exists():
raise FileNotFoundError(f"File not found: {path_obj}")
if path_obj.suffix.lower() != ".ibw":
raise ValueError(f"Expected an .ibw file, got: {path_obj.suffix}")
load_ibw = _import_ibw_loader()
wave = load_ibw(str(path_obj))
note_bytes = wave["wave"].get("note", b"") or b""
rows = _parse_ibw_note(note_bytes)
if not rows:
raise ValueError("No metadata found in the .ibw note.")
return (DataTable(rows),)