a
    Dg7                     @   s   d dl Z d dl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 dlmZ d dlmZ d dlmZ eeZG d	d
 d
eZG dd dZG dd deZG dd deZdS )    N)OrderedDict)	JSONFieldFQSubqueryOuterRef)Cast)	RunPython)cached_property)StreamValue)utilsc                       sB   e Zd ZdZd fdd	Z fddZedd	 Zd
d Z  Z	S )MigrateStreamDataz?Subclass of RunPython for streamfield data migration operationsN   c                    sF   || _ || _|| _|| _|| _|| _t jf | jdd d| dS )as  MigrateStreamData constructor

        Args:
            app_name (str): Name of the app.
            model_name (str): Name of the model.
            field_name (str): Name of the streamfield.
            operations_and_block_paths (:obj:`list` of :obj:`tuple` of (:obj:`operation`, :obj:`str`)):
                List of operations and corresponding block paths to apply.
            revisions_from (:obj:`datetime`, optional): Only revisions created from this date
                onwards will be updated. Passing `None` updates all revisions. Defaults to `None`.
                Note that live and latest revisions will be updated regardless of what value this
                takes.
            chunk_size (:obj:`int`, optional): chunk size for queryset.iterator and bulk_update.
                Defaults to 1024.
            **kwargs: atomic, elidable, hints for superclass RunPython can be given

        Example:
            Renaming a block named `field1` to `block1`::
                MigrateStreamData(
                    app_name="blog",
                    model_name="BlogPage",
                    field_name="content",
                    operations_and_block_paths=[
                        (RenameStreamChildrenOperation(old_name="field1", new_name="block1"), ""),
                    ],
                    revisions_from=datetime.date(2022, 7, 25)
                ),
        c                  W   s   d S N )argsr   r   j/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/wagtail/blocks/migrations/migrate_operation.py<lambda>C       z,MigrateStreamData.__init__.<locals>.<lambda>)codeZreverse_codeN)	app_name
model_name
field_nameoperations_and_block_pathsrevisions_from
chunk_sizesuper__init__migrate_stream_data_forward)selfr   r   r   r   r   r   kwargs	__class__r   r   r      s    'zMigrateStreamData.__init__c                    sZ   t   \}}}| j|d< | j|d< | j|d< | j|d< | j|d< | j|d< | jj	||fS )Nr   r   r   r   r   r   )
r   deconstructr   r   r   r   r   r   r"   __qualname__)r   _r   r    r!   r   r   r#   G   s    





zMigrateStreamData.deconstructc                 C   s"   t dd | jD }d| S )Nc                 s   s   | ]\}}|j d fV  qd S r   )Zoperation_name_fragment).0opr%   r   r   r   	<genexpr>V   s   z<MigrateStreamData.migration_name_fragment.<locals>.<genexpr>r%   )r   r   joinkeys)r   	fragmentsr   r   r   migration_name_fragmentR   s    z)MigrateStreamData.migration_name_fragmentc                 C   s  | | j| j}z| dd t||| j}W n  tyN   t||| j}Y n0 |jjt	t
| jt d }g }|j| jdD ]}|jd u rq|| |j}| jD ]^\}	}
ztj||
|	t|| jd}W q tjy } ztj|d|W Y d }~qd }~0 0 qt|| jj}t|| jt||dd || t|| jkr|j|| jg g }qt|d	kr~|j|| jg |jsd S | }g }|j| jdD ]}t |j!| j }| jD ]\}	}
ztj||
|	t|| jd}W nh tjyN } zL|"|s*t#$tj||d
 W Y d }~qntj||d
|W Y d }~n
d }~0 0 qt%||j!| j< || t|| jkr|| g }qt|d	kr|| d S )NwagtailcoreRevision)raw_content)r   )raw_datablock_path_str	operationZstreamfield)instanceT)Zis_lazyr   )revisionr3   )&	get_modelr   r   DefaultRevisionQueryMakerr   LookupErrorWagtail3RevisionQueryMakerobjectsZannotater   r   r   r   alliteratorr   r/   'append_instance_data_for_revision_queryr   r   Zapply_changes_to_raw_datagetattrZInvalidBlockDefErrorstream_blocksetattrr   appendlenbulk_updatehas_revisionsget_revision_querysetjsonloadscontentget_is_live_or_latest_revisionlogger	exceptiondumps)r   appsZschema_editormodelZrevision_query_makerZmodel_querysetZupdated_model_instances_bufferr3   r0   r2   r1   er>   Zrevision_querysetZupdated_revisions_bufferr4   r   r   r   r   \   s    





&




z-MigrateStreamData.migrate_stream_data_forward)Nr   )
__name__
__module__r$   __doc__r   r#   propertyr,   r   __classcell__r   r   r!   r   r      s     6
	r   c                   @   sP   e Zd Z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S )AbstractRevisionQueryMakerzHHelper class for making the revision query needed for the data migrationc                 C   s8   || _ || _|| _|  | _|  | _| jr4t | _d S r   )	rL   rM   r   get_revision_modelRevisionModelget_has_revisionsrC   setinstance_field_revision_idsr   rL   rM   r   r   r   r   r      s    

