mirror of https://github.com/aristocratos/bpytop
Added load_config(), save_config(), get_themes() and changed DEFAULT_CONF to a string template
parent
e2de8e7401
commit
bea8bf084a
421
bpytop
421
bpytop
|
@ -19,6 +19,7 @@ import os, sys, time, threading, signal, re, subprocess, logging, logging.handle
|
|||
from select import select
|
||||
from pathlib import Path
|
||||
from distutils.util import strtobool
|
||||
from string import Template
|
||||
from typing import List, Set, Dict, Tuple, Optional, Union, Any, Callable, ContextManager, Iterable
|
||||
|
||||
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
|
||||
|
||||
#? Variables ------------------------------------------------------------------------------------->
|
||||
#? Constants ------------------------------------------------------------------------------------->
|
||||
|
||||
BANNER_SRC: Dict[str, str] = {
|
||||
"#E62525" : "██████╗ ██████╗ ██╗ ██╗████████╗ ██████╗ ██████╗",
|
||||
|
@ -62,63 +63,65 @@ BANNER_SRC: Dict[str, str] = {
|
|||
|
||||
VERSION: str = "0.0.1"
|
||||
|
||||
DEFAULT_CONF: str = f'#? Config file for bpytop v. {VERSION}\n'
|
||||
DEFAULT_CONF += '''
|
||||
#* This is the template used to create a new config file
|
||||
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 = "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_ms = 2500
|
||||
update_ms=$update_ms
|
||||
|
||||
#* Processes sorting, "pid" "program" "arguments" "threads" "user" "memory" "cpu lazy" "cpu responsive"
|
||||
#* "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
|
||||
proc_reversed = False
|
||||
proc_reversed=$proc_reversed
|
||||
|
||||
#* 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_temp = True
|
||||
check_temp=$check_temp
|
||||
|
||||
#* 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
|
||||
background_update = True
|
||||
background_update=$background_update
|
||||
|
||||
#* 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
|
||||
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
|
||||
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
|
||||
disks_filter = ""
|
||||
disks_filter="$disks_filter"
|
||||
|
||||
#* 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
|
||||
hires_graphs = False
|
||||
hires_graphs=$hires_graphs
|
||||
''')
|
||||
|
||||
'''
|
||||
|
||||
conf: Path = Path(f'{Path.home()}/.config/bpytop')
|
||||
if not conf.is_dir():
|
||||
CONFIG_DIR: str = f'{Path.home()}/.config/bpytop'
|
||||
if not os.path.isdir(CONFIG_DIR):
|
||||
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:
|
||||
print(f'ERROR!\nNo permission to write to "{conf}" directory!')
|
||||
print(f'ERROR!\nNo permission to write to "{CONFIG_DIR}" directory!')
|
||||
quit(1)
|
||||
|
||||
CONFIG_DIR: str = str(conf)
|
||||
del conf
|
||||
CONFIG_FILE: str = f'{CONFIG_DIR}/bpytop.conf'
|
||||
THEME_DIR: str = f'{CONFIG_DIR}/themes'
|
||||
USER_THEME_DIR: str = f'{CONFIG_DIR}/user_themes'
|
||||
|
||||
CORES: int = psutil.cpu_count(logical=False) or 1
|
||||
THREADS: int = psutil.cpu_count(logical=True) or 1
|
||||
|
@ -386,24 +389,24 @@ class Theme:
|
|||
|
||||
class Draw:
|
||||
'''Holds the draw buffer\n
|
||||
Add to buffer: .buffer(name, *args, now=False, clear=False)\n
|
||||
Print buffer: .out()\n
|
||||
Add to buffer: .buffer(name, *args, append=False, now=False)\n
|
||||
Print buffer: .out(clear=False)\n
|
||||
'''
|
||||
strings: Dict[str, str] = {}
|
||||
last_screen: str = ""
|
||||
|
||||
@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 = ""
|
||||
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
|
||||
if now: print(string)
|
||||
|
||||
@classmethod
|
||||
def out(cls):
|
||||
def out(cls, clear = False):
|
||||
cls.last_screen = "".join(cls.strings.values())
|
||||
#cls.strings = {}
|
||||
if clear: cls.strings = {}
|
||||
print(cls.last_screen)
|
||||
|
||||
class Symbol:
|
||||
|
@ -432,6 +435,101 @@ class Symbol:
|
|||
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 ------------------------------------------------------------------------------------->
|
||||
|
@ -469,9 +567,24 @@ def get_cpu_name():
|
|||
|
||||
return name
|
||||
|
||||
def load_theme(path: str) -> Dict[str, str]:
|
||||
'''Load a bashtop formatted theme file'''
|
||||
def get_themes() -> Dict[str, str]:
|
||||
'''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] = {}
|
||||
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:
|
||||
with open(path) as f:
|
||||
for line in f:
|
||||
|
@ -485,6 +598,49 @@ def load_theme(path: str) -> Dict[str, str]:
|
|||
|
||||
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:
|
||||
"""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 = ""
|
||||
|
@ -567,6 +723,7 @@ def quit_sigint(signum, frame):
|
|||
def clean_quit(errcode: int = 0):
|
||||
"""Reset terminal settings, save settings to config and stop background input read before quitting"""
|
||||
Key.stop()
|
||||
save_config(CONFIG_FILE, config)
|
||||
print(Term.clear, Term.normal_screen, Term.show_cursor)
|
||||
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
|
||||
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
|
||||
cpu.box_x = (cpu.width - 2) - cpu.box_width
|
||||
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
|
||||
|
||||
#? Main function --------------------------------------------------------------------------------->
|
||||
def draw_bg(now: bool = True):
|
||||
'''Draw all boxes to buffer and print to screen if now=True'''
|
||||
|
||||
def main():
|
||||
line: str = ""
|
||||
this_key: str = ""
|
||||
count: int = 0
|
||||
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 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}'
|
||||
|
||||
#? 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:
|
||||
out: List[str] = []
|
||||
|
@ -722,68 +875,47 @@ class Banner:
|
|||
if now: print(out)
|
||||
else: return out
|
||||
|
||||
class Config:
|
||||
'''Holds all config variables'''
|
||||
check_temp: bool = True
|
||||
#? Main function --------------------------------------------------------------------------------->
|
||||
|
||||
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
|
||||
def main():
|
||||
line: str = ""
|
||||
this_key: str = ""
|
||||
count: int = 0
|
||||
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)
|
||||
|
||||
|
||||
#? Init variables -------------------------------------------------------------------------------->
|
||||
#? Init ------------------------------------------------------------------------------------------>
|
||||
|
||||
#Key.start()
|
||||
|
||||
CPU_NAME: str = get_cpu_name()
|
||||
|
||||
config: Config = Config(load_config(CONFIG_FILE))
|
||||
|
||||
#theme = Theme(load_theme("/home/gnm/.config/bashtop/themes/monokai.theme"))
|
||||
theme = Theme(DEFAULT_THEME)
|
||||
config.proc_per_core = True
|
||||
|
||||
theme: Theme = Theme(load_theme(config.color_theme))
|
||||
|
||||
cpu = Box("cpu", height_p=32, width_p=100)
|
||||
mem = Box("mem", height_p=40, width_p=45)
|
||||
|
@ -798,39 +930,11 @@ orange = theme.available_end
|
|||
green = theme.cpu_start
|
||||
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():
|
||||
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(theme.temp_start, "Hej!\n")
|
||||
print(Term.fg, "\nHEJ\n")
|
||||
|
@ -840,23 +944,21 @@ def testing_colors():
|
|||
|
||||
def testing_banner():
|
||||
print(Term.normal_screen, Term.alt_screen)
|
||||
Key.start()
|
||||
#try:
|
||||
#sad
|
||||
#except Exception as e:
|
||||
# errlog.exception(f'{e}')
|
||||
#Key.start()
|
||||
|
||||
|
||||
|
||||
#eprint("Test")
|
||||
calc_sizes()
|
||||
|
||||
draw_bg()
|
||||
|
||||
Draw.buffer("banner", Banner.draw(18, 45), clear=True)
|
||||
Draw.buffer("banner", Banner.draw(18, 45))
|
||||
Draw.out()
|
||||
|
||||
print(Mv.to(35, 1), repr(Term.fg), " ", repr(Term.bg), "\n")
|
||||
print(Mv.to(35, 1))
|
||||
|
||||
|
||||
|
||||
quit()
|
||||
|
||||
|
||||
# quit()
|
||||
|
||||
|
@ -882,7 +984,7 @@ def testing_banner():
|
|||
# total_h += getattr(box, "height")
|
||||
# total_w += getattr(box, "width")
|
||||
# print(f'\nTotal Height={cpu.height + net.height + mem.height} Width={net.width + proc.width}')
|
||||
Key.stop()
|
||||
#Key.stop()
|
||||
quit()
|
||||
|
||||
|
||||
|
@ -892,6 +994,7 @@ def testing_banner():
|
|||
|
||||
try:
|
||||
testing_banner()
|
||||
#testing_colors()
|
||||
except Exception as e:
|
||||
errlog.exception(f'{e}')
|
||||
clean_quit(1)
|
||||
|
|
Loading…
Reference in New Issue