class LibraryControllerTest(object): artists = [Artist(name='artist1'), Artist(name='artist2'), Artist()] albums = [Album(name='album1', artists=artists[:1]), Album(name='album2', artists=artists[1:2]), Album()] tracks = [Track(name='track1', length=4000, artists=artists[:1], album=albums[0], uri='file://' + path_to_data_dir('uri1')), Track(name='track2', length=4000, artists=artists[1:2], album=albums[1], uri='file://' + path_to_data_dir('uri2')), Track()] def setUp(self): self.backend = self.backend_class() self.library = self.backend.library def test_refresh(self): self.library.refresh() @unittest.SkipTest def test_refresh_uri(self): pass @unittest.SkipTest def test_refresh_missing_uri(self): pass def test_lookup(self): track = self.library.lookup(self.tracks[0].uri) self.assertEqual(track, self.tracks[0]) def test_lookup_unknown_track(self): track = self.library.lookup('fake uri') self.assertEquals(track, None) def test_find_exact_no_hits(self): result = self.library.find_exact(track=['unknown track']) self.assertEqual(result, Playlist()) result = self.library.find_exact(artist=['unknown artist']) self.assertEqual(result, Playlist()) result = self.library.find_exact(album=['unknown artist']) self.assertEqual(result, Playlist()) def test_find_exact_artist(self): result = self.library.find_exact(artist=['artist1']) self.assertEqual(result, Playlist(tracks=self.tracks[:1])) result = self.library.find_exact(artist=['artist2']) self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) def test_find_exact_track(self): result = self.library.find_exact(track=['track1']) self.assertEqual(result, Playlist(tracks=self.tracks[:1])) result = self.library.find_exact(track=['track2']) self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) def test_find_exact_album(self): result = self.library.find_exact(album=['album1']) self.assertEqual(result, Playlist(tracks=self.tracks[:1])) result = self.library.find_exact(album=['album2']) self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) def test_find_exact_wrong_type(self): test = lambda: self.library.find_exact(wrong=['test']) self.assertRaises(LookupError, test) def test_find_exact_with_empty_query(self): test = lambda: self.library.find_exact(artist=['']) self.assertRaises(LookupError, test) test = lambda: self.library.find_exact(track=['']) self.assertRaises(LookupError, test) test = lambda: self.library.find_exact(album=['']) self.assertRaises(LookupError, test) def test_search_no_hits(self): result = self.library.search(track=['unknown track']) self.assertEqual(result, Playlist()) result = self.library.search(artist=['unknown artist']) self.assertEqual(result, Playlist()) result = self.library.search(album=['unknown artist']) self.assertEqual(result, Playlist()) result = self.library.search(uri=['unknown']) self.assertEqual(result, Playlist()) result = self.library.search(any=['unknown']) self.assertEqual(result, Playlist()) def test_search_artist(self): result = self.library.search(artist=['Tist1']) self.assertEqual(result, Playlist(tracks=self.tracks[:1])) result = self.library.search(artist=['Tist2']) self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) def test_search_track(self): result = self.library.search(track=['Rack1']) self.assertEqual(result, Playlist(tracks=self.tracks[:1])) result = self.library.search(track=['Rack2']) self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) def test_search_album(self): result = self.library.search(album=['Bum1']) self.assertEqual(result, Playlist(tracks=self.tracks[:1])) result = self.library.search(album=['Bum2']) self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) def test_search_uri(self): result = self.library.search(uri=['RI1']) self.assertEqual(result, Playlist(tracks=self.tracks[:1])) result = self.library.search(uri=['RI2']) self.assertEqual(result, Playlist(tracks=self.tracks[1:2])) def test_search_any(self): result = self.library.search(any=['Tist1']) self.assertEqual(result, Playlist(tracks=self.tracks[:1])) result = self.library.search(any=['Rack1']) self.assertEqual(result, Playlist(tracks=self.tracks[:1])) result = self.library.search(any=['Bum1']) self.assertEqual(result, Playlist(tracks=self.tracks[:1])) result = self.library.search(any=['RI1']) self.assertEqual(result, Playlist(tracks=self.tracks[:1])) def test_search_wrong_type(self): test = lambda: self.library.search(wrong=['test']) self.assertRaises(LookupError, test) def test_search_with_empty_query(self): test = lambda: self.library.search(artist=['']) self.assertRaises(LookupError, test) test = lambda: self.library.search(track=['']) self.assertRaises(LookupError, test) test = lambda: self.library.search(album=['']) self.assertRaises(LookupError, test) test = lambda: self.library.search(uri=['']) self.assertRaises(LookupError, test) test = lambda: self.library.search(any=['']) self.assertRaises(LookupError, test)
def _album_as_track(album): return Track(uri=album.uri, name='Album: ' + album.name, artists=album.artists, album=album, date=album.date)
def test_clear(self): self.storage.begin() self.storage.add(Track(uri="local:track:track.mp3")) self.storage.close() self.storage.clear() assert self.storage.load() == 0
def test_version_increases_when_adding_something(self): version = self.controller.version self.controller.add([Track()]) self.assertLess(version, self.controller.version)
def test_filter_by_uri_returns_multiple_matches(self): track = Track(uri='a') self.controller.add([Track(uri='z'), track, track]) tl_tracks = self.controller.filter(uri=['a']) self.assertEqual(track, tl_tracks[0].track) self.assertEqual(track, tl_tracks[1].track)
def _to_mopidy_track(self, song): return Track(uri=song['url'], name=unquote(song['title']), artists=[Artist(name=unquote(song['artist']))], length=int(song['duration']) * 1000)
class LocalTracklistProviderTest(unittest.TestCase): config = { 'local': { 'media_dir': path_to_data_dir(''), 'data_dir': path_to_data_dir(''), 'playlists_dir': b'', 'library': 'json', } } tracks = [Track(uri=generate_song(i), length=4464) for i in range(1, 4)] def setUp(self): self.audio = audio.DummyAudio.start().proxy() self.backend = actor.LocalBackend.start(config=self.config, audio=self.audio).proxy() self.core = core.Core(mixer=None, backends=[self.backend]) self.controller = self.core.tracklist self.playback = self.core.playback assert len(self.tracks) == 3, 'Need three tracks to run tests.' def tearDown(self): pykka.ActorRegistry.stop_all() def test_length(self): self.assertEqual(0, len(self.controller.tl_tracks)) self.assertEqual(0, self.controller.length) self.controller.add(self.tracks) self.assertEqual(3, len(self.controller.tl_tracks)) self.assertEqual(3, self.controller.length) def test_add(self): for track in self.tracks: tl_tracks = self.controller.add([track]) self.assertEqual(track, self.controller.tracks[-1]) self.assertEqual(tl_tracks[0], self.controller.tl_tracks[-1]) self.assertEqual(track, tl_tracks[0].track) def test_add_at_position(self): for track in self.tracks[:-1]: tl_tracks = self.controller.add([track], 0) self.assertEqual(track, self.controller.tracks[0]) self.assertEqual(tl_tracks[0], self.controller.tl_tracks[0]) self.assertEqual(track, tl_tracks[0].track) @populate_tracklist def test_add_at_position_outside_of_playlist(self): for track in self.tracks: tl_tracks = self.controller.add([track], len(self.tracks) + 2) self.assertEqual(track, self.controller.tracks[-1]) self.assertEqual(tl_tracks[0], self.controller.tl_tracks[-1]) self.assertEqual(track, tl_tracks[0].track) @populate_tracklist def test_filter_by_tlid(self): tl_track = self.controller.tl_tracks[1] self.assertEqual([tl_track], self.controller.filter(tlid=[tl_track.tlid])) @populate_tracklist def test_filter_by_uri(self): tl_track = self.controller.tl_tracks[1] self.assertEqual([tl_track], self.controller.filter(uri=[tl_track.track.uri])) @populate_tracklist def test_filter_by_uri_returns_nothing_for_invalid_uri(self): self.assertEqual([], self.controller.filter(uri=['foobar'])) def test_filter_by_uri_returns_single_match(self): track = Track(uri='a') self.controller.add([Track(uri='z'), track, Track(uri='y')]) self.assertEqual(track, self.controller.filter(uri=['a'])[0].track) def test_filter_by_uri_returns_multiple_matches(self): track = Track(uri='a') self.controller.add([Track(uri='z'), track, track]) tl_tracks = self.controller.filter(uri=['a']) self.assertEqual(track, tl_tracks[0].track) self.assertEqual(track, tl_tracks[1].track) def test_filter_by_uri_returns_nothing_if_no_match(self): self.controller.playlist = Playlist( tracks=[Track(uri=['z']), Track(uri=['y'])]) self.assertEqual([], self.controller.filter(uri=['a'])) def test_filter_by_multiple_criteria_returns_elements_matching_all(self): track1 = Track(uri='a', name='x') track2 = Track(uri='b', name='x') track3 = Track(uri='b', name='y') self.controller.add([track1, track2, track3]) self.assertEqual( track1, self.controller.filter(uri=['a'], name=['x'])[0].track) self.assertEqual( track2, self.controller.filter(uri=['b'], name=['x'])[0].track) self.assertEqual( track3, self.controller.filter(uri=['b'], name=['y'])[0].track) def test_filter_by_criteria_that_is_not_present_in_all_elements(self): track1 = Track() track2 = Track(uri='b') track3 = Track() self.controller.add([track1, track2, track3]) self.assertEqual(track2, self.controller.filter(uri=['b'])[0].track) @populate_tracklist def test_clear(self): self.controller.clear() self.assertEqual(len(self.controller.tracks), 0) def test_clear_empty_playlist(self): self.controller.clear() self.assertEqual(len(self.controller.tracks), 0) @populate_tracklist def test_clear_when_playing(self): self.playback.play() self.assertEqual(self.playback.state, PlaybackState.PLAYING) self.controller.clear() self.assertEqual(self.playback.state, PlaybackState.STOPPED) def test_add_appends_to_the_tracklist(self): self.controller.add([Track(uri='a'), Track(uri='b')]) self.assertEqual(len(self.controller.tracks), 2) self.controller.add([Track(uri='c'), Track(uri='d')]) self.assertEqual(len(self.controller.tracks), 4) self.assertEqual(self.controller.tracks[0].uri, 'a') self.assertEqual(self.controller.tracks[1].uri, 'b') self.assertEqual(self.controller.tracks[2].uri, 'c') self.assertEqual(self.controller.tracks[3].uri, 'd') def test_add_does_not_reset_version(self): version = self.controller.version self.controller.add([]) self.assertEqual(self.controller.version, version) @populate_tracklist def test_add_preserves_playing_state(self): self.playback.play() track = self.playback.current_track self.controller.add(self.controller.tracks[1:2]) self.assertEqual(self.playback.state, PlaybackState.PLAYING) self.assertEqual(self.playback.current_track, track) @populate_tracklist def test_add_preserves_stopped_state(self): self.controller.add(self.controller.tracks[1:2]) self.assertEqual(self.playback.state, PlaybackState.STOPPED) self.assertEqual(self.playback.current_track, None) @populate_tracklist def test_add_returns_the_tl_tracks_that_was_added(self): tl_tracks = self.controller.add(self.controller.tracks[1:2]) self.assertEqual(tl_tracks[0].track, self.controller.tracks[1]) def test_index_returns_index_of_track(self): tl_tracks = self.controller.add(self.tracks) self.assertEqual(0, self.controller.index(tl_tracks[0])) self.assertEqual(1, self.controller.index(tl_tracks[1])) self.assertEqual(2, self.controller.index(tl_tracks[2])) def test_index_returns_none_if_item_not_found(self): tl_track = TlTrack(0, Track()) self.assertEqual(self.controller.index(tl_track), None) @populate_tracklist def test_move_single(self): self.controller.move(0, 0, 2) tracks = self.controller.tracks self.assertEqual(tracks[2], self.tracks[0]) @populate_tracklist def test_move_group(self): self.controller.move(0, 2, 1) tracks = self.controller.tracks self.assertEqual(tracks[1], self.tracks[0]) self.assertEqual(tracks[2], self.tracks[1]) @populate_tracklist def test_moving_track_outside_of_playlist(self): tracks = len(self.controller.tracks) test = lambda: self.controller.move(0, 0, tracks + 5) self.assertRaises(AssertionError, test) @populate_tracklist def test_move_group_outside_of_playlist(self): tracks = len(self.controller.tracks) test = lambda: self.controller.move(0, 2, tracks + 5) self.assertRaises(AssertionError, test) @populate_tracklist def test_move_group_out_of_range(self): tracks = len(self.controller.tracks) test = lambda: self.controller.move(tracks + 2, tracks + 3, 0) self.assertRaises(AssertionError, test) @populate_tracklist def test_move_group_invalid_group(self): test = lambda: self.controller.move(2, 1, 0) self.assertRaises(AssertionError, test) def test_tracks_attribute_is_immutable(self): tracks1 = self.controller.tracks tracks2 = self.controller.tracks self.assertNotEqual(id(tracks1), id(tracks2)) @populate_tracklist def test_remove(self): track1 = self.controller.tracks[1] track2 = self.controller.tracks[2] version = self.controller.version self.controller.remove(uri=[track1.uri]) self.assertLess(version, self.controller.version) self.assertNotIn(track1, self.controller.tracks) self.assertEqual(track2, self.controller.tracks[1]) @populate_tracklist def test_removing_track_that_does_not_exist_does_nothing(self): self.controller.remove(uri=['/nonexistant']) def test_removing_from_empty_playlist_does_nothing(self): self.controller.remove(uri=['/nonexistant']) @populate_tracklist def test_remove_lists(self): track0 = self.controller.tracks[0] track1 = self.controller.tracks[1] track2 = self.controller.tracks[2] version = self.controller.version self.controller.remove(uri=[track0.uri, track2.uri]) self.assertLess(version, self.controller.version) self.assertNotIn(track0, self.controller.tracks) self.assertNotIn(track2, self.controller.tracks) self.assertEqual(track1, self.controller.tracks[0]) @populate_tracklist def test_shuffle(self): random.seed(1) self.controller.shuffle() shuffled_tracks = self.controller.tracks self.assertNotEqual(self.tracks, shuffled_tracks) self.assertEqual(set(self.tracks), set(shuffled_tracks)) @populate_tracklist def test_shuffle_subset(self): random.seed(1) self.controller.shuffle(1, 3) shuffled_tracks = self.controller.tracks self.assertNotEqual(self.tracks, shuffled_tracks) self.assertEqual(self.tracks[0], shuffled_tracks[0]) self.assertEqual(set(self.tracks), set(shuffled_tracks)) @populate_tracklist def test_shuffle_invalid_subset(self): test = lambda: self.controller.shuffle(3, 1) self.assertRaises(AssertionError, test) @populate_tracklist def test_shuffle_superset(self): tracks = len(self.controller.tracks) test = lambda: self.controller.shuffle(1, tracks + 5) self.assertRaises(AssertionError, test) @populate_tracklist def test_shuffle_open_subset(self): random.seed(1) self.controller.shuffle(1) shuffled_tracks = self.controller.tracks self.assertNotEqual(self.tracks, shuffled_tracks) self.assertEqual(self.tracks[0], shuffled_tracks[0]) self.assertEqual(set(self.tracks), set(shuffled_tracks)) @populate_tracklist def test_slice_returns_a_subset_of_tracks(self): track_slice = self.controller.slice(1, 3) self.assertEqual(2, len(track_slice)) self.assertEqual(self.tracks[1], track_slice[0].track) self.assertEqual(self.tracks[2], track_slice[1].track) @populate_tracklist def test_slice_returns_empty_list_if_indexes_outside_tracks_list(self): self.assertEqual(0, len(self.controller.slice(7, 8))) self.assertEqual(0, len(self.controller.slice(-1, 1))) def test_version_does_not_change_when_adding_nothing(self): version = self.controller.version self.controller.add([]) self.assertEquals(version, self.controller.version) def test_version_increases_when_adding_something(self): version = self.controller.version self.controller.add([Track()]) self.assertLess(version, self.controller.version)
def test_track_to_mpd_format_with_tlid(self): result = translator.track_to_mpd_format(TlTrack(1, Track())) assert ("Id", 1) not in result
def test_track_to_mpd_format_with_position_and_tlid(self): result = translator.track_to_mpd_format( TlTrack(2, Track(uri="a uri")), position=1 ) assert ("Pos", 1) in result assert ("Id", 2) in result
def channel_to_track(self, channel): ref = self.channel_to_ref(str(channel['catid']), channel) return Track(uri=ref.uri, name=ref.name)
def test_track_to_mpd_format_with_position(self): result = translator.track_to_mpd_format(Track(), position=1) assert ("Pos", 1) not in result
def _convert_mpd_data(data, tracks, music_dir): if not data: return track_kwargs = {} album_kwargs = {} artist_kwargs = {} albumartist_kwargs = {} if 'track' in data: if '/' in data['track']: album_kwargs['num_tracks'] = int(data['track'].split('/')[1]) track_kwargs['track_no'] = int(data['track'].split('/')[0]) else: track_kwargs['track_no'] = int(data['track']) if 'artist' in data: artist_kwargs['name'] = data['artist'] albumartist_kwargs['name'] = data['artist'] if 'albumartist' in data: albumartist_kwargs['name'] = data['albumartist'] if 'album' in data: album_kwargs['name'] = data['album'] if 'title' in data: track_kwargs['name'] = data['title'] if 'musicbrainz_trackid' in data: track_kwargs['musicbrainz_id'] = data['musicbrainz_trackid'] if 'musicbrainz_albumid' in data: album_kwargs['musicbrainz_id'] = data['musicbrainz_albumid'] if 'musicbrainz_artistid' in data: artist_kwargs['musicbrainz_id'] = data['musicbrainz_artistid'] if 'musicbrainz_albumartistid' in data: albumartist_kwargs['musicbrainz_id'] = ( data['musicbrainz_albumartistid']) if data['file'][0] == '/': path = data['file'][1:] else: path = data['file'] if artist_kwargs: artist = Artist(**artist_kwargs) track_kwargs['artists'] = [artist] if albumartist_kwargs: albumartist = Artist(**albumartist_kwargs) album_kwargs['artists'] = [albumartist] if album_kwargs: album = Album(**album_kwargs) track_kwargs['album'] = album track_kwargs['uri'] = path_to_uri(music_dir, path) track_kwargs['length'] = int(data.get('time', 0)) * 1000 track = Track(**track_kwargs) tracks.add(track)
def test_status_method_when_playing_contains_bitrate(self): self.set_tracklist([Track(uri="dummy:/a", bitrate=3200)]) self.core.playback.play().get() result = dict(status.status(self.context)) assert "bitrate" in result assert int(result["bitrate"]) == 3200
def test_status_method_when_playlist_loaded_contains_nextsongid(self): self.set_tracklist([Track(uri="dummy:/a"), Track(uri="dummy:/b")]) self.core.playback.play().get() result = dict(status.status(self.context)) assert "nextsongid" in result assert int(result["nextsongid"]) == 2
def test_track_to_mpd_format_with_cpid(self): result = translator.track_to_mpd_format(Track(), cpid=1) self.assert_(('Id', 1) not in result)
class TrackMpdFormatTest(unittest.TestCase): track = Track( uri="à uri", artists=[Artist(name="an artist")], name="a nàme", album=Album( name="an album", num_tracks=13, artists=[Artist(name="an other artist")], uri="urischeme:àlbum:12345", ), track_no=7, composers=[Artist(name="a composer")], performers=[Artist(name="a performer")], genre="a genre", date="1977-01-01", disc_no=1, comment="a comment", length=137000, ) def setUp(self): # noqa: N802 self.media_dir = "/dir/subdir" path_utils.mtime.set_fake_time(1234567) def tearDown(self): # noqa: N802 path_utils.mtime.undo_fake() def test_track_to_mpd_format_for_empty_track(self): result = translator.track_to_mpd_format( Track(uri="a uri", length=137000) ) assert ("file", "a uri") in result assert ("Time", 137) in result assert ("Artist", "") not in result assert ("Title", "") not in result assert ("Album", "") not in result assert ("Track", 0) not in result assert ("Date", "") not in result assert len(result) == 2 def test_track_to_mpd_format_with_position(self): result = translator.track_to_mpd_format(Track(), position=1) assert ("Pos", 1) not in result def test_track_to_mpd_format_with_tlid(self): result = translator.track_to_mpd_format(TlTrack(1, Track())) assert ("Id", 1) not in result def test_track_to_mpd_format_with_position_and_tlid(self): result = translator.track_to_mpd_format( TlTrack(2, Track(uri="a uri")), position=1 ) assert ("Pos", 1) in result assert ("Id", 2) in result def test_track_to_mpd_format_for_nonempty_track(self): result = translator.track_to_mpd_format( TlTrack(122, self.track), position=9 ) assert ("file", "à uri") in result assert ("Time", 137) in result assert ("Artist", "an artist") in result assert ("Title", "a nàme") in result assert ("Album", "an album") in result assert ("AlbumArtist", "an other artist") in result assert ("Composer", "a composer") in result assert ("Performer", "a performer") in result assert ("Genre", "a genre") in result assert ("Track", "7/13") in result assert ("Date", "1977-01-01") in result assert ("Disc", 1) in result assert ("Pos", 9) in result assert ("Id", 122) in result assert ("X-AlbumUri", "urischeme:àlbum:12345") in result assert ("Comment", "a comment") not in result assert len(result) == 15 def test_track_to_mpd_format_with_last_modified(self): track = self.track.replace(last_modified=995303899000) result = translator.track_to_mpd_format(track) assert ("Last-Modified", "2001-07-16T17:18:19Z") in result def test_track_to_mpd_format_with_last_modified_of_zero(self): track = self.track.replace(last_modified=0) result = translator.track_to_mpd_format(track) keys = [k for k, v in result] assert "Last-Modified" not in keys def test_track_to_mpd_format_musicbrainz_trackid(self): track = self.track.replace(musicbrainz_id="foo") result = translator.track_to_mpd_format(track) assert ("MUSICBRAINZ_TRACKID", "foo") in result def test_track_to_mpd_format_musicbrainz_albumid(self): album = self.track.album.replace(musicbrainz_id="foo") track = self.track.replace(album=album) result = translator.track_to_mpd_format(track) assert ("MUSICBRAINZ_ALBUMID", "foo") in result def test_track_to_mpd_format_musicbrainz_albumartistid(self): artist = list(self.track.artists)[0].replace(musicbrainz_id="foo") album = self.track.album.replace(artists=[artist]) track = self.track.replace(album=album) result = translator.track_to_mpd_format(track) assert ("MUSICBRAINZ_ALBUMARTISTID", "foo") in result def test_track_to_mpd_format_musicbrainz_artistid(self): artist = list(self.track.artists)[0].replace(musicbrainz_id="foo") track = self.track.replace(artists=[artist]) result = translator.track_to_mpd_format(track) assert ("MUSICBRAINZ_ARTISTID", "foo") in result def test_concat_multi_values(self): artists = [Artist(name="ABBA"), Artist(name="Beatles")] translated = translator.concat_multi_values(artists, "name") assert translated == "ABBA;Beatles" def test_concat_multi_values_artist_with_no_name(self): artists = [Artist(name=None)] translated = translator.concat_multi_values(artists, "name") assert translated == "" def test_concat_multi_values_artist_with_no_musicbrainz_id(self): artists = [Artist(name="Jah Wobble")] translated = translator.concat_multi_values(artists, "musicbrainz_id") assert translated == "" def test_track_to_mpd_format_with_stream_title(self): result = translator.track_to_mpd_format(self.track, stream_title="foo") assert ("Name", "a nàme") in result assert ("Title", "foo") in result def test_track_to_mpd_format_with_empty_stream_title(self): result = translator.track_to_mpd_format(self.track, stream_title="") assert ("Name", "a nàme") in result assert ("Title", "") not in result def test_track_to_mpd_format_with_stream_and_no_track_name(self): track = self.track.replace(name=None) result = translator.track_to_mpd_format(track, stream_title="foo") assert ("Name", "") not in result assert ("Title", "foo") in result
def test_track_to_mpd_format_with_position_and_cpid(self): result = translator.track_to_mpd_format(Track(), position=1, cpid=2) self.assert_(('Pos', 1) in result) self.assert_(('Id', 2) in result)
def build_track(self): if self.albumartist: self.album[b'artists'] = [Artist(**self.albumartist)] self.track[b'album'] = Album(**self.album) self.track[b'artists'] = [Artist(**self.artist)] return Track(**self.track)
def test_filter_by_criteria_that_is_not_present_in_all_elements(self): track1 = Track() track2 = Track(uri='b') track3 = Track() self.controller.add([track1, track2, track3]) self.assertEqual(track2, self.controller.filter(uri=['b'])[0].track)
def parse_m3u(file_path, media_dir): r""" Convert M3U file list to list of tracks Example M3U data:: # This is a comment Alternative\Band - Song.mp3 Classical\Other Band - New Song.mp3 Stuff.mp3 D:\More Music\Foo.mp3 http://www.example.com:8000/Listen.pls http://www.example.com/~user/Mine.mp3 Example extended M3U data:: #EXTM3U #EXTINF:123, Sample artist - Sample title Sample.mp3 #EXTINF:321,Example Artist - Example title Greatest Hits\Example.ogg #EXTINF:-1,Radio XMP http://mp3stream.example.com:8000/ - Relative paths of songs should be with respect to location of M3U. - Paths are normally platform specific. - Lines starting with # are ignored, except for extended M3U directives. - Track.name and Track.length are set from extended M3U directives. - m3u files are latin-1. """ # TODO: uris as bytes tracks = [] try: with open(file_path) as m3u: contents = m3u.readlines() except IOError as error: logger.warning('Couldn\'t open m3u: %s', locale_decode(error)) return tracks if not contents: return tracks extended = contents[0].decode('latin1').startswith('#EXTM3U') track = Track() for line in contents: line = line.strip().decode('latin1') if line.startswith('#'): if extended and line.startswith('#EXTINF'): track = m3u_extinf_to_track(line) continue if urlparse.urlsplit(line).scheme: tracks.append(track.copy(uri=line)) elif os.path.normpath(line) == os.path.abspath(line): path = path_to_uri(line) tracks.append(track.copy(uri=path)) else: path = path_to_uri(os.path.join(media_dir, line)) tracks.append(track.copy(uri=path)) track = Track() return tracks
def test_index_returns_none_if_item_not_found(self): tl_track = TlTrack(0, Track()) self.assertEqual(self.controller.index(tl_track), None)
class TrackMpdFormatTest(unittest.TestCase): 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, artists=[Artist(name=u'an other artist')]), track_no=7, date=datetime.date(1977, 1, 1), length=137000, ) def setUp(self): settings.LOCAL_MUSIC_PATH = '/dir/subdir' mtime.set_fake_time(1234567) def tearDown(self): settings.runtime.clear() mtime.undo_fake() def test_track_to_mpd_format_for_empty_track(self): result = translator.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.assertEqual(len(result), 7) def test_track_to_mpd_format_with_position(self): result = translator.track_to_mpd_format(Track(), position=1) self.assert_(('Pos', 1) not in result) def test_track_to_mpd_format_with_cpid(self): result = translator.track_to_mpd_format(Track(), cpid=1) self.assert_(('Id', 1) not in result) def test_track_to_mpd_format_with_position_and_cpid(self): result = translator.track_to_mpd_format(Track(), position=1, cpid=2) self.assert_(('Pos', 1) in result) self.assert_(('Id', 2) in result) def test_track_to_mpd_format_for_nonempty_track(self): result = translator.track_to_mpd_format(self.track, position=9, cpid=122) 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_(('AlbumArtist', 'an other artist') in result) self.assert_(('Track', '7/13') in result) self.assert_(('Date', datetime.date(1977, 1, 1)) in result) self.assert_(('Pos', 9) in result) self.assert_(('Id', 122) in result) self.assertEqual(len(result), 10) def test_track_to_mpd_format_musicbrainz_trackid(self): track = self.track.copy(musicbrainz_id='foo') result = translator.track_to_mpd_format(track) self.assert_(('MUSICBRAINZ_TRACKID', 'foo') in result) def test_track_to_mpd_format_musicbrainz_albumid(self): album = self.track.album.copy(musicbrainz_id='foo') track = self.track.copy(album=album) result = translator.track_to_mpd_format(track) self.assert_(('MUSICBRAINZ_ALBUMID', 'foo') in result) def test_track_to_mpd_format_musicbrainz_albumid(self): artist = list(self.track.artists)[0].copy(musicbrainz_id='foo') album = self.track.album.copy(artists=[artist]) track = self.track.copy(album=album) result = translator.track_to_mpd_format(track) self.assert_(('MUSICBRAINZ_ALBUMARTISTID', 'foo') in result) def test_track_to_mpd_format_musicbrainz_artistid(self): artist = list(self.track.artists)[0].copy(musicbrainz_id='foo') track = self.track.copy(artists=[artist]) result = translator.track_to_mpd_format(track) self.assert_(('MUSICBRAINZ_ARTISTID', 'foo') in result) def test_artists_to_mpd_format(self): artists = [Artist(name=u'ABBA'), Artist(name=u'Beatles')] translated = translator.artists_to_mpd_format(artists) self.assertEqual(translated, u'ABBA, Beatles') def test_artists_to_mpd_format_artist_with_no_name(self): artists = [Artist(name=None)] translated = translator.artists_to_mpd_format(artists) self.assertEqual(translated, u'')
def test_filter_by_uri_returns_single_match(self): track = Track(uri='a') self.controller.add([Track(uri='z'), track, Track(uri='y')]) self.assertEqual(track, self.controller.filter(uri=['a'])[0].track)
def test_tag_cache_has_header(self): track = Track(uri='file:///dir/subdir/song.mp3') result = translator.tracks_to_tag_cache_format([track]) result = self.consume_headers(result)
def test_filter_by_uri_returns_nothing_if_no_match(self): self.controller.playlist = Playlist( tracks=[Track(uri=['z']), Track(uri=['y'])]) self.assertEqual([], self.controller.filter(uri=['a']))
def test_single_file_in_sub_subdir(self): tracks = [Track(uri='file:///root/dir1/dir2/file1.mp3')] tree = translator.tracks_to_directory_tree(tracks) expected = ({'dir1': ({'dir1/dir2': ({}, tracks)}, [])}, []) self.assertEqual(tree, expected)
def _artist_as_track(artist): return Track(uri=artist.uri, name='Artist: ' + artist.name, artists=[artist])
def test_track_to_mpd_format_with_position(self): result = translator.track_to_mpd_format(Track(), position=1) self.assert_(('Pos', 1) not in result)
def test_set_rate_to_zero_pauses_playback(self): self.core.tracklist.add([Track(uri='dummy:a'), Track(uri='dummy:b')]) self.core.playback.play() self.assertEqual(self.core.playback.state.get(), PLAYING) self.mpris.Set(objects.PLAYER_IFACE, 'Rate', 0) self.assertEqual(self.core.playback.state.get(), PAUSED)
def test_open_uri_adds_uri_to_tracklist(self): self.mpris.get_CanPlay = lambda *_: True self.backend.library.dummy_library = [Track(uri='dummy:/test/uri')] self.mpris.OpenUri('dummy:/test/uri') self.assertEqual(self.core.tracklist.tracks.get()[0].uri, 'dummy:/test/uri')