a
    YÒOcý4  ã                   @   s~   d dl mZ zd dlZW n ey.   dZY n0 G dd„ dƒZG dd„ deƒZG dd„ dƒZG d	d
„ d
ƒZG dd„ deƒZdS )é    )ÚValidationErrorNc                   @   s    e Zd ZdZdd„ Zedd„ ƒZedd„ ƒZedd	„ ƒZed
d„ ƒZ	edd„ ƒZ
edd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZdd„ Zdd„ ZdS )ÚVersionzt
    Object version interface - extend to support
    different types of django object versioning
    solutions
    c                 C   s
   || _ dS )zŒ
        Argument(s):

            - version: version object instance, for example
                django reversion Version object

        N)Úversion©Úselfr   © r   úO/var/www/html/gsl.tools/lib/python3.9/site-packages/django_handleref/version.pyÚ__init__   s    	zVersion.__init__c                 C   s
   t ƒ ‚dS )z>
        Should return version date (datetime object)
        N©ÚNotImplementedError©r   r   r   r   Údate   s    zVersion.datec                 C   s
   t ƒ ‚dS )zz
        Should return user (django User object) that commited the version
        or None if no such user exists
        Nr
   r   r   r   r   Úuser#   s    zVersion.userc                 C   s
   t ƒ ‚dS )z]
        Should return the internal version id (primary
        key in the database)
        Nr
   r   r   r   r   Úid+   s    z
Version.idc                 C   s
   t ƒ ‚dS )zg
        Should return comment (str) for the version
        or None if no such comment exists
        Nr
   r   r   r   r   Úcomment3   s    zVersion.commentc                 C   s
   t ƒ ‚dS )z�
        Should return a dict of the object snapshot
        store in this version, with field names mapping
        to field values
        Nr
   r   r   r   r   Údata;   s    zVersion.datac                 C   s
   t ƒ ‚dS )zp
        Should return `data` in list form with (field, value)
        tuples as items, sorted by field
        Nr
   r   r   r   r   Údata_sortedD   s    zVersion.data_sortedc                 C   s
   t ƒ ‚dS )zg
        Should return the django model class of the object
        snapshotted by the version
        Nr
   r   r   r   r   ÚmodelL   s    zVersion.modelc                 C   s
   t ƒ ‚dS )zÁ
        Should return a Version instance holding the previous
        version neighbour of this version

        If no previous version exists return an empty Version
        instance
        Nr
   r   r   r   r   ÚpreviousT   s    	zVersion.previousc                 C   s
   t ƒ ‚dS )z¹
        Should return a Version instance holding the next
        version neighbour of this version

        if no next version exists return an empty Version
        instance
        Nr
   r   r   r   r   Únext_   s    	zVersion.nextc           	      C   s‚   i }|D ]X}|  |j¡}| ¡ D ]>\}}||vr8i ||< d|i}| |¡ ||  |j|i¡ q qt| ¡ ƒ}t|dd„ d�}|S )aÇ  
        Compiles and return a changes summary of multiple
        Version objects.

        Argument(s):

            - versions(list): list of Version instances

        Returns:

            - list: a list of (field, dict) tuples where
                the dict will be mapping version ids to a
                dict containing changes made to the field
                by the version. Check `Diff` class for
                further information

        r   c                 S   s   | d S ©Nr   r   ©Úir   r   r   Ú<lambda>ˆ   ó    z)Version.changes_summary.<locals>.<lambda>©Úkey)Úchangesr   ÚitemsÚupdater   ÚlistÚsorted)	r   Úversionsr   r   Z_changesÚfieldÚdiffZ_diffZchanges_listr   r   r   Úchanges_summaryj   s    
zVersion.changes_summaryc                 C   s   t || ƒjS )z»
        Return a `Diff` instance for this version
        and a previous version

        Argument(s):

            - previous(Version)

        Returns(s):

            - Diff

        )ÚDiffr   )r   r   r   r   r   r   ‹   s    zVersion.changesc                 C   s"   |   |¡}|du rdS t| ¡ ƒS )zÈ
        Return a list of changed fields between
        this version and a previous version

        Argument(s):

            - previous(Version)

        Returns:

            - list(str)

        N)r   r!   Úkeys)r   r   r   r   r   r   Úchanged_fieldsœ   s    
zVersion.changed_fieldsN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r	   Úpropertyr   r   r   r   r   r   r   r   r   Úclassmethodr%   r   r(   r   r   r   r   r   	   s0   











 r   c                       sŒ   e Zd ZdZ‡ fdd„Zedd„ ƒZedd„ ƒZedd	„ ƒZed
d„ ƒZ	edd„ ƒZ
edd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZ‡  ZS )ÚReversionVersionz1
    Version abtraction for django-reversion
    c                    s,   t |tƒrtjjjj|d�}tƒ  |¡ dS )z¡
        Argument(s):

            - Version(int|reversion.models.Version): can be either
                a reversion version instance or the id of one

        )r   N)	Ú
