diff --git a/README.md b/README.md index a741551..97acf9a 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Release-Tag oder ein bestimmter Commit verwendet werden: ```bash /opt/netbox/venv/bin/pip install --upgrade --force-reinstall \ - "git+https://git.mrblake.cc/MrBlake/Netbox-Utilities.git@v0.6.0" + "git+https://git.mrblake.cc/MrBlake/Netbox-Utilities.git@v0.6.1" ``` Alternativ kann hinter dem `@` die vollständige Commit-ID stehen. @@ -179,7 +179,7 @@ Einzel-Upload durch **Mehrere Bilder hochladen** ersetzt. Im Dateidialog können bis zu 50 Bilder gemeinsam ausgewählt werden. Vor dem Speichern zeigt das Plugin Vorschaubilder und die jeweiligen Dateinamen an. -Alle Dateien werden zunächst mit NetBox' eigener Bildvalidierung geprüft. Ist +Jede Datei wird genau einmal mit NetBox' eigener Bildvalidierung geprüft. Ist eine Datei ungültig, wird kein Bild aus dieser Auswahl gespeichert. Eine optionale gemeinsame Beschreibung kann auf alle Bilder angewendet werden; als Anzeigename bleibt der jeweilige ursprüngliche Dateiname erhalten. Benötigt diff --git a/netbox_utilities/__init__.py b/netbox_utilities/__init__.py index 0a9fd71..3c8002c 100644 --- a/netbox_utilities/__init__.py +++ b/netbox_utilities/__init__.py @@ -1,6 +1,6 @@ from netbox.plugins import PluginConfig, get_plugin_config -__version__ = "0.6.0" +__version__ = "0.6.1" class NetBoxUtilitiesConfig(PluginConfig): diff --git a/netbox_utilities/forms.py b/netbox_utilities/forms.py index 636a2d9..e8fa67c 100644 --- a/netbox_utilities/forms.py +++ b/netbox_utilities/forms.py @@ -11,7 +11,7 @@ class MultipleImageInput(forms.ClearableFileInput): allow_multiple_selected = True -class MultipleImageField(forms.ImageField): +class MultipleFileField(forms.FileField): widget = MultipleImageInput def clean(self, data, initial=None): @@ -22,7 +22,7 @@ class MultipleImageField(forms.ImageField): class BulkImageUploadForm(forms.Form): - images = MultipleImageField( + images = MultipleFileField( label="Bilder", widget=MultipleImageInput( attrs={ diff --git a/netbox_utilities/tests/test_bulk_image_form.py b/netbox_utilities/tests/test_bulk_image_form.py index 0bbcde4..c87bc57 100644 --- a/netbox_utilities/tests/test_bulk_image_form.py +++ b/netbox_utilities/tests/test_bulk_image_form.py @@ -3,6 +3,7 @@ from io import BytesIO from django.core.files.uploadedfile import SimpleUploadedFile from django.test import SimpleTestCase from django.utils.datastructures import MultiValueDict +from extras.forms import ImageAttachmentForm from PIL import Image from netbox_utilities.forms import BulkImageUploadForm @@ -10,10 +11,11 @@ from netbox_utilities.forms import BulkImageUploadForm class BulkImageUploadFormTest(SimpleTestCase): @staticmethod - def _image(name): + def _image(name, image_format="PNG"): content = BytesIO() - Image.new("RGB", (2, 2), "white").save(content, format="PNG") - return SimpleUploadedFile(name, content.getvalue(), content_type="image/png") + Image.new("RGB", (2, 2), "white").save(content, format=image_format) + content_type = "image/jpeg" if image_format == "JPEG" else "image/png" + return SimpleUploadedFile(name, content.getvalue(), content_type=content_type) def test_accepts_multiple_images(self): files = MultiValueDict({"images": [self._image("front.png"), self._image("rear.png")]}) @@ -24,6 +26,22 @@ class BulkImageUploadFormTest(SimpleTestCase): self.assertEqual(len(form.cleaned_data["images"]), 2) self.assertEqual(form.cleaned_data["description"], "Dokumentation") + def test_jpegs_are_validated_once_by_netbox(self): + files = MultiValueDict( + { + "images": [ + self._image("front.JPG", "JPEG"), + self._image("rear.jpg", "JPEG"), + ] + } + ) + form = BulkImageUploadForm(data={}, files=files) + + self.assertTrue(form.is_valid(), form.errors) + for image in form.cleaned_data["images"]: + image.seek(0) + self.assertIsNotNone(ImageAttachmentForm.base_fields["image"].clean(image)) + def test_requires_at_least_one_image(self): form = BulkImageUploadForm(data={}, files={}) diff --git a/netbox_utilities/views.py b/netbox_utilities/views.py index 979eb4b..27c496d 100644 --- a/netbox_utilities/views.py +++ b/netbox_utilities/views.py @@ -109,14 +109,18 @@ class BulkImageUploadView(ContentTypePermissionRequiredMixin, View): @staticmethod def _build_image_forms(parent, cleaned_data): - return [ - ImageAttachmentForm( - data={"name": "", "description": cleaned_data["description"]}, - files={"image": image}, - instance=ImageAttachment(parent=parent), + image_forms = [] + for image in cleaned_data["images"]: + if hasattr(image, "seek"): + image.seek(0) + image_forms.append( + ImageAttachmentForm( + data={"name": "", "description": cleaned_data["description"]}, + files={"image": image}, + instance=ImageAttachment(parent=parent), + ) ) - for image in cleaned_data["images"] - ] + return image_forms def _return_url(self, request, parent): candidate = request.POST.get("return_url") or request.GET.get("return_url") diff --git a/pyproject.toml b/pyproject.toml index 1683b32..cbcaac6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "netbox-utilities" -version = "0.6.0" +version = "0.6.1" description = "Navigation, tenant utilities, bulk image/module upload, and atomic rack reordering for NetBox 4.6" readme = "README.md" requires-python = ">=3.12"