diff --git a/api/funkwhale_api/common/management/commands/load_test_data.py b/api/funkwhale_api/common/management/commands/load_test_data.py index 26f787f48..9eab5ff08 100644 --- a/api/funkwhale_api/common/management/commands/load_test_data.py +++ b/api/funkwhale_api/common/management/commands/load_test_data.py @@ -46,16 +46,28 @@ def create_local_accounts(factories, count, dependencies): return actors -def create_tagged_tracks(factories, count, dependencies): +def create_taggable_items(dependency): + def inner(factories, count, dependencies): - objs = [] - for track in dependencies["tracks"]: - tag = random.choice(dependencies["tags"]) - objs.append(factories["tags.TaggedItem"].build(content_object=track, tag=tag)) + objs = [] + tagged_objects = dependencies.get( + dependency, list(CONFIG_BY_ID[dependency]["model"].objects.all().only("pk")) + ) + tags = dependencies.get("tags", list(tags_models.Tag.objects.all().only("pk"))) + for i in range(count): + tag = random.choice(tags) + tagged_object = random.choice(tagged_objects) + objs.append( + factories["tags.TaggedItem"].build( + content_object=tagged_object, tag=tag + ) + ) - return tags_models.TaggedItem.objects.bulk_create( - objs, batch_size=BATCH_SIZE, ignore_conflicts=True - ) + return tags_models.TaggedItem.objects.bulk_create( + objs, batch_size=BATCH_SIZE, ignore_conflicts=True + ) + + return inner CONFIG = [ @@ -110,7 +122,10 @@ CONFIG = [ { "id": "track_tags", "model": tags_models.TaggedItem, - "handler": create_tagged_tracks, + "queryset": tags_models.TaggedItem.objects.filter( + content_type__app_label="music", content_type__model="track" + ), + "handler": create_taggable_items("tracks"), "depends_on": [ { "field": "tag", @@ -127,6 +142,52 @@ CONFIG = [ }, ], }, + { + "id": "album_tags", + "model": tags_models.TaggedItem, + "queryset": tags_models.TaggedItem.objects.filter( + content_type__app_label="music", content_type__model="album" + ), + "handler": create_taggable_items("albums"), + "depends_on": [ + { + "field": "tag", + "id": "tags", + "default_factor": 0.1, + "queryset": tags_models.Tag.objects.all(), + "set": False, + }, + { + "field": "content_object", + "id": "albums", + "default_factor": 1, + "set": False, + }, + ], + }, + { + "id": "artist_tags", + "model": tags_models.TaggedItem, + "queryset": tags_models.TaggedItem.objects.filter( + content_type__app_label="music", content_type__model="artist" + ), + "handler": create_taggable_items("artists"), + "depends_on": [ + { + "field": "tag", + "id": "tags", + "default_factor": 0.1, + "queryset": tags_models.Tag.objects.all(), + "set": False, + }, + { + "field": "content_object", + "id": "artists", + "default_factor": 1, + "set": False, + }, + ], + }, ] CONFIG_BY_ID = {c["id"]: c for c in CONFIG} @@ -194,8 +255,8 @@ class Command(BaseCommand): self.stdout.write("\nFinal state of database:\n\n") for row in CONFIG: - model = row["model"] - total = model.objects.all().count() + qs = row.get("queryset", row["model"].objects.all()) + total = qs.count() self.stdout.write("- {} {} objects".format(total, row["id"])) self.stdout.write("") diff --git a/api/funkwhale_api/tags/filters.py b/api/funkwhale_api/tags/filters.py index 4be4afeef..e0ac9675a 100644 --- a/api/funkwhale_api/tags/filters.py +++ b/api/funkwhale_api/tags/filters.py @@ -18,4 +18,4 @@ class TagFilter(filters.FilterSet): class Meta: model = models.Tag - fields = ["q"] + fields = {"q": ["exact"], "name": ["exact", "startswith"]} diff --git a/api/funkwhale_api/tags/views.py b/api/funkwhale_api/tags/views.py index d7b1d8aa5..1d052ca7b 100644 --- a/api/funkwhale_api/tags/views.py +++ b/api/funkwhale_api/tags/views.py @@ -1,6 +1,8 @@ from django.db.models import functions from rest_framework import viewsets +import django_filters.rest_framework + from funkwhale_api.users.oauth import permissions as oauth_permissions from . import filters @@ -20,3 +22,4 @@ class TagViewSet(viewsets.ReadOnlyModelViewSet): required_scope = "libraries" anonymous_policy = "setting" filterset_class = filters.TagFilter + filter_backends = [django_filters.rest_framework.DjangoFilterBackend] diff --git a/api/tests/common/test_commands.py b/api/tests/common/test_commands.py index e2755256e..a6fabfc06 100644 --- a/api/tests/common/test_commands.py +++ b/api/tests/common/test_commands.py @@ -81,11 +81,7 @@ def test_load_test_data_dry_run(factories, mocker): ), ( {"create_dependencies": True, "track_tags": 3}, - [ - (tags_models.Tag.objects.all(), 1), - (tags_models.TaggedItem.objects.all(), 3), - (music_models.Track.objects.all(), 3), - ], + [(tags_models.Tag.objects.all(), 1), (music_models.Track.objects.all(), 3)], ), ], ) diff --git a/api/tests/tags/test_views.py b/api/tests/tags/test_views.py index fd3246adb..b42e9ab37 100644 --- a/api/tests/tags/test_views.py +++ b/api/tests/tags/test_views.py @@ -23,18 +23,21 @@ def test_tags_list_ordering_length(factories, logged_in_api_client): url = reverse("api:v1:tags-list") tags = [ factories["tags.Tag"](name="iamareallylongtag"), - factories["tags.Tag"](name="reallylongtag"), factories["tags.Tag"](name="short"), + factories["tags.Tag"](name="reallylongtag"), factories["tags.Tag"](name="bar"), ] expected = { "count": 4, "next": None, "previous": None, - "results": [serializers.TagSerializer(tag).data for tag in tags], + "results": [ + serializers.TagSerializer(tag).data + for tag in [tags[3], tags[1], tags[2], tags[0]] + ], } - response = logged_in_api_client.get(url, {"ordering": "-length"}) + response = logged_in_api_client.get(url, {"ordering": "length"}) assert response.data == expected diff --git a/dev.yml b/dev.yml index b0ca7fc72..eaa7ca8d3 100644 --- a/dev.yml +++ b/dev.yml @@ -57,6 +57,7 @@ services: - "${MUSIC_DIRECTORY_SERVE_PATH-./data/music}:/music:ro" - "./data/plugins:/srv/funkwhale/plugins" - "./data/staticfiles:/staticfiles" + - "./data/media:/data/media" environment: - "FUNKWHALE_HOSTNAME=${FUNKWHALE_HOSTNAME-localhost}" - "FUNKWHALE_HOSTNAME_SUFFIX=funkwhale.test" @@ -65,6 +66,7 @@ services: - "DATABASE_URL=postgresql://postgres@postgres/postgres" - "CACHE_URL=redis://redis:6379/0" - "STATIC_ROOT=/staticfiles" + - "MEDIA_ROOT=/data/media" depends_on: - postgres @@ -92,10 +94,12 @@ services: - "FUNKWHALE_PROTOCOL=${FUNKWHALE_PROTOCOL-http}" - "DATABASE_URL=postgresql://postgres@postgres/postgres" - "CACHE_URL=redis://redis:6379/0" + - "MEDIA_ROOT=/data/media" volumes: - ./api:/app - "${MUSIC_DIRECTORY_SERVE_PATH-./data/music}:/music:ro" - "./data/plugins:/srv/funkwhale/plugins" + - "./data/media:/data/media" networks: - internal nginx: @@ -122,9 +126,9 @@ services: - ./docker/nginx/entrypoint.sh:/entrypoint.sh:ro - "${MUSIC_DIRECTORY_SERVE_PATH-./data/music}:/music:ro" - ./deploy/funkwhale_proxy.conf:/etc/nginx/funkwhale_proxy.conf:ro - - "${MEDIA_ROOT-./api/funkwhale_api/media}:/protected/media:ro" - "./front:/frontend:ro" - "./data/staticfiles:/staticfiles:ro" + - "./data/media:/protected/media:ro" networks: - federation - internal diff --git a/front/package.json b/front/package.json index 54cf3c8e1..2c8f041f0 100644 --- a/front/package.json +++ b/front/package.json @@ -22,6 +22,7 @@ "masonry-layout": "^4.2.2", "moment": "^2.22.2", "fomantic-ui-css": "^2.7", + "qs": "^6.7.0", "showdown": "^1.8.6", "vue": "^2.5.17", "vue-gettext": "^2.1.0", diff --git a/front/src/components/audio/album/Widget.vue b/front/src/components/audio/album/Widget.vue index ecc0a280e..609ef6ebc 100644 --- a/front/src/components/audio/album/Widget.vue +++ b/front/src/components/audio/album/Widget.vue @@ -2,10 +2,11 @@
@@ -28,7 +29,9 @@