
    h>              
          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	m
Z
mZ d dlmZ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) ddl*m+Z+ ddl,m-Z- 	 d dl.m/Z/ dejb                  de!de2fdZ3de4ejj                     de4de4ejj                     fdZ6de4ejj                     de4d ejn                  fd!Z8dQd"e9e4ejb                     e4f   d eejn                     fd#Z:dQd eejn                     fd$Z;d% Z<d& Z=d'e4ejb                     fd(Z>d) Z?ed'e4ejb                     fd*       Z@ed'e4ejb                     fd+       ZAd, ZBd-ejb                  fd.ZCd/ejb                  fd0ZDd1ed2ejb                  de2fd3ZEdRd4ZFdQd5ee4ejb                        deGeH   fd6ZI	 dQdejb                  d7eeJ   deJfd8ZKd'e4d9eJdeJfd:ZLd;ej                  dej                  fd<ZN	 dRd/ejb                  d=e2dejb                  fd>ZOd?e	d7eJde
fd@ZPdAejb                  dBe4dejb                  fdCZQdD ZRdE ZSdej                  fdFZUd2ej                  de2fdGZVd-ejb                  d2ej                  de2fdHZWd1ed2ej                  de2fdIZXdJeYdKeJdLeJdMeZdeHf
dNZ[dOejb                  dejb                  fdPZ\y# e0$ r dZ/Y Nw xY w)S    N)Iterable)contextmanager)Optional)PagePageContentPlaceholder)get_object_edit_urlget_object_preview_url)is_editable_model)add_url_parametersadmin_reverse)settings)admin)GenericRelation)ContentType)EmailMessage)models)HttpRequest)render_to_string)	force_str)get_language   )versionables)!EMAIL_NOTIFICATIONS_FAIL_SILENTLY)DRAFT)emit_content_changecontent_objrequestreturnc                     ddl m} |j                  j                  |       j                  j                  |j                        S )z Check of content_obj is editabler   Version)r   r"   objectsget_for_contentcheck_modifyas_booluser)r   r   r"   s      L/home/dcms/DCMS/lib/python3.12/site-packages/djangocms_versioning/helpers.pyis_editabler)       s4    ??**;7DDLL     admin_classmixinc                 V    t        | |      st        d| j                   || fi       S | S )zA class factory returning admin class with overriden
    versioning functionality.

    :param admin_class: Existing admin class
    :param mixin: Mixin class
    :return: A subclass of `VersioningAdminMixin` and `admin_class`
    	Versioned)
issubclasstype__name__)r+   r,   s     r(   versioning_admin_factoryr2   )   s8     k5) i 4 4568LbQQr*   
modeladmin
admin_sitec                     t        | |      ryt        | j                  |      }|j                  | j                         |j                  | j                  |       y)a?  Replaces existing admin class registered for `modeladmin.model` with
    a subclass that includes versioning functionality.

    Doesn't do anything if `modeladmin` is already an instance of
    `mixin`.

    :param model: ModelAdmin instance
    :param mixin: Mixin class
    :param admin_site: AdminSite instance
    N)
isinstancer2   	__class__
unregistermodelregister)r3   r,   r4   new_admin_classs       r(   _replace_admin_for_modelr<   8   sM     *e$.z/C/CUKO***+
((/:r*   pairsc                     |t         j                  }| D ]"  \  }}	 |j                  |   }t	        |||       $ y# t        $ r Y 1w xY w)zr
    :param models: List of (model class, admin mixin class) tuples
    :param admin_site: AdminSite instance
    N)r   site	_registryKeyErrorr<   )r=   r4   r9   r,   r3   s        r(   replace_admin_for_modelsrB   J   s_    
 ZZ
 @u	#--e4J 	!UJ?@  		s   ;	AAc                     ddl m} |t         j                  } j                  |j                  v r*t        j                   j                  dt        d       y G  fdd|      }t         j                  j                  |j                  z   |t         j                  fi       }|j                   j                  |       y)	ah  Creates a model admin class based on `VersionAdmin` and registers
    it with `admin_site` for `versionable.version_model_proxy`.

    This model class applies filtering on the list of versions,
    so that only versions for `versionable.content_model` are shown.

    :param versionable: VersionableItem instance
    :param admin_site: AdminSite instance
    r   )VersionAdminNz" is already registered with admin.   
