Commit e8eaf6db authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Now display CLI instructions to download a set of tracks

parent c34ea446
......@@ -362,6 +362,12 @@ class TrackFile(models.Model):
'api:v1:trackfiles-serve', kwargs={'pk': self.pk})
return self.audio_file.url
@property
def filename(self):
return '{}{}'.format(
self.track.full_name,
os.path.splitext(self.audio_file.name)[-1])
class ImportBatch(models.Model):
creation_date = models.DateTimeField(default=timezone.now)
......
......@@ -34,7 +34,7 @@ class ImportBatchSerializer(serializers.ModelSerializer):
class TrackFileSerializer(serializers.ModelSerializer):
class Meta:
model = models.TrackFile
fields = ('id', 'path', 'duration', 'source')
fields = ('id', 'path', 'duration', 'source', 'filename')
class SimpleAlbumSerializer(serializers.ModelSerializer):
......
......@@ -139,9 +139,8 @@ class TrackFileViewSet(viewsets.ReadOnlyModelViewSet):
return Response(status=404)
response = Response()
filename = "filename*=UTF-8''{}{}".format(
urllib.parse.quote(f.track.full_name),
os.path.splitext(f.audio_file.name)[-1])
filename = "filename*=UTF-8''{}".format(
urllib.parse.quote(f.filename))
response["Content-Disposition"] = "attachment; {}".format(filename)
response['X-Accel-Redirect'] = "{}{}".format(
settings.PROTECT_FILES_PATH,
......
......@@ -40,26 +40,70 @@
<td><track-favorite-icon class="favorite-icon" :track="track"></track-favorite-icon></td>
</tr>
</tbody>
<tfoot class="full-width">
<tr>
<th colspan="3">
<button @click="showDownloadModal = !showDownloadModal" class="ui basic button">Download...</button>
<modal :show.sync="showDownloadModal">
<div class="header">
Download tracks
</div>
<div class="content">
<div class="description">
<p>There is currently no way to download directly multiple tracks from funkwhale as a ZIP archive.
However, you can use a command line tools such as <a href="https://curl.haxx.se/" target="_blank">cURL</a> to easily download a list of tracks.
</p>
<p>Simply copy paste the snippet below into a terminal to launch the download.</p>
<div class="ui warning message">
Keep your PRIVATE_TOKEN secret as it gives access to your account.
</div>
<pre>
export PRIVATE_TOKEN="{{ auth.getAuthToken ()}}"
<template v-for="track in tracks">
curl -G -o "{{ track.files[0].filename }}" <template v-if="auth.user.authenticated">--header "Authorization: JWT $PRIVATE_TOKEN"</template> "{{ backend.absoluteUrl(track.files[0].path) }}"</template>
</pre>
</div>
</div>
<div class="actions">
<div class="ui black deny button">
Cancel
</div>
</div>
</modal>
</th>
<th></th>
<th colspan="4"></th>
<th colspan="6"></th>
<th colspan="6"></th>
<th></th>
</tr>
</tfoot>
</table>
</template>
<script>
import backend from '@/audio/backend'
import auth from '@/auth'
import TrackFavoriteIcon from '@/components/favorites/TrackFavoriteIcon'
import PlayButton from '@/components/audio/PlayButton'
import Modal from '@/components/semantic/Modal'
export default {
props: {
tracks: {type: Array, required: true},
displayPosition: {type: Boolean, default: false}
},
components: {
Modal,
TrackFavoriteIcon,
PlayButton
},
data () {
return {
backend: backend
backend: backend,
auth: auth,
showDownloadModal: false
}
}
}
......
......@@ -34,7 +34,7 @@
</div>
<div class="ui vertical stripe segment">
<h2>Tracks</h2>
<track-table v-if="album" display-position="true" :tracks="album.tracks"></track-table>
<track-table v-if="album" :display-position="true" :tracks="album.tracks"></track-table>
</div>
</template>
</div>
......
<template>
<div :class="['ui', {'active': show}, 'modal']">
<i class="close icon"></i>
<slot>
</slot>
</div>
</template>
<script>
import $ from 'jquery'
export default {
props: {
show: {type: Boolean, required: true}
},
data () {
return {
control: null
}
},
mounted () {
this.control = $(this.$el).modal({
onApprove: function () {
this.$emit('approved')
}.bind(this),
onDeny: function () {
this.$emit('deny')
}.bind(this),
onHidden: function () {
this.$emit('update:show', false)
}.bind(this)
})
},
watch: {
show: {
handler (newValue) {
if (newValue) {
this.control.modal('show')
} else {
this.control.modal('hide')
}
}
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
</style>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment