Beispiel #1
0
    def setUp(self):
        super().setUp()

        try:
            # try to find out whether youtube is happy with us this time
            # send a request and skip the test if there is an error
            ydl_opts = Youtube.get_ydl_opts()
            ydl_opts["logger"] = YoutubeDLLogger(self)
            with youtube_dl.YoutubeDL(ydl_opts) as ydl:
                self.info_dict = ydl.download(
                    ["https://www.youtube.com/watch?v=wobbf3lb2nk"])
        except (youtube_dl.utils.ExtractorError,
                youtube_dl.utils.DownloadError) as e:
            self.skipTest(
                f"Error when interacting with youtube, skipping test: {e}")

        # reduce the number for youtube playlists
        self.client.post(reverse("set_max_playlist_items"), {"value": "3"})

        # clear test cache; ensure that it's the test directory
        if os.path.split(os.path.dirname(
                settings.SONGS_CACHE_DIR))[1] == "test_cache":
            for member in os.listdir(settings.SONGS_CACHE_DIR):
                member_path = os.path.join(settings.SONGS_CACHE_DIR, member)
                if os.path.isfile(member_path):
                    os.remove(member_path)
Beispiel #2
0
    def _online_suggestions(
            self, query, suggest_playlist) -> List[Dict[str, Union[str, int]]]:
        results: List[Dict[str, Union[str, int]]] = []
        if (self.musiq.base.settings.basic.online_suggestions
                and self.musiq.base.settings.basic.has_internet):
            platform_settings = self.musiq.base.settings.platforms

            if (platform_settings.spotify_enabled
                    and platform_settings.spotify_suggestions > 0):
                from core.musiq.spotify import Spotify

                spotify_suggestions = Spotify().get_search_suggestions(
                    self.musiq, query, suggest_playlist)
                spotify_suggestions = spotify_suggestions[:platform_settings.
                                                          spotify_suggestions]
                for suggestion, external_url in spotify_suggestions:
                    results.append({
                        "key": external_url,
                        "value": suggestion,
                        "type": "spotify-online",
                    })

            if (platform_settings.soundcloud_enabled
                    and platform_settings.soundcloud_suggestions > 0):
                from core.musiq.soundcloud import Soundcloud

                soundcloud_suggestions = Soundcloud().get_search_suggestions(
                    self.musiq, query)
                soundcloud_suggestions = soundcloud_suggestions[:
                                                                platform_settings
                                                                .
                                                                soundcloud_suggestions]
                for suggestion in soundcloud_suggestions:
                    results.append({
                        "key": -1,
                        "value": suggestion,
                        "type": "soundcloud-online"
                    })

            if (platform_settings.youtube_enabled
                    and platform_settings.youtube_suggestions > 0):
                from core.musiq.youtube import Youtube

                youtube_suggestions = Youtube().get_search_suggestions(
                    self.musiq, query)
                youtube_suggestions = youtube_suggestions[:platform_settings.
                                                          youtube_suggestions]
                for suggestion in youtube_suggestions:
                    results.append({
                        "key": -1,
                        "value": suggestion,
                        "type": "youtube-online"
                    })
        return results
Beispiel #3
0
        def fetch_youtube() -> None:
            from core.musiq.youtube import Youtube

            youtube_suggestions = Youtube().get_search_suggestions(query)
            youtube_suggestions = youtube_suggestions[:storage.get(
                "youtube_suggestions")]
            with results_lock:
                for suggestion in youtube_suggestions:
                    results.append({
                        "key": -1,
                        "value": suggestion,
                        "type": "youtube-online"
                    })
