import datetime import logging import os import sys from typing import Callable, List from rich.console import Console, ConsoleOptions, ConsoleRenderable, NewLine from rich.highlighter import NullHighlighter, RegexHighlighter from rich.logging import RichHandler from rich.rule import Rule from rich.style import Style from rich.theme import Theme from rich.traceback import Traceback sys.stdout.reconfigure(encoding='utf-8') sys.stderr.reconfigure(encoding='utf-8') def empty_function(*args, **kwargs): pass # cnocr will set root logger in cnocr.utils # Delete logging.basicConfig to avoid logging the same message twice. logging.basicConfig = empty_function logging.raiseExceptions = True # Set True if wanna see encode errors on console # Remove HTTP keywords (GET, POST etc.) RichHandler.KEYWORDS = [] class RichFileHandler(RichHandler): # Rename pass class RichRenderableHandler(RichHandler): """ Pass renderable into a function """ def __init__(self, *args, func: Callable[[ConsoleRenderable], None] = None, **kwargs): super().__init__(*args, **kwargs) self._func = func def emit(self, record: logging.LogRecord) -> None: message = self.format(record) traceback = None if ( self.rich_tracebacks and record.exc_info and record.exc_info != (None, None, None) ): exc_type, exc_value, exc_traceback = record.exc_info assert exc_type is not None assert exc_value is not None traceback = Traceback.from_exception( exc_type, exc_value, exc_traceback, width=self.tracebacks_width, extra_lines=self.tracebacks_extra_lines, theme=self.tracebacks_theme, word_wrap=self.tracebacks_word_wrap, show_locals=self.tracebacks_show_locals, locals_max_length=self.locals_max_length, locals_max_string=self.locals_max_string, ) message = record.getMessage() if self.formatter: record.message = record.getMessage() formatter = self.formatter if hasattr(formatter, "usesTime") and formatter.usesTime(): record.asctime = formatter.formatTime( record, formatter.datefmt) message = formatter.formatMessage(record) message_renderable = self.render_message(record, message) log_renderable = self.render( record=record, traceback=traceback, message_renderable=message_renderable ) # Directly put renderable into function self._func(log_renderable) def handle(self, record: logging.LogRecord) -> bool: if not self._func: return True super().handle(record) class HTMLConsole(Console): """ Force full feature console but not working lol :( """ @property def options(self) -> ConsoleOptions: return ConsoleOptions( max_height=self.size.height, size=self.size, legacy_windows=False, min_width=1, max_width=self.width, encoding='utf-8', is_terminal=False, ) class Highlighter(RegexHighlighter): base_style = 'web.' highlights = [ # (r'(?P(\d{2}|\d{4})(?:\-)?([0]{1}\d{1}|[1]{1}[0-2]{1})' # r'(?:\-)?([0-2]{1}\d{1}|[3]{1}[0-1]{1})(?:\s)?([0-1]{1}\d{1}|' # r'[2]{1}[0-3]{1})(?::)?([0-5]{1}\d{1})(?::)?([0-5]{1}\d{1}).\d+\b)'), (r'(?P