wip - nicegui progress spinner

This commit is contained in:
Stephan Lüscher 2024-05-08 15:37:49 +00:00
parent 75095a841f
commit dd001f4fe5
No known key found for this signature in database
GPG key ID: 445779060FF3D3CF
2 changed files with 55 additions and 13 deletions

View file

@ -1,14 +1,15 @@
import ansible_runner import ansible_runner
import re import re
import asyncio
import time
from nicegui import ui from nicegui import ui
from utils import get_project_root, local_file_picker from utils import get_project_root, local_file_picker, progress_spinner
from multiprocessing import Manager, Queue
ANSIBLE_EXTRA_VARS = None ANSIBLE_EXTRA_VARS = None
# Ansible integration # Ansible integration
@ui.refreshable #https://www.reddit.com/r/nicegui/comments/1bphjk5/comment/kx7l5kj/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button @ui.refreshable # https://www.reddit.com/r/nicegui/comments/1bphjk5/comment/kx7l5kj/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button
async def load_configuration_file() -> None: async def load_configuration_file() -> None:
result = await local_file_picker( result = await local_file_picker(
directory="/data", multiple=False, file_name_filter=".yml" directory="/data", multiple=False, file_name_filter=".yml"
@ -23,7 +24,15 @@ async def load_configuration_file() -> None:
## Preserve configuration file path for ansible-playbook --extra-vars ## Preserve configuration file path for ansible-playbook --extra-vars
ANSIBLE_EXTRA_VARS = f'"@{file_path}"' ANSIBLE_EXTRA_VARS = f'"@{file_path}"'
async def run_ansible_playbook(playbook_name: str, ngui_log: ui.log):
async def run_ansible_playbook(
playbook_name: str,
ngui_log: ui.log,
ngui_spinner: progress_spinner,
) -> None:
ngui_spinner.enable_progress()
# make sure spinner is displayed
await asyncio.sleep(1)
project_root = str(get_project_root()) project_root = str(get_project_root())
playbook_path = project_root + "/ansible/playbooks/" playbook_path = project_root + "/ansible/playbooks/"
inventory_path = project_root + "/ansible/inventory.yml" inventory_path = project_root + "/ansible/inventory.yml"
@ -36,7 +45,7 @@ async def run_ansible_playbook(playbook_name: str, ngui_log: ui.log):
inventory_path, inventory_path,
"--extra-vars", "--extra-vars",
extra_vars_file, extra_vars_file,
] ],
) )
# clear log # clear log
ngui_log.clear() ngui_log.clear()
@ -45,16 +54,18 @@ async def run_ansible_playbook(playbook_name: str, ngui_log: ui.log):
# show log from asynchronous job # show log from asynchronous job
while runner.rc is None: while runner.rc is None:
for event in runner.events: for event in runner.events:
ansible_log = format(ansi_escape.sub("", event['stdout'])) ansible_log = format(ansi_escape.sub("", event["stdout"]))
ngui_log.push(ansible_log) ngui_log.push(ansible_log)
ngui_spinner.disable_progress()
# Page content # Page content
def content() -> None: def content() -> None:
with ui.row().classes("w-full"): with ui.row().classes("w-full"):
with ui.row().classes("w-full"): with ui.row().classes("w-full"):
with ui.card().classes("h-full"): with ui.card().classes("h-full"):
ui.button(text= ui.button(
"Load configuration file", text="Load configuration file",
on_click=lambda: load_configuration_file.refresh(), on_click=lambda: load_configuration_file.refresh(),
icon="folder", icon="folder",
) )
@ -63,22 +74,30 @@ def content() -> None:
with ui.row().classes("w-full"): with ui.row().classes("w-full"):
# First Row # First Row
with ui.card().classes("h-full"): with ui.card().classes("h-full"):
ui.label("Build").classes("text-h6") with ui.row().classes("no-wrap"):
ui.label("Build").classes("text-h5")
build_progress = progress_spinner()
ui.button( ui.button(
text="Clone project", text="Clone project",
on_click=lambda: run_ansible_playbook( on_click=lambda: run_ansible_playbook(
playbook_name="project_clone.yml", ngui_log=playbook_log playbook_name="project_clone.yml",
ngui_log=playbook_log,
ngui_spinner=build_progress,
), ),
) )
ui.button( ui.button(
text="Build project", text="Build project",
on_click=lambda: run_ansible_playbook( on_click=lambda: run_ansible_playbook(
"project_build.yml", ngui_log=playbook_log "project_build.yml",
ngui_log=playbook_log,
ngui_spinner=build_progress,
), ),
) )
# Second Row # Second Row
with ui.card().classes("h-full"): with ui.card().classes("h-full"):
with ui.row().classes("no-wrap"):
ui.label("Deploy").classes("text-h6") ui.label("Deploy").classes("text-h6")
deploy_progress = progress_spinner()
ui.button( ui.button(
"Deploy VM", "Deploy VM",
on_click=lambda: ui.notify("This playbook is not implemented yet"), on_click=lambda: ui.notify("This playbook is not implemented yet"),
@ -88,4 +107,5 @@ def content() -> None:
with ui.card().classes("w-full"): with ui.card().classes("w-full"):
ui.label("Playbook Log").classes("text-h6") ui.label("Playbook Log").classes("text-h6")
ui.button("Clear Log", on_click=lambda: playbook_log.clear()) ui.button("Clear Log", on_click=lambda: playbook_log.clear())
playbook_log = ui.log().classes("w-full h-full") playbook_log = ui.log().classes("w-full h-full")

View file

@ -74,7 +74,9 @@ class local_file_picker(ui.dialog):
if not self.show_hidden_files: if not self.show_hidden_files:
paths = [p for p in paths if not p.name.startswith(".")] paths = [p for p in paths if not p.name.startswith(".")]
if self.file_name_filter: # Add this condition if self.file_name_filter: # Add this condition
paths = [p for p in paths if p.is_file() and p.suffix == self.file_name_filter] paths = [
p for p in paths if p.is_file() and p.suffix == self.file_name_filter
]
paths.sort(key=lambda p: p.name.lower()) paths.sort(key=lambda p: p.name.lower())
paths.sort(key=lambda p: not p.is_dir()) paths.sort(key=lambda p: not p.is_dir())
@ -114,5 +116,25 @@ class local_file_picker(ui.dialog):
self.submit([r["path"] for r in rows]) self.submit([r["path"] for r in rows])
class progress_spinner(ui.spinner):
def __init__(
self,
*,
type: str = "dots",
size: str = "lg",
color: str | None = "red",
thickness: float = 5,
) -> None:
super().__init__(type, size=size, color=color, thickness=thickness)
with self, ui.spinner():
self.visible = False
def enable_progress(self) -> None:
self.set_visibility(True)
def disable_progress(self) -> None:
self.set_visibility(False)
def get_project_root() -> Path: def get_project_root() -> Path:
return Path(__file__).parent.parent return Path(__file__).parent.parent