stacklevelc                   "     e Zd Z fdZ xZS );register_versionadmin_proxy.<locals>.VersionProxyAdminMixinc                 V    t         |   |      j                  j                        S )N)content_type__in)superget_querysetfiltercontent_types)selfr   r7   versionables     r(   rM   zHregister_versionadmin_proxy.<locals>.VersionProxyAdminMixin.get_querysetr   s*     %&)B)BCr*   )r1   
__module____qualname__rM   __classcell__)r7   rQ   s   @r(   VersionProxyAdminMixinrI   q   s    	 	r*   rU   )r   rD   r?   version_model_proxyr@   warningswarnUserWarningr0   grouper_modelr1   
ModelAdminr:   )rQ   r4   rD   rU   ProxiedAdmins   `    r(   register_versionadmin_proxyr]   Y   s     $ZZ
&&**>*>>..11ST	

 	  !!**\-B-BB	!1!12
L 77Fr*   c                 >    t        || j                  z   || fddi      S )zA class factory returning a manager class with an added mixin to override for
    versioning functionality.

    :param manager: Existing manager class
    :return: A subclass of `PublishedContentManagerMixin` and `manager`
    use_in_migrationsF)r0   r1   )managerprefixr,   s      r(   manager_factoryrb      s/     !!!		e$ r*   c                    t        | |      rt        t        | |      |      ry t        | |      rt        | |      j                  nt        j
                  } t        |d|             }|j                         D ]  \  }}t        |||        | j                  j                  D cg c]  }|j                  |k7  s| c}| j                  _
        | j                  ||       |dk(  r"| j                  d|dk(  rdn|  |              y y c c}w )Nr.   r#   
_original_r`   )hasattrr6   getattrr7   r   Managerrb   itemssetattr_metalocal_managersnameadd_to_class)	r9   r`   r,   kwargsoriginal_managermanager_objectkeyvaluemngrs	            r(   replace_managerrt      s    ug:geW.Eu#M-4UG-Dw))&..  K_%5{EJLNlln ,
UU+, 33"tyyG7K"EKK 
w/)g&:HI	
 	"s   %D
:D
r9   c                     ddl m} | j                  j                   d| j                  j                   }| j                  dt        ||             t        | d      s| j                  dt               y y )Nr   r!   _versions)related_query_namer)   )	r   r"   rj   	app_label
model_namerm   r   re   r)   )r9   r"   rx   s      r(   "inject_generic_relation_to_versionr{      sh    !KK112!EKK4J4J3KL	OG@RS 5-(=+6 )r*   c                     | j                   j                  D cg c]  }|j                  dk7  s| c}| j                   _        t        j                  |      }d|_        | j	                  d|       y c c}w )Nr#   )rj   rk   rl   copyrm   )r9   r`   mmanager_s       r(   _set_default_managerr      s_    ;;--"91D"EKK yy!HHM	y(+"s
   A3A3c              #   \   K   | j                   }t        | |       d  t        | |       y wN)r#   r   )r9   r`   ro   s      r(   override_default_managerr      s(     }}(	 01   *,c              #   \   K   | j                   j                  }d|_        d  d|_        y w)NFT)r#   r7   versioning_enabled)r9   manager_clss     r(   nonversioned_managerr      s(     --))K%*K"	%)K"r   c                     | j                   }t        t        |j                  j                   d|j                  j
                   d      fi |S )Nrv   _changelist)rV   r   r   rj   ry   rz   )rQ   paramsproxys      r(   _version_list_urlr      sM    ++E../q1G1G0HTU
 r*   contentc                     t        j                         j                  | j                     }t	        |fi |j                  | d      S )zYReturns a URL to list of content model versions,
    filtered by `content`'s grouper
    F)relation_suffix)r   _cms_extensionversionables_by_contentr7   r   grouping_values)r   rQ   s     r(   version_list_urlr      sP     --/GGK "227E2R r*   grouperc                     t        j                         j                  | j                     }t	        |fi |j
                  t        | j                        iS )zOReturns a URL to list of content model versions,
    filtered by `grouper`
    )r   r   versionables_by_grouperr7   r   grouper_field_namestrpk)r   rQ   s     r(   version_list_url_for_grouperr      sS     --/GGK #66GJJH r*   placeholderr'   c                     	 t        j                  | j                         ddlm} |j                  j                  | j                        }|j                  t        k(  S # t        $ r Y yw xY w)a  A helper method for monkey patch to check version is in edit state.
    Returns True if placeholder is related to a source object
    which is not versioned.

    :param placeholder: current placeholder
    :param user: user object
    :return: Boolean
    Tr   r!   )
