Refactor Docker and Local Setup Commands
- Enhanced the docker_setup.py to streamline image building and pulling processes with improved logging and error handling. - Introduced a new LogScreen for better user feedback during long-running tasks. - Updated local_setup.py to utilize logging for installation steps and improved error handling. - Refactored robot_setup.py to simplify configuration saving and user interaction. - Added a new LogScreen class in tui.py for consistent logging across different setup processes. - Modified install.sh to adjust the installation directory for better organization.
This commit is contained in:
+58
-2
@@ -1,12 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, Optional
|
||||
from typing import Callable, List, Optional
|
||||
|
||||
from textual import on
|
||||
from textual.app import ComposeResult
|
||||
from textual.binding import Binding
|
||||
from textual.screen import Screen
|
||||
from textual.widgets import Footer, Input, RadioButton, RadioSet, Static
|
||||
from textual.widgets import Footer, Input, RadioButton, RadioSet, RichLog, Static
|
||||
|
||||
SCREEN_CSS = """
|
||||
Screen {
|
||||
@@ -36,6 +36,16 @@ RadioSet {
|
||||
Input {
|
||||
margin-bottom: 1;
|
||||
}
|
||||
LogScreen #log {
|
||||
height: 1fr;
|
||||
border: none;
|
||||
padding: 0 1;
|
||||
margin-top: 1;
|
||||
}
|
||||
LogScreen #hint {
|
||||
margin-top: 1;
|
||||
color: $text;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
@@ -114,3 +124,49 @@ class InputScreen(Screen[Optional[str]]):
|
||||
|
||||
def action_abort(self) -> None:
|
||||
self.app.exit(None)
|
||||
|
||||
|
||||
class LogScreen(Screen[bool]):
|
||||
"""Streams task output into a scrollable log; press Enter to close when done."""
|
||||
|
||||
BINDINGS = [Binding("enter,escape", "close", "Close", show=False)]
|
||||
|
||||
def __init__(self, title: str, task: Callable[[LogScreen], None]):
|
||||
super().__init__()
|
||||
self._title = title
|
||||
self._run_fn = task
|
||||
self._finished = False
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Static(self._title, id="step")
|
||||
yield RichLog(id="log", highlight=True, markup=True, wrap=True)
|
||||
yield Static("", id="hint")
|
||||
yield Footer()
|
||||
|
||||
def on_mount(self) -> None:
|
||||
self.query_one(RichLog).focus()
|
||||
self.app.run_worker(lambda: self._run_fn(self), thread=True)
|
||||
|
||||
def write(self, line: str) -> None:
|
||||
"""Thread-safe: append a line to the log."""
|
||||
self.app.call_from_thread(self._append, line)
|
||||
|
||||
def _append(self, line: str) -> None:
|
||||
self.query_one(RichLog).write(line)
|
||||
|
||||
def finish(self, success: bool) -> None:
|
||||
"""Thread-safe: mark task done and prompt the user to close."""
|
||||
self.app.call_from_thread(self._do_finish, success)
|
||||
|
||||
def _do_finish(self, success: bool) -> None:
|
||||
self._finished = True
|
||||
msg = (
|
||||
"[green]Done![/green] Press [bold]Enter[/bold] to close."
|
||||
if success
|
||||
else "[red]Failed.[/red] Press [bold]Enter[/bold] to close."
|
||||
)
|
||||
self.query_one("#hint", Static).update(msg)
|
||||
|
||||
def action_close(self) -> None:
|
||||
if self._finished:
|
||||
self.dismiss(True)
|
||||
|
||||
Reference in New Issue
Block a user