From dd494107d370dce1e0de0524e05459958edd9f5b Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Thu, 1 Jul 2010 00:39:50 +0200 Subject: [PATCH] Extract mpd_format from models to mopidy.mpd.serializers --- mopidy/models.py | 70 +++------------------------------- mopidy/mpd/serializer.py | 71 ++++++++++++++++++++++++++++++++++ tests/models_test.py | 66 -------------------------------- tests/mpd/serializer_test.py | 74 ++++++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 130 deletions(-) create mode 100644 mopidy/mpd/serializer.py create mode 100644 tests/mpd/serializer_test.py diff --git a/mopidy/models.py b/mopidy/models.py index df1d12a1..09a509dc 100644 --- a/mopidy/models.py +++ b/mopidy/models.py @@ -1,5 +1,7 @@ from copy import copy +from mopidy.mpd import serializer + class ImmutableObject(object): """ Superclass for immutable objects whose fields can only be modified via the @@ -138,43 +140,8 @@ class Track(ImmutableObject): """List of :class:`Artist`. Read-only.""" return list(self._artists) - def mpd_format(self, position=0, search_result=False): - """ - Format track for output to MPD client. - - :param position: track's position in playlist - :type position: integer - :param search_result: format for output in search result - :type search_result: boolean - :rtype: list of two-tuples - """ - result = [ - ('file', self.uri or ''), - ('Time', self.length and (self.length // 1000) or 0), - ('Artist', self.mpd_format_artists()), - ('Title', self.name or ''), - ('Album', self.album and self.album.name or ''), - ('Date', self.date or ''), - ] - if self.album is not None and self.album.num_tracks != 0: - result.append(('Track', '%d/%d' % ( - self.track_no, self.album.num_tracks))) - else: - result.append(('Track', self.track_no)) - if not search_result: - result.append(('Pos', position)) - result.append(('Id', self.id or position)) - return result - - def mpd_format_artists(self): - """ - Format track artists for output to MPD client. - - :rtype: string - """ - artists = list(self._artists) - artists.sort(key=lambda a: a.name) - return u', '.join([a.name for a in artists]) + def mpd_format(self, *args, **kwargs): + return serializer.track_to_mpd_format(self, *args, **kwargs) class Playlist(ImmutableObject): @@ -214,33 +181,8 @@ class Playlist(ImmutableObject): """The number of tracks in the playlist. Read-only.""" return len(self._tracks) - def mpd_format(self, start=0, end=None, search_result=False): - """ - Format playlist for output to MPD client. - - Optionally limit output to the slice ``[start:end]`` of the playlist. - - :param start: position of first track to include in output - :type start: int (positive or negative) - :param end: position after last track to include in output - :type end: int (positive or negative) or :class:`None` for end of list - :rtype: list of lists of two-tuples - """ - if start < 0: - range_start = self.length + start - else: - range_start = start - if end is not None and end < 0: - range_end = self.length - end - elif end is not None and end >= 0: - range_end = end - else: - range_end = self.length - tracks = [] - for track, position in zip(self.tracks[start:end], - range(range_start, range_end)): - tracks.append(track.mpd_format(position, search_result)) - return tracks + def mpd_format(self, *args, **kwargs): + return serializer.playlist_to_mpd_format(self, *args, **kwargs) def with_(self, uri=None, name=None, tracks=None, last_modified=None): """ diff --git a/mopidy/mpd/serializer.py b/mopidy/mpd/serializer.py new file mode 100644 index 00000000..c88ef1c0 --- /dev/null +++ b/mopidy/mpd/serializer.py @@ -0,0 +1,71 @@ +def track_to_mpd_format(track, position=0, search_result=False): + """ + Format track for output to MPD client. + + :param track: the track + :type track: :class:`mopidy.models.Track` + :param position: track's position in playlist + :type position: integer + :param search_result: format for output in search result + :type search_result: boolean + :rtype: list of two-tuples + """ + result = [ + ('file', track.uri or ''), + ('Time', track.length and (track.length // 1000) or 0), + ('Artist', track_artists_to_mpd_format(track)), + ('Title', track.name or ''), + ('Album', track.album and track.album.name or ''), + ('Date', track.date or ''), + ] + if track.album is not None and track.album.num_tracks != 0: + result.append(('Track', '%d/%d' % ( + track.track_no, track.album.num_tracks))) + else: + result.append(('Track', track.track_no)) + if not search_result: + result.append(('Pos', position)) + result.append(('Id', track.id or position)) + return result + +def track_artists_to_mpd_format(track): + """ + Format track artists for output to MPD client. + + :param track: the track + :type track: :class:`mopidy.models.Track` + :rtype: string + """ + artists = track.artists + artists.sort(key=lambda a: a.name) + return u', '.join([a.name for a in artists]) + +def playlist_to_mpd_format(playlist, start=0, end=None, search_result=False): + """ + Format playlist for output to MPD client. + + Optionally limit output to the slice ``[start:end]`` of the playlist. + + :param playlist: the playlist + :type playlist: :class:`mopidy.models.Playlist` + :param start: position of first track to include in output + :type start: int (positive or negative) + :param end: position after last track to include in output + :type end: int (positive or negative) or :class:`None` for end of list + :rtype: list of lists of two-tuples + """ + if start < 0: + range_start = playlist.length + start + else: + range_start = start + if end is not None and end < 0: + range_end = playlist.length - end + elif end is not None and end >= 0: + range_end = end + else: + range_end = playlist.length + tracks = [] + for track, position in zip(playlist.tracks[start:end], + range(range_start, range_end)): + tracks.append(track.mpd_format(position, search_result)) + return tracks diff --git a/tests/models_test.py b/tests/models_test.py index 1bafd792..7fab86f5 100644 --- a/tests/models_test.py +++ b/tests/models_test.py @@ -228,45 +228,6 @@ class TrackTest(unittest.TestCase): self.assertEqual(track.id, track_id) self.assertRaises(AttributeError, setattr, track, 'id', None) - def test_mpd_format_for_empty_track(self): - track = Track() - result = track.mpd_format() - self.assert_(('file', '') in result) - self.assert_(('Time', 0) in result) - self.assert_(('Artist', '') in result) - self.assert_(('Title', '') in result) - self.assert_(('Album', '') in result) - self.assert_(('Track', 0) in result) - self.assert_(('Date', '') in result) - self.assert_(('Pos', 0) in result) - self.assert_(('Id', 0) in result) - - def test_mpd_format_for_nonempty_track(self): - track = Track( - uri=u'a uri', - artists=[Artist(name=u'an artist')], - name=u'a name', - album=Album(name=u'an album', num_tracks=13), - track_no=7, - date=dt.date(1977, 1, 1), - length=137000, - id=122, - ) - result = track.mpd_format(position=9) - self.assert_(('file', 'a uri') in result) - self.assert_(('Time', 137) in result) - self.assert_(('Artist', 'an artist') in result) - self.assert_(('Title', 'a name') in result) - self.assert_(('Album', 'an album') in result) - self.assert_(('Track', '7/13') in result) - self.assert_(('Date', dt.date(1977, 1, 1)) in result) - self.assert_(('Pos', 9) in result) - self.assert_(('Id', 122) in result) - - def test_mpd_format_artists(self): - track = Track(artists=[Artist(name=u'ABBA'), Artist(name=u'Beatles')]) - self.assertEqual(track.mpd_format_artists(), u'ABBA, Beatles') - def test_invalid_kwarg(self): test = lambda: Track(foo='baz') self.assertRaises(TypeError, test) @@ -450,33 +411,6 @@ class PlaylistTest(unittest.TestCase): self.assertRaises(AttributeError, setattr, playlist, 'last_modified', None) - def test_mpd_format(self): - playlist = Playlist(tracks=[ - Track(track_no=1), Track(track_no=2), Track(track_no=3)]) - result = playlist.mpd_format() - self.assertEqual(len(result), 3) - - def test_mpd_format_with_range(self): - playlist = Playlist(tracks=[ - Track(track_no=1), Track(track_no=2), Track(track_no=3)]) - result = playlist.mpd_format(1, 2) - self.assertEqual(len(result), 1) - self.assertEqual(dict(result[0])['Track'], 2) - - def test_mpd_format_with_negative_start_and_no_end(self): - playlist = Playlist(tracks=[ - Track(track_no=1), Track(track_no=2), Track(track_no=3)]) - result = playlist.mpd_format(-1, None) - self.assertEqual(len(result), 1) - self.assertEqual(dict(result[0])['Track'], 3) - - def test_mpd_format_with_negative_start_and_end(self): - playlist = Playlist(tracks=[ - Track(track_no=1), Track(track_no=2), Track(track_no=3)]) - result = playlist.mpd_format(-2, -1) - self.assertEqual(len(result), 1) - self.assertEqual(dict(result[0])['Track'], 2) - def test_with_new_uri(self): tracks = [Track()] last_modified = dt.datetime.now() diff --git a/tests/mpd/serializer_test.py b/tests/mpd/serializer_test.py new file mode 100644 index 00000000..1ca34cf3 --- /dev/null +++ b/tests/mpd/serializer_test.py @@ -0,0 +1,74 @@ +import datetime as dt +import unittest + +from mopidy.models import Album, Artist, Playlist, Track +from mopidy.mpd import serializer + +class TrackMpdFormatTest(unittest.TestCase): + def test_mpd_format_for_empty_track(self): + result = serializer.track_to_mpd_format(Track()) + self.assert_(('file', '') in result) + self.assert_(('Time', 0) in result) + self.assert_(('Artist', '') in result) + self.assert_(('Title', '') in result) + self.assert_(('Album', '') in result) + self.assert_(('Track', 0) in result) + self.assert_(('Date', '') in result) + self.assert_(('Pos', 0) in result) + self.assert_(('Id', 0) in result) + + def test_mpd_format_for_nonempty_track(self): + track = Track( + uri=u'a uri', + artists=[Artist(name=u'an artist')], + name=u'a name', + album=Album(name=u'an album', num_tracks=13), + track_no=7, + date=dt.date(1977, 1, 1), + length=137000, + id=122, + ) + result = serializer.track_to_mpd_format(track, position=9) + self.assert_(('file', 'a uri') in result) + self.assert_(('Time', 137) in result) + self.assert_(('Artist', 'an artist') in result) + self.assert_(('Title', 'a name') in result) + self.assert_(('Album', 'an album') in result) + self.assert_(('Track', '7/13') in result) + self.assert_(('Date', dt.date(1977, 1, 1)) in result) + self.assert_(('Pos', 9) in result) + self.assert_(('Id', 122) in result) + + def test_mpd_format_artists(self): + track = Track(artists=[Artist(name=u'ABBA'), Artist(name=u'Beatles')]) + self.assertEqual(serializer.track_artists_to_mpd_format(track), + u'ABBA, Beatles') + + +class PlaylistMpdFormatTest(unittest.TestCase): + def test_mpd_format(self): + playlist = Playlist(tracks=[ + Track(track_no=1), Track(track_no=2), Track(track_no=3)]) + result = serializer.playlist_to_mpd_format(playlist) + self.assertEqual(len(result), 3) + + def test_mpd_format_with_range(self): + playlist = Playlist(tracks=[ + Track(track_no=1), Track(track_no=2), Track(track_no=3)]) + result = serializer.playlist_to_mpd_format(playlist, 1, 2) + self.assertEqual(len(result), 1) + self.assertEqual(dict(result[0])['Track'], 2) + + def test_mpd_format_with_negative_start_and_no_end(self): + playlist = Playlist(tracks=[ + Track(track_no=1), Track(track_no=2), Track(track_no=3)]) + result = serializer.playlist_to_mpd_format(playlist, -1, None) + self.assertEqual(len(result), 1) + self.assertEqual(dict(result[0])['Track'], 3) + + def test_mpd_format_with_negative_start_and_end(self): + playlist = Playlist(tracks=[ + Track(track_no=1), Track(track_no=2), Track(track_no=3)]) + result = serializer.playlist_to_mpd_format(playlist, -2, -1) + self.assertEqual(len(result), 1) + self.assertEqual(dict(result[0])['Track'], 2)