logging.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. __package__ = 'archivebox.misc'
  2. # Low-level logging primitives (Rich console, ANSI colors, stdout/stderr helpers)
  3. # Higher-level logging functions are in logging_util.py
  4. import sys
  5. from typing import Optional, Union, Tuple, List
  6. from collections import defaultdict
  7. from random import randint
  8. from benedict import benedict
  9. from rich.console import Console
  10. from rich.highlighter import Highlighter
  11. # SETUP RICH CONSOLE / TTY detection / COLOR / PROGRESS BARS
  12. # Disable wrapping - use soft_wrap=True and large width so text flows naturally
  13. # Colors are preserved, just no hard line breaks inserted
  14. CONSOLE = Console(width=32768, soft_wrap=True, force_terminal=True)
  15. STDERR = Console(stderr=True, width=32768, soft_wrap=True, force_terminal=True)
  16. IS_TTY = sys.stdout.isatty()
  17. class RainbowHighlighter(Highlighter):
  18. def highlight(self, text):
  19. for index in range(len(text)):
  20. text.stylize(f"color({randint(90, 98)})", index, index + 1)
  21. rainbow = RainbowHighlighter()
  22. DEFAULT_CLI_COLORS = benedict(
  23. {
  24. "reset": "\033[00;00m",
  25. "lightblue": "\033[01;30m",
  26. "lightyellow": "\033[01;33m",
  27. "lightred": "\033[01;35m",
  28. "red": "\033[01;31m",
  29. "green": "\033[01;32m",
  30. "blue": "\033[01;34m",
  31. "white": "\033[01;37m",
  32. "black": "\033[01;30m",
  33. }
  34. )
  35. ANSI = benedict({k: '' for k in DEFAULT_CLI_COLORS.keys()})
  36. COLOR_DICT = defaultdict(lambda: [(0, 0, 0), (0, 0, 0)], {
  37. '00': [(0, 0, 0), (0, 0, 0)],
  38. '30': [(0, 0, 0), (0, 0, 0)],
  39. '31': [(255, 0, 0), (128, 0, 0)],
  40. '32': [(0, 200, 0), (0, 128, 0)],
  41. '33': [(255, 255, 0), (128, 128, 0)],
  42. '34': [(0, 0, 255), (0, 0, 128)],
  43. '35': [(255, 0, 255), (128, 0, 128)],
  44. '36': [(0, 255, 255), (0, 128, 128)],
  45. '37': [(255, 255, 255), (255, 255, 255)],
  46. })
  47. # Logging Helpers (DEPRECATED, use rich.print instead going forward)
  48. def stdout(*args, color: Optional[str]=None, prefix: str='', config: Optional[benedict]=None) -> None:
  49. ansi = DEFAULT_CLI_COLORS if (config or {}).get('USE_COLOR') else ANSI
  50. if color:
  51. strs = [ansi[color], ' '.join(str(a) for a in args), ansi['reset'], '\n']
  52. else:
  53. strs = [' '.join(str(a) for a in args), '\n']
  54. sys.stdout.write(prefix + ''.join(strs))
  55. def stderr(*args, color: Optional[str]=None, prefix: str='', config: Optional[benedict]=None) -> None:
  56. ansi = DEFAULT_CLI_COLORS if (config or {}).get('USE_COLOR') else ANSI
  57. if color:
  58. strs = [ansi[color], ' '.join(str(a) for a in args), ansi['reset'], '\n']
  59. else:
  60. strs = [' '.join(str(a) for a in args), '\n']
  61. sys.stderr.write(prefix + ''.join(strs))
  62. def hint(text: Union[Tuple[str, ...], List[str], str], prefix=' ', config: Optional[benedict]=None) -> None:
  63. ansi = DEFAULT_CLI_COLORS if (config or {}).get('USE_COLOR') else ANSI
  64. if isinstance(text, str):
  65. stderr('{}{lightred}Hint:{reset} {}'.format(prefix, text, **ansi))
  66. else:
  67. stderr('{}{lightred}Hint:{reset} {}'.format(prefix, text[0], **ansi))
  68. for line in text[1:]:
  69. stderr('{} {}'.format(prefix, line))