def extract_id(self) -> Optional[str]: if self.key is not None: try: archived_song = ArchivedSong.objects.get(id=self.key) return self.__class__.get_id_from_external_url(archived_song.url) except ArchivedSong.DoesNotExist: return None if self.query is not None: url_type = song_utils.determine_url_type(self.query) if url_type == "youtube": from core.musiq.youtube import YoutubeSongProvider return YoutubeSongProvider.get_id_from_external_url(self.query) if url_type == "spotify": from core.musiq.spotify import SpotifySongProvider return SpotifySongProvider.get_id_from_external_url(self.query) if url_type == "soundcloud": from core.musiq.soundcloud import SoundcloudSongProvider return SoundcloudSongProvider.get_id_from_external_url(self.query) # interpret the query as an external url and try to look it up in the database try: archived_song = ArchivedSong.objects.get(url=self.query) return self.__class__.get_id_from_external_url(archived_song.url) except ArchivedSong.DoesNotExist: return None logging.error("Can not extract id because neither key nor query are known") return None
def _request_music(self, ip, query, key, playlist, platform, archive=True, manually_requested=True): providers = [] if playlist: if key is not None: # an archived song was requested. The key determines the SongProvider (Youtube or Spotify) provider = PlaylistProvider.create(self, query, key) if provider is None: return HttpResponseBadRequest('No provider found for requested playlist') providers.append(provider) else: # try to use spotify if the user did not specifically request youtube if platform is None or platform == 'spotify': if self.base.settings.spotify_enabled: providers.append(SpotifyPlaylistProvider(self, query, key)) # use Youtube as a fallback providers.append(YoutubePlaylistProvider(self, query, key)) else: if key is not None: # an archived song was requested. The key determines the SongProvider (Youtube or Spotify) provider = SongProvider.create(self, query, key) if provider is None: return HttpResponseBadRequest('No provider found for requested song') providers.append(provider) else: # try to use spotify if the user did not specifically request youtube if platform is None or platform == 'spotify': if self.base.settings.spotify_enabled: providers.append(SpotifySongProvider(self, query, key)) # use Youtube as a fallback providers.append(YoutubeSongProvider(self, query, key)) fallback = False used_provider = None for i, provider in enumerate(providers): if not provider.check_cached(): if not provider.check_downloadable(): # this provider cannot provide this song, use the next provider # if this was the last provider, show its error if i == len(providers) - 1: return HttpResponseBadRequest(provider.error) fallback = True continue if not provider.download(ip, archive=archive, manually_requested=manually_requested): return HttpResponseBadRequest(provider.error) else: provider.enqueue(ip, archive=archive, manually_requested=manually_requested) # the current provider could provide the song, don't try the other ones used_provider = provider break message = used_provider.ok_message if fallback: message = message + ' (used fallback)' return HttpResponse(message)
def do_request_music( self, request_ip: str, query: str, key: Optional[int], playlist: bool, platform: str, archive: bool = True, manually_requested: bool = True, ) -> Tuple[bool, str, Optional[int]]: """Performs the actual requesting of the music, not an endpoint. Enqueues the requested song or playlist into the queue, using appropriate providers. Returns a 3-tuple: successful, message, queue_key""" providers: List[MusicProvider] = [] provider: MusicProvider if playlist: if key is not None: # an archived song was requested. # The key determines the PlaylistProvider provider = PlaylistProvider.create(self, query, key) if provider is None: return False, "No provider found for requested playlist", None providers.append(provider) else: # try to use spotify if the user did not specifically request youtube if self.base.settings.soundcloud_enabled: soundcloud_provider = SoundcloudPlaylistProvider(self, query, key) if platform == "soundcloud": providers.insert(0, soundcloud_provider) else: providers.append(soundcloud_provider) if self.base.settings.spotify_enabled: spotify_provider = SpotifyPlaylistProvider(self, query, key) if platform == "spotify": providers.insert(0, spotify_provider) else: providers.append(spotify_provider) if self.base.settings.youtube_enabled: youtube_provider = YoutubePlaylistProvider(self, query, key) if platform == "youtube": providers.insert(0, youtube_provider) else: providers.append(youtube_provider) else: if key is not None: # an archived song was requested. # The key determines the SongProvider provider = SongProvider.create(self, query, key) if provider is None: return False, "No provider found for requested song", None providers.append(provider) else: if platform == "local": # if a local provider was requested, # use only this one as its only possible source is the database providers.append(LocalSongProvider(self, query, key)) else: if self.base.settings.soundcloud_enabled: try: soundcloud_provider = SoundcloudSongProvider( self, query, key ) if platform == "soundcloud": providers.insert(0, soundcloud_provider) else: providers.append(soundcloud_provider) except WrongUrlError: pass if self.base.settings.spotify_enabled: try: spotify_provider = SpotifySongProvider(self, query, key) if platform == "spotify": providers.insert(0, spotify_provider) else: providers.append(spotify_provider) except WrongUrlError: pass if self.base.settings.youtube_enabled: try: youtube_provider = YoutubeSongProvider(self, query, key) if platform == "youtube": providers.insert(0, youtube_provider) else: providers.append(youtube_provider) except WrongUrlError: pass if not len(providers): return False, "No backend configured to handle your request.", None fallback = False for i, provider in enumerate(providers): try: provider.request( request_ip, archive=archive, manually_requested=manually_requested ) # the current provider could provide the song, don't try the other ones break except ProviderError: # this provider cannot provide this song, use the next provider # if this was the last provider, show its error if i == len(providers) - 1: return False, provider.error, None fallback = True message = provider.ok_message queue_key = None if not playlist: queue_key = provider.queued_song.id if fallback: message += " (used fallback)" return True, message, queue_key
def do_request_music( self, request_ip: str, query: str, key: Optional[int], playlist: bool, platform: str, archive: bool = True, manually_requested: bool = True, ) -> HttpResponse: """Performs the actual requesting of the music, not an endpoint. Enqueues the requested song or playlist into the queue, using appropriate providers.""" providers: List[MusicProvider] = [] provider: MusicProvider if playlist: if key is not None: # an archived song was requested. # The key determines the SongProvider (Youtube or Spotify) provider = PlaylistProvider.create(self, query, key) if provider is None: return HttpResponseBadRequest( "No provider found for requested playlist") providers.append(provider) else: # try to use spotify if the user did not specifically request youtube if platform is None or platform == "spotify": if self.base.settings.spotify_enabled: providers.append( SpotifyPlaylistProvider(self, query, key)) if self.base.settings.youtube_enabled: # use Youtube as a fallback providers.append(YoutubePlaylistProvider(self, query, key)) else: if key is not None: # an archived song was requested. # The key determines the SongProvider (Youtube or Spotify) provider = SongProvider.create(self, query, key) if provider is None: return HttpResponseBadRequest( "No provider found for requested song") providers.append(provider) else: if platform == "local": # if a local provider was requested, # use only this one as its only possible source is the database providers.append(LocalSongProvider(self, query, key)) else: # try to use spotify if the user did not specifically request youtube if platform is None or platform == "spotify": if self.base.settings.spotify_enabled: try: providers.append( SpotifySongProvider(self, query, key)) except ValueError: pass if self.base.settings.youtube_enabled: # use Youtube as a fallback providers.append(YoutubeSongProvider(self, query, key)) if not len(providers): return HttpResponseBadRequest( "No backend configured to handle your request.") fallback = False for i, provider in enumerate(providers): if not provider.check_cached(): if not provider.check_downloadable(): # this provider cannot provide this song, use the next provider # if this was the last provider, show its error if i == len(providers) - 1: return HttpResponseBadRequest(provider.error) fallback = True continue if not provider.download( request_ip, archive=archive, manually_requested=manually_requested): return HttpResponseBadRequest(provider.error) else: provider.enqueue(request_ip, archive=archive, manually_requested=manually_requested) # the current provider could provide the song, don't try the other ones used_provider = provider break message = provider.ok_message if fallback: message += " (used fallback)" return HttpResponse(message)