Added load_config(), save_config(), get_themes() and changed DEFAULT_CONF to a string template

pull/27/head
aristocratos 2020-07-02 02:40:53 +02:00
parent e2de8e7401
commit bea8bf084a
1 changed files with 262 additions and 159 deletions

421
bpytop
View File

@ -19,6 +19,7 @@ import os, sys, time, threading, signal, re, subprocess, logging, logging.handle
from select import select from select import select
from pathlib import Path from pathlib import Path
from distutils.util import strtobool from distutils.util import strtobool
from string import Template
from typing import List, Set, Dict, Tuple, Optional, Union, Any, Callable, ContextManager, Iterable from typing import List, Set, Dict, Tuple, Optional, Union, Any, Callable, ContextManager, Iterable
errors: List[str] = [] errors: List[str] = []
@ -49,7 +50,7 @@ from functools import partial
print: partial = partial(print, sep="", end="", flush=True) #* Setup print function to default to empty seperator and no new line print: partial = partial(print, sep="", end="", flush=True) #* Setup print function to default to empty seperator and no new line
#? Variables -------------------------------------------------------------------------------------> #? Constants ------------------------------------------------------------------------------------->
BANNER_SRC: Dict[str, str] = { BANNER_SRC: Dict[str, str] = {
"#E62525" : "██████╗ ██████╗ ██╗ ██╗████████╗ ██████╗ ██████╗", "#E62525" : "██████╗ ██████╗ ██╗ ██╗████████╗ ██████╗ ██████╗",
@ -62,63 +63,65 @@ BANNER_SRC: Dict[str, str] = {
VERSION: str = "0.0.1" VERSION: str = "0.0.1"
DEFAULT_CONF: str = f'#? Config file for bpytop v. {VERSION}\n' #* This is the template used to create a new config file
DEFAULT_CONF += ''' DEFAULT_CONF: Template = Template(f'#? Config file for bpytop v. {VERSION}' + '''
#* Color theme, looks for a .theme file in "~/.config/bpytop/themes" and "~/.config/bpytop/user_themes", "Default" for builtin default theme #* Color theme, looks for a .theme file in "~/.config/bpytop/themes" and "~/.config/bpytop/user_themes", "Default" for builtin default theme
color_theme = "Default" color_theme="$color_theme"
#* Update time in milliseconds, increases automatically if set below internal loops processing time, recommended 2000 ms or above for better sample times for graphs #* Update time in milliseconds, increases automatically if set below internal loops processing time, recommended 2000 ms or above for better sample times for graphs
update_ms = 2500 update_ms=$update_ms
#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu responsive" #* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu responsive"
#* "cpu lazy" updates sorting over time, "cpu responsive" updates sorting directly #* "cpu lazy" updates sorting over time, "cpu responsive" updates sorting directly
proc_sorting = "cpu lazy" proc_sorting="$proc_sorting"
#* Reverse sorting order, True or False #* Reverse sorting order, True or False
proc_reversed = False proc_reversed=$proc_reversed
#* Show processes as a tree #* Show processes as a tree
proc_tree = False proc_tree=$proc_tree
#* Check cpu temperature, only works if "sensors", "vcgencmd" or "osx-cpu-temp" commands is available #* Check cpu temperature, only works if "sensors", "vcgencmd" or "osx-cpu-temp" commands is available
check_temp = True check_temp=$check_temp
#* Draw a clock at top of screen, formatting according to strftime, empty string to disable #* Draw a clock at top of screen, formatting according to strftime, empty string to disable
draw_clock = "%X" draw_clock="$draw_clock"
#* Update main ui when menus are showing, set this to false if the menus is flickering too much for comfort #* Update main ui when menus are showing, set this to false if the menus is flickering too much for comfort
background_update = True background_update=$background_update
#* Custom cpu model name, empty string to disable #* Custom cpu model name, empty string to disable
custom_cpu_name = "" custom_cpu_name="$custom_cpu_name"
#* Show color gradient in process list, True or False #* Show color gradient in process list, True or False
proc_gradient = True proc_gradient=$proc_gradient
#* If process cpu usage should be of the core it's running on or usage of the total available cpu power #* If process cpu usage should be of the core it's running on or usage of the total available cpu power
proc_per_core = False proc_per_core=$proc_per_core
#* Optional filter for shown disks, should be names of mountpoints, "root" replaces "/", separate multiple values with space #* Optional filter for shown disks, should be names of mountpoints, "root" replaces "/", separate multiple values with space
disks_filter = "" disks_filter="$disks_filter"
#* Enable check for new version from github.com/aristocratos/bpytop at start #* Enable check for new version from github.com/aristocratos/bpytop at start
update_check = True update_check=$update_check
#* Enable graphs with double the horizontal resolution, increases cpu usage #* Enable graphs with double the horizontal resolution, increases cpu usage
hires_graphs = False hires_graphs=$hires_graphs
''')
''' CONFIG_DIR: str = f'{Path.home()}/.config/bpytop'
if not os.path.isdir(CONFIG_DIR):
conf: Path = Path(f'{Path.home()}/.config/bpytop')
if not conf.is_dir():
try: try:
conf.mkdir(mode=0o777, parents=True) os.makedirs(CONFIG_DIR)
os.mkdir(f'{CONFIG_DIR}/themes')
os.mkdir(f'{CONFIG_DIR}/user_themes')
except PermissionError: except PermissionError:
print(f'ERROR!\nNo permission to write to "{conf}" directory!') print(f'ERROR!\nNo permission to write to "{CONFIG_DIR}" directory!')
quit(1) quit(1)
CONFIG_FILE: str = f'{CONFIG_DIR}/bpytop.conf'
CONFIG_DIR: str = str(conf) THEME_DIR: str = f'{CONFIG_DIR}/themes'
del conf USER_THEME_DIR: str = f'{CONFIG_DIR}/user_themes'
CORES: int = psutil.cpu_count(logical=False) or 1 CORES: int = psutil.cpu_count(logical=False) or 1
THREADS: int = psutil.cpu_count(logical=True) or 1 THREADS: int = psutil.cpu_count(logical=True) or 1
@ -386,24 +389,24 @@ class Theme:
class Draw: class Draw:
'''Holds the draw buffer\n '''Holds the draw buffer\n
Add to buffer: .buffer(name, *args, now=False, clear=False)\n Add to buffer: .buffer(name, *args, append=False, now=False)\n
Print buffer: .out()\n Print buffer: .out(clear=False)\n
''' '''
strings: Dict[str, str] = {} strings: Dict[str, str] = {}
last_screen: str = "" last_screen: str = ""
@classmethod @classmethod
def buffer(cls, name: str, *args, now: bool = False, clear: bool = False): def buffer(cls, name: str, *args, append: bool = False, now: bool = False):
string: str = "" string: str = ""
if args: string = "".join(map(str, args)) if args: string = "".join(map(str, args))
if name not in cls.strings or clear: cls.strings[name] = "" if name not in cls.strings or not append: cls.strings[name] = ""
cls.strings[name] += string cls.strings[name] += string
if now: print(string) if now: print(string)
@classmethod @classmethod
def out(cls): def out(cls, clear = False):
cls.last_screen = "".join(cls.strings.values()) cls.last_screen = "".join(cls.strings.values())
#cls.strings = {} if clear: cls.strings = {}
print(cls.last_screen) print(cls.last_screen)
class Symbol: class Symbol:
@ -432,6 +435,101 @@ class Symbol:
4.0 : "⡇", 4.1 : "⡏", 4.2 : "⡟", 4.3 : "⡿", 4.4 : "⣿" 4.0 : "⡇", 4.1 : "⡏", 4.2 : "⡟", 4.3 : "⡿", 4.4 : "⣿"
} }
class Graphs:
'''Holds all graph objects and dicts for dynamically created graphs'''
cpu: object = None
cores: Dict[int, object] = {}
temps: Dict[int, object] = {}
net: object = None
detailed_cpu: object = None
detailed_mem: object = None
pid_cpu: Dict[int, object] = {}
class Meters:
'''Holds created meters to reuse instead of recreating meters of past values'''
cpu: Dict[int, str] = {}
mem_used: Dict[int, str] = {}
mem_available: Dict[int, str] = {}
mem_cached: Dict[int, str] = {}
mem_free: Dict[int, str] = {}
swap_used: Dict[int, str] = {}
swap_free: Dict[int, str] = {}
disks_used: Dict[int, str] = {}
disks_free: Dict[int, str] = {}
class Box:
'''Box object with all needed attributes for create_box() function'''
def __init__(self, name: str, height_p: int, width_p: int):
self.name: str = name
self.height_p: int = height_p
self.width_p: int = width_p
self.x: int = 0
self.y: int = 0
self.width: int = 0
self.height: int = 0
self.out: str = ""
if name == "proc":
self.detailed: bool = False
self.detailed_x: int = 0
self.detailed_y: int = 0
self.detailed_width: int = 0
self.detailed_height: int = 8
if name == "mem":
self.divider: int = 0
self.mem_width: int = 0
self.disks_width: int = 0
if name in ("cpu", "net"):
self.box_x: int = 0
self.box_y: int = 0
self.box_width: int = 0
self.box_height: int = 0
self.box_columns: int = 0
class Config:
'''Holds all config variables'''
keys: List[str] = ["color_theme", "update_ms", "proc_sorting", "proc_reversed", "proc_tree", "check_temp", "draw_clock", "background_update", "custom_cpu_name", "proc_gradient", "proc_per_core", "disks_filter", "update_check", "hires_graphs"]
conf_dict: Dict[str, Union[str, int, bool]] = {}
color_theme: str = "Default"
update_ms: int = 2500
proc_sorting: str = "cpu lazy"
proc_reversed: bool = False
proc_tree: bool = False
check_temp: bool = True
draw_clock: str = "%X"
background_update: bool = True
custom_cpu_name: str = ""
proc_gradient: bool = True
proc_per_core: bool = False
disks_filter: str = ""
update_check: bool = True
hires_graphs: bool = False
changed: bool = False
recreate: bool = False
__initialized: bool = False
def __init__(self, conf: Dict[str, Union[str, int, bool]]):
if not isinstance(conf, dict):
conf = {}
if not "version" in conf.keys() or conf["version"] != VERSION:
self.recreate = True
for key in self.keys:
if key in conf.keys():
setattr(self, key, conf[key])
else:
self.recreate = True
self.conf_dict[key] = getattr(self, key)
self.__initialized = True
def __setattr__(self, name, value):
if self.__initialized:
object.__setattr__(self, "changed", True)
object.__setattr__(self, name, value)
if name not in ["_Config__initialized", "recreate", "changed"]:
self.conf_dict[name] = value
#? Functions -------------------------------------------------------------------------------------> #? Functions ------------------------------------------------------------------------------------->
@ -469,9 +567,24 @@ def get_cpu_name():
return name return name
def load_theme(path: str) -> Dict[str, str]: def get_themes() -> Dict[str, str]:
'''Load a bashtop formatted theme file''' '''Returns a dict with names and paths to all found themes'''
found: Dict[str, str] = { "Default" : "Default" }
try:
for d in (THEME_DIR, USER_THEME_DIR):
for f in os.listdir(d):
if f.endswith(".theme"):
found[f'{f[:-6] if d == THEME_DIR else f[:-6] + "*"}'] = f'{d}/{f}'
except Exception as e:
errlog.exception(str(e))
return found
def load_theme(name: str) -> Dict[str, str]:
'''Load a bashtop formatted theme file and return a dict'''
new_theme: Dict[str, str] = {} new_theme: Dict[str, str] = {}
all_themes: Dict[str, str] = get_themes()
if name == "Default" or name not in all_themes.keys(): return DEFAULT_THEME
path: str = all_themes[name]
try: try:
with open(path) as f: with open(path) as f:
for line in f: for line in f:
@ -485,6 +598,49 @@ def load_theme(path: str) -> Dict[str, str]:
return new_theme return new_theme
def load_config(path: str) -> Dict[str, Union[str, int, bool]]:
'''Load config from file, set correct types for values and return a dict'''
new_config: Dict[str,Union[str, int, bool]] = {}
if not os.path.isfile(path): return new_config
try:
with open(path, "r") as f:
for line in f:
line = line.rstrip()
if line.startswith("#? Config"):
new_config["version"] = line[line.find("v. ") + 3:]
for key in Config.keys:
if line.startswith(key):
l = line.lstrip(key + "=")
if l.startswith('"'):
l = l.lstrip('"').rstrip('"')
if type(getattr(Config, key)) == type(int()):
try:
new_config[key] = int(l)
except Exception as e:
errlog.exception(str(e))
new_config[key] = ""
if type(getattr(Config, key)) == type(bool()):
try:
new_config[key] = bool(strtobool(l))
except Exception as e:
errlog.exception(str(e))
new_config[key] = ""
if type(getattr(Config, key)) == type(str()):
new_config[key] = str(l)
except Exception as e:
errlog.exception(str(e))
return new_config
def save_config(path: str, conf: Config):
'''Save current config to config file if difference in values or version, creates a new file if not found'''
if not conf.changed and not conf.recreate: return
try:
with open(path, "w" if os.path.isfile(path) else "x") as f:
f.write(DEFAULT_CONF.substitute(conf.conf_dict))
except Exception as e:
errlog.exception(str(e))
def fg(h_r: Union[str, int], g: int = 0, b: int = 0) -> str: def fg(h_r: Union[str, int], g: int = 0, b: int = 0) -> str:
"""Returns escape sequence to set foreground color, accepts either 6 digit hexadecimal: "#RRGGBB", 2 digit hexadecimal: "#FF" or decimal RGB: 0-255, 0-255, 0-255""" """Returns escape sequence to set foreground color, accepts either 6 digit hexadecimal: "#RRGGBB", 2 digit hexadecimal: "#FF" or decimal RGB: 0-255, 0-255, 0-255"""
color: str = "" color: str = ""
@ -567,6 +723,7 @@ def quit_sigint(signum, frame):
def clean_quit(errcode: int = 0): def clean_quit(errcode: int = 0):
"""Reset terminal settings, save settings to config and stop background input read before quitting""" """Reset terminal settings, save settings to config and stop background input read before quitting"""
Key.stop() Key.stop()
save_config(CONFIG_FILE, config)
print(Term.clear, Term.normal_screen, Term.show_cursor) print(Term.clear, Term.normal_screen, Term.show_cursor)
raise SystemExit(errcode) raise SystemExit(errcode)
@ -597,7 +754,7 @@ def calc_sizes():
elif THREADS > cpu.height - 5 and cpu.width > 100: cpu.box_width = 24 * 2; cpu.box_height = round(THREADS / 2) + 4; cpu.box_columns = 2 elif THREADS > cpu.height - 5 and cpu.width > 100: cpu.box_width = 24 * 2; cpu.box_height = round(THREADS / 2) + 4; cpu.box_columns = 2
else: cpu.box_width = 24; cpu.box_height = THREADS + 4; cpu.box_columns = 1 else: cpu.box_width = 24; cpu.box_height = THREADS + 4; cpu.box_columns = 1
if Config.check_temp: cpu.box_width += 13 * cpu.box_columns if config.check_temp: cpu.box_width += 13 * cpu.box_columns
if cpu.box_height > cpu.height - 3: cpu.box_height = cpu.height - 3 if cpu.box_height > cpu.height - 3: cpu.box_height = cpu.height - 3
cpu.box_x = (cpu.width - 2) - cpu.box_width cpu.box_x = (cpu.width - 2) - cpu.box_width
cpu.box_y = cpu.y + ((cpu.height - 2) // 2) - round(cpu.box_height / 2) + 2 cpu.box_y = cpu.y + ((cpu.height - 2) // 2) - round(cpu.box_height / 2) + 2
@ -659,37 +816,33 @@ def create_box(x: int = 0, y: int = 0, width: int = 0, height: int = 0, title: s
return out return out
#? Main function ---------------------------------------------------------------------------------> def draw_bg(now: bool = True):
'''Draw all boxes to buffer and print to screen if now=True'''
def main(): #* Draw cpu box and cpu sub box
line: str = "" cpu_box = f'{create_box(box_object=cpu, line_color=theme.cpu_box, fill=True)}\
this_key: str = "" {Mv.to(cpu.y, cpu.x + 10)}{theme.cpu_box(Symbol.title_left)}{Fx.b}{theme.hi_fg("m")}{theme.title("enu")}{Fx.ub}{theme.cpu_box(Symbol.title_right)}\
count: int = 0 {create_box(x=cpu.box_x, y=cpu.box_y, width=cpu.box_width, height=cpu.box_height, line_color=theme.div_line, title=CPU_NAME[:18 if config.check_temp else 9])}'
while True:
count += 1
print(f'{Mv.to(1,1)}{Fx.b}{blue("Count:")} {count} {lime("Time:")} {time.strftime("%H:%M:%S", time.localtime())}')
print(f'{fg("#ff")} Width: {Term.width} Height: {Term.height} Resized: {Term.resized}')
while Key.list:
Key.new.clear()
this_key = Key.list.pop()
print(f'{Mv.to(2,1)}{fg("#ff9050")}{Fx.b}Last key= {Term.fg}{Fx.ub}{repr(this_key)}{" " * 40}')
if this_key == "backspace":
line = line[:-1]
elif this_key == "enter":
line += "\n"
else:
line += this_key
print(f'{Mv.to(3,1)}{fg("#90ff50")}{Fx.b}Full line= {Term.fg}{Fx.ub}{line}{Fx.bl}| {Fx.ubl}')
if this_key == "q":
clean_quit()
if this_key == "R":
raise Exception("Test ERROR")
if not Key.reader.is_alive():
clean_quit(1)
Key.new.wait(1.0)
#* Draw mem/disk box and divider
mem_box = f'{create_box(box_object=mem, line_color=theme.mem_box, fill=True)}\
{Mv.to(mem.y, mem.divider + 2)}{theme.mem_box(Symbol.title_left)}{Fx.b}{theme.title("disks")}{Fx.ub}{theme.mem_box(Symbol.title_right)}\
{Mv.to(mem.y, mem.divider)}{theme.mem_box(Symbol.div_up)}\
{Mv.to(mem.y + mem.height, mem.divider)}{theme.mem_box(Symbol.div_down)}{theme.div_line}'
for i in range(1, mem.height):
mem_box += f'{Mv.to(mem.y + i, mem.divider)}{Symbol.v_line}'
#? Init Classes ----------------------------------------------------------------------------------> #* Draw net box and net sub box
net_box = f'{create_box(box_object=net, line_color=theme.net_box, fill=True)}\
{create_box(x=net.box_x, y=net.box_y, width=net.box_width, height=net.box_height, line_color=theme.div_line, title="Download")}\
{Mv.to(net.box_y + net.box_height, net.box_x + 1)}{theme.div_line(Symbol.title_left)}{Fx.b}{theme.title("Upload")}{Fx.ub}{theme.div_line(Symbol.title_right)}'
#* Draw proc box
proc_box = create_box(box_object=proc, line_color=theme.proc_box, fill=True)
Draw.buffer("bg", cpu_box, mem_box, net_box, proc_box)
#? Function dependent classes -------------------------------------------------------------------->
class Banner: class Banner:
out: List[str] = [] out: List[str] = []
@ -722,68 +875,47 @@ class Banner:
if now: print(out) if now: print(out)
else: return out else: return out
class Config: #? Main function --------------------------------------------------------------------------------->
'''Holds all config variables'''
check_temp: bool = True
class Graphs: def main():
'''Holds all graph objects and dicts for dynamically created graphs''' line: str = ""
cpu: object = None this_key: str = ""
cores: Dict[int, object] = {} count: int = 0
temps: Dict[int, object] = {} while True:
net: object = None count += 1
detailed_cpu: object = None print(f'{Mv.to(1,1)}{Fx.b}{blue("Count:")} {count} {lime("Time:")} {time.strftime("%H:%M:%S", time.localtime())}')
detailed_mem: object = None print(f'{fg("#ff")} Width: {Term.width} Height: {Term.height} Resized: {Term.resized}')
pid_cpu: Dict[int, object] = {} while Key.list:
Key.new.clear()
class Meters: this_key = Key.list.pop()
'''Holds created meters to reuse instead of recreating meters of past values''' print(f'{Mv.to(2,1)}{fg("#ff9050")}{Fx.b}Last key= {Term.fg}{Fx.ub}{repr(this_key)}{" " * 40}')
cpu: Dict[int, str] = {} if this_key == "backspace":
mem_used: Dict[int, str] = {} line = line[:-1]
mem_available: Dict[int, str] = {} elif this_key == "enter":
mem_cached: Dict[int, str] = {} line += "\n"
mem_free: Dict[int, str] = {} else:
swap_used: Dict[int, str] = {} line += this_key
swap_free: Dict[int, str] = {} print(f'{Mv.to(3,1)}{fg("#90ff50")}{Fx.b}Full line= {Term.fg}{Fx.ub}{line}{Fx.bl}| {Fx.ubl}')
disks_used: Dict[int, str] = {} if this_key == "q":
disks_free: Dict[int, str] = {} clean_quit()
if this_key == "R":
class Box: raise Exception("Test ERROR")
'''Box object with all needed attributes for create_box() function''' if not Key.reader.is_alive():
def __init__(self, name: str, height_p: int, width_p: int): clean_quit(1)
self.name: str = name Key.new.wait(1.0)
self.height_p: int = height_p
self.width_p: int = width_p
self.x: int = 0
self.y: int = 0
self.width: int = 0
self.height: int = 0
self.out: str = ""
if name == "proc":
self.detailed: bool = False
self.detailed_x: int = 0
self.detailed_y: int = 0
self.detailed_width: int = 0
self.detailed_height: int = 8
if name == "mem":
self.divider: int = 0
self.mem_width: int = 0
self.disks_width: int = 0
if name in ("cpu", "net"):
self.box_x: int = 0
self.box_y: int = 0
self.box_width: int = 0
self.box_height: int = 0
self.box_columns: int = 0
#? Init variables --------------------------------------------------------------------------------> #? Init ------------------------------------------------------------------------------------------>
#Key.start()
CPU_NAME: str = get_cpu_name() CPU_NAME: str = get_cpu_name()
config: Config = Config(load_config(CONFIG_FILE))
#theme = Theme(load_theme("/home/gnm/.config/bashtop/themes/monokai.theme")) config.proc_per_core = True
theme = Theme(DEFAULT_THEME)
theme: Theme = Theme(load_theme(config.color_theme))
cpu = Box("cpu", height_p=32, width_p=100) cpu = Box("cpu", height_p=32, width_p=100)
mem = Box("mem", height_p=40, width_p=45) mem = Box("mem", height_p=40, width_p=45)
@ -798,39 +930,11 @@ orange = theme.available_end
green = theme.cpu_start green = theme.cpu_start
dfg = theme.main_fg dfg = theme.main_fg
def draw_bg(now: bool = True):
'''Draw all boxes to buffer and print to screen if now=True'''
Draw.buffer("bg", clear=True)
#* Draw cpu box and cpu sub box
cpu_box = f'{create_box(box_object=cpu, line_color=theme.cpu_box, fill=True)}\
{Mv.to(cpu.y, cpu.x + 10)}{theme.cpu_box(Symbol.title_left)}{Fx.b}{theme.hi_fg("m")}{theme.title("enu")}{Fx.ub}{theme.cpu_box(Symbol.title_right)}\
{create_box(x=cpu.box_x, y=cpu.box_y, width=cpu.box_width, height=cpu.box_height, line_color=theme.div_line, title=CPU_NAME[:18 if Config.check_temp else 9])}'
#* Draw mem/disk box and divider
mem_box = f'{create_box(box_object=mem, line_color=theme.mem_box, fill=True)}\
{Mv.to(mem.y, mem.divider + 2)}{theme.mem_box(Symbol.title_left)}{Fx.b}{theme.title("disks")}{Fx.ub}{theme.mem_box(Symbol.title_right)}\
{Mv.to(mem.y, mem.divider)}{theme.mem_box(Symbol.div_up)}\
{Mv.to(mem.y + mem.height, mem.divider)}{theme.mem_box(Symbol.div_down)}{theme.div_line}'
for i in range(1, mem.height):
mem_box += f'{Mv.to(mem.y + i, mem.divider)}{Symbol.v_line}'
#* Draw net box and net sub box
net_box = f'{create_box(box_object=net, line_color=theme.net_box, fill=True)}\
{create_box(x=net.box_x, y=net.box_y, width=net.box_width, height=net.box_height, line_color=theme.div_line, title="Download")}\
{Mv.to(net.box_y + net.box_height, net.box_x + 1)}{theme.div_line(Symbol.title_left)}{Fx.b}{theme.title("Upload")}{Fx.ub}{theme.div_line(Symbol.title_right)}'
#* Draw proc box
proc_box = create_box(box_object=proc, line_color=theme.proc_box, fill=True)
Draw.buffer("bg", cpu_box, mem_box, net_box, proc_box)
def testing_colors(): def testing_colors():
for item, _ in DEFAULT_THEME.items(): for item, _ in DEFAULT_THEME.items():
print(Fx.b, getattr(theme, item)(f'{item:<20}'), Fx.ub, f'{"hex=" + getattr(theme, item).hex:<20} dec={getattr(theme, item).dec}', end="\n") Draw.buffer("testing", Fx.b, getattr(theme, item)(f'{item:<20}'), Fx.ub, f'{"hex=" + getattr(theme, item).hex:<20} dec={getattr(theme, item).dec}\n')
Draw.out()
print() print()
print(theme.temp_start, "Hej!\n") print(theme.temp_start, "Hej!\n")
print(Term.fg, "\nHEJ\n") print(Term.fg, "\nHEJ\n")
@ -840,23 +944,21 @@ def testing_colors():
def testing_banner(): def testing_banner():
print(Term.normal_screen, Term.alt_screen) print(Term.normal_screen, Term.alt_screen)
Key.start() #Key.start()
#try:
#sad
#except Exception as e:
# errlog.exception(f'{e}')
#eprint("Test")
calc_sizes() calc_sizes()
draw_bg() draw_bg()
Draw.buffer("banner", Banner.draw(18, 45), clear=True) Draw.buffer("banner", Banner.draw(18, 45))
Draw.out() Draw.out()
print(Mv.to(35, 1), repr(Term.fg), " ", repr(Term.bg), "\n") print(Mv.to(35, 1))
quit()
# quit() # quit()
@ -882,7 +984,7 @@ def testing_banner():
# total_h += getattr(box, "height") # total_h += getattr(box, "height")
# total_w += getattr(box, "width") # total_w += getattr(box, "width")
# print(f'\nTotal Height={cpu.height + net.height + mem.height} Width={net.width + proc.width}') # print(f'\nTotal Height={cpu.height + net.height + mem.height} Width={net.width + proc.width}')
Key.stop() #Key.stop()
quit() quit()
@ -892,6 +994,7 @@ def testing_banner():
try: try:
testing_banner() testing_banner()
#testing_colors()
except Exception as e: except Exception as e:
errlog.exception(f'{e}') errlog.exception(f'{e}')
clean_quit(1) clean_quit(1)