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)
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
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" })
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)
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)