import requests import tkinter as tk import threading import time import os from tkinter import ttk from new_job_window import NewJobWindow from server_proxy import RenderServerProxy def request_data(server_ip, payload, server_port=8080, timeout=2): try: req = requests.get(f'http://{server_ip}:{server_port}/api/{payload}', timeout=timeout) if req.ok: return req.json() except Exception as e: pass return None def sort_column(tree, col, reverse=False): data = [(tree.set(child, col), child) for child in tree.get_children('')] data.sort(reverse=reverse) for index, (_, child) in enumerate(data): tree.move(child, '', index) def make_sortable(tree): for col in tree["columns"]: tree.heading(col, text=col, command=lambda c=col: sort_column(tree, c)) class ZordonClient: def __init__(self): # Create a Treeview widget self.root = tk.Tk() self.tree = ttk.Treeview(self.root, show="headings") self.server_proxy = RenderServerProxy(hostname='localhost') self.job_cache = [] # Define the columns self.tree["columns"] = ("id", "Name", "Renderer", "Priority", "Status", "Time Elapsed", "Frames") # Format the columns self.tree.column("id", width=0, stretch=False) self.tree.column("Name", width=50) self.tree.column("Renderer", width=100, stretch=False) self.tree.column("Priority", width=50, stretch=False) self.tree.column("Status", width=100, stretch=False) self.tree.column("Time Elapsed", width=100, stretch=False) self.tree.column("Frames", width=50, stretch=False) # Create the column headings for name in self.tree['columns']: self.tree.heading(name, text=name) # Pack the Treeview widget self.tree.pack(fill=tk.BOTH, expand=False) new_job_button = tk.Button(self.root, text="New Job", command=self.show_new_job_window) new_job_button.pack() # Start the Tkinter event loop self.root.geometry("500x600+300+300") self.root.maxsize(width=2000, height=1200) self.root.minsize(width=600, height=600) make_sortable(self.tree) self.start_update_thread() def mainloop(self): self.root.mainloop() def start_update_thread(self): x = threading.Thread(target=self.__background_update) x.daemon = True x.start() def __background_update(self): while True: self.update_jobs(clear_table=False) time.sleep(1) def update_jobs(self, clear_table=False): def update_row(tree, id, new_values): for item in tree.get_children(): values = tree.item(item, "values") if values[0] == id: tree.item(item, values=new_values) break if clear_table: self.tree.delete(*self.tree.get_children()) self.job_cache = self.server_proxy.get_jobs() all_jobs = self.job_cache for job in all_jobs: display_status = job['status'] if job['status'] != 'running' else job['percent_complete'] values = (job['id'], job['name'] or os.path.basename(job['input_path']), job['renderer'] + "-" + job['renderer_version'], job['priority'], display_status, job['time_elapsed'], job['total_frames']) if self.tree.exists(job['id']): update_row(self.tree, job['id'], new_values=values) else: self.tree.insert("", tk.END, iid=job['id'], values=values) def show_new_job_window(self): new_window = tk.Toplevel(self.root) new_window.title("New Window") new_window.geometry("500x600+300+300") new_window.resizable(False, False) x = NewJobWindow(parent=new_window, hostname=self.server_proxy.hostname) x.pack() if __name__ == '__main__': x = ZordonClient() x.mainloop()