
    >Tf`              	       J   d dl Z d dlZd dlmZ d dlmZ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T d dlmZ d dlT 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(m)Z)m*Z*m+Z+m,Z,m-Z- d dl.m/Z/ d dl0m1Z1 d dl2m3Z3 d dl4m5Z5 dZ6 G d de)e+e-e&          Z7 G d de)e+e-e&          Z8 G d de(e+e&          Z9 G d d e,e(e+e&          Z: G d! d"e(e+e&          Z; G d# d$e&          Z< G d% d&e)e*e-e+e&          Z= G d' d(ej>                  Z?dS ))    N)settings)GenericForeignKeyGenericRelation)
ArrayField)ValidationError)models)HttpResponse)reverse)timezone)gettext_lazy)JSONEncoder)
ObjectType)*)ConditionSet)image_upload)
get_config)get_event_type_choices)ChangeLoggedModel)CloningMixinCustomFieldsMixinCustomLinksMixinExportTemplatesMixinSyncedDataMixin	TagsMixin)
clean_html)render_jinja2)dict_to_querydict)RestrictedQuerySet)Bookmark
CustomLink	EventRuleExportTemplateImageAttachmentJournalEntrySavedFilterWebhookc                       e Zd ZdZ ej        dd ed           ed                    Z ej         ed          dd	
          Z	 ej         ed          dd	          Z
 e ej        de           ed                    Z ej         ed          d	          Z ej         ed          d	d	 ed                    Z ej        deej         ed                    Z ej        ddej                  Z ej        d	d	          Z edd           Z ej         ed!          d	d	 ed"                    Z ej         ed#          d	$          Z G d% d&          Zd' Z d( Z! fd)Z"d* Z# xZ$S )+r!   a  
    An EventRule defines an action to be taken automatically in response to a specific set of events, such as when a
    specific type of object is created, modified, or deleted. The action to be taken might entail transmitting a
    webhook or executing a custom script.
    core.ObjectTypeevent_ruleszobject typesz)The object(s) to which this rule applies.)torelated_nameverbose_name	help_textname   Tr,   
max_lengthuniquedescription   r,   r1   blank2   )r1   choicesz0The types of event which will trigger this rule.)
base_fieldr-   enabledr,   default
conditionszHA set of conditions which determine whether the event will be generated.)r,   r6   nullr-      zaction typer1   r8   r<   r,   contenttypes.ContentTypeeventrule_actions)r*   r+   	on_delete)r6   r>   action_object_typeaction_object_idct_fieldfk_fielddataz,Additional data to pass to the action objectcomments)r,   r6   c                   b    e Zd ZdZ ej        d          fZ ed          Z ed          Z	dS )EventRule.Metar.   )rD   rE   fieldsz
event rulezevent rulesN
__name__
__module____qualname__orderingr   Indexindexes_r,   verbose_name_plural     9/var/www/html/netbox-4.1.3/netbox/extras/models/models.pyMetarL   o   sN        FL JKKK
 qa..rZ   r\   c                     | j         S NrM   selfs    r[   __str__zEventRule.__str__w   
    yrZ   c                 0    t          d| j        g          S )Nzextras:eventruleargsr
   pkr_   s    r[   get_absolute_urlzEventRule.get_absolute_urlz   s    )	::::rZ   c                     t                                                       | j        r:	 t          | j                   d S # t          $ r}t          d|i          d }~ww xY wd S )Nr=   )supercleanr=   r   
ValueErrorr   )r`   e	__class__s     r[   rk   zEventRule.clean}   sw     ? 	99T_----- 9 9 9%|Q&78889	9 	9s   A   
A 
AA c                 b    | j         sdS t          | j                                       |          S )z
        Test whether the given data meets the conditions of the event rule (if any). Return True
        if met or no conditions are specified.
        T)r=   r   eval)r`   rI   s     r[   eval_conditionszEventRule.eval_conditions   s1    
  	4DO,,11$777rZ   )%rQ   rR   rS   __doc__r   ManyToManyFieldrW   object_types	CharFieldr.   r3   r   r   event_typesBooleanFieldr:   	JSONFieldr=   EventRuleActionChoicesWEBHOOKaction_type
ForeignKeyCASCADErD   PositiveBigIntegerFieldrE   r   action_objectaction_data	TextFieldrJ   r\   ra   rh   rk   rq   __classcell__rn   s   @r[   r!   r!   +   s        
 *6)"Q~&&!?@@	  L 6QvYY  D
 #&"Q}%%  K
 *#6#r;QRRR!FGG  K "f!Qy\\  G "!Q|__!^__	  J #&"&&.Q}%%	  K +*%(.  
 6v5   &%%#  M #&"QvYY!BCC	  K  vQz]]  H
/ / / / / / / /  ; ; ;9 9 9 9 98 8 8 8 8 8 8rZ   r!   c            	       N    e Zd ZdZ ej         ed          dd          Z ej         ed          dd          Z ej        d	 ed
           ed                    Z	 ej        de
e
j         ed                    Z ej        de ed           ed                    Z ej         ed          d ed                    Z ej         ed          d ed                    Z ej         ed          dd ed                    Z ej        d ed           ed                    Z ej        d dd ed!           ed"          #          Z eed$d%&          Z G d' d(          Zd) Zd* Zed+             Z fd,Zd- Zd. Z d/ Z! xZ"S )0r&   aM  
    A Webhook defines a request that will be sent to a remote application when an object is created, updated, and/or
    delete in NetBox. The request will contain a representation of the object, which the remote application can act on.
    Each Webhook can be limited to firing only on certain actions or certain object types.
    r.   r/   Tr0   r3   r4   r5   i  URLzThis URL will be called using the HTTP method defined when the webhook is called. Jinja2 template processing is supported with the same context as the request body.)r1   r,   r-   r?   zHTTP methodr@   d   zHTTP content typezThe complete list of official content types is available <a href="https://www.iana.org/assignments/media-types/media-types.xhtml">here</a>.)r1   r<   r,   r-   zadditional headerszUser-supplied HTTP headers to be sent with the request in addition to the HTTP content type. Headers should be defined in the format <code>Name: Value</code>. Jinja2 template processing is supported with the same context as the request body (below).)r,   r6   r-   zbody templatea  Jinja2 template for a custom request body. If blank, a JSON object representing the change will be included. Available context data includes: <code>event</code>, <code>model</code>, <code>timestamp</code>, <code>username</code>, <code>request_id</code>, and <code>data</code>.secret   zWhen provided, the request will include a <code>X-Hook-Signature</code> header containing a HMAC hex digest of the payload body using the secret as the key. The secret is not transmitted in the request.r,   r1   r6   r-   zSSL verificationz:Enable SSL certificate verification. Disable with caution!)r<   r,   r-   i   zCA File PathzeThe specific CA certificate file to use for SSL verification. Leave blank to use the system defaults.)r1   r>   r6   r,   r-   rD   rE   )content_type_fieldobject_id_fieldc                   >    e Zd ZdZ ed          Z ed          ZdS )Webhook.MetarM   webhookwebhooksNrQ   rR   rS   rT   rW   r,   rX   rY   rZ   r[   r\   r      s0        q||a
mmrZ   r\   c                     | j         S r^   rM   r_   s    r[   ra   zWebhook.__str__   rb   rZ   c                 0    t          d| j        g          S )Nzextras:webhookrd   rf   r_   s    r[   rh   zWebhook.get_absolute_url   s    'twi8888rZ   c                      t           j         dS )Nzdocs/models/extras/webhook/r   
STATIC_URLr_   s    r[   docs_urlzWebhook.docs_url   s    %BBBBrZ   c                     t                                                       | j        s%| j        r t	          dt          d          i          d S d S )Nca_file_pathzEDo not specify a CA certificate file if SSL verification is disabled.)rj   rk   ssl_verificationr   r   rW   r`   rn   s    r[   rk   zWebhook.clean   sd     $ 	): 	!"i j j#   	 	 	 	rZ   c                     | j         si S i }t          | j         |          }|                                D ]D}|                    dd          \  }}|                                ||                                <   E|S )zU
        Render additional_headers and return a dict of Header: Value pairs.
        :   )additional_headersr   
