
    BhH                    d   d dl mZ d dlZd dlZd dlZd dlmZ d dlmZm	Z	 d dl
mZ d dl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 d dlmZ d dlmZ d dl m!Z! d dl"m#Z# ed        Z$ed        Z%d Z&d Z'd Z( G d d      Z) G d de      Z* G d dejV                  e*      Z,d Z-y)    )annotationsN)date)cachecached_property)ObjectDoesNotExist)
connectionconnectionsmodelsrouter)QuerySet)	ModelBase)timezone)	force_str)gettext_lazy)DontUsePageAttributeWarning)Placeholder)get_cms_setting)admin_reversec                     t        d      } | dk(  rd}nd}|j                  t        j                  j	                  t
        j                  j                              S )Nreadoraclea  WITH descendants (id, cms_plugin_position, cms_plugin_parent_id) as (SELECT {0}.id, {0}.position, {0}.parent_id  FROM {0} WHERE {0}.parent_id = %s UNION ALL SELECT {0}.id, {0}.position, {0}.parent_id FROM descendants, {0} WHERE {0}.parent_id = descendants.id)zWITH RECURSIVE descendants as (SELECT {0}.id, {0}.position, {0}.parent_id  FROM {0} WHERE {0}.parent_id = %s UNION ALL SELECT {0}.id, {0}.position, {0}.parent_id FROM descendants, {0} WHERE {0}.parent_id = descendants.id)_get_database_vendorformatr   ops
quote_name	CMSPlugin_metadb_table	db_vendorsqls     F/home/dcms/DCMS/lib/python3.12/site-packages/cms/models/pluginmodel.py_get_descendants_cter$      R    $V,IH 	 	 ::jnn//	0H0HIJJ    c                     t        d      } | dk(  rd}nd}|j                  t        j                  j	                  t
        j                  j                              S )Nr   r   zWITH ancestors AS (SELECT {0}.id, {0}.parent_id FROM {0} WHERE id = %s UNION ALL SELECT {0}.id, {0}.parent_id FROM {0} INNER JOIN ancestors ON {0}.id=ancestors.parent_id)zWITH RECURSIVE ancestors AS (SELECT {0}.id, {0}.parent_id FROM {0} WHERE id = %s UNION ALL SELECT {0}.id, {0}.parent_id FROM {0} INNER JOIN ancestors ON {0}.id=ancestors.parent_id)r   r    s     r#   _get_ancestors_cter(   1   r%   r&   c                    t         t        j                  t                 t         t        j                  t                 d|    S )N)r   write)r	   r   db_for_readr   db_for_writeactions    r#   _get_database_connectionr/   K   s<    F..y9:V00;<  r&   c                ,    t        |       j                  S N)r/   vendorr-   s    r#   r   r   R   s    #F+222r&   c                4    t        |       j                         S r1   )r/   cursorr-   s    r#   _get_database_cursorr5   V   s    #F+2244r&   c                      e Zd Zd Zy)BoundRenderMetac                D    d| _         d| _        t        |dd      | _        y )Nr      text_enabledF)indextotalgetattrr:   )selfmetas     r#   __init__zBoundRenderMeta.__init__[   s!    

#D.%@r&   N)__name__
__module____qualname__r@    r&   r#   r7   r7   Z   s    Ar&   r7   c                  "     e Zd ZdZ fdZ xZS )PluginModelBasezq
    Metaclass for all CMSPlugin subclasses. This class should not be used for
    any other type of models.
    c                   t         |   }|j                  dd       }|D cg c]  }t        |t              s| }}|red|vra|j                  dd       }t        |dd      }	t        d |D              }
|	s.|
s,t        j                  dddd	d	t        j                  
      |d<    || |||      }|xs t        |dd       }t        |      |_        |S c c}w )N
