示例#1
0
    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
示例#2
0
    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)
示例#3
0
    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
示例#4
0
    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)