
    Bh                        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
mZ d dl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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& d dl'm(Z( d dl)m*Z*m+Z+ d dl,m-Z- d dl.m/Z/ d dl0m1Z1 d dl2m3Z3 d dl4m5Z5 d dl6m7Z7  ee8      Z9 G d de:      Z; G d de&      Z< G d dejz                        Z> G d d e<      Z?y)!    N)	getLogger)join)get_user_model)Site)IntegrityErrormodels)FPrefetchQ)
ModelState)UniqueConstraint)Concat)model_to_dict)NoReverseMatchreverse)	force_str)now)get_languagegettext_lazyoverride)MP_Node)	constants)PageManagerPageUrlManager)i18n)RemovedInDjangoCMS60Warning)get_cms_setting)get_current_language)get_clean_username)	menu_poolc                       e Zd ZdZd Zy)AdminCacheDictzZDictionary that disallows setting individual items to prevent accidental cache corruption.c                     t        d      )NzXDo not set individual items in the admin cache dict. Use the clear_cache method instead.)
ValueError)selfkeyvalues      D/home/dcms/DCMS/lib/python3.12/site-packages/cms/models/pagemodel.py__setitem__zAdminCacheDict.__setitem__"   s    stt    N)__name__
__module____qualname____doc__r)    r*   r(   r"   r"      s    dur*   r"   c            
           e Zd ZdZ ej
                  dej                  dddd      Z ej
                  eej                   e	d      dd      Z
 ej                   e	d	      ej                  d
      Z ej                   e	d      ej                  d
      Z ej                   d      Z ej                   d      Z ej                   e	d      dddd e	d            Z ej                   e	d      dddd      Z ej*                   e	d      d
      Z ej*                  d
dd
      Z ej                   e	d      dddd      Z ej                   e	d      ddd      Z ej*                  d
 e	d            Z e       Z G d  d!      Z fd"Zd# Zd$ Z e!d%        Z"e!d&        Z#d' Z$ fd(Z%d fd)	Z&d* Z'd+ Z(d, Z)e!d-        Z*d. Z+dd/Z,d0 Z-dd1Z.dd2Z/d3 Z0d4 Z1d5 Z2d6 Z3d7 Z4dd8Z5dd9Z6dd:Z7dd;Z8d< Z9	 	 	 	 	 	 	 dd=Z:	 dd>Z;d? Z<dd@Z= fdAZ>ddBZ?ddCZ@dD ZAddEZBdF ZCdG ZDdH ZEdI ZFdJ ZGe!dK        ZHddLZIdM ZJdN ZKdO ZLdP ZMdQ ZNddRZOdS ZPdT ZQdU ZRddVZSdW ZTddXZUddYZVddZZWdd[ZXdd\ZYdd]ZZdd^Z[dd_e\d`e]daej                  fdbZ_ddcZ`dddZaddeZbddfZcddgZdddhZedi Zfe!dj        Zge!dk        ZhddlZidm Zjdn Zkdo Zldp Zmdq Zndr Zods Zpdt Zqdu Zrdv Zsdw Ztdx Zudy Zvdz Zwdd{Zxdd|Zydd}Zzdd~Z{ddZ| xZ}S )PageaB  
    A ``Page`` is the basic unit of site structure in django CMS. The CMS uses a hierarchical page model: each page
    stands in relation to other pages as parent, child or sibling. This hierarchy is managed by the `django-treebeard
    <http://django-treebeard.readthedocs.io/en/latest/>`_ library.

    A ``Page`` is an abstract entity. It does not have any content associated with it, nor does is provide any slugs to
    build a URL. This is part of the model :class:`~cms.models.contentmodels.PageContent` and
    :class:`~cms.models.pagemodel.PageUrl` respectively.
    r%   Tchildren)	on_deleteblanknullrelated_namedb_indexsitedjangocms_pages)r3   verbose_namer6   r7   z
created byF)
max_lengtheditablez
changed by)auto_now_add)auto_nowid(   zWA unique identifier that is used with the page_url templatetag for linking to this page)r;   r7   r4   r5   	help_textzattached menuP   )r;   r7   r4   r5   zlogin requireddefault)r<   r7   rD   application   )r;   r4   r5   r7   zapplication instance name)r;   r4   r5   zMark this page as a page type)rD   rA   c                   F    e Zd Zg dZg dZ ed      Z ed      ZdZdgZ	y)	Page.Meta)addchangedelete))	view_pagezCan view page)publish_pagezCan publish page)edit_static_placeholderzCan edit static placeholderspagepagescmspathN)
r+   r,   r-   default_permissionspermissions_r:   verbose_name_plural	app_labelorderingr/   r*   r(   MetarH   ~   s0    9

 yj	8r*   rY   c                 ^    t        |   |i | i | _        i | _        t	               | _        y N)super__init__
