diff --git a/inventree_wireviz/serializers.py b/inventree_wireviz/serializers.py
index 749cec4..4ddd84b 100644
--- a/inventree_wireviz/serializers.py
+++ b/inventree_wireviz/serializers.py
@@ -1,9 +1,11 @@
"""DRF serializers for the wireviz plugin."""
import os
+import yaml
from django.conf import settings
from rest_framework import serializers
+from rest_framework.exceptions import ValidationError
from part.models import Part
from plugin.registry import registry
@@ -85,6 +87,42 @@ def save(self, user=None, **kwargs):
mgr.import_harness(wv_file, part, user)
+class UploadTemplateSerializer(serializers.Serializer):
+ """Serializer for uploading a wireviz template file."""
+
+ template = serializers.FileField(
+ label="Template file",
+ help_text="Upload a wireviz template file",
+ required=True,
+ )
+
+ def validate_template(self, template):
+ """Validate template file."""
+
+ if not template.name.endswith('.wireviz'):
+ raise ValidationError("File must be .wireviz file")
+
+ data = template.file.read().decode('utf-8')
+
+ try:
+ yaml.safe_load(data)
+ except yaml.YAMLError:
+ raise ValidationError("Invalid YAML file")
+
+ return template
+
+ def save(self, **kwargs):
+ """Save the uploaded wireviz template file."""
+
+ template = self.validated_data['template']
+
+ filename = template_path(template.name)
+
+ with open(filename, 'w') as output:
+ template.file.seek(0)
+ output.write(template.file.read().decode('utf-8'))
+
+
class DeleteTemplateSerializer(serializers.Serializer):
"""Serializer for deleting a wireviz template file."""
diff --git a/inventree_wireviz/templates/wireviz/settings_panel.html b/inventree_wireviz/templates/wireviz/settings_panel.html
index 239ae8c..ba479e1 100644
--- a/inventree_wireviz/templates/wireviz/settings_panel.html
+++ b/inventree_wireviz/templates/wireviz/settings_panel.html
@@ -38,4 +38,6 @@
WireViz Templates
{% endif %}
+
+
\ No newline at end of file
diff --git a/inventree_wireviz/templates/wireviz/upload_script.html b/inventree_wireviz/templates/wireviz/upload_script.html
index c62c559..bff57a3 100644
--- a/inventree_wireviz/templates/wireviz/upload_script.html
+++ b/inventree_wireviz/templates/wireviz/upload_script.html
@@ -58,6 +58,27 @@
);
}
+ function uploadWirevizTemplate() {
+
+ const url = "/plugin/wireviz/upload-template/";
+
+ let fields = {
+ 'template': {
+ required: true,
+ label: 'Template File',
+ type: 'file upload',
+ help_text: 'Select a Wireviz template file to upload',
+ }
+ };
+
+ constructCreateForm(fields, {
+ url: url,
+ method: 'POST',
+ fields: fields,
+ title: 'Upload WireViz Template'
+ });
+ }
+
function deleteWirevizTemplate(templateName) {
diff --git a/inventree_wireviz/views.py b/inventree_wireviz/views.py
index 7e15df0..b1d1dd0 100644
--- a/inventree_wireviz/views.py
+++ b/inventree_wireviz/views.py
@@ -4,7 +4,7 @@
from rest_framework.views import APIView
from rest_framework.response import Response
-from .serializers import DeleteTemplateSerializer, WirevizDeleteSerializer, WirevizUploadSerializer
+from .serializers import DeleteTemplateSerializer, UploadTemplateSerializer, WirevizDeleteSerializer, WirevizUploadSerializer
class UploadWirevizView(APIView):
@@ -39,6 +39,22 @@ def post(self, request, *args, **kwargs):
return Response(serializer.data, status=201)
+class UploadTemplateView(APIView):
+ """View for uploading a wireviz template file."""
+
+ permission_classes = [permissions.IsAdminUser]
+
+ def post(self, request, *args, **kwargs):
+ """Handle POST request."""
+
+ serializer = UploadTemplateSerializer(data=request.data)
+ serializer.is_valid(raise_exception=True)
+
+ serializer.save()
+
+ return Response(serializer.data, status=201)
+
+
class DeleteTemplateView(APIView):
"""View for deleting a wireviz template file."""
diff --git a/inventree_wireviz/wireviz.py b/inventree_wireviz/wireviz.py
index 87cd6d0..2c3e3a2 100644
--- a/inventree_wireviz/wireviz.py
+++ b/inventree_wireviz/wireviz.py
@@ -213,6 +213,7 @@ def setup_urls(self):
return [
path('upload/', views.UploadWirevizView.as_view(), name='wireviz-file-upload'),
path('delete/', views.DeleteWirevizView.as_view(), name='wireviz-file-delete'),
+ path('upload-template/', views.UploadTemplateView.as_view(), name='wireviz-upload-template'),
path('delete-template/', views.DeleteTemplateView.as_view(), name='wireviz-delete-template'),
]