RenderMetacmsplugin_ptrMetaproxyFc              3  4   K   | ]  }t        |d         yw)rI   N)hasattr).0parents     r#   	<genexpr>z*PluginModelBase.__new__.<locals>.<genexpr>w   s     $\&WV_%E$\s   zcms.CMSPluginz%(app_label)s_%(class)sT)tonamerelated_nameauto_createdparent_link	on_delete_render_meta)super__new__pop
isinstancerF   getr=   anyr
   OneToOneFieldCASCADEr7   rW   )clsrR   basesattrs	super_new	attr_metabparentsr?   rK   field_is_inherited	new_class	__class__s               r#   rY   zPluginModelBase.__new__g   s    GO	IIlD1	 $Fz!_'E1FFe3 99VT*DD'51E "%$\T[$\!\ !3
 *0)=)=&(!:!% $$nn*o& c46	 DGI~tD!0!6	Q Gs
   CC)rA   rB   rC   __doc__rY   __classcell__ri   s   @r#   rF   rF   a   s    
/ /r&   rF   c                      e Zd ZdZ ej
                  eej                  dd      Z ej
                  dej                  ddd      Z	 ej                   ed      dd	      Z ej                   ed
      dddd      Z ej                   ed      ddd      Z ej                    ed      dej$                        Z ej                   d      ZdZ G d d      Z G d d      Zd Zd Zd Zd Zed        Zd Zd6dZd6dZ d  Z!d7d!Z" fd"Z#d# Z$e%d$        Z&d% Z'd& Z(d8d'Z)d( Z*d) Z+d* Z,d9d+Z-d9d,Z.d:d-Z/d9d.Z0d/ Z1d0 Z2d1 Z3e4d2        Z5d3 Z6d4 Z7d;d5Z8 xZ9S )<r   a  
    The base class for a CMS plugin model. When defining a new custom plugin, you should
    store plugin-instance specific information on a subclass of this class. (An example for this
    would be to store the number of pictures to display in a gallery.)

    Two restrictions apply when subclassing this to use in your own models:

    1. Subclasses of CMSPlugin **cannot be further subclassed**
    2. Subclasses of CMSPlugin cannot define a "text" field.
    FT)rV   editablenullr>   )rV   blankro   rn   positionr9   )defaultrn   language   )
max_lengthrp   db_indexrn   plugin_name2   )ru   rv   rn   zcreation date)rn   rr   )auto_nowNc                  d    e Zd Z ed      Z ed      ZdZdZ ej                  g d      gZ
dZy)CMSPlugin.Metapluginpluginscms)rq   )placeholderrs   rq   )fieldsN)rA   rB   rC   _verbose_nameverbose_name_plural	app_labelorderingr
   Indexindexesunique_togetherrD   r&   r#   rJ   r{      s=    {	l	 FLL GH
 Br&   rJ   c                      e Zd ZdZdZdZy)CMSPlugin.RenderMetar   r9   FN)rA   rB   rC   r;   r<   r:   rD   r&   r#   rH   r      s    r&   rH   c                ,    t        | j                        S r1   )r   pkr>   s    r#   __str__zCMSPlugin.__str__   s    !!r&   c                    d| j                    d| j                  j                   d| j                   d| j                   dt        t        |              d}|S )N<.z id=z plugin_type='z' object at >)rB   ri   rA   r   plugin_typehexid)r>   displays     r#   __repr__zCMSPlugin.__repr__   st    doo&a(?(?'@TWWI^\`\l\l[mmyz}  A  BF  G  {H  zI  IJ  Kr&   c                .    | j                   j                  S r1   )plugin_classrR   r   s    r#   get_plugin_namezCMSPlugin.get_plugin_name   s      %%%r&   c                X    | j                         d   }|t        |      S t        d      S )Nr   z<Empty>)get_plugin_instancer   r   )r>   instances     r#   get_short_descriptionzCMSPlugin.get_short_description   s0    ++-a0X&&|r&   c                D    ddl m} |j                  | j                        S )Nr   )plugin_pool)cms.plugin_poolr   
