From fdad6cb149453826df0900f18ff7e23b7efe296d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Wed, 30 Aug 2023 22:26:49 +0300 Subject: [PATCH 01/10] Create ServerStarted event --- plextraktsync/watch/events.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/plextraktsync/watch/events.py b/plextraktsync/watch/events.py index 370e35dc8c..12c7b1be73 100644 --- a/plextraktsync/watch/events.py +++ b/plextraktsync/watch/events.py @@ -1,8 +1,26 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from plexapi.server import PlexServer + + class Event(dict): def __str__(self): return f"{self.__class__}:{str(self.copy())}" +class ServerStarted(Event): + @property + def notifier(self): + return self["notifier"] + + @property + def server(self) -> PlexServer: + return self.notifier._server + + class Error(Event): @property def msg(self): From d615aa227748908ac7084dc62574a1c31c6fc131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Wed, 30 Aug 2023 22:30:07 +0300 Subject: [PATCH 02/10] Add special case of ServerStarted event handling --- plextraktsync/watch/EventDispatcher.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plextraktsync/watch/EventDispatcher.py b/plextraktsync/watch/EventDispatcher.py index 32010a9802..d21c3d86c6 100644 --- a/plextraktsync/watch/EventDispatcher.py +++ b/plextraktsync/watch/EventDispatcher.py @@ -1,6 +1,6 @@ from plextraktsync.factory import logging from plextraktsync.watch.EventFactory import EventFactory -from plextraktsync.watch.events import Error +from plextraktsync.watch.events import Error, ServerStarted class EventDispatcher: @@ -21,7 +21,7 @@ def on(self, event_type, listener, **kwargs): def event_handler(self, data): self.logger.debug(data) - if isinstance(data, Error): + if isinstance(data, (Error, ServerStarted)): return self.dispatch(data) events = self.event_factory.get_events(data) From 62f269df0e141172a92e19a7ace0a5faf881608e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Wed, 30 Aug 2023 22:30:45 +0300 Subject: [PATCH 03/10] Add SetWindowTitle mixin to WatchStateUpdater --- plextraktsync/watch/WatchStateUpdater.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plextraktsync/watch/WatchStateUpdater.py b/plextraktsync/watch/WatchStateUpdater.py index aa89f62426..925c6c8600 100644 --- a/plextraktsync/watch/WatchStateUpdater.py +++ b/plextraktsync/watch/WatchStateUpdater.py @@ -4,6 +4,7 @@ from typing import TYPE_CHECKING from plextraktsync.factory import logging +from plextraktsync.mixin.SetWindowTitle import SetWindowTitle from plextraktsync.watch.events import (ActivityNotification, Error, PlaySessionStateNotification, TimelineEntry) @@ -16,7 +17,7 @@ from plextraktsync.trakt.TraktApi import TraktApi -class WatchStateUpdater: +class WatchStateUpdater(SetWindowTitle): def __init__( self, plex: PlexApi, From 0d57a229553114ba489bcb367b978d4b4310b3c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Wed, 30 Aug 2023 22:31:27 +0300 Subject: [PATCH 04/10] Add clear_window_title to SetWindowTitle mixin --- plextraktsync/mixin/SetWindowTitle.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plextraktsync/mixin/SetWindowTitle.py b/plextraktsync/mixin/SetWindowTitle.py index a4ed354bf2..f41d1735e2 100644 --- a/plextraktsync/mixin/SetWindowTitle.py +++ b/plextraktsync/mixin/SetWindowTitle.py @@ -8,5 +8,8 @@ def console(self): return factory.console + def clear_window_title(self): + self.console.set_window_title("PlexTraktSync") + def set_window_title(self, title: str): self.console.set_window_title(f"PlexTraktSync: {title}") From f428d058c6df98306eb4d159c69c0067a829702d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Wed, 30 Aug 2023 22:33:08 +0300 Subject: [PATCH 05/10] Add server info print on server started --- plextraktsync/watch/WatchStateUpdater.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plextraktsync/watch/WatchStateUpdater.py b/plextraktsync/watch/WatchStateUpdater.py index 925c6c8600..0a7cc23d7a 100644 --- a/plextraktsync/watch/WatchStateUpdater.py +++ b/plextraktsync/watch/WatchStateUpdater.py @@ -7,7 +7,7 @@ from plextraktsync.mixin.SetWindowTitle import SetWindowTitle from plextraktsync.watch.events import (ActivityNotification, Error, PlaySessionStateNotification, - TimelineEntry) + ServerStarted, TimelineEntry) if TYPE_CHECKING: from plextraktsync.config.Config import Config @@ -93,6 +93,9 @@ def find_by_key(self, key: str, reload=False): return m + def on_start(self, event: ServerStarted): + self.set_window_title(f"watch: {event.server.friendlyName} ({event.server.version})") + def on_error(self, error: Error): self.logger.error(error.msg) self.scrobblers.clear() From ec0f0e757b841afe286d9d424f2629343103c35c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Wed, 30 Aug 2023 22:34:47 +0300 Subject: [PATCH 06/10] Listen to ServerStarted event --- plextraktsync/commands/watch.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plextraktsync/commands/watch.py b/plextraktsync/commands/watch.py index 50c18d6347..b666b1c1ee 100644 --- a/plextraktsync/commands/watch.py +++ b/plextraktsync/commands/watch.py @@ -3,7 +3,7 @@ from plextraktsync.factory import factory from plextraktsync.watch.events import (ActivityNotification, Error, PlaySessionStateNotification, - TimelineEntry) + ServerStarted, TimelineEntry) def watch(server: str): @@ -13,6 +13,7 @@ def watch(server: str): ws = factory.web_socket_listener updater = factory.watch_state_updater + ws.on(ServerStarted, updater.on_start) ws.on( PlaySessionStateNotification, updater.on_play, From d9f861bac5e1b42f01d03c6de6d4d0a02c52b6fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Wed, 30 Aug 2023 22:35:30 +0300 Subject: [PATCH 07/10] Emit ServerStarted on server started --- plextraktsync/watch/WebSocketListener.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plextraktsync/watch/WebSocketListener.py b/plextraktsync/watch/WebSocketListener.py index 30a841336d..15ccebc632 100644 --- a/plextraktsync/watch/WebSocketListener.py +++ b/plextraktsync/watch/WebSocketListener.py @@ -5,7 +5,7 @@ from plextraktsync.factory import logging from plextraktsync.watch.EventDispatcher import EventDispatcher -from plextraktsync.watch.events import Error +from plextraktsync.watch.events import Error, ServerStarted if TYPE_CHECKING: from plexapi.server import PlexServer @@ -28,6 +28,8 @@ def listen(self): notifier = self.plex.startAlertListener( callback=self.dispatcher.event_handler ) + self.dispatcher.event_handler(ServerStarted(notifier=notifier)) + while notifier.is_alive(): sleep(self.poll_interval) From b3af8f282652b14d2f5dd1c16d84d35b0b2b90c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Wed, 30 Aug 2023 22:36:46 +0300 Subject: [PATCH 08/10] Update window title when playing/stopping --- plextraktsync/watch/WatchStateUpdater.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plextraktsync/watch/WatchStateUpdater.py b/plextraktsync/watch/WatchStateUpdater.py index 0a7cc23d7a..35db17b66d 100644 --- a/plextraktsync/watch/WatchStateUpdater.py +++ b/plextraktsync/watch/WatchStateUpdater.py @@ -157,18 +157,21 @@ def scrobble(self, m: Media, percent: float, event: PlaySessionStateNotification if state == "playing": if self.progressbar is not None: self.progressbar.play(m.plex, percent) + self.set_window_title(f"Watching {m.title}") return self.scrobblers[tm].update(percent) if state == "paused": if self.progressbar is not None: self.progressbar.pause(m.plex, percent) + self.clear_window_title() return self.scrobblers[tm].pause(percent) if state == "stopped": if self.progressbar is not None: self.progressbar.stop(m.plex) + self.clear_window_title() value = self.scrobblers[tm].stop(percent) del self.scrobblers[tm] From 7b1aeae0580f502f14e23acba6329ace4166ba82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Wed, 30 Aug 2023 22:41:40 +0300 Subject: [PATCH 09/10] Refactor to have reusabe reset_title() method --- plextraktsync/watch/WatchStateUpdater.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/plextraktsync/watch/WatchStateUpdater.py b/plextraktsync/watch/WatchStateUpdater.py index 35db17b66d..64face61c1 100644 --- a/plextraktsync/watch/WatchStateUpdater.py +++ b/plextraktsync/watch/WatchStateUpdater.py @@ -93,8 +93,15 @@ def find_by_key(self, key: str, reload=False): return m + @property + def server(self): + return self.plex.plex + def on_start(self, event: ServerStarted): - self.set_window_title(f"watch: {event.server.friendlyName} ({event.server.version})") + self.reset_title() + + def reset_title(self): + self.set_window_title(f"watch: {self.server.friendlyName} ({self.server.version})") def on_error(self, error: Error): self.logger.error(error.msg) From 646963125ad24531f8077fb011fa1e8edfd86fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Wed, 30 Aug 2023 22:42:12 +0300 Subject: [PATCH 10/10] Use reset_title() to reset title after stop/pause --- plextraktsync/watch/WatchStateUpdater.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plextraktsync/watch/WatchStateUpdater.py b/plextraktsync/watch/WatchStateUpdater.py index 64face61c1..ccd935bb9a 100644 --- a/plextraktsync/watch/WatchStateUpdater.py +++ b/plextraktsync/watch/WatchStateUpdater.py @@ -171,14 +171,14 @@ def scrobble(self, m: Media, percent: float, event: PlaySessionStateNotification if state == "paused": if self.progressbar is not None: self.progressbar.pause(m.plex, percent) - self.clear_window_title() + self.reset_title() return self.scrobblers[tm].pause(percent) if state == "stopped": if self.progressbar is not None: self.progressbar.stop(m.plex) - self.clear_window_title() + self.reset_title() value = self.scrobblers[tm].stop(percent) del self.scrobblers[tm]