urls_cachepage_content_cacher"   admin_content_cache)r%   argskwargs	__class__s      r(   r]   zPage.__init__   s/    $)&)"$#1#3 r*   c                     | j                  t               d      }|r|j                  xs |j                  }nt	        d      }| j                  t               d      }t        |      |dz   S d| dz   S )NTfallbackzNo available title z (/))get_content_objr   
menu_titletitlerU   get_pathr   )r%   page_contentrk   rR   s       r(   __str__zPage.__str__   su    ++LNT+J ++A|/A/AE*+E}}\^d};2IISa=IIr*   c                     d| j                    d| j                  j                   d| j                   dt	        t        |              d	}|S )N<.z id=z object at >)r,   rc   r+   pkhexr?   )r%   displays     r(   __repr__zPage.__repr__   sJ    doo&a(?(?'@TWWI[Y\]_`d]eYfXgghir*   c                 >    t        j                  dt        d       | S )NzWThe `node` has been removed from Page objects. Access the TreeNode attributes directly.   
stacklevelwarningswarnr   r%   s    r(   nodez	Page.node   s    e'	

 r*   c                 ,    t        | j                        S r[   )boolnumchildr~   s    r(   	is_branchzPage.is_branch   s    DMM""r*   c           	           t         fdt        dt         j                         j                        dd  D              }|S )Nc              3   <   K   | ]  }j                   d |   yw)r   NrR   ).0posr%   s     r(   	<genexpr>z*Page.get_ancestor_paths.<locals>.<genexpr>   s     as$))Ac*as   r      )	frozensetrangelenrR   steplen)r%   pathss   ` r(   get_ancestor_pathszPage.get_ancestor_paths   s6    aeAs499~t||6\]^]_6`aar*   c                 f    t        |      dk(  rd|v r| |d   _        n| |d<   t        |   di |S )Nr   instanceparentr/   )r   r   r\   	add_child)r%   rb   rc   s     r(   r   zPage.add_child   s@    v;!
f 4(,F:%#F8w *6**r*   c                     t        |      dk(  rd|v r| j                  |d   _        n| j                  |d<   t        |   |i |S )Nr   r   	parent_id)r   r   r\   add_sibling)r%   r   ra   rb   rc   s       r(   r   zPage.add_sibling   sJ    v;!
f 4+/>>F:("&..F;w"D3F33r*   c                 >    | j                         r| j                  S g S r[   )_has_cached_hierarchy
_ancestorsr~   s    r(   get_cached_ancestorszPage.get_cached_ancestors   s    %%'??"	r*   c                 >    | j                         r| j                  S g S r[   )r   _descendantsr~   s    r(   get_cached_descendantszPage.get_cached_descendants   s    %%'$$$	r*   c                 \    i | _         i | _        t               | _        t	        | d      r| `y y )N_prefetched_objects_cache)r^   r_   r"   r`   hasattrr   r~   s    r(   _clear_internal_cachezPage._clear_internal_cache   s2    "$#1#3 445. 6r*   c                 R    t        j                  dt        d       | j                  S )NzJAttribute `parent_page` is deprecated. Instead use the attribute `parent`.rx   ry   r|   r}   r   r   r~   s    r(   parent_pagezPage.parent_page   s#    X'	

 {{r*   c                 X    | j                   j                  |d      j                         S )NF)languagepath__isnull)urlsfilterexistsr%   r   s     r(   has_valid_urlzPage.has_valid_url   s%    yyFMMOOr*   c                    |rt        |      }nt        j                  }t               }	 | j                  j
                  j                  d| j                        }|j                  d||       |j                         }| j                  d||       | j                         }||fS # | j                  j                  $ r g }Y Ew xY w)z
        Sets the given page as the homepage.
        Updates the url paths for all affected pages.
        Returns the old home page (if any).
        T)is_homer8   F)r   
changed_bychanged_date)r   r   SCRIPT_USERNAMEr   rc   objectsgetsite_idupdate_set_title_root_pathDoesNotExist_remove_title_root_path)r%   userr   r   old_homeold_home_treenew_home_trees          r(   set_as_homepagezPage.set_as_homepage   s     +D1J"22Ju	<~~--11\\ 2 H OO%)  
 %99;M!% 	 	

 446}--! ~~** 	M	s   1B' 'CCc                 6    t        | d      xr t        | d      S )Nr   r   )r   r~   s    r(   r   zPage._has_cached_hierarchy  s    t^,L|1LLr*   c                    | j                   rV|D cg c]D  }|j                  j                  | j                        s)|j                  | j                  kD  sC|F c}| _        ng | _        | j                         rg | _        n|| _        | j                  D ]J  }|j                  | j                  dz   k(  s |j                  | j                  | g| j                  z          L y c c}w )Nr   )	ancestors)r   rR   
startswithdepthr   is_rootr   _set_hierarchy)r%   rP   r   rO   childs        r(   r   zPage._set_hierarchy  s    >>27 w$499;O;OPTPYPY;Z_c_i_ilplvlv_v wD "D<<> DO'DO&& 	^E{{djj1n,$$T%6%6D6DOOC[$]	^ !xs   *C#C#C#c                     |r\t        t        j                  |      t        j                  d      t        j                  d      t        j                               }|S |d }|S t        j                  d      }|S )N/slug)output_field)r   r   Valuer	   	CharField)r%   	base_pathnew_paths      r(   _get_path_sql_valuezPage._get_path_sql_value  so    Y'S! #--/	H  H  xx'Hr*   c                     | j                   r| j                   j                  |      nd}| j                  |      }t        j                  j                  ||       j                  d      j                  |       y )Nrg   r   rO   Fmanagedr   )r   rl   r   PageUrlr   r   excluder   )r%   r   r   r   s       r(   _update_url_pathzPage._update_url_path#  se    6:kkDKK((2r	++I6 OO""H4"@HHQVHW^^dl^mr*   c                    | j                         s|| j                         vry | j                         }| j                  |      }| j	                  |      }t
        j                  j                  ||      j                  d      j                  |       |j                  |      j                         D ]  }|j                  |        y )N)r   page__inFr   r   )urls__language)is_leafget_languagesget_child_pagesrl   r   r   r   r   r   r   iterator_update_url_path_recursive)r%   r   rP   r   r   r   s         r(   r   zPage._update_url_path_recursive+  s    <<>XT-?-?-AA$$&MM(+	++I6 OO""Hu"EMMV[M\cciqcr \\\:CCE 	7E,,X6	7r*   c           	         | j                   j                  |       }t        j                  j	                  |dd      }| j
                  j                  dd      D ]k  \  }}|j	                  |      j                  t        t        j                  |      t        j                  d      d      	       | j                  ||	       m |S )
