Revert "Apply suggestion to api/funkwhale_api/common/filters.py"
This reverts commit 4972d760e2809122af54060252be14a638cc87cc.
This commit is contained in:
parent
c8218c8007
commit
6d84a814d9
|
@ -168,3 +168,37 @@ class MutationFilter(filters.FilterSet):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Mutation
|
model = models.Mutation
|
||||||
fields = ["is_approved", "is_applied", "type"]
|
fields = ["is_approved", "is_applied", "type"]
|
||||||
|
|
||||||
|
|
||||||
|
class ActorScopeFilter(filters.CharFilter):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.actor_field = kwargs.pop("actor_field")
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def filter(self, queryset, value):
|
||||||
|
if not value:
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
request = getattr(self.parent, "request", None)
|
||||||
|
if not request:
|
||||||
|
return queryset.none()
|
||||||
|
|
||||||
|
user = getattr(request, "user", None)
|
||||||
|
qs = queryset
|
||||||
|
if value.lower() == "me":
|
||||||
|
qs = self.filter_me(user=user, queryset=queryset)
|
||||||
|
elif value.lower() == "all":
|
||||||
|
return queryset
|
||||||
|
else:
|
||||||
|
return queryset.none()
|
||||||
|
|
||||||
|
if self.distinct:
|
||||||
|
qs = qs.distinct()
|
||||||
|
return qs
|
||||||
|
|
||||||
|
def filter_me(self, user, queryset):
|
||||||
|
actor = getattr(user, "actor", None)
|
||||||
|
if not actor:
|
||||||
|
return queryset.none()
|
||||||
|
|
||||||
|
return queryset.filter(**{self.actor_field: actor})
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from funkwhale_api.common import fields
|
from funkwhale_api.common import fields
|
||||||
|
from funkwhale_api.common import filters as common_filters
|
||||||
from funkwhale_api.moderation import filters as moderation_filters
|
from funkwhale_api.moderation import filters as moderation_filters
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
|
@ -8,10 +9,11 @@ class TrackFavoriteFilter(moderation_filters.HiddenContentFilterSet):
|
||||||
q = fields.SearchFilter(
|
q = fields.SearchFilter(
|
||||||
search_fields=["track__title", "track__artist__name", "track__album__title"]
|
search_fields=["track__title", "track__artist__name", "track__album__title"]
|
||||||
)
|
)
|
||||||
|
scope = common_filters.ActorScopeFilter(actor_field="user__actor", distinct=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.TrackFavorite
|
model = models.TrackFavorite
|
||||||
fields = ["user", "q"]
|
fields = ["user", "q", "scope"]
|
||||||
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG[
|
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG[
|
||||||
"TRACK_FAVORITE"
|
"TRACK_FAVORITE"
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import django_filters
|
import django_filters
|
||||||
|
|
||||||
|
from funkwhale_api.common import filters as common_filters
|
||||||
from funkwhale_api.moderation import filters as moderation_filters
|
from funkwhale_api.moderation import filters as moderation_filters
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
|
@ -8,10 +9,11 @@ from . import models
|
||||||
class ListeningFilter(moderation_filters.HiddenContentFilterSet):
|
class ListeningFilter(moderation_filters.HiddenContentFilterSet):
|
||||||
username = django_filters.CharFilter("user__username")
|
username = django_filters.CharFilter("user__username")
|
||||||
domain = django_filters.CharFilter("user__actor__domain_id")
|
domain = django_filters.CharFilter("user__actor__domain_id")
|
||||||
|
scope = common_filters.ActorScopeFilter(actor_field="user__actor", distinct=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Listening
|
model = models.Listening
|
||||||
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG[
|
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG[
|
||||||
"LISTENING"
|
"LISTENING"
|
||||||
]
|
]
|
||||||
fields = ["hidden"]
|
fields = ["hidden", "scope"]
|
||||||
|
|
|
@ -23,12 +23,17 @@ class ArtistFilter(moderation_filters.HiddenContentFilterSet):
|
||||||
q = fields.SearchFilter(search_fields=["name"])
|
q = fields.SearchFilter(search_fields=["name"])
|
||||||
playable = filters.BooleanFilter(field_name="_", method="filter_playable")
|
playable = filters.BooleanFilter(field_name="_", method="filter_playable")
|
||||||
tag = TAG_FILTER
|
tag = TAG_FILTER
|
||||||
|
scope = common_filters.ActorScopeFilter(
|
||||||
|
actor_field="tracks__uploads__library__actor", distinct=True
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Artist
|
model = models.Artist
|
||||||
fields = {
|
fields = {
|
||||||
"name": ["exact", "iexact", "startswith", "icontains"],
|
"name": ["exact", "iexact", "startswith", "icontains"],
|
||||||
"playable": "exact",
|
"playable": ["exact"],
|
||||||
|
"scope": ["exact"],
|
||||||
|
"mbid": ["exact"],
|
||||||
}
|
}
|
||||||
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["ARTIST"]
|
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["ARTIST"]
|
||||||
|
|
||||||
|
@ -42,6 +47,9 @@ class TrackFilter(moderation_filters.HiddenContentFilterSet):
|
||||||
playable = filters.BooleanFilter(field_name="_", method="filter_playable")
|
playable = filters.BooleanFilter(field_name="_", method="filter_playable")
|
||||||
tag = TAG_FILTER
|
tag = TAG_FILTER
|
||||||
id = common_filters.MultipleQueryFilter(coerce=int)
|
id = common_filters.MultipleQueryFilter(coerce=int)
|
||||||
|
scope = common_filters.ActorScopeFilter(
|
||||||
|
actor_field="uploads__library__actor", distinct=True
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Track
|
model = models.Track
|
||||||
|
@ -52,6 +60,8 @@ class TrackFilter(moderation_filters.HiddenContentFilterSet):
|
||||||
"artist": ["exact"],
|
"artist": ["exact"],
|
||||||
"album": ["exact"],
|
"album": ["exact"],
|
||||||
"license": ["exact"],
|
"license": ["exact"],
|
||||||
|
"scope": ["exact"],
|
||||||
|
"mbid": ["exact"],
|
||||||
}
|
}
|
||||||
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["TRACK"]
|
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["TRACK"]
|
||||||
|
|
||||||
|
@ -67,6 +77,7 @@ class UploadFilter(filters.FilterSet):
|
||||||
album_artist = filters.UUIDFilter("track__album__artist__uuid")
|
album_artist = filters.UUIDFilter("track__album__artist__uuid")
|
||||||
library = filters.UUIDFilter("library__uuid")
|
library = filters.UUIDFilter("library__uuid")
|
||||||
playable = filters.BooleanFilter(field_name="_", method="filter_playable")
|
playable = filters.BooleanFilter(field_name="_", method="filter_playable")
|
||||||
|
scope = common_filters.ActorScopeFilter(actor_field="library__actor", distinct=True)
|
||||||
q = fields.SmartSearchFilter(
|
q = fields.SmartSearchFilter(
|
||||||
config=search.SearchConfig(
|
config=search.SearchConfig(
|
||||||
search_fields={
|
search_fields={
|
||||||
|
@ -96,6 +107,7 @@ class UploadFilter(filters.FilterSet):
|
||||||
"album_artist",
|
"album_artist",
|
||||||
"library",
|
"library",
|
||||||
"import_reference",
|
"import_reference",
|
||||||
|
"scope",
|
||||||
]
|
]
|
||||||
|
|
||||||
def filter_playable(self, queryset, name, value):
|
def filter_playable(self, queryset, name, value):
|
||||||
|
@ -107,10 +119,13 @@ class AlbumFilter(moderation_filters.HiddenContentFilterSet):
|
||||||
playable = filters.BooleanFilter(field_name="_", method="filter_playable")
|
playable = filters.BooleanFilter(field_name="_", method="filter_playable")
|
||||||
q = fields.SearchFilter(search_fields=["title", "artist__name"])
|
q = fields.SearchFilter(search_fields=["title", "artist__name"])
|
||||||
tag = TAG_FILTER
|
tag = TAG_FILTER
|
||||||
|
scope = common_filters.ActorScopeFilter(
|
||||||
|
actor_field="tracks__uploads__library__actor", distinct=True
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Album
|
model = models.Album
|
||||||
fields = ["playable", "q", "artist"]
|
fields = ["playable", "q", "artist", "scope", "mbid"]
|
||||||
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["ALBUM"]
|
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["ALBUM"]
|
||||||
|
|
||||||
def filter_playable(self, queryset, name, value):
|
def filter_playable(self, queryset, name, value):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django_filters import rest_framework as filters
|
from django_filters import rest_framework as filters
|
||||||
|
|
||||||
|
from funkwhale_api.common import filters as common_filters
|
||||||
from funkwhale_api.music import utils
|
from funkwhale_api.music import utils
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
|
@ -9,6 +10,7 @@ from . import models
|
||||||
class PlaylistFilter(filters.FilterSet):
|
class PlaylistFilter(filters.FilterSet):
|
||||||
q = filters.CharFilter(field_name="_", method="filter_q")
|
q = filters.CharFilter(field_name="_", method="filter_q")
|
||||||
playable = filters.BooleanFilter(field_name="_", method="filter_playable")
|
playable = filters.BooleanFilter(field_name="_", method="filter_playable")
|
||||||
|
scope = common_filters.ActorScopeFilter(actor_field="user__actor", distinct=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Playlist
|
model = models.Playlist
|
||||||
|
@ -17,6 +19,7 @@ class PlaylistFilter(filters.FilterSet):
|
||||||
"name": ["exact", "icontains"],
|
"name": ["exact", "icontains"],
|
||||||
"q": "exact",
|
"q": "exact",
|
||||||
"playable": "exact",
|
"playable": "exact",
|
||||||
|
"scope": "exact",
|
||||||
}
|
}
|
||||||
|
|
||||||
def filter_playable(self, queryset, name, value):
|
def filter_playable(self, queryset, name, value):
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
import django_filters
|
import django_filters
|
||||||
|
|
||||||
|
from funkwhale_api.common import filters as common_filters
|
||||||
from . import models
|
from . import models
|
||||||
|
|
||||||
|
|
||||||
class RadioFilter(django_filters.FilterSet):
|
class RadioFilter(django_filters.FilterSet):
|
||||||
|
scope = common_filters.ActorScopeFilter(actor_field="user__actor", distinct=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Radio
|
model = models.Radio
|
||||||
fields = {"name": ["exact", "iexact", "startswith", "icontains"]}
|
fields = {
|
||||||
|
"name": ["exact", "iexact", "startswith", "icontains"],
|
||||||
|
"scope": "exact",
|
||||||
|
}
|
||||||
|
|
|
@ -36,3 +36,53 @@ def test_mutation_filter_is_approved(value, expected, factories):
|
||||||
)
|
)
|
||||||
|
|
||||||
assert list(filterset.qs) == [mutations[expected]]
|
assert list(filterset.qs) == [mutations[expected]]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"scope, user_index, expected_tracks",
|
||||||
|
[
|
||||||
|
("me", 0, [0]),
|
||||||
|
("me", 1, [1]),
|
||||||
|
("me", 2, []),
|
||||||
|
("all", 0, [0, 1, 2]),
|
||||||
|
("all", 1, [0, 1, 2]),
|
||||||
|
("all", 2, [0, 1, 2]),
|
||||||
|
("noop", 0, []),
|
||||||
|
("noop", 1, []),
|
||||||
|
("noop", 2, []),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_actor_scope_filter(
|
||||||
|
scope,
|
||||||
|
user_index,
|
||||||
|
expected_tracks,
|
||||||
|
queryset_equal_list,
|
||||||
|
factories,
|
||||||
|
mocker,
|
||||||
|
anonymous_user,
|
||||||
|
):
|
||||||
|
actor1 = factories["users.User"]().create_actor()
|
||||||
|
actor2 = factories["users.User"]().create_actor()
|
||||||
|
users = [actor1.user, actor2.user, anonymous_user]
|
||||||
|
tracks = [
|
||||||
|
factories["music.Upload"](library__actor=actor1, playable=True).track,
|
||||||
|
factories["music.Upload"](library__actor=actor2, playable=True).track,
|
||||||
|
factories["music.Upload"](playable=True).track,
|
||||||
|
]
|
||||||
|
|
||||||
|
class FS(filters.filters.FilterSet):
|
||||||
|
scope = filters.ActorScopeFilter(
|
||||||
|
actor_field="uploads__library__actor", distinct=True
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = tracks[0].__class__
|
||||||
|
fields = ["scope"]
|
||||||
|
|
||||||
|
queryset = tracks[0].__class__.objects.all()
|
||||||
|
request = mocker.Mock(user=users[user_index])
|
||||||
|
filterset = FS({"scope": scope}, queryset=queryset.order_by("id"), request=request)
|
||||||
|
|
||||||
|
expected = [tracks[i] for i in expected_tracks]
|
||||||
|
|
||||||
|
assert filterset.qs == expected
|
||||||
|
|
Loading…
Reference in New Issue