Exemplo n.º 1
0
 def tracks(self, request, *args, **kwargs):
     playlist = self.get_object()
     plts = playlist.playlist_tracks.all().for_nested_serialization(
         music_utils.get_actor_from_request(request))
     serializer = serializers.PlaylistTrackSerializer(plts, many=True)
     data = {"count": len(plts), "results": serializer.data}
     return Response(data, status=200)
Exemplo n.º 2
0
    def get_album_list2(self, request, *args, **kwargs):
        queryset = music_models.Album.objects.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)

        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)
Exemplo n.º 3
0
    def search3(self, request, *args, **kwargs):
        data = request.GET or request.POST
        query = str(data.get("query", "")).replace("*", "")
        actor = utils.get_actor_from_request(request)
        conf = [
            {
                "subsonic":
                "artist",
                "search_fields": ["name"],
                "queryset":
                (music_models.Artist.objects.with_albums_count().values(
                    "id", "_albums_count", "name")),
                "serializer":
                lambda qs: [serializers.get_artist_data(a) for a in qs],
            },
            {
                "subsonic":
                "album",
                "search_fields": ["title"],
                "queryset":
                (music_models.Album.objects.with_tracks_count().select_related(
                    "artist")),
                "serializer":
                serializers.get_album_list2_data,
            },
            {
                "subsonic":
                "song",
                "search_fields": ["title"],
                "queryset": (music_models.Track.objects.prefetch_related(
                    "uploads").select_related("album__artist")),
                "serializer":
                serializers.get_song_list_data,
            },
        ]
        payload = {"searchResult3": {}}
        for c in conf:
            offsetKey = "{}Offset".format(c["subsonic"])
            countKey = "{}Count".format(c["subsonic"])
            try:
                offset = int(data[offsetKey])
            except (TypeError, KeyError, ValueError):
                offset = 0

            try:
                size = int(data[countKey])
            except (TypeError, KeyError, ValueError):
                size = 20

            size = min(size, 100)
            queryset = c["queryset"]
            if query:
                queryset = c["queryset"].filter(
                    utils.get_query(query, c["search_fields"]))
            queryset = queryset.playable_by(actor)
            queryset = common_utils.order_for_search(queryset,
                                                     c["search_fields"][0])
            queryset = queryset[offset:offset + size]
            payload["searchResult3"][c["subsonic"]] = c["serializer"](queryset)
        return response.Response(payload)
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    def get_indexes(self, request, *args, **kwargs):
        artists = music_models.Artist.objects.all().playable_by(
            utils.get_actor_from_request(request))
        data = serializers.GetArtistsSerializer(artists).data
        payload = {"indexes": data}

        return response.Response(payload, status=200)
Exemplo n.º 6
0
 def get_queryset(self):
     return self.queryset.filter(
         fields.privacy_level_query(
             self.request.user,
             lookup_field="playlist__privacy_level",
             user_field="playlist__user",
         )).for_nested_serialization(
             music_utils.get_actor_from_request(self.request))
Exemplo n.º 7
0
 def get_queryset(self):
     queryset = super().get_queryset()
     queryset = queryset.filter(
         fields.privacy_level_query(self.request.user,
                                    "user__privacy_level"))
     tracks = Track.objects.with_playable_uploads(
         music_utils.get_actor_from_request(self.request)).select_related(
             "artist", "album__artist", "attributed_to")
     return queryset.prefetch_related(Prefetch("track", queryset=tracks))
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
 def tracks(self, request, *args, **kwargs):
     radio = self.get_object()
     tracks = radio.get_candidates().for_nested_serialization()
     actor = music_utils.get_actor_from_request(self.request)
     tracks = tracks.with_playable_uploads(actor)
     tracks = tracks.playable_by(actor)
     page = self.paginate_queryset(tracks)
     if page is not None:
         serializer = TrackSerializer(page, many=True)
         return self.get_paginated_response(serializer.data)
Exemplo n.º 10
0
 def add(self, request, *args, **kwargs):
     playlist = self.get_object()
     serializer = serializers.PlaylistAddManySerializer(data=request.data)
     serializer.is_valid(raise_exception=True)
     try:
         plts = playlist.insert_many(serializer.validated_data["tracks"])
     except exceptions.ValidationError as e:
         payload = {"playlist": e.detail}
         return Response(payload, status=400)
     ids = [p.id for p in plts]
     plts = (models.PlaylistTrack.objects.filter(
         pk__in=ids).order_by("index").for_nested_serialization(
             music_utils.get_actor_from_request(request)))
     serializer = serializers.PlaylistTrackSerializer(plts, many=True)
     data = {"count": len(plts), "results": serializer.data}
     return Response(data, status=201)
Exemplo n.º 11
0
        def inner(self, request, *args, **kwargs):
            data = request.GET or request.POST
            try:
                raw_value = data[field]
            except KeyError:
                return response.Response({
                    "error": {
                        "code":
                        10,
                        "message":
                        "required parameter '{}' not present".format(field),
                    }
                })
            try:
                value = cast(raw_value)
            except (ValueError, TypeError, ValidationError):
                return response.Response({
                    "error": {
                        "code": 0,
                        "message": 'For input string "{}"'.format(raw_value),
                    }
                })
            qs = queryset
            if hasattr(qs, "__call__"):
                qs = qs(request)

            if filter_playable:
                actor = utils.get_actor_from_request(request)
                qs = qs.playable_by(actor).distinct()

            try:
                obj = qs.get(**{model_field: value})
            except qs.model.DoesNotExist:
                return response.Response({
                    "error": {
                        "code":
                        70,
                        "message":
                        "{} not found".format(qs.model.__class__.__name__),
                    }
                })
            kwargs["obj"] = obj
            return func(self, request, *args, **kwargs)
Exemplo n.º 12
0
    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)
Exemplo n.º 13
0
 def get_queryset(self):
     queryset = super().get_queryset()
     actor = music_utils.get_actor_from_request(self.request)
     return queryset.playable_by(actor)
Exemplo n.º 14
0
 def get_queryset(self):
     return self.queryset.filter(
         fields.privacy_level_query(self.request.user)).with_playable_plts(
             music_utils.get_actor_from_request(self.request))
Exemplo n.º 15
0
    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)