
    >Tf_)                         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T d	ZddZd Zd Zd Zd Zd Zd Zd ZddZd Zd ZdS )    N)forms)fields_for_model)gettext)unpack_grouped_choices)RestrictedQuerySet   )*)add_blank_choiceexpand_alphanumeric_patternexpand_ipaddress_patternform_from_modelget_field_valueget_selected_valuesparse_alphanumeric_rangeparse_numeric_rangerestrict_form_fields	parse_csvvalidate_csv
   c                 D   t                      }|                     d          D ]}	 |                    d          \  }}n# t          $ r ||}}Y nw xY w	 t          |                                |          t          |                                |          dz   }}nC# t          $ r6 t          j        t          d                              |                    w xY w|	                    t          ||                     t          t          |                    S )z
    Expand a numeric range (continuous or not) into a decimal or
    hexadecimal list, as specified by the base parameter
      '0-3,5' => [0, 1, 2, 3, 5]
      '2,8-b,d,f' => [2, 8, 9, a, b, d, f]
    ,-)baser   Range "{value}" is invalid.value)listsplit
ValueErrorintstripr   ValidationError_formatextendrangesortedset)stringr   values
dash_rangebeginends         :/var/www/html/netbox-4.1.3/netbox/utilities/forms/utils.pyr   r      s-    VVFll3'' 	) 	)
	0#))#..JE33 	0 	0 	0#Z3EEE	0	cU[[]]666CIIKKd8S8S8SVW8W3EE 	c 	c 	c'*G(H(H(O(OV`(O(a(abbb	ceE3''((((#f++s   A  AAA	BA Cc           	         g }|                      d          D ]}d|vr|                    |           	 |                     d          \  }}||z   }|                                s|                                r<|                                r,|                                s|                                sg c S nC# t          $ r6 t          j        t          d          
                    |                    w xY w|                                r|                                rt          |          t          |          k    r6t          j        t          d          
                    ||                    t          t          t          |          t          |          dz                       D ]}|                    |           t          |          t          |          cxk    rdk    s7n t          j        t          d          
                    |                    t          |          t          |          k    r5t          j        t          d          
                    |                    t          t          t          |          t          |          dz                       D ]$}|                    t!          |                     %|S )z
    Expand an alphanumeric range (continuous or not) into a list.
    'a-d,f' => [a, b, c, d, f]
    '0-3,a-d' => [0, 1, 2, 3, a, b, c, d]
    r   r   r   r   zSInvalid range: Ending value ({end}) must be greater than beginning value ({begin}).)r,   r-   r   )r   appendisdigitisalphaisupperislowerr   r   r"   r#   r$   r    r   r&   lenordchr)r)   r*   r   r,   r-   valsns          r.   r   r   /   s    Fc"" #& #&eMM%   	^S))JE33;D\\^^ t||~~ DLLNN TXT`T`TbTb fjfrfrftft 			 	^ 	^ 	^'*G(H(H(O(OV[(O(\(\]]]	^ ==?? 	&s{{}} 	&5zzSXX%%+kllss# t    
 %E

CHHqL99:: ! !a    ! u::S....Q....+A.K,L,L,S,SZ_,S,`,`aaa5zzSXX%%+A.K,L,L,S,SZ_,S,`,`aaa%E

CHHqL99:: & &c!ff%%%%& Ms   BB<<A C<c              #   0  K   t          j        t          | d          \  }}}t          |          }|D ]a}t          j        t          |          r,t          |          D ]} d                    |||           V  Hd                    |||          V  bdS )z>
    Expand an alphabetic pattern into a list of strings.
    r   maxsplitz{}{}{}N)rer   ALPHANUMERIC_EXPANSION_PATTERNr   searchr   r$   )r)   leadpatternremnantparsed_rangeis         r.   r   r   ^   s        X&DfWXYYYD'7+G44L 4 493W== 	45g>> 7 7oodAv6666667 //$73333334 4    c           
   #     K   |dvr"t          d                    |                    |dk    r
t          }d}n	t          }d}t	          j        || d          \  }}}t          ||          }|D ]}t	          j        ||          rDt          ||          D ]2} d	                    |t          ||d	k    rd
nd          | g          V  3[d	                    |t          ||d	k    rd
nd          |g          V  dS )a  
    Expand an IP address pattern into a list of strings. Examples:
      '192.0.2.[1,2,100-250]/24' => ['192.0.2.1/24', '192.0.2.2/24', '192.0.2.100/24' ... '192.0.2.250/24']
      '2001:db8:0:[0,fd-ff]::/64' => ['2001:db8:0:0::/64', '2001:db8:0:fd::/64', ... '2001:db8:0:ff::/64']
    )      zInvalid IP address family: {}rG   r      r   r;    rH   xdN)
	Exceptionr$   IP4_EXPANSION_PATTERNIP6_EXPANSION_PATTERNr=   r   r   r?   r   join)	r)   familyregexr   r@   rA   rB   rC   rD   s	            r.   r   r   l   s@      V7>>vFFGGG{{%%XeVa@@@D'7&w55L S S9UG$$ 	S27FCC V VggtVAfkksss%K%KVTUUUUUUV ''4&A++333!G!GQRRRRRRS SrE   c                     | j         |         }| j        rC| j                            |          x}r't	          |d          r|                    |          r|S |                     ||          S )z|
    Return the current bound or initial value associated with a form field, prior to calling
    clean() for the form.
    valid_value)fieldsis_bounddatagethasattrrT   get_initial_for_field)form
