split listener into own object

added callback functions
added max recent tracks check
added log dir check
This commit is contained in:
aj 2019-12-24 10:25:32 +00:00
parent e6f120b930
commit c3fd748c65
5 changed files with 75 additions and 46 deletions

View File

@ -7,9 +7,12 @@ from spotframework.net.network import Network, NetworkUser
logger = logging.getLogger('spotframework') 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' 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) formatter = logging.Formatter(log_format)
file_handler.setFormatter(formatter) file_handler.setFormatter(formatter)

View File

@ -41,7 +41,7 @@ class ListenCmd(Cmd):
Cmd.__init__(self) Cmd.__init__(self)
self.net = net self.net = net
self.listen_thread: Optional[ListenerThread] = None self.listen_thread: Optional[ListenerThread] = None
self.last_dataset = None self.last_listener = None
self.verbose = False self.verbose = False
self.log_stream_handler = log_stream_handler self.log_stream_handler = log_stream_handler
@ -55,14 +55,14 @@ class ListenCmd(Cmd):
logger.info('starting') logger.info('starting')
print('>> starting listener') print('>> starting listener')
self.listen_thread = ListenerThread(self.net) 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() self.listen_thread.start()
@check_thread @check_thread
def stop_listener(self): def stop_listener(self):
logger.info('stopping') logger.info('stopping')
print('>> stopping listener') print('>> stopping listener')
self.last_dataset = self.listen_thread.recent_tracks self.last_listener = self.listen_thread.listener
self.listen_thread.stop() self.listen_thread.stop()
def print_tracks(self, tracks): def print_tracks(self, tracks):
@ -71,10 +71,10 @@ class ListenCmd(Cmd):
def print(self): def print(self):
if self.listen_thread is not None: if self.listen_thread is not None:
print('now playing:', self.listen_thread.now_playing) self.print_tracks(self.listen_thread.listener.recent_tracks)
self.print_tracks(self.listen_thread.recent_tracks) print('now playing:', self.listen_thread.listener.now_playing)
elif self.last_dataset is not None: elif self.last_listener is not None:
self.print_tracks(self.last_dataset) self.print_tracks(self.last_listener.recent_tracks)
else: else:
print('>> no tracks to print') print('>> no tracks to print')

View File

@ -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')

View File

@ -1,9 +1,8 @@
import threading import threading
import logging import logging
from typing import Optional
from spotframework.net.network import Network from spotframework.net.network import Network
from spotframework.model.service import CurrentlyPlaying from spotframework.listener.listener import Listener
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -13,20 +12,13 @@ class ListenerThread(threading.Thread):
def __init__(self, def __init__(self,
net: Network, net: Network,
sleep_interval: int = 5, sleep_interval: int = 5,
request_size: int = 5): request_size: int = 20):
super(ListenerThread, self).__init__() super(ListenerThread, self).__init__()
self._stop_event = threading.Event() self._stop_event = threading.Event()
self.net = net
self.sleep_interval = sleep_interval self.sleep_interval = sleep_interval
self.request_size = request_size self.iterating_actions = []
self.recent_tracks = [] self.listener = Listener(net=net, request_size=request_size)
self.prev_now_playing: Optional[CurrentlyPlaying] = None
self.now_playing: Optional[CurrentlyPlaying] = net.get_player()
self.on_playback_change = []
def stop(self): def stop(self):
logger.info('stopping thread') logger.info('stopping thread')
@ -35,31 +27,10 @@ class ListenerThread(threading.Thread):
def stopped(self): def stopped(self):
return self._stop_event.is_set() 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): def run(self):
while not self.stopped(): while not self.stopped():
self.update_recent_tracks() self.listener.update_recent_tracks()
self.update_now_playing() self.listener.update_now_playing()
for action in self.iterating_actions:
action()
self._stop_event.wait(self.sleep_interval) self._stop_event.wait(self.sleep_interval)

View File

@ -21,6 +21,9 @@ class Context:
self.href = href self.href = href
self.external_spot = external_spot self.external_spot = external_spot
def __eq__(self, other):
return isinstance(other, Context) and other.uri == self.uri
def __repr__(self): def __repr__(self):
return f'Context: {self.object_type} uri({self.uri})' return f'Context: {self.object_type} uri({self.uri})'
@ -95,7 +98,7 @@ class CurrentlyPlaying:
f'repeat({self.repeat}) time({self.timestamp})' f'repeat({self.repeat}) time({self.timestamp})'
def __eq__(self, other): 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 @staticmethod
def _format_duration(duration): def _format_duration(duration):