Files
ArchiveBox/archivebox/misc/logging.py
Nick Sweeting b749b26c5d wip
2026-03-23 03:58:32 -07:00

94 lines
3.0 KiB
Python

__package__ = "archivebox.misc"
# Low-level logging primitives (Rich console, ANSI colors, stdout/stderr helpers)
# Higher-level logging functions are in logging_util.py
import sys
from collections import defaultdict
from random import randint
from benedict import benedict
from rich.console import Console
from rich.highlighter import Highlighter
# SETUP RICH CONSOLE / TTY detection / COLOR / PROGRESS BARS
# Disable wrapping - use soft_wrap=True and large width so text flows naturally
# Colors are preserved, just no hard line breaks inserted
CONSOLE = Console(width=32768, soft_wrap=True, force_terminal=True)
STDERR = Console(stderr=True, width=32768, soft_wrap=True, force_terminal=True)
IS_TTY = sys.stdout.isatty()
class RainbowHighlighter(Highlighter):
def highlight(self, text):
for index in range(len(text)):
text.stylize(f"color({randint(90, 98)})", index, index + 1)
rainbow = RainbowHighlighter()
DEFAULT_CLI_COLORS = benedict(
{
"reset": "\033[00;00m",
"lightblue": "\033[01;30m",
"lightyellow": "\033[01;33m",
"lightred": "\033[01;35m",
"red": "\033[01;31m",
"green": "\033[01;32m",
"blue": "\033[01;34m",
"white": "\033[01;37m",
"black": "\033[01;30m",
},
)
ANSI = benedict({k: "" for k in DEFAULT_CLI_COLORS.keys()})
COLOR_DICT = defaultdict(
lambda: [(0, 0, 0), (0, 0, 0)],
{
"00": [(0, 0, 0), (0, 0, 0)],
"30": [(0, 0, 0), (0, 0, 0)],
"31": [(255, 0, 0), (128, 0, 0)],
"32": [(0, 200, 0), (0, 128, 0)],
"33": [(255, 255, 0), (128, 128, 0)],
"34": [(0, 0, 255), (0, 0, 128)],
"35": [(255, 0, 255), (128, 0, 128)],
"36": [(0, 255, 255), (0, 128, 128)],
"37": [(255, 255, 255), (255, 255, 255)],
},
)
# Logging Helpers (DEPRECATED, use rich.print instead going forward)
def stdout(*args, color: str | None = None, prefix: str = "", config: benedict | None = None) -> None:
ansi = DEFAULT_CLI_COLORS if (config or {}).get("USE_COLOR") else ANSI
if color:
strs = [ansi[color], " ".join(str(a) for a in args), ansi["reset"], "\n"]
else:
strs = [" ".join(str(a) for a in args), "\n"]
sys.stdout.write(prefix + "".join(strs))
def stderr(*args, color: str | None = None, prefix: str = "", config: benedict | None = None) -> None:
ansi = DEFAULT_CLI_COLORS if (config or {}).get("USE_COLOR") else ANSI
if color:
strs = [ansi[color], " ".join(str(a) for a in args), ansi["reset"], "\n"]
else:
strs = [" ".join(str(a) for a in args), "\n"]
sys.stderr.write(prefix + "".join(strs))
def hint(text: tuple[str, ...] | list[str] | str, prefix=" ", config: benedict | None = None) -> None:
ansi = DEFAULT_CLI_COLORS if (config or {}).get("USE_COLOR") else ANSI
if isinstance(text, str):
stderr(f"{prefix}{ansi['lightred']}Hint:{ansi['reset']} {text}")
else:
stderr(f"{prefix}{ansi['lightred']}Hint:{ansi['reset']} {text[0]}")
for line in text[1:]:
stderr(f"{prefix} {line}")