From c3fd748c653ca54d60754a09eb387e9799155576 Mon Sep 17 00:00:00 2001 From: aj Date: Tue, 24 Dec 2019 10:25:32 +0000 Subject: [PATCH] split listener into own object added callback functions added max recent tracks check added log dir check --- listener.py | 5 ++- spotframework/listener/cmd.py | 14 ++++---- spotframework/listener/listener.py | 52 ++++++++++++++++++++++++++++++ spotframework/listener/thread.py | 45 +++++--------------------- spotframework/model/service.py | 5 ++- 5 files changed, 75 insertions(+), 46 deletions(-) create mode 100644 spotframework/listener/listener.py diff --git a/listener.py b/listener.py index 6a94592..1df6052 100644 --- a/listener.py +++ b/listener.py @@ -7,9 +7,12 @@ from spotframework.net.network import Network, NetworkUser logger = logging.getLogger('spotframework') +if not os.path.exists('.spot'): + os.mkdir('.spot') + log_format = '%(asctime)s %(levelname)s %(name)s:%(funcName)s - %(message)s' -file_handler = logging.FileHandler("data/listener.log") +file_handler = logging.FileHandler(".spot/listener.log") formatter = logging.Formatter(log_format) file_handler.setFormatter(formatter) diff --git a/spotframework/listener/cmd.py b/spotframework/listener/cmd.py index 3964145..f7764a5 100644 --- a/spotframework/listener/cmd.py +++ b/spotframework/listener/cmd.py @@ -41,7 +41,7 @@ class ListenCmd(Cmd): Cmd.__init__(self) self.net = net self.listen_thread: Optional[ListenerThread] = None - self.last_dataset = None + self.last_listener = None self.verbose = False self.log_stream_handler = log_stream_handler @@ -55,14 +55,14 @@ class ListenCmd(Cmd): logger.info('starting') print('>> starting listener') self.listen_thread = ListenerThread(self.net) - self.listen_thread.on_playback_change.append(lambda x: print(f'playback changed -> {x}')) + self.listen_thread.listener.on_playback_change.append(lambda x: print(f'playback changed -> {x}')) self.listen_thread.start() @check_thread def stop_listener(self): logger.info('stopping') print('>> stopping listener') - self.last_dataset = self.listen_thread.recent_tracks + self.last_listener = self.listen_thread.listener self.listen_thread.stop() def print_tracks(self, tracks): @@ -71,10 +71,10 @@ class ListenCmd(Cmd): def print(self): if self.listen_thread is not None: - print('now playing:', self.listen_thread.now_playing) - self.print_tracks(self.listen_thread.recent_tracks) - elif self.last_dataset is not None: - self.print_tracks(self.last_dataset) + self.print_tracks(self.listen_thread.listener.recent_tracks) + print('now playing:', self.listen_thread.listener.now_playing) + elif self.last_listener is not None: + self.print_tracks(self.last_listener.recent_tracks) else: print('>> no tracks to print') diff --git a/spotframework/listener/listener.py b/spotframework/listener/listener.py new file mode 100644 index 0000000..bae56c1 --- /dev/null +++ b/spotframework/listener/listener.py @@ -0,0 +1,52 @@ +from spotframework.model.service import CurrentlyPlaying +from spotframework.net.network import Network + +from typing import Optional +import logging + +logger = logging.getLogger(__name__) + + +class Listener: + def __init__(self, + net: Network, + request_size: int = 20, + max_recent_tracks: int = None): + self.net = net + self.request_size = request_size + self.max_recent_tracks = max_recent_tracks + + self.recent_tracks = [] + self.prev_now_playing: Optional[CurrentlyPlaying] = None + self.now_playing: Optional[CurrentlyPlaying] = net.get_player() + + self.on_playback_change = [] + + def update_now_playing(self): + logger.debug('updating now playing') + live_now_playing = self.net.get_player() + + if self.now_playing is None and live_now_playing is None: + return + + if live_now_playing != self.now_playing: + self.prev_now_playing = self.now_playing + self.now_playing = live_now_playing + for func in self.on_playback_change: + func(live_now_playing) + else: + self.now_playing = live_now_playing + + def update_recent_tracks(self): + logger.debug('updating recent tracks') + tracks = self.net.get_recently_played_tracks(response_limit=self.request_size) + if tracks is not None: + for track in tracks: + if track.played_at not in [i.played_at for i in self.recent_tracks]: + self.recent_tracks.append(track) + + self.recent_tracks.sort(key=lambda x: x.played_at) + if self.max_recent_tracks is not None: + self.recent_tracks = self.recent_tracks[-self.max_recent_tracks:] + else: + logger.error('no recent tracks returned') diff --git a/spotframework/listener/thread.py b/spotframework/listener/thread.py index 9def839..d5f51c4 100644 --- a/spotframework/listener/thread.py +++ b/spotframework/listener/thread.py @@ -1,9 +1,8 @@ import threading import logging -from typing import Optional from spotframework.net.network import Network -from spotframework.model.service import CurrentlyPlaying +from spotframework.listener.listener import Listener logger = logging.getLogger(__name__) @@ -13,20 +12,13 @@ class ListenerThread(threading.Thread): def __init__(self, net: Network, sleep_interval: int = 5, - request_size: int = 5): + request_size: int = 20): super(ListenerThread, self).__init__() self._stop_event = threading.Event() - - self.net = net - self.sleep_interval = sleep_interval - self.request_size = request_size + self.iterating_actions = [] - self.recent_tracks = [] - self.prev_now_playing: Optional[CurrentlyPlaying] = None - self.now_playing: Optional[CurrentlyPlaying] = net.get_player() - - self.on_playback_change = [] + self.listener = Listener(net=net, request_size=request_size) def stop(self): logger.info('stopping thread') @@ -35,31 +27,10 @@ class ListenerThread(threading.Thread): def stopped(self): return self._stop_event.is_set() - def update_now_playing(self): - live_now_playing = self.net.get_player() - - if self.now_playing is None and live_now_playing is None: - return - - if live_now_playing != self.now_playing: - self.prev_now_playing = self.now_playing - self.now_playing = live_now_playing - for func in self.on_playback_change: - func(live_now_playing) - else: - self.now_playing = live_now_playing - - def update_recent_tracks(self): - logger.debug('pulling tracks') - tracks = self.net.get_recently_played_tracks(response_limit=self.request_size) - for track in tracks: - if track.played_at not in [i.played_at for i in self.recent_tracks]: - self.recent_tracks.append(track) - - self.recent_tracks.sort(key=lambda x: x.played_at) - def run(self): while not self.stopped(): - self.update_recent_tracks() - self.update_now_playing() + self.listener.update_recent_tracks() + self.listener.update_now_playing() + for action in self.iterating_actions: + action() self._stop_event.wait(self.sleep_interval) diff --git a/spotframework/model/service.py b/spotframework/model/service.py index 4343495..cda1705 100644 --- a/spotframework/model/service.py +++ b/spotframework/model/service.py @@ -21,6 +21,9 @@ class Context: self.href = href self.external_spot = external_spot + def __eq__(self, other): + return isinstance(other, Context) and other.uri == self.uri + def __repr__(self): return f'Context: {self.object_type} uri({self.uri})' @@ -95,7 +98,7 @@ class CurrentlyPlaying: f'repeat({self.repeat}) time({self.timestamp})' def __eq__(self, other): - return isinstance(other, CurrentlyPlaying) and other.track == self.track + return isinstance(other, CurrentlyPlaying) and other.track == self.track and other.context == self.context @staticmethod def _format_duration(duration):