Spaces:
Paused
Paused
File size: 6,083 Bytes
8d1819a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
import os, webcolors, html
import sys
from datetime import datetime
from . import files
class PrintStyle:
last_endline = True
log_file_path = None
def __init__(self, bold=False, italic=False, underline=False, font_color="default", background_color="default", padding=False, log_only=False):
self.bold = bold
self.italic = italic
self.underline = underline
self.font_color = font_color
self.background_color = background_color
self.padding = padding
self.padding_added = False # Flag to track if padding was added
self.log_only = log_only
if PrintStyle.log_file_path is None:
logs_dir = files.get_abs_path("logs")
os.makedirs(logs_dir, exist_ok=True)
log_filename = datetime.now().strftime("log_%Y%m%d_%H%M%S.html")
PrintStyle.log_file_path = os.path.join(logs_dir, log_filename)
with open(PrintStyle.log_file_path, "w") as f:
f.write("<html><body style='background-color:black;font-family: Arial, Helvetica, sans-serif;'><pre>\n")
def _get_rgb_color_code(self, color, is_background=False):
try:
if color.startswith("#") and len(color) == 7:
r = int(color[1:3], 16)
g = int(color[3:5], 16)
b = int(color[5:7], 16)
else:
rgb_color = webcolors.name_to_rgb(color)
r, g, b = rgb_color.red, rgb_color.green, rgb_color.blue
if is_background:
return f"\033[48;2;{r};{g};{b}m", f"background-color: rgb({r}, {g}, {b});"
else:
return f"\033[38;2;{r};{g};{b}m", f"color: rgb({r}, {g}, {b});"
except ValueError:
return "", ""
def _get_styled_text(self, text):
start = ""
end = "\033[0m" # Reset ANSI code
if self.bold:
start += "\033[1m"
if self.italic:
start += "\033[3m"
if self.underline:
start += "\033[4m"
font_color_code, _ = self._get_rgb_color_code(self.font_color)
background_color_code, _ = self._get_rgb_color_code(self.background_color, True)
start += font_color_code
start += background_color_code
return start + text + end
def _get_html_styled_text(self, text):
styles = []
if self.bold:
styles.append("font-weight: bold;")
if self.italic:
styles.append("font-style: italic;")
if self.underline:
styles.append("text-decoration: underline;")
_, font_color_code = self._get_rgb_color_code(self.font_color)
_, background_color_code = self._get_rgb_color_code(self.background_color, True)
styles.append(font_color_code)
styles.append(background_color_code)
style_attr = " ".join(styles)
escaped_text = html.escape(text).replace("\n", "<br>") # Escape HTML special characters
return f'<span style="{style_attr}">{escaped_text}</span>'
def _add_padding_if_needed(self):
if self.padding and not self.padding_added:
if not self.log_only:
print() # Print an empty line for padding
self._log_html("<br>")
self.padding_added = True
def _log_html(self, html):
with open(PrintStyle.log_file_path, "a", encoding='utf-8') as f: # type: ignore # add encoding='utf-8'
f.write(html)
@staticmethod
def _close_html_log():
if PrintStyle.log_file_path:
with open(PrintStyle.log_file_path, "a") as f:
f.write("</pre></body></html>")
def get(self, *args, sep=' ', **kwargs):
text = sep.join(map(str, args))
# Automatically mask secrets in all print output
try:
if not hasattr(self, "secrets_mgr"):
from python.helpers.secrets import get_secrets_manager
self.secrets_mgr = get_secrets_manager()
text = self.secrets_mgr.mask_values(text)
except Exception:
# If masking fails, proceed without masking to avoid breaking functionality
pass
return text, self._get_styled_text(text), self._get_html_styled_text(text)
def print(self, *args, sep=' ', **kwargs):
self._add_padding_if_needed()
if not PrintStyle.last_endline:
print()
self._log_html("<br>")
plain_text, styled_text, html_text = self.get(*args, sep=sep, **kwargs)
if not self.log_only:
print(styled_text, end='\n', flush=True)
self._log_html(html_text+"<br>\n")
PrintStyle.last_endline = True
def stream(self, *args, sep=' ', **kwargs):
self._add_padding_if_needed()
plain_text, styled_text, html_text = self.get(*args, sep=sep, **kwargs)
if not self.log_only:
print(styled_text, end='', flush=True)
self._log_html(html_text)
PrintStyle.last_endline = False
def is_last_line_empty(self):
lines = sys.stdin.readlines()
return bool(lines) and not lines[-1].strip()
@staticmethod
def standard(text: str):
PrintStyle().print(text)
@staticmethod
def hint(text: str):
PrintStyle(font_color="#6C3483", padding=True).print("Hint: "+text)
@staticmethod
def info(text: str):
PrintStyle(font_color="#0000FF", padding=True).print("Info: "+text)
@staticmethod
def success(text: str):
PrintStyle(font_color="#008000", padding=True).print("Success: "+text)
@staticmethod
def warning(text: str):
PrintStyle(font_color="#FFA500", padding=True).print("Warning: "+text)
@staticmethod
def debug(text: str):
PrintStyle(font_color="#808080", padding=True).print("Debug: "+text)
@staticmethod
def error(text: str):
PrintStyle(font_color="red", padding=True).print("Error: "+text)
# Ensure HTML file is closed properly when the program exits
import atexit
atexit.register(PrintStyle._close_html_log)
|