Files
Claude 2040792699 Refactor to v0.2.0: context chaining, new output nodes, simplified switch
Major changes:
- PD Project Context: accepts incoming context for override chaining,
  adds auto_increment_version (persistent via widget state, like seed)
- New PD Custom Context: 5 user-defined key/value token pairs
- Replace PD Output Namer + PD Network Output with:
  - PD Output Relative (saves to ComfyUI output dir)
  - PD Output Absolute (saves to absolute/UNC paths)
  Both show a token reference panel via JS after execution
- PD Switch simplified to single-channel with auto-growing inputs (2-8)
  managed by JS extension (onConnectionsChange pattern)
- 💭 emoji prefix on all node display names (with Windows fallback)
- Consolidated all JS extensions into web/pipedream.js
- Backward compat: PDOutputNamer/PDNetworkOutput aliases preserved

https://claude.ai/code/session_015UV4rjSvFatMiNtKhd1sT3
2026-04-03 06:03:18 +00:00

97 lines
2.8 KiB
Python

"""
Shared utility helpers for Pipedream nodes.
Path normalization, directory creation, image saving, and other small
helpers that multiple node modules rely on.
"""
import os
import sys
def normalize_path(path: str) -> str:
"""
Normalize slashes for the current platform.
On Windows, forward slashes become backslashes and UNC prefixes
(``\\\\server\\share``) are preserved. On POSIX, backslashes become
forward slashes. Trailing separators are stripped.
"""
if sys.platform == "win32":
path = path.replace("/", "\\")
else:
path = path.replace("\\", "/")
return path.rstrip(os.sep)
def ensure_directory(path: str, create: bool = True) -> str:
"""
Return the directory portion of *path*, optionally creating it.
Raises ``OSError`` with a descriptive message on failure.
"""
directory = os.path.dirname(path)
if not directory:
return directory
if create and not os.path.isdir(directory):
try:
os.makedirs(directory, exist_ok=True)
except OSError as exc:
raise OSError(
f"[Pipedream] Failed to create directory '{directory}': {exc}"
) from exc
return directory
def save_image_batch(images, full_path: str, overwrite: bool = False) -> list[str]:
"""
Save a batch of ComfyUI IMAGE tensors to disk.
*images* is a tensor of shape ``(B, H, W, C)`` with float32 values in
``[0, 1]``. When the batch size is greater than one, a zero-padded
index is appended before the extension (e.g. ``name_0001.png``).
Returns a list of successfully written file paths.
"""
import numpy as np
from PIL import Image
ext = os.path.splitext(full_path)[1].lower()
batch_size = images.shape[0]
written: list[str] = []
for i in range(batch_size):
if batch_size > 1:
base, extension = os.path.splitext(full_path)
out_path = f"{base}_{i:04d}{extension}"
else:
out_path = full_path
if not overwrite and os.path.exists(out_path):
print(
f"[Pipedream] Error: file already exists and overwrite is "
f"disabled: '{out_path}'",
file=sys.stderr,
)
continue
img_array = (images[i].cpu().numpy() * 255).clip(0, 255).astype(np.uint8)
img = Image.fromarray(img_array)
save_kwargs: dict = {}
if ext in (".jpg", ".jpeg"):
save_kwargs["quality"] = 95
elif ext == ".webp":
save_kwargs["quality"] = 95
try:
img.save(out_path, **save_kwargs)
written.append(out_path)
except Exception as exc:
print(
f"[Pipedream] Error: failed to write '{out_path}': {exc}",
file=sys.stderr,
)
return written