From db7662261aebb7cf3fa399ab37f2f9de244ea953 Mon Sep 17 00:00:00 2001 From: Blaine Jester Date: Tue, 2 Aug 2022 14:06:38 -0700 Subject: [PATCH 1/2] Call ceiling on file duration --- .../contentcuration/frontend/shared/vuex/file/utils.js | 2 +- contentcuration/contentcuration/tests/viewsets/test_file.py | 3 +++ contentcuration/contentcuration/viewsets/file.py | 6 +++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/contentcuration/contentcuration/frontend/shared/vuex/file/utils.js b/contentcuration/contentcuration/frontend/shared/vuex/file/utils.js index 8b1764cc0e..64c9b900c8 100644 --- a/contentcuration/contentcuration/frontend/shared/vuex/file/utils.js +++ b/contentcuration/contentcuration/frontend/shared/vuex/file/utils.js @@ -92,7 +92,7 @@ export function extractMetadata(file, preset = null) { const mediaElement = document.createElement(isVideo ? 'video' : 'audio'); // Add a listener to read the metadata once it has loaded. mediaElement.addEventListener('loadedmetadata', () => { - metadata.duration = mediaElement.duration; + metadata.duration = Math.ceil(mediaElement.duration); // Override preset based off video resolution if (isVideo) { metadata.preset = diff --git a/contentcuration/contentcuration/tests/viewsets/test_file.py b/contentcuration/contentcuration/tests/viewsets/test_file.py index 6b3394ad01..a64099fba9 100644 --- a/contentcuration/contentcuration/tests/viewsets/test_file.py +++ b/contentcuration/contentcuration/tests/viewsets/test_file.py @@ -390,6 +390,7 @@ def setUp(self): "name": "le_studio", "file_format": file_formats.MP3, "preset": format_presets.AUDIO, + "duration": 10.123 } def test_required_keys(self): @@ -414,3 +415,5 @@ def test_upload_url(self): self.client.force_authenticate(user=self.user) response = self.client.post(reverse("file-upload-url"), self.file, format="json",) self.assertEqual(response.status_code, 200) + file = models.File.objects.get(checksum=self.file["checksum"]) + self.assertEqual(11, file.duration) diff --git a/contentcuration/contentcuration/viewsets/file.py b/contentcuration/contentcuration/viewsets/file.py index b594a55bc9..d16071cddd 100644 --- a/contentcuration/contentcuration/viewsets/file.py +++ b/contentcuration/contentcuration/viewsets/file.py @@ -1,4 +1,5 @@ import codecs +import math from django.core.exceptions import PermissionDenied from django.http import HttpResponseBadRequest @@ -156,6 +157,9 @@ def upload_url(self, request): retval = get_presigned_upload_url( filepath, checksum_base64, 600, content_length=size ) + duration = request.data.get("duration") + if duration is not None: + duration = math.ceil(duration) file = File( file_size=size, @@ -165,7 +169,7 @@ def upload_url(self, request): file_format_id=file_format, preset_id=preset, uploaded_by=request.user, - duration=request.data.get("duration"), + duration=duration, ) # Avoid using our file_on_disk attribute for checks From d36e3349fb9fd69dd5a5a37d4282a1d874639f99 Mon Sep 17 00:00:00 2001 From: Blaine Jester Date: Tue, 2 Aug 2022 14:41:56 -0700 Subject: [PATCH 2/2] Make sure duration is numeric --- .../contentcuration/tests/viewsets/test_file.py | 10 ++++++++++ contentcuration/contentcuration/viewsets/file.py | 9 ++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/contentcuration/contentcuration/tests/viewsets/test_file.py b/contentcuration/contentcuration/tests/viewsets/test_file.py index a64099fba9..be19e660af 100644 --- a/contentcuration/contentcuration/tests/viewsets/test_file.py +++ b/contentcuration/contentcuration/tests/viewsets/test_file.py @@ -403,6 +403,16 @@ def test_required_keys(self): self.assertEqual(response.status_code, 400) + def test_duration_invalid(self): + self.file["duration"] = '1.23' + + self.client.force_authenticate(user=self.user) + response = self.client.post( + reverse("file-upload-url"), self.file, format="json", + ) + + self.assertEqual(response.status_code, 400) + def test_insufficient_storage(self): self.file["size"] = 100000000000000 diff --git a/contentcuration/contentcuration/viewsets/file.py b/contentcuration/contentcuration/viewsets/file.py index d16071cddd..de64dfa935 100644 --- a/contentcuration/contentcuration/viewsets/file.py +++ b/contentcuration/contentcuration/viewsets/file.py @@ -143,6 +143,12 @@ def upload_url(self, request): reason="Must specify: size, checksum, name, file_format, and preset" ) + duration = request.data.get("duration") + if duration is not None: + if not isinstance(duration, (int, float)): + return HttpResponseBadRequest(reason="File duration must be a number") + duration = math.ceil(duration) + try: request.user.check_space(float(size), checksum) except PermissionDenied: @@ -157,9 +163,6 @@ def upload_url(self, request): retval = get_presigned_upload_url( filepath, checksum_base64, 600, content_length=size ) - duration = request.data.get("duration") - if duration is not None: - duration = math.ceil(duration) file = File( file_size=size,