NTFr   r   r   r   r   r   r   rR   r   )rc   get_treer   r   r   r   values_listr   r   r   r   update_urls)r%   	page_tree	page_urlsr   r   s        r(   r   zPage._set_title_root_path:  s    NN++D1	OO**ItZ_*`	"ii33JG 	2NHd x077VFLLQUDVX^XdXdehXikq=r7sXD1		2
 r*   c                    | j                   j                  |       }t        j                  j	                  |dd      }| j
                  j                  dd      D ]t  \  }}t        |      dz   }t        j                  t        j                  d      t        j                  |      d	      }|j	                  ||
      j                  |       v |S )NTFr   r   r   rx   rR   substr)function)r   path__startswithr   )rc   r   r   r   r   r   r   r   r   Funcr	   r   r   )r%   r   r   r   r   
trim_countsql_funcs          r(   r   zPage._remove_title_root_pathE  s    NN++D1	OO**ItZ_*`	"ii33JG 		_NHd TQJ{{ Z(!H
 x$GNNT\N]		_ r*   c                 R    | j                    xr t        | j                               S )a  
        Encapsulates logic for determining if this page is eligible to be set
        as `is_home`. This is a public method so that it can be accessed in the
        admin for determining whether to enable the "Set as home" menu item.
        :return: Boolean
        )r   r   r   r~   s    r(   is_potential_homezPage.is_potential_homeU  s!     <<8D$88r*   c                 @   |s
t               }t        |      5  	 | j                  rt        d      cd d d        S | j	                  ||      xs | j                  ||      }|rt        dd|i      nd 	 cd d d        S # t        $ r Y d d d        y w xY w# 1 sw Y   y xY w)N
pages-rootpages-details-by-slugr   rb   )r   force_languager   r   rl   get_slugr   )r%   r   rf   rR   s       r(   get_absolute_urlzPage.get_absolute_url_  s    +-HH% 		<<"<0		 		 }}Xx8 DMMh= SWw6~N\``		 		 " 		 				 		s-   BA=8A==	BBBBBc                 z    t        j                  dt        d       || _        || _        | j                  |      S )Nz@Method `set_tree_node` is deprecated. Use `add_to_tree` instead.rx   ry   )position)r|   r}   r   r8   r   add_to_tree)r%   r8   targetr   s       r(   set_tree_nodezPage.set_tree_noden  s;    N'	

 	22r*   c                 `   |dv sJ | j                   t        j                  |        y |dk(  rB| j                   j                  r,| j                   j	                         j                  d|        y |dv r| j                   j                  |        y | j                   j                  ||        y )N)
last-childfirst-childleftright)r   r   r   )r   r   )r   r   )r   r1   add_rootr   get_first_childr   r   )r%   r   s     r(   r   zPage.add_to_treex  s    IIII;;MM4M(&4;;+@+@KK'')55&45P66KK!!4!0KK##4#@r*   c                    t        |t              s
J | d       | j                  t        j                  k(  }|r6|j                         r&|dv r"| j                         }| j                  |       | j                          | j                  ||       |dv r|| _
        n|j                  | _
        | j                  | j                         | j                  d       | j                  j                  dd	
      }|D ]0  }| j                  s| j!                  |       | j#                  |       2 | j%                  d	       | S )z
        Called from admin interface when page is moved. Should be used on
        all the places which are changing page position. Used like an interface
        to django-treebeard, but after move is done page_moved signal is fired.
         is not an instance of Page.)r   r   )templater   r   )r   rR   r   fieldsr   Tflatmenu)
isinstancer1   r  r   TEMPLATE_INHERITANCE_MAGICr   get_templateupdate_translationsr   mover   r   refresh_from_dbr   r   r   r   r   clear_cache)r%   target_pager   inherited_templater  	languagesr   s          r(   	move_pagezPage.move_page  s3    +t,Z=Y.ZZ,!]]i.R.RR+"5"5"7HHY<Y ((*H$$h$7 	""$ 			+x(44%DK &,,DK4;;'$56 II))*4)@	! 	6H<<%%h/++H5	6 	d#r*   c                     ddl m} | j                  |      }d |D        }|j                  j	                  ||      }t
        j                  j                  j                  |       |S )Nr   )	CMSPluginc              3   4   K   | ]  }|j                     y wr[   rs   )r   placeholders     r(   r   z+Page._clear_placeholders.<locals>.<genexpr>  s     Jk;>>Js   )placeholder__inr   )	
cms.modelsr  get_placeholdersr   r   r   queryQuerySetrK   )r%   r   r  placeholdersplaceholder_idspluginss         r(   _clear_placeholderszPage._clear_placeholders  sY    (,,X6J\J##**?U]*^$$W-r*   c	                    ddl m}	 ddlm}
 |t	        |t
              s
J | d       t	        |t                     s
J | d       |"t        j                  dt        d       |xs |}|r|j                  |	      }nt
        j                  |	      }t               |_        |j                          |rA|r?| j                  j!                  |
      }| j#                  d      j!                  |
      }ni|r-| j                  j%                         }| j#                  d      }n:| j                  j'                         }| j#                  d      j'                         }|j)                  d      }|D ]  }t+        |      }|j-                  dd        |j-                  dd        ||d<   |r;|j/                  |j0                        }|r| d|j2                   n|j2                  }nd}|j2                  } |
|||j0                        |d<   |rdj5                  ||d         n|d   |d<   t7        j8                  j;                  |      j<                  di |  |j?                         D ]  }t+        |      }|j-                  dd        ||d<    |	j8                  j;                  |      j<                  di |}|j@                  j%                         D ]P  }|j@                  j=                  |jB                  |jD                        }|jG                  ||j0                  
       R ||jH                  |j0                  <    |rddl%m&} |jO                  | |       |rjtQ        d      r_| jR                  jU                         }g }|D ]!  }d |_+        ||_,        |j[                  |       # |r|jR                  j]                  |       |S )Nr   PageContent)get_available_slugr  z is not an instance of User.@Argument `parent_node` is deprecated. Use `parent_page` instead.rx   ry   )r8   r   admin_managermanagerr#  r?   r8   rO   r   rg   r   z{}/{}rR   )slotdefault_width)extension_pool
PERMISSIONr/   )/r  r)  cms.utils.pager*  r  r1   r   r|   r}   r   r   r  r   _stater   r   r   pagecontent_setallnoneprefetch_relatedr   poprl   r   r   formatr   r   	with_usercreatecurrent_contentr#  r/  r0  copy_pluginsr_   cms.extensionsr1  copy_extensionsr   pagepermission_setr   rs   rO   appendbulk_create)r%   r8   r   parent_noder   translationsrT   
extensionsr   r)  r*  new_pager   page_urlnew_urlbaserR   rk   	new_titler  new_placeholderr1  permissions_new
permissions                           r(   copyz	Page.copy  s    	+5"jd&Cq}TpEqqC$ 01XdV;W3XX1"MMR+
 &4K",,$,7H}}$}/H$,&&(		((((;I///HOOYaObL		I///HL		(I///HMMOL#44^D! 	>H#H-GKKd#KK%&GFO"++H,=,=>48$q0hmm}}0tX=N=NOGFOGKgnnT76?CQXY_Q`GFOOO%%d+22=W=	>$ "113 	HE%e,IMM$% (IfB++55d;BBOYOI$11557 W"+"8"8"?"?$))"-";"; #@ # ((9CUCU(VW ?HH''	(:(:;	H 5**4: ?<811::<K O) 3
 $
"*
&&z23
 ++77Hr*   c           
         ddl m} |"t        j                  dt        d       |xs |}|dv r|}n|r|j
                  }nd}||r|j                  n| j                  }t        | j                         j                  dt        d	|j                  j                         
                  }	| j                  |||      }
|r(|dv r$|
j                  ||       |
j                  d       |r(|dv r$|
j                  ||       |
j                  d       | j                   |
i}|	D ]4  }||j"                     }|j                  ||d||      ||j                   <   6 |
S )zK
        Copy a page [ and all its descendants to a new location ]
        r   r(  Nr+  rx   ry   r  r   r5  )queryset)r   r   r   r  r  )r   r   T)r   rE  rT   r   )r  r)  r|   r}   r   r   r8   listget_descendant_pagesr8  r
   r,  r6  rO  r  r  r?   r   )r%   r  target_noder   copy_permissionstarget_siter   r)  r   descendantsnew_root_pagepages_by_idrO   r   s                 r(   copy_with_descendantszPage.copy_with_descendants  su    	+"MMR+
 &4K44%K%,,KK.9+**tyyK %%'88*[5N5N5R5R5TU
 		+;T	R86 {H5))1B)C8'=={H5))1B)Cww. 	D 0F#'99dP`gk $- $K 	
 r*   c                 &   t         j                  |       j                          | j                  rPt         j                  j                  | j                        j                  t        j                  d      dz
         | j                  d       y )N)r?   r   r   )r   Tr  )r1   r   delete_fastr   r   r   r   r   r   r	   r  )r%   ra   rb   s      r(   rK   zPage.deleteO  se    d'');;LL4>>299688JCWZ[C[9\d#r*   c                     || j                         }n|g}| j                  d      j                  |      j                          y )Nr,  r-  )language__in)r   r5  r   rK   )r%   r   r  s      r(   delete_translationszPage.delete_translationsV  sE    **,I!
I_5<<)<T[[]r*   c                     | j                   dk(  rd | _         | j                  dk(  rd | _        t        | j                         }ddlm}  |       | _        |r| j                  | _        t        | $  di | y )Nrg   r   )get_current_user_namer/   )

reverse_idapplication_namespacer   rs   cms.utils.permissionsra  r   
created_byr\   save)r%   rb   createdra  rc   s       r(   rf  z	Page.save^  sf    ??b "DO%%+)-D&477m#?/1"ooDOvr*   c                     | j                   } |j                  j                  | j                        j                  di | |r| j                         S |j                         D ]  \  }}t        | ||        y )Nr  r/   )rc   r   r   rs   r   reloaditemssetattr)r%   refreshdataclsfieldr'   s         r(   r   zPage.updatem  sk    nn-dgg&--55;;=  $

 ,ueU+,r*   c                     |r| j                   j                  |      }n| j                   j                         } |j                  di |S )Nr   r/   )r5  r   r6  r   )r%   r   rm  rE  s       r(   r  zPage.update_translationsx  sH    //666IL//335L"|""*T**r*   c                 V    | j                   j                  |      j                         S Nr   )r5  r   r   r   s     r(   has_translationzPage.has_translation  s%    ##**H*=DDFFr*   c                    ddl m} t        d      r |        |rIt        d      r>|sJ d       | j                  |      }|D ]  }|j	                  || j
                         ! |r!t        j                  | j
                         y y )Nr   )invalidate_cms_page_cache
PAGE_CACHEPLACEHOLDER_CACHEz4language is required when clearing placeholder cacher   )	cms.cacheru  r   r   r  r   r    clear)r%   r   r  r  ru  r#  placeholder_instances          r(   r  zPage.clear_cache  s    7<(%'?+>?SSS800:L(4 Q$$004<<0PQ OODLL1 r*   c                 @    | j                         j                  d      S NrR   )get_childrenorder_byr~   s    r(   r   zPage.get_child_pages  s      "++F33r*   c                 @    | j                         j                  d      S r}  )get_ancestorsr  r~   s    r(   get_ancestor_pageszPage.get_ancestor_pages  s    !!#,,V44r*   c                 @    | j                         j                  d      S r}  )get_descendantsr  r~   s    r(   rS  zPage.get_descendant_pages  s    ##%..v66r*   c                 |    | j                   j                  j                  | j                  d| j                         S )Nr   r   )rc   r   r   rR   r   r~   s    r(   get_rootzPage.get_root  s/    ~~%%))tyyT\\/J)KKr*   c                 R    t        j                  dt        d       | j                  S )NzMMethod `get_parent_page()` is deprecated. Instead use the `parent` attribute.rx   ry   r   r~   s    r(   get_parent_pagezPage.get_parent_page  s#    ['	

 {{r*   c                 x    t        j                  dt        d       dj                  | j	                               S )NzAAttribute `languages` is deprecated. Use `get_languages` instead.rx   ry   ,)r|   r}   r   r   r   r~   s    r(   r  zPage.languages  s1    O'	

 xx**,--r*   c                    |r?| j                   s| j                          t        | j                   j                               S | j                  s| j                  t               dd       t        | j                  j                               S )zEReturns available languages for the page. This is potentially costly.F)rf   force_reload)r`   set_admin_content_cacherR  keysr_   _get_page_content_cacher   )r%   r,  s     r(   r   zPage.get_languages  so    ++,,.0055788&&((%V[(\D++00233r*   c                 <    t        j                  dt        d       y )NzBMethod `remove_language` is deprecated and has no effect any more.rx   ry   r{   r   s     r(   remove_languagezPage.remove_language  s    P'	
r*   c                 <    t        j                  dt        d       y )NzCMethod `update_languages` is deprecated and has no effect any more.rx   ry   r{   )r%   r  s     r(   update_languageszPage.update_languages  s    Q'	
r*   c                 ^    t        j                  dt        d       | j                  d      S )NzaMethod `get_published_languages` is deprecated. Use `get_languages(admin_manager=False)` instead.rx   ry   F)r,  )r|   r}   r   r   r~   s    r(   get_published_languageszPage.get_published_languages  s-    o'	

 !!!66r*   c                     t        j                  dt        d       | j                  j	                         D ](  }| j
                  j                  |j                  |       * y )NzMethod `set_translations_cache` is deprecated. Use `get_content_obj` instead. For admin views use `set_admin_content_cache` instead.rx   ry   )r|   r}   r   r5  r6  r_   
setdefaultr   r%   translations     r(   set_translations_cachezPage.set_translations_cache  sX    E'		
  //335 	RK##..{/C/C[Q	Rr*   c                     t               | _        | j                  d      j                         j	                         D ](  }| j                  j                  |j                  |       * y )Nr,  r-  )r"   r`   r5  latest_contentr6  r  r   r  s     r(   r  zPage.set_admin_content_cache  sZ    #1#3 ///HWWY]]_ 	SK$$//0D0DkR	Sr*   c                 x   ddl m} | j                  s| j                          | j                  j	                  | |||             }|sq|rot        j                  |      D ]#  }| j                  j	                  |      }|s!|c S   |||       }|dk(  r%| j                  j                         D ]  }|s|c S  |S )Nr   EmptyPageContentr   force)cms.models.contentmodelsr  r`   r  r   r   get_fallback_languagesvalues)r%   r   rf   r  rm   langitems          r(   get_admin_contentzPage.get_admin_content  s    =''((*//33H>NX`gk>lm33H= (#77;;DA''( ,XDIL7" 44;;= $D#$ r*   c                     | j                   ry| j                  r,| j                  j                  |d      }|r	| d| }|S |}|S |}|S )Nrg   Tre   r   )r   r   rl   )r%   r   r   rJ  rR   s        r(   get_path_for_slugzPage.get_path_for_slug  s_    <<;;;;''4'@D'+dV1TF#D  26D  Dr*   c                 B    | j                         j                  |      S rr  )get_urlsr   r   s     r(   get_urlzPage.get_url   s    }}""H"55r*   c                 6    | j                   j                         S r[   )r   r6  r~   s    r(   r  zPage.get_urls  s    yy}}r*   c           
         |r!| j                         j                  |      }n| j                         j                         }d|v r|d   |d   }|r|gn)t        |j	                  dd      j                               }|D ]  }t        j                  j                  ||| j                        j                  |j                  |      j                  d            j                         }|sot        |j                  |      j	                  d	d            }t        d
| d| d| d        |j                  di |S )Nr   rR   r   Tr
  )r   rR   
page__siters   )pk__inpage__pkz.Cannot update URL path. A page URL with path='z' and language='zA' already exists for another page on the same site (not page(s): z).r/   )r  r   r6  rR  r   distinctr   r   r8   r   r  r   r   r   )	r%   r   rm  page_urls_qsr   languages_to_checkr  existing_url_collisionpage_pks_being_updateds	            r(   r   zPage.update_urls  sa   ==?1181DL==?..0LT>d6l6F|H&
D1I1I*[_1I1`1i1i1k,l  +  OO**!%%#'99 + 
 WL$7$7$7$F$M$Md$SWTVX ' *-1$++T+:FFzX\F].* )H
 S))- /::P9QQSU !. #|""*T**r*   c                 D    t        j                  || j                        S )Nrx  )r   r  r   r   s     r(   get_fallbackszPage.get_fallbacks+  s    **8T\\JJr*   c                     | j                  |||      }|| j                  v r| j                  |   S ddlm}  |||       S )zHelper function for accessing wanted / current title.
        If wanted title doesn't exist, EmptyPageContent instance will be returned.
        r   r  r   )r  r_   r  r  )r%   r   rf   r  r  s        r(   ri   zPage.get_content_obj0  sG     //(LQt...**844/==r*   c                 `    	 t        | j                  |||      |      }|S # t        $ r Y yw xY w)zOHelper function for getting attribute or None from wanted/current page content.N)getattrri   AttributeError)r%   attrnamer   rf   r  	attributes         r(   get_page_content_obj_attributez#Page.get_page_content_obj_attribute;  s;    	 4 4Xx VX`aI 		s   ! 	--c                 D    |g}|r |j                   j                  |              j                  | j                  vrG j                  j	                         D ci c]  }|j
                  |v s|j
                  |  c} _        t         fd|D        d      S c c}w )z8Get the path of the page depending on the given languageNc              3   Z   K   | ]"  }|j                   v sj                   |    $ y wr[   )r^   )r   r  r%   s     r(   r   z#Page.get_url_obj.<locals>.<genexpr>N  s%     \tDDOOD[T__T*\s   ++)extendr  r^   r   r6  r   next)r%   r   rf   r  urls   `    r(   get_url_objzPage.get_url_objC  s    J	T//9:??"hdoo&E =AIIMMOiSs||_hOhs||S0iDO\y\^bcc js   B1Bc                 D    | j                  ||      }|r|j                  S y r[   )r  rR   r%   r   rf   r  s       r(   rl   zPage.get_pathP  #    x288Or*   c                 D    | j                  ||      }|r|j                  S y r[   )r  r   r  s       r(   r   zPage.get_slugV  r  r*   c                 *    | j                  d|||      S )zK
        get the title of the page depending on the given language
        rk   r  r%   r   rf   r  s       r(   	get_titlezPage.get_title\  s     227HhP\]]r*   c                 X    | j                  d|||      }|s| j                  |d|      S |S )zP
        get the menu title of the page depending on the given language
        rj   Tr  r  )r%   r   rf   r  rj   s        r(   get_menu_titlezPage.get_menu_titleb  s8     88xQY[gh
>>(D,??r*   r   r,  returnc                     ddl m}m} |r,|j                  j	                         j                  ||       }n|j                  j                  ||       }|j                  j                  |      S )Nr   )r)  Placeholderr   )r  r)  r  r,  r=  r   r   get_for_obj)r%   r   r,  r)  r  rm   s         r(   r   zPage.get_placeholdersk  s`    7&44DDFJJT\cgJhL&..22H42PL""..|<<r*   c                 *    | j                  d|||      S )z5
        get when this page was last updated
        r   r  r  s       r(   get_changed_datezPage.get_changed_dateu  s     22>8XWcddr*   c                 *    | j                  d|||      S )z5
        get user who last changed this page
        r   r  r  s       r(   get_changed_byzPage.get_changed_by{  s     22<8Uabbr*   c                 X    | j                  d|||      }|s| j                  |d|      S |S )zP
        get the page title of the page depending on the given language
        
page_titleTr  )r%   r   rf   r  r  s        r(   get_page_titlezPage.get_page_title  s8     88xQY[gh
>>(D,??r*   c                 *    | j                  d|||      S )zg
        get content for the description meta tag for the page depending on the given language
        meta_descriptionr  r  s       r(   get_meta_descriptionzPage.get_meta_description  s     223ExQY[ghhr*   c                     | j                   S )z@
        get application urls conf for application hook
        )application_urlsr  s       r(   get_application_urlszPage.get_application_urls  s     $$$r*   c                 *    | j                  d|||      S )z
        get redirect
        redirectr  r  s       r(   get_redirectzPage.get_redirect  s     22:xS_``r*   c                    d }|s
t               }t        | di       }|j                  dg       }|D ]  }|| j                  |j                  <    |s|| j                  vr8| j
                  j                         D ]  }|| j                  |j                  <    | j                  j                  |      r|S t        || j                  j                  |        || |      g      }|r	 || |      S |S )z
        Sets the internal page object cache for page content objects available to the general user.
        It optionally respe
        c                 z    t        j                  |      }|D ]!  }| j                  j                  |      s|c S  y r[   )r   r  r_   r   )rO   r   fallback_langsr  s       r(   get_fallback_languagez;Page._get_page_content_cache.<locals>.get_fallback_language  s:    !88BN&  **..t4K r*   r   r5  )r   r  r   r_   r   r5  r6  )	r%   r   rf   r  r  prefetch_cachecached_page_contentrm   use_fallbacks	            r(   r  zPage._get_page_content_cache  s   	  #~H !'BBG,001BBG/ 	JL=ID##L$9$9:	J 84+B+BB $ 4 4 8 8 : NAM''(=(=>N ""&&x0O42266x@@BWX\^fBgh
 (x88r*   c                 $    | j                  d      S )Nr  r  r~   s    r(   r  zPage.template  s    22:>>r*   c                 $    | j                  d      S N	soft_rootr  r~   s    r(   r  zPage.soft_root  s    22;??r*   c                     | j                  |||      }|r|j                         S t        d      rt        d      d   d   S dS )N	TEMPLATESr   rg   )ri   r  r   r%   r   rf   r  contents        r(   r  zPage.get_template  sJ    &&x<H''))5D[5Q{+A.q1YWYYr*   c                 v    | j                         }t        d      D ]  }|d   |k(  s|d   c S  t        d      S )z
        get the textual name (2nd parameter in get_cms_setting('TEMPLATES'))
        of the template of this page or of the nearest
        ancestor. failing to find that, return the name of the default template.
        r  r   r   rD   )r  r   rU   )r%   r  ts      r(   get_template_namezPage.get_template_name  sG     $$& - 	Atxt	 |r*   c                 "    ddl m}  |||       S )Nr   )user_can_view_pagerO   )cms.utils.page_permissionsr  )r%   r   r  s      r(   has_view_permissionzPage.has_view_permission  s    A!$T22r*   c                     ddl m} t        d      r;|j                  j	                  |       j                  d      }|j                         S y)Nr   )PagePermissionr2  T)can_viewF)r  r  r   r   for_pager   r   )r%   r8   r  restrictionss       r(   has_view_restrictionszPage.has_view_restrictions  sD    -<()11::4@GGQUGVL&&((r*   c                      ddl m}  |||       S )zB
        Has user ability to add page under current page?
        r   )user_can_add_subpage)r  r  )r%   r   r  s      r(   has_add_permissionzPage.has_add_permission  s     	D#D$//r*   c                 "    ddl m}  |||       S )Nr   )user_can_change_pager  )r  r  )r%   r   r  s      r(   has_change_permissionzPage.has_change_permission      C#Dt44r*   c                 "    ddl m}  |||       S )Nr   )user_can_delete_pager  )r  r	  )r%   r   r	  s      r(   has_delete_permissionzPage.has_delete_permission  r  r*   c                 $    ddl m}  ||| |      S )Nr   ) user_can_delete_page_translation)rO   r   )r  r  )r%   r   r   r  s       r(   !has_delete_translation_permissionz&Page.has_delete_translation_permission  s    O/4(SSr*   c                 "    ddl m}  |||       S )Nr   )user_can_publish_pager  )r  r  )r%   r   r  s      r(   has_publish_permissionzPage.has_publish_permission   s    D$T55r*   c                 "    ddl m}  |||       S )Nr   )&user_can_change_page_advanced_settingsr  )r  r  )r%   r   r  s      r(    has_advanced_settings_permissionz%Page.has_advanced_settings_permission  s    U5dFFr*   c                 "    ddl m}  |||       S )zJ
        Has user ability to change permissions for current page?
        r   ) user_can_change_page_permissionsr  )r  r  )r%   r   r  s      r(   !has_change_permissions_permissionz&Page.has_change_permissions_permission
  s     	P/4@@r*   c                 "    ddl m}  |||       S )z&Has user ability to move current page?r   )user_can_move_pager  )r  r  )r%   r   r  s      r(   has_move_page_permissionzPage.has_move_page_permission  s    A!$T22r*   c                 H    t        t        d      d| j                  z  |      S )a\  
        Returns path (relative to MEDIA_ROOT/MEDIA_URL) to directory for storing
        page-scope files. This allows multiple pages to contain files with
        identical names without namespace issues. Plugins such as Picture can
        use this method to initialise the 'upload_to' parameter for File-based
        fields. For example:
            image = models.ImageField(
                _("image"), upload_to=CMSPlugin.get_media_path)

        where CMSPlugin.get_media_path calls self.page.get_media_path

        This location can be customised using the CMS_PAGE_MEDIA_PATH setting
        PAGE_MEDIA_PATHz%d)r   r   rs   )r%   filenames     r(   get_media_pathzPage.get_media_path  s!     O$56twwQQr*   c                 b    | j                   j                  j                  | j                        S )z1
        Reload a page from the database
        r  )rc   r   r   rs   r~   s    r(   ri  zPage.reload(  s&     ~~%%))TWW)55r*   c                 B    | j                  |      j                         S rr  )ri   rescan_placeholdersr   s     r(   r   zPage.rescan_placeholders.  s    ##X#6JJLLr*   c                 L    ddl m} | j                  |||      }|r ||      S g S )Nr   )!get_declared_placeholders_for_obj)cms.utils.placeholderr"  ri   )r%   r   rf   r  r"  r  s         r(   get_declared_placeholderszPage.get_declared_placeholders1  s,    K&&x<H4W==	r*   c                 N    | j                  |||      }|r|j                         S y r[   )ri   get_xframe_optionsr  s        r(   r&  zPage.get_xframe_options9  s-    &&x<H--// r*   c                 *    | j                  d|||      S r  r  r  s       r(   get_soft_rootzPage.get_soft_root>  s    22;(T`aar*   c                 *    | j                  d|||      S )Nin_navigationr  r  s       r(   get_in_navigationzPage.get_in_navigationA  s    22?HhXdeer*   c                 *    | j                  d|||      S )Nlimit_visibility_in_menur  r  s       r(   get_limit_visibility_in_menuz!Page.get_limit_visibility_in_menuD  s    223MxYacoppr*   r[   rg   NT)Nr   )r   )NNNTFTN)NNNTNN)F)NFF)T)NTF)~r+   r,   r-   r.   r   
