dev: bump to 0.1.71-dev – vollständiges Trakt-Scrobbling mit stop-Monitor
This commit is contained in:
@@ -1,5 +1,12 @@
|
|||||||
# Changelog (Dev)
|
# Changelog (Dev)
|
||||||
|
|
||||||
|
## 0.1.71-dev - 2026-03-01
|
||||||
|
|
||||||
|
- Trakt Scrobble vollständig: scrobble/stop wird nach Wiedergabe-Ende mit berechnetem Fortschritt gesendet.
|
||||||
|
- Neue Funktion `_trakt_scrobble_stop_async()` und `_trakt_monitor_playback()`.
|
||||||
|
- Monitor blockiert den Plugin-Prozess bis Wiedergabe endet → Fortschritt wird korrekt berechnet.
|
||||||
|
- Damit wird Trakt "als gesehen" erst ab ≥ 80% Fortschritt markiert.
|
||||||
|
|
||||||
## 0.1.70-dev - 2026-03-01
|
## 0.1.70-dev - 2026-03-01
|
||||||
|
|
||||||
- Suchergebnisse werden über alle Plugins hinweg nach Titel gruppiert.
|
- Suchergebnisse werden über alle Plugins hinweg nach Titel gruppiert.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
<addon id="plugin.video.viewit" name="ViewIt" version="0.1.70-dev" provider-name="ViewIt">
|
<addon id="plugin.video.viewit" name="ViewIt" version="0.1.71-dev" provider-name="ViewIt">
|
||||||
<requires>
|
<requires>
|
||||||
<import addon="xbmc.python" version="3.0.0" />
|
<import addon="xbmc.python" version="3.0.0" />
|
||||||
<import addon="script.module.requests" />
|
<import addon="script.module.requests" />
|
||||||
|
|||||||
@@ -3814,9 +3814,10 @@ def _play_final_link(
|
|||||||
player = xbmc.Player()
|
player = xbmc.Player()
|
||||||
player.play(item=link, listitem=list_item)
|
player.play(item=link, listitem=list_item)
|
||||||
|
|
||||||
# Trakt Scrobble Start (Hintergrund-Thread)
|
# Trakt Scrobble: Start senden, dann blockierend auf Wiedergabe-Ende warten
|
||||||
if trakt_media and _get_setting_bool("trakt_enabled", default=False):
|
if trakt_media and _get_setting_bool("trakt_enabled", default=False):
|
||||||
_trakt_scrobble_start_async(trakt_media)
|
_trakt_scrobble_start_async(trakt_media)
|
||||||
|
_trakt_monitor_playback(trakt_media)
|
||||||
|
|
||||||
|
|
||||||
def _trakt_scrobble_start_async(media: dict[str, object]) -> None:
|
def _trakt_scrobble_start_async(media: dict[str, object]) -> None:
|
||||||
@@ -3844,6 +3845,77 @@ def _trakt_scrobble_start_async(media: dict[str, object]) -> None:
|
|||||||
threading.Thread(target=_do, daemon=True).start()
|
threading.Thread(target=_do, daemon=True).start()
|
||||||
|
|
||||||
|
|
||||||
|
def _trakt_scrobble_stop_async(media: dict[str, object], progress: float = 100.0) -> None:
|
||||||
|
"""Sendet scrobble/stop an die Trakt-API in einem Hintergrund-Thread."""
|
||||||
|
def _do() -> None:
|
||||||
|
try:
|
||||||
|
from core.trakt import TraktClient
|
||||||
|
except Exception:
|
||||||
|
return
|
||||||
|
client_id = _get_setting_string("trakt_client_id").strip()
|
||||||
|
client_secret = _get_setting_string("trakt_client_secret").strip()
|
||||||
|
access_token = _get_setting_string("trakt_access_token").strip()
|
||||||
|
if not client_id or not client_secret or not access_token:
|
||||||
|
return
|
||||||
|
client = TraktClient(client_id, client_secret, log=lambda m: _log(m, xbmc.LOGDEBUG))
|
||||||
|
client.scrobble_stop(
|
||||||
|
access_token,
|
||||||
|
media_type=str(media.get("kind", "movie")),
|
||||||
|
title=str(media.get("title", "")),
|
||||||
|
tmdb_id=int(media.get("tmdb_id", 0)),
|
||||||
|
imdb_id=str(media.get("imdb_id", "")),
|
||||||
|
season=int(media.get("season", 0)),
|
||||||
|
episode=int(media.get("episode", 0)),
|
||||||
|
progress=progress,
|
||||||
|
)
|
||||||
|
_log(f"Trakt scrobble/stop: {media.get('title')} progress={progress:.0f}%", xbmc.LOGDEBUG)
|
||||||
|
threading.Thread(target=_do, daemon=True).start()
|
||||||
|
|
||||||
|
|
||||||
|
def _trakt_monitor_playback(media: dict[str, object]) -> None:
|
||||||
|
"""Blockiert bis die Wiedergabe endet, berechnet Fortschritt und sendet scrobble/stop.
|
||||||
|
|
||||||
|
Muss im Haupt-Thread nach player.play() / setResolvedUrl() aufgerufen werden,
|
||||||
|
damit der Plugin-Prozess bis zum Wiedergabe-Ende aktiv bleibt.
|
||||||
|
"""
|
||||||
|
monitor = xbmc.Monitor()
|
||||||
|
player = xbmc.Player()
|
||||||
|
|
||||||
|
# Warten bis Wiedergabe startet (max 15 Sekunden)
|
||||||
|
timeout = 0
|
||||||
|
while not player.isPlaying() and timeout < 15:
|
||||||
|
if monitor.waitForAbort(1):
|
||||||
|
return
|
||||||
|
timeout += 1
|
||||||
|
if not player.isPlaying():
|
||||||
|
_log("Trakt monitor: Wiedergabe nicht gestartet.", xbmc.LOGDEBUG)
|
||||||
|
return
|
||||||
|
|
||||||
|
last_pos: float = 0.0
|
||||||
|
total_time: float = 0.0
|
||||||
|
try:
|
||||||
|
total_time = player.getTotalTime()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Wiedergabe verfolgen (alle 5 Sekunden)
|
||||||
|
while player.isPlaying() and not monitor.abortRequested():
|
||||||
|
try:
|
||||||
|
last_pos = player.getTime()
|
||||||
|
if not total_time:
|
||||||
|
total_time = player.getTotalTime()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
monitor.waitForAbort(5)
|
||||||
|
|
||||||
|
if monitor.abortRequested():
|
||||||
|
return
|
||||||
|
|
||||||
|
progress = min(100.0, (last_pos / total_time * 100.0)) if total_time > 0 else 100.0
|
||||||
|
_log(f"Trakt monitor: Wiedergabe beendet, progress={progress:.0f}%", xbmc.LOGDEBUG)
|
||||||
|
_trakt_scrobble_stop_async(media, progress=progress)
|
||||||
|
|
||||||
|
|
||||||
def _track_playback_and_update_state_async(key: str) -> None:
|
def _track_playback_and_update_state_async(key: str) -> None:
|
||||||
# Eigenes Resume/Watched ist deaktiviert; Kodi verwaltet das selbst.
|
# Eigenes Resume/Watched ist deaktiviert; Kodi verwaltet das selbst.
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user