From 077f13a5ddfd27a8d24809b703cc1bd7a857cb34 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 26 Dec 2009 05:08:51 +0100 Subject: [PATCH] Add tracking of time position in track --- mopidy/backends/base.py | 25 +++++++++++++++++++++++ mopidy/backends/spotify.py | 42 +++++++++++++++++++++++--------------- mopidy/handler.py | 6 ++++-- tests/handlertest.py | 12 ++++++++++- 4 files changed, 65 insertions(+), 20 deletions(-) diff --git a/mopidy/backends/base.py b/mopidy/backends/base.py index 740d3843..4e8d8163 100644 --- a/mopidy/backends/base.py +++ b/mopidy/backends/base.py @@ -1,3 +1,5 @@ +import time + class BaseBackend(object): PLAY = u'play' PAUSE = u'pause' @@ -5,6 +7,8 @@ class BaseBackend(object): def __init__(self): self.state = self.STOP + self._play_time_accumulated = 0 + self._play_start = False def current_song(self): return None @@ -38,6 +42,19 @@ class BaseBackend(object): return self.state def status_time(self): + return u'%s:%s' % ( + self.status_time_position(), self.status_time_total()) + + def status_time_position(self): + if self.state == self.PAUSE: + return self._play_time_accumulated + elif self.state == self.PLAY and self._play_start: + return self._play_time_accumulated + ( + int(time.time()) - self._play_start) + else: + return 0 + + def status_time_total(self): return 0 def status_xfade(self): @@ -49,21 +66,29 @@ class BaseBackend(object): def pause(self): self.state = self.PAUSE + self._play_time_accumulated += int(time.time()) - self._play_start def play(self): self.state = self.PLAY + self._play_time_accumulated = 0 + self._play_start = int(time.time()) def play_pos(self, songpos): self.state = self.PLAY + self._play_time_accumulated = 0 + self._play_start = int(time.time()) def play_id(self, songid): self.state = self.PLAY + self._play_time_accumulated = 0 + self._play_start = int(time.time()) def previous(self): pass def resume(self): self.state = self.PLAY + self._play_start = int(time.time()) def stop(self): self.state = self.STOP diff --git a/mopidy/backends/spotify.py b/mopidy/backends/spotify.py index a9272245..7fd5b052 100644 --- a/mopidy/backends/spotify.py +++ b/mopidy/backends/spotify.py @@ -63,6 +63,10 @@ class SpotifyBackend(BaseBackend): self._x_current_playlist_version = 0 return self._x_current_playlist_version + @property + def _current_track(self): + return self._current_playlist[self._current_song_id] + @property def _current_song_id(self): if not hasattr(self, '_x_current_song_id'): @@ -106,42 +110,47 @@ class SpotifyBackend(BaseBackend): artist_names = [decode(artist.name) for artist in artists] return u', '.join(artist_names) - # Control methods + def next(self): self._current_song_id += 1 - self.play_id(self._current_song_id) + self.play() def pause(self): - self.state = self.PAUSE + super(SpotifyBackend, self).pause() self.spotify.pause() def play(self): - self.play_id(self._current_song_id) + if self.state == self.PAUSE: + return self.resume() + super(SpotifyBackend, self).play() + self.spotify.play(self._current_track) def play_pos(self, songpos): - self.play_id(songpos) + super(SpotifyBackend, self).play_pos(songpos) + self._current_song_id = songpos + track = self._current_playlist[songid] + self.spotify.play(track) def play_id(self, songid): - self.state = self.PLAY + super(SpotifyBackend, self).play_id(songid) self._current_song_id = songid track = self._current_playlist[songid] self.spotify.play(track) def previous(self): self._current_song_id -= 1 - self.play_id(self._current_song_id) + self.play() def resume(self): - self.state = self.PLAY + super(SpotifyBackend, self).resume() self.spotify.resume() def stop(self): - if self.state is not self.STOP: - self.state = self.STOP - self.spotify.stop() + super(SpotifyBackend, self).stop() + self.spotify.stop() - ### MPD handlers +# Unsorted def current_song(self): try: @@ -184,6 +193,7 @@ class SpotifyBackend(BaseBackend): return self._format_playlist(self._current_playlist) # Status methods + def status_playlist(self): return self._current_playlist_version @@ -193,16 +203,14 @@ class SpotifyBackend(BaseBackend): def status_song_id(self): return self._current_song_id - def status_time(self): - if self.state is self.PLAY: - return u'0:00' - else: - return None + def status_time_total(self): + return self._current_track.length // 1000 def url_handlers(self): return [u'spotify:', u'http://open.spotify.com/'] # Music database methods + def search(self, type, what): result = self.spotify.search(encode(u'%s:%s' % (type, what))) return self._format_playlist(result.playlist.tracks) diff --git a/mopidy/handler.py b/mopidy/handler.py index dc472cc4..277146fb 100644 --- a/mopidy/handler.py +++ b/mopidy/handler.py @@ -379,7 +379,7 @@ class MpdHandler(object): @register(r'^status$') def _status(self): - return [ + result = [ ('volume', self.backend.status_volume()), ('repeat', self.backend.status_repeat()), ('random', self.backend.status_random()), @@ -391,8 +391,10 @@ class MpdHandler(object): ('state', self.backend.status_state()), ('song', self.backend.status_song_id()), ('songid', self.backend.status_song_id()), - ('time', self.backend.status_time()), ] + if self.backend.state in (self.backend.PLAY, self.backend.PAUSE): + result.append(('time', self.backend.status_time())) + return result @register(r'^swap (?P\d+) (?P\d+)$') def _swap(self, songpos1, songpos2): diff --git a/tests/handlertest.py b/tests/handlertest.py index f4088df6..cd2ba823 100644 --- a/tests/handlertest.py +++ b/tests/handlertest.py @@ -73,7 +73,8 @@ class CommandListsTest(unittest.TestCase): class StatusHandlerTest(unittest.TestCase): def setUp(self): - self.h = handler.MpdHandler(backend=DummyBackend()) + self.b = DummyBackend() + self.h = handler.MpdHandler(backend=self.b) def test_clearerror(self): result = self.h.handle_request(u'clearerror') @@ -137,6 +138,15 @@ class StatusHandlerTest(unittest.TestCase): self.assert_('state' in result) self.assert_(result['state'] in ('play', 'stop', 'pause')) + def test_status_method_when_playing(self): + self.b.state = self.b.PLAY + result = dict(self.h._status()) + self.assert_('time' in result) + (position, total) = result['time'].split(':') + position = int(position) + total = int(total) + self.assert_(position <= total) + class PlaybackOptionsHandlerTest(unittest.TestCase): def setUp(self):