ForeignKeyCASCADEr   r   rU   r8   r   r   PAGE_USERNAME_MAX_LENGTHre  r   DateTimeFieldcreation_dater   rb  navigation_extendersBooleanFieldlogin_requiredr   r  rc  is_page_typer   r   rY   r]   rn   rv   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r&  rO  rZ  rK   r_  rf  r   r  rs  r  r   r  rS  r  r  r  r   r  r  r  r  r  r  r  r  r  r   r  ri   r  r  rl   r   r  r  strr   r"  r   r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r
  r  r  r  r  r  r  ri  r   r$  r&  r(  r+  r.  __classcell__)rc   s   @r(   r1   r1   &   se    V..F 6..vY&D "!!	,55J
 "!!	,55J
 )F((d;M'6''6L "!!	$mnJ ,6++	/ )V((	
N "f!!G
 (v''	- -F,,	
%&	 '6&&34L mG
 
4J   # #+4

/  P".HM^
7	 93
A)V ^B pt5n$^	+G2&457L . .4

7RS
&
6#+JK
	>d^= =T =foo =eci%a#J ? ? @ @Z
3
05
5
T
6
G
A3R 6M0
bfqr*   r1   c                   Z   e Zd Z ej                   ed      dd      Z ej                   ed      ddd      Z ej                   ed      dd      Z	 ej                  eej                   ed	      d
      Z ej                  d      Z e       Z G d d      Zd ZddZddZy)r   r      T)r;   r7   Path)r;   r7   r5   r      rO   r   )r3   r:   r6   FrC   c                   .    e Zd ZdZg Z eddgd      gZy)PageUrl.MetarQ   rO   r   unique_together_page_language)r	  nameN)r+   r,   r-   rW   rS   r   constraintsr/   r*   r(   rY   rB  U  s$    	 VZ$8?^_
r*   rY   c                 V    | j                   xs | j                   d| j                   dS )Nz (rh   )rR   r   r   r~   s    r(   rn   zPageUrl.__str__\  s'    ))(tyy)DMM?!<<r*   Nc                    |s
t               }t        |      5  	 | j                  dk(  rt        d      cd d d        S t        dd| j                  i      cd d d        S # t        $ r Y d d d        y w xY w# 1 sw Y   y xY w)Nrg   r   r   r   r   )r   r   rR   r   r   )r%   r   rf   s      r(   r   zPageUrl.get_absolute_url_  s    +-HH% 	99?"<0	 	 6		?RS		 	
 " 	 	
	 	s-   A6AA	A3(A62A33A66A?c                 V    | j                   j                  d      \  }}}|r| d| S |S )Nr   )rR   
