def list_fols(uri, user_key): # followers or following uri = strip_uri(uri) refs = refs_cache.get(uri) if refs is not None: return refs json = uri_json(uri) fols = json['data'] refs = [] for fol in fols: name = fol['username'] key = fol['key'] fol_uri = make_special_uri(key, uri_user) ref = Ref.directory(name=enc(name), uri=fol_uri) refs.append(ref) more = get_next_page_uri(json) if more is not None: if 'following' in uri: name_for_more = make_more_name(user_key, u'follows') uri_for_more = uri_following else: name_for_more = make_more_name(user_key, u'followers') uri_for_more = uri_followers more_param = more.split('/')[-1] more_uri = make_special_uri(user_key, uri_for_more, more_param) ref = Ref.directory(name=name_for_more, uri=make_uri(more_uri)) refs.append(ref) refs_cache.add(uri, refs) return refs
def __init__(self, *args, **kwargs): super(GMusicLibraryProvider, self).__init__(*args, **kwargs) # tracks, albums, and artists here refer to what is explicitly # in our library. self.tracks = {} self.albums = {} self.artists = {} # aa_* caches are *only* used for temporary objects. Library # objects will never make it here. self.aa_artists = LRUCache(1024) self.aa_tracks = LRUCache(1024) self.aa_albums = LRUCache(1024) self._radio_stations_in_browse = ( self.backend.config['gmusic']['radio_stations_in_browse']) self._radio_stations_count = ( self.backend.config['gmusic']['radio_stations_count']) self._radio_tracks_count = ( self.backend.config['gmusic']['radio_tracks_count']) self._top_tracks_count = ( self.backend.config['gmusic']['top_tracks_count']) # Setup the root of library browsing. self._root = [ Ref.directory(uri='gmusic:album', name='Albums'), Ref.directory(uri='gmusic:artist', name='Artists'), Ref.directory(uri='gmusic:track', name='Tracks') ] if self._radio_stations_in_browse: self._root.append(Ref.directory(uri='gmusic:radio', name='Radios'))
def setUp(self): # noqa: N802 dummy1_root = Ref.directory(uri='dummy1:directory', name='dummy1') self.backend1 = mock.Mock() self.backend1.uri_schemes.get.return_value = ['dummy1'] self.backend1.actor_ref.actor_class.__name__ = 'DummyBackend1' self.library1 = mock.Mock(spec=backend.LibraryProvider) self.library1.get_images.return_value.get.return_value = {} self.library1.root_directory.get.return_value = dummy1_root self.backend1.library = self.library1 self.backend1.has_playlists.return_value.get.return_value = False dummy2_root = Ref.directory(uri='dummy2:directory', name='dummy2') self.backend2 = mock.Mock() self.backend2.uri_schemes.get.return_value = ['dummy2', 'du2'] self.backend2.actor_ref.actor_class.__name__ = 'DummyBackend2' self.library2 = mock.Mock(spec=backend.LibraryProvider) self.library2.get_images.return_value.get.return_value = {} self.library2.root_directory.get.return_value = dummy2_root self.backend2.library = self.library2 self.backend2.has_playlists.return_value.get.return_value = False # A backend without the optional library provider self.backend3 = mock.Mock() self.backend3.uri_schemes.get.return_value = ['dummy3'] self.backend3.actor_ref.actor_class.__name__ = 'DummyBackend3' self.backend3.has_library.return_value.get.return_value = False self.backend3.has_library_browse.return_value.get.return_value = False self.core = core.Core(mixer=None, backends=[ self.backend1, self.backend2, self.backend3])
def __init__(self, *args, **kwargs): super(PlexLibraryProvider, self).__init__(*args, **kwargs) self.plex = self.backend.plex self.library_id = self.backend.library_id self._root = [] self._root.append(Ref.directory(uri='plex:album', name='Albums')) self._root.append(Ref.directory(uri='plex:artist', name='Artists'))
def list_fols(uri, user_key): # followers or following refs = cache.refs.get(uri) if refs is not None: return refs json = get_json(uri) fols = json['data'] refs = [] for fol in fols: name = fol['username'] key = fol['key'] fol_uri = make_encoded_uri(key, uri_user) cache.add_thumbnail(fol, fol_uri) ref = Ref.directory(name=name, uri=fol_uri) refs.append(ref) more = next_page_uri(json) if more is not None: if 'following' in uri: name_for_more = make_more_name(user_key, u'follows') uri_for_more = uri_following else: name_for_more = make_more_name(user_key, u'followers') uri_for_more = uri_followers more_param = more.split('/')[-1] more_uri = make_encoded_uri(user_key, uri_for_more, more_param) ref = Ref.directory(name=name_for_more, uri=make_uri(more_uri)) refs.append(ref) cache.refs.add(uri, refs) return refs
def test_browse_root(backend, servers): with mock.patch.object(backend, 'client') as m: m.servers.return_value = Future.fromvalue(servers) assert backend.library.browse(backend.library.root_directory.uri) == [ Ref.directory(name='Media Server #1', uri='dleyna://media1'), Ref.directory(name='Media Server #2', uri='dleyna://media2'), ]
def _browse_directory(self, uri, order=('type', 'name')): query = dict(uritools.urisplit(uri).getquerylist()) type = query.pop('type', None) role = query.pop('role', None) # TODO: handle these in schema (generically)? if type == 'date': format = query.get('format', '%Y-%m-%d') return map(_dateref, schema.dates(self._connect(), format=format)) if type == 'genre': return map(_genreref, schema.list_distinct(self._connect(), 'genre')) # noqa # Fix #38: keep sort order of album tracks; this also applies # to composers and performers if type == Ref.TRACK and 'album' in query: order = ('disc_no', 'track_no', 'name') roles = role or ('artist', 'albumartist') # FIXME: re-think 'roles'... refs = [] for ref in schema.browse(self._connect(), type, order, role=roles, **query): # noqa if ref.type == Ref.TRACK or (not query and not role): refs.append(ref) elif ref.type == Ref.ALBUM: refs.append(Ref.directory(uri=uritools.uricompose( 'local', None, 'directory', dict(query, type=Ref.TRACK, album=ref.uri) # noqa ), name=ref.name)) elif ref.type == Ref.ARTIST: refs.append(Ref.directory(uri=uritools.uricompose( 'local', None, 'directory', dict(query, **{role: ref.uri}) ), name=ref.name)) else: logger.warn('Unexpected SQLite browse result: %r', ref) return refs
def __init__(self, *args, **kwargs): super(GMusicLibraryProvider, self).__init__(*args, **kwargs) self.tracks = {} self.albums = {} self.artists = {} self.aa_artists = {} self.aa_tracks = LruCache() self.aa_albums = LruCache() self.all_access = False self._radio_stations_in_browse = ( self.backend.config['gmusic']['radio_stations_in_browse']) self._radio_stations_count = ( self.backend.config['gmusic']['radio_stations_count']) self._radio_tracks_count = ( self.backend.config['gmusic']['radio_tracks_count']) self._root = [] self._root.append(Ref.directory(uri='gmusic:album', name='Albums')) self._root.append(Ref.directory(uri='gmusic:artist', name='Artists')) # browsing all tracks results in connection timeouts # self._root.append(Ref.directory(uri='gmusic:track', name='Tracks')) if self._radio_stations_in_browse: self._root.append(Ref.directory(uri='gmusic:radio', name='Radios')) # show root only if there is something to browse if len(self._root) > 0: GMusicLibraryProvider.root_directory = Ref.directory( uri='gmusic:directory', name='Google Music')
def setUp(self): # noqa: N802 dummy1_root = Ref.directory(uri='dummy1:directory', name='dummy1') self.backend1 = mock.Mock() self.backend1.uri_schemes.get.return_value = ['dummy1'] self.library1 = mock.Mock(spec=backend.LibraryProvider) self.library1.get_images().get.return_value = {} self.library1.get_images.reset_mock() self.library1.root_directory.get.return_value = dummy1_root self.backend1.library = self.library1 dummy2_root = Ref.directory(uri='dummy2:directory', name='dummy2') self.backend2 = mock.Mock() self.backend2.uri_schemes.get.return_value = ['dummy2', 'du2'] self.library2 = mock.Mock(spec=backend.LibraryProvider) self.library2.get_images().get.return_value = {} self.library2.get_images.reset_mock() self.library2.root_directory.get.return_value = dummy2_root self.backend2.library = self.library2 # A backend without the optional library provider self.backend3 = mock.Mock() self.backend3.uri_schemes.get.return_value = ['dummy3'] self.backend3.has_library().get.return_value = False self.backend3.has_library_browse().get.return_value = False self.core = core.Core( mixer=None, backends=[self.backend1, self.backend2, self.backend3])
def country_to_ref(country_code): uri = unparse_uri('country', country_code.lower()) try: country = pycountry.countries.get(alpha2=country_code.upper()) return Ref.directory(uri=uri, name=country.name) except KeyError: return Ref.directory(uri=uri, name=country_code.upper())
def test_browse_root(backend, servers): with mock.patch.object(backend, "client") as m: m.servers.return_value = Future.fromvalue(servers) assert backend.library.browse(backend.library.root_directory.uri) == [ Ref.directory(name="Media Server #1", uri="dleyna://media1"), Ref.directory(name="Media Server #2", uri="dleyna://media2"), ]
def setUp(self): # noqa: N802 dummy1_root = Ref.directory(uri='dummy1:directory', name='dummy1') self.backend1 = mock.Mock() self.backend1.uri_schemes.get.return_value = ['dummy1'] self.library1 = mock.Mock(spec=backend.LibraryProvider) self.library1.get_images().get.return_value = {} self.library1.get_images.reset_mock() self.library1.root_directory.get.return_value = dummy1_root self.backend1.library = self.library1 dummy2_root = Ref.directory(uri='dummy2:directory', name='dummy2') self.backend2 = mock.Mock() self.backend2.uri_schemes.get.return_value = ['dummy2', 'du2'] self.library2 = mock.Mock(spec=backend.LibraryProvider) self.library2.get_images().get.return_value = {} self.library2.get_images.reset_mock() self.library2.root_directory.get.return_value = dummy2_root self.backend2.library = self.library2 # A backend without the optional library provider self.backend3 = mock.Mock() self.backend3.uri_schemes.get.return_value = ['dummy3'] self.backend3.has_library().get.return_value = False self.backend3.has_library_browse().get.return_value = False self.core = core.Core(mixer=None, backends=[ self.backend1, self.backend2, self.backend3])
def root_collections(): from mopidy.models import Ref return [ Ref.directory(name="Audio Archive", uri="internetarchive:audio"), Ref.directory(name="Live Music Archive", uri="internetarchive:etree"), ]
def setUp(self): dummy1_root = Ref.directory(uri='dummy1:directory', name='dummy1') self.backend1 = mock.Mock() self.backend1.uri_schemes.get.return_value = ['dummy1'] self.backend1.actor_ref.actor_class.__name__ = 'dummy1' self.library1 = mock.Mock(spec=backend.LibraryProvider) self.library1.root_directory.get.return_value = dummy1_root self.backend1.library = self.library1 dummy2_root = Ref.directory(uri='dummy2:directory', name='dummy2') self.backend2 = mock.Mock() self.backend2.uri_schemes.get.return_value = ['dummy2'] self.backend2.actor_ref.actor_class.__name__ = 'dummy2' self.library2 = mock.Mock(spec=backend.LibraryProvider) self.library2.root_directory.get.return_value = dummy2_root self.backend2.library = self.library2 # A backend without the optional library provider self.backend3 = mock.Mock() self.backend3.uri_schemes.get.return_value = ['dummy3'] self.backend3.actor_ref.actor_class.__name__ = 'dummy3' self.backend3.has_library().get.return_value = False self.backend3.has_library_browse().get.return_value = False self.core = core.Core(audio=None, backends=[ self.backend1, self.backend2, self.backend3])
def browse(self, uri): # we have four levels: # root dir -> # artists -> # albums -> # tracks contents = [] if translator.is_root_dir(uri): contents = [ Ref.directory(uri='funkwhale:directory:artist:%s' % translator.get_id(a.uri), name=a.name) for a in self.client.get_artists_refs() ] elif translator.is_artist_dir(uri): contents = [ Ref.directory(uri='funkwhale:directory:album:%s' % translator.get_id(a.uri), name=a.name) for a in self.client.get_albums_refs(uri=translator.get_id(uri)) ] elif translator.is_album_dir(uri): contents = self.client.get_album_tracks_refs( uri=translator.get_id(uri)) return contents
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # tracks, albums, and artists here refer to what is explicitly # in our library. self.tracks = {} self.albums = {} self.artists = {} # aa_* caches are *only* used for temporary objects. Library # objects will never make it here. self.aa_artists = LRUCache(1024) self.aa_tracks = LRUCache(1024) self.aa_albums = LRUCache(1024) self._radio_stations_in_browse = self.backend.config["gmusic"][ "radio_stations_in_browse"] self._radio_stations_count = self.backend.config["gmusic"][ "radio_stations_count"] self._radio_tracks_count = self.backend.config["gmusic"][ "radio_tracks_count"] self._top_tracks_count = self.backend.config["gmusic"][ "top_tracks_count"] # Setup the root of library browsing. self._root = [ Ref.directory(uri="gmusic:album", name="Albums"), Ref.directory(uri="gmusic:artist", name="Artists"), Ref.directory(uri="gmusic:track", name="Tracks"), ] if self._radio_stations_in_browse: self._root.append(Ref.directory(uri="gmusic:radio", name="Radios"))
def setUp(self): # noqa: N802 dummy1_root = Ref.directory(uri="dummy1:directory", name="dummy1") self.backend1 = mock.Mock() self.backend1.uri_schemes.get.return_value = ["dummy1"] self.backend1.actor_ref.actor_class.__name__ = "DummyBackend1" self.library1 = mock.Mock(spec=backend.LibraryProvider) self.library1.get_images.return_value.get.return_value = {} self.library1.root_directory.get.return_value = dummy1_root self.backend1.library = self.library1 self.backend1.has_playlists.return_value.get.return_value = False dummy2_root = Ref.directory(uri="dummy2:directory", name="dummy2") self.backend2 = mock.Mock() self.backend2.uri_schemes.get.return_value = ["dummy2", "du2"] self.backend2.actor_ref.actor_class.__name__ = "DummyBackend2" self.library2 = mock.Mock(spec=backend.LibraryProvider) self.library2.get_images.return_value.get.return_value = {} self.library2.root_directory.get.return_value = dummy2_root self.backend2.library = self.library2 self.backend2.has_playlists.return_value.get.return_value = False # A backend without the optional library provider self.backend3 = mock.Mock() self.backend3.uri_schemes.get.return_value = ["dummy3"] self.backend3.actor_ref.actor_class.__name__ = "DummyBackend3" self.backend3.has_library.return_value.get.return_value = False self.backend3.has_library_browse.return_value.get.return_value = False self.core = core.Core( mixer=None, backends=[self.backend1, self.backend2, self.backend3])
class OE1LibraryProvider(backend.LibraryProvider): root_directory = Ref.directory(uri=OE1Uris.ROOT, name='OE1') root = [ Ref.track(uri=OE1Uris.LIVE, name='Live'), Ref.track(uri=OE1Uris.CAMPUS, name='Campus'), Ref.directory(uri=OE1Uris.ARCHIVE, name='7 Tage') ] def __init__(self, backend, client=OE1Client()): super(OE1LibraryProvider, self).__init__(backend) self.client = client def browse(self, uri): try: library_uri = OE1LibraryUri.parse(uri) except InvalidOE1Uri, e: logger.error(e) return [] if library_uri.uri_type == OE1UriType.ROOT: return self.root if library_uri.uri_type == OE1UriType.ARCHIVE: return self._browse_archive() if library_uri.uri_type == OE1UriType.ARCHIVE_DAY: return self._browse_day(library_uri.day_id) logger.warn('OE1LibraryProvider.browse called with uri ' 'that does not support browsing: \'%s\'.' % uri) return []
def test_browse_root(config, library, genres): responses.add(responses.GET, re.compile(r'.*/genres\b.*'), json=genres) assert library.browse('podcast+itunes:') == [ Ref.directory(name='Top Podcasts', uri='podcast+itunes:charts:26'), Ref.directory(name='Bar', uri='podcast+itunes:genre:1001'), Ref.directory(name='Foo', uri='podcast+itunes:charts:1000') ]
def test_lsinfo_duplicate(self): self.backend.library.dummy_browse_result = { 'dummy:/': [Ref.directory(uri='dummy:/a1', name='a'), Ref.directory(uri='dummy:/a2', name='a')]} self.sendRequest('lsinfo "/dummy"') self.assertInResponse('directory: dummy/a') self.assertInResponse('directory: dummy/a [2]')
def test_lsinfo_duplicate(self): self.backend.library.dummy_browse_result = { "dummy:/": [Ref.directory(uri="dummy:/a1", name="a"), Ref.directory(uri="dummy:/a2", name="a")] } self.sendRequest('lsinfo "/dummy"') self.assertInResponse("directory: dummy/a") self.assertInResponse("directory: dummy/a [2]")
def test_browse_subgenre(config, library, genres, charts, lookup): responses.add(responses.GET, re.compile(r'.*/genres\b.*'), json=genres) responses.add(responses.GET, re.compile(r'.*/charts\b.*'), json=charts) responses.add(responses.GET, re.compile(r'.*/lookup\b.*'), json=lookup) assert library.browse('podcast+itunes:genre:1001') == [ Ref.directory(name='Top Bar', uri='podcast+itunes:charts:1001'), Ref.directory(name='Baz', uri='podcast+itunes:charts:1002') ]
def test_lookup_foo(self): expected = [ Ref.directory(uri='local:directory:foo/bar', name='bar'), Ref.directory(uri='local:directory:foo/baz', name='baz'), Ref.track(uri=self.uris[3], name='song4') ] result = self.cache.lookup('local:directory:foo') self.assertEqual(expected, result)
def list_tag(tag): latest = Ref.directory(name=u'latest', uri=make_encoded_uri('/discover{}'.format(tag), uri_latest)) popular = Ref.directory(name=u'popular', uri=make_encoded_uri('/discover{}'.format(tag), uri_popular)) return [latest, popular]
def test_browse_root(tmp_path, caplog): provider = KitchenLibraryProvider(backend={}, config=make_config(tmp_path)) result = provider.browse("kitchen:root") assert caplog.text == "" assert result == [ Ref.directory(uri="kitchen:albums", name="Albums"), Ref.directory(uri="kitchen:stations", name="Stations"), ]
def test_browse_root_returns_dir_ref_for_each_lib_with_root_dir_name(self): result = self.core.library.browse(None) assert result == [ Ref.directory(uri="dummy1:directory", name="dummy1"), Ref.directory(uri="dummy2:directory", name="dummy2"), ] assert not self.library1.browse.called assert not self.library2.browse.called assert not self.backend3.library.browse.called
def test_browse_root_returns_dir_ref_for_each_lib_with_root_dir_name(self): result = self.core.library.browse(None) self.assertEqual(result, [ Ref.directory(uri='dummy1:directory', name='dummy1'), Ref.directory(uri='dummy2:directory', name='dummy2'), ]) self.assertFalse(self.library1.browse.called) self.assertFalse(self.library2.browse.called) self.assertFalse(self.backend3.library.browse.called)
def test_browse_dir_returns_subdirs_and_tracks(self): self.library1.browse.return_value.get.return_value = [ Ref.directory(uri="dummy1:directory:/foo/bar", name="Bar"), Ref.track(uri="dummy1:track:/foo/baz.mp3", name="Baz"), ] result = self.core.library.browse("dummy1:directory:/foo") assert result == [ Ref.directory(uri="dummy1:directory:/foo/bar", name="Bar"), Ref.track(uri="dummy1:track:/foo/baz.mp3", name="Baz"), ]
def test_browse_dir_returns_subdirs_and_tracks(self): self.library1.browse.return_value.get.return_value = [ Ref.directory(uri='dummy1:directory:/foo/bar', name='Bar'), Ref.track(uri='dummy1:track:/foo/baz.mp3', name='Baz'), ] result = self.core.library.browse('dummy1:directory:/foo') self.assertEqual(result, [ Ref.directory(uri='dummy1:directory:/foo/bar', name='Bar'), Ref.track(uri='dummy1:track:/foo/baz.mp3', name='Baz'), ])
def test_lsinfo_duplicate(self): self.backend.library.dummy_browse_result = { "dummy:/": [ Ref.directory(uri="dummy:/a1", name="a"), Ref.directory(uri="dummy:/a2", name="a"), ] } self.send_request('lsinfo "/dummy"') self.assertInResponse("directory: dummy/a") self.assertInResponse("directory: dummy/a [2]")
def _browse_directory(self, uri, order=("type", "name COLLATE NOCASE")): query = dict(uritools.urisplit(uri).getquerylist()) type = query.pop("type", None) role = query.pop("role", None) # TODO: handle these in schema (generically)? if type == "date": format = query.get("format", "%Y-%m-%d") return list( map(date_ref, schema.dates(self._connect(), format=format))) if type == "genre": return list( map(genre_ref, schema.list_distinct(self._connect(), "genre"))) # Fix #38: keep sort order of album tracks; this also applies # to composers and performers if type == Ref.TRACK and "album" in query: order = ("disc_no", "track_no", "name") if type == Ref.ARTIST and self._config["use_artist_sortname"]: order = ("coalesce(sortname, name) COLLATE NOCASE", ) roles = role or ("artist", "albumartist") # FIXME: re-think 'roles'... refs = [] for ref in schema.browse(self._connect(), type, order, role=roles, **query): # noqa if ref.type == Ref.TRACK or (not query and not role): refs.append(ref) elif ref.type == Ref.ALBUM: refs.append( Ref.directory( uri=uritools.uricompose( "local", None, "directory", dict(query, type=Ref.TRACK, album=ref.uri), # noqa ), name=ref.name, )) elif ref.type == Ref.ARTIST: refs.append( Ref.directory( uri=uritools.uricompose("local", None, "directory", dict(query, **{role: ref.uri})), name=ref.name, )) else: logger.warning("Unexpected SQLite browse result: %r", ref) return refs
def _browse_artist(self, uri): refs = [] for album in self._get_artist_albums(uri): refs.append(album_to_ref(album)) refs.sort(key=lambda ref: ref.name) if len(refs) > 0: refs.insert(0, Ref.directory(uri=uri + ':all', name='All Tracks')) is_all_access = uri.startswith('gmusic:artist:A') if is_all_access: refs.insert(1, Ref.directory(uri=uri + ':top', name='Top Tracks')) return refs else: # Show all tracks if no album is available return self._browse_artist_all_tracks(uri)
def _track_to_refs(track): track_path = translator.local_track_uri_to_path(track.uri, b'/') track_path = track_path.decode(sys.getfilesystemencoding(), 'replace') parts = re.findall(r'([^/]+)', track_path) track_ref = Ref.track(uri=track.uri, name=parts.pop()) refs = [Ref.directory(uri='local:directory')] for i in range(len(parts)): directory = '/'.join(parts[:i+1]) uri = translator.path_to_local_directory_uri(directory) refs.append(Ref.directory(uri=unicode(uri), name=parts[i])) return refs + [track_ref]
def browse(self, uri): result = [] if not uri.startswith('yle:'): return result if uri == 'yle:root': categories = self.__yleapi.get_yle_category('root') for item in categories: result.append(Ref.directory(name=item['name'], uri=item['uri'])) result.append( Ref.directory(name='Live radio', uri='yle:category:live')) return result elif uri.startswith('yle:category:'): item_url = uri.split(':') id = item_url[2] result = [] if id == 'live': for station in LIVERADIO: result.append( Ref.track(name=LIVERADIO[station], uri='yle:liveradio:{0}'.format(station))) else: categories = self.__yleapi.get_yle_category(id) if categories: for item in categories: result.append( Ref.directory(name=item['name'], uri=item['uri'])) else: albums, tracks = self.__yleapi.get_yle_item(offset=0, category=id, limit=100) for i in albums: result.append( Ref.album(name=albums[i]['name'], uri=albums[i]['uri'])) return result elif uri.startswith('yle:series:'): item_url = uri.split(':') id = item_url[2] tracks = self.__yleapi.get_yle_series_info(id) result = [] for track in tracks: result.append(Ref.track(name=track['name'], uri=track['uri'])) return result return result
def test_browse_dir_returns_subdirs_and_tracks(self): self.library1.browse().get.return_value = [ Ref.directory(uri="dummy1:directory:/foo/bar", name="Bar"), Ref.track(uri="dummy1:track:/foo/baz.mp3", name="Baz"), ] self.library1.browse.reset_mock() result = self.core.library.browse("dummy1:directory:/foo") self.assertEqual( result, [ Ref.directory(uri="dummy1:directory:/foo/bar", name="Bar"), Ref.track(uri="dummy1:track:/foo/baz.mp3", name="Baz"), ], )
def genres_to_sub_genres_mopidy_directories(tunigo_genres, genre_key): sub_genres = [] for genre in tunigo_genres: if genre.key == genre_key: sub_genres.append(Ref.directory( uri='spotifytunigo:genres:{}:all'.format(genre_key), name='All')) sub_genres.append(Ref.directory(uri=genre.playlist.uri, name='Top tracks')) for sub_genre in genre.sub_genres: uri = 'spotifytunigo:genres:{}:{}'.format(genre_key, sub_genre.key) sub_genres.append(Ref.directory(uri=uri, name=sub_genre.name)) break return sub_genres
def __init__(self, *args, **kwargs): super(SpotifyTunigoLibraryProvider, self).__init__(*args, **kwargs) self._tunigo = tunigo.Tunigo( region=self.backend.config['spotify_tunigo']['region'], cache_time=self.backend.config['spotify_tunigo']['cache_time']) self._root = [Ref.directory(uri='spotifytunigo:featured', name='Featured Playlists'), Ref.directory(uri='spotifytunigo:toplists', name='Top Lists'), Ref.directory(uri='spotifytunigo:genres', name='Genres & Moods'), Ref.directory(uri='spotifytunigo:releases', name='New Releases')]
def _lastmodifiedref(option): timestamp = int(time.time()) - option[0] * 24*60*1000 return Ref.directory( uri=uritools.uricompose('local', None, 'directory', {'last_modified': timestamp}), name=option[1] )
def ref(obj, uri=uri): identifier = obj['identifier'] mediatype = obj['mediatype'] if mediatype == 'collection': return Ref.directory(name=name(obj), uri=uri(identifier)) else: return Ref.album(name=name(obj), uri=uri(identifier))
def test_lsinfo_for_dir_includes_subdirs(self): self.backend.library.dummy_browse_result = { 'dummy:/': [Ref.directory(uri='dummy:/foo', name='foo')]} self.sendRequest('lsinfo "/dummy"') self.assertInResponse('directory: dummy/foo') self.assertInResponse('OK')
def spotify_browse_process_results(results): logger.debug('Processing spotify browse result') if 'categories' in results: result_list = results['categories'] browse_uri = 'spotifyweb:browse:categories:' arr = [Ref.directory(uri=browse_uri + cat['id'], name=cat['name']) for cat in result_list['items']] elif 'playlists' in results: result_list = results['playlists'] arr = [Ref.playlist(uri=playlist['uri'], name=playlist['name']) for playlist in result_list['items']] elif 'albums' in results: result_list = results['albums'] arr = [Ref.album(uri=album['uri'], name=album['name']) for album in result_list['items']] else: result_list = None arr = [] cont = result_list is not None and result_list['next'] is not None logger.debug('Spotify browse result cont: %s' % cont) return arr, cont
def artist_to_ref(artist): """Convert a mopidy artist to a mopidy ref.""" if artist.name: name = artist.name else: name = 'Unknown artist' return Ref.directory(uri=artist.uri, name=name)
def test_listallinfo_without_uri(self): tracks = [ Track(uri="dummy:/a", name="a"), Track(uri="dummy:/foo/b", name="b"), ] self.backend.library.dummy_library = tracks self.backend.library.dummy_browse_result = { "dummy:/": [ Ref.track(uri="dummy:/a", name="a"), Ref.directory(uri="dummy:/foo", name="foo"), Ref.album(uri="dummy:/album", name="album"), Ref.artist(uri="dummy:/artist", name="artist"), Ref.playlist(uri="dummy:/pl", name="pl"), ], "dummy:/foo": [Ref.track(uri="dummy:/foo/b", name="b")], } self.send_request("listallinfo") self.assertInResponse("file: dummy:/a") self.assertInResponse("Title: a") self.assertInResponse("directory: dummy/foo") self.assertInResponse("directory: dummy/album") self.assertInResponse("directory: dummy/artist") self.assertInResponse("directory: dummy/pl") self.assertInResponse("file: dummy:/foo/b") self.assertInResponse("Title: b") self.assertInResponse("OK")
def test_listallinfo_without_uri(self): tracks = [ Track(uri='dummy:/a', name='a'), Track(uri='dummy:/foo/b', name='b') ] self.backend.library.dummy_library = tracks self.backend.library.dummy_browse_result = { 'dummy:/': [ Ref.track(uri='dummy:/a', name='a'), Ref.directory(uri='dummy:/foo', name='foo'), Ref.album(uri='dummy:/album', name='album'), Ref.artist(uri='dummy:/artist', name='artist'), Ref.playlist(uri='dummy:/pl', name='pl') ], 'dummy:/foo': [Ref.track(uri='dummy:/foo/b', name='b')] } self.send_request('listallinfo') self.assertInResponse('file: dummy:/a') self.assertInResponse('Title: a') self.assertInResponse('directory: /dummy/foo') self.assertInResponse('directory: /dummy/album') self.assertInResponse('directory: /dummy/artist') self.assertInResponse('directory: /dummy/pl') self.assertInResponse('file: dummy:/foo/b') self.assertInResponse('Title: b') self.assertInResponse('OK')
def browse(self, uri): logger.debug(u"Browse being called for %s" % uri) level = urisplit(uri).path query = self._sanitize_query(dict(urisplit(uri).getquerylist())) logger.debug("Got parsed to level: %s - query: %s" % (level, query)) result = [] if not level: logger.error("No level for uri %s" % uri) # import pdb; pdb.set_trace() if level == 'root': for row in self._browse_genre(): result.append(Ref.directory( uri=uricompose('beetslocal', None, 'genre', dict(genre=row[0])), name=row[0] if bool(row[0]) else u'No Genre')) elif level == "genre": # artist refs not browsable via mpd for row in self._browse_artist(query): result.append(Ref.directory( uri=uricompose('beetslocal', None, 'artist', dict(genre=query['genre'][0], artist=row[1])), name=row[0] if bool(row[0]) else u'No Artist')) elif level == "artist": for album in self._browse_album(query): result.append(Ref.album( uri=uricompose('beetslocal', None, 'album', dict(album=album.id)), name=album.album)) elif level == "album": for track in self._browse_track(query): result.append(Ref.track( uri="beetslocal:track:%s:%s" % ( track.id, uriencode(track.path, '/')), name=track.title)) else: logger.debug('Unknown URI: %s', uri) # logger.debug(result) return result
def test_lsinfo_for_dir_does_not_include_self(self): self.backend.library.dummy_browse_result = { 'dummy:/': [Ref.directory(uri='dummy:/foo', name='foo')], 'dummy:/foo': [Ref.track(uri='dummy:/a', name='a')]} self.sendRequest('lsinfo "/dummy"') self.assertNotInResponse('directory: dummy') self.assertInResponse('OK')
def test_lsinfo_for_dir_with_and_without_trailing_slash_is_the_same(self): self.backend.library.dummy_browse_result = { 'dummy:/': [Ref.track(uri='dummy:/a', name='a'), Ref.directory(uri='dummy:/foo', name='foo')]} response1 = self.sendRequest('lsinfo "dummy"') response2 = self.sendRequest('lsinfo "dummy/"') self.assertEqual(response1, response2)
def test_lsinfo_for_root_includes_dirs_for_each_lib_with_content(self): self.backend.library.dummy_browse_result = { 'dummy:/': [Ref.track(uri='dummy:/a', name='a'), Ref.directory(uri='dummy:/foo', name='foo')]} self.sendRequest('lsinfo "/"') self.assertInResponse('directory: dummy') self.assertInResponse('OK')
def get_albums_from_web_api(sp, uri): arr = [Ref.directory( uri='spotifyweb:sauce:artist-toptracks:%s' % get_artist_from_uri(uri), name='Top Tracks')] arr += get_from_sp(sp, get_albums_items, spotify_albums_results, uri) return arr
def _browse_mood_playlists(self, uri): mood = uri.split(':')[3] logger.debug(u'Getting mood %s tracks' % mood) playlists = [] for p in self.backend.session.get_mood_playlists(mood): playlists.append(Ref.directory(uri=u'wimpy:mood:playlist:tracks:' + p.id, name=p.name)) logger.debug(u'Got featured %s:%s' % (p.id, p.name)) return playlists