Rsync exit 23 (partial transfer) now triggers an automatic retry to recover failed files before accepting with a warning. Also adds a task counter next to the clock in the header bar showing running job count. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
52 lines
1.3 KiB
Python
52 lines
1.3 KiB
Python
from datetime import datetime
|
|
|
|
from rich.text import Text
|
|
from textual.reactive import Reactive
|
|
from textual.widgets import Header, Static
|
|
from textual.widgets._header import HeaderIcon, HeaderTitle, HeaderClock, HeaderClockSpace
|
|
|
|
from tui.jobs import job_manager
|
|
|
|
|
|
class HeaderTaskClock(HeaderClock):
|
|
"""Clock widget that also shows running task count."""
|
|
|
|
DEFAULT_CSS = """
|
|
HeaderTaskClock {
|
|
background: $foreground-darken-1 5%;
|
|
color: $foreground;
|
|
text-opacity: 85%;
|
|
content-align: center middle;
|
|
dock: right;
|
|
width: auto;
|
|
min-width: 10;
|
|
padding: 0 1;
|
|
}
|
|
"""
|
|
|
|
time_format: Reactive[str] = Reactive("%X")
|
|
|
|
def render(self):
|
|
clock = datetime.now().time().strftime(self.time_format)
|
|
count = job_manager.running_count()
|
|
if count > 0:
|
|
return Text.assemble(
|
|
("Tasks ", "bold"),
|
|
(f"({count})", "bold yellow"),
|
|
" ",
|
|
clock,
|
|
)
|
|
return Text(clock)
|
|
|
|
|
|
class GnizaHeader(Header):
|
|
|
|
def compose(self):
|
|
yield HeaderIcon().data_bind(Header.icon)
|
|
yield HeaderTitle()
|
|
yield (
|
|
HeaderTaskClock().data_bind(Header.time_format)
|
|
if self._show_clock
|
|
else HeaderClockSpace()
|
|
)
|