Files
gniza4linux/tui/backend.py
shuki 587149f062 Add Python Textual TUI replacing gum-based bash TUI
New tui/ package with 14 screens (main menu, backup, restore, targets,
remotes, snapshots, verify, retention, schedule, logs, settings, wizard),
3 custom widgets (folder picker, confirm dialog, operation log), async
backend wrapper, pure-Python config parser, and TCSS theme.

bin/gniza now launches Textual TUI when available, falls back to gum.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:39:48 +02:00

41 lines
1.1 KiB
Python

import asyncio
import os
from pathlib import Path
def _gniza_bin() -> str:
gniza_dir = os.environ.get("GNIZA_DIR", "")
if gniza_dir:
return str(Path(gniza_dir) / "bin" / "gniza")
here = Path(__file__).resolve().parent.parent / "bin" / "gniza"
if here.is_file():
return str(here)
return "gniza"
async def run_cli(*args: str) -> tuple[int, str, str]:
cmd = [_gniza_bin(), "--cli"] + list(args)
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await proc.communicate()
return proc.returncode or 0, stdout.decode(), stderr.decode()
async def stream_cli(callback, *args: str) -> int:
cmd = [_gniza_bin(), "--cli"] + list(args)
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT,
)
while True:
line = await proc.stdout.readline()
if not line:
break
callback(line.decode().rstrip("\n"))
await proc.wait()
return proc.returncode or 0