field_namefieldrW   s       r.   r   r      sv    
 K
#E} $)--
";";;$ 5-(( 	U->->t-D-D 	K%%eZ888rE   c                 d   t          | d          s|                                  | j                            |          | j        |         }t          |d          st                    gS t          |j                  t          j	        j
        u rt          d          sg}nE}nBt          |j                  }t                    t          t          fvrgfd|D             }t          |dd          r4dv r0|                    d           |                    d|j                   |S )zL
    Return the list of selected human-friendly values for a form field
    cleaned_datachoices__iter__c                 D    g | ]\  }}t          |          v sd v |S )N)str).0r   labelfilter_datas      r.   
<listcomp>z'get_selected_values.<locals>.<listcomp>   s?     
 
 
"eUU{1J1JdVaNaNaENaNaNarE   null_optionNr   )rY   is_validr_   rX   rU   rc   typer`   r   modelsModelChoiceIteratorr   r   tuplegetattrremoveinsertrh   )r[   r\   r]   r*   r`   rf   s        @r.   r   r      sN    4(( #''
33KK
#E 5)$$ "K  !! EMel>>>{J// 	!!]FF FF )77T5M11&-K
 
 
 
&-
 
 
 umT** ,t{/B/Bda*+++MrE   c                 &    dt          |           z   S )z@
    Add a blank choice to the beginning of a choices list.
    ))Nz	---------)rm   )r`   s    r.   r
   r
      s     "E'NN22rE   c                     t          | |          }|                                D ]	}d|_        
t          dt          j        f|          S )a  
    Return a Form class with the specified fields derived from a model. This is useful when we need a form to be used
    for creating objects, but want to avoid the model's validation (e.g. for bulk create/edit functions). All fields
    are marked as not required.
    )rU   FFormFromModel)r   r*   requiredrj   r   Form)modelrU   form_fieldsr]   s       r.   r   r      sP     #5888K##%%  %*<<<rE   viewc                     | j                                         D ]Q}t          |d          r?t          |j        j        t                    r |j                            ||          |_        RdS )z
    Restrict all form fields which reference a RestrictedQuerySet. This ensures that users see only permitted objects
    as available choices.
    querysetN)rU   r*   rY   
issubclassrz   	__class__r   restrict)r[   useractionr]   s       r.   r   r      st    
 ##%% C C5*%% 	C*U^5MOa*b*b 	C"^44T6BBENC CrE   c           
      B   g }i }t          |           D ]}|                                }d|v rX|                    dd          \  }}||v r5t          j        t          d                              |                    |||<   r||v r5t          j        t          d                              |                    d||<   t          | d          D ]\  }}t          |          t          |          k    rQt          j        t          d	                              |t          |          t          |          
                    d |D             }t          t          |                                |                    }|                    |           ||fS )z
    Parse a csv_reader object into a headers dictionary and a list of records dictionaries. Raise an error
    if the records are formatted incorrectly. Return headers and records as a tuple.
    .r   z4Duplicate or conflicting column header for "{field}"r]   z5Duplicate or conflicting column header for "{header}"headerN)startzDRow {row}: Expected {count_expected} columns but found {count_found})rowcount_expectedcount_foundc                 6    g | ]}|                                 S  )r!   )rd   cols     r.   rg   zparse_csv.<locals>.<listcomp>   s     ***ssyy{{***rE   )nextr!   r   r   r"   r#   r$   	enumerater5   dictzipkeysr0   )	readerrecordsheadersr   r]   to_fieldrD   r   records	            r.   r   r      s   
 GG v,, # #&==$ll322OE8+A.d,e,e,l,l -m - -    &GENN  +A.e,f,f,m,m! -n - -    #GFOO F!,,, 	 	3s88s7||##'XYY``#g,,CHH a    
 +*c***c',,..#..//vGrE   c                    d}|                                  D ]\  }}|dk    rd}||vr5t          j        t          d                              |                    |rKt          ||         d          s5t          j        t          d                              |                    |rVt          ||         j        j        |          s6t          j        t          d                              ||	                    |s>|D ]=}|| vr5t          j        t          d
                              |                    <dS dS )z
    Validate that parsed csv data conforms to the object's available fields. Raise validation errors
    if parsed csv data contains invalid headers or does not contain required headers.
    FidTz)Unexpected column header "{field}" found.r   to_field_namez9Column "{field}" is not a related object; cannot use dotszAInvalid related object attribute for column "{field}": {to_field})r]   r   z,Required column header "{header}" not found.r   N)itemsr   r"   r#   r$   rY   rz   rv   )r   rU   required_fields	is_updater]   r   fs          r.   r   r     s    I"==??  xD==I'*U(V(V(](]di(](j(jkkk 	GF5M?CC 	'*e(f(f(m(m )n ) )     	GF5M$:$@(KK 	'*m(n(n(u(uh )v ) )   
  p  	p 	pA+A.\,],],d,dlm,d,n,nooo  p p	p 	prE   )r   )rx   )r=   djangor   django.forms.modelsr   django.utils.translationr   r#   utilities.choicesr   utilities.querysetsr   	constants__all__r   r   r   r   r   r   r
   r   r   r   r   r   rE   r.   <module>r      sC   				       0 0 0 0 0 0 1 1 1 1 1 1 4 4 4 4 4 4 2 2 2 2 2 2       *, , ,^4 4 4S S S09 9 9$ $ $N3 3 3
= 
= 
=C C C C( ( (Vp p p p prE   