Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbf5f3b93f | ||
|
|
9bd4b360cd |
@@ -1,4 +1,4 @@
|
||||
"""Playtube - ein eigenstaendiger YouTube- & YouTube-Music-Player mit Discord Rich Presence."""
|
||||
|
||||
__app_name__ = "Playtube"
|
||||
__version__ = "2.1.3"
|
||||
__version__ = "2.1.4"
|
||||
|
||||
@@ -48,6 +48,14 @@ def _app_data_dir() -> Path:
|
||||
return d
|
||||
|
||||
|
||||
def app_data_dir() -> Path:
|
||||
"""Oeffentlicher Zugriff auf den App-Datenordner, z.B. fuer Debug-Logs - die
|
||||
gepackte .exe laeuft ohne Konsolenfenster (console=False), print()-Debugging ist
|
||||
dort also unsichtbar; ein Log-File ist die einzige Moeglichkeit, dort etwas
|
||||
nachtraeglich einzusehen."""
|
||||
return _app_data_dir()
|
||||
|
||||
|
||||
def _config_path() -> Path:
|
||||
# Im Entwicklungsmodus liegt config.json direkt im Projektordner (leicht editierbar),
|
||||
# im gepackten Build im APPDATA-Ordner.
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
"""Sehr einfaches, immer aktives Datei-Log fuer schwer reproduzierbare Bugs.
|
||||
|
||||
Die gepackte .exe laeuft ohne Konsolenfenster (console=False in packaging/playtube.spec),
|
||||
also sind print()-Debugausgaben dort unsichtbar - selbst mit PLAYTUBE_DEBUG=1 sieht der
|
||||
Nutzer nichts. Dieses Modul schreibt stattdessen in eine kleine, automatisch gekappte
|
||||
Log-Datei im App-Datenordner, die sich jederzeit nachtraeglich auslesen laesst.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
import traceback
|
||||
from pathlib import Path
|
||||
|
||||
from .config import app_data_dir
|
||||
|
||||
_MAX_LINES = 500
|
||||
|
||||
|
||||
def _log_path() -> Path:
|
||||
d = app_data_dir() / "logs"
|
||||
d.mkdir(parents=True, exist_ok=True)
|
||||
return d / "discord_rpc.log"
|
||||
|
||||
|
||||
def log_line(msg: str) -> None:
|
||||
"""Haengt eine Zeile mit Zeitstempel an - haelt die Datei klein, indem bei
|
||||
Ueberlaenge nur die letzten _MAX_LINES Zeilen behalten werden."""
|
||||
try:
|
||||
path = _log_path()
|
||||
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
line = f"[{timestamp}] {msg}\n"
|
||||
with open(path, "a", encoding="utf-8") as f:
|
||||
f.write(line)
|
||||
|
||||
lines = path.read_text(encoding="utf-8", errors="replace").splitlines()
|
||||
if len(lines) > _MAX_LINES:
|
||||
path.write_text("\n".join(lines[-_MAX_LINES:]) + "\n", encoding="utf-8")
|
||||
except Exception:
|
||||
# Logging darf niemals die App zum Absturz bringen.
|
||||
pass
|
||||
|
||||
|
||||
def log_exception(context: str, exc: BaseException) -> None:
|
||||
log_line(f"{context}: {exc!r}\n{''.join(traceback.format_exception(exc))}")
|
||||
@@ -16,6 +16,7 @@ from typing import Any
|
||||
from PySide6.QtCore import QThread
|
||||
|
||||
from .config import APP_NAME
|
||||
from .debug_log import log_line
|
||||
|
||||
try:
|
||||
from pypresence.types import ActivityType
|
||||
@@ -199,6 +200,7 @@ class DiscordRPCWorker(QThread):
|
||||
self._presence = Presence(self._client_id)
|
||||
self._presence.connect()
|
||||
self._connected = True
|
||||
log_line("[connect] verbunden")
|
||||
if os.environ.get("PLAYTUBE_DEBUG"):
|
||||
print("[discord-rpc] verbunden", flush=True)
|
||||
except Exception as exc:
|
||||
@@ -224,6 +226,7 @@ class DiscordRPCWorker(QThread):
|
||||
now = time.time()
|
||||
|
||||
if key != self._track_key:
|
||||
old_key = self._track_key
|
||||
self._track_key = key
|
||||
# current_time nur als grobe Anfangs-Schaetzung verwenden (z.B. Programm
|
||||
# startet waehrend ein Titel schon laeuft) - plausibilisiert, damit ein
|
||||
@@ -231,6 +234,7 @@ class DiscordRPCWorker(QThread):
|
||||
# rein ueber die Systemzeit weiterlaeuft statt ueber currentTime.
|
||||
offset = current_time if (duration <= 0 or 0 <= current_time <= duration) else 0
|
||||
self._track_start_ts = int(now - offset)
|
||||
log_line(f"[track-change] alt={old_key!r} neu={key!r} offset={offset:.1f}s")
|
||||
|
||||
start_ts = self._track_start_ts if self._track_start_ts is not None else int(now)
|
||||
end_ts = start_ts + int(duration) if duration and duration > 0 else None
|
||||
@@ -254,11 +258,22 @@ class DiscordRPCWorker(QThread):
|
||||
start_ts, end_ts = self._track_timestamps(item)
|
||||
payload = build_presence_payload(item, self._session_start, start_ts, end_ts)
|
||||
self._presence.update(**payload)
|
||||
log_line(
|
||||
"[send] title=%r thumbnail=%r large_image=%r start=%s end=%s"
|
||||
% (
|
||||
item.get("title"),
|
||||
item.get("thumbnail"),
|
||||
payload.get("large_image"),
|
||||
start_ts,
|
||||
end_ts,
|
||||
)
|
||||
)
|
||||
if os.environ.get("PLAYTUBE_DEBUG"):
|
||||
print(f"[discord-rpc] gesendet: {payload!r}", flush=True)
|
||||
except Exception as exc:
|
||||
# Discord evtl. geschlossen worden -> beim naechsten Mal neu verbinden.
|
||||
self._connected = False
|
||||
log_line(f"[send-error] {exc!r}")
|
||||
if os.environ.get("PLAYTUBE_DEBUG"):
|
||||
print(f"[discord-rpc] Senden fehlgeschlagen: {exc!r}", flush=True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user