machineconfig 5.29__py3-none-any.whl → 5.31__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/scripts/python/croshell_helpers/__init__.py +0 -0
- machineconfig/scripts/python/devops.py +13 -122
- machineconfig/scripts/python/devops_helpers/choose_pwsh_theme.ps1 +44 -0
- machineconfig/scripts/python/devops_helpers/cli_config.py +43 -0
- machineconfig/scripts/python/devops_helpers/cli_data.py +18 -0
- machineconfig/scripts/python/devops_helpers/cli_nw.py +39 -0
- machineconfig/scripts/python/{repos.py → devops_helpers/cli_repos.py} +43 -7
- machineconfig/scripts/python/devops_helpers/cli_self.py +41 -0
- machineconfig/scripts/python/devops_helpers/devops_status.py +118 -55
- machineconfig/scripts/python/devops_navigator.py +806 -0
- machineconfig/scripts/python/helpers/repo_sync_helpers.py +1 -1
- machineconfig/scripts/python/helpers_repos/__init__.py +0 -0
- machineconfig/scripts/python/helpers_repos/grource.py +2 -3
- machineconfig/scripts/python/{secure_repo.py → helpers_repos/secure_repo.py} +1 -1
- machineconfig/scripts/python/interactive.py +2 -2
- machineconfig/scripts/python/nw/__init__.py +0 -0
- machineconfig/scripts/python/sessions.py +1 -1
- machineconfig/scripts/python/sessions_helpers/__init__.py +0 -0
- machineconfig/settings/linters/.ruff.toml +1 -1
- machineconfig/settings/shells/pwsh/init.ps1 +1 -1
- machineconfig/setup_windows/uv.ps1 +1 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +2 -3
- machineconfig/utils/code.py +13 -3
- machineconfig/utils/installer_utils/installer_class.py +3 -5
- {machineconfig-5.29.dist-info → machineconfig-5.31.dist-info}/METADATA +2 -1
- {machineconfig-5.29.dist-info → machineconfig-5.31.dist-info}/RECORD +45 -40
- {machineconfig-5.29.dist-info → machineconfig-5.31.dist-info}/entry_points.txt +1 -0
- machineconfig/scripts/python/gh_models.py +0 -104
- machineconfig/scripts/python/snapshot.py +0 -25
- machineconfig/scripts/python/start_terminals.py +0 -121
- machineconfig/scripts/windows/choose_wezterm_theme.ps1 +0 -1
- machineconfig/scripts/windows/wifi_conn.ps1 +0 -2
- /machineconfig/scripts/python/{pomodoro.py → croshell_helpers/pomodoro.py} +0 -0
- /machineconfig/scripts/python/{scheduler.py → croshell_helpers/scheduler.py} +0 -0
- /machineconfig/scripts/python/{start_slidev.py → croshell_helpers/start_slidev.py} +0 -0
- /machineconfig/scripts/python/{viewer.py → croshell_helpers/viewer.py} +0 -0
- /machineconfig/scripts/python/{viewer_template.py → croshell_helpers/viewer_template.py} +0 -0
- /machineconfig/scripts/python/{choose_wezterm_theme.py → devops_helpers/choose_wezterm_theme.py} +0 -0
- /machineconfig/scripts/python/{dotfile.py → devops_helpers/cli_config_dotfile.py} +0 -0
- /machineconfig/scripts/python/{share_terminal.py → devops_helpers/cli_terminal.py} +0 -0
- /machineconfig/scripts/python/{cloud_repo_sync.py → helpers_repos/cloud_repo_sync.py} +0 -0
- /machineconfig/scripts/python/{mount_nfs.py → nw/mount_nfs.py} +0 -0
- /machineconfig/scripts/python/{mount_nw_drive.py → nw/mount_nw_drive.py} +0 -0
- /machineconfig/scripts/python/{mount_ssh.py → nw/mount_ssh.py} +0 -0
- /machineconfig/scripts/python/{onetimeshare.py → nw/onetimeshare.py} +0 -0
- /machineconfig/scripts/python/{wifi_conn.py → nw/wifi_conn.py} +0 -0
- /machineconfig/scripts/python/{wsl_windows_transfer.py → nw/wsl_windows_transfer.py} +0 -0
- /machineconfig/scripts/python/{sessions_multiprocess.py → sessions_helpers/sessions_multiprocess.py} +0 -0
- {machineconfig-5.29.dist-info → machineconfig-5.31.dist-info}/WHEEL +0 -0
- {machineconfig-5.29.dist-info → machineconfig-5.31.dist-info}/top_level.txt +0 -0
|
@@ -40,9 +40,10 @@ def _check_shell_profile_status() -> dict[str, Any]:
|
|
|
40
40
|
|
|
41
41
|
try:
|
|
42
42
|
profile_path = get_shell_profile_path()
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
if not profile_path.exists():
|
|
44
|
+
profile_path.parent.mkdir(parents=True, exist_ok=True)
|
|
45
|
+
profile_path.touch()
|
|
46
|
+
profile_content = profile_path.read_text(encoding="utf-8")
|
|
46
47
|
system_name = platform.system()
|
|
47
48
|
if system_name == "Windows":
|
|
48
49
|
init_script = PathExtended(LIBRARY_ROOT).joinpath("settings/shells/pwsh/init.ps1")
|
|
@@ -60,14 +61,22 @@ def _check_shell_profile_status() -> dict[str, Any]:
|
|
|
60
61
|
|
|
61
62
|
return {
|
|
62
63
|
"profile_path": str(profile_path),
|
|
63
|
-
"exists":
|
|
64
|
+
"exists": True,
|
|
64
65
|
"configured": configured,
|
|
65
66
|
"method": method,
|
|
66
67
|
"init_script_exists": init_script.exists(),
|
|
67
68
|
"init_script_copy_exists": init_script_copy.exists(),
|
|
68
69
|
}
|
|
69
70
|
except Exception as ex:
|
|
70
|
-
return {
|
|
71
|
+
return {
|
|
72
|
+
"profile_path": "Error",
|
|
73
|
+
"exists": False,
|
|
74
|
+
"configured": False,
|
|
75
|
+
"method": "error",
|
|
76
|
+
"error": str(ex),
|
|
77
|
+
"init_script_exists": False,
|
|
78
|
+
"init_script_copy_exists": False,
|
|
79
|
+
}
|
|
71
80
|
|
|
72
81
|
|
|
73
82
|
def _check_machineconfig_repo() -> dict[str, Any]:
|
|
@@ -116,7 +125,16 @@ def _check_repos_status() -> dict[str, Any]:
|
|
|
116
125
|
import git
|
|
117
126
|
|
|
118
127
|
repo = git.Repo(str(repo_path))
|
|
119
|
-
repos_info.append(
|
|
128
|
+
repos_info.append(
|
|
129
|
+
{
|
|
130
|
+
"path": str(repo_path),
|
|
131
|
+
"name": repo_path.name,
|
|
132
|
+
"exists": True,
|
|
133
|
+
"is_repo": True,
|
|
134
|
+
"clean": not repo.is_dirty(untracked_files=True),
|
|
135
|
+
"branch": repo.active_branch.name if not repo.head.is_detached else "DETACHED",
|
|
136
|
+
}
|
|
137
|
+
)
|
|
120
138
|
except Exception:
|
|
121
139
|
repos_info.append({"path": str(repo_path), "name": repo_path.name, "exists": True, "is_repo": False})
|
|
122
140
|
|
|
@@ -134,7 +152,15 @@ def _check_ssh_status() -> dict[str, Any]:
|
|
|
134
152
|
keys = []
|
|
135
153
|
for pub_key in ssh_dir.glob("*.pub"):
|
|
136
154
|
private_key = pub_key.with_suffix("")
|
|
137
|
-
keys.append(
|
|
155
|
+
keys.append(
|
|
156
|
+
{
|
|
157
|
+
"name": pub_key.stem,
|
|
158
|
+
"public_exists": True,
|
|
159
|
+
"private_exists": private_key.exists(),
|
|
160
|
+
"public_path": str(pub_key),
|
|
161
|
+
"private_path": str(private_key),
|
|
162
|
+
}
|
|
163
|
+
)
|
|
138
164
|
|
|
139
165
|
config_file = ssh_dir.joinpath("config")
|
|
140
166
|
authorized_keys = ssh_dir.joinpath("authorized_keys")
|
|
@@ -187,13 +213,21 @@ def _check_config_files_status() -> dict[str, Any]:
|
|
|
187
213
|
"private_configs": private_configs,
|
|
188
214
|
}
|
|
189
215
|
except Exception as ex:
|
|
190
|
-
return {
|
|
216
|
+
return {
|
|
217
|
+
"public_count": 0,
|
|
218
|
+
"public_linked": 0,
|
|
219
|
+
"private_count": 0,
|
|
220
|
+
"private_linked": 0,
|
|
221
|
+
"error": str(ex),
|
|
222
|
+
"public_configs": [],
|
|
223
|
+
"private_configs": [],
|
|
224
|
+
}
|
|
191
225
|
|
|
192
226
|
|
|
193
227
|
def _check_important_tools() -> dict[str, dict[str, bool]]:
|
|
194
228
|
"""Check if important CLI tools are installed, organized by groups."""
|
|
195
229
|
from machineconfig.jobs.installer.package_groups import PACKAGE_GROUP2NAMES
|
|
196
|
-
|
|
230
|
+
|
|
197
231
|
group_status = {}
|
|
198
232
|
for group_name, tools in PACKAGE_GROUP2NAMES.items():
|
|
199
233
|
tool_status = {}
|
|
@@ -257,25 +291,33 @@ def _display_shell_status(status: dict[str, Any]) -> None:
|
|
|
257
291
|
return
|
|
258
292
|
|
|
259
293
|
from rich.columns import Columns
|
|
260
|
-
|
|
294
|
+
|
|
261
295
|
left_table = Table(show_header=False, box=None, padding=(0, 1))
|
|
262
296
|
left_table.add_column("Item", style="cyan", no_wrap=True)
|
|
263
297
|
left_table.add_column("Status")
|
|
264
|
-
|
|
265
|
-
left_table.add_row("📄 Profile", status[
|
|
266
|
-
left_table.add_row(f"{'✅' if status['exists'] else '❌'} Exists", str(status[
|
|
267
|
-
left_table.add_row(f"{'✅' if status['configured'] else '❌'} Configured", str(status[
|
|
268
|
-
|
|
298
|
+
|
|
299
|
+
left_table.add_row("📄 Profile", status["profile_path"])
|
|
300
|
+
left_table.add_row(f"{'✅' if status['exists'] else '❌'} Exists", str(status["exists"]))
|
|
301
|
+
left_table.add_row(f"{'✅' if status['configured'] else '❌'} Configured", str(status["configured"]))
|
|
302
|
+
|
|
269
303
|
right_table = Table(show_header=False, box=None, padding=(0, 1))
|
|
270
304
|
right_table.add_column("Item", style="cyan", no_wrap=True)
|
|
271
305
|
right_table.add_column("Status")
|
|
272
|
-
|
|
273
|
-
right_table.add_row("🔧 Method", status[
|
|
274
|
-
right_table.add_row(f"{'✅' if status['init_script_exists'] else '❌'} Init (source)", str(status[
|
|
275
|
-
right_table.add_row(f"{'✅' if status['init_script_copy_exists'] else '❌'} Init (copy)", str(status[
|
|
306
|
+
|
|
307
|
+
right_table.add_row("🔧 Method", status["method"])
|
|
308
|
+
right_table.add_row(f"{'✅' if status['init_script_exists'] else '❌'} Init (source)", str(status["init_script_exists"]))
|
|
309
|
+
right_table.add_row(f"{'✅' if status['init_script_copy_exists'] else '❌'} Init (copy)", str(status["init_script_copy_exists"]))
|
|
276
310
|
|
|
277
311
|
border_style = "green" if status["configured"] else "yellow"
|
|
278
|
-
console.print(
|
|
312
|
+
console.print(
|
|
313
|
+
Panel(
|
|
314
|
+
Columns([left_table, right_table], equal=True, expand=True),
|
|
315
|
+
title="Shell Profile",
|
|
316
|
+
border_style=border_style,
|
|
317
|
+
padding=(1, 2),
|
|
318
|
+
expand=False,
|
|
319
|
+
)
|
|
320
|
+
)
|
|
279
321
|
|
|
280
322
|
|
|
281
323
|
def _display_machineconfig_repo(info: dict[str, Any]) -> None:
|
|
@@ -283,22 +325,38 @@ def _display_machineconfig_repo(info: dict[str, Any]) -> None:
|
|
|
283
325
|
console.rule("[bold magenta]📦 Machineconfig Repository[/bold magenta]")
|
|
284
326
|
|
|
285
327
|
if not info["exists"]:
|
|
286
|
-
console.print(
|
|
328
|
+
console.print(
|
|
329
|
+
Panel(
|
|
330
|
+
"❌ Machineconfig repository not found at ~/code/machineconfig",
|
|
331
|
+
title="Repository Status",
|
|
332
|
+
border_style="red",
|
|
333
|
+
padding=(1, 2),
|
|
334
|
+
expand=False,
|
|
335
|
+
)
|
|
336
|
+
)
|
|
287
337
|
return
|
|
288
338
|
|
|
289
339
|
if not info["is_repo"]:
|
|
290
|
-
console.print(
|
|
340
|
+
console.print(
|
|
341
|
+
Panel(
|
|
342
|
+
f"❌ Directory exists but is not a git repository\n{info.get('error', 'Unknown error')}",
|
|
343
|
+
title="Repository Status",
|
|
344
|
+
border_style="red",
|
|
345
|
+
padding=(1, 2),
|
|
346
|
+
expand=False,
|
|
347
|
+
)
|
|
348
|
+
)
|
|
291
349
|
return
|
|
292
350
|
|
|
293
351
|
table = Table(show_header=False, box=None, padding=(0, 1), expand=False)
|
|
294
352
|
table.add_column("Property", style="cyan", no_wrap=True)
|
|
295
353
|
table.add_column("Value", style="white")
|
|
296
|
-
|
|
297
|
-
table.add_row("📁 Path", info[
|
|
298
|
-
table.add_row("🌿 Branch", info[
|
|
299
|
-
table.add_row("🔖 Commit", info[
|
|
300
|
-
table.add_row(f"{'✅' if info['clean'] else '⚠️'} Status",
|
|
301
|
-
table.add_row("📡 Remotes",
|
|
354
|
+
|
|
355
|
+
table.add_row("📁 Path", info["path"])
|
|
356
|
+
table.add_row("🌿 Branch", info["branch"])
|
|
357
|
+
table.add_row("🔖 Commit", info["commit"])
|
|
358
|
+
table.add_row(f"{'✅' if info['clean'] else '⚠️'} Status", "Clean" if info["clean"] else "Uncommitted changes")
|
|
359
|
+
table.add_row("📡 Remotes", ", ".join(info["remotes"]) if info["remotes"] else "None")
|
|
302
360
|
|
|
303
361
|
border_style = "green" if info["clean"] else "yellow"
|
|
304
362
|
console.print(Panel(table, title="Machineconfig Repository", border_style=border_style, padding=(1, 2), expand=False))
|
|
@@ -344,15 +402,15 @@ def _display_ssh_status(status: dict[str, Any]) -> None:
|
|
|
344
402
|
return
|
|
345
403
|
|
|
346
404
|
from rich.columns import Columns
|
|
347
|
-
|
|
405
|
+
|
|
348
406
|
config_table = Table(show_header=False, box=None, padding=(0, 1))
|
|
349
407
|
config_table.add_column("Item", style="cyan", no_wrap=True)
|
|
350
408
|
config_table.add_column("Status")
|
|
351
|
-
|
|
352
|
-
config_table.add_row("📁 Directory", status[
|
|
353
|
-
config_table.add_row(f"{'✅' if status['config_exists'] else '❌'} Config", str(status[
|
|
354
|
-
config_table.add_row(f"{'✅' if status['authorized_keys_exists'] else '❌'} Auth Keys", str(status[
|
|
355
|
-
config_table.add_row(f"{'✅' if status['known_hosts_exists'] else '❌'} Known Hosts", str(status[
|
|
409
|
+
|
|
410
|
+
config_table.add_row("📁 Directory", status["ssh_dir_path"])
|
|
411
|
+
config_table.add_row(f"{'✅' if status['config_exists'] else '❌'} Config", str(status["config_exists"]))
|
|
412
|
+
config_table.add_row(f"{'✅' if status['authorized_keys_exists'] else '❌'} Auth Keys", str(status["authorized_keys_exists"]))
|
|
413
|
+
config_table.add_row(f"{'✅' if status['known_hosts_exists'] else '❌'} Known Hosts", str(status["known_hosts_exists"]))
|
|
356
414
|
|
|
357
415
|
config_panel = Panel(config_table, title="SSH Config", border_style="yellow", padding=(1, 2), expand=False)
|
|
358
416
|
|
|
@@ -368,7 +426,7 @@ def _display_ssh_status(status: dict[str, Any]) -> None:
|
|
|
368
426
|
keys_table.add_row(key["name"], pub_status, priv_status)
|
|
369
427
|
|
|
370
428
|
keys_panel = Panel(keys_table, title=f"SSH Keys ({len(status['keys'])})", border_style="yellow", padding=(1, 2), expand=False)
|
|
371
|
-
|
|
429
|
+
|
|
372
430
|
console.print(Columns([config_panel, keys_panel], equal=False, expand=True))
|
|
373
431
|
else:
|
|
374
432
|
console.print(config_panel)
|
|
@@ -379,7 +437,9 @@ def _display_config_files_status(status: dict[str, Any]) -> None:
|
|
|
379
437
|
console.rule("[bold bright_blue]⚙️ Configuration Files[/bold bright_blue]")
|
|
380
438
|
|
|
381
439
|
if "error" in status:
|
|
382
|
-
console.print(
|
|
440
|
+
console.print(
|
|
441
|
+
Panel(f"❌ Error reading configuration: {status['error']}", title="Configuration Files", border_style="red", padding=(1, 2), expand=False)
|
|
442
|
+
)
|
|
383
443
|
return
|
|
384
444
|
|
|
385
445
|
public_percentage = (status["public_linked"] / status["public_count"] * 100) if status["public_count"] > 0 else 0
|
|
@@ -390,9 +450,9 @@ def _display_config_files_status(status: dict[str, Any]) -> None:
|
|
|
390
450
|
table.add_column("Linked", justify="right")
|
|
391
451
|
table.add_column("Total", justify="right")
|
|
392
452
|
table.add_column("Progress", justify="right")
|
|
393
|
-
|
|
394
|
-
table.add_row("📂 Public", str(status[
|
|
395
|
-
table.add_row("🔒 Private", str(status[
|
|
453
|
+
|
|
454
|
+
table.add_row("📂 Public", str(status["public_linked"]), str(status["public_count"]), f"{public_percentage:.0f}%")
|
|
455
|
+
table.add_row("🔒 Private", str(status["private_linked"]), str(status["private_count"]), f"{private_percentage:.0f}%")
|
|
396
456
|
|
|
397
457
|
overall_linked = status["public_linked"] + status["private_linked"]
|
|
398
458
|
overall_total = status["public_count"] + status["private_count"]
|
|
@@ -400,7 +460,9 @@ def _display_config_files_status(status: dict[str, Any]) -> None:
|
|
|
400
460
|
|
|
401
461
|
border_style = "green" if overall_percentage > 80 else ("yellow" if overall_percentage > 50 else "red")
|
|
402
462
|
|
|
403
|
-
console.print(
|
|
463
|
+
console.print(
|
|
464
|
+
Panel(table, title=f"Configuration Files ({overall_percentage:.0f}% configured)", border_style=border_style, padding=(1, 2), expand=False)
|
|
465
|
+
)
|
|
404
466
|
|
|
405
467
|
|
|
406
468
|
def _display_tools_status(grouped_tools: dict[str, dict[str, bool]]) -> None:
|
|
@@ -408,60 +470,61 @@ def _display_tools_status(grouped_tools: dict[str, dict[str, bool]]) -> None:
|
|
|
408
470
|
console.rule("[bold bright_magenta]🛠️ Important Tools[/bold bright_magenta]")
|
|
409
471
|
|
|
410
472
|
from rich.columns import Columns
|
|
411
|
-
|
|
473
|
+
|
|
412
474
|
all_group_panels = []
|
|
413
475
|
total_installed = 0
|
|
414
476
|
total_tools = 0
|
|
415
|
-
|
|
477
|
+
|
|
416
478
|
for group_name, tools in grouped_tools.items():
|
|
417
479
|
sorted_tools = sorted(tools.keys())
|
|
418
480
|
installed = [tool for tool, status in tools.items() if status]
|
|
419
481
|
total_installed += len(installed)
|
|
420
482
|
total_tools += len(tools)
|
|
421
|
-
|
|
483
|
+
|
|
422
484
|
num_columns = 8
|
|
423
485
|
tools_per_column = (len(sorted_tools) + num_columns - 1) // num_columns
|
|
424
|
-
|
|
486
|
+
|
|
425
487
|
tables = []
|
|
426
488
|
for col_idx in range(num_columns):
|
|
427
489
|
table = Table(show_header=False, box=None, padding=(0, 0), collapse_padding=True)
|
|
428
490
|
table.add_column("Tool", style="cyan", no_wrap=True, width=None)
|
|
429
491
|
table.add_column("", justify="center", width=2, no_wrap=True)
|
|
430
|
-
|
|
492
|
+
|
|
431
493
|
start_idx = col_idx * tools_per_column
|
|
432
494
|
end_idx = min(start_idx + tools_per_column, len(sorted_tools))
|
|
433
|
-
|
|
495
|
+
|
|
434
496
|
for i in range(start_idx, end_idx):
|
|
435
497
|
tool = sorted_tools[i]
|
|
436
498
|
status_icon = "✅" if tools[tool] else "❌"
|
|
437
499
|
table.add_row(tool, status_icon)
|
|
438
|
-
|
|
500
|
+
|
|
439
501
|
if start_idx < len(sorted_tools):
|
|
440
502
|
tables.append(table)
|
|
441
503
|
|
|
442
504
|
installed_percentage = (len(installed) / len(tools) * 100) if tools else 0
|
|
443
505
|
border_style = "green" if installed_percentage > 80 else ("yellow" if installed_percentage > 50 else "red")
|
|
444
|
-
|
|
506
|
+
|
|
445
507
|
group_display_name = group_name.replace("_", " ").title()
|
|
446
508
|
group_panel = Panel(
|
|
447
509
|
Columns(tables, equal=False, expand=False, padding=(0, 1)),
|
|
448
510
|
title=f"{group_display_name} ({len(installed)}/{len(tools)})",
|
|
449
511
|
border_style=border_style,
|
|
450
512
|
padding=(0, 1),
|
|
451
|
-
expand=False
|
|
513
|
+
expand=False,
|
|
452
514
|
)
|
|
453
515
|
all_group_panels.append(group_panel)
|
|
454
|
-
|
|
516
|
+
|
|
455
517
|
overall_percentage = (total_installed / total_tools * 100) if total_tools else 0
|
|
456
518
|
master_border_style = "green" if overall_percentage > 80 else ("yellow" if overall_percentage > 50 else "red")
|
|
457
|
-
|
|
519
|
+
|
|
458
520
|
from rich.console import Group
|
|
521
|
+
|
|
459
522
|
master_panel = Panel(
|
|
460
523
|
Group(*all_group_panels),
|
|
461
524
|
title=f"🛠️ Tools Overview ({total_installed}/{total_tools} installed - {overall_percentage:.0f}%)",
|
|
462
525
|
border_style=master_border_style,
|
|
463
526
|
padding=(1, 2),
|
|
464
|
-
expand=False
|
|
527
|
+
expand=False,
|
|
465
528
|
)
|
|
466
529
|
console.print(master_panel)
|
|
467
530
|
|
|
@@ -473,9 +536,9 @@ def _display_backup_status(status: dict[str, Any]) -> None:
|
|
|
473
536
|
table = Table(show_header=False, box=None, padding=(0, 1), expand=False)
|
|
474
537
|
table.add_column("Property", style="cyan", no_wrap=True)
|
|
475
538
|
table.add_column("Value", style="white")
|
|
476
|
-
|
|
477
|
-
table.add_row("🌥️ Cloud Config", status[
|
|
478
|
-
table.add_row("📦 Backup Items", str(status[
|
|
539
|
+
|
|
540
|
+
table.add_row("🌥️ Cloud Config", status["cloud_config"])
|
|
541
|
+
table.add_row("📦 Backup Items", str(status["backup_items_count"]))
|
|
479
542
|
|
|
480
543
|
border_style = "green" if status["cloud_config"] != "Not configured" else "yellow"
|
|
481
544
|
|