From 562bb813795b383a88784f72763907066cdc2b5d Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Fri, 5 Mar 2021 17:09:12 +0100 Subject: [PATCH] Fixed output when console is spinning --- src/cpl/console/console.py | 63 +++++++++++++++++++++++++++---- src/cpl/console/console_call.py | 16 ++++++++ src/cpl/console/spinner_thread.py | 17 +++++---- 3 files changed, 82 insertions(+), 14 deletions(-) create mode 100644 src/cpl/console/console_call.py diff --git a/src/cpl/console/console.py b/src/cpl/console/console.py index 88d1cab3..33d5e385 100644 --- a/src/cpl/console/console.py +++ b/src/cpl/console/console.py @@ -8,6 +8,7 @@ from tabulate import tabulate from termcolor import colored from cpl.console.background_color import BackgroundColor +from cpl.console.console_call import ConsoleCall from cpl.console.foreground_color import ForegroundColor from cpl.console.spinner_thread import SpinnerThread @@ -21,6 +22,9 @@ class Console: _y: Optional[int] = None _disabled: bool = False + _hold_back = False + _hold_back_calls: list[ConsoleCall] = [] + """ Properties """ @@ -39,6 +43,10 @@ class Console: Settings """ + @classmethod + def set_hold_back(cls, value: bool): + cls._hold_back = value + @classmethod def set_background_color(cls, color: Union[BackgroundColor, str]): if type(color) is str: @@ -95,16 +103,25 @@ class Console: """ Useful public methods """ + @classmethod def banner(cls, string: str): if cls._disabled: return + if cls._hold_back: + cls._hold_back_calls.append(ConsoleCall(cls.banner, string)) + return + ascii_banner = pyfiglet.figlet_format(string) cls.write_line(ascii_banner) @classmethod def clear(cls): + if cls._hold_back: + cls._hold_back_calls.append(ConsoleCall(cls.clear)) + return + os.system('cls' if os.name == 'nt' else 'clear') @classmethod @@ -112,6 +129,10 @@ class Console: if cls._disabled: return + if cls._hold_back: + cls._hold_back_calls.append(ConsoleCall(cls.close)) + return + Console.reset() Console.write('\n\n\nPress any key to continue...') Console.read_line() @@ -126,6 +147,10 @@ class Console: if cls._disabled: return + if cls._hold_back: + cls._hold_back_calls.append(ConsoleCall(cls.error, string, tb)) + return + cls.set_foreground_color('red') if tb is not None: cls.write_line(f'{string} -> {tb}') @@ -139,14 +164,14 @@ class Console: @classmethod def read(cls, output: str = None) -> str: - if output is not None: + if output is not None and not cls._hold_back: cls.write(output) return input()[0] @classmethod def read_line(cls, output: str = None) -> str: - if cls._disabled: + if cls._disabled and not cls._hold_back: return '' if output is not None: @@ -164,6 +189,10 @@ class Console: if cls._disabled: return + if cls._hold_back: + cls._hold_back_calls.append(ConsoleCall(cls.table, header, values)) + return + table = tabulate(values, headers=header) Console.write_line(table) @@ -174,6 +203,10 @@ class Console: if cls._disabled: return + if cls._hold_back: + cls._hold_back_calls.append(ConsoleCall(cls.write, args)) + return + string = ' '.join(map(str, args)) cls._output(string, end='') @@ -182,6 +215,10 @@ class Console: if cls._disabled: return + if cls._hold_back: + cls._hold_back_calls.append(ConsoleCall(cls.write_at, x, y, args)) + return + string = ' '.join(map(str, args)) cls._output(string, x, y, end='') @@ -190,6 +227,10 @@ class Console: if cls._disabled: return + if cls._hold_back: + cls._hold_back_calls.append(ConsoleCall(cls.write_line, args)) + return + string = ' '.join(map(str, args)) if not cls._is_first_write: cls._output('') @@ -200,6 +241,10 @@ class Console: if cls._disabled: return + if cls._hold_back: + cls._hold_back_calls.append(ConsoleCall(cls.write_line_at, x, y, args)) + return + string = ' '.join(map(str, args)) if not cls._is_first_write: cls._output('', end='') @@ -207,14 +252,18 @@ class Console: @classmethod def spinner(cls, message: str, call: Callable) -> any: + if cls._hold_back: + cls._hold_back_calls.append(ConsoleCall(cls.spinner, message, call)) + return + cls.write_line(message) - spinner = SpinnerThread(cls) + cls.set_hold_back(True) + spinner = SpinnerThread() spinner.start() return_value = call() spinner.stop_spinning() + cls.set_hold_back(False) + for call in cls._hold_back_calls: + call.function(*call.args) return return_value - - @classmethod - def flush(cls): - sys.stdout.flush() diff --git a/src/cpl/console/console_call.py b/src/cpl/console/console_call.py new file mode 100644 index 00000000..ee4b3c46 --- /dev/null +++ b/src/cpl/console/console_call.py @@ -0,0 +1,16 @@ +from collections import Callable + + +class ConsoleCall: + + def __init__(self, function: Callable, *args): + self._func = function + self._args = args + + @property + def function(self): + return self._func + + @property + def args(self): + return self._args diff --git a/src/cpl/console/spinner_thread.py b/src/cpl/console/spinner_thread.py index ea810f33..2541e961 100644 --- a/src/cpl/console/spinner_thread.py +++ b/src/cpl/console/spinner_thread.py @@ -1,13 +1,13 @@ +import sys import threading import time class SpinnerThread(threading.Thread): - def __init__(self, console): + def __init__(self): threading.Thread.__init__(self) - self._console = console self._is_spinning = True @staticmethod @@ -17,16 +17,19 @@ class SpinnerThread(threading.Thread): yield cursor def run(self) -> None: - self._console.write('\t') + print('\t', end='') spinner = self._spinner() while self._is_spinning: - self._console.write(next(spinner)) + # self._console.write(next(spinner)) + print(next(spinner), end='') time.sleep(0.1) - self._console.write('\b') + # self._console.write('\b') + print('\b', end='') - self._console.flush() + sys.stdout.flush() - self._console.write(' ') + # self._console.write(' ') + print(' ', end='') def stop_spinning(self): self._is_spinning = False