get_pluginr   )r>   r   s     r#   r   zCMSPlugin.plugin_class   s    /%%d&6&677r&   c                    | j                   S r1   )r   r   s    r#   get_plugin_classzCMSPlugin.get_plugin_class   s       r&   c                H    | j                         } ||j                  |      S r1   )r   model)r>   adminr   s      r#   get_plugin_class_instancez#CMSPlugin.get_plugin_class_instance   s#    ,,.L..66r&   c                    | j                  |      }	 | j                         }||fS # t        $ r d}d| _        Y ||fS w xY w)a  
        For a plugin instance (usually as a CMSPluginBase), this method
        returns the downcasted (i.e., correctly typed subclass of CMSPluginBase) instance and the plugin class

        :return: Tuple (instance, plugin)

        instance: The instance AS THE APPROPRIATE SUBCLASS OF CMSPluginBase and not necessarily just 'self', which is
        often just a CMSPluginBase,

        plugin: the associated plugin class instance (subclass of CMSPlugin)
        N)r   get_bound_pluginr   _inst)r>   r   r|   r   s       r#   r   zCMSPlugin.get_plugin_instance   s\     //6	,,.H  " 	HDJ	s   ' ??c                   t        | d      r| j                  S | j                         }|j                  | j                  k7  r|j                  j
                  j                  |       | _        | j                  | j                  j                  j                  d<   | j                  | j                  _
        | j                  S | | _        | j                  S )zb
        Returns an instance of the plugin model
        configured for this plugin type.
        r   )rI   r   )rM   r   r   r   ri   objectsr\   r   _statefields_cacherW   )r>   r|   s     r#   r   zCMSPlugin.get_bound_plugin   s    
 4!::&&(<<4>>)--111EDJ<@<L<LDJJ**=9&*&7&7DJJ# zz DJzzr&   c                L   | j                   }d| j                  | j                  t        | j	                               xs d| j
                  | j                  | j                  xs d| j                  xs d|xs g |xs g |j                  |j                  | j                         dS )Nr|    )typerq   placeholder_idrw   r   	plugin_idplugin_languageplugin_parentplugin_restrictionplugin_parent_restrictiondisable_editdisable_child_pluginsurls)r   rq   r   r   r   r   r   rs   	parent_idr   r   get_action_urls)r>   childrenrf   r   s       r#   get_plugin_infozCMSPlugin.get_plugin_info  s    (( "11$T%9%9%;<B++#}}2!^^1r"*.b)0B(55%1%G%G((*
 	
