a
    xd[                     @   s  d dl Z d dlZ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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)m*Z* ddl#m+Z+ zd dl,m-Z. W n  e/y<   d dl0m1Z. Y n0 i Z2dd Z3dd Z4dd Z5G dd dZ6d d! Z7G d"d# d#Z8G d$d% d%Z9G d&d' d'Z:G d(d) d)Z;dS )*    N)apps)settings)admin)get_user_model)ObjectDoesNotExist)models)ManyToManyFieldQ)OrderWrt)model_to_dict)reverse)timezone)	smart_str)format_lazy)gettext_lazy)utils   )
exceptions)HistoryDescriptor)post_create_historical_recordpre_create_historical_record)get_change_reason_from_object)Local)localc                 K   s"   z| j W S  ty   Y d S 0 d S N)userAttributeError)requestkwargs r   M/var/www/html/Ranjet/env/lib/python3.9/site-packages/simple_history/models.py_default_get_user$   s    r!   c                 C   sB   | j d u rd S t }z|jj| j dW S  |jy<   Y d S 0 d S )Npk)history_user_idr   objectsgetZDoesNotExist)historical_instanceZUserr   r   r    _history_user_getter+   s    
r(   c                 C   s   |d ur|j | _d S r   )r#   r$   )r'   r   r   r   r    _history_user_setter5   s    r)   c                   @   s   e Zd Ze  ZZdejfdddddddedddde	e
dddfddZdd Zd	d
 Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd)d!d"Zd*d#d$Zd+d%d&Zd'd( ZdS ),HistoricalRecordsN+FTc                 C   s   || _ || _|| _|| _|| _|| _|| _|	| _|
| _|| _	|| _
|| _|| _|| _|| _|| _|| _|d u rrg }|| _z"t|trttft| | _W n ty   tdY n0 d S )Nz-The `bases` option must be a list or a tuple.)user_set_verbose_nameuser_related_nameuser_db_constraint
table_nameinherithistory_id_fieldhistory_change_reason_field
user_modelget_usercascade_delete_historycustom_model_nameappuser_id_fielduser_getteruser_setterrelated_nameuse_base_model_dbexcluded_fields
isinstancestr	TypeErrorHistoricalChangestuplebases)selfverbose_namerC   r-   r/   r0   r=   r1   r2   r3   r4   r5   r6   r7   Zhistory_user_id_fieldZhistory_user_getterZhistory_user_setterr;   r<   r.   r   r   r    __init__=   s4    
zHistoricalRecords.__init__c                 C   s^   || _ |j| _|| _tjjj| jdd | 	| |j
jrZ| jsZd| jj}t|t d S )NF)weakzCHistoricalRecords added to abstract model ({}) without inherit=True)manager_name
__module__moduleclsr   signalsZclass_preparedconnectfinalizeadd_extra_methods_metaZabstractr0   format__name__warningswarnUserWarning)rD   rK   namemsgr   r   r    contribute_to_classo   s    
z%HistoricalRecords.contribute_to_classc                 C   s   dd }t |d| d S )Nc                 _   s*   d| _ z| j|i |}W | ` n| ` 0 |S )z
            Save model without saving a historical record

            Make sure you know what you're doing before you use this method.
            T)skip_history_when_savingsave)rD   argsr   retr   r   r    save_without_historical_record~   s
    zKHistoricalRecords.add_extra_methods.<locals>.save_without_historical_recordr]   )setattr)rD   rK   r]   r   r   r    rO   }   s    z#HistoricalRecords.add_extra_methodsc                 K   s   d}| j |ur(| jot|| j }|s(d S t|jdrNtd|jj|jj	| 
