fix(gui): 🐛 integrate ansi2html for improved log message formatting

* Added `Ansi2HTMLConverter` to convert ANSI color codes in log messages to HTML.
* Updated the `MainWindow` class to utilize the new converter for displaying logs.
* Removed dependency on `coloredlogs.converter` for log message display.
This commit is contained in:
Robert Honz
2025-10-21 07:58:00 +02:00
parent 5c09b6594c
commit d3ec0398b4
3 changed files with 47 additions and 24 deletions
Generated
+37 -16
View File
@@ -1,5 +1,21 @@
# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand.
[[package]]
name = "ansi2html"
version = "1.9.2"
description = "Convert text with ANSI color codes to HTML or to LaTeX"
optional = false
python-versions = ">=3.7"
groups = ["main"]
files = [
{file = "ansi2html-1.9.2-py3-none-any.whl", hash = "sha256:dccb75aa95fb018e5d299be2b45f802952377abfdce0504c17a6ee6ef0a420c5"},
{file = "ansi2html-1.9.2.tar.gz", hash = "sha256:3453bf87535d37b827b05245faaa756dbab4ec3d69925e352b6319c3c955c0a5"},
]
[package.extras]
docs = ["mkdocs", "mkdocs-material", "mkdocs-material-extensions", "mkdocstrings", "mkdocstrings-python", "pymdown-extensions"]
test = ["pytest", "pytest-cov"]
[[package]]
name = "astroid"
version = "4.0.1"
@@ -633,14 +649,14 @@ all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2
[[package]]
name = "iniconfig"
version = "2.1.0"
version = "2.3.0"
description = "brain-dead simple config-ini parsing"
optional = false
python-versions = ">=3.8"
python-versions = ">=3.10"
groups = ["dev"]
files = [
{file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"},
{file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"},
{file = "iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"},
{file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"},
]
[[package]]
@@ -1160,15 +1176,14 @@ files = [
]
[[package]]
name = "nuitka"
version = "2.8.3"
name = "Nuitka"
version = "2.8.4"
description = "Python compiler with full language support and CPython compatibility"
optional = false
python-versions = "*"
groups = ["dev"]
files = [
{file = "Nuitka-2.8.3.tar.gz", hash = "sha256:10dc85443c49e7d6e4e8d3413cdfaefe7ebf3d8f47d2bfb5324b5676c3d77b5f"},
]
files = []
develop = false
[package.dependencies]
ordered-set = ">=4.1.0"
@@ -1180,6 +1195,12 @@ build-wheel = ["setuptools (>=42)", "toml", "wheel"]
icon-conversion = ["imageio"]
onefile = ["zstandard (>=0.15)"]
[package.source]
type = "git"
url = "https://github.com/Nuitka/Nuitka.git"
reference = "2.8.4"
resolved_reference = "fa3c20ac628e9652f58cff9558ae066c7a500ca0"
[[package]]
name = "ordered-set"
version = "4.1.0"
@@ -1528,14 +1549,14 @@ windows-terminal = ["colorama (>=0.4.6)"]
[[package]]
name = "pylint"
version = "4.0.1"
version = "4.0.2"
description = "python code static checker"
optional = false
python-versions = ">=3.10.0"
groups = ["dev"]
files = [
{file = "pylint-4.0.1-py3-none-any.whl", hash = "sha256:6077ac21d01b7361eae6ed0f38d9024c02732fdc635d9e154d4fe6063af8ac56"},
{file = "pylint-4.0.1.tar.gz", hash = "sha256:06db6a1fda3cedbd7aee58f09d241e40e5f14b382fd035ed97be320f11728a84"},
{file = "pylint-4.0.2-py3-none-any.whl", hash = "sha256:9627ccd129893fb8ee8e8010261cb13485daca83e61a6f854a85528ee579502d"},
{file = "pylint-4.0.2.tar.gz", hash = "sha256:9c22dfa52781d3b79ce86ab2463940f874921a3e5707bcfc98dd0c019945014e"},
]
[package.dependencies]
@@ -2095,14 +2116,14 @@ virtualenv = ">=20.34"
[[package]]
name = "typer"
version = "0.19.2"
version = "0.20.0"
description = "Typer, build great CLIs. Easy to code. Based on Python type hints."
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "typer-0.19.2-py3-none-any.whl", hash = "sha256:755e7e19670ffad8283db353267cb81ef252f595aa6834a0d1ca9312d9326cb9"},
{file = "typer-0.19.2.tar.gz", hash = "sha256:9ad824308ded0ad06cc716434705f691d4ee0bfd0fb081839d2e426860e7fdca"},
{file = "typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a"},
{file = "typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37"},
]
[package.dependencies]
@@ -2339,4 +2360,4 @@ gui = ["pyqtdarktheme-fork", "pyside6"]
[metadata]
lock-version = "2.1"
python-versions = ">=3.12,<3.14"
content-hash = "df2d544dcb81e9722b5eb931b6e3d1f045052f31b5ce0f9e5e92f7a7d8aefbe8"
content-hash = "73a9195e1d46d0176c01c731c1431d4b43085376485622d33e0efd53c42e2fb1"
+3 -3
View File
@@ -11,7 +11,6 @@ classifiers = [
"Intended Audience :: Developers",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]
requires-python = ">=3.12,<3.14"
dynamic = ["dependencies"]
@@ -40,10 +39,11 @@ pyside6 = { version = "6.10.0", optional = true }
pyqtdarktheme-fork = { version = "^2.3.4", optional = true }
rich = "^14.2.0"
toml = "^0.10.2"
typer = "^0.19.2"
typer = "^0.20.0"
tidalapi = "^0.8.8"
python-ffmpeg = "^2.0.12"
pycryptodome = "^3.23.0"
ansi2html = "^1.9.2"
[project.optional-dependencies]
gui = ["pyside6", "pyqtdarktheme-fork"]
@@ -67,7 +67,7 @@ pylint = "^4.0.1"
pillow = "^12.0.0"
pytest-cov = "^7.0.0"
black = "^25.9.0"
nuitka = "^2.8.3"
nuitka = { git = "https://github.com/Nuitka/Nuitka.git", tag = "2.8.4" }
[tool.poetry.group.docs]
optional = true
+7 -5
View File
@@ -89,7 +89,8 @@ except ImportError as e:
print("Qt dependencies missing. Cannot start GUI. Please read the 'README.md' carefully.")
sys.exit(1)
import coloredlogs.converter
from ansi2html import Ansi2HTMLConverter
from rich.progress import Progress
from tidalapi import Album, Mix, Playlist, Quality, Track, UserPlaylist, Video
from tidalapi.artist import Artist
@@ -143,6 +144,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
s_queue_download_item_finished: QtCore.Signal = QtCore.Signal(object)
s_queue_download_item_failed: QtCore.Signal = QtCore.Signal(object)
s_queue_download_item_skipped: QtCore.Signal = QtCore.Signal(object)
converter_ansi_html: Ansi2HTMLConverter
def __init__(self, tidal: Tidal | None = None) -> None:
"""Initialize the main window and all components.
@@ -187,6 +189,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
self.settings.data.window_h,
)
self.spinners: dict[QtWidgets.QWidget, QtWaitingSpinner] = {}
self.converter_ansi_html: Ansi2HTMLConverter = Ansi2HTMLConverter()
def init_tidal(self, tidal: Tidal | None = None):
"""Initialize Tidal session and handle login flow.
@@ -297,12 +300,11 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
Args:
text (str): Log message.
"""
display_msg = coloredlogs.converter.convert(text)
cursor: QtGui.QTextCursor = self.te_debug.textCursor()
cursor.movePosition(QtGui.QTextCursor.End)
cursor.insertHtml(display_msg)
html = self.converter_ansi_html.convert(text)
cursor.movePosition(QtGui.QTextCursor.End)
cursor.insertHtml(html)
self.te_debug.setTextCursor(cursor)
self.te_debug.ensureCursorVisible()