diff --git a/mopidy/backends/base/current_playlist.py b/mopidy/backends/base/current_playlist.py index ffdce176..2633f166 100644 --- a/mopidy/backends/base/current_playlist.py +++ b/mopidy/backends/base/current_playlist.py @@ -2,6 +2,8 @@ from copy import copy import logging import random +from mopidy.models import CpTrack + logger = logging.getLogger('mopidy.backends.base') class CurrentPlaylistController(object): @@ -66,7 +68,7 @@ class CurrentPlaylistController(object): """ assert at_position <= len(self._cp_tracks), \ u'at_position can not be greater than playlist length' - cp_track = (self.version, track) + cp_track = CpTrack(self.version, track) if at_position is not None: self._cp_tracks.insert(at_position, cp_track) else: diff --git a/mopidy/backends/base/playback.py b/mopidy/backends/base/playback.py index 88ae141d..4ea7a13f 100644 --- a/mopidy/backends/base/playback.py +++ b/mopidy/backends/base/playback.py @@ -80,12 +80,12 @@ class PlaybackController(object): def _get_cpid(self, cp_track): if cp_track is None: return None - return cp_track[0] + return cp_track.cpid def _get_track(self, cp_track): if cp_track is None: return None - return cp_track[1] + return cp_track.track @property def current_cpid(self): @@ -331,7 +331,7 @@ class PlaybackController(object): self.stop(clear_current_track=True) if self.consume: - self.backend.current_playlist.remove(cpid=original_cp_track[0]) + self.backend.current_playlist.remove(cpid=original_cp_track.cpid) def on_current_playlist_change(self): """ @@ -389,7 +389,7 @@ class PlaybackController(object): self.state = self.STOPPED self.current_cp_track = cp_track self.state = self.PLAYING - if not self.provider.play(cp_track[1]): + if not self.provider.play(cp_track.track): # Track is not playable if self.random and self._shuffled: self._shuffled.remove(cp_track) diff --git a/mopidy/frontends/mpd/protocol/current_playlist.py b/mopidy/frontends/mpd/protocol/current_playlist.py index 82e096a0..8e26013d 100644 --- a/mopidy/frontends/mpd/protocol/current_playlist.py +++ b/mopidy/frontends/mpd/protocol/current_playlist.py @@ -59,7 +59,7 @@ def addid(context, uri, songpos=None): raise MpdArgError(u'Bad song index', command=u'addid') cp_track = context.backend.current_playlist.add(track, at_position=songpos).get() - return ('Id', cp_track[0]) + return ('Id', cp_track.cpid) @handle_request(r'^delete "(?P\d+):(?P\d+)*"$') def delete_range(context, start, end=None): @@ -217,7 +217,7 @@ def playlistid(context, cpid=None): cp_track = context.backend.current_playlist.get(cpid=cpid).get() position = context.backend.current_playlist.cp_tracks.get().index( cp_track) - return cp_track[1].mpd_format(position=position, cpid=cpid) + return cp_track.track.mpd_format(position=position, cpid=cpid) except LookupError: raise MpdNoExistError(u'No such song', command=u'playlistid') else: diff --git a/mopidy/frontends/mpd/protocol/status.py b/mopidy/frontends/mpd/protocol/status.py index bf0c4f08..abbb8d7f 100644 --- a/mopidy/frontends/mpd/protocol/status.py +++ b/mopidy/frontends/mpd/protocol/status.py @@ -28,9 +28,9 @@ def currentsong(context): """ current_cp_track = context.backend.playback.current_cp_track.get() if current_cp_track is not None: - return current_cp_track[1].mpd_format( + return current_cp_track.track.mpd_format( position=context.backend.playback.current_playlist_position.get(), - cpid=current_cp_track[0]) + cpid=current_cp_track.cpid) @handle_request(r'^idle$') @handle_request(r'^idle (?P.+)$') @@ -171,7 +171,7 @@ def status(context): def _status_bitrate(futures): current_cp_track = futures['playback.current_cp_track'].get() if current_cp_track is not None: - return current_cp_track[1].bitrate + return current_cp_track.track.bitrate def _status_consume(futures): if futures['playback.consume'].get(): @@ -197,7 +197,7 @@ def _status_single(futures): def _status_songid(futures): current_cp_track = futures['playback.current_cp_track'].get() if current_cp_track is not None: - return current_cp_track[0] + return current_cp_track.cpid else: return _status_songpos(futures) @@ -224,10 +224,10 @@ def _status_time_total(futures): current_cp_track = futures['playback.current_cp_track'].get() if current_cp_track is None: return 0 - elif current_cp_track[1].length is None: + elif current_cp_track.track.length is None: return 0 else: - return current_cp_track[1].length + return current_cp_track.track.length def _status_volume(futures): volume = futures['mixer.volume'].get() diff --git a/mopidy/models.py b/mopidy/models.py index 2ede4352..ed323b71 100644 --- a/mopidy/models.py +++ b/mopidy/models.py @@ -1,3 +1,4 @@ +from collections import namedtuple class ImmutableObject(object): """ @@ -128,6 +129,9 @@ class Album(ImmutableObject): super(Album, self).__init__(*args, **kwargs) +CpTrack = namedtuple('CpTrack', ['cpid', 'track']) + + class Track(ImmutableObject): """ :param uri: track URI diff --git a/tests/backends/base/current_playlist.py b/tests/backends/base/current_playlist.py index 427ce76d..b84391af 100644 --- a/tests/backends/base/current_playlist.py +++ b/tests/backends/base/current_playlist.py @@ -23,14 +23,14 @@ class CurrentPlaylistControllerTest(object): cp_track = self.controller.add(track) self.assertEqual(track, self.controller.tracks[-1]) self.assertEqual(cp_track, self.controller.cp_tracks[-1]) - self.assertEqual(track, cp_track[1]) + self.assertEqual(track, cp_track.track) def test_add_at_position(self): for track in self.tracks[:-1]: cp_track = self.controller.add(track, 0) self.assertEqual(track, self.controller.tracks[0]) self.assertEqual(cp_track, self.controller.cp_tracks[0]) - self.assertEqual(track, cp_track[1]) + self.assertEqual(track, cp_track.track) @populate_playlist def test_add_at_position_outside_of_playlist(self): @@ -40,12 +40,12 @@ class CurrentPlaylistControllerTest(object): @populate_playlist def test_get_by_cpid(self): cp_track = self.controller.cp_tracks[1] - self.assertEqual(cp_track, self.controller.get(cpid=cp_track[0])) + self.assertEqual(cp_track, self.controller.get(cpid=cp_track.cpid)) @populate_playlist def test_get_by_uri(self): cp_track = self.controller.cp_tracks[1] - self.assertEqual(cp_track, self.controller.get(uri=cp_track[1].uri)) + self.assertEqual(cp_track, self.controller.get(uri=cp_track.track.uri)) @populate_playlist def test_get_by_uri_raises_error_for_invalid_uri(self): diff --git a/tests/models_test.py b/tests/models_test.py index afbf9d50..637a8209 100644 --- a/tests/models_test.py +++ b/tests/models_test.py @@ -1,7 +1,7 @@ import datetime as dt import unittest -from mopidy.models import Artist, Album, Track, Playlist +from mopidy.models import Artist, Album, CpTrack, Track, Playlist from tests import SkipTest @@ -274,6 +274,21 @@ class AlbumTest(unittest.TestCase): self.assertNotEqual(hash(album1), hash(album2)) +class CpTrackTest(unittest.TestCase): + def setUp(self): + self.cpid = 123 + self.track = Track() + self.cp_track = CpTrack(self.cpid, self.track) + + def test_cp_track_can_be_accessed_as_a_tuple(self): + self.assertEqual(self.cpid, self.cp_track[0]) + self.assertEqual(self.track, self.cp_track[1]) + + def test_cp_track_can_be_accessed_by_attribute_names(self): + self.assertEqual(self.cpid, self.cp_track.cpid) + self.assertEqual(self.track, self.cp_track.track) + + class TrackTest(unittest.TestCase): def test_uri(self): uri = u'an_uri'