diff --git a/client/src/app/shared/components/media-upload-content/media-upload-content.component.html b/client/src/app/shared/components/media-upload-content/media-upload-content.component.html
index d6bdae870..4cc4a808e 100644
--- a/client/src/app/shared/components/media-upload-content/media-upload-content.component.html
+++ b/client/src/app/shared/components/media-upload-content/media-upload-content.component.html
@@ -54,7 +54,10 @@
File information |
- insert_drive_file {{ file.mediafile.type }}
+
+ insert_drive_file
+ {{ getFiletype(file.mediafile) | translate }}
+
data_usage
{{ getReadableSize(file.mediafile.size) }}
diff --git a/client/src/app/shared/components/media-upload-content/media-upload-content.component.ts b/client/src/app/shared/components/media-upload-content/media-upload-content.component.ts
index 94bf3ae62..9940d702e 100644
--- a/client/src/app/shared/components/media-upload-content/media-upload-content.component.ts
+++ b/client/src/app/shared/components/media-upload-content/media-upload-content.component.ts
@@ -158,14 +158,27 @@ export class MediaUploadContentComponent implements OnInit {
}
/**
- * Converts a file size in bit into human readable format
+ * Returns the filetype from the file or a generic "File", if the type could
+ * not be determinated.
*
- * @param bits file size in bits
+ * @param file The file to get the type from.
+ */
+ public getFiletype(file: File): string {
+ return file.type || 'File';
+ }
+
+ /**
+ * Converts a file size in byte into human readable format
+ *
+ * @param bytes file size in bytes
* @returns a readable file size representation
*/
- public getReadableSize(bits: number): string {
- const unitLevel = Math.floor(Math.log(bits) / Math.log(1024));
- const bytes = +(bits / Math.pow(1024, unitLevel)).toFixed(2);
+ public getReadableSize(bytes: number): string {
+ if (bytes === 0) {
+ return '0 B';
+ }
+ const unitLevel = Math.floor(Math.log(bytes) / Math.log(1024));
+ bytes = +(bytes / Math.pow(1024, unitLevel)).toFixed(2);
return `${bytes} ${['B', 'kB', 'MB', 'GB', 'TB'][unitLevel]}`;
}
diff --git a/client/src/app/site/mediafiles/components/mediafile-list/mediafile-list.component.html b/client/src/app/site/mediafiles/components/mediafile-list/mediafile-list.component.html
index 3e6118c42..921ba1860 100644
--- a/client/src/app/site/mediafiles/components/mediafile-list/mediafile-list.component.html
+++ b/client/src/app/site/mediafiles/components/mediafile-list/mediafile-list.component.html
@@ -111,7 +111,7 @@
{{ mediafile.filename }}
- {{ getDateFromTimestamp(mediafile.timestamp) }} · {{ mediafile.size }}
+ {{ getDateFromTimestamp(mediafile.timestamp) }} · {{ mediafile.filesize }}
diff --git a/openslides/mediafiles/models.py b/openslides/mediafiles/models.py
index 53956a696..9898f5cb5 100644
--- a/openslides/mediafiles/models.py
+++ b/openslides/mediafiles/models.py
@@ -103,14 +103,27 @@ class Mediafile(RESTModelMixin, ListOfSpeakersMixin, models.Model):
"""
`unique_together` is not working with foreign keys with possible `null` values.
So we do need to check this here.
+
+ self.original_filename is not yet set, but if is_file is True, the actual
+ filename is self.mediafile.file
"""
+ title_or_original_filename = models.Q(title=self.title)
+ if self.is_file:
+ title_or_original_filename = title_or_original_filename | models.Q(
+ original_filename=self.mediafile.name
+ )
+
if (
- Mediafile.objects.exclude(pk=self.pk)
- .filter(title=self.title, parent=self.parent)
+ Mediafile.objects.exclude(
+ pk=self.pk
+ ) # self.pk is None on creation, but this does not invalidate the exclude statement.
+ .filter(title_or_original_filename, parent=self.parent)
.exists()
):
raise ValidationError(
- {"detail": "A mediafile with this title already exists in this folder."}
+ {
+ "detail": "A mediafile with this title or filename already exists in this folder."
+ }
)
def __str__(self):
diff --git a/tests/integration/mediafiles/test_viewset.py b/tests/integration/mediafiles/test_viewset.py
index 4d5617745..1db7c1875 100644
--- a/tests/integration/mediafiles/test_viewset.py
+++ b/tests/integration/mediafiles/test_viewset.py
@@ -70,7 +70,35 @@ class TestCreation(TestCase):
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertFalse(Mediafile.objects.exists())
- def test_mediafile_twice(self):
+ def test_no_extension(self):
+ file = SimpleUploadedFile("no_extension", b"some content.")
+ response = self.client.post(
+ reverse("mediafile-list"),
+ {"title": "test_title_vai8oDogohheideedie4", "mediafile": file},
+ )
+ self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+ mediafile = Mediafile.objects.get()
+ self.assertEqual(mediafile.title, "test_title_vai8oDogohheideedie4")
+
+ def test_mediafile_twice_different_title(self):
+ file1 = SimpleUploadedFile("file.ext", b"some content.")
+ file2 = SimpleUploadedFile("file.ext", b"some content.")
+ response = self.client.post(
+ reverse("mediafile-list"),
+ {"title": "test_title_Zeicheipeequie3ohfid", "mediafile": file1},
+ )
+ self.assertEqual(response.status_code, status.HTTP_201_CREATED)
+ mediafile = Mediafile.objects.get()
+ self.assertEqual(mediafile.title, "test_title_Zeicheipeequie3ohfid")
+
+ response = self.client.post(
+ reverse("mediafile-list"),
+ {"title": "test_title_aiChaetohs0quicee9eb", "mediafile": file2},
+ )
+ self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
+ self.assertEqual(Mediafile.objects.count(), 1)
+
+ def test_directory_twice(self):
title = "test_title_kFJq83fjmqo2babfqk3f"
Mediafile.objects.create(is_directory=True, title=title)
response = self.client.post(
|