Files
mono/artdag/nodes/source.py
giles cc2dcbddd4 Squashed 'core/' content from commit 4957443
git-subtree-dir: core
git-subtree-split: 4957443184ae0eb6323635a90a19acffb3e01d07
2026-02-24 23:09:39 +00:00

63 lines
1.6 KiB
Python

# primitive/nodes/source.py
"""
Source executors: Load media from paths.
Primitives: SOURCE
"""
import logging
import os
import shutil
from pathlib import Path
from typing import Any, Dict, List
from ..dag import NodeType
from ..executor import Executor, register_executor
logger = logging.getLogger(__name__)
@register_executor(NodeType.SOURCE)
class SourceExecutor(Executor):
"""
Load source media from a path.
Config:
path: Path to source file
Creates a symlink to the source file for zero-copy loading.
"""
def execute(
self,
config: Dict[str, Any],
inputs: List[Path],
output_path: Path,
) -> Path:
source_path = Path(config["path"])
if not source_path.exists():
raise FileNotFoundError(f"Source file not found: {source_path}")
output_path.parent.mkdir(parents=True, exist_ok=True)
# Use symlink for zero-copy
if output_path.exists() or output_path.is_symlink():
output_path.unlink()
# Preserve extension from source
actual_output = output_path.with_suffix(source_path.suffix)
if actual_output.exists() or actual_output.is_symlink():
actual_output.unlink()
os.symlink(source_path.resolve(), actual_output)
logger.debug(f"SOURCE: {source_path.name} -> {actual_output}")
return actual_output
def validate_config(self, config: Dict[str, Any]) -> List[str]:
errors = []
if "path" not in config:
errors.append("SOURCE requires 'path' config")
return errors