mirror of
				https://github.com/Garmelon/PFERD.git
				synced 2025-10-31 12:52:43 +01:00 
			
		
		
		
	Use rich for log colorization
This commit is contained in:
		| @@ -5,8 +5,9 @@ Contains a few logger utility functions and implementations. | |||||||
| import logging | import logging | ||||||
| from typing import Optional | from typing import Optional | ||||||
|  |  | ||||||
| import colorama | from rich._log_render import LogRender | ||||||
| from colorama import Fore, Style | from rich.console import Console | ||||||
|  | from rich.text import Text | ||||||
|  |  | ||||||
| from .utils import PathLike, to_path | from .utils import PathLike, to_path | ||||||
|  |  | ||||||
| @@ -14,31 +15,20 @@ STYLE = "{" | |||||||
| FORMAT = "[{levelname:<7}] {message}" | FORMAT = "[{levelname:<7}] {message}" | ||||||
| DATE_FORMAT = "%F %T" | DATE_FORMAT = "%F %T" | ||||||
|  |  | ||||||
| FORMATTER = logging.Formatter( |  | ||||||
|     fmt=FORMAT, |  | ||||||
|     datefmt=DATE_FORMAT, |  | ||||||
|     style=STYLE, |  | ||||||
| ) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def enable_logging(name: str = "PFERD", level: int = logging.INFO) -> None: | def enable_logging(name: str = "PFERD", level: int = logging.INFO) -> None: | ||||||
|     """ |     """ | ||||||
|     Enable and configure logging via the logging module. |     Enable and configure logging via the logging module. | ||||||
|     """ |     """ | ||||||
|  |  | ||||||
|     handler = logging.StreamHandler() |  | ||||||
|     handler.setFormatter(FORMATTER) |  | ||||||
|  |  | ||||||
|     logger = logging.getLogger(name) |     logger = logging.getLogger(name) | ||||||
|     logger.setLevel(level) |     logger.setLevel(level) | ||||||
|     logger.addHandler(handler) |     logger.addHandler(RichLoggingHandler()) | ||||||
|  |  | ||||||
|     # This should be logged by our own handler, and not the root logger's |     # This should be logged by our own handler, and not the root logger's | ||||||
|     # default handler, so we don't pass it on to the root logger. |     # default handler, so we don't pass it on to the root logger. | ||||||
|     logger.propagate = False |     logger.propagate = False | ||||||
|  |  | ||||||
|     colorama.init() |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class FatalException(Exception): | class FatalException(Exception): | ||||||
|     """ |     """ | ||||||
| @@ -46,6 +36,36 @@ class FatalException(Exception): | |||||||
|     """ |     """ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class RichLoggingHandler(logging.Handler): | ||||||
|  |     """ | ||||||
|  |     A logging handler that uses rich for highlighting | ||||||
|  |     """ | ||||||
|  |  | ||||||
|  |     def __init__(self, level: int = logging.NOTSET, console: Optional[Console] = None) -> None: | ||||||
|  |         super().__init__(level=level) | ||||||
|  |         self.console = Console() if console is None else console | ||||||
|  |         self._log_render = LogRender(show_level=True, show_time=False, show_path=False) | ||||||
|  |  | ||||||
|  |     def emit(self, record: logging.LogRecord) -> None: | ||||||
|  |         """ | ||||||
|  |         Invoked by logging. | ||||||
|  |         """ | ||||||
|  |         log_style = f"logging.level.{record.levelname.lower()}" | ||||||
|  |         message = self.format(record) | ||||||
|  |  | ||||||
|  |         level = Text() | ||||||
|  |         level.append(record.levelname, log_style) | ||||||
|  |         message_text = Text.from_markup(message) | ||||||
|  |  | ||||||
|  |         self.console.print( | ||||||
|  |             self._log_render( | ||||||
|  |                 self.console, | ||||||
|  |                 [message_text], | ||||||
|  |                 level=level, | ||||||
|  |             ) | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |  | ||||||
| class PrettyLogger: | class PrettyLogger: | ||||||
|     """ |     """ | ||||||
|     A logger that prints some specially formatted log messages in color. |     A logger that prints some specially formatted log messages in color. | ||||||
| @@ -63,7 +83,7 @@ class PrettyLogger: | |||||||
|         Print an error message indicating some operation fatally failed. |         Print an error message indicating some operation fatally failed. | ||||||
|         """ |         """ | ||||||
|         self.logger.error( |         self.logger.error( | ||||||
|             f"{Fore.RED}{Style.BRIGHT}{message}{Style.RESET_ALL}" |             f"[bold red]{message}[/bold red]" | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     def warning(self, message: str) -> None: |     def warning(self, message: str) -> None: | ||||||
| @@ -72,7 +92,7 @@ class PrettyLogger: | |||||||
|         or ignored. |         or ignored. | ||||||
|         """ |         """ | ||||||
|         self.logger.warning( |         self.logger.warning( | ||||||
|             f"{Fore.YELLOW}{Style.BRIGHT}{message}{Style.RESET_ALL}" |             f"[bold yellow]{message}[/bold yellow]" | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     def modified_file(self, path: PathLike) -> None: |     def modified_file(self, path: PathLike) -> None: | ||||||
| @@ -81,7 +101,7 @@ class PrettyLogger: | |||||||
|         """ |         """ | ||||||
|  |  | ||||||
|         self.logger.info( |         self.logger.info( | ||||||
|             f"{Fore.MAGENTA}{Style.BRIGHT}Modified {self._format_path(path)}.{Style.RESET_ALL}" |             f"[bold magenta]Modified {self._format_path(path)}.[/bold magenta]" | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     def new_file(self, path: PathLike) -> None: |     def new_file(self, path: PathLike) -> None: | ||||||
| @@ -90,7 +110,7 @@ class PrettyLogger: | |||||||
|         """ |         """ | ||||||
|  |  | ||||||
|         self.logger.info( |         self.logger.info( | ||||||
|             f"{Fore.GREEN}{Style.BRIGHT}Created {self._format_path(path)}.{Style.RESET_ALL}" |             f"[bold green]Created {self._format_path(path)}.[/bold green]" | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     def ignored_file(self, path: PathLike, reason: str) -> None: |     def ignored_file(self, path: PathLike, reason: str) -> None: | ||||||
| @@ -99,8 +119,8 @@ class PrettyLogger: | |||||||
|         """ |         """ | ||||||
|  |  | ||||||
|         self.logger.info( |         self.logger.info( | ||||||
|             f"{Style.DIM}Ignored {self._format_path(path)} " |             f"[dim]Ignored {self._format_path(path)} " | ||||||
|             f"({Style.NORMAL}{reason}{Style.DIM}).{Style.RESET_ALL}" |             f"([/dim]{reason}[dim]).[/dim]" | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     def searching(self, path: PathLike) -> None: |     def searching(self, path: PathLike) -> None: | ||||||
| @@ -116,8 +136,8 @@ class PrettyLogger: | |||||||
|         """ |         """ | ||||||
|  |  | ||||||
|         self.logger.info( |         self.logger.info( | ||||||
|             f"{Style.DIM}Not searching {self._format_path(path)} " |             f"[dim]Not searching {self._format_path(path)} " | ||||||
|             f"({Style.NORMAL}{reason}{Style.DIM}).{Style.RESET_ALL}" |             f"([/dim]{reason}[dim]).[/dim]" | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     def starting_synchronizer( |     def starting_synchronizer( | ||||||
| @@ -133,7 +153,7 @@ class PrettyLogger: | |||||||
|         subject_str = f"{subject} " if subject else "" |         subject_str = f"{subject} " if subject else "" | ||||||
|         self.logger.info("") |         self.logger.info("") | ||||||
|         self.logger.info(( |         self.logger.info(( | ||||||
|             f"{Fore.CYAN}{Style.BRIGHT}Synchronizing " |             f"[bold cyan]Synchronizing " | ||||||
|             f"{subject_str}to {self._format_path(target_directory)} " |             f"{subject_str}to {self._format_path(target_directory)} " | ||||||
|             f"using the {synchronizer_name} synchronizer.{Style.RESET_ALL}" |             f"using the {synchronizer_name} synchronizer.[/bold cyan]" | ||||||
|         )) |         )) | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								mypy.ini
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								mypy.ini
									
									
									
									
									
								
							| @@ -3,5 +3,5 @@ disallow_untyped_defs = True | |||||||
| disallow_incomplete_defs = True | disallow_incomplete_defs = True | ||||||
| no_implicit_optional = True | no_implicit_optional = True | ||||||
|  |  | ||||||
| [mypy-colorama,bs4] | [mypy-rich.*,bs4] | ||||||
| ignore_missing_imports = True | ignore_missing_imports = True | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								setup.py
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| from setuptools import setup, find_packages | from setuptools import find_packages, setup | ||||||
|  |  | ||||||
| setup( | setup( | ||||||
|     name="PFERD", |     name="PFERD", | ||||||
| @@ -7,7 +7,6 @@ setup( | |||||||
|     install_requires=[ |     install_requires=[ | ||||||
|         "requests>=2.21.0", |         "requests>=2.21.0", | ||||||
|         "beautifulsoup4>=4.7.1", |         "beautifulsoup4>=4.7.1", | ||||||
|             "colorama>=0.4.1", |  | ||||||
|         "rich>=1.0.0" |         "rich>=1.0.0" | ||||||
|     ], |     ], | ||||||
| ) | ) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 I-Al-Istannen
					I-Al-Istannen