Merge branch '258-subsonic-covers' into 'develop'
Resolve "Include album covers in subsonic API" Closes #258 See merge request funkwhale/funkwhale!220
This commit is contained in:
commit
9ee0f09ff4
|
@ -242,8 +242,8 @@ def get_file_path(audio_file):
|
|||
'You need to specify MUSIC_DIRECTORY_SERVE_PATH and '
|
||||
'MUSIC_DIRECTORY_PATH to serve in-place imported files'
|
||||
)
|
||||
path = audio_file.replace(prefix, serve_path, 1).encode('utf-8')
|
||||
return path
|
||||
path = audio_file.replace(prefix, serve_path, 1)
|
||||
return path.encode('utf-8')
|
||||
|
||||
|
||||
def handle_serve(track_file):
|
||||
|
|
|
@ -57,8 +57,10 @@ class GetArtistSerializer(serializers.Serializer):
|
|||
'name': album.title,
|
||||
'artist': artist.name,
|
||||
'created': album.creation_date,
|
||||
'songCount': len(album.tracks.all())
|
||||
'songCount': len(album.tracks.all()),
|
||||
}
|
||||
if album.cover:
|
||||
album_data['coverArt'] = 'al-{}'.format(album.id)
|
||||
if album.release_date:
|
||||
album_data['year'] = album.release_date.year
|
||||
payload['album'].append(album_data)
|
||||
|
@ -81,6 +83,8 @@ def get_track_data(album, track, tf):
|
|||
'artistId': album.artist.pk,
|
||||
'type': 'music',
|
||||
}
|
||||
if track.album.cover:
|
||||
data['coverArt'] = 'al-{}'.format(track.album.id)
|
||||
if tf.bitrate:
|
||||
data['bitrate'] = int(tf.bitrate/1000)
|
||||
if tf.size:
|
||||
|
@ -98,6 +102,9 @@ def get_album2_data(album):
|
|||
'artist': album.artist.name,
|
||||
'created': album.creation_date,
|
||||
}
|
||||
if album.cover:
|
||||
payload['coverArt'] = 'al-{}'.format(album.id)
|
||||
|
||||
try:
|
||||
payload['songCount'] = album._tracks_count
|
||||
except AttributeError:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import datetime
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
|
||||
from rest_framework import exceptions
|
||||
|
@ -459,7 +460,7 @@ class SubsonicViewSet(viewsets.GenericViewSet):
|
|||
'code': 10,
|
||||
'message': 'Playlist ID or name must be specified.'
|
||||
}
|
||||
}, data)
|
||||
})
|
||||
|
||||
playlist = request.user.playlists.create(
|
||||
name=name
|
||||
|
@ -503,3 +504,51 @@ class SubsonicViewSet(viewsets.GenericViewSet):
|
|||
}
|
||||
}
|
||||
return response.Response(data)
|
||||
|
||||
@list_route(
|
||||
methods=['get', 'post'],
|
||||
url_name='get_cover_art',
|
||||
url_path='getCoverArt')
|
||||
def get_cover_art(self, request, *args, **kwargs):
|
||||
data = request.GET or request.POST
|
||||
id = data.get('id', '')
|
||||
if not id:
|
||||
return response.Response({
|
||||
'error': {
|
||||
'code': 10,
|
||||
'message': 'cover art ID must be specified.'
|
||||
}
|
||||
})
|
||||
|
||||
if id.startswith('al-'):
|
||||
try:
|
||||
album_id = int(id.replace('al-', ''))
|
||||
album = music_models.Album.objects.exclude(
|
||||
cover__isnull=True
|
||||
).exclude(cover='').get(pk=album_id)
|
||||
except (TypeError, ValueError, music_models.Album.DoesNotExist):
|
||||
return response.Response({
|
||||
'error': {
|
||||
'code': 70,
|
||||
'message': 'cover art not found.'
|
||||
}
|
||||
})
|
||||
cover = album.cover
|
||||
else:
|
||||
return response.Response({
|
||||
'error': {
|
||||
'code': 70,
|
||||
'message': 'cover art not found.'
|
||||
}
|
||||
})
|
||||
|
||||
mapping = {
|
||||
'nginx': 'X-Accel-Redirect',
|
||||
'apache2': 'X-Sendfile',
|
||||
}
|
||||
path = music_views.get_file_path(cover)
|
||||
file_header = mapping[settings.REVERSE_PROXY_TYPE]
|
||||
# let the proxy set the content-type
|
||||
r = response.Response({}, content_type='')
|
||||
r[file_header] = path
|
||||
return r
|
|
@ -60,6 +60,7 @@ def test_get_artist_serializer(factories):
|
|||
'album': [
|
||||
{
|
||||
'id': album.pk,
|
||||
'coverArt': 'al-{}'.format(album.id),
|
||||
'artistId': artist.pk,
|
||||
'name': album.title,
|
||||
'artist': artist.name,
|
||||
|
@ -88,11 +89,13 @@ def test_get_album_serializer(factories):
|
|||
'songCount': 1,
|
||||
'created': album.creation_date,
|
||||
'year': album.release_date.year,
|
||||
'coverArt': 'al-{}'.format(album.id),
|
||||
'song': [
|
||||
{
|
||||
'id': track.pk,
|
||||
'isDir': 'false',
|
||||
'title': track.title,
|
||||
'coverArt': 'al-{}'.format(album.id),
|
||||
'album': album.title,
|
||||
'artist': artist.name,
|
||||
'track': track.position,
|
||||
|
|
|
@ -391,3 +391,16 @@ def test_get_indexes(f, db, logged_in_api_client, factories):
|
|||
|
||||
assert response.status_code == 200
|
||||
assert response.data == expected
|
||||
|
||||
|
||||
def test_get_cover_art_album(factories, logged_in_api_client):
|
||||
url = reverse('api:subsonic-get-cover-art')
|
||||
assert url.endswith('getCoverArt') is True
|
||||
album = factories['music.Album']()
|
||||
response = logged_in_api_client.get(url, {'id': 'al-{}'.format(album.pk)})
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response['Content-Type'] == ''
|
||||
assert response['X-Accel-Redirect'] == music_views.get_file_path(
|
||||
album.cover
|
||||
).decode('utf-8')
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Implemented getCovertArt in Subsonic API to serve album covers (#258)
|
Loading…
Reference in New Issue