Merge branch '1036-local-to-remote-tracks-listen' into 'develop'
Fix #1036: Favor local uploads when playing a track with multiple uploads Closes #1036 See merge request funkwhale/funkwhale!1053
This commit is contained in:
commit
08f4dd70ed
|
@ -281,6 +281,22 @@ def serialize_upload(upload):
|
|||
}
|
||||
|
||||
|
||||
def sort_uploads_for_listen(uploads):
|
||||
"""
|
||||
Given a list of uploads, return a sorted list of uploads, with local or locally
|
||||
cached ones first, and older first
|
||||
"""
|
||||
score = {upload: 0 for upload in uploads}
|
||||
for upload in uploads:
|
||||
if upload.is_local:
|
||||
score[upload] = 3
|
||||
elif upload.audio_file:
|
||||
score[upload] = 2
|
||||
|
||||
sorted_tuples = sorted(score.items(), key=lambda t: (t[1], -t[0].pk), reverse=True)
|
||||
return [t[0] for t in sorted_tuples]
|
||||
|
||||
|
||||
class TrackSerializer(OptionalDescriptionMixin, serializers.Serializer):
|
||||
artist = serializers.SerializerMethodField()
|
||||
album = TrackAlbumSerializer(read_only=True)
|
||||
|
@ -310,7 +326,8 @@ class TrackSerializer(OptionalDescriptionMixin, serializers.Serializer):
|
|||
return obj.listen_url
|
||||
|
||||
def get_uploads(self, obj):
|
||||
return [serialize_upload(u) for u in getattr(obj, "playable_uploads", [])]
|
||||
uploads = getattr(obj, "playable_uploads", [])
|
||||
return [serialize_upload(u) for u in sort_uploads_for_listen(uploads)]
|
||||
|
||||
def get_tags(self, obj):
|
||||
tagged_items = getattr(obj, "_prefetched_tagged_items", [])
|
||||
|
|
|
@ -25,6 +25,7 @@ from funkwhale_api.common import (
|
|||
from funkwhale_api.favorites.models import TrackFavorite
|
||||
from funkwhale_api.moderation import filters as moderation_filters
|
||||
from funkwhale_api.music import models as music_models
|
||||
from funkwhale_api.music import serializers as music_serializers
|
||||
from funkwhale_api.music import utils
|
||||
from funkwhale_api.music import views as music_views
|
||||
from funkwhale_api.playlists import models as playlists_models
|
||||
|
@ -255,10 +256,13 @@ class SubsonicViewSet(viewsets.GenericViewSet):
|
|||
data = request.GET or request.POST
|
||||
track = kwargs.pop("obj")
|
||||
queryset = track.uploads.select_related("track__album__artist", "track__artist")
|
||||
upload = queryset.first()
|
||||
if not upload:
|
||||
sorted_uploads = music_serializers.sort_uploads_for_listen(queryset)
|
||||
|
||||
if not sorted_uploads:
|
||||
return response.Response(status=404)
|
||||
|
||||
upload = sorted_uploads[0]
|
||||
|
||||
max_bitrate = data.get("maxBitRate")
|
||||
try:
|
||||
max_bitrate = min(max(int(max_bitrate), 0), 320) or None
|
||||
|
|
|
@ -584,3 +584,24 @@ def test_detail_serializers_with_description_description(
|
|||
expected = common_serializers.ContentSerializer(content).data
|
||||
serializer = serializer_class(obj, context={"description": True})
|
||||
assert serializer.data["description"] == expected
|
||||
|
||||
|
||||
def test_sort_uploads_for_listen(factories):
|
||||
local_upload = factories["music.Upload"](library__local=True)
|
||||
new_local_upload = factories["music.Upload"](library__local=True)
|
||||
remote_upload = factories["music.Upload"](audio_file__from_path=None)
|
||||
remote_upload_with_local_version = factories["music.Upload"]()
|
||||
|
||||
unsorted = [
|
||||
remote_upload_with_local_version,
|
||||
new_local_upload,
|
||||
remote_upload,
|
||||
local_upload,
|
||||
]
|
||||
expected = [
|
||||
local_upload,
|
||||
new_local_upload,
|
||||
remote_upload,
|
||||
remote_upload_with_local_version,
|
||||
]
|
||||
assert serializers.sort_uploads_for_listen(unsorted) == expected
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Favor local uploads when playing a track with multiple uploads (#1036)
|
Loading…
Reference in New Issue