_log_render.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. from datetime import datetime
  2. from typing import Iterable, List, Optional, TYPE_CHECKING, Union, Callable
  3. from .text import Text, TextType
  4. if TYPE_CHECKING:
  5. from .console import Console, ConsoleRenderable, RenderableType
  6. from .table import Table
  7. FormatTimeCallable = Callable[[datetime], Text]
  8. class LogRender:
  9. def __init__(
  10. self,
  11. show_time: bool = True,
  12. show_level: bool = False,
  13. show_path: bool = True,
  14. time_format: Union[str, FormatTimeCallable] = "[%x %X]",
  15. omit_repeated_times: bool = True,
  16. level_width: Optional[int] = 8,
  17. ) -> None:
  18. self.show_time = show_time
  19. self.show_level = show_level
  20. self.show_path = show_path
  21. self.time_format = time_format
  22. self.omit_repeated_times = omit_repeated_times
  23. self.level_width = level_width
  24. self._last_time: Optional[Text] = None
  25. def __call__(
  26. self,
  27. console: "Console",
  28. renderables: Iterable["ConsoleRenderable"],
  29. log_time: Optional[datetime] = None,
  30. time_format: Optional[Union[str, FormatTimeCallable]] = None,
  31. level: TextType = "",
  32. path: Optional[str] = None,
  33. line_no: Optional[int] = None,
  34. link_path: Optional[str] = None,
  35. ) -> "Table":
  36. from .containers import Renderables
  37. from .table import Table
  38. output = Table.grid(padding=(0, 1))
  39. output.expand = True
  40. if self.show_time:
  41. output.add_column(style="log.time")
  42. if self.show_level:
  43. output.add_column(style="log.level", width=self.level_width)
  44. output.add_column(ratio=1, style="log.message", overflow="fold")
  45. if self.show_path and path:
  46. output.add_column(style="log.path")
  47. row: List["RenderableType"] = []
  48. if self.show_time:
  49. log_time = log_time or console.get_datetime()
  50. time_format = time_format or self.time_format
  51. if callable(time_format):
  52. log_time_display = time_format(log_time)
  53. else:
  54. log_time_display = Text(log_time.strftime(time_format))
  55. if log_time_display == self._last_time and self.omit_repeated_times:
  56. row.append(Text(" " * len(log_time_display)))
  57. else:
  58. row.append(log_time_display)
  59. self._last_time = log_time_display
  60. if self.show_level:
  61. row.append(level)
  62. row.append(Renderables(renderables))
  63. if self.show_path and path:
  64. path_text = Text()
  65. path_text.append(
  66. path, style=f"link file://{link_path}" if link_path else ""
  67. )
  68. if line_no:
  69. path_text.append(":")
  70. path_text.append(
  71. f"{line_no}",
  72. style=f"link file://{link_path}#{line_no}" if link_path else "",
  73. )
  74. row.append(path_text)
  75. output.add_row(*row)
  76. return output
  77. if __name__ == "__main__": # pragma: no cover
  78. from rich.console import Console
  79. c = Console()
  80. c.print("[on blue]Hello", justify="right")
  81. c.log("[on blue]hello", justify="right")