r   for_contentsourcerA   r   r"   r#   r$   stater   )r   r'   r"   versions       r(   is_content_editabler      s]      !3!34  oo--k.@.@AG==E!!  s   A 	A+*A+c                     t        | j                        r|st        | dd      }t        | |      }|S t	        | j
                  j                   d| j
                  j                   d| j                  f      }|S )zIf the object is editable the cms editable view should be used, with the toolbar.
    This method provides the URL for it.
    languageNrv   _changeargs)	r   r7   rf   r	   r   rj   ry   rz   r   )r   force_adminr   urls       r(   get_editable_urlr      s|     ../;
D9!+x8 J	   **+1[->->-I-I,J'R.."
 Jr*   r   c                    t               }| D ]{  }t        j                  j                  |      j	                  |d      }|j                  |j                         |j                         }|sa|j                  t        ||             } |S )NF)for_concrete_model)
setr   r#   
db_managerget_for_modeladdr   __subclasses__update!get_content_types_with_subclasses)r   usingrO   r9   content_type
subclassess         r(   r   r     s    EM W"**55e<JJe K 
 	,//*))+
  !B:u!UVW r*   r   c                    t        j                  |       }|j                  r|j                  |       S t        | j                        r&|st        | dt                     }t        | |      }|S t        | j                  j                   d| j                  j                   d| j                  g      }|r|d| z  }|S )zIf the object is editable the cms preview view should be used, with the toolbar.
    This method provides the URL for it. It falls back the standard change view
    should the object not be frontend editable.
    r   r   rv   r   r   z
