
    Wwg?                         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
mZmZmZmZ d dlmZ d dlmZ d Zd	 Zd
 ZdedefdZ	 ddee   dee   fdZy)    Ntimezone)Optional)settings)ObjectDoesNotExist)NOT_PROVIDEDDateTimeField
ForeignKey	JSONFieldModel)	smart_strc                 x    ddl m} | j                  ryt        | dd      | j                  j
                  |k(  ryy)a.  
    Returns whether the given field should be tracked by Auditlog.

    Untracked fields are many-to-many relations and relations to the Auditlog LogEntry model.

    :param field: The field to check.
    :type field: Field
    :return: Whether the given field should be tracked.
    :rtype: bool
    r   )LogEntryFremote_fieldNT)auditlog.modelsr   many_to_manygetattrr   model)fieldr   s     D/var/www/horilla/myenv/lib/python3.12/site-packages/auditlog/diff.pytrack_fieldr      s@     )  	~t,8$$0    c                     t        | t              sJ | j                  j                         D cg c]  }t	        |      s| c}S c c}w )aZ  
    Returns the list of fields in the given model instance. Checks whether to use the official
    _meta API or use the raw data. This method excludes many to many fields.

    :param instance: The model instance to get the fields for
    :type instance: Model
    :return: The list of fields for the given model (instance)
    :rtype: list
    )
isinstancer   _meta
get_fieldsr   )instancefs     r   get_fields_in_modelr   '   s;     h&&&~~002E!k!nAEEEs   A Ac                 T   	 t        |t              rx|j                  t        | |j                  d            }|8t
        j                  r't        j                  |      st        j                  |t        j                        }	 |S t        |t              rJ|j                  t        | |j                  d            }t        j                  |d|j                        }|S |j                   s|j"                  r4t%        |d      r(t'        t        | |j)                         d      d      }|S t'        t        | |j                  d            }t+        |      j,                  dk(  rt/        |      }|S # t0        $ r) t        |dt2              t2        ur|j4                  nd}Y |S w xY w)	a  
    Gets the value of a given model instance field.

    :param obj: The model instance.
    :type obj: Model
    :param field: The field you want to find the value of.
    :type field: Any
    :return: The value of the field as a string.
    :rtype: str
    Nr   T)	sort_keyscls	rel_class)strings_only	__proxy__default)r   r	   	to_pythonr   namer   USE_TZdjango_timezoneis_naive
make_naiver   utcr   jsondumpsencoder
one_to_onemany_to_onehasattrr   get_attnametype__name__strr   r   r&   )objr   values      r   get_field_valuer:   6   se   
e]+ OOGCT$BCE!OO'007'2258<<P& L% y)OOGCT$BCEJJu%--HE  L %"3"39TU..0$7dE L gc5::t<=EE{##{2E
 L  
 ui6lJ MM 	 L
s'   BE5 
AE5 $A
E5 0AE5 5.F'&F'r9   returnc                 F    t        t        |       dz        }d|z  | |d z   S )z
    Masks the first half of the input string to remove sensitive data.

    :param value: The value to mask.
    :type value: str
    :return: The masked version of the string.
    :rtype: str
       *N)intlen)r9   
mask_limits     r   mask_strrB   a   s-     SZ!^$JeJK000r   oldnewc                    ddl m} | t        | t              st	        d      |t        |t              st	        d      i }| ^|\t        | j                  j                  |j                  j                  z         }|j                  |j                  j                        }n| :t        t        |             }|j                  | j                  j                        }nH|:t        t        |            }|j                  |j                  j                        }nt               }d}|r;|D ch c]0  }t        |t              r|j                  |v s|j                  |v r|2 }}|r]|d   s|d   rS|rQg }|d   r!|D cg c]  }|j                  |d   v r| }}n|}|d   r |D cg c]  }|j                  |d   vr| }}|}|D ]  }t        | |      }	t        ||      }
|	|
k7  s!|rG|j                  |d   v r6t        t!        |	            t        t!        |
            f||j                  <   jt!        |	      t!        |
      f||j                  <    t#        |      dk(  rd}|S c c}w c c}w c c}w )	a  
    Calculates the differences between two model instances. One of the instances may be ``None``
    (i.e., a newly created model or deleted model). This will cause all fields with a value to have
    changed (from ``None``).

    :param old: The old state of the model instance.
    :type old: Model
    :param new: The new state of the model instance.
    :type new: Model
    :param fields_to_check: An iterable of the field names to restrict the diff to, while ignoring the rest of
        the model's fields. This is used to pass the `update_fields` kwarg from the model's `save` method.
    :type fields_to_check: Iterable
    :return: A dictionary with the names of the changed fields as keys and a two tuple of the old and new
            field values as value.
    :rtype: dict
    r   )auditlogNz8The supplied old instance is not a valid model instance.z8The supplied new instance is not a valid model instance.include_fieldsexclude_fieldsmask_fields)auditlog.registryrF   r   r   	TypeErrorsetr   fieldsget_model_fieldsr   r   r
   attnamer(   r:   rB   r   r@   )rC   rD   fields_to_checkrF   diffrM   model_fieldsr   filtered_fields	old_value	new_values              r   model_instance_diffrV   n   s   & +K:c51RSSK:c51RSSD
3?SYY%%		(8(88900A	(-.00A	(-.00A  
E:.5==O3SJJ/1	 
 
 	*+|<L/M() $::.>!?? O  %O() -::\2B%CC O 
 ! P#C/	#C/		!

l=.I IYy12Yy12$UZZ 
 %.i$8)I:N#OUZZ P 4yA~Ka
"s   -5I&=I+%I0)N)r.   datetimer   typingr   django.confr   django.core.exceptionsr   django.db.modelsr   r	   r
   r   r   django.utilsr*   django.utils.encodingr   r   r   r:   r7   rB   rV    r   r   <module>r_      sk         5 V V 4 +6F(V
1C 
1C 
1 AEZ	%Z'Zr   