fd
Some checks failed
smoke-mm / Install & smoke test mm --help (push) Has been cancelled

This commit is contained in:
2025-12-27 03:13:16 -08:00
parent a595453a9b
commit 71b542ae91
8 changed files with 1069 additions and 57 deletions

173
MPV/mpv_lua_api.py Normal file
View File

@@ -0,0 +1,173 @@
"""MPV Lua API - Clean interface for Lua scripts to call Python functions.
This module provides a streamlined way for mpv Lua scripts to execute Python
functions and commands without relying on the broken observe_property IPC pattern.
Instead, Lua calls Python CLI directly via subprocess, and Python returns JSON
responses that Lua can parse.
"""
import json
import logging
import sys
from pathlib import Path
from typing import Any, Dict, Optional
# Add parent directory to path so we can import CLI, pipeline, cmdlet_catalog from root
_SCRIPT_DIR = Path(__file__).parent
_ROOT_DIR = _SCRIPT_DIR.parent
if str(_ROOT_DIR) not in sys.path:
sys.path.insert(0, str(_ROOT_DIR))
def setup_logging(log_file: Optional[Path] = None) -> logging.Logger:
"""Setup logging for MPV API calls."""
logger = logging.getLogger("mpv-lua-api")
logger.setLevel(logging.DEBUG)
if not logger.handlers:
if log_file:
handler = logging.FileHandler(str(log_file), encoding="utf-8")
else:
handler = logging.StreamHandler(sys.stderr)
formatter = logging.Formatter(
"[%(asctime)s][%(levelname)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
def log_to_helper(msg: str, log_file: Optional[Path] = None) -> None:
"""Log a message that will appear in the helper log."""
if log_file:
with open(log_file, "a", encoding="utf-8") as f:
f.write(f"[lua] {msg}\n")
def execute_pipeline(
pipeline_cmd: str,
log_file: Optional[Path] = None,
dry_run: bool = False,
) -> Dict[str, Any]:
"""Execute a pipeline command and return result as JSON.
Args:
pipeline_cmd: Pipeline command string (e.g. "trim-file -path ... | add-file -store ...")
log_file: Optional path to helper log file for logging
dry_run: If True, log but don't execute
Returns:
JSON object with keys: success, stdout, stderr, error, returncode
"""
try:
if log_file:
log_to_helper(f"[api] execute_pipeline cmd={pipeline_cmd}", log_file)
if dry_run:
return {
"success": True,
"stdout": "",
"stderr": "DRY RUN - command not executed",
"error": None,
"returncode": 0,
"cmd": pipeline_cmd,
}
# Call the CLI directly as subprocess
import subprocess
import shlex
# Parse the pipeline command into separate arguments
cmd_args = shlex.split(pipeline_cmd)
result = subprocess.run(
[sys.executable, "-m", "CLI"] + cmd_args,
capture_output=True,
text=True,
cwd=str(_ROOT_DIR),
env={**dict(__import__('os').environ), "MEDEIA_MPV_CALLER": "lua"},
)
if log_file:
log_to_helper(
f"[api] result returncode={result.returncode} len_stdout={len(result.stdout or '')} len_stderr={len(result.stderr or '')}",
log_file
)
if result.stderr:
log_to_helper(f"[api] stderr: {result.stderr[:500]}", log_file)
return {
"success": result.returncode == 0,
"stdout": result.stdout or "",
"stderr": result.stderr or "",
"error": None if result.returncode == 0 else result.stderr,
"returncode": result.returncode,
"cmd": pipeline_cmd,
}
except Exception as exc:
msg = f"{type(exc).__name__}: {exc}"
if log_file:
log_to_helper(f"[api] exception {msg}", log_file)
return {
"success": False,
"stdout": "",
"stderr": str(exc),
"error": msg,
"returncode": 1,
"cmd": pipeline_cmd,
}
def handle_api_request(request_json: str, log_file: Optional[Path] = None) -> str:
"""Handle an API request from Lua and return JSON response.
Request format:
{
"cmd": "execute_pipeline",
"pipeline": "trim-file -path ... | add-file -store ...",
...
}
Response format: JSON with result of the operation.
"""
try:
request = json.loads(request_json)
cmd = request.get("cmd")
if cmd == "execute_pipeline":
pipeline_cmd = request.get("pipeline", "")
result = execute_pipeline(pipeline_cmd, log_file)
return json.dumps(result)
else:
return json.dumps({
"success": False,
"error": f"Unknown command: {cmd}",
})
except Exception as exc:
return json.dumps({
"success": False,
"error": f"{type(exc).__name__}: {exc}",
})
if __name__ == "__main__":
# When called from Lua via subprocess:
# python mpv_lua_api.py <json-request>
if len(sys.argv) < 2:
print(json.dumps({"success": False, "error": "No request provided"}))
sys.exit(1)
request_json = sys.argv[1]
log_file = Path(sys.argv[2]) if len(sys.argv) > 2 else None
response = handle_api_request(request_json, log_file)
print(response)