66Usage: Create a Console object and call the appropriate method to print messages.
77"""
88
9- from traceback import print_exc
9+ from logging import DEBUG , ERROR , INFO , basicConfig , getLogger
1010
11- from colorama import Back , Fore , Style , init
12-
13- # Constants.
14- TAB_BLOCK = "\t \t "
11+ from rich .logging import RichHandler
12+ from rich .traceback import install
1513
1614
1715class Console :
@@ -21,34 +19,59 @@ def __init__(self, *, enable_debug: bool) -> None:
2119 :param enable_debug: Enable debug mode.
2220 :type enable_debug: bool
2321 """
24- self ._enable_debug = enable_debug
25-
2622 # Repeat message fields.
27- self ._last_message = ""
28- self ._repeat_counter = 1
23+ self ._last_message = ( 0 , "" , "" )
24+ self ._repeat_counter = 0
2925
30- # Initialize colorama.
31- init (autoreset = True )
26+ # Config logger.
27+ basicConfig (
28+ level = DEBUG if enable_debug else INFO ,
29+ format = "%(message)s" ,
30+ datefmt = "[%I:%M:%S %p]" ,
31+ handlers = [RichHandler (rich_tracebacks = True )],
32+ )
33+ self ._log = getLogger ("rich" )
3234
33- @staticmethod
34- def error_print (msg : str ) -> None :
35- """Print an error message to the console.
35+ # Install Rich traceback.
36+ install ()
3637
37- :param msg: Error message to print.
38+ def debug_print (self , label : str , msg : str ) -> None :
39+ """Print a debug message to the console.
40+
41+ :param label: Label for the debug message.
42+ :type label: str
43+ :param msg: Debug message to print.
3844 :type msg: str
3945 """
40- print ( f" \n { Back . RED } { Style . BRIGHT } ERROR { Style . RESET_ALL } { TAB_BLOCK } { Fore . RED } { msg } " )
46+ self . _repeatable_log ( DEBUG , f"[b green] { label } " , f"[green] { msg } " )
4147
42- @staticmethod
43- def labeled_error_print (label : str , msg : str ) -> None :
44- """Print an error message with a label to the console.
48+ def info_print (self , label : str , msg : str ) -> None :
49+ """Print info to console.
50+
51+ :param label: Label for the message.
52+ :type label: str
53+ :param msg: Message to print.
54+ :type msg: str
55+ """
56+ self ._repeatable_log (INFO , f"[b blue]{ label } " , msg )
57+
58+ def error_print (self , label : str , msg : str ) -> None :
59+ """Print an error message to the console.
4560
4661 :param label: Label for the error message.
4762 :type label: str
4863 :param msg: Error message to print.
4964 :type msg: str
5065 """
51- print (f"\n { Back .RED } { Style .BRIGHT } ERROR { label } { Style .RESET_ALL } { TAB_BLOCK } { Fore .RED } { msg } " )
66+ self ._repeatable_log (ERROR , f"[b red]{ label } " , f"[red]{ msg } " )
67+
68+ def critical_print (self , msg : str ) -> None :
69+ """Print a critical message to the console.
70+
71+ :param msg: Critical message to print.
72+ :type msg: str
73+ """
74+ self ._log .critical (f"[b i red]{ msg } " , extra = {"markup" : True })
5275
5376 @staticmethod
5477 def pretty_exception (exception : Exception ) -> str :
@@ -61,52 +84,50 @@ def pretty_exception(exception: Exception) -> str:
6184 """
6285 return f"{ type (exception ).__name__ } : { exception } "
6386
64- @staticmethod
65- def exception_error_print (label : str , exception : Exception ) -> None :
87+ def exception_error_print (self , label : str , exception : Exception ) -> None :
6688 """Print an error message with exception details to the console.
6789
6890 :param label: Label for the error message.
6991 :type label: str
7092 :param exception: Exception to print.
7193 :type exception: Exception
7294 """
73- Console .labeled_error_print (label , Console .pretty_exception (exception ))
74- print_exc ()
75-
76- def debug_print (self , label : str , msg : str ) -> None :
77- """Print a debug message to the console.
78-
79- :param label: Label for the debug message.
80- :type label: str
81- :param msg: Debug message to print.
82- :type msg: str
83- """
84- if self ._enable_debug :
85- self ._repeat_print (f"{ Back .BLUE } { Style .BRIGHT } DEBUG { label } { Style .RESET_ALL } { TAB_BLOCK } { Fore .BLUE } { msg } " )
95+ self ._log .exception (
96+ f"[b magenta]{ label } :[/] [magenta]{ Console .pretty_exception (exception )} " , extra = {"markup" : True }
97+ )
8698
87- @ staticmethod
88- def info_print ( label : str , msg : str ) -> None :
89- """Print info to console .
99+ # Helper methods.
100+ def _repeatable_log ( self , log_type : int , label : str , message : str ) -> None :
101+ """Add a row to the output table .
90102
103+ :param log_type: Type of log.
104+ :type log_type: int
91105 :param label: Label for the message.
92106 :type label: str
93- :param msg : Message to print .
94- :type msg : str
107+ :param message : Message.
108+ :type message : str
95109 """
96- print (f"\n { Back .GREEN } { Style .BRIGHT } { label } { Style .RESET_ALL } { TAB_BLOCK } { Fore .GREEN } { msg } " )
97-
98- # Helper methods.
99- def _repeat_print (self , msg : str ) -> None :
100- """Print a message to the console with repeat counter.
101110
102- :param msg: Message to print .
103- :type msg: str
104- """
105- if msg == self . _last_message :
111+ # Compute if this is a repeated message .
112+ message_set = ( log_type , label , message )
113+ if message_set == self . _last_message :
114+ # Handle repeat.
106115 self ._repeat_counter += 1
107- else :
108- self ._repeat_counter = 1
109- self ._last_message = msg
110- print ()
111116
112- print (f"\r { msg } { f" (x{ self ._repeat_counter } )" if self ._repeat_counter > 1 else "" } " , end = "" )
117+ # Add an ellipsis row for first repeat.
118+ if self ._repeat_counter == 1 :
119+ self ._log .log (log_type , "..." )
120+ else :
121+ # Handle novel message.
122+ if self ._repeat_counter > 0 :
123+ # Complete previous repeat.
124+ self ._log .log (
125+ self ._last_message [0 ],
126+ f"{ self ._last_message [1 ]} :[/] { self ._last_message [2 ]} [/] x { self ._repeat_counter } " ,
127+ extra = {"markup" : True },
128+ )
129+ self ._repeat_counter = 0
130+
131+ # Log new message.
132+ self ._log .log (log_type , f"{ label } :[/] { message } " , extra = {"markup" : True })
133+ self ._last_message = message_set
0 commit comments