r&   c                H    t        |   |i | 	 | `y # t        $ r Y y w xY wr1   )rX   refresh_from_dbr   AttributeError)r>   argskwargsri   s      r#   r   zCMSPlugin.refresh_from_db   s1    00	
 		s    	!!c                   | j                   j                  j                         }|j                         r|d   j	                  |      S t        j                         }t        j                  j                  t        d      t        |j                        t        |j                        t        |j                        |      S )Nr   PAGE_MEDIA_PATH)r   page_setallexistsget_media_pathr   todayospathjoinr   stryearmonthday)r>   filenamepagesr   s       r#   r   zCMSPlugin.get_media_path*  s      ))--/<<>8**844JJLE77<<0A B #EJJU[[1A3uyy>S[] ]r&   c                    t        j                  dt        d       | j                  r| j                  j
                  S d S )NznDon't use the page attribute on CMSPlugins! CMSPlugins are not guaranteed to have a page associated with them!   )
stacklevel)warningswarnr   r   r   pager   s    r#   r   zCMSPlugin.page3  s:    >'		
 )-(;(;t$$EEr&   c                R    | j                         \  }}|r|j                  |      S dS )z1
        Get src URL for instance's icon
        r   )r   icon_srcr>   r   r|   s      r#   get_instance_icon_srczCMSPlugin.get_instance_icon_src=  s-      335&,4vx(<"<r&   c                d    | j                         \  }}|rt        |j                  |            S dS )z2
        Get alt text for instance's icon
        r   )r   r   icon_altr   s      r#   get_instance_icon_altzCMSPlugin.get_instance_icon_altD  s2      335&7?y23GRGr&   c                    t        j                  j                  | j                        j                  di | |r| j                         S y )Nr   rD   )r   r   filterr   updatereload)r>   refreshr   s      r#   r   zCMSPlugin.updateK  s=      DGG ,33=f=;;= r&   c                v    t         j                  j                  dd      j                  | j                        S )NrO   r   r   )r   r   select_relatedr\   r   r   s    r#   r   zCMSPlugin.reloadQ  s0      //-HLLPTPWPWLXXr&   c                .   t        d      }t               dz   }|dz  }|j                  t        j                  j                  t        j                  j                              }|j                  || j                  g       |j                         d   d   S )Nr*   
z!SELECT COUNT(*) FROM descendants;r   r5   r$   r   r   r   r   r   r   r   executer   fetchall)r>   r4   r"   s      r#   _get_descendants_countz CMSPlugin._get_descendants_countT  sv    %g."$t+22jj229??3K3KLMsTWWI& #A&&r&   c                N   t        d      }t               dz   }|dz  }|j                  t        j                  j                  t        j                  j                              }|j                  || j                  g       |j                         D cg c]  }|d   	 c}S c c}w )Nr*   r   zSELECT id FROM descendants;r   r   )r>   r4   r"   items       r#   _get_descendants_idszCMSPlugin._get_descendants_ids\  s~    %g."$t+,,jj229??3K3KLMsTWWI&$*OO$56DQ666s   B"c                6    | j                   j                         S r1   )cmsplugin_setr   r   s    r#   get_childrenzCMSPlugin.get_childrend  s    !!%%''r&   c                ^    t         j                  j                  | j                               S )Npk__in)r   r   r   r   r   s    r#   get_descendantszCMSPlugin.get_descendantsg  s%      ''t/H/H/J'KKr&   c                    | j                   sg S | j                  j                  j                  d      r(| j                  j                         | j                  gz   S t        | j                               S )a  
        Retrieve the list of ancestor plugins for the current plugin.

        This method returns a list of ancestor plugins, starting from the root
        ancestor down to the immediate parent of the current plugin. If the
        current plugin has no parent, an empty list is returned.

        Returns:
            list: A list of ancestor plugins, ordered from the root ancestor
                  to the immediate parent of the current plugin.
        rO   )r   r   r   r\   rO   get_ancestorslistget_ancestors_qsr   s    r#   r   zCMSPlugin.get_ancestorsj  sZ     ~~I;;##''1;;,,.$++>>D))+,,r&   c                   t        d      }t                d}|j                  || j                  g       |j	                         D cg c]  }|d   	 }}t
        j                  j                  |      j                  d      S c c}w )Nr*   z SELECT id FROM ancestors;r   r   rq   )	r5   r(   r   r   r   r   r   r   order_by)r>   r4   r"   r   ancestor_idss        r#   r   zCMSPlugin.get_ancestors_qs|  sz    %g.#%&&@AsT^^,-,2OO,=>DQ>>  ''|'<EEjQQ ?s   Bc           	     @    dD ]  }t        ||t        | |              y )N)r   r   rs   r   creation_dater   rq   )setattrr=   )r>   r|   attrs      r#   set_base_attrzCMSPlugin.set_base_attr  s$    n 	7DFD'$"56	7r&   c                     y)a
  
        Can (should) be overridden to handle the copying of plugins which contain children plugins after the original
        parent has been copied.

        E.g., TextPlugins use this to correct the references in the text to child plugins.
        copied
        NrD   )r>   old_instancenew_old_ziplists      r#   	post_copyzCMSPlugin.post_copy       	r&   c                     y)a+  
        Handle copying of any relations attached to this plugin. Custom plugins have
        to do this themselves.

        See also: :ref:`Handling-Relations`, :meth:`post_copy`.

        :param old_instance: Source plugin instance
        :type old_instance: :class:`CMSPlugin` instance
        NrD   )r>   r  s     r#   copy_relationszCMSPlugin.copy_relations  s     	r&   c                d    | j                   j                  dddd      }t        d |D              S )NFT)forwardreverseinclude_parentsinclude_hiddenc              3  j   K   | ]+  }t        |j                  t        j                        r(| - y wr1   )r[   fieldr
   ManyToManyField)rN   objs     r#   rP   z1CMSPlugin._get_related_objects.<locals>.<genexpr>  s#     _CCIIvG]G]1^C_s   )33)r   _get_fieldsr   )r`   r   s     r#   _get_related_objectszCMSPlugin._get_related_objects  s9    &&4   ' 

 _6___r&   c                     y)z
        Method called when we auto add this plugin via default_plugins in
        CMS_PLACEHOLDER_CONF.

        Some specific plugins may have some special stuff to do when they are
        auto added.
        NrD   )r>   requestconfs      r#   notify_on_autoaddzCMSPlugin.notify_on_autoadd  r
  r&   c                     y)ab  
        Method called when we auto add children to this plugin via
        default_plugins/<plugin>/children in CMS_PLACEHOLDER_CONF.

        Some specific plugins may have some special stuff to do when we add
        children to them. ie : TextPlugin must update its content to add HTML
        tags to be able to see his children in WYSIWYG.
        NrD   )r>   r  r  r   s       r#   notify_on_autoadd_childrenz$CMSPlugin.notify_on_autoadd_children  s     	r&   c                B   |rOt        d| j                  f      t        d      t        d| j                  f      t        d      t        d      dS t        d| j                  f      t        d      t        d| j                  f      t        d      t        d      dS )	a
  
        .. versionadd: 4.0

        :return: dict of action urls for edit, add, delete, copy, and move plugin.

        This method replaces the set of legacy methods `get_add_url`, ``get_edit_url`, `get_move_url`,
        `get_delete_url`, `get_copy_url`.
        cms_placeholder_edit_plugin)r   cms_placeholder_add_plugincms_placeholder_delete_plugincms_placeholder_move_plugincms_placeholder_copy_plugins)edit_plugin
add_plugindelete_pluginmove_plugincopy_plugin)edit_urladd_url
delete_urlmove_urlcopy_url)r   r   )r>   	js_compats     r#   r   zCMSPlugin.get_action_urls  s     
  --JRVRYRYQ[\+,HI!./NVZV]V]U_!`,-JK,-KL  **GtwwjY()EF+,KSWSZSZR\])*GH)*HI r&   r1   )NN)F)returnr   )r/  zlist[CMSPlugin])T):rA   rB   rC   rj   r
   
