
    >Tf5                        d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ dZ dZ!dZ"dZ#dZ$d Z%d Z& G d d          Z'dS )    N)	Hyperlink)Image)LinearGradient)Rect)Text)settings)
FieldError)Q)floatformat)reverse)	urlencode)
get_config)array_to_ranges)foreground_color)RACK_ELEVATION_BORDER_WIDTH)RackElevationSVGz#b0b0ffz#d7d7d7z#ffc0c0z#4d4dffc                    | j         r| j         j         d| j         }n#| j        r| j        }nt          | j                  }| j        rB|d                    |                                                                 | j                  z  }|S )N:z ({}/{}))	virtual_chassisnamevc_positionstrdevice_typedevicebay_countformatget_childrencount)devicer   s     3/var/www/html/netbox-4.1.3/netbox/dcim/svg/racks.pyget_device_namer        s     '(-DD0BDD	 '{6%&& Y
!!&"5"5"7"7"="="?"?AWXXXK    c                 4   d| j          }|d| j         z  }t          | j        j                   d}|d| j        j        j          d| j        j         d| dz  }| j        r|d| j         z  }| j        r|d	| j         z  }| j	        r|d
| j	         z  }|S )a6  
    Return a description for a device to be rendered in the rack elevation in the following format

    Name: <name>
    Role: <role>
    Device Type: <manufacturer> <model> (<u_height>)
    Asset tag: <asset_tag> (if defined)
    Serial: <serial> (if defined)
    Description: <description> (if defined)
    zName: z
Role: Uz
Device Type:  z ()z
Asset tag: z	
Serial: z
Description: )
r   roler   r   u_heightmanufacturermodel	asset_tagserialdescription)r   r,   r'   s      r   get_device_descriptionr-   -   s     )6;((K+fk+++Kf09::===HsV%7%D%IssFL^LdsshpssssK :9v'7999} 43FM333 >=);===r!   c                   z    e Zd ZdZ	 	 ddZed             Zd Zd ZddZ	d	 Z
d
 Zd Zd Zd Zd ZddZd ZdS )r   a  
    Use this class to render a rack elevation as an SVG image.

    :param rack: A NetBox Rack instance
    :param unit_width: Rendered unit width, in pixels
    :param unit_height: Rendered unit height, in pixels
    :param legend_width: Legend width, in pixels (where the unit labels appear)
    :param margin_width: Margin width, in pixels (where reservations appear)
    :param user: User instance. If specified, only devices viewable by this user will be fully displayed.
    :param include_images: If true, the SVG document will embed front/rear device face images, where available
    :param base_url: Base URL for links within the SVG document. If none, links will be relative.
    :param highlight_params: Iterable of two-tuples which identifies attributes of devices to highlight
    NTc
                 &   || _         || _        ||                    d          nd| _        t	                      }
|p|
j        | _        |p|
j        | _        |p|
j	        | _
        |p|
j        | _        | j         j        }||                    |d          }|                    dd          | _        g | _        |	rUt%                      }|	D ]\  }}|t%          di ||iz  }	 |                    |          | _        d S # t(          $ r Y d S w xY wd S )N/ viewpkT)flat )rackinclude_imagesrstripbase_urlr   !RACK_ELEVATION_DEFAULT_UNIT_WIDTH
unit_width"RACK_ELEVATION_DEFAULT_UNIT_HEIGHTunit_height#RACK_ELEVATION_DEFAULT_LEGEND_WIDTHlegend_width#RACK_ELEVATION_DEFAULT_MARGIN_WIDTHmargin_widthdevicesrestrictvalues_listpermitted_device_idshighlight_devicesr
   filterr	   )selfr6   r=   r;   r?   rA   userr7   r9   highlight_paramsconfigpermitted_devicesqkvs                  r   __init__zRackElevationSVG.__init__T   sQ   	,080D,,," $P(P&S&*S(VF,V(VF,V !I- 1 : :4 H H$5$A$A$T$A$R$R! "$ 	A( ! !1Q[[!Q[[ ):)A)A!)D)D&&&   	 	s   $D   
