From f4ac0b2d3fc0f3ea665336ad010d25580b93b694 Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Sat, 21 Apr 2018 18:21:15 +0200 Subject: [PATCH] Serve view can now serve in-place imported files --- api/funkwhale_api/music/models.py | 20 ++++++++++++++++++++ api/funkwhale_api/music/views.py | 15 ++++++++++++--- api/tests/music/test_views.py | 19 +++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/api/funkwhale_api/music/models.py b/api/funkwhale_api/music/models.py index 18f181e8..98fc1965 100644 --- a/api/funkwhale_api/music/models.py +++ b/api/funkwhale_api/music/models.py @@ -463,6 +463,26 @@ class TrackFile(models.Model): self.mimetype = utils.guess_mimetype(self.audio_file) return super().save(**kwargs) + @property + def serve_from_source_path(self): + if not self.source or not self.source.startswith('file://'): + raise ValueError('Cannot serve this file from source') + serve_path = settings.MUSIC_DIRECTORY_SERVE_PATH + prefix = settings.MUSIC_DIRECTORY_PATH + if not serve_path or not prefix: + raise ValueError( + 'You need to specify MUSIC_DIRECTORY_SERVE_PATH and ' + 'MUSIC_DIRECTORY_PATH to serve in-place imported files' + ) + file_path = self.source.replace('file://', '', 1) + parts = os.path.split(file_path.replace(prefix, '', 1)) + if parts[0] == '/': + parts = parts[1:] + return os.path.join( + serve_path, + *parts + ) + IMPORT_STATUS_CHOICES = ( ('pending', 'Pending'), diff --git a/api/funkwhale_api/music/views.py b/api/funkwhale_api/music/views.py index f961e3fd..d03b55e5 100644 --- a/api/funkwhale_api/music/views.py +++ b/api/funkwhale_api/music/views.py @@ -224,12 +224,21 @@ class TrackFileViewSet(viewsets.ReadOnlyModelViewSet): library_track = qs.get(pk=library_track.pk) library_track.download_audio() audio_file = library_track.audio_file + file_path = '{}{}'.format( + settings.PROTECT_FILES_PATH, + audio_file.url) mt = library_track.audio_mimetype + elif audio_file: + file_path = '{}{}'.format( + settings.PROTECT_FILES_PATH, + audio_file.url) + elif f.source and f.source.startswith('file://'): + file_path = '{}{}'.format( + settings.PROTECT_FILES_PATH + '/music', + f.serve_from_source_path) response = Response() filename = f.filename - response['X-Accel-Redirect'] = "{}{}".format( - settings.PROTECT_FILES_PATH, - audio_file.url) + response['X-Accel-Redirect'] = file_path filename = "filename*=UTF-8''{}".format( urllib.parse.quote(filename)) response["Content-Disposition"] = "attachment; {}".format(filename) diff --git a/api/tests/music/test_views.py b/api/tests/music/test_views.py index 81f34fbe..95c56d91 100644 --- a/api/tests/music/test_views.py +++ b/api/tests/music/test_views.py @@ -93,6 +93,25 @@ def test_can_proxy_remote_track( assert library_track.audio_file.read() == b'test' +def test_can_serve_in_place_imported_file( + factories, settings, api_client, r_mock): + settings.PROTECT_AUDIO_FILES = False + settings.MUSIC_DIRECTORY_SERVE_PATH = '/host/music' + settings.MUSIC_DIRECTORY_PATH = '/music' + settings.MUSIC_DIRECTORY_PATH = '/music' + track_file = factories['music.TrackFile']( + in_place=True, + source='file:///music/test.ogg') + + response = api_client.get(track_file.path) + + assert response.status_code == 200 + assert response['X-Accel-Redirect'] == '{}{}'.format( + settings.PROTECT_FILES_PATH, + '/music/host/music/test.ogg' + ) + + def test_can_create_import_from_federation_tracks( factories, superuser_api_client, mocker): lts = factories['federation.LibraryTrack'].create_batch(size=5) -- GitLab