From 0efdb6d98088c6a143f3fa6cece38c7d3911dba4 Mon Sep 17 00:00:00 2001 From: Vierkantor Date: Tue, 29 Jan 2019 09:32:35 +0100 Subject: [PATCH] Resolve "In-place imports cannot be transcoded" --- api/funkwhale_api/music/models.py | 15 ++++++++++++--- api/funkwhale_api/music/utils.py | 4 ++++ api/tests/music/test_views.py | 26 ++++++++++++++++++++++++++ changes/changelog.d/688.bugfix | 1 + 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 changes/changelog.d/688.bugfix diff --git a/api/funkwhale_api/music/models.py b/api/funkwhale_api/music/models.py index 325cdacec..4ba832717 100644 --- a/api/funkwhale_api/music/models.py +++ b/api/funkwhale_api/music/models.py @@ -7,6 +7,7 @@ import uuid import markdown import pendulum +import pydub from django.conf import settings from django.contrib.postgres.fields import JSONField from django.core.files.base import ContentFile @@ -780,6 +781,15 @@ class Upload(models.Model): "size": self.get_file_size(), } + def get_audio_segment(self): + input = self.get_audio_file() + if not input: + return + + input_format = utils.MIMETYPE_TO_EXTENSION[self.mimetype] + audio = pydub.AudioSegment.from_file(input, format=input_format) + return audio + def save(self, **kwargs): if not self.mimetype: if self.audio_file: @@ -824,10 +834,9 @@ class Upload(models.Model): 0 ] + ".{}".format(format) version.audio_file.save(new_name, f) - utils.transcode_file( - input=self.audio_file, + utils.transcode_audio( + audio=self.get_audio_segment(), output=version.audio_file, - input_format=utils.MIMETYPE_TO_EXTENSION[self.mimetype], output_format=utils.MIMETYPE_TO_EXTENSION[mimetype], ) version.size = version.audio_file.size diff --git a/api/funkwhale_api/music/utils.py b/api/funkwhale_api/music/utils.py index ae5cda750..574f4c8e1 100644 --- a/api/funkwhale_api/music/utils.py +++ b/api/funkwhale_api/music/utils.py @@ -75,5 +75,9 @@ def get_actor_from_request(request): def transcode_file(input, output, input_format, output_format, **kwargs): with input.open("rb"): audio = pydub.AudioSegment.from_file(input, format=input_format) + return transcode_audio(audio, output, output_format, **kwargs) + + +def transcode_audio(audio, output, output_format, **kwargs): with output.open("wb"): return audio.export(output, format=output_format, **kwargs) diff --git a/api/tests/music/test_views.py b/api/tests/music/test_views.py index aa1214f83..85ba2955a 100644 --- a/api/tests/music/test_views.py +++ b/api/tests/music/test_views.py @@ -374,6 +374,32 @@ def test_listen_transcode(factories, now, logged_in_api_client, mocker): ) +@pytest.mark.parametrize("serve_path", [("/host/music",), ("/app/music",)]) +def test_listen_transcode_in_place( + serve_path, factories, now, logged_in_api_client, mocker, settings +): + settings.MUSIC_DIRECTORY_PATH = "/app/music" + settings.MUSIC_DIRECTORY_SERVE_PATH = serve_path + upload = factories["music.Upload"]( + import_status="finished", + library__actor__user=logged_in_api_client.user, + audio_file=None, + source="file://" + os.path.join(DATA_DIR, "test.ogg"), + ) + + assert upload.get_audio_segment() + + url = reverse("api:v1:listen-detail", kwargs={"uuid": upload.track.uuid}) + handle_serve = mocker.spy(views, "handle_serve") + response = logged_in_api_client.get(url, {"to": "mp3"}) + + assert response.status_code == 200 + + handle_serve.assert_called_once_with( + upload, user=logged_in_api_client.user, format="mp3" + ) + + def test_user_can_create_library(factories, logged_in_api_client): actor = logged_in_api_client.user.create_actor() url = reverse("api:v1:libraries-list") diff --git a/changes/changelog.d/688.bugfix b/changes/changelog.d/688.bugfix new file mode 100644 index 000000000..085f205cd --- /dev/null +++ b/changes/changelog.d/688.bugfix @@ -0,0 +1 @@ +Fix transcoding of in-place imported tracks (#688)