||}|rlt|j}nt| j}t||j| tjjj| j|dd tjjj| j|dd t|}t|| j| | j|j_d S )NF simple_history_manager_attributez5{}.{} registered multiple times for history tracking.)senderrG   )rK   r0   
issubclasshasattrrP   r   ZMultipleRegistrationsErrorrQ   	app_labelobject_namecreate_history_model	importlibimport_modulerI   rJ   r^   rR   r   rL   	post_saverM   post_deleter   rH   r_   )rD   r`   r   	inheritedhistory_modelrJ   Z
descriptorr   r   r    rN      s*    
zHistoricalRecords.finalizec                 C   sl   | j sd|jjS t| j r.|  |jj}n| j }| |jj krT|j| jksX|S td| j d S )NzHistorical{}z|The 'custom_model_name' option '{}' evaluates to a name that is the same as the model it is tracking. This is not permitted.)	r6   rQ   rP   rd   callablelowerrI   rJ   
ValueError)rD   modelrV   r   r   r    get_history_model_name   s    

z(HistoricalRecords.get_history_model_namec           
      C   s   | j | jd}d|jj }|r*|j|d< n>|j| j krB| j |d< n&|| j krhtj|jj }|j}||d< | |}|	| |	| 
|| |j	ttdd| |d | jdur| j|d _| |}|t|jj< tt|| j|}	|	S )zR
        Creates a historical model to associate with the model provided.
        )rI   _history_excluded_fieldsz	%s.modelsrI   Metar   )rr   N)rJ   r=   rP   rc   rI   r   Zapp_configsrV   copy_fieldsupdateget_extra_fieldstyper?   get_meta_optionsr/   Zdb_tablerp   registered_modelsrC   )
rD   ro   rj   attrsZ
app_moduler7   Zmodels_modulefieldsrV   rk   r   r   r    re      s,    




z&HistoricalRecords.create_history_modelc                 C   s,   g }|j jD ]}|j| jvr|| q|S r   )rP   rz   rV   r=   append)rD   ro   rz   fieldr   r   r    fields_included   s
    z!HistoricalRecords.fields_includedc                 C   s  i }|  |D ]}t|}t|j|_t|tr<tj|_t|tjr|}|j	}d|_	z|
 \}}}}	W ||_	n||_	0 t|ddst|tjrtj}
nt|}
|	dddkr|j|	d< |	jddddddddtjd	 |
|i |	}|j|_nt| |||j< q|S )	z
        Creates copies of the model's original fields, returning
        a dictionary mapping field name to copied field object.
        FZ
one_to_onetoNrD   r+   T)	db_constraintr;   nullZblankprimary_keydb_index	serializeunique	on_delete)r}   copyZremote_fieldr>   r
   r   IntegerField	__class__
ForeignKeyZ	swappableZdeconstructgetattrZOneToOneFieldrv   r&   ro   rt   
DO_NOTHINGrV   transform_field)rD   ro   rz   r|   Z	old_fieldZold_swappable_name_pathr[   Z
field_argsZ	FieldTyper   r   r    rs      sH    



zHistoricalRecords.copy_fieldsc                 C   s:   | j r| j }n(ttddr(tjdd}ntjddd}|S )NZ3SIMPLE_HISTORY_HISTORY_CHANGE_REASON_USE_TEXT_FIELDFT)r   d   )
max_lengthr   )r2   r   r   r   	TextField	CharField)rD   r2   r   r   r     _get_history_change_reason_field$  s    z2HistoricalRecords._get_history_change_reason_fieldc                 C   sJ   | j r| j }d|_d|_n,ttddr:tjdtjdd}ntj	dd}|S )NTFZ"SIMPLE_HISTORY_HISTORY_ID_USE_UUID)r   defaulteditable)r   )
r1   r   r   r   r   r   Z	UUIDFielduuiduuid4	AutoField)rD   r1   r   r   r    _get_history_id_field3  s    z'HistoricalRecords._get_history_id_fieldc                 C   sV   | j d ur"t| j| j| j d}n0| jp2ttdd}dtj|d| j	tj
| jdi}|S )N)history_userr$   ZAUTH_USER_MODELz	auth.Userr   T)r   r;   r   r   )r8   propertyr9   r:   r3   r   r   r   r   r-   ZSET_NULLr.   )rD   Zhistory_user_fieldsr3   r   r   r    _get_history_user_fieldsA  s     

z*HistoricalRecords._get_history_user_fieldsc                 C   s>   | j r6| j| j krtddtj|tj| j ddiS i S d S )Nz=The related name must not be called like the history manager.history_relationF)r   r;   r   )r;   rH   r   ZRelatedNameConflictErrorr   r   r   )rD   ro   r   r   r    _get_history_related_fieldY  s    	z,HistoricalRecords._get_history_related_fieldc           	         s   fdd} fdd}dd }dd }fd	d
}  t  tjddtdfdtdfdtdffdtt|t|t||dd t	|d}|
 |
  |S )z@Return dict of extra fields added to the historical record modelc                    s>    j }|j|j }}tdtjj||f t| |jj	| j
gdS )z.URL for this change in the default admin site.z%s:%s_%s_simple_history)r[   )rP   rc   
model_namer   r   siterV   r   r#   attname
history_id)rD   optsrc   r   ro   r   r    
revert_urlm  s    z6HistoricalRecords.get_extra_fields.<locals>.revert_urlc                    s    fdd  D } jrvfdd jD }z(jjt jjjdj |  }W n t	yj   Y n0 |
| f i |S )Nc                    s   i | ]}|j t |j qS r   r   r   .0r|   rD   r   r    
<dictcomp>w  s   zLHistoricalRecords.get_extra_fields.<locals>.get_instance.<locals>.<dictcomp>c                    s,   g | ]$}t  j|ts j|jqS r   )r>   rP   	get_fieldr   r   r   r   r   r    
<listcomp>}  s   zLHistoricalRecords.get_extra_fields.<locals>.get_instance.<locals>.<listcomp>r"   )valuesrq   r%   filterr   rP   r#   r   r&   r   rt   )rD   ry   Zexcluded_attnamesr   )rz   ro   r   r    get_instancev  s     


z8HistoricalRecords.get_extra_fields.<locals>.get_instancec                 S   s(   t | j}|t| jdd S )zW
            Get the next history record for the instance. `None` if last.
            )Zhistory_date__gthistory_date)r   get_history_manager_for_modelinstancer   r	   r   order_byfirstrD   historyr   r   r    get_next_record  s
    z;HistoricalRecords.get_extra_fields.<locals>.get_next_recordc                 S   s(   t | j}|t| jdd S )z\
            Get the previous history record for the instance. `None` if first.
            )Zhistory_date__ltr   )r   r   r   r   r	   r   r   lastr   r   r   r    get_prev_record  s
    z;HistoricalRecords.get_extra_fields.<locals>.get_prev_recordc                    s
     | S )z~
            Returns the user specified by `get_user` method for manually creating
            historical objects
            )get_history_userr   r   r   r    get_default_history_user  s    zDHistoricalRecords.get_extra_fields.<locals>.get_default_history_userr   r+   Created~ZChanged-ZDeleted)r   choicesc                 S   s   d | j| jS )Nz{} as of {})rQ   history_objectr   r   r   r   r    <lambda>  s   z4HistoricalRecords.get_extra_fields.<locals>.<lambda>)r   r   history_change_reasonhistory_typer   r   Zinstance_typeZnext_recordZprev_recordr   __str__r   )r   r   ZDateTimeFieldr   r   _HistoricalObjectDescriptorr}   r   staticmethodrt   r   r   )	rD   ro   rz   r   r   r   r   r   Zextra_fieldsr   )rz   ro   rD   r    ru   j  s4    	 
z"HistoricalRecords.get_extra_fieldsc                 C   sF   ddd}| j r| j }ntdt|jj}||d< | jrB| j|d< |S )z
        Returns a dictionary of fields that will be added to
        the Meta inner class of the historical record model.
        )z-history_datez-history_idr   )ZorderingZget_latest_byzhistorical {}rE   rc   )r,   r   r   rP   rE   r7   )rD   ro   Zmeta_fieldsrV   r   r   r    rw     s    
z"HistoricalRecords.get_meta_optionsc                 K   s:   |st |drd S |dds6| j||r,dp.d|d d S )NrY   rawFr+   r   using)rb   r&   create_historical_record)rD   r   createdr   r   r   r   r    rh     s    zHistoricalRecords.post_savec                 K   s:   | j r&t|| j}||   n| j|d|d d S )Nr   r   )r5   r   rH   r   alldeleter   )rD   r   r   r   managerr   r   r    ri     s    zHistoricalRecords.post_deletec              	   C   s   | j r
|nd }t|dt }| |}t|}t|| j}i }| |D ]}	t||	j||	j< qJt|j	dd }
|
d ur||d< |j	f ||||d|}t
j|j	||||||d |j|d tj|j	||||||d d S )NZ_history_dater   )r   r   r   r   )r`   r   r   r   r   history_instancer   r   )r`   r   r   r   r   r   r   )r<   r   r   nowr   r   rH   r}   r   ro   r   sendrZ   r   )rD   r   r   r   r   r   r   r   ry   r|   Zrelation_fieldr   r   r   r    r     sL    

z*HistoricalRecords.create_historical_recordc                 C   sZ   z|j W S  tyJ   d}z| jjjjr0| jj}W n tyD   Y n0 Y n0 | j||dS )z3Get the modifying user from instance or middleware.N)r   r   )Z_history_userr   contextr   r   is_authenticatedr4   )rD   r   r   r   r   r    r     s    z"HistoricalRecords.get_history_user)N)N)N)rR   rI   __qualname__LocalContextthreadr   r   ZModelr!   r(   r)   rF   rX   rO   rN   rp   re   r}   rs   r   r   r   r   ru   rw   rh   ri   r   r   r   r   r   r    r*   :   sL   

2&6\


-r*   c                 C   s   | j | _t| tjrtj| _n@t| tjr4tj| _n*t| tj	r^t
tddrVtj| _ntj| _d| _d| _d| _| js|| jrd| _d| _d| _d| _dS )z9Customize field appropriately for use in historical modelZ%SIMPLE_HISTORY_FILEFIELD_TO_CHARFIELDFNT)r   rV   r>   r   ZBigAutoFieldZBigIntegerFieldr   r   r   Z	FileFieldr   r   r   r   Zauto_nowZauto_now_addZdb_collationr   r   _uniquer   r   )r|   r   r   r    r   !  s"    


r   c                   @   s   e Zd Zdd Zdd ZdS )r   c                 C   s   || _ || _d S r   )ro   r}   )rD   ro   r}   r   r   r    rF   A  s    z#HistoricalObjectDescriptor.__init__c                    s$    fdd| j D }| jf i |S )Nc                    s   i | ]}|j t |j qS r   r   )r   fr   r   r    r   F      z6HistoricalObjectDescriptor.__get__.<locals>.<dictcomp>)r}   ro   )rD   r   ownerr   r   r   r    __get__E  s    z"HistoricalObjectDescriptor.__get__N)rR   rI   r   rF   r   r   r   r   r    r   @  s   r   c                   @   s   e Zd ZdddZdS )rA   Nc                 C   s   t |t| s&tdt| t||d u r2g }g }g }t|j}t| j}| D ]J\}}||v rhqV||v rV|| }	|	|krVt||	|}
||
 || qVt	|||| S )Nz.unsupported type(s) for diffing: '{}' and '{}')
r>   rv   r@   rQ   r   r   itemsModelChanger{   
ModelDelta)rD   Zold_historyr=   changeschanged_fieldsZ
old_valuesZcurrent_valuesr|   	new_value	old_valueZchanger   r   r    diff_againstK  s,    


zHistoricalChanges.diff_against)N)rR   rI   r   r   r   r   r   r    rA   J  s   rA   c                   @   s   e Zd Zdd ZdS )r   c                 C   s   || _ || _|| _d S r   )r|   oldnew)rD   
field_namer   r   r   r   r    rF   f  s    zModelChange.__init__NrR   rI   r   rF   r   r   r   r    r   e  s   r   c                   @   s   e Zd Zdd ZdS )r   c                 C   s   || _ || _|| _|| _d S r   )r   r   
old_record
new_record)rD   r   r   r   r   r   r   r    rF   m  s    zModelDelta.__init__Nr   r   r   r   r    r   l  s   r   )<r   rf   r   rS   Zdjango.appsr   Zdjango.confr   Zdjango.contribr   Zdjango.contrib.authr   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.db.modelsr   r	   Zdjango.db.models.fields.proxyr
   Zdjango.forms.modelsr   Zdjango.urlsr   Zdjango.utilsr   Zdjango.utils.encodingr   Zdjango.utils.textr   Zdjango.utils.translationr   r   Zsimple_historyr    r   r   r   rL   r   r   r   Zasgiref.localr   r   ImportError	threadingr   rx   r!   r(   r)   r*   r   r   rA   r   r   r   r   r   r    <module>   sN   
   j