splitlinessplitstrip)r`   contextretrI   lineheadervalues          r[   render_headerszWebhook.render_headers   s}     & 	IT4g>>OO%% 	0 	0D JJsA..MFE"'++--C
rZ   c                 p    | j         rt          | j         |          S t          j        |t                    S )ze
        Render the body template, if defined. Otherwise, jump the context as a JSON object.
        )cls)body_templater   jsondumpsr   r`   r   s     r[   render_bodyzWebhook.render_body  s7      	8 !3W===:g;7777rZ   c                 ,    t          | j        |          S )z)
        Render the payload URL.
        )r   payload_urlr   s     r[   render_payload_urlzWebhook.render_payload_url  s     T-w777rZ   )#rQ   rR   rS   rr   r   ru   rW   r.   r3   r   WebhookHttpMethodChoicesMETHOD_POSThttp_methodHTTP_CONTENT_TYPE_JSONhttp_content_typer   r   r   r   rw   r   r   r   r!   eventsr\   ra   rh   propertyr   rk   r   r   r   r   r   s   @r[   r&   r&      sE        
 6QvYY  D
 #&"Q}%%  K
 #&"QuXX!Q
 
  K #&"((4Q}%%	  K )(&Q*++!a
 
	   *)Q+,,!<
 
   %F$Q''!m
 
  M VQx[[!t
 
	  F +v*Q)**!PQQ  
 $6#Q~&&!s
 
  L _/*  F, , , , , , , ,
  9 9 9 C C XC      8 8 88 8 8 8 8 8 8rZ   r&   c            	          e Zd ZdZ ej        dd ed                    Z ej         ed          dd	          Z	 ej
         ed
          d          Z ej         ed           ed                    Z ej         ed           ed                    Z ej         ed          d          Z ej         ed          dd ed                    Z ej         ed          deej         ed                    Z ej
         ed          d ed                    ZdZ G d d           Zd! Zd" Zed#             Zd$ Zd%S )&r    z
    A custom link to an external representation of a NetBox object. The link text and URL fields accept Jinja2 template
    code to be rendered with an object as context.
    r(   custom_linksz.The object type(s) to which this link applies.r*   r+   r-   r.   r   Tr0   r:   r;   z	link textz"Jinja2 template code for link text)r,   r-   zlink URLz!Jinja2 template code for link URLweightz
group namer7   z8Links with the same group will appear as a dropdown menur   zbutton classr?   zKThe class of the first link in a group will be used for the dropdown button)r,   r1   r8   r<   r-   z
new windowFz"Force link to open in a new windowr,   r<   r-   )rt   r:   r   
group_namebutton_class
new_windowc                   B    e Zd Zg dZ ed          Z ed          ZdS )CustomLink.Meta)r   r   r.   zcustom linkzcustom linksNr   rY   rZ   r[   r\   r   S  s:        333q''a//rZ   r\   c                     | j         S r^   rM   r_   s    r[   ra   zCustomLink.__str__X  rb   rZ   c                 0    t          d| j        g          S )Nzextras:customlinkrd   rf   r_   s    r[   rh   zCustomLink.get_absolute_url[  s    *$';;;;rZ   c                      t           j         dS )Nzdocs/models/extras/customlink/r   r_   s    r[   r   zCustomLink.docs_url^  s    %EEEErZ   c                    t          | j        |                                          }|si S t          | j        |                                          }| j        rdnd}t                      j        }t          ||          }t          j	        
                    |d          }t          j	                            |          }|j        r|j        |vrd}|||dS )z
        Render the CustomLink given the provided context, and return the text, link, and link_target.

        :param context: The context passed to Jinja2
        z target="_blank" z/:?&=%+[]@#,;!)safe)textlinklink_target)r   	link_textr   link_urlr   r   ALLOWED_URL_SCHEMESr   urllibparsequoteurlparsescheme)r`   r   r   r   r   allowed_schemesresults          r[   renderzCustomLink.renderb  s     T^W55;;== 	IT]G44::<<,0OC(( %,,:$00 |!!$-=!>> &&t,,= 	V]/AAD &
 
 	
rZ   N)rQ   rR   rS   rr   r   rs   rW   rt   ru   r.   rw   r:   r   r   r   PositiveSmallIntegerFieldr   r   CustomLinkButtonClassChoicesDEFAULTr   r   clone_fieldsr\   ra   rh   r   r   r   rY   rZ   r[   r    r      s`         *6)#!DEE  L
 6QvYY  D
 "f!Qy\\  G ! Q{^^!899  I  vQz]]!788  H .V-Qx[[  F "!Q|__!NOO	  J $6#Q~&&,,4!abb  L %$Q|__!899  JL0 0 0 0 0 0 0 0
  < < < F F XF
 
 
 
 
rZ   r    c                   :    e Zd Z ej        dd ed                    Z ej         ed          d          Z ej         ed          d	d
          Z	 ej
         ed                    Z ej        dd
 ed           ed                    Z ej         ed          dd
 ed                    Z ej         ed          d
 ed                    ZdZ G d d          Zd Zd Zed             Z fdZd  Zd
e_        d! Zd" Z xZS )#r"   r(   export_templatesz2The object type(s) to which this template applies.r   r.   r   )r,   r1   r3   r4   Tr5   zuJinja2 template code. The list of objects being exported is passed as a context variable named <code>queryset</code>.)r-   r7   z	MIME typez2Defaults to <code>text/plain; charset=utf-8</code>)r1   r6   r,   r-   zfile extension   z,Extension to append to the rendered filenamer   zas attachmentzDownload file as attachmentr   )rt   template_code	mime_typefile_extensionas_attachmentc                   >    e Zd ZdZ ed          Z ed          ZdS )ExportTemplate.MetarM   zexport templatezexport templatesNr   rY   rZ   r[   r\   r     s6        q*++a 233rZ   r\   c                     | j         S r^   rM   r_   s    r[   ra   zExportTemplate.__str__  rb   rZ   c                 0    t          d| j        g          S )Nzextras:exporttemplaterd   rf   r_   s    r[   rh   zExportTemplate.get_absolute_url  s    .dgY????rZ   c                      t           j         dS )Nz"docs/models/extras/exporttemplate/r   r_   s    r[   r   zExportTemplate.docs_url  s    %IIIIrZ   c                     t                                                       | j                                        dk    r7t	          dt          d                              | j                  i          d S )Ntabler.   z<"{name}" is a reserved name. Please choose a different name.rM   )rj   rk   r.   lowerr   rW   formatr   s    r[   rk   zExportTemplate.clean  sm    9??''!XYY``fjfo`pp#    ('rZ   c                 (    | j         j        | _        dS )zU
        Synchronize template content from the designated DataFile (if any).
        N)	data_filedata_as_stringr   r_   s    r[   	sync_datazExportTemplate.sync_data  s     "^:rZ   c                 d    d|i}t          | j        |          }|                    dd          }|S )z6
        Render the contents of the template.
        querysetz

)r   r   replace)r`   r   r   outputs       r[   r   zExportTemplate.render  s>    
 
 t17;; --rZ   c                    |                      |          }| j        sdn| j        }t          ||          }| j        rH|j        j        j                            dd          }| j        r
d| j         nd}d| | }d| d	|d
<   |S )z_
        Render the template to an HTTP response, delivered as a named file attachment
        ztext/plain; charset=utf-8)content_type rW   .r   netbox_zattachment; filename=""zContent-Disposition)	r   r   r	   r   model_metarX   r   r   )r`   r   r   r   responsebasename	extensionfilenames           r[   render_to_responsez!ExportTemplate.render_to_response  s     X&&7;~Y//4>	  Y??? 	S~+?GGSQQH595HP1D/111bI66966H.Rx.R.R.RH*+rZ   )rQ   rR   rS   r   rs   rW   rt   ru   r.   r3   r   r   r   r   rw   r   r   r\   ra   rh   r   r   rk   r   alters_datar   r   r   r   s   @r[   r"   r"     s@       )6)'!HII  L
 6QvYY  D #&"Q}%%  K
 %F$!%
 
  M ! Q{^^!HII	  I &V%Q'((!BCC	  N (F'Q''!122  ML4 4 4 4 4 4 4 4
  @ @ @ J J XJ    ; ; ;
 !I        rZ   r"   c                   j    e Zd ZdZ ej        dd ed                    Z ej         ed          dd	          Z	 ej
         ed
          dd	          Z ej         ed          dd          Z ej        ej        ej        dd          Z ej         ed          d          Z ej         ed          d          Z ej         ed          d          Z ej         ed                    ZdZ G d d          Zd Zd Zed             Z fdZed             Z  xZ!S )r%   zc
    A set of predefined keyword parameters that can be reused to filter for specific objects.
    r(   saved_filtersz0The object type(s) to which this filter applies.r   r.   r   Tr0   slugr3   r4   r5   r*   rC   r6   r>   r   r;   r:   shared
parametersr,   )rt   r   r:   r  c                   >    e Zd ZdZ ed          Z ed          ZdS )SavedFilter.Meta)r   r.   zsaved filterzsaved filtersNr   rY   rZ   r[   r\   r
    s4        %q((a00rZ   r\   c                     | j         S r^   rM   r_   s    r[   ra   zSavedFilter.__str__"  rb   rZ   c                 0    t          d| j        g          S )Nzextras:savedfilterrd   rf   r_   s    r[   rh   zSavedFilter.get_absolute_url%  s    +47)<<<<rZ   c                      t           j         dS )Nzdocs/models/extras/savedfilter/r   r_   s    r[   r   zSavedFilter.docs_url(  s    %FFFFrZ   c                     t                                                       t          | j                  t          urt          dt          d          i          d S )Nr  zFFilter parameters must be stored as a dictionary of keyword arguments.)rj   rk   typer  dictr   rW   r   s    r[   rk   zSavedFilter.clean,  sV       ,,!q!ijjk   -,rZ   c                 R    t          | j                  }|                                S r^   )r   r  	urlencode)r`   qds     r[   
url_paramszSavedFilter.url_params5  s    t//||~~rZ   )"rQ   rR   rS   rr   r   rs   rW   rt   ru   r.   	SlugFieldr  r3   r|   r   AUTH_USER_MODELSET_NULLuserr   r   rw   r:   r  rx   r  r   r\   ra   rh   r   r   rk   r  r   r   s   @r[   r%   r%     sJ         *6)$!FGG  L
 6QvYY  D
 6QvYY  D
 #&"Q}%%  K
 6#/	  D .V-Qx[[  F "f!Qy\\  G !V Qx[[  F "!Q|__  JL1 1 1 1 1 1 1 1
  = = = G G XG       X    rZ   r%   c                       e Zd ZdZ ej        dej                  Z ej                    Z	 e
dd          Z ej        edd	          Z ej         ed
                    Z ej         ed                    Z ej         ed          dd          Z ej                    ZdZ G d d          Zd Z fdZ fdZed             Z fdZ xZ S )r#   z?
    An uploaded image which is associated with an object.
    rA   r*   rC   object_type	object_idrF   image_heightimage_width)	upload_toheight_fieldwidth_fieldzimage heightr  zimage widthr.   r7   Tr5   r  r  c                   b    e Zd ZdZ ej        d          fZ ed          Z ed          Z	dS )ImageAttachment.Meta)r.   rg   r"  rN   zimage attachmentzimage attachmentsNrP   rY   rZ   r[   r\   r$  ]  sR        !FL <===
 q+,,a 344rZ   r\   c                     | j         r| j         S | j        j                             dd          d         }|                    dd          d         S )N/r   rW      )r.   imagersplitr   )r`   r   s     r[   ra   zImageAttachment.__str__e  sK    9 	9:?))#q11"5~~c1%%a((rZ   c                     t                                                       | j        t          j                            d          vr5t          t          d                              | j                            d S )Nimage_attachmentszBImage attachments cannot be assigned to this object type ({type}).r  	rj   rk   r  r   objectswith_featurer   rW   r   r   s    r[   rk   zImageAttachment.cleank  sr     :#5#B#BCV#W#WWW!VWW^^dhdt^uu   XWrZ   c                     | j         j        } t                      j        |i | | j                             d           || j         _        d S )NF)save)r)  r.   rj   delete)r`   re   kwargs_namern   s       r[   r3  zImageAttachment.deletet  sQ    
'''' 	
u%%%  
rZ   c                     t           g}	 ddlm} |                    |           n# t          $ r Y nw xY w	 | j        j        S # t          |          $ r Y dS w xY w)z
        Wrapper around `image.size` to suppress an OSError in case the file is inaccessible. Also opportunistically
        catch other exceptions that we know other storage back-ends to throw.
        r   )ClientErrorN)OSErrorbotocore.exceptionsr7  appendImportErrorr)  sizetuple)r`   expected_exceptionsr7  s      r[   r<  zImageAttachment.size  s      'i	777777&&{3333 	 	 	D		:?"()) 	 	 	44	s   & 
33A AAc                 b    t                                          |          }| j        |_        |S r^   )rj   to_objectchangeparentrelated_object)r`   actionobjectchangern   s      r[   r@  zImageAttachment.to_objectchange  s*    ww..v66&*k#rZ   )!rQ   rR   rS   rr   r   r|   r}   r  r~   r  r   rA  
ImageFieldr   r)  r   rW   r  r  ru   r.   r   
as_managerr/  r   r\   ra   rk   r3  r   r<  r@  r   r   s   @r[   r#   r#   ;  s         $&#%.  K /.00I  F F#!  E
 463Q~&&  L 3&2Q}%%  K 6QvYY  D , +--G/L5 5 5 5 5 5 5 5) ) )                X$        rZ   r#   c                   h    e Zd ZdZ ej        dej                  Z ej                    Z	 e
dd          Z ej        ej        ej        dd          Z ej         ed	          d
eej                  Z ej         ed                    Z G d d          Zd Zd Z fdZd Z xZS )r$   aU  
    A historical remark concerning an object; collectively, these form an object's journal. The journal is used to
    preserve historical context around an object, and complements NetBox's built-in change logging. For example, you
    might record a new journal entry when a device undergoes maintenance, or when a prefix is expanded.
    rA   r  assigned_object_typeassigned_object_idrF   Tr  kindr?   )r,   r1   r8   r<   rJ   r  c                   b    e Zd ZdZ ej        d          fZ ed          Z ed          Z	dS )JournalEntry.Meta)z-created)rH  rI  rN   zjournal entryzjournal entriesNrP   rY   rZ   r[   r\   rL    sQ         FL NOOO
 q))a 122rZ   r\   c                    t          j        | j                  }|                                                                 d|                                                    d           d|                                  dS )Nr   minutes)timespecz ())r   	localtimecreateddate	isoformattimeget_kind_display)r`   rR  s     r[   ra   zJournalEntry.__str__  sn    $T\22,,..**,,yyw||~~/G/GQZ/G/[/[yy_c_t_t_v_vyyyyrZ   c                 0    t          d| j        g          S )Nzextras:journalentryrd   rf   r_   s    r[   rh   zJournalEntry.get_absolute_url  s    ,DG9====rZ   c                     t                                                       | j        t          j                            d          vr5t          t          d                              | j                            d S )N
journalingz:Journaling is not supported for this object type ({type}).r-  )	rj   rk   rH  r   r/  r0  r   rW   r   r   s    r[   rk   zJournalEntry.clean  sq     $J,>,K,KL,Y,YYY!NOOVV\`\uVvv   ZYrZ   c                 J    t           j                            | j                  S r^   )JournalEntryKindChoicescolorsgetrJ  r_   s    r[   get_kind_colorzJournalEntry.get_kind_color  s    &-11$)<<<rZ   )rQ   rR   rS   rr   r   r|   r}   rH  r~   rI  r   assigned_objectr   r  r  
created_byru   rW   r[  	KIND_INFOrJ  r   rJ   r\   ra   rh   rk   r^  r   r   s   @r[   r$   r$     sr        
 -6,%.   8799'''%  O #"#/	  J 6QvYY''1	  D  vQz]]  H3 3 3 3 3 3 3 3z z z> > >    = = = = = = =rZ   r$   c                   8    e Zd ZdZ ej         ed          d          Z ej        dej	                  Z
 ej                    Z edd	          Z ej        ej        ej                  Z ej                    Z G d
 d          Z fdZ fdZ xZS )r   z)
    An object bookmarked by a User.
    rR  T)r,   auto_now_addrA   r  r  r  rF   c                       e Zd ZdZ ej        d          fZ ej        dd          fZ e	d          Z
 e	d          Zd	S )
Bookmark.Meta)rR  rg   r"  rN   )r  r  r  z2%(app_label)s_%(class)s_unique_per_object_and_user)rO   r.   bookmark	bookmarksN)rQ   rR   rS   rT   r   rU   rV   UniqueConstraintconstraintsrW   r,   rX   rY   rZ   r[   r\   re    sr        $FL <===
 $F#;I  
 q}}annrZ   r\   c                 z    | j         rt          | j                   S t                                                      S r^   )objectstrrj   ra   r   s    r[   ra   zBookmark.__str__  s1    ; 	$t{###ww   rZ   c                     t                                                       | j        t          j                            d          vr5t          t          d                              | j                            d S )Nrg  z:Bookmarks cannot be assigned to this object type ({type}).r-  r.  r   s    r[   rk   zBookmark.clean   sq     :#5#B#B;#O#OOO!NOOVV\`\lVmm   POrZ   )rQ   rR   rS   rr   r   DateTimeFieldrW   rR  r|   PROTECTr  r~   r  r   rk  r   r  r}   r  r   rF  r/  r\   ra   rk   r   r   s   @r[   r   r     s7         #f"Qy\\  G $&#%.  K /.00I  F 6#.  D
 , +--G- - - - - - - -! ! ! ! !
        rZ   r   )@r   urllib.parser   django.confr   "django.contrib.contenttypes.fieldsr   r   django.contrib.postgres.fieldsr   django.core.validatorsr   	django.dbr   django.httpr	   django.urlsr
   django.utilsr   django.utils.translationr   rW   rest_framework.utils.encodersr   core.modelsr   extras.choicesextras.conditionsr   extras.constantsextras.utilsr   netbox.configr   netbox.eventsr   netbox.modelsr   netbox.models.featuresr   r   r   r   r   r   utilities.htmlr   utilities.jinja2r   utilities.querydictr   utilities.querysetsr   __all__r!   r&   r    r"   r%   r#   r$   Modelr   rY   rZ   r[   <module>r     s                    Q Q Q Q Q Q Q Q 5 5 5 5 5 5 2 2 2 2 2 2       $ $ $ $ $ $       ! ! ! ! ! ! 6 6 6 6 6 6 5 5 5 5 5 5 " " " " " "     * * * * * *     % % % % % % $ $ $ $ $ $ 0 0 0 0 0 0 + + + + + +                & % % % % % * * * * * * 1 1 1 1 1 1 2 2 2 2 2 2	d8 d8 d8 d8 d8!#7DU d8 d8 d8NH8 H8 H8 H8 H8!5yBS H8 H8 H8Va
 a
 a
 a
 a
35F a
 a
 a
Hg g g g g_l4HJ[ g g gTM M M M M, 46G M M M`\ \ \ \ \' \ \ \~8= 8= 8= 8= 8=$&6	CWYj 8= 8= 8=v2 2 2 2 2v| 2 2 2 2 2rZ   