ForeignKeyr   r_   r   rO   SmallIntegerFieldr   rq   	CharFieldrs   r   DateTimeFieldr   nowr  changed_datechild_plugin_instancesrJ   rH   r   r   r   r   r   r   r   r   r   r   r   r   r   propertyr   r   r   r   r   r   r   r   r   r   r   r  r	  r  classmethodr  r  r  r   rk   rl   s   @r#   r   r      s   	 $&##K6>>TY`deK VvtRVafgF (v''*q5QHv*"ETXchiH"&""1]#3T\abK(F((?);eU]UaUabM'6''6L!B B 
"& 8 8
!7
 *(
&] F F=HY'7(L-$R7
 ` `	r&   r   )	metaclassc                $    | j                  |      S )a  
    Django requires that unbound function used in fields' definitions to be
    defined outside the parent class.
     (see https://docs.djangoproject.com/en/dev/topics/migrations/#serializing-values)
    This function is used within field definition:

        file = models.FileField(_("file"), upload_to=get_plugin_media_path)

    and it invokes the bounded method on the given instance at runtime
    )r   )r   r   s     r#   get_plugin_media_pathr;    s     ""8,,r&   ).
__future__r   r   rer   datetimer   	functoolsr   r   django.core.exceptionsr   	django.dbr   r	   r
   r   django.db.modelsr   django.db.models.baser   django.utilsr   django.utils.encodingr   django.utils.translationr   r   cms.exceptionsr   cms.models.placeholdermodelr   cms.utils.confr   cms.utils.urlutilsr   r$   r(   r/   r   r5   r7   rF   Modelr   r;  rD   r&   r#   <module>rL     s    " 	 	   , 5 = = % + ! + 6 6 3 * , K K2 K K235A A5i 5p} }@
-r&   