z#AbstractRevisionQueryMaker.__init__c                 C   s   t d S r   NotImplementedErrorr   r   r   r   rU      s    z-AbstractRevisionQueryMaker.get_revision_modelc                 C   s   t d S r   r[   r]   r   r   r   rW      s    z,AbstractRevisionQueryMaker.get_has_revisionsc                 C   s   t d S r   r[   r   r3   r   r   r   r<      s    zBAbstractRevisionQueryMaker.append_instance_data_for_revision_queryc                 C   s   t d S r   r[   r]   r   r   r   _make_revision_query   s    z/AbstractRevisionQueryMaker._make_revision_queryc                 C   s   |   }| jj|S r   )r_   rV   r9   filterr   revision_queryr   r   r   rD      s    z0AbstractRevisionQueryMaker.get_revision_querysetc                 C   s   | j j|dg d S )NrG   )rV   r9   rB   )r   datar   r   r   rB      s    z&AbstractRevisionQueryMaker.bulk_updatec                 C   s   t d S r   r[   r   r4   r   r   r   rH      s    z9AbstractRevisionQueryMaker.get_is_live_or_latest_revisionN)rO   rP   r$   rQ   r   rU   rW   r<   r_   rD   rB   rH   r   r   r   r   rT      s   rT   c                       sT   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	e
dd Z  ZS )r8   z)Revision Query maker to support Wagtail 3c                    s   g | _ t ||| d S r   )page_idsr   r   rZ   r!   r   r   r      s    z#Wagtail3RevisionQueryMaker.__init__c                 C   s   | j ddS )Nr-   ZPageRevisionrL   r5   r]   r   r   r   rU      s    z-Wagtail3RevisionQueryMaker.get_revision_modelc                 C   s   t | j| jddS )Nr-   ZPage)
issubclassrM   rL   r5   r]   r   r   r   rW      s    z,Wagtail3RevisionQueryMaker.get_has_revisionsc                 C   s&   | j r"| j|j | j|j d S r   )rC   re   r@   idrY   addlive_revision_idr^   r   r   r   r<      s    zBWagtail3RevisionQueryMaker.append_instance_data_for_revision_queryc                 C   s~   | j d urnt| j | jd}|t| jdB }|tt| jjjtdd	ddj
ddd	d d
 | jdB }|S t| jdS d S )N)created_at__gtepage_id__inid__inpage_idro   -created_at-idrh   TZflat   rn   rl   )rl   )r   r   re   rY   r   rV   r9   r`   r   order_byvalues_listra   r   r   r   r_      s(    
z/Wagtail3RevisionQueryMaker._make_revision_queryc                 C   s   |j | jv rdS |j | jv S )NT)rh   rY   _latest_revision_idsrd   r   r   r   rH     s    z9Wagtail3RevisionQueryMaker.get_is_live_or_latest_revisionc                 C   sL   | j jjt| j jjtddddjdddd d | jd	jdddS )
Nro   rp   rq   rr   rh   Trs   rt   ru   )rV   r9   r`   r   r   rv   rw   re   r]   r   r   r   rx     s    z/Wagtail3RevisionQueryMaker._latest_revision_ids)rO   rP   r$   rQ   r   rU   rW   r<   r_   rH   r
   rx   rS   r   r   r!   r   r8      s   r8   c                       sH   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	  Z
S )r6   z#Revision Query Maker for Wagtail 4+c                    s    d| _ d| _t ||| d S )NF)has_live_revisionshas_latest_revisionsr   r   rZ   r!   r   r   r   )  s    z"DefaultRevisionQueryMaker.__init__c                 C   s   | j ddS )Nr-   r.   rf   r]   r   r   r   rU   /  s    z,DefaultRevisionQueryMaker.get_revision_modelc                 C   sP   t | jdo| jjjjj| ju | _t | jdo@| jjjjj| ju | _| jpN| jS )Nlatest_revisionlive_revision)	hasattrrM   r{   fieldZremote_fieldrV   rz   r|   ry   r]   r   r   r   rW   2  s    z+DefaultRevisionQueryMaker.get_has_revisionsc                 C   s2   | j r.| jr| j|j | jr.| j|j d S r   )rC   rz   rY   ri   Zlatest_revision_idry   rj   r^   r   r   r   r<   A  s
    zADefaultRevisionQueryMaker.append_instance_data_for_revision_queryc                 C   sX   | j dd}|j| jj}| jd urJt| j|d}|t| jdB }|S t|dS d S )NZcontenttypesContentType)rk   content_type_idrm   )r   )	rL   r5   r9   Zget_for_modelrM   rh   r   r   rY   )r   r   Zcontenttype_idrb   r   r   r   r_   K  s    
z.DefaultRevisionQueryMaker._make_revision_queryc                 C   s   |j | jv S r   )rh   rY   rd   r   r   r   rH   _  s    z8DefaultRevisionQueryMaker.get_is_live_or_latest_revision)rO   rP   r$   rQ   r   rU   rW   r<   r_   rH   rS   r   r   r!   r   r6   &  s   
r6   )rE   loggingcollectionsr   Zdjango.db.modelsr   r   r   r   r   Zdjango.db.models.functionsr   Zdjango.db.migrationsr	   Zdjango.utils.functionalr
   Zwagtail.blocksr   Zwagtail.blocks.migrationsr   	getLoggerrO   rI   r   rT   r8   r6   r   r   r   r   <module>   s   
 7%=