isinstanceÚintÚ	reversionÚmodelsr   ÚobjectsÚgetÚsuperr	   r   ©Ú	__class__r   r   r	   ¸   s    
zReversionVersion.__init__c                 C   s
   | j jjS )zE
        Returns:

            - datetime: date of revision

        )r   ÚrevisionZdate_createdr   r   r   r   r   Ä   s    zReversionVersion.datec                 C   s
   | j jjS )zw
        Returns:

            - User: user that authored revision
            - None: if no such user exists

        )r   r9   r   r   r   r   r   r   Î   s    	zReversionVersion.userc                 C   s
   | j jjS )zz
        Returns:

            - str: comment stored with revision
            - None: if no such comment exists

        )r   r9   r   r   r   r   r   r   Ù   s    	zReversionVersion.commentc                 C   s   | j jS )zB
        Returns:

            - int:version instance id

        )r   r   r   r   r   r   r   ä   s    zReversionVersion.idc                 C   s   | j jS )z<
        Returns:

            - dict: object data

        )r   Z
field_dictr   r   r   r   r   î   s    zReversionVersion.datac                 C   s   | j jS )zy
        Returns:

            - model: django model for the object
                snapshotted by this version

        )r   Ú_modelr   r   r   r   r   ø   s    	zReversionVersion.modelc                 C   s6   g }| j  ¡ D ]\}}| ||f¡ qt|dd„ d�S )zn
        Returns:

            - list: list of (field, value) tuples for
                object data

        c                 S   s   | d S r   r   r   r   r   r   r     r   z.ReversionVersion.data_sorted.<locals>.<lambda>r   )r   r   Úappendr!   )r   r   r#   Úvaluer   r   r   r     s    	zReversionVersion.data_sortedc                 C   s\   t | dƒr| jS tjjj | jj¡ 	d¡}|D ](}|j
| jj
k r.|  |¡| _| j  S q.dS )z—
        Returns:

            - Version: previous version - if no previous version exists
                the Version instance will be empty

        Ú	_previousz-idN)Úhasattrr=   r2   r3   r   r4   Zget_for_objectr   ÚobjectÚorder_byr   r8   )r   r"   r   r   r   r   r     s    


ÿþzReversionVersion.previousc                 C   sR   t | dƒr| jS tjjjj| jj| jj	| jj
d�}| d¡}|  | ¡ ¡| _| jS )z�
        Returns:

            - Version: next version - if no next version exists
                the Version instance will be empty

        Ú_next)Úcontent_type_idÚ	object_idZid__gtr   )r>   rA   r2   r3   r   r4   Úfilterr   rB   rC   r   r@   r8   Úfirst)r   Zqsetr   r   r   r   +  s    


ý
zReversionVersion.next)r)   r*   r+   r,   r	   r-   r   r   r   r   r   r   r   r   r   Ú__classcell__r   r   r7   r   r/   ²   s(   
	




	
	



r/   c                   @   s4   e Zd ZdZg d¢Zdd„ Zedd„ ƒZdd„ Zd	S )
r&   z0
    Describes changes between two versions
    )r   ÚcreatedÚupdatedc                 C   s   || _ || _dS )z€
        Argument(s):

            - version_a(Version): older version
            - version_b(Version): newer version

        N)Ú	version_aÚ	version_b)r   rI   rJ   r   r   r   r	   O  s    
zDiff.__init__c                 C   s¬   | j r| jsdS | j jr | jjs$dS | j j}| jj}i }| ¡ D ]f\}}|| jv rTq@| |¡}||krhq@t|tƒs|t|t	ƒrŒ||dœ||< q@|  
|¡|  
|¡dœ||< q@|S )a·  
        Compile and return a dict describing changes between
        the two versions tracked in this diff

        Returns:

            - dict: dict mapping field names to a dict describing
              changed made to the field


              {
                  field_name: {
                      "old": old_value,
                      "changed": changed_value,
                  },
                  ...
              }

        N)ÚoldÚchanged)rI   rJ   r   r   r   Údiff_ignore_fieldsr5   r0   Ústrr1   Úformat_value)r   Zdata_aZdata_br$   r#   Zvalue_bZvalue_ar   r   r   r   \  s&    

