diff --git a/api/funkwhale_api/radios/radios.py b/api/funkwhale_api/radios/radios.py
index 4f23fb281..ef1931d5f 100644
--- a/api/funkwhale_api/radios/radios.py
+++ b/api/funkwhale_api/radios/radios.py
@@ -1,3 +1,4 @@
+import logging
import random
from django.core.exceptions import ValidationError
@@ -11,9 +12,11 @@ from funkwhale_api.moderation import filters as moderation_filters
from funkwhale_api.music.models import Artist, Library, Track, Upload
from funkwhale_api.tags.models import Tag
-from . import filters, models
+from . import filters, models, utils
from .registries import registry
+logger = logging.getLogger(__name__)
+
class SimpleRadio(object):
related_object_field = None
@@ -201,7 +204,7 @@ class NextNotFound(Exception):
pass
-@registry.register(name="similar")
+@registry.register(name="similar_history")
class SimilarRadio(RelatedObjectRadio):
model = Track
@@ -254,6 +257,27 @@ class SimilarRadio(RelatedObjectRadio):
return random.choice([c[0] for c in next_candidates])
+@registry.register(name="similar_mbid")
+class SimilarAcousticRadio(RelatedObjectRadio):
+ model = Track
+
+ def get_regex(self):
+ related_mbid = str(self.session.related_object.mbid)
+ if not related_mbid:
+ logger.info(f"No mbid found for the related object.")
+ pass
+ mbids_regex = str()
+ mbids = utils.get_similar_tracks_mbids_from_mbid(related_mbid, "rosamerica")
+ for mbid in mbids:
+ mbids_regex = str(mbids_regex) + str(mbid + "|")
+ return mbids_regex
+
+ def filter_queryset(self, queryset):
+ queryset = super().filter_queryset(queryset)
+ mbids_regex = self.get_regex()
+ return queryset.filter(mbid__regex=r'({mbids_regex})'.format(mbids_regex=mbids_regex))
+
+
@registry.register(name="artist")
class ArtistRadio(RelatedObjectRadio):
model = Artist
diff --git a/api/funkwhale_api/radios/utils.py b/api/funkwhale_api/radios/utils.py
new file mode 100644
index 000000000..1190b78b5
--- /dev/null
+++ b/api/funkwhale_api/radios/utils.py
@@ -0,0 +1,35 @@
+import json
+import logging
+
+import requests
+
+logger = logging.getLogger(__name__)
+
+VALID_METRICS = ['mfccs', 'mfccsw', 'gfccs', 'gfccsw', 'key', 'bpm', 'onsetrate', 'moods',
+ 'instruments', 'dortmund', 'rosamerica', 'tzanetakis']
+
+
+class EndpointError(Exception):
+ pass
+
+
+def get_similar_tracks_mbids_from_mbid(mbid, annoy_similarity):
+
+ if annoy_similarity not in VALID_METRICS:
+ raise AttributeError("Metric %s is not valid. Must be one of : " + print(VALID_METRICS))
+
+ headers = {'Content-Type': 'application/json'}
+ endpoint = "acousticbrainz.org/api/v1/similarity"
+ similar_tracks_mbids = []
+ similar_tracks = requests.get(
+ 'https://{endpoint}/{annoy_similarity}/?recording_ids={mbid}&remove_dups&n_neighbours=1000'
+ .format(endpoint=endpoint, annoy_similarity=annoy_similarity, mbid=mbid), headers=headers
+ )
+ if similar_tracks.status_code != 200:
+ logger.warning("Error while querying {endpoint!r} : {similar_tracks.content!r}")
+ raise EndpointError
+
+ j = json.loads(similar_tracks.content)
+ for tracks in j['{mbid}'.format(mbid=mbid)]['0']:
+ similar_tracks_mbids.append(tracks['recording_mbid'])
+ return similar_tracks_mbids
diff --git a/front/src/components/audio/PlayButton.vue b/front/src/components/audio/PlayButton.vue
index dd0e65132..564ac3d7f 100644
--- a/front/src/components/audio/PlayButton.vue
+++ b/front/src/components/audio/PlayButton.vue
@@ -25,7 +25,7 @@
-