DDc                    t          ddd|dd          }|                    dd	           |                    d
d	           |                    d
|	           |                    d|	           | j                            |           d S )N)r   r   )r      repeatzrotate(45, 0, 0)userSpaceOnUse)startendspreadMethodid_gradientTransformgradientUnitsz0%z#f7f7f7)offsetcolorz50%z100%)r   add_stop_colordefsadd)drawingrX   r\   gradients       r   _add_gradientzRackElevationSVG._add_gradientr   s    !!0*
 
 
 	t9===uI>>>uE:::vU;;;"""""r!   c                 b   | j         | j        z   | j        z   t          dz  z   }| j        | j        j        z  t          dz  z   }t          j        ||f          }t          t          j         d          5 }|j                            |                    |                                                     d d d            n# 1 swxY w Y   t                               |dt$                     t                               |dt&                     t                               |dt(                     |S )N   )sizez/rack_elevation.cssreservedoccupiedblocked)r;   r?   rA   r   r=   r6   r'   svgwriteDrawingopenr   STATIC_ROOTr^   r_   stylereadr   rb   GRADIENT_RESERVEDGRADIENT_OCCUPIEDGRADIENT_BLOCKED)rH   widthheightr`   css_files        r   _setup_drawingzRackElevationSVG._setup_drawing   sD   $"33d6GGJehiJii!DI$669TWX9XX"888 X)>>>?? 	=8LW]]8==??;;<<<	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	&&w
<MNNN&&w
<MNNN&&w	;KLLLs   5A CCCc                 6   | j         t          z   }t          }| j        j        r(|t	          || j        j        z
  | j        z            z  }nL|t	          | j        j        |z
  | j        j        z   | j        z            t	          || j        z            z
  z  }||fS )zm
        Return the X, Y coordinates of the top left corner for a device in the specified rack unit.
        )r?   r   r6   
desc_unitsintstarting_unitr=   r'   )rH   positionrs   xys        r   _get_device_coordsz#RackElevationSVG._get_device_coords   s      ;;'9 	Dh!88D<LLMMMAAdi(83di6MMQUQaabbehiorv  sC  jC  fD  fD  D  DA!tr!   c                 >   t          |          }t          |          }|rdt          |           nd}|d         |d         dz  z   |d         |d         dz  z   f}	| j        o|| j        v}
|
rdnd}t	          | j         |                                 d	          }|                    |           |r-|                    t          ||d
| d|                      n(|                    t          ||d|                      |                    t          ||	|d|                      | j        r|r|j                            d          r| j         |j         n|j        }t          |||d|           }|                    d           |                    |           |                    t          ||	dddd|                      |                    t          ||	dd|                      | j                            |           d S )N#z#000000r   rd      z shadedr1   _parenthreftargetzfill: #slot)rm   class_zslot blockedr   label)insertfillr   r0   zdevice-image)r   r   re   r   slice)scaleblackz0.2emroundzdevice-image-label)r   strokestroke_widthstroke_linejoinr   white)r    r-   r   rF   r   r9   get_absolute_urlset_descr_   r   r   r7   url
startswithr   fitr`   )rH   r   coordsre   r\   imager   r,   
text_colortext_coords	is_shaded	css_extralinkr   s                 r   _draw_devicezRackElevationSVG._draw_device   s   v&&,V446;J2)%00222
1IQ!#1IQ!#
 *SvT=S/S	!*2II	 K0G0G0I0IKKT]^^^k"""  	LHHT&$.?.?.?HZyHZHZ[[[\\\\HHT&$/Ii/I/IJJJKKKd;ZH[PYH[H[\\\]]]  	5 	3893G3G3L3L[T]/EI///RWR[C1i11	  E IIGI$$$HHUOOOHHT+gGel<<<> > >   HHT+GDdYbDdDdeee   	r!   c                 j    |j         j        }|j        j        }|                     |||||           dS )z<
        Draw the front (mounted) face of a device.
        )r\   r   N)r&   r\   r   front_imager   )rH   r   r   re   r\   r   s         r   draw_device_frontz"RackElevationSVG.draw_device_front   s>     !".&&$e5IIIIIr!   c                 P    |j         j        }|                     ||||           dS )z<
        Draw the rear (opposite) face of a device.
        )r   N)r   
rear_imager   )rH   r   r   re   r   s        r   draw_device_rearz!RackElevationSVG.draw_device_rear   s2     "-&&$e<<<<<r!   c                     t           }t           dz  }t          | j        |z   |f| j        |z   | j        j        | j        z  |z   fd          }| j                            |           dS )zD
        Draw a border around the collection of rack units.
        rd   r6   )r   re   r   N)	r   r   r?   r;   r6   r'   r=   r`   r_   )rH   border_widthborder_offsetframes       r   draw_borderzRackElevationSVG.draw_border   sz     33a7%5}E/L0$)2DtGW2WZf2fg
 
 

 	r!   c                 t   t          d| j        j                  D ]}|| j        z  t          z   }| j        dz  || j        dz  z   t          z   f}| j        j        r|dz   n| j        j        |z
  }|| j        j        z   dz
  }| j        	                    t          t          |          |d                     dS )zU
        Draw the rack unit labels along the lefthand side of the elevation.
        r   rd   r   unitr   N)ranger6   r'   r=   r   r?   rw   ry   r`   r_   r   r   )rH   rustart_yposition_coordinatesr   s        r   draw_legendzRackElevationSVG.draw_legend   s     49-.. 	 	B4++.IIG$($5$97TEUXYEY;Y\w;w#x !Y1N266ty7IB7ND$)11A5DLSYY 4VDDD   	 	r!   c                    | j         j                                        D ]/}t          |j                  D ]}t          |          dk    rdn|d         dz   |d         z
  }|                     |d         |          }|d         | j        z   t          dz  z   |d         f}| j	        dz
  || j
        z  f}t          | j         |                                 d          }|                    d|j         d|j                    |                    t%          ||d	t&          d
                     | j                            |           1dS )zc
        Draw any rack reservations in the right-hand margin alongside the rack elevation.
        r   r   rd      r   r   zReservation #z: reservation)r   r   r   N)r6   reservationsallr   unitslenr}   r;   r   rA   r=   r   r9   r   r   r3   r,   r_   r   STROKE_RESERVEDr`   )rH   r   segmentr'   r   re   r   s          r   draw_marginzRackElevationSVG.draw_margin   st     915577 	' 	'K*;+<== ' ' #G 1 111wqzA~PQ