þzDiff.changesc                 C   s   |› S )Nr   )r   r<   r   r   r   rO   ‘  s    zDiff.format_valueN)	r)   r*   r+   r,   rM   r	   r-   r   rO   r   r   r   r   r&   A  s   
4r&   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚReverterz-
    Allows to revert / rollback changes
    c                 K   sR   |  ¡ D ]4\}}t|||j| ƒ |dkr|  ||j| ¡ q| ¡  | ¡  dS )aQ  
        Revert a set of fields

        Argument(s):

            - instance(model instance): instance of django model
              to be reverted
            - field_versions(dict): dict mapping field names to
              version object

        Raises:

            - ValidationError: if any of the fields fail validation

        ÚstatusN)r   Úsetattrr   Úvalidate_status_changeÚ
full_cleanÚsave)r   ÚinstanceÚfield_versionsÚkwargsr#   r   r   r   r   Úrevert_fields›  s    zReverter.revert_fieldsc                 K   sR   |j  ¡ D ]2\}}|dv rq
|dkr0|  ||¡ t|||ƒ q
| ¡  | ¡  dS )a4  
        Rollback to a specific version

        Argument(s):

            - instance(model instance): instance of django model
              to be reverted
            - version(Version): version to roll back to

        Raises:

            - ValidationError: if any of the fields fail validation

        )rG   rH   r   rQ   N)r   r   rS   rR   rT   rU   )r   rV   r   rX   r#   r<   r   r   r   Úrollback´  s    zReverter.rollbackc              	   C   sZ   |j j ¡ D ]H}|jr|jsqzt||jƒ}W n tyD   Y qY n0 |  |||¡ qdS )a9  
        Validate a status value change - this will make sure
        an object cannot be undeleted if a parent relationship
        is still flagged as deleted

        Argument(s):

            - instance(model instance): instance of django model
              to be reverted
            - status(str)

        N)	r8   Ú_metaZ
get_fieldsZis_relationZmany_to_oneÚgetattrÚnameÚ	ExceptionÚvalidate_parent_status)r   rV   rQ   r#   Zrelationr   r   r   rS   Î  s    
zReverter.validate_status_changec                 C   s6   t |dƒsd S |jdkr2|dkr2tdd |¡iƒ‚d S )NZ	HandleRefZdeletedZnon_field_errorsztParent object {} is currently flagged as deleted.This object may not be undeleted while the parent is still deleted.)r>   rQ   r   Úformat)r   rV   ÚparentrQ   r   r   r   r_   æ  s    
þÿÿzReverter.validate_parent_statusN)r)   r*   r+   r,   rY   rZ   rS   r_   r   r   r   r   rP   •  s
   rP   c                       s0   e Zd ZdZd‡ fdd„	Zd‡ fdd„	Z‡  ZS )	ÚReversionReverterz3
    Reverter abstraction for django-reversion
    Nc                    s|   t  ¡ �` |rt  |¡ dd„ | ¡ D ƒ}tt|ƒƒ}t  d d |¡¡¡ t	ƒ  
||¡ W d  ƒ n1 sn0    Y  dS )a¦  
        Revert a set of fields

        Argument(s):

            - instance(model instance): instance of django model
              to be reverted
            - field_versions(dict): dict mapping field names to
              version pk

        Keyword Argument(s):

            - user(User): user that authored the revision

        Raises:

            - ValidationError: if any of the fields fail validation

        c                 S   s   g | ]}d   |jd ¡‘qS )z{}r   )r`   r   )Ú.0r   r   r   r   Ú
<listcomp>  s   ÿz3ReversionReverter.revert_fields.<locals>.<listcomp>z%reverted some fields via versions: {}z, N)r2   Úcreate_revisionÚset_userÚvaluesr    ÚsetÚset_commentr`   Újoinr6   rY   )r   rV   rW   r   Zversion_idsr7   r   r   rY   û  s    

þÿzReversionReverter.revert_fieldsc                    s^   t  ¡ �B |rt  |¡ t  d |jd ¡¡ tƒ  ||¡ W d  ƒ n1 sP0    Y  dS )a�  
        Rollback to a specific version

        Argument(s):

            - instance(model instance): instance of django model
              to be reverted
            - version(Version): version to roll back to

        Keyword Argument(s):

            - user(User): user that authored the revision

        Raises:

            - ValidationError: if any of the fields fail validation

        zrollback to version {}r   N)r2   re   rf   ri   r`   r   r6   rZ   )r   rV   r   r   r7   r   r   rZ     s    

ÿzReversionReverter.rollback)N)N)r)   r*   r+   r,   rY   rZ   rF   r   r   r7   r   rb   õ  s   #rb   )	Zdjango.core.exceptionsr   r2   ÚImportErrorr   r/   r&   rP   rb   r   r   r   r   Ú<module>   s   
 * T`