diff --git a/api/funkwhale_api/radios/migrations/0006_radiosession_config.py b/api/funkwhale_api/radios/migrations/0006_radiosession_config.py
new file mode 100644
index 000000000..944886b9b
--- /dev/null
+++ b/api/funkwhale_api/radios/migrations/0006_radiosession_config.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.2.10 on 2022-01-21 11:56
+
+import django.contrib.postgres.fields.jsonb
+import django.core.serializers.json
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('radios', '0005_auto_20200803_1222'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='radiosession',
+ name='config',
+ field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, encoder=django.core.serializers.json.DjangoJSONEncoder, null=True),
+ ),
+ ]
diff --git a/api/funkwhale_api/radios/migrations/0007_merge_20220715_0801.py b/api/funkwhale_api/radios/migrations/0007_merge_20220715_0801.py
new file mode 100644
index 000000000..15c05ac9f
--- /dev/null
+++ b/api/funkwhale_api/radios/migrations/0007_merge_20220715_0801.py
@@ -0,0 +1,14 @@
+# Generated by Django 3.2.13 on 2022-07-15 08:01
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('radios', '0006_alter_radio_config'),
+ ('radios', '0006_radiosession_config'),
+ ]
+
+ operations = [
+ ]
diff --git a/api/funkwhale_api/radios/models.py b/api/funkwhale_api/radios/models.py
index 8cb56cb92..6439e25db 100644
--- a/api/funkwhale_api/radios/models.py
+++ b/api/funkwhale_api/radios/models.py
@@ -51,6 +51,8 @@ class RadioSession(models.Model):
related_object = GenericForeignKey(
"related_object_content_type", "related_object_id"
)
+ CONFIG_VERSION = 0
+ config = JSONField(encoder=DjangoJSONEncoder, blank=True, null=True)
def save(self, **kwargs):
self.radio.clean(self)
diff --git a/api/funkwhale_api/radios/radios.py b/api/funkwhale_api/radios/radios.py
index 065d51848..126dac672 100644
--- a/api/funkwhale_api/radios/radios.py
+++ b/api/funkwhale_api/radios/radios.py
@@ -1,4 +1,5 @@
import datetime
+import logging
import random
from django.core.exceptions import ValidationError
@@ -15,6 +16,8 @@ from funkwhale_api.tags.models import Tag
from . import filters, models
from .registries import registry
+logger = logging.getLogger(__name__)
+
class SimpleRadio(object):
related_object_field = None
@@ -148,6 +151,37 @@ class CustomRadio(SessionRadio):
return data
+@registry.register(name="custom_multiple")
+class CustomMultiple(SessionRadio):
+ """
+ Receive a vuejs generated config and use it to launch a radio session
+ """
+
+ config = serializers.JSONField(required=True)
+
+ def get_config(self, data):
+ return data["config"]
+
+ def get_queryset_kwargs(self):
+ kwargs = super().get_queryset_kwargs()
+ kwargs["config"] = self.session.config
+ return kwargs
+
+ def validate_session(self, data, **context):
+ data = super().validate_session(data, **context)
+ try:
+ data["config"] is not None
+ except KeyError:
+ raise serializers.ValidationError(
+ "You must provide a configuration for this radio"
+ )
+ return data
+
+ def get_queryset(self, **kwargs):
+ qs = super().get_queryset(**kwargs)
+ return filters.run(kwargs["config"], candidates=qs)
+
+
class RelatedObjectRadio(SessionRadio):
"""Abstract radio related to an object (tag, artist, user...)"""
diff --git a/api/funkwhale_api/radios/serializers.py b/api/funkwhale_api/radios/serializers.py
index 65e48449a..dc5d6c908 100644
--- a/api/funkwhale_api/radios/serializers.py
+++ b/api/funkwhale_api/radios/serializers.py
@@ -66,6 +66,7 @@ class RadioSessionSerializer(serializers.ModelSerializer):
"user",
"creation_date",
"custom_radio",
+ "config",
)
def validate(self, data):
diff --git a/api/tests/radios/test_radios.py b/api/tests/radios/test_radios.py
index f64fcac5f..0e2b47f60 100644
--- a/api/tests/radios/test_radios.py
+++ b/api/tests/radios/test_radios.py
@@ -413,3 +413,19 @@ def test_get_choices_for_custom_radio_exclude_tag(factories):
expected = [u.track.pk for u in included_uploads]
assert list(choices.values_list("id", flat=True)) == expected
+
+
+def test_can_start_custom_multiple_radio_from_api(api_client, factories):
+ tracks = factories["music.Track"].create_batch(5)
+ url = reverse("api:v1:radios:sessions-list")
+ map_filters_to_type = {"tags": "names", "artists": "ids"}
+ for (key, value) in map_filters_to_type.items():
+ attr = value[:-1]
+ track_filter_key = [getattr(a.artist, attr) for a in tracks]
+ config = {"filters": [{"type": key, value: track_filter_key}]}
+ response = api_client.post(
+ url,
+ {"radio_type": "custom_multiple", "config": config},
+ format="json",
+ )
+ assert response.status_code == 201
diff --git a/api/tests/radios/test_serializers.py b/api/tests/radios/test_serializers.py
index 748bd993a..ef52ad8a6 100644
--- a/api/tests/radios/test_serializers.py
+++ b/api/tests/radios/test_serializers.py
@@ -40,5 +40,6 @@ def test_tag_radio_repr(factories, to_api_date):
"user": session.user.pk,
"related_object_id": tag.name,
"creation_date": to_api_date(session.creation_date),
+ "config": None,
}
assert serializers.RadioSessionSerializer(session).data == expected
diff --git a/changes/changelog.d/1563-enhancement b/changes/changelog.d/1563-enhancement
new file mode 100644
index 000000000..dd31a1c79
--- /dev/null
+++ b/changes/changelog.d/1563-enhancement
@@ -0,0 +1 @@
+Adding support for play all radio in search result page (#1563)
\ No newline at end of file
diff --git a/front/src/components/radios/Button.vue b/front/src/components/radios/Button.vue
index 5f36ec488..1d63b5528 100644
--- a/front/src/components/radios/Button.vue
+++ b/front/src/components/radios/Button.vue
@@ -7,16 +7,7 @@
class="ui feed icon"
role="button"
/>
-
-