Show disk usage in remotes table with async loading
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -274,6 +274,11 @@ run_cli() {
|
|||||||
validate_remote "$name"
|
validate_remote "$name"
|
||||||
echo "Remote '$name' is valid."
|
echo "Remote '$name' is valid."
|
||||||
;;
|
;;
|
||||||
|
disk-info-short)
|
||||||
|
[[ -z "$name" ]] && die "remotes disk-info-short requires --name=NAME"
|
||||||
|
load_remote "$name"
|
||||||
|
remote_disk_info_short
|
||||||
|
;;
|
||||||
disk-info)
|
disk-info)
|
||||||
[[ -z "$name" ]] && die "remotes disk-info requires --name=NAME"
|
[[ -z "$name" ]] && die "remotes disk-info requires --name=NAME"
|
||||||
load_remote "$name"
|
load_remote "$name"
|
||||||
|
|||||||
@@ -290,6 +290,31 @@ get_target_remotes() {
|
|||||||
|
|
||||||
# ── Disk info ────────────────────────────────────────────────
|
# ── Disk info ────────────────────────────────────────────────
|
||||||
|
|
||||||
|
# Compact one-line disk info: "USED/TOTAL (FREE free)"
|
||||||
|
remote_disk_info_short() {
|
||||||
|
local base="${REMOTE_BASE:-/}"
|
||||||
|
local df_out=""
|
||||||
|
case "${REMOTE_TYPE:-ssh}" in
|
||||||
|
ssh)
|
||||||
|
df_out=$(remote_exec "df -h '$base' 2>/dev/null | tail -1") || return 1
|
||||||
|
;;
|
||||||
|
local)
|
||||||
|
df_out=$(df -h "$base" 2>/dev/null | tail -1) || return 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "N/A"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
# df output: Filesystem Size Used Avail Use% Mount
|
||||||
|
local size used avail pct
|
||||||
|
size=$(echo "$df_out" | awk '{print $2}')
|
||||||
|
used=$(echo "$df_out" | awk '{print $3}')
|
||||||
|
avail=$(echo "$df_out" | awk '{print $4}')
|
||||||
|
pct=$(echo "$df_out" | awk '{print $5}')
|
||||||
|
echo "${used}/${size} (${avail} free) ${pct}"
|
||||||
|
}
|
||||||
|
|
||||||
remote_disk_info() {
|
remote_disk_info() {
|
||||||
local base="${REMOTE_BASE:-/}"
|
local base="${REMOTE_BASE:-/}"
|
||||||
case "${REMOTE_TYPE:-ssh}" in
|
case "${REMOTE_TYPE:-ssh}" in
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ class RemotesScreen(Screen):
|
|||||||
def _refresh_table(self) -> None:
|
def _refresh_table(self) -> None:
|
||||||
table = self.query_one("#remotes-table", DataTable)
|
table = self.query_one("#remotes-table", DataTable)
|
||||||
table.clear(columns=True)
|
table.clear(columns=True)
|
||||||
table.add_columns("Name", "Type", "Host/Path")
|
cols = table.add_columns("Name", "Type", "Host/Path", "Disk")
|
||||||
|
self._disk_col_key = cols[3]
|
||||||
remotes = list_conf_dir("remotes.d")
|
remotes = list_conf_dir("remotes.d")
|
||||||
for name in remotes:
|
for name in remotes:
|
||||||
data = parse_conf(CONFIG_DIR / "remotes.d" / f"{name}.conf")
|
data = parse_conf(CONFIG_DIR / "remotes.d" / f"{name}.conf")
|
||||||
@@ -47,7 +48,8 @@ class RemotesScreen(Screen):
|
|||||||
loc = f"s3://{data.get('S3_BUCKET', '')}{data.get('REMOTE_BASE', '')}"
|
loc = f"s3://{data.get('S3_BUCKET', '')}{data.get('REMOTE_BASE', '')}"
|
||||||
else:
|
else:
|
||||||
loc = data.get("REMOTE_BASE", "")
|
loc = data.get("REMOTE_BASE", "")
|
||||||
table.add_row(name, rtype, loc, key=name)
|
table.add_row(name, rtype, loc, "loading...", key=name)
|
||||||
|
self._fetch_disk_info()
|
||||||
|
|
||||||
def _selected_remote(self) -> str | None:
|
def _selected_remote(self) -> str | None:
|
||||||
table = self.query_one("#remotes-table", DataTable)
|
table = self.query_one("#remotes-table", DataTable)
|
||||||
@@ -95,6 +97,18 @@ class RemotesScreen(Screen):
|
|||||||
else:
|
else:
|
||||||
self.notify("Select a remote first", severity="warning")
|
self.notify("Select a remote first", severity="warning")
|
||||||
|
|
||||||
|
@work
|
||||||
|
async def _fetch_disk_info(self) -> None:
|
||||||
|
remotes = list_conf_dir("remotes.d")
|
||||||
|
for name in remotes:
|
||||||
|
rc, stdout, stderr = await run_cli("remotes", "disk-info-short", f"--name={name}")
|
||||||
|
disk_text = stdout.strip() if rc == 0 and stdout.strip() else "N/A"
|
||||||
|
try:
|
||||||
|
table = self.query_one("#remotes-table", DataTable)
|
||||||
|
table.update_cell(name, self._disk_col_key, disk_text, update_width=True)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
@work
|
@work
|
||||||
async def _test_remote(self, name: str) -> None:
|
async def _test_remote(self, name: str) -> None:
|
||||||
log_screen = OperationLog(f"Testing Remote: {name}", show_spinner=False)
|
log_screen = OperationLog(f"Testing Remote: {name}", show_spinner=False)
|
||||||
|
|||||||
Reference in New Issue
Block a user