added table manager, to manage tables and handle the treeview

This commit is contained in:
UpstreamData
2022-05-05 15:53:13 -06:00
parent 26c6e47f1e
commit 725b14e583
7 changed files with 166 additions and 87 deletions

View File

@@ -42,17 +42,19 @@ from settings import (
)
class MinerFactory:
_instance = None
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class MinerFactory(metaclass=Singleton):
def __init__(self):
self.miners = {}
def __new__(cls):
if not cls._instance:
cls._instance = super(MinerFactory, cls).__new__(cls)
return cls._instance
async def get_miner_generator(self, ips: list):
"""
Get Miner objects from ip addresses using an async generator.

View File

@@ -1,12 +1,9 @@
import PySimpleGUI as sg
import asyncio
import sys
import base64
from io import BytesIO
from PIL import ImageTk, Image
from tools.cfg_util.cfg_util_qt.imgs import FAULT_LIGHT, TkImages
from tools.cfg_util.cfg_util_qt.tables import clear_tables, _update_tree_by_ip
from tools.cfg_util.cfg_util_qt.scan import btn_scan
from tools.cfg_util.cfg_util_qt.commands import btn_light
from tools.cfg_util.cfg_util_qt.layout import window
from tools.cfg_util.cfg_util_qt.general import btn_all
import tkinter as tk
@@ -46,6 +43,10 @@ async def main():
if event == "cmd_all":
_table = "cmd_table"
btn_all(_table, value[_table])
if event == "cmd_light":
_table = "cmd_table"
_ips = value[_table]
await btn_light(_ips)
if event == "__TIMEOUT__":
await asyncio.sleep(0)

View File

@@ -0,0 +1,20 @@
from tools.cfg_util.cfg_util_qt.layout import window
from tools.cfg_util.cfg_util_qt.tables import update_tree
from tools.cfg_util.cfg_util_qt.imgs import TkImages
async def btn_light(ips: list):
_table = window["cmd_table"].Widget
data = []
iids = _table.get_children()
for idx in ips:
item = _table.item(iids[idx])
data.append(
{
"IP": item["values"][0],
"Model": item["values"][1],
"Command Output": item["values"][2],
"Light": True,
}
)
await update_tree(data)

View File

@@ -8,9 +8,16 @@ FAULT_LIGHT = b"iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAA
LIGHT = b"iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACkSURBVChThZDhDcIgEIWBLuAe8N90kAa2MDWdw8YtIEzgBF0AdJviey0aNWn9kiv3Li8vvZOiYq3tpJQ92nadiFhKiSGESLEYnXMXPCeUov5gRl2992dZkzwGv6YXM5KdgqmD2DIRenoaaPxHu5f0BY3T2u4SFX50RMPttuAysck5340xBwyOqPddK8t5cMuxoUop3bTWD2xHqfkBE5IGmoQQ4gmmsjUl2gChkgAAAABJRU5ErkJggg=="
class TkImages:
_instance = None
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class TkImages(metaclass=Singleton):
def __init__(self):
self.fault_light = ImageTk.PhotoImage(
Image.open(BytesIO(base64.b64decode(FAULT_LIGHT)))
@@ -18,8 +25,3 @@ class TkImages:
self.light = ImageTk.PhotoImage(
Image.open(BytesIO(base64.b64decode(FAULT_LIGHT)))
)
def __new__(cls):
if not cls._instance:
cls._instance = super(TkImages, cls).__new__(cls)
return cls._instance

View File

@@ -14,7 +14,6 @@ TABLE_HEADERS = {
"CMD": ["IP", "Model", "Command Output"],
"POOLS": [
"IP",
# "Model",
"Split",
"Pool 1",
"Pool 1 User",
@@ -134,8 +133,6 @@ def get_scan_layout():
def get_command_layout():
data = sg.TreeData()
data.insert("", 0, "", ["", "", ""], icon=FAULT_LIGHT)
data.insert("", 1, "", ["192.168.1.13", "", ""], icon=LIGHT)
col_widths = [
IP_COL_WIDTH,
MODEL_COL_WIDTH,

View File

@@ -11,6 +11,20 @@ import logging
progress_bar_len = 0
DEFAULT_DATA = [
"Model",
"Hostname",
"Hashrate",
"Temperature",
"Pool User",
"Pool 1",
"Pool 1 User",
"Pool 2",
"Pool 2 User",
"Wattage",
"Split",
]
async def btn_all():
table = "scan_table"
@@ -53,7 +67,15 @@ async def _scan_miners(network: MinerNetwork):
async for found_miner in get_miner_genenerator:
resolved_miners.append(found_miner)
resolved_miners.sort(key=lambda x: x.ip)
update_tables([{"IP": str(miner.ip)} for miner in resolved_miners])
resolved_miners_data = []
for miner in resolved_miners:
_data = {}
for key in DEFAULT_DATA:
_data[key] = ""
_data["IP"] = str(miner.ip)
_data["Light"] = False
resolved_miners_data.append(_data)
update_tables(resolved_miners_data)
progress_bar_len += 1
await update_prog_bar(progress_bar_len)
progress_bar_len += network_size - len(resolved_miners)
@@ -68,7 +90,6 @@ async def _get_miners_data(miners: list):
for all_data in data_generator:
data = await all_data
for idx, item in enumerate(miner_data):
# print(item["IP"], data["IP"])
if item["IP"] == data["IP"]:
miner_data[idx] = data
update_tables(miner_data)

View File

@@ -21,69 +21,105 @@ def update_miner_count(count):
window[button].update(f"Miners: {count}")
def update_tables(data: list):
tables = {
"SCAN": [["" for _ in TABLE_HEADERS["SCAN"]] for _ in data],
"CMD": [["" for _ in TABLE_HEADERS["CMD"]] for _ in data],
"POOLS": [["" for _ in TABLE_HEADERS["POOLS"]] for _ in data],
"CONFIG": [["" for _ in TABLE_HEADERS["CONFIG"]] for _ in data],
}
for data_idx, item in enumerate(data):
keys = item.keys()
if "Hashrate" in keys:
if not isinstance(item["Hashrate"], str):
item[
"Hashrate"
] = f"{format(float(item['Hashrate']), '.2f').rjust(6, ' ')} TH/s"
for key in keys:
for table in TABLE_HEADERS.keys():
for idx, header in enumerate(TABLE_HEADERS[table]):
if key == header:
tables[table][data_idx][idx] = item[key]
window["scan_table"].update(tables["SCAN"])
window["pools_table"].update(tables["POOLS"])
window["cfg_table"].update(tables["CONFIG"])
treedata = sg.TreeData()
for idx, item in enumerate(tables["CMD"]):
treedata.insert("", idx, "", item, icon=LIGHT)
window["cmd_table"].update(treedata)
update_miner_count(len(data))
def update_tables(data: list or None = None):
table_manager = TableManager()
table_manager.update_tables(data)
async def _update_tree_by_ip(ip: str, data: dict):
keys = data.keys()
img = None
if "IP" not in keys or "Model" not in keys:
return
_tree = window["cmd_table"].Widget
for iid in _tree.get_children():
values = _tree.item(iid)["values"]
if data.get("Light"):
if data["Light"]:
img = TkImages().fault_light
if not data["Light"]:
img = TkImages().light
if values[0] == ip:
if img:
_tree.item(
iid,
image=img,
values=[
data["IP"],
data["Model"] if "Model" in keys else "",
data["Command Output"] if "Command Output" in keys else "",
],
)
else:
_tree.item(
iid,
values=[
data["IP"],
data["Model"] if "Model" in keys else "",
data["Command Output"] if "Command Output" in keys else "",
],
)
async def update_tree(data: list):
for item in data:
if not item.get("IP"):
continue
table_manager = TableManager()
table_manager.update_tree_by_key(item, "IP")
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class TableManager(metaclass=Singleton):
_instance = None
def __init__(self):
self.images = TkImages()
self.data = []
def update_tables(self, data: list or None = None):
if not data or data == []:
data = self.data
self.data = data
tables = {
"SCAN": [["" for _ in TABLE_HEADERS["SCAN"]] for _ in data],
"CMD": [["" for _ in TABLE_HEADERS["CMD"]] for _ in data],
"POOLS": [["" for _ in TABLE_HEADERS["POOLS"]] for _ in data],
"CONFIG": [["" for _ in TABLE_HEADERS["CONFIG"]] for _ in data],
}
for data_idx, item in enumerate(data):
keys = item.keys()
if "Hashrate" in keys:
if not isinstance(item["Hashrate"], str):
item[
"Hashrate"
] = f"{format(float(item['Hashrate']), '.2f').rjust(6, ' ')} TH/s"
for key in keys:
for table in TABLE_HEADERS.keys():
for idx, header in enumerate(TABLE_HEADERS[table]):
if key == header:
tables[table][data_idx][idx] = item[key]
window["scan_table"].update(tables["SCAN"])
window["pools_table"].update(tables["POOLS"])
window["cfg_table"].update(tables["CONFIG"])
treedata = sg.TreeData()
for idx, item in enumerate(tables["CMD"]):
treedata.insert("", idx, "", item, icon=LIGHT)
window["cmd_table"].update(treedata)
update_miner_count(len(data))
def update_tree_by_key(self, data: dict, key: str = "IP"):
for idx, item in enumerate(self.data):
if key in item.keys():
if data[key] == item[key]:
self.data[idx] = data
keys = data.keys()
img = None
if key not in keys:
return
_tree = window["cmd_table"].Widget
for iid in _tree.get_children():
values = _tree.item(iid)["values"]
if data.get("Light"):
if data["Light"]:
img = self.images.fault_light
if not data["Light"]:
img = self.images.light
if values[0] == data["IP"]:
if img:
_tree.item(
iid,
image=img,
values=[
data["IP"],
data["Model"] if "Model" in keys else "",
data["Command Output"] if "Command Output" in keys else "",
],
)
else:
_tree.item(
iid,
values=[
data["IP"],
data["Model"] if "Model" in keys else "",
data["Command Output"] if "Command Output" in keys else "",
],
)