cli-loading-bar/tui.py
2025-04-10 14:00:42 +02:00

123 lines
No EOL
3.7 KiB
Python

from tuicolors import WHITE, BRIGHT_BLACK, GREEN, RED
import os
import math
SPIN_STATUS = ['|','/','-','\\']
CORRECT = "\033[92mv\033[00m"
INCORRECT = "\033[91mX\033[00m"
UP_LINE = "\033[A"
def colourText(string: str, colour: int = WHITE, backgroundcolour: int = None) -> str:
if backgroundcolour is not None:
bg_code = backgroundcolour + 10
return f"\033[{colour};{bg_code}m{string}\033[0m"
else:
return f"\033[{colour}m{string}\033[0m"
def limitText(string: str, limit: int=-1) -> str:
if limit == -1:
limit = os.get_terminal_size().columns-3
if len(string) > limit:
return string[:limit]+"..."
else:
return string
class LoadingBar:
def __init__(self):
if os.get_terminal_size().columns < 57:
self.size = os.get_terminal_size().columns - 5
else:
self.size = 55
self.percentage = 0.0
self.spin = 0
self.line = []
self.first = True
self.max = -1
def addLine(self, line: int):
self.line = [""] * line
def updateLine(self, index: int, text: str):
self.line[index] = f"{text}{' '*(os.get_terminal_size().columns-len(text))}"
def setPercentage(self, percentage: float):
if percentage >= 0.0 and percentage <= 100.0:
self.percentage = percentage
def getPercentage(self) -> float:
return self.percentage
def setMaximum(self, max: int):
self.max = max
def getMaximum(self) -> int:
return self.max
def setValue(self, value: int):
if self.max == -1:
raise ValueError("Please set the maximum before setValue by calling LoadingBar.setMaximum()")
elif value > self.max:
raise ValueError(f"Cannot set a value superior to LoadingBar maximum: {self.max}")
else:
self.percentage = (value/self.max)*100.0
def incrementValue(self):
if self.max == -1:
raise ValueError("Please set the maximum before incrementValue by calling LoadingBar.setMaximum()")
value = math.floor((self.percentage/100.0)*self.max)+1
self.setValue(value)
def finish(self):
self.percentage = 100.0
def hasFinished(self) -> bool:
return self.percentage == 100.0
def updateSpin(self):
self.spin += 1
if self.spin >= len(SPIN_STATUS):
self.spin = 0
def getSpin(self) -> str:
if self.percentage >= 100.0:
return CORRECT
else:
return SPIN_STATUS[self.spin]
def getBackgroundColour(self) -> str:
if self.percentage >= 100.0:
return GREEN
else:
return WHITE
def getUpLine(self) -> str:
if not(self.first):
return UP_LINE*len(self.line)
else:
return ""
def start(self):
print("\n"*(len(self.line)+1), end='', flush=True)
def __str__(self) -> str:
filled = math.floor((self.percentage/100)*(self.size-5))
empty = (self.size-5)-filled
filled_str = colourText(" " * filled, backgroundcolour=self.getBackgroundColour())
empty_str = colourText(" " * empty, backgroundcolour=BRIGHT_BLACK)
formatted_percent = colourText(str(int(self.percentage)), self.getBackgroundColour())
ret = self.getUpLine()
for l in self.line:
ret += f"{l}\n"
ret += f"{self.getSpin()} {filled_str}{empty_str} {formatted_percent}%"
self.updateSpin()
self.first = False
return ret
def getLastEntry(filepath: str) -> str:
with open(filepath, "r") as log_file:
log_file.seek(0)
new_data = log_file.readlines()
if new_data:
last_line = new_data[-1].strip()
return last_line