&language=)r   r   preview_urlr   r7   rf   r   r
   r   rj   ry   rz   r   )r   r   rQ   r   s       r(   get_preview_urlr     s     **;7K&&{33../{JGH$[8D J   **+1[->->-I-I,J'R..!
 Zz**CJr*   actionc                 p    | j                   }|j                   d|j                   d| }t        ||      S )Nrv   r   )rj   ry   rz   r   )r9   r   r   optsurl_names        r(   get_admin_urlr   5  s8    ;;D..!4??"31VH=H--r*   querysetc                     t        d      )z
    By default, the versioned queryset filters out so that only versions
    that are published are returned. If you need to return the full queryset
    use the "admin_manager" instead of "objects"
    zDremove_published_where has been replaced by ContentObj.admin_manager)NotImplementedError)r   s    r(   remove_published_wherer   ;  s     N r*   include_unpublished_archivedc                    t        j                  |       }|j                  D cg c]  }||vr|
 }}|rt        d| d|j                   d      |j
                  j                  j                         } t        | |      d      }|r. |j                  di |j                         j                         S  |j                  di |j                         j                         S c c}w )zY
    Return the latest Draft or Published PageContent using the draft where possible
    zGrouping field(s) z required for .admin_manager)r`    )r   for_grouperextra_grouping_fields
ValueErrorrZ   grouper_fieldremote_fieldget_accessor_namerf   rN   latest_contentfirstcurrent_content)r   r   r   rQ   fieldmissing_fieldscontent_setqss           r(   !get_latest_admin_viewable_contentr   F  s     **73K
 !66-- 	N 
   0{?X?X>YYZ[
 	

 ++88JJLK 
'+	&	?B#ryy101@@BHHJJ299-,-==?EEGG)s   C&pagec                 T    t        j                  dt        d       t        | |      S )Nzget_latst_admin_viewable_page_content has ben deprecated. Use get_latest_admin_viewable_content(page, language=language) instead.rE   rF   r   )rW   rX   DeprecationWarningr   )r   r   s     r(   &get_latest_admin_viewable_page_contentr   h  s+     MM	R	 -THEEr*   objcontent_modelc                 |    t        j                  |      }t        j                  |       }|j                  |_        |S )z
    Get the proxy model from a

    :param obj: A registered versionable object
    :param content_model: A registered content model
    )r   r   r}   deepcopyrV   r7   )r   r   rQ   obj_s       r(   proxy_modelr   t  s4     **=9K==D 44DNKr*   c                     | j                   |k7  }|| _         | j                          |rt        rt        | j                         | S )z,
    Create a version lock if necessary
    )	locked_bysaver   r   )r   r'   changeds      r(   create_version_lockr     s<     4'GGLLN&GOO,Nr*   c                     t        | d      S )zG
    Delete a version lock, handles when there are none available.
    N)r   r   s    r(   remove_version_lockr     s     w--r*   c                     | j                   S )z*
    Determine if a version is locked
    r   r   s    r(   version_is_lockedr     s     r*   c                 @    | j                   du xs | j                   |k(  S )zOCheck if lock doesn't exist for a version object or is locked to provided user.Nr   )r   r'   s     r(   version_is_unlocked_for_userr     s#    $A(9(9T(AAr*   c                     	 t        | d      r| j                  d   }n| j                  j                         }t	        ||      S # t
        $ r Y yw xY w)zACheck if lock doesn't exist or object is locked to provided user.prefetched_versionsr   T)re   r   rw   r   r   AttributeError)r   r'   r   s      r(   content_is_unlocked_for_userr     sU    71211!4G&&,,.G+GT:: s   AA 	AAc                 2    | j                   }t        ||      S )z]Check if lock doesn't exist or placeholder source object
    is locked to provided user.
    )r   r   )r   r'   r   s      r(   (placeholder_content_is_unlocked_for_userr     s       G'66r*   
recipientssubjecttemplatetemplate_contextc                     d| }t        |      }t        ||      }t        ||t        j                  |       }|j                  t              S )z-
    Send emails using locking templates
    zdjangocms_versioning/emails/)r   body
from_emailto)fail_silently)r   r   r   r   DEFAULT_FROM_EMAILsendr   )r   r   r   r   r   messages         r(   
send_emailr     sW     .hZ8H Gx)9:G..	G <<&G<HHr*   r   c                 n   ddl m} t        | j                  d      r,t	        | j                  j
                  dt              t        k7  rX|j                  j                  | j                        j                  t              }|j                         | j                  _        | j                  j
                  S )zRGet latest draft version of version object and caches it in the
    content objectr   r!   _latest_draft_versionr   )r   )r   r"   re   r   rf   r  r   r#   !filter_by_content_grouping_valuesrN   r   )r   r"   draftss      r(   get_latest_draft_versionr    s       GOO%<=7??88'5IURBBOO

&u&
 	 17-??000r*   r   )F)]r}   rW   collections.abcr   
contextlibr   typingr   
cms.modelsr   r   r   cms.toolbar.utilsr	   r
   cms.utils.helpersr   cms.utils.urlutilsr   r   django.confr   django.contribr   "django.contrib.contenttypes.fieldsr   "django.contrib.contenttypes.modelsr   django.core.mailr   	django.dbr   django.httpr   django.template.loaderr   django.utils.encodingr   django.utils.translationr    r   confr   	constantsr    djangocms_internalsearch.helpersr   ImportErrorModelboolr)   r0   r[   r2   	AdminSiter<   tuplerB   r]   rb   rt   r{   r   r   r   r   r   r   r   r   r   intr   r   r   r   QuerySetr   r   r   r   r   r   AUTH_USER_MODELr   r   r   r   listdictr   r  r   r*   r(   <module>r%     s     $ %  5 5 I / @     > : )  # 3 + 1  3 D
V\\ K D $u/?/?*@  RVW\WgWgRh ;e.>.>)? ; ;Z_ZiZi ;$@E$v||*<d*B$C @QYZ_ZiZiQj @&G%//9R &GR
*7d6<<.@ 7, 2D$6 2 2 *V\\ 2 * *	fll 		&,, 	"[ " " "&$
htFLL7I.J 
[^_b[c 
 :>)1#4. .s .c .V__   */H\\H"&H \\	HD	F
	F	F	F
V\\ 
$ 
6<< 
	.(":": B0H0H BT B
\\!)!9!9	77$,$<$<7	7II"I.1IEIII&1fll 1v|| 1_  s   
K KK