mirror of
https://github.com/blw1138/Zordon.git
synced 2025-12-17 08:48:13 +00:00
Improve dashboard to fetch data async from screen refreshes
This commit is contained in:
93
dashboard.py
93
dashboard.py
@@ -32,7 +32,7 @@ status_colors = {RenderStatus.ERROR: "red", RenderStatus.CANCELLED: 'orange1', R
|
|||||||
categories = [RenderStatus.RUNNING, RenderStatus.ERROR, RenderStatus.NOT_STARTED, RenderStatus.SCHEDULED,
|
categories = [RenderStatus.RUNNING, RenderStatus.ERROR, RenderStatus.NOT_STARTED, RenderStatus.SCHEDULED,
|
||||||
RenderStatus.COMPLETED, RenderStatus.CANCELLED]
|
RenderStatus.COMPLETED, RenderStatus.CANCELLED]
|
||||||
|
|
||||||
renderer_colors = {'ffmpeg': '[magenta]', 'Blender': '[orange1]', 'aerender': '[purple]'}
|
renderer_colors = {'ffmpeg': '[magenta]', 'blender': '[orange1]', 'aerender': '[purple]'}
|
||||||
|
|
||||||
local_hostname = socket.gethostname()
|
local_hostname = socket.gethostname()
|
||||||
|
|
||||||
@@ -132,7 +132,21 @@ def create_jobs_table(all_server_data) -> Table:
|
|||||||
if job_status == RenderStatus.ERROR and job['worker']['errors']:
|
if job_status == RenderStatus.ERROR and job['worker']['errors']:
|
||||||
job_text = job_text + "\n" + "\n".join(job['worker']['errors'])
|
job_text = job_text + "\n" + "\n".join(job['worker']['errors'])
|
||||||
|
|
||||||
elapsed_time = job['worker'].get('time_elapsed', 'unknown')
|
# calculate elapsed time
|
||||||
|
elapsed_time = 'Unknown'
|
||||||
|
start_time = None
|
||||||
|
end_time = None
|
||||||
|
|
||||||
|
if job['worker']['start_time']:
|
||||||
|
start_time = datetime.datetime.fromisoformat(job['worker']['start_time'])
|
||||||
|
if job['worker']['end_time']:
|
||||||
|
end_time = datetime.datetime.fromisoformat(job['worker']['end_time'])
|
||||||
|
|
||||||
|
if start_time:
|
||||||
|
if end_time:
|
||||||
|
elapsed_time = str(end_time - start_time)
|
||||||
|
elif job_status == RenderStatus.RUNNING:
|
||||||
|
elapsed_time = str(datetime.datetime.now() - start_time)
|
||||||
|
|
||||||
# Project name
|
# Project name
|
||||||
project_name = job_color + job['name']
|
project_name = job_color + job['name']
|
||||||
@@ -174,20 +188,21 @@ def create_status_panel(all_server_data):
|
|||||||
return "no status"
|
return "no status"
|
||||||
|
|
||||||
|
|
||||||
class RenderDashboard:
|
class RenderServerProxy:
|
||||||
|
|
||||||
def __init__(self, server_ip=None, server_port="8080"):
|
def __init__(self, server_ip=None, server_port="8080"):
|
||||||
self.server_ip = server_ip
|
self.hostname = server_ip
|
||||||
self.server_port = server_port
|
self.port = server_port
|
||||||
self.local_hostname = local_hostname
|
self.local_hostname = local_hostname
|
||||||
|
self.fetched_status_data = None
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
status = self.request_data('status')
|
status = self.request_data('status')
|
||||||
return status
|
return status
|
||||||
|
|
||||||
def request_data(self, payload, timeout=2):
|
def request_data(self, payload, timeout=5):
|
||||||
try:
|
try:
|
||||||
req = requests.get(f'http://{self.server_ip}:{self.server_port}/{payload}', timeout=timeout)
|
req = requests.get(f'http://{self.hostname}:{self.port}/{payload}', timeout=timeout)
|
||||||
if req.ok:
|
if req.ok:
|
||||||
return req.json()
|
return req.json()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -204,8 +219,8 @@ class RenderDashboard:
|
|||||||
sorted_jobs.extend(found_jobs)
|
sorted_jobs.extend(found_jobs)
|
||||||
return sorted_jobs
|
return sorted_jobs
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self, timeout=5):
|
||||||
all_data = self.request_data('full_status', timeout=5)
|
all_data = self.request_data('full_status', timeout=timeout)
|
||||||
return all_data
|
return all_data
|
||||||
|
|
||||||
|
|
||||||
@@ -230,23 +245,23 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
get_server_ip = input("Enter server IP or None for local: ") or local_hostname
|
get_server_ip = input("Enter server IP or None for local: ") or local_hostname
|
||||||
|
|
||||||
client = RenderDashboard(get_server_ip, "8080")
|
server_proxy = RenderServerProxy(get_server_ip, "8080")
|
||||||
|
|
||||||
if not client.connect():
|
if not server_proxy.connect():
|
||||||
if client.server_ip == local_hostname:
|
if server_proxy.hostname == local_hostname:
|
||||||
start_server_input = input("Local server not running. Start server? (y/n) ")
|
start_server_input = input("Local server not running. Start server? (y/n) ")
|
||||||
if start_server_input and start_server_input[0].lower() == "y":
|
if start_server_input and start_server_input[0].lower() == "y":
|
||||||
# Startup the local server
|
# Startup the local server
|
||||||
start_server(background_thread=True)
|
start_server(background_thread=True)
|
||||||
test = client.connect()
|
test = server_proxy.connect()
|
||||||
print(f"connected? {test}")
|
print(f"connected? {test}")
|
||||||
else:
|
else:
|
||||||
print(f"\nUnable to connect to server: {client.server_ip}")
|
print(f"\nUnable to connect to server: {server_proxy.hostname}")
|
||||||
print("\nVerify IP address is correct and server is running")
|
print("\nVerify IP address is correct and server is running")
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
# start the Keyboard thread
|
# start the Keyboard thread
|
||||||
kthread = KeyboardThread(my_callback)
|
# kthread = KeyboardThread(my_callback)
|
||||||
|
|
||||||
# Console Layout
|
# Console Layout
|
||||||
console = Console()
|
console = Console()
|
||||||
@@ -268,34 +283,42 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
# Server connection header
|
# Server connection header
|
||||||
header_text = Text(f"Connected to server: ")
|
header_text = Text(f"Connected to server: ")
|
||||||
header_text.append(f"{client.server_ip} ", style="green")
|
header_text.append(f"{server_proxy.hostname} ", style="green")
|
||||||
if client.server_ip == local_hostname:
|
if server_proxy.hostname == local_hostname:
|
||||||
header_text.append("(This Computer)", style="yellow")
|
header_text.append("(This Computer)", style="yellow")
|
||||||
else:
|
else:
|
||||||
header_text.append("(Remote)", style="magenta")
|
header_text.append("(Remote)", style="magenta")
|
||||||
|
|
||||||
with Live(console=console, screen=False, refresh_per_second=1, transient=True) as live:
|
# background process to update server data independent of the UI
|
||||||
|
def fetch_server_data(server):
|
||||||
cached_server_data = None
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
server_data = client.get_data()
|
fetched_data = server.get_data(timeout=5)
|
||||||
if server_data:
|
if fetched_data:
|
||||||
cached_server_data = server_data
|
server.fetched_status_data = fetched_data
|
||||||
server_data['online'] = True
|
time.sleep(1)
|
||||||
else:
|
|
||||||
server_data = cached_server_data
|
|
||||||
if server_data:
|
|
||||||
server_data['online'] = False
|
|
||||||
|
|
||||||
|
x = threading.Thread(target=fetch_server_data, args=(server_proxy,))
|
||||||
|
x.daemon = True
|
||||||
|
x.start()
|
||||||
|
|
||||||
|
# draw and update the UI
|
||||||
|
with Live(console=console, screen=False, refresh_per_second=1, transient=True) as live:
|
||||||
|
while True:
|
||||||
try:
|
try:
|
||||||
if server_data:
|
if server_proxy.fetched_status_data:
|
||||||
layout["body"].update(create_jobs_table(server_data))
|
|
||||||
layout["side_top"].update(Panel(create_node_tree(server_data)))
|
|
||||||
layout["side_bottom"].update(Panel(create_status_panel(server_data)))
|
|
||||||
|
|
||||||
online_text = "Online" if server_data['online'] else "Offline"
|
server_online = False
|
||||||
online_color = "green" if server_data['online'] else "red"
|
if server_proxy.fetched_status_data.get('timestamp', None):
|
||||||
|
timestamp = datetime.datetime.fromisoformat(server_proxy.fetched_status_data['timestamp'])
|
||||||
|
time_diff = datetime.datetime.now() - timestamp
|
||||||
|
server_online = time_diff.seconds < 10 # client is offline if not updated in certain time
|
||||||
|
|
||||||
|
layout["body"].update(create_jobs_table(server_proxy.fetched_status_data))
|
||||||
|
layout["side_top"].update(Panel(create_node_tree(server_proxy.fetched_status_data)))
|
||||||
|
layout["side_bottom"].update(Panel(create_status_panel(server_proxy.fetched_status_data)))
|
||||||
|
|
||||||
|
online_text = "Online" if server_online else "Offline"
|
||||||
|
online_color = "green" if server_online else "red"
|
||||||
layout["header"].update(Panel(Text(f"Zordon Render Client - Version 0.0.1 alpha - {online_text}",
|
layout["header"].update(Panel(Text(f"Zordon Render Client - Version 0.0.1 alpha - {online_text}",
|
||||||
justify="center", style=online_color)))
|
justify="center", style=online_color)))
|
||||||
live.update(layout, refresh=False)
|
live.update(layout, refresh=False)
|
||||||
|
|||||||
Reference in New Issue
Block a user