rpartition)r%   r   old_basesepr   s        r(   get_path_for_basezPageUrl.get_path_for_basek  s5    "ii2237#t(1)AdV$;t;r*   r0  r/  )r+   r,   r-   r   	SlugFieldrU   r   r   rR   r   r1  r1   r2  rO   r7  r   r   r   rY   rn   r   rL  r/   r*   r(   r   r   H  s    6AfI#ED6AfI#4PDv*"tLH6..vY	D "f!!%0GG
 
=
<r*   r   c                   6    e Zd Z G d d      Zed        Zd Zy)PageTypec                       e Zd ZdZg Zy)PageType.MetaTN)r+   r,   r-   proxyrS   r/   r*   r(   rY   rQ  q  s     r*   rY   c                     t         j                  j                  |      j                  dd      }|j	                         S )Nr   T)r   r9  )r1   r   on_siter   first)rn  r8   rP   s      r(   get_root_pagezPageType.get_root_pageu  s:    $$T*11 2 
 {{}r*   c                      y)NFr/   r~   s    r(   r   zPageType.is_potential_home}  s    r*   N)r+   r,   r-   rY   classmethodrV  r   r/   r*   r(   rO  rO  p  s%    ! !  r*   rO  )@r|   loggingr   os.pathr   django.contrib.authr   django.contrib.sites.modelsr   	django.dbr   r   django.db.modelsr	   r
   r   django.db.models.baser   django.db.models.constraintsr   django.db.models.functionsr   django.formsr   django.urlsr   r   django.utils.encodingr   django.utils.timezoner   django.utils.translationr   r   rU   r   r   treebeard.mp_treer   rQ   r   cms.models.managersr   r   	cms.utilsr   cms.utils.compat.warningsr   cms.utils.confr   cms.utils.i18nr   r3  r   menus.menu_poolr    r+   loggerdictr"   r1   Modelr   rO  r/   r*   r(   <module>rq     s       . , , + + , 9 - & / + % ` ` %  ;  A * / - %	8	uT u_q7 _qD!%<fll %<Pt r*   