Просмотр исходного кода

Add ability to toggle the inclusion of device images when rendering a rack elevation SVG

Jeremy Stretch 6 лет назад
Родитель
Сommit
ba6562a5db

+ 7 - 0
netbox/dcim/api/serializers.py

@@ -186,6 +186,9 @@ class RackElevationDetailFilterSerializer(serializers.Serializer):
     unit_height = serializers.IntegerField(
         default=RACK_ELEVATION_UNIT_HEIGHT_DEFAULT
     )
+    legend_width = serializers.IntegerField(
+        default=RACK_ELEVATION_LEGEND_WIDTH_DEFAULT
+    )
     exclude = serializers.IntegerField(
         required=False,
         default=None
@@ -194,6 +197,10 @@ class RackElevationDetailFilterSerializer(serializers.Serializer):
         required=False,
         default=True
     )
+    include_images = serializers.BooleanField(
+        required=False,
+        default=True
+    )
 
 
 #

+ 7 - 1
netbox/dcim/api/views.py

@@ -220,7 +220,13 @@ class RackViewSet(CustomFieldModelViewSet):
 
         if data['render'] == 'svg':
             # Render and return the elevation as an SVG drawing with the correct content type
-            drawing = rack.get_elevation_svg(data['face'], data['unit_width'], data['unit_height'])
+            drawing = rack.get_elevation_svg(
+                face=data['face'],
+                unit_width=data['unit_width'],
+                unit_height=data['unit_height'],
+                legend_width=data['legend_width'],
+                include_images=data['include_images']
+            )
             return HttpResponse(drawing.tostring(), content_type='image/svg+xml')
 
         else:

+ 11 - 8
netbox/dcim/elevations.py

@@ -11,9 +11,13 @@ from .choices import DeviceFaceChoices
 class RackElevationSVG:
     """
     Use this class to render a rack elevation as an SVG image.
+
+    :param rack: A NetBox Rack instance
+    :param include_images: If true, the SVG document will embed front/rear device face images, where available
     """
-    def __init__(self, rack):
+    def __init__(self, rack, include_images=True):
         self.rack = rack
+        self.include_images = include_images
 
     @staticmethod
     def _add_gradient(drawing, id_, color):
@@ -46,8 +50,7 @@ class RackElevationSVG:
 
         return drawing
 
-    @staticmethod
-    def _draw_device_front(drawing, device, start, end, text):
+    def _draw_device_front(self, drawing, device, start, end, text):
         name = str(device)
         if device.devicebay_count:
             name += ' ({}/{})'.format(device.get_children().count(), device.devicebay_count)
@@ -69,14 +72,13 @@ class RackElevationSVG:
         link.add(drawing.text(str(name), insert=text, fill=hex_color))
 
         # Embed front device type image if one exists
-        if device.device_type.front_image:
+        if self.include_images and device.device_type.front_image:
             url = device.device_type.front_image.url
             image = drawing.image(href=url, insert=start, size=end, class_='device-image')
             image.stretch()
             link.add(image)
 
-    @staticmethod
-    def _draw_device_rear(drawing, device, start, end, text):
+    def _draw_device_rear(self, drawing, device, start, end, text):
         rect = drawing.rect(start, end, class_="slot blocked")
         rect.set_desc('{} — {} ({}U) {} {}'.format(
             device.device_role, device.device_type.display_name,
@@ -86,7 +88,7 @@ class RackElevationSVG:
         drawing.add(drawing.text(str(device), insert=text))
 
         # Embed rear device type image if one exists
-        if device.device_type.front_image:
+        if self.include_images and device.device_type.front_image:
             url = device.device_type.rear_image.url
             image = drawing.image(href=url, insert=start, size=end, class_='device-image')
             image.stretch()
@@ -128,11 +130,12 @@ class RackElevationSVG:
 
         return elevation
 
-    def render(self, reserved_units, face, unit_width, unit_height, legend_width):
+    def render(self, face, unit_width, unit_height, legend_width):
         """
         Return an SVG document representing a rack elevation.
         """
         drawing = self._setup_drawing(unit_width + legend_width, unit_height * self.rack.u_height)
+        reserved_units = self.rack.get_reserved_units()
 
         unit_cursor = 0
         for ru in range(0, self.rack.u_height):

+ 5 - 4
netbox/dcim/models/__init__.py

@@ -666,7 +666,8 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
             face=DeviceFaceChoices.FACE_FRONT,
             unit_width=RACK_ELEVATION_UNIT_WIDTH_DEFAULT,
             unit_height=RACK_ELEVATION_UNIT_HEIGHT_DEFAULT,
-            legend_width=RACK_ELEVATION_LEGEND_WIDTH_DEFAULT
+            legend_width=RACK_ELEVATION_LEGEND_WIDTH_DEFAULT,
+            include_images=True
     ):
         """
         Return an SVG of the rack elevation
@@ -676,11 +677,11 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
         :param unit_height: Height of each rack unit for the rendered drawing. Note this is not the total
             height of the elevation
         :param legend_width: Width of the unit legend, in pixels
+        :param include_images: Embed front/rear device images where available
         """
-        elevation = RackElevationSVG(self)
-        reserved_units = self.get_reserved_units()
+        elevation = RackElevationSVG(self, include_images=include_images)
 
-        return elevation.render(reserved_units, face, unit_width, unit_height, legend_width)
+        return elevation.render(face, unit_width, unit_height, legend_width)
 
     def get_0u_devices(self):
         return self.devices.filter(position=0)