7R00XFF )do58SVW8WWY_`aYbc%)t// !&X8T8T8V8V&X&XajkkkYknYY@WYYZZZmObcddd     &&&&'	' 	'r!   c           
         t           | j        z   }d                    t          d          t	          | j        j        j        | j        j        r| j        j        j        nd| j        j        |d                    }t          d| j        j
                  D ]}| j        j        r|dz   n| j        j
        |z
  }|| j        j        z   dz
  }t           || j        z  z   }|| j        dz  z   || j        dz  z   f}t          |                    |          d	          }|                    t#          ||f| j        | j        fd
                     |                    t%          d|d                     | j                            |           dS )zd
        Draw the rack unit placeholders which form the "background" of the rack elevation.
        z{}?{}&position={{}}zdcim:device_addr1   )sitelocationr6   facer   r   rd   r   r   r   r   z
add devicez
add-device)r   r   N)r   r?   r   r   r   r6   r   r3   r   r   r'   rw   ry   r=   r;   r   r_   r   r   r`   )	rH   r   x_offset
url_stringr   r   y_offsetr   r   s	            r   draw_backgroundz RackElevationSVG.draw_background
  s    /1BB*11%&&	)59Y5GODI.11R		   
 

 49-.. 	# 	#B!Y1N266ty7IB7ND$)11A5D2R$:J5JJH4?Q..4+a//K
 *"3"3D"9"9)LLLDHHT8X.$BR0S\bcccdddHHT,{<PPPQQQLT""""	# 	#r!   Fc                 
   | j                             |d          D ]}|d         }|                    dt          j        d                    }|                     |d         |          }| j        t          | j        |z            f}|rK|j	        | j
        v r=|j        |k    r|s|                     |||           |                     |||           |r*| j                            t!          ||d                     d	S )
zK
        Draw any occupied rack units for the specified rack face.
        F)r   expand_devicesr   rs   g      ?idrh   r   N)r6   get_rack_unitsgetdecimalDecimalr}   r;   rx   r=   r3   rE   r   r   r   r`   r_   r   )rH   r   oppositer   r   rs   device_coordsdevice_sizes           r   	draw_facezRackElevationSVG.draw_face(  s'    I,,$u,MM 	U 	UD (^FXXh(<(<==F 33DJGGMD$v-..K  U&)t'@@@;$&&x&**6=+NNNN))&-MMMM U  m[!S!S!STTT+	U 	Ur!   c                    |                                  | _        |                                  |                     |           |                                  |                     |           |                                  | j        S )zG
        Return an SVG document representing a rack elevation.
        )ru   r`   r   r   r   r   r   )rH   r   s     r   renderzRackElevationSVG.renderC  s     **,, 	T""" 	t 	|r!   )NNNNNTNN)NN)F)__name__
__module____qualname____doc__rP   staticmethodrb   ru   r}   r   r   r   r   r   r   r   r   r   r5   r!   r   r   r   F   s         lpFJ   < # # \#      + + + +ZJ J J= = =       ' ' '(# # #<U U U U6    r!   r   )(r   ri   svgwrite.containerr   svgwrite.imager   svgwrite.gradientsr   svgwrite.shapesr   svgwrite.textr   django.confr   django.core.exceptionsr	   django.db.modelsr
   django.template.defaultfiltersr   django.urlsr   django.utils.httpr   netbox.configr   utilities.datar   utilities.htmlr   dcim.constantsr   __all__ro   rp   rq   r   r    r-   r   r5   r!   r   <module>r      s     ( ( ( ( ( (             - - - - - -                               - - - - - -       6 6 6 6 6 6       ' ' ' ' ' ' $ $ $ $ $ $ * * * * * * + + + + + + 6 6 6 6 6 6    
 
 
  2P P P P P P P P P Pr!   