diff --git a/pdm.lock b/pdm.lock index c69ab88..5f5f2cf 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "dev"] strategy = [] lock_version = "4.5.0" -content_hash = "sha256:6aa6f02f71070c93d191e7242d0986a66d73173b39bfbc6568ffcbf3deb9f647" +content_hash = "sha256:819a55a6259056418a7d6ba23fefef909ad33f9f73d626662e28a18438b199e0" [[metadata.targets]] requires_python = ">=3.10,<3.14" @@ -112,19 +112,6 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -[[package]] -name = "coloredlogs" -version = "15.0.1" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -summary = "Colored terminal output for Python's logging module" -dependencies = [ - "humanfriendly>=9.1", -] -files = [ - {file = "coloredlogs-15.0.1-py2.py3-none-any.whl", hash = "sha256:612ee75c546f53e92e70049c9dbfcc18c935a2b9a53b66085ce9ef6a6e5c0934"}, - {file = "coloredlogs-15.0.1.tar.gz", hash = "sha256:7c991aa71a4577af2f82600d8f8f3a89f936baeaf9b50a9c197da014e5bf16b0"}, -] - [[package]] name = "deprecated" version = "1.2.15" @@ -158,21 +145,6 @@ files = [ {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, ] -[[package]] -name = "humanfriendly" -version = "10.0" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -summary = "Human friendly output for text interfaces using Python" -dependencies = [ - "monotonic; python_version == \"2.7\"", - "pyreadline3; sys_platform == \"win32\" and python_version >= \"3.8\"", - "pyreadline; sys_platform == \"win32\" and python_version < \"3.8\"", -] -files = [ - {file = "humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477"}, - {file = "humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc"}, -] - [[package]] name = "iniconfig" version = "2.0.0" @@ -362,7 +334,7 @@ version = "0.38.post1" requires_python = ">=3.9" git = "https://github.com/ultrafunkamsterdam/nodriver.git" revision = "ec6c3fcd8ea18638d6d2b76d5245bed11cbf4aa2" -summary = "\r\n [Docs here](https://ultrafunkamsterdam.github.io/nodriver)\r\n\r\n * Official successor of Undetected Chromedriver\r\n * Can be made to work for for all chromium based browsers.\r\n * Dropped selenium and chromedriver binary requirements.\r\n * fully asynchronous == bizarre performance gains, and more granular control\r\n\r\n Part of undetected-chromedriver, or merely the successor of it, this library is a full rewrite, providing a\r\n fast framework for web automation, webscraping, bots and any other creative ideas which are normally\r\n hindered by annoying anti bot systems like Captcha / CloudFlare / Imperva / hCaptcha and other\r\n big corp \"ai\" money machines using your input to make even more $$ (http://tinyurl.com/bigcorp-ai-inputs)\r\n\r\n The webdriver/selenium requirement is dropped entirely, since this library communicates directly to the browser.\r\n Being fully asynchronous, this adds massive performance improvements and more detailed control possibilities.\r\n\r\n As usual ( like undetected chromedriver) all config details and best practices are built-in, which means\r\n up and running with just a line of code.\r\n\r\n This makes it simple to use for quick prototyping, and perfect for interactive interpreter use (eg: IPython).\r\n\r\n\r\n WARNING:\r\n - results may vary due to many factors. No guarantees are given whatsoever.\r\n - Running from bad IP or datacenter may still cause captcha's and/or other problems.\r\n - With great power comes ... etc etc etc\r\n no but SERIOUS: for your own benefit, make sure \"they\" have no reason for upscaling anti-bot measurements.\r\n there might be one day it would not be feasible anymore to work up against big corp, and provide upgrades\r\n and free libraries.\r\n\r\n" +summary = "[Docs here](https://ultrafunkamsterdam.github.io/nodriver)" dependencies = [ "deprecated", "mss", @@ -523,16 +495,6 @@ files = [ {file = "pylint-3.3.3.tar.gz", hash = "sha256:07c607523b17e6d16e2ae0d7ef59602e332caa762af64203c24b41c27139f36a"}, ] -[[package]] -name = "pyreadline3" -version = "3.5.4" -requires_python = ">=3.8" -summary = "A python implementation of GNU readline." -files = [ - {file = "pyreadline3-3.5.4-py3-none-any.whl", hash = "sha256:eaf8e6cc3c49bcccf145fc6067ba8643d1df34d604a1ec0eccbf7a18e6d3fae6"}, - {file = "pyreadline3-3.5.4.tar.gz", hash = "sha256:8d57d53039a1c75adba8e50dd3d992b28143480816187ea5efbd5c78e6c885b7"}, -] - [[package]] name = "pyright" version = "1.1.391" diff --git a/pyinstaller.spec b/pyinstaller.spec index 726cb6e..78dd3a4 100644 --- a/pyinstaller.spec +++ b/pyinstaller.spec @@ -18,7 +18,6 @@ datas = [ excluded_modules = [ "_aix_support", - "_pydecimal", "argparse", "bz2", "ftplib", diff --git a/pyproject.toml b/pyproject.toml index 6ad41c5..22977da 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,6 @@ classifiers = [ # https://pypi.org/classifiers/ requires-python = ">=3.10,<3.14" dependencies = [ "colorama", - "coloredlogs", "nodriver @ git+https://github.com/ultrafunkamsterdam/nodriver.git", "jaraco.text", # required by pkg_resources during runtime "ruamel.yaml", diff --git a/src/kleinanzeigen_bot/utils.py b/src/kleinanzeigen_bot/utils.py index ccd5cdd..e525471 100644 --- a/src/kleinanzeigen_bot/utils.py +++ b/src/kleinanzeigen_bot/utils.py @@ -11,7 +11,7 @@ from types import FrameType, ModuleType, TracebackType from typing import Any, Final, TypeVar -import coloredlogs +import colorama from ruamel.yaml import YAML from .i18n import get_translating_logger @@ -154,17 +154,53 @@ def safe_get(a_map:dict[Any, Any], *keys:str) -> Any: def configure_console_logging() -> None: - class LevelTranslatingFormatter(coloredlogs.ColoredFormatter): # type: ignore + class CustomFormatter(logging.Formatter): + LEVEL_COLORS = { + logging.DEBUG: colorama.Fore.BLACK + colorama.Style.BRIGHT, + logging.INFO: colorama.Fore.BLACK + colorama.Style.BRIGHT, + logging.WARNING: colorama.Fore.YELLOW, + logging.ERROR: colorama.Fore.RED, + logging.CRITICAL: colorama.Fore.RED, + } + MESSAGE_COLORS = { + logging.DEBUG: colorama.Fore.BLACK + colorama.Style.BRIGHT, + logging.INFO: colorama.Fore.RESET, + logging.WARNING: colorama.Fore.YELLOW, + logging.ERROR: colorama.Fore.RED, + logging.CRITICAL: colorama.Fore.RED + colorama.Style.BRIGHT, + } + VALUE_COLORS = { + logging.DEBUG: colorama.Fore.BLACK + colorama.Style.BRIGHT, + logging.INFO: colorama.Fore.MAGENTA, + logging.WARNING: colorama.Fore.MAGENTA, + logging.ERROR: colorama.Fore.MAGENTA, + logging.CRITICAL: colorama.Fore.MAGENTA, + } def format(self, record:logging.LogRecord) -> str: - msg:str = super().format(record) - if record.levelno > logging.DEBUG: - levelname = _(record.levelname) - if levelname != record.levelname: - msg = msg.replace(record.levelname, levelname, 1) - return msg - - formatter = LevelTranslatingFormatter("[%(levelname)s] %(message)s") + record = copy.deepcopy(record) + + level_color = self.LEVEL_COLORS.get(record.levelno, "") + msg_color = self.MESSAGE_COLORS.get(record.levelno, "") + value_color = self.VALUE_COLORS.get(record.levelno, "") + + # translate and colorize log level name + levelname = _(record.levelname) if record.levelno > logging.DEBUG else record.levelname + record.levelname = f"{level_color}[{levelname}]{colorama.Style.RESET_ALL}" + + # highlight message values enclosed by [...], "...", and '...' + record.msg = re.sub( + r"\[([^\]]+)\]|\"([^\"]+)\"|\'([^\']+)\'", + lambda match: f"[{value_color}{match.group(1) or match.group(2) or match.group(3)}{colorama.Fore.RESET}{msg_color}]", + str(record.msg), + ) + + # colorize message + record.msg = f"{msg_color}{record.msg}{colorama.Style.RESET_ALL}" + + return super().format(record) + + formatter = CustomFormatter("%(levelname)s %(message)s") stdout_log = logging.StreamHandler(sys.stderr) stdout_log.setLevel(logging.DEBUG)