Beispiel #4
0
    def get_suggestions(self, request: WSGIRequest) -> JsonResponse:
        """Returns suggestions for a given query.
        Combines online and offline suggestions."""
        terms = request.GET["term"].split()
        suggest_playlist = request.GET["playlist"] == "true"

        results: List[Dict[str, Union[str, int]]] = []

        if self.musiq.base.settings.has_internet:
            if self.musiq.base.settings.spotify_enabled:
                spotify_suggestions = Spotify().get_search_suggestions(
                    " ".join(terms), suggest_playlist)
                spotify_suggestions = spotify_suggestions[:2]
                for suggestion, external_url in spotify_suggestions:
                    results.append({
                        "key": external_url,
                        "value": suggestion,
                        "type": "spotify-online",
                    })

            if self.musiq.base.settings.soundcloud_enabled:
                spotify_suggestions = Soundcloud().get_search_suggestions(
                    " ".join(terms))
                soundcloud_suggestions = spotify_suggestions[:2]
                for suggestion in soundcloud_suggestions:
                    results.append({
                        "key": -1,
                        "value": suggestion,
                        "type": "soundcloud-online"
                    })

            if self.musiq.base.settings.youtube_enabled:
                youtube_suggestions = Youtube().get_search_suggestions(
                    " ".join(terms))
                # limit to the first three online suggestions
                youtube_suggestions = youtube_suggestions[:2]
                for suggestion in youtube_suggestions:
                    results.append({
                        "key": -1,
                        "value": suggestion,
                        "type": "youtube-online"
                    })

        # The following query is roughly equivalent to the following SQL code:
        # SELECT DISTINCT id, title, artist, counter
        # FROM core_archivedsong s LEFT JOIN core_archivedquery q ON q.song
        # WHERE forall term in terms: term in q.query or term in s.artist or term in s.title
        # ORDER BY -counter
        if suggest_playlist:
            remaining_playlists = ArchivedPlaylist.objects.prefetch_related(
                "queries")
            # exclude radios from suggestions
            remaining_playlists = remaining_playlists.exclude(
                list_id__startswith="RD").exclude(list_id__contains="&list=RD")

            for term in terms:
                remaining_playlists = remaining_playlists.filter(
                    Q(title__icontains=term)
                    | Q(queries__query__icontains=term))

            playlist_suggestions = (remaining_playlists.values(
                "id", "title", "counter").distinct().order_by("-counter")[:20])

            for playlist in playlist_suggestions:
                archived_playlist = ArchivedPlaylist.objects.get(
                    id=playlist["id"])
                result_dict: Dict[str, Union[str, int]] = {
                    "key": playlist["id"],
                    "value": playlist["title"],
                    "counter": playlist["counter"],
                    "type":
                    song_utils.determine_playlist_type(archived_playlist),
                }
                results.append(result_dict)
        else:
            remaining_songs = ArchivedSong.objects.prefetch_related("queries")

            for term in terms:
                remaining_songs = remaining_songs.filter(
                    Q(title__icontains=term)
                    | Q(artist__icontains=term)
                    | Q(queries__query__icontains=term))

            song_suggestions = (remaining_songs.values(
                "id", "title", "url", "artist",
                "counter").distinct().order_by("-counter")[:20])

            for song in song_suggestions:
                provider = SongProvider.create(self.musiq,
                                               external_url=song["url"])
                cached = provider.check_cached()
                # don't suggest local songs if they are not cached (=not at expected location)
                if not cached and provider.type == "local":
                    continue
                # don't suggest online songs when we don't have internet
                if not self.musiq.base.settings.has_internet and not cached:
                    continue
                # don't suggest youtube songs if it was disabled
                if (not self.musiq.base.settings.youtube_enabled
                        and provider.type == "youtube"):
                    continue
                # don't suggest spotify songs if we are not logged in
                if (not self.musiq.base.settings.spotify_enabled
                        and provider.type == "spotify"):
                    continue
                # don't suggest soundcloud songs if we are not logged in
                if (not self.musiq.base.settings.soundcloud_enabled
                        and provider.type == "soundcloud"):
                    continue
                result_dict = {
                    "key": song["id"],
                    "value": song_utils.displayname(song["artist"],
                                                    song["title"]),
                    "counter": song["counter"],
                    "type": provider.type,
                }
                results.append(result_dict)

        return JsonResponse(results, safe=False)
