def __init__(self, *args, **kwargs): super(TidalLibraryProvider, self).__init__(*args, **kwargs) self.lru_album_tracks = LruCache(max_size=10) self.lru_artist_img = LruCache() self.lru_album_img = LruCache() self.track_cache = Cache() self.config = kwargs["backend"]._config if self.config["tidal"]["spotify_proxy"]: self.spotify_proxy = SpotifyProxy( str(self.config["tidal"]["spotify_client_id"]), str(self.config["tidal"]["spotify_client_secret"]))
def __init__(self, *args, **kwargs): super(TidalLibraryProvider, self).__init__(*args, **kwargs) self.lru_album_tracks = LruCache(max_size=10) self.lru_artist_img = LruCache() self.lru_album_img = LruCache()
class TidalLibraryProvider(backend.LibraryProvider): root_directory = models.Ref.directory(uri='tidal:directory', name='Tidal') def __init__(self, *args, **kwargs): super(TidalLibraryProvider, self).__init__(*args, **kwargs) self.lru_album_tracks = LruCache(max_size=10) self.lru_artist_img = LruCache() self.lru_album_img = LruCache() def get_distinct(self, field, query=None): logger.debug("Browsing distinct %s with query %r", field, query) session = self.backend._session if not query: # library root if field == "artist" or field == "albumartist": return [apply_watermark(a.name) for a in session.user.favorites.artists()] elif field == "album": return [apply_watermark(a.name) for a in session.user.favorites.albums()] elif field == "track": return [apply_watermark(t.name) for t in session.user.favorites.tracks()] else: if field == "artist": return [apply_watermark(a.name) for a in session.user.favorites.artists()] elif field == "album" or field == "albumartist": artists, _, _ = tidal_search(session, query=query, exact=True) if len(artists) > 0: artist = artists[0] artist_id = artist.uri.split(":")[2] return [apply_watermark(a.name) for a in session.get_artist_albums(artist_id)] elif field == "track": return [apply_watermark(t.name) for t in session.user.favorites.tracks()] pass return [] def browse(self, uri): logger.info("Browsing uri %s", uri) if not uri or not uri.startswith("tidal:"): return [] session = self.backend._session # summaries if uri == self.root_directory.uri: return ref_models_mappers.create_root() elif uri == "tidal:my_artists": return ref_models_mappers.create_artists( session.user.favorites.artists()) elif uri == "tidal:my_albums": return ref_models_mappers.create_albums( session.user.favorites.albums()) elif uri == "tidal:my_playlists": return ref_models_mappers.create_playlists( session.user.favorites.playlists()) # details parts = uri.split(':') nr_of_parts = len(parts) if nr_of_parts == 3 and parts[1] == "album": return ref_models_mappers.create_tracks( session.get_album_tracks(parts[2])) if nr_of_parts == 3 and parts[1] == "artist": top_10_tracks = session.get_artist_top_tracks(parts[2])[:10] albums = ref_models_mappers.create_albums( session.get_artist_albums(parts[2])) return albums + ref_models_mappers.create_tracks(top_10_tracks) logger.debug('Unknown uri for browse request: %s', uri) return [] def search(self, query=None, uris=None, exact=False): try: artists, albums, tracks = \ tidal_search(self.backend._session, query=query, exact=exact) return SearchResult(artists=artists, albums=albums, tracks=tracks) except Exception as ex: logger.info("EX") logger.info("%r", ex) def get_images(self, uris): logger.debug("Searching Tidal for images for %r" % uris) session = self.backend._session images = {} for uri in uris: uri_images = None if uri.startswith('tidal:'): parts = uri.split(':') if parts[1] == 'artist': artist_id = parts[2] img_uri = self.lru_artist_img.hit(artist_id) if img_uri is None: artist = session.get_artist(artist_id) img_uri = artist.image self.lru_artist_img[artist.id] = img_uri uri_images = [Image(uri=img_uri, width=512, height=512)] elif parts[1] == 'album': album_id = parts[2] img_uri = self.lru_album_img.hit(album_id) if img_uri is None: album = session.get_album(album_id) img_uri = album.image self.lru_album_img[album_id] = img_uri uri_images = [Image(uri=img_uri, width=512, height=512)] elif parts[1] == 'track': album_id = parts[3] img_uri = self.lru_album_img.hit(album_id) if img_uri is None: album = session.get_album(album_id) img_uri = album.image self.lru_album_img[album_id] = img_uri uri_images = [Image(uri=img_uri, width=512, height=512)] pass images[uri] = uri_images or () return images def lookup(self, uris=None): logger.info("Lookup uris %r", uris) session = self.backend._session if not hasattr(uris, '__iter__'): uris = [uris] tracks = [] for uri in uris: parts = uri.split(':') if uri.startswith('tidal:track:'): tracks += self._lookup_track(session, parts) elif uri.startswith('tidal:album'): tracks += self._lookup_album(session, parts) elif uri.startswith('tidal:artist'): tracks += self._lookup_artist(session, parts) logger.info("Returning %d tracks", len(tracks)) return tracks def _lookup_track(self, session, parts): album_id = parts[3] tracks = self.lru_album_tracks.hit(album_id) if tracks is None: tracks = session.get_album_tracks(album_id) self.lru_album_tracks[album_id] = tracks track = [t for t in tracks if t.id == int(parts[4])][0] artist = full_models_mappers.create_mopidy_artist(track.artist) album = full_models_mappers.create_mopidy_album(track.album, artist) return [full_models_mappers.create_mopidy_track(artist, album, track)] def _lookup_album(self, session, parts): album_id = parts[2] tracks = session.get_album_tracks(album_id) return full_models_mappers.create_mopidy_tracks(tracks) def _lookup_artist(self, session, parts): artist_id = parts[2] artist_tracks = session.get_artist_top_tracks(artist_id) return full_models_mappers.create_mopidy_tracks(artist_tracks)
class TidalLibraryProvider(backend.LibraryProvider): root_directory = models.Ref.directory(uri='tidal:directory', name='Tidal') def __init__(self, *args, **kwargs): super(TidalLibraryProvider, self).__init__(*args, **kwargs) self.lru_album_tracks = LruCache(max_size=10) self.lru_artist_img = LruCache() self.lru_album_img = LruCache() self.track_cache = Cache() self.config = kwargs["backend"]._config if self.config["tidal"]["spotify_proxy"]: self.spotify_proxy = SpotifyProxy( str(self.config["tidal"]["spotify_client_id"]), str(self.config["tidal"]["spotify_client_secret"])) def get_distinct(self, field, query=None): logger.debug("Browsing distinct %s with query %r", field, query) session = self.backend._session if not query: # library root if field == "artist" or field == "albumartist": return [ apply_watermark(a.name) for a in session.user.favorites.artists() ] elif field == "album": return [ apply_watermark(a.name) for a in session.user.favorites.albums() ] elif field == "track": return [ apply_watermark(t.name) for t in session.user.favorites.tracks() ] else: if field == "artist": return [ apply_watermark(a.name) for a in session.user.favorites.artists() ] elif field == "album" or field == "albumartist": artists, _, _ = tidal_search(session, query=query, exact=True) if len(artists) > 0: artist = artists[0] artist_id = artist.uri.split(":")[2] return [ apply_watermark(a.name) for a in session.get_artist_albums(artist_id) ] elif field == "track": return [ apply_watermark(t.name) for t in session.user.favorites.tracks() ] pass return [] def browse(self, uri): logger.info("Browsing uri %s", uri) if not uri or not uri.startswith("tidal:"): return [] session = self.backend._session # summaries if uri == self.root_directory.uri: return ref_models_mappers.create_root() elif uri == "tidal:my_artists": return ref_models_mappers.create_artists( session.user.favorites.artists()) elif uri == "tidal:my_albums": return ref_models_mappers.create_albums( session.user.favorites.albums()) elif uri == "tidal:my_playlists": return ref_models_mappers.create_playlists( session.user.favorites.playlists()) elif uri == "tidal:my_tracks": return ref_models_mappers.create_tracks( session.user.favorites.tracks()) elif uri == "tidal:moods": return ref_models_mappers.create_moods(session.get_moods()) elif uri == "tidal:genres": return ref_models_mappers.create_genres(session.get_genres()) # details parts = uri.split(':') nr_of_parts = len(parts) if nr_of_parts == 3 and parts[1] == "album": return ref_models_mappers.create_tracks( session.get_album_tracks(parts[2])) if nr_of_parts == 3 and parts[1] == "artist": top_10_tracks = session.get_artist_top_tracks(parts[2])[:10] albums = ref_models_mappers.create_albums( session.get_artist_albums(parts[2])) return albums + ref_models_mappers.create_tracks(top_10_tracks) if nr_of_parts == 3 and parts[1] == "playlist": return ref_models_mappers.create_tracks( session.get_playlist_tracks(parts[2])) if nr_of_parts == 3 and parts[1] == "mood": return ref_models_mappers.create_playlists( session.get_mood_playlists(parts[2])) if nr_of_parts == 3 and parts[1] == "genre": return ref_models_mappers.create_playlists( session.get_genre_items(parts[2], 'playlists')) logger.debug('Unknown uri for browse request: %s', uri) return [] def search(self, query=None, uris=None, exact=False): try: artists, albums, tracks = \ tidal_search(self.backend._session, query=query, exact=exact) return SearchResult(artists=artists, albums=albums, tracks=tracks) except Exception as ex: logger.info("EX") logger.info("%r", ex) def get_images(self, uris): logger.debug("Searching Tidal for images for %r" % uris) session = self.backend._session images = {} for uri in uris: uri_images = None if uri.startswith('tidal:'): parts = uri.split(':') if parts[1] == 'artist': artist_id = parts[2] img_uri = self.lru_artist_img.hit(artist_id) if img_uri is None: artist = session.get_artist(artist_id) img_uri = artist.image self.lru_artist_img[artist.id] = img_uri uri_images = [Image(uri=img_uri, width=512, height=512)] elif parts[1] == 'album': album_id = parts[2] img_uri = self.lru_album_img.hit(album_id) if img_uri is None: album = session.get_album(album_id) img_uri = album.image self.lru_album_img[album_id] = img_uri uri_images = [Image(uri=img_uri, width=512, height=512)] elif parts[1] == 'track': album_id = parts[3] img_uri = self.lru_album_img.hit(album_id) if img_uri is None: album = session.get_album(album_id) img_uri = album.image self.lru_album_img[album_id] = img_uri uri_images = [Image(uri=img_uri, width=512, height=512)] pass images[uri] = uri_images or () return images def lookup(self, uris=None): logger.info("Lookup uris %r", uris) session = self.backend._session if isinstance(uris, str): uris = [uris] if not hasattr(uris, '__iter__'): uris = [uris] tracks = [] for uri in uris: parts = uri.split(':') logger.info('URI: %s', uri) if uri.startswith('spotify:track:'): info = self.spotify_proxy.get_song_info(uri) if info is not None: result = self.search( query={ "track_name": [info["title"] + " " + " ".join(info["artists"])] }) if len(result.tracks) > 0: tracks.append(result.tracks[0]) if uri.startswith('tidal:track:'): if uri in self.track_cache: tracks.append(self.track_cache[uri]) else: tracks += self._lookup_track(session, parts) elif uri.startswith('tidal:album'): tracks += self._lookup_album(session, parts) elif uri.startswith('tidal:artist'): tracks += self._lookup_artist(session, parts) elif uri.startswith('tidal:playlist'): tracks += self._lookup_playlist(session, parts) logger.info("Returning %d tracks", len(tracks)) self.track_cache.update({track.uri: track for track in tracks}) return tracks def _lookup_playlist(self, session, parts): tracks = session.get_playlist_tracks(parts[2]) return full_models_mappers.create_mopidy_tracks(tracks) def _lookup_track(self, session, parts): album_id = parts[3] tracks = self.lru_album_tracks.hit(album_id) if tracks is None: tracks = session.get_album_tracks(album_id) self.lru_album_tracks[album_id] = tracks track = [t for t in tracks if t.id == int(parts[4])][0] artist = full_models_mappers.create_mopidy_artist(track.artist) album = full_models_mappers.create_mopidy_album(track.album, artist) return [full_models_mappers.create_mopidy_track(artist, album, track)] def _lookup_album(self, session, parts): album_id = parts[2] tracks = session.get_album_tracks(album_id) return full_models_mappers.create_mopidy_tracks(tracks) def _lookup_artist(self, session, parts): artist_id = parts[2] artist_tracks = session.get_artist_top_tracks(artist_id) return full_models_mappers.create_mopidy_tracks(artist_tracks)
def __init__(self, *args, **kwargs): super(TidalLibraryProvider, self).__init__(*args, **kwargs) self.lru_album_tracks = LruCache(max_size=10) self.lru_artist_img = LruCache() self.lru_album_img = LruCache() self.track_cache = Cache()