1+ import os
12from pathlib import Path
23import queue
4+ import re
35import subprocess
46import threading
7+ import traceback
58from typing import Optional
69import sys
710import time
811from watchdog .observers import Observer
912from watchdog .events import FileSystemEvent , FileSystemEventHandler
13+
14+ class PrintColor :
15+ def __init__ (self ) -> None :
16+ self .ansi = (
17+ (sys .platform != 'Pocket PC' ) and
18+ (
19+ (sys .platform != 'win32' ) or
20+ ('ANSICON' in os .environ )
21+ ) and
22+ (
23+ sys .stdout .isatty () or
24+ (sys .platform == 'win32' )
25+ ) and
26+ (
27+ 'TERM' not in os .environ or
28+ (
29+ os .environ ['TERM' ].lower () in ('xterm' , 'linux' , 'screen' , 'vt100' , 'cygwin' , 'ansicon' ) and
30+ os .environ ['TERM' ].lower () not in ('dumb' , 'emacs' , 'emacs-24' , 'xterm-mono' )
31+ )
32+ )
33+ )
34+ self .colors = {
35+ 'reset' : '\033 [0m' ,
36+ 'red' : '\033 [31m' ,
37+ 'green' : '\033 [32m' ,
38+ 'yellow' : '\033 [33m' ,
39+ 'blue' : '\033 [34m' ,
40+ 'magenta' : '\033 [35m' ,
41+ 'cyan' : '\033 [36m' ,
42+ 'white' : '\033 [37m' ,
43+ 'black' : '\033 [30m' ,
44+ }
45+ self .open_tag_pattern = r'<(\w+)>'
46+ self .close_tag_pattern = r'<(\w+)/>'
47+
48+ def parse (self , text : str ):
49+ current_color = self .colors ['reset' ]
50+ open_tags = re .findall (self .open_tag_pattern , text )
51+ for tag in open_tags :
52+ if tag in self .colors :
53+ text = text .replace (f'<{ tag } >' , self .colors [tag ], 1 )
54+ current_color = self .colors [tag ]
55+ else :
56+ text = text .replace (f'<{ tag } >' , '' , 1 )
57+ close_tags = re .findall (self .close_tag_pattern , text )
58+ for tag in close_tags :
59+ if tag == tag .lower () and self .colors .get (tag .lower (), '' ) == current_color :
60+ text = text .replace (f'<{ tag } />' , self .colors ['reset' ], 1 )
61+ current_color = self .colors ['reset' ]
62+ return text
63+
64+ printColor = PrintColor ()
1065encoding = sys .getdefaultencoding ()
1166process : Optional [subprocess .Popen ] = None
1267stdout = None
@@ -55,10 +110,23 @@ def _err():
55110 else :
56111 output .put (line )
57112
58- def _parse (params ):
113+ def _parse (params : str ):
59114 kwargs = {}
60- if "flush" in params :
61- kwargs ["flush" ] = True
115+ for item in params .split ("," ):
116+ k , v = item .split (":" , 1 )
117+ if v == "True" :
118+ v = True
119+ elif v == "False" :
120+ v = False
121+ else :
122+ try :
123+ v = float (v )
124+ except :
125+ try :
126+ v = int (v )
127+ except :
128+ ...
129+ kwargs [k ] = v
62130 return kwargs
63131def _print ():
64132 global output , last_output_length , last_flush
@@ -71,22 +139,28 @@ def _print():
71139 msg = msg .decode ("gbk" )
72140 except :
73141 msg = repr (msg )
74- msg = msg .removesuffix ("\n " )
75- date = time .localtime ()
76- date = f"[{ date .tm_year :04d} -{ date .tm_mon :02d} -{ date .tm_mday :02d} { date .tm_hour :02d} :{ date .tm_min :02d} :{ date .tm_sec :02d} ]"
77- kwargs : dict = {}
78- flush : bool = False
79- if msg .startswith ("<<<" ) and ">>>" in msg :
80- kwargs = _parse (msg [3 :msg .find (">>>" )])
81- msg = msg [msg .find (">>>" ) + 3 :]
82- flush = kwargs .get ("flush" , False )
83- text = f"{ date } { msg } "
84- if flush :
85- sys .stdout .write ('\r ' + ' ' * (last_output_length + 16 ) + '\r ' )
86- sys .stdout .flush ()
87- last_output_length = len (text )
88- print (text + ('\n ' if not flush else '' ), end = '' , flush = flush )
89- last_flush = flush
142+ try :
143+ msg = msg .removesuffix ("\n " )
144+ date = time .localtime ()
145+ kwargs : dict = {}
146+ flush : bool = False
147+ if msg .startswith ("<<<" ) and ">>>" in msg :
148+ kwargs = _parse (msg [3 :msg .find (">>>" )])
149+ msg = msg [msg .find (">>>" ) + 3 :]
150+ flush = kwargs .get ("flush" , False )
151+ if 'time' in kwargs :
152+ date = time .localtime (kwargs ["time" ])
153+ date = f"[{ date .tm_year :04d} -{ date .tm_mon :02d} -{ date .tm_mday :02d} { date .tm_hour :02d} :{ date .tm_min :02d} :{ date .tm_sec :02d} ]"
154+ text = printColor .parse (f"<{ kwargs .get ('color' , 'reset' )} >{ date } { msg } " )
155+ if flush :
156+ sys .stdout .write ('\r ' + ' ' * (last_output_length + 16 ) + '\r ' )
157+ sys .stdout .flush ()
158+ last_output_length = len (text )
159+ print (text + ('\n ' if not flush else '' ), end = '' , flush = flush )
160+ last_flush = flush
161+ except :
162+ traceback .print_exc ()
163+ ...
90164
91165class MyHandler (FileSystemEventHandler ):
92166 def on_any_event (self , event : FileSystemEvent ) -> None :
0 commit comments