Beispiel #5
0
    def get_suggestions(self, request: WSGIRequest) -> JsonResponse:
        """Returns suggestions for a given query.
        Combines online and offline suggestions."""
        query = request.GET["term"]
        suggest_playlist = request.GET["playlist"] == "true"

        results: List[Dict[str, Union[str, int]]] = []

        if (self.musiq.base.settings.online_suggestions
                and self.musiq.base.settings.has_internet):

            number_of_suggestions = 2
            if [
                    self.musiq.base.settings.spotify_enabled,
                    self.musiq.base.settings.soundcloud_enabled,
                    self.musiq.base.settings.youtube_enabled,
            ].count(True) > 1:
                # If there is more than one active service,
                # only offer one online suggestion per service
                number_of_suggestions = 1

            if self.musiq.base.settings.spotify_enabled:
                spotify_suggestions = Spotify().get_search_suggestions(
                    query, suggest_playlist)
                spotify_suggestions = spotify_suggestions[:
                                                          number_of_suggestions]
                for suggestion, external_url in spotify_suggestions:
                    results.append({
                        "key": external_url,
                        "value": suggestion,
                        "type": "spotify-online",
                    })

            if self.musiq.base.settings.soundcloud_enabled:
                soundcloud_suggestions = Soundcloud().get_search_suggestions(
                    query)
                soundcloud_suggestions = soundcloud_suggestions[:
                                                                number_of_suggestions]
                for suggestion in soundcloud_suggestions:
                    results.append({
                        "key": -1,
                        "value": suggestion,
                        "type": "soundcloud-online"
                    })

            if self.musiq.base.settings.youtube_enabled:
                youtube_suggestions = Youtube().get_search_suggestions(query)
                # limit to the first three online suggestions
                youtube_suggestions = youtube_suggestions[:
                                                          number_of_suggestions]
                for suggestion in youtube_suggestions:
                    results.append({
                        "key": -1,
                        "value": suggestion,
                        "type": "youtube-online"
                    })

        if suggest_playlist:
            search_results = watson.search(query,
                                           models=(ArchivedPlaylist, ))[:20]

            for playlist in search_results:
                playlist_info = playlist.meta
                archived_playlist = ArchivedPlaylist.objects.get(
                    id=playlist_info["id"])
                result_dict: Dict[str, Union[str, int]] = {
                    "key": playlist_info["id"],
                    "value": playlist_info["title"],
                    "counter": playlist_info["counter"],
                    "type":
                    song_utils.determine_playlist_type(archived_playlist),
                }
                results.append(result_dict)
        else:
            search_results = watson.search(query, models=(ArchivedSong, ))[:20]

            for search_result in search_results:
                song_info = search_result.meta
                provider = SongProvider.create(self.musiq,
                                               external_url=song_info["url"])
                cached = provider.check_cached()
                # don't suggest local songs if they are not cached (=not at expected location)
                if not cached and provider.type == "local":
                    continue
                # don't suggest online songs when we don't have internet
                if not self.musiq.base.settings.has_internet and not cached:
                    continue
                # don't suggest youtube songs if it was disabled
                if (not self.musiq.base.settings.youtube_enabled
                        and provider.type == "youtube"):
                    continue
                # don't suggest spotify songs if we are not logged in
                if (not self.musiq.base.settings.spotify_enabled
                        and provider.type == "spotify"):
                    continue
                # don't suggest soundcloud songs if we are not logged in
                if (not self.musiq.base.settings.soundcloud_enabled
                        and provider.type == "soundcloud"):
                    continue
                result_dict = {
                    "key":
                    song_info["id"],
                    "value":
                    song_utils.displayname(song_info["artist"],
                                           song_info["title"]),
                    "counter":
                    song_info["counter"],
                    "type":
                    provider.type,
                }
                results.append(result_dict)

        return JsonResponse(results, safe=False)