def get_songs_by_genre(self, request, *args, **kwargs): data = request.GET or request.POST actor = utils.get_actor_from_request(request) queryset = music_models.Track.objects.all().exclude( moderation_filters.get_filtered_content_query( moderation_filters.USER_FILTER_CONFIG["TRACK"], request.user)) queryset = queryset.playable_by(actor) try: offset = int(data.get("offset", 0)) except (TypeError, ValueError): offset = 0 try: size = int(data["count"] ) # yep. Some endpoints have size, other have count… except (TypeError, KeyError, ValueError): size = 50 genre = data.get("genre") queryset = (queryset.playable_by(actor).filter( Q(tagged_items__tag__name=genre) | Q(artist__tagged_items__tag__name=genre) | Q(album__artist__tagged_items__tag__name=genre) | Q(album__tagged_items__tag__name=genre)).prefetch_related( "uploads").distinct().order_by("-creation_date") [offset:offset + size]) data = { "songsByGenre": { "song": serializers.GetSongSerializer(queryset, many=True).data } } return response.Response(data)
def test_get_indexes(f, db, logged_in_api_client, factories, mocker, queryset_equal_queries): factories["moderation.UserFilter"]( user=logged_in_api_client.user, target_artist=factories["music.Artist"](playable=True), ) exclude_query = moderation_filters.get_filtered_content_query( moderation_filters.USER_FILTER_CONFIG["ARTIST"], logged_in_api_client.user) url = reverse("api:subsonic-get_indexes") assert url.endswith("getIndexes") is True factories["music.Artist"].create_batch(size=3, playable=True) expected = { "indexes": serializers.GetArtistsSerializer( music_models.Artist.objects.all().exclude(exclude_query)).data } playable_by = mocker.spy(music_models.ArtistQuerySet, "playable_by") response = logged_in_api_client.get(url) assert response.status_code == 200 assert response.data == expected playable_by.assert_called_once_with( music_models.Artist.objects.all().exclude(exclude_query), logged_in_api_client.user.actor, )
def get_indexes(self, request, *args, **kwargs): artists = (music_models.Artist.objects.all().exclude( moderation_filters.get_filtered_content_query( moderation_filters.USER_FILTER_CONFIG["ARTIST"], request.user)).playable_by( utils.get_actor_from_request(request))) data = serializers.GetArtistsSerializer(artists).data payload = {"indexes": data} return response.Response(payload, status=200)
def get_queryset(self, **kwargs): qs = Track.objects.all() if not self.session: return qs if not self.session.user: return qs query = moderation_filters.get_filtered_content_query( config=moderation_filters.USER_FILTER_CONFIG["TRACK"], user=self.session.user, ) return qs.exclude(query)
def get_random_songs(self, request, *args, **kwargs): data = request.GET or request.POST actor = utils.get_actor_from_request(request) queryset = music_models.Track.objects.all().exclude( moderation_filters.get_filtered_content_query( moderation_filters.USER_FILTER_CONFIG["TRACK"], request.user)) queryset = queryset.playable_by(actor) try: size = int(data["size"]) except (TypeError, KeyError, ValueError): size = 50 queryset = (queryset.playable_by(actor).prefetch_related( "uploads").order_by("?")[:size]) data = { "randomSongs": { "song": serializers.GetSongSerializer(queryset, many=True).data } } return response.Response(data)
def get_album_list2(self, request, *args, **kwargs): queryset = (music_models.Album.objects.exclude( moderation_filters.get_filtered_content_query( moderation_filters.USER_FILTER_CONFIG["ALBUM"], request.user)).with_tracks_count().order_by("artist__name")) data = request.GET or request.POST filterset = filters.AlbumList2FilterSet(data, queryset=queryset) queryset = filterset.qs actor = utils.get_actor_from_request(request) queryset = queryset.playable_by(actor) type = data.get("type", "alphabeticalByArtist") if type == "alphabeticalByArtist": queryset = queryset.order_by("artist__name") elif type == "random": queryset = queryset.order_by("?") elif type == "alphabeticalByName" or not type: queryset = queryset.order_by("artist__title") elif type == "recent" or not type: queryset = queryset.exclude( release_date__in=["", None]).order_by("-release_date") elif type == "newest" or not type: queryset = queryset.order_by("-creation_date") elif type == "byGenre" and data.get("genre"): genre = data.get("genre") queryset = queryset.filter( Q(tagged_items__tag__name=genre) | Q(artist__tagged_items__tag__name=genre)) elif type == "byYear": try: boundaries = [ int(data.get("fromYear", 0)), int(data.get("toYear", 99999999)), ] except (TypeError, ValueError): return response.Response({ "error": { "code": 10, "message": "Invalid fromYear or toYear parameter", } }) # because, yeah, the specification explicitly state that fromYear can be greater # than toYear, to indicate reverse ordering… # http://www.subsonic.org/pages/api.jsp#getAlbumList2 from_year = min(boundaries) to_year = max(boundaries) queryset = queryset.filter(release_date__year__gte=from_year, release_date__year__lte=to_year) if boundaries[0] <= boundaries[1]: queryset = queryset.order_by("release_date") else: queryset = queryset.order_by("-release_date") try: offset = int(data["offset"]) except (TypeError, KeyError, ValueError): offset = 0 try: size = int(data["size"]) except (TypeError, KeyError, ValueError): size = 50 size = min(size, 500) queryset = queryset[offset:offset + size] data = { "albumList2": { "album": serializers.get_album_list2_data(queryset) } } return response.Response(data)