Skip to content
Snippets Groups Projects
Commit 2f44dd0e authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Merge branch '199-disabled-play' into 'develop'

Resolve "Unplayable tracks are not disabled in the interface"

Closes #199

See merge request funkwhale/funkwhale!191
parents 9c9f6708 2f5a13a3
No related branches found
No related tags found
No related merge requests found
......@@ -38,6 +38,7 @@ class ImportBatchAdmin(admin.ModelAdmin):
search_fields = [
'import_request__name', 'source', 'batch__pk', 'mbid']
@admin.register(models.ImportJob)
class ImportJobAdmin(admin.ModelAdmin):
list_display = ['source', 'batch', 'track_file', 'status', 'mbid']
......@@ -77,5 +78,10 @@ class TrackFileAdmin(admin.ModelAdmin):
list_select_related = [
'track'
]
search_fields = ['source', 'acoustid_track_id']
search_fields = [
'source',
'acoustid_track_id',
'track__title',
'track__album__title',
'track__artist__name']
list_filter = ['mimetype']
......@@ -15,6 +15,9 @@ class SubsonicJSONRenderer(renderers.JSONRenderer):
}
}
final['subsonic-response'].update(data)
if 'error' in final:
# an error was returned
final['subsonic-response']['status'] = 'failed'
return super().render(final, accepted_media_type, renderer_context)
......@@ -31,6 +34,9 @@ class SubsonicXMLRenderer(renderers.JSONRenderer):
'version': '1.16.0',
}
final.update(data)
if 'error' in final:
# an error was returned
final['status'] = 'failed'
tree = dict_to_xml_tree('subsonic-response', final)
return b'<?xml version="1.0" encoding="UTF-8"?>\n' + ET.tostring(tree, encoding='utf-8')
......
......@@ -31,15 +31,19 @@ def find_object(queryset, model_field='pk', field='id', cast=int):
raw_value = data[field]
except KeyError:
return response.Response({
'code': 10,
'message': "required parameter '{}' not present".format(field)
'error': {
'code': 10,
'message': "required parameter '{}' not present".format(field)
}
})
try:
value = cast(raw_value)
except (TypeError, ValidationError):
return response.Response({
'code': 0,
'message': 'For input string "{}"'.format(raw_value)
'error': {
'code': 0,
'message': 'For input string "{}"'.format(raw_value)
}
})
qs = queryset
if hasattr(qs, '__call__'):
......@@ -48,9 +52,11 @@ def find_object(queryset, model_field='pk', field='id', cast=int):
obj = qs.get(**{model_field: value})
except qs.model.DoesNotExist:
return response.Response({
'code': 70,
'message': '{} not found'.format(
qs.model.__class__.__name__)
'error': {
'code': 70,
'message': '{} not found'.format(
qs.model.__class__.__name__)
}
})
kwargs['obj'] = obj
return func(self, request, *args, **kwargs)
......@@ -83,15 +89,14 @@ class SubsonicViewSet(viewsets.GenericViewSet):
payload = {
'status': 'failed'
}
try:
if exc.__class__ in mapping:
code, message = mapping[exc.__class__]
except KeyError:
return super().handle_exception(exc)
else:
payload['error'] = {
'code': code,
'message': message
}
return super().handle_exception(exc)
payload['error'] = {
'code': code,
'message': message
}
return response.Response(payload, status=200)
......@@ -450,8 +455,10 @@ class SubsonicViewSet(viewsets.GenericViewSet):
name = data.get('name', '')
if not name:
return response.Response({
'code': 10,
'message': 'Playlist ID or name must be specified.'
'error': {
'code': 10,
'message': 'Playlist ID or name must be specified.'
}
}, data)
playlist = request.user.playlists.create(
......
Uplayable tracks are now properly disabled in the interface (#199)
<template>
<div :class="['ui', {'tiny': discrete}, 'buttons']">
<div :title="title" :class="['ui', {'tiny': discrete}, 'buttons']">
<button
:title="$t('Add to current queue')"
@click="addNext(true)"
:disabled="!playable"
:class="['ui', {loading: isLoading}, {'mini': discrete}, {disabled: !playable}, 'button']">
<i class="ui play icon"></i>
<template v-if="!discrete"><slot><i18next path="Play"/></slot></template>
......@@ -10,9 +11,9 @@
<div v-if="!discrete" :class="['ui', {disabled: !playable}, 'floating', 'dropdown', 'icon', 'button']">
<i class="dropdown icon"></i>
<div class="menu">
<div class="item"@click="add"><i class="plus icon"></i><i18next path="Add to queue"/></div>
<div class="item"@click="addNext()"><i class="step forward icon"></i><i18next path="Play next"/></div>
<div class="item"@click="addNext(true)"><i class="arrow down icon"></i><i18next path="Play now"/></div>
<div class="item" :disabled="!playable" @click="add"><i class="plus icon"></i><i18next path="Add to queue"/></div>
<div class="item" :disabled="!playable" @click="addNext()"><i class="step forward icon"></i><i18next path="Play next"/></div>
<div class="item" :disabled="!playable" @click="addNext(true)"><i class="arrow down icon"></i><i18next path="Play now"/></div>
</div>
</div>
</div>
......@@ -45,9 +46,18 @@ export default {
jQuery(this.$el).find('.ui.dropdown').dropdown()
},
computed: {
title () {
if (this.playable) {
return this.$t('Play immediatly')
} else {
if (this.track) {
return this.$t('This track is not imported and cannot be played')
}
}
},
playable () {
if (this.track) {
return true
return this.track.files.length > 0
} else if (this.tracks) {
return this.tracks.length > 0
} else if (this.playlist) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment