
    h                     f   d dl Z d dlZd dl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 d dl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&m'Z'm(Z( d dl)m*Z* d dl+m,Z,m-Z- d dl.m/Z/m0Z0 d dl1m2Z2 d dl3m4Z4m5Z5m6Z6m7Z7 d dl8m9Z9m:Z: d dl;m<Z<m=Z= d dl>m?Z? d dl@mAZAmBZBmCZCmDZD d dlEmFZF d dlGmHZH d dlImJZJ d dlKmLZM dd lNmOZOmPZP dd!lQmRZRmSZSmTZTmUZU dd"lVmWZW dd#lXmYZY dd$lZm[Z[ dd%l\m]Z]m^Z^m_Z_m`Z`maZambZbmcZcmdZdmeZemfZf dd&lgmhZhmiZi dd'l*mjZj dd(lPmkZk  G d) d*      Zld+ Zm G d, d-      Zn G d. d/e20      Zo G d1 d2      Zp G d3 d4ep      Zq G d5 d6eoeq      Zr G d7 d8epe	ene20      Zs G d9 d:eoes      Zt G d; d<e"      Zud= Zv G d> d?e	ej                  e20      Zxy)@    N)OrderedDict)urlparse)CONTENT_PREFIXChangeListActionsMixinGrouperModelAdmin)PageContent)get_language_from_request)get_cms_setting)is_editable_model)add_url_parametersstatic_with_version)settings)adminmessages)delete_selected)IncorrectLookupParameters)unquote)
ChangeList)ContentType)ImproperlyConfiguredObjectDoesNotExistPermissionDenied)models)OuterRefSubquery)CastLower)MediaDefiningClass)Http404HttpRequestHttpResponseForbiddenHttpResponseNotAllowed)redirectrender)render_to_stringselect_template)TemplateResponse)Resolver404pathresolvereverse)	force_str)format_html)	mark_safe)gettext_lazy   )confversionables)DRAFTINDICATOR_DESCRIPTIONS	PUBLISHEDVERSION_STATES)&notify_version_author_version_unlocked)ConditionFailed)grouper_form_factory)
content_is_unlocked_for_usercreate_version_lockget_admin_urlget_editable_url!get_latest_admin_viewable_contentget_preview_urlproxy_modelremove_version_lockversion_is_lockedversion_list_url)content_indicatorcontent_indicator_menu)Version)_cms_extensionc                   $     e Zd ZdZd fd	Z xZS )VersioningChangeListMixinz4Mixin used for ChangeList classes of content models.c                    |rt         |   ||      }nt         |   |      }t        j                  |j                        }	 i }|j
                  D ]T  }t        | j                  d| d      r$ t        | j                  d| d      |      ||<   A|dk(  sGt        |      ||<   V |j                   |j                  di |      S )z=Limit the content model queryset to the latest versions only.get__from_requestlanguagepk__in )superget_querysetr2   for_contentmodelextra_grouping_fieldshasattrmodel_admingetattrr	   filterdistinct_groupers)selfrequestexclude_parametersquerysetversionablegrouping_filtersfield	__class__s          J/home/dcms/DCMS/lib/python3.12/site-packages/djangocms_versioning/admin.pyrR   z&VersioningChangeListMixin.get_querysetA   s    w+G5GHH w+G4H"..x~~>	  66 	MEt''4wm)DE*`'$2B2Bd5'Q^D_*`ah*i '*$*CG*L '		M
 &Ck&C&C&WFV&WXX    N)__name__
__module____qualname____doc__rR   __classcell__rb   s   @rc   rI   rI   >   s    >Y Yrd   rI   c                 B    t        d| j                  z   t        | fi       S )z8Generate a ChangeList class to use for the content model	Versioned)typerf   rI   )base_changelist_clss    rc   versioning_change_list_factoryrp   \   s*    )222	"$78
 rd   c                   T     e Zd ZdZ fdZ fdZ fdZdZ	 d fd	Zd	 fd	Z	 xZ
S )
VersioningAdminMixinzUMixin providing versioning functionality to admin classes of
    content models.
    c                     t         |   ||||       |s=t        |t              ryt        j
                  j                  ||j                         yy)zo
        Overrides the save method to create a version object
        when a content object is created
        N)content
created_by)rQ   
save_model
isinstancer   rF   objectscreateuser)r[   r\   objformchangerb   s        rc   rv   zVersioningAdminMixin.save_modelj   sJ    
 	7Cv6#{+ OO""37<<"H rd   c                     ddl m}  || j                  | j                  j                        5  t        |   |      }ddd       |S # 1 sw Y   S xY w)zCOverride manager so records not in published state can be displayedr0   )override_default_managerN)helpersr   rT   _original_managerrQ   rR   )r[   r\   r   r^   rb   s       rc   rR   z!VersioningAdminMixin.get_querysetx   sG    5%djj$**2N2NO 	5w+G4H	5	5s   A		Ac                 :    t        |   |fi |}t        |      S re   )rQ   get_changelistrp   )r[   r\   kwargsr   rb   s       rc   r   z#VersioningAdminMixin.get_changelist   s"    W+G>v>
-j99rd   z1djangocms_versioning/admin/mixin/change_form.htmlc                 P    d|vrt         |   |d<   t         | 	  ||||||      S )z7Add a link to the version table to the change form view(versioning_fallback_change_form_template)addr}   form_urlr{   )rQ   change_form_templaterender_change_form)r[   r\   contextr   r}   r   r{   rb   s          rc   r   z'VersioningAdminMixin.render_change_form   sE     6WD , : w)'7F]ekn)oord   c                    |rnt         j                  j                  |      }|j                  j	                  |j
                        }t        j                  r|rt        ||j
                        }|S t        | )  ||      S re   )rF   rx   get_for_contentcheck_modifyas_boolrz   r1   LOCK_VERSIONSr:   rQ   has_change_permission)r[   r\   r{   version
permissionrb   s        rc   r   z*VersioningAdminMixin.has_change_permission   sg    oo55c:G --55gllCJ!!j9#w||L
w,Wc::rd   )FF Nre   )rf   rg   rh   ri   rv   rR   r   r   r   r   rj   rk   s   @rc   rr   rr   e   s8    I: O KO	p	; 	;rd   rr   c                   b     e Zd ZdZ G d d      Z ed      Zed        Zd Z	d Z
 fdZ xZS )	StateIndicatorMixinzMixin to provide state_indicator column to the changelist view of a content model admin. Usage::

        class MyContentModelAdmin(StateIndicatorMixin, admin.ModelAdmin):
            list_display = [..., "state_indicator", ...]
    c                   &    e Zd ZdZd ed      fiZy)StateIndicatorMixin.Media)zadmin/js/jquery.init.jsz%djangocms_versioning/js/indicators.jsallzcms/css/cms.pagetree.cssN)rf   rg   rh   jsr   cssrP   rd   rc   Mediar      s    R '(BCE
rd   r   Statec                 t    	 t        j                  | j                        j                  S # t        $ r Y y w xY wre   )r2   for_grouperrT   rU   KeyErrorr[   s    rc   _extra_grouping_fieldsz*StateIndicatorMixin._extra_grouping_fields   s4    	++DJJ7MMM 		s   (+ 	77c                 8      fd} j                   |_        |S )Nc                    j                   2t        | fddij                   D ci c]  }|t        |       c}}n| }t        |      }|rAt	        ||j
                  j                  dz   j                  j                         z         nd }t        d|xs dt        j                  |t        d            d|r't        j                  t        dd	|i            d
      S d d
      S c c}w )Ninclude_unpublished_archivedT?)backz)admin/djangocms_versioning/indicator.htmlemptyEmptyz'admin/cms/page/tree/indicator_menu.htmlindicator_menu_items)statedescriptionmenu_templatemenu)r   r>   rX   rD   rE   _version	path_infoGET	urlencoder%   r4   get_jsondumps)r{   ra   content_objstatusr   r\   r[   s        rc   	indicatorz;StateIndicatorMixin.get_indicator_column.<locals>.indicator   s!   **6? bf =A=X=Xk49E74//k  "&{3F  *$$&&,w{{/D/D/FF	
 "  $;#.w#9#=#=faj#Q%N\` !JJ'78a9OQU8V(X Y		 	 gk	 	ks   C-)indicator_column_labelshort_description)r[   r\   r   s   `` rc   get_indicator_columnz(StateIndicatorMixin.get_indicator_column   s    	0 '+&A&A	#rd   c                     t        d      )NzModelAdmin.display_list contains "state_indicator" as a placeholder for status indicators. Status indicators, however, are not loaded. If you implement "get_list_display" make sure it calls super().get_list_display.)
ValueErrorr[   r{   s     rc   state_indicatorz#StateIndicatorMixin.state_indicator   s    6
 	
rd   c                     t        j                   j                        st        j                   j                        r"t	         fdt
                 D              S t	        d t
                 D              S )zMDefault behavior: replaces the text "state_indicator" by the indicator columnc              3   N   K   | ]  }|d k(  rj                        n|  ywr   N)r   ).0itemr\   r[   s     rc   	<genexpr>z7StateIndicatorMixin.get_list_display.<locals>.<genexpr>   s6      H! @DGX?X227;^bb Hs   "%c              3   ,   K   | ]  }|d k7  s	|  ywr   rP   )r   r   s     rc   r   z7StateIndicatorMixin.get_list_display.<locals>.<genexpr>   s     i$tWhOhis   
)r2   exists_for_contentrT   exists_for_groupertuplerQ   get_list_display)r[   r\   rb   s   ``rc   r   z$StateIndicatorMixin.get_list_display   sn    **4::6,:Y:YZ^ZdZd:e H%*W%=g%FH H H i%'*B7*Kiiird   )rf   rg   rh   ri   r   r   r   propertyr   r   r   r   rj   rk   s   @rc   r   r      sF    

 
 wZ 8
j jrd   r   )	metaclassc                   >     e Zd ZdZed        Zd Zd Z fdZ xZ	S )ExtendedListDisplayMixinz~Implements the extend_list_display method at allows other packages to add fields to the list display
    of a verisoned objectc                 "    t        | t              S re   )rw   r   r   s    rc   _is_grouper_adminz*ExtendedListDisplayMixin._is_grouper_admin   s    $ 122rd   c                 2     |    fd}|_         |S )Nc                 ^    j                   r j                  |             S  |       S re   )r   get_content_obj)r{   ra   methodr[   s    rc   get_field_modifierzHExtendedListDisplayMixin._get_field_modifier.<locals>.get_field_modifier   s1    %%d2237??c5))rd   )r   )r[   r\   modifier_dictra   r   r   s   `  ` @rc   _get_field_modifierz,ExtendedListDisplayMixin._get_field_modifier   s#    u%	* 05,!!rd   c                    g |}|D ]Z  }t        ||         st        d      	 | j                  rt        nd}| j	                  |||      }|||j                  ||z         <   \ t        |      S # t        $ r t        d      d w xY w)NzField provided must be callabler   z/The target field does not exist in this context)callabler   r   r   r   indexr   r   )r[   r\   r   list_displayra   prefixfield_modifiers          rc   extend_list_displayz,ExtendedListDisplayMixin.extend_list_display   s    &" 	hEM%01*+LMMh+/+A+Ar!%!9!9'=RW!XCQ\//?@	h \""  h*+\]cgghs   >A//Bc                    t         |   |      }t               }t        | t              r'|j
                  j                  | j                  d       }n&|j
                  j                  | j                  d       }|r| j                  |||      }|S re   )
rQ   r   rG   rw   r   add_to_field_extensionr   content_modelrT   r   )r[   r\   r   	extensionr   rb   s        rc   r   z)ExtendedListDisplayMixin.get_list_display  s}    w/8"$	d-.%<<@@ASASUYZM%<<@@TRM33G]LYLrd   )
rf   rg   rh   ri   r   r   r   r   r   rj   rk   s   @rc   r   r      s0     3 3
"# rd   r   c                       e Zd ZdZdedej                  f fdZ ej                   e
d      d      dej                  dej                  ed	f   fd
       Z ej                   e
d      d      dej                  dej                  ed	f   fd       Z ej                   e
d      d      dej                  dej                  ed	f   fd       Zdedej                  defdZ xZS ) ExtendedGrouperVersionAdminMixina  Mixin to provide state_indicator, author and changed date column to the changelist view of a
    grouper model admin. Usage::

        class MyContentModelAdmin(ExtendedGrouperVersionAdminMixin, cms.admin.utils.GrouperModelAdmin):
            list_display = [
                ...,
                "get_author",   # Adds the author column
                "get_modified_date",  # Adds the modified column
                "get_versioning_state",  # Adds the state (w/o interaction)
                ...]

        r\   returnc                    t        j                  | j                        j                  }t        |   |      }t        j                  j                  t        d      |      } | j                  j                  j                  di | j                  t        d      i| j                  j                  t!        |j#                  dt$        j&                         dd       t!        |j#                  d            t!        |j#                  d      dd             }|j                  t!        |j#                  d	      dd       t)        t!        |j#                  d	      dd             t!        |j#                  d
            t+        t!        |j#                  d      dd       t-        j.                                     }|S )zAnnotates the username of the ``created_by`` field, the ``modified`` field (date time),
        and the ``state`` field of the version object to the grouper queryset.pk)	object_idcontent_type__increated_by__Nr0   r   modified)content_created_bycontent_statecontent_modifiedr   r   r   )r   content_created_by_sortr   r   rP   )r2   r   rT   content_typesrQ   rR   rF   rx   rY   r   r   admin_managerlatest_contentgrouper_field_namecurrent_content_filtersannotater   valuesr1   USERNAME_FIELDr   r   r   DateTimeField)r[   r\   grouper_content_typeqsversionscontentsrb   s         rc   rR   z-ExtendedGrouperVersionAdminMixin.get_queryset  s     ,77

CQQW!'*??))HTNUi)jB4%%33BB 
&&W$:V:VW

(',tGZGZF[8\(]^`_`(ab"8??7#;<%hooj&A"1&EF  
 	 [['8L(Mbq(QR$)(8??CW3XY[Z[3\*]$^"8???#CD!(8??;M+NrPQ+R"SU[UiUiUkl  
 	rd   r   r   r   orderingr{   Nc                 R    t        t              j                  |j                        S )a  Returns verbose text of objects versioning state. This is a text column without user interaction.
        Typically, either ``get_versioning_state`` or ``state_indicator`` (provided by the
        :class:`~djangocms_versioning.admin.StateIndicatorMixin`) is used. The state indicator
        allows for user interaction.
        :param obj: Versioned grouper model instance annotated with its content state
        :return: description of state
        )dictr6   r   r   r   s     rc   get_versioning_statez5ExtendedGrouperVersionAdminMixin.get_versioning_state3  s      N#''(9(9::rd   Authorr   c                     t        |dd      S )z
        Return the author who created a version
        :param obj: Versioned grouper model instance annotated with its author username
        :return: Author username
        r   NrX   r   s     rc   
get_authorz+ExtendedGrouperVersionAdminMixin.get_authorA  s     s0$77rd   Modifiedr   c                     t        |dd      S )z
        Get the last modified date of a version
        :param obj: Versioned grouper model instance annotated with its modified datetime
        :return: Modified Date
        r   Nr  r   s     rc   get_modified_datez2ExtendedGrouperVersionAdminMixin.get_modified_dateO  s     s.55rd   r   c                     |yt         j                  j                  |      }|j                  j	                  |j
                        S )z+Returns True if user can change content_objT)rF   rx   r   r   r   rz   )r[   r\   r   r   s       rc   can_change_contentz3ExtendedGrouperVersionAdminMixin.can_change_content[  s:    //11+>##++GLL99rd   )rf   rg   rh   ri   r    r   QuerySetrR   r   displayr   ModeltypingUnionstrr  r  r	  boolr  rj   rk   s   @rc   r   r     s   K FOO , U]]gJ ; ;c4i9P ;	; U]]hK*8fll 8v||CI/F 8	8 U]]jM#6V\\ 6fll396M 6	6:+ :FLL :UY :rd   r   c                   "     e Zd ZdZ fdZ xZS )"DefaultGrouperVersioningAdminMixina  Default mixin for grouper model admin classes: Includes state indicator, author and modified date.
    Usage::
        class MyContentModelAdmin(DefaultGrouperAdminMixin, cms.admin.utils.GrouperModelAdmin):
            list_display = [
                ...,
                "get_author",   # Adds the author column
                "get_modified_date",  # Adds the modified column
                "state_indicator",  # Adds the state indicator column
                ...]

    If "state_indicator" is not in `list_display`, it will be added automatically before the
    "admin_list_actions" field, or - together with the actions - at the end of the list_display
    if no actions are present.
    c                     t        | dd      }d|vr8d|v r&|j                  d      }g |d | d||d  | _        ng |dd| _        t        |   |      S )Nr   rP   r   admin_list_actions)rX   r   r   rQ   r   )r[   r\   r   r   rb   s       rc   r   z3DefaultGrouperVersioningAdminMixin.get_list_displayt  s    t^R8L0#|3 %**+?@%!&5)%%% "%&)%! %^l$]4E$]G[$]!w'00rd   )rf   rg   rh   ri   r   rj   rk   s   @rc   r  r  e  s    1 1rd   r  c                       e Zd ZdZdZ fdZd Z ej                   e	d      d      d        Z
 ej                   e	d	      d
      d        Z ej                   e	d      d      d        Zd ZddZddZddZd Z fdZ xZS )ExtendedVersionAdminMixina  
    Extended VersionAdminMixin for common/generic versioning admin items

    CAVEAT: Ordered fields are implemented by this mixin, if custom ordering is added to any models that
    inherits this Mixin it will require accommodating/reimplementing this.
    )r  r	  r  c                 ~    t         |   |      }|j                  t        dt        j
                               }|S )Nversions__created_by__)created_by_username_ordering)rQ   rR   r   r   r1   r   )r[   r\   r^   rb   s      rc   rR   z&ExtendedVersionAdminMixin.get_queryset  sA    7'0 $$%J`aeatat`uHvBw$xrd   c                 <    |j                   j                         d   S )z
        Return the latest version of a given object
        :param obj: Versioned Content instance
        :return: Latest Version linked with content instance
        r   )r   r   r   s     rc   get_versionz%ExtendedVersionAdminMixin.get_version  s     ||!!$$rd   r   versions__stater   c                 @    | j                  |      j                         S )z5
        Return the state of a given version
        )r  get_state_displayr   s     rc   r  z.ExtendedVersionAdminMixin.get_versioning_state  s     $6688rd   r  r  c                 8    | j                  |      j                  S )z
        Return the author who created a version
        :param obj: Versioned content model Instance
        :return: Author
        )r  ru   r   s     rc   r  z$ExtendedVersionAdminMixin.get_author  s     $///rd   r  versions__modifiedc                 8    | j                  |      j                  S )z
        Get the last modified date of a version
        :param obj: Versioned content model Instance
        :return: Modified Date
        )r  r   r   s     rc   r	  z+ExtendedVersionAdminMixin.get_modified_date  s     $---rd   c                 <    t        |d      r|j                         S y)zo
        Return the preview method if available, otherwise return None
        :return: method or None
        r?   N)rV   r?   r   s     rc   _get_preview_urlz*ExtendedVersionAdminMixin._get_preview_url  s!    
 3)*&&((rd   c                     | j                  |      xs t        |      }|sd}| j                  |dt        d      dd|      S )a  
        Return a user-friendly button for previewing the content model
        :param obj: Instance of versioned content model
        :param request: The request to admin menu
        :param disabled: Should the link be marked disabled?
        :return: Preview icon template
        TviewPreviewpreviewF)icontitlenamekeepsideframedisabled)r%  r?   admin_action_buttonr   )r[   r{   r\   r.  preview_urls        rc   _get_preview_linkz+ExtendedVersionAdminMixin._get_preview_link  sT     ++C0HOC4HH''I, ( 
 	
rd   c           	      &   t        | j                  |      | j                        }|j                  j	                  |j
                        sy|j
                  j                  |j                  j                   d|j                  j                         sd}t        d|j                  j                   d|j                  j                   d|j                  f      }|j                  t        k(  rp|j                  j                  |      j!                  dd	      }t"        j$                  j'                  ||j(                  t*        
      }|j-                         ryd}nd}| j/                  |||dk(  rt1        d      n
t1        d      d|dd      S )a  
        Return a user-friendly button for editing the content model
        - mark disabled if user doesn't have permission
        - hide completely if instance cannot be edited
        :param obj: Instance of Versioned model
        :param request: The request to admin menu
        :param disabled: Should the link be marked disabled?
        :return: Preview icon template
        r   .Tadmin:r   _edit_redirectargsr   flatobject_id__incontent_typer   edit-neweditEdit	New DraftpostF)r*  r+  r,  r.  actionr-  )r@   r  rT   check_edit_redirectr   rz   has_perm_meta	app_label
model_namer+   r   r   r5   r_   for_content_grouping_valuesvalues_listrF   rx   rY   r<  r3   existsr/  r   )	r[   r{   r\   r.  r   urlpks_for_grouperdraftsr*  s	            rc   _get_edit_linkz(ExtendedVersionAdminMixin._get_edit_link  sd    d..s3TZZ@**227<<@||$$		(;(;'<Acii>R>R=S%TUHW]],,-Qw}}/G/G.HW**

 ==I%%11MMk$Tk*  __++-$11 , F
 }}DD''#v~!F)1[> ( 
 	
rd   c                 V    t        |      }| j                  |dt        d      d|      S )NcopyzManage versionszmanage-versionsr*  r+  r,  r.  )rC   r/  r   )r[   r{   r\   r.  rK  s        rc   _get_manage_versions_linkz3ExtendedVersionAdminMixin._get_manage_versions_link  s9    s#''%&" ( 
 	
rd   c                     | j                   | j                  g}d| j                  vr|j                  | j                         |S )zV
        Collect rendered actions from implemented methods and return as list
        r   )r1  rN  versioning_list_displayappendrR  )r[   actionss     rc   get_actions_listz*ExtendedVersionAdminMixin.get_actions_list(  sD    
 ""
 D$@$@@NN499:rd   c                 j    t         |   |      }|| j                  | j                  |      fz   z  }|S re   )rQ   r   rT  get_admin_list_actions)r[   r\   r   rb   s      rc   r   z*ExtendedVersionAdminMixin.get_list_display5  s<    w/8448S8ST[8\7^^^rd   F)rf   rg   rh   ri   rT  rR   r  r   r  r   r  r  r	  r%  r1  rN  rR  rW  r   rj   rk   s   @rc   r  r    s    % U]]gJ"9	9 U]]hK/0	0 U]]jM%.	.
*0
d
 rd   r  c                       e Zd ZdZy)"ExtendedIndicatorVersionAdminMixin)r  r	  r   N)rf   rg   rh   rT  rP   rd   rc   r\  r\  =  s
    rd   r\  c                   2     e Zd Zd fd	Zd Zd fd	Z xZS )VersionChangeListc                     | j                   j                  j                  }t        j                  |      }t
        |   |      }|j                  |j                  d       |S )zRemoves the grouper param from the filters as the main grouper
        filtering is not handled by the UI filters and therefore needs to be
        handled differently.
        N)	rW   rT   _source_modelr2   rS   rQ   get_filters_paramspopr   )r[   paramsr   r_   filter_paramsrb   s        rc   ra  z$VersionChangeList.get_filters_paramsF  sW    
 ((..<<"..}=26:+88$?rd   c              #      K   | j                   j                  j                  }t        j                  |      }|j
                  }|D ]&  }|j                  j                  |      }|!||f ( yw)aR  Handles extra grouping params (such as PageContent.language).

        The get_filters_params method does return these filters as they are
        visible in the UI, however they need extra handling due to db
        optimization and the difficulties involved in handling the
        generic foreign key from Version to the content model.N)rW   rT   r`  r2   rS   grouping_fieldsr   r   )r[   r\   r   r_   fieldsra   values          rc   get_grouping_field_filtersz,VersionChangeList.get_grouping_field_filtersQ  sk      ((..<<"..}=,, 	#EKKOOE*E Ul"	#s   A$A0'	A0c                 >   |rt         |   ||      }nt         |   |      }| j                  j                  j                  }t        j                  |      }t        | j                  |            }|j                  |vrt        d       |j                  |fi |S )au  Adds support for querying the version model by grouping fields.

        Filters by the value of grouping fields (specified in VersionableItem
        definition) of content model.

        Functionality is implemented here, because list_filter doesn't allow
        for specifying filters that work without being shown in the UI
        along with filter choices.
        zMissing grouper)rQ   rR   rW   rT   r`  r2   rS   r  ri  r   r   filter_by_grouping_values)r[   r\   r]   r^   r   r_   filtersrb   s          rc   rR   zVersionChangeList.get_queryset`  s     w+G5GHH w+G4H((..<<"..}=t66w?@))8+,=>>1x11+IIIrd   re   )rf   rg   rh   ra  ri  rR   rj   rk   s   @rc   r^  r^  E  s    	#J Jrd   r^  c                     | j                   j                  j                        | j                      G fddt        j
                        }|S )zrReturns filters that merely expose the filtering UI,
    without having any effect on the resulting queryset.
    c                   >    e Zd ZW  j                  ZW ZfdZd Zy)'fake_filter_factory.<locals>.FakeFilterc                 ,    t              r        S S re   )r   )r[   r\   rW   lookups_s      rc   lookupsz/fake_filter_factory.<locals>.FakeFilter.lookups  s    !z!rd   c                     |S re   rP   )r[   r\   r^   s      rc   r^   z0fake_filter_factory.<locals>.FakeFilter.queryset  s    Ord   N)rf   rg   rh   verbose_namer+  parameter_namerr  r^   )ra   
field_namerq  s   rc   
FakeFilterro    s    ""#	 	rd   rw  )r   rE  	get_fieldversion_list_filter_lookupsr   SimpleListFilter)r_   rv  rw  ra   rq  s    ` @@rc   fake_filter_factoryr{  x  sP     %%++55jAE66zBH U++  rd   c                       e Zd ZdZddgZdej                  rdndz   dz   ej                  rdndz   d	z   Zd
Z	 G d d      Z
d Zd Zd Z ej                   ed      d      d        Z ej                   ed            d        Zd Zd<dZd Zd<dZd<dZd<dZd<dZd Zd Zd  Zd! Z ej<                   ed"            d#        Zd=d$Z  ej<                  d%g ed&      '      d(        Z! fd)Z"d* Z#d+ Z$d, Z%d- Z&d. Z'd/ Z(d0 Z)d1 Z*d2 Z+d3 Z,d4 Z-d5 Z.e/d=d6       Z0d= fd7	Z1 fd8Z2d9 Z3d= fd:	Z4d= fd;	Z5 xZ6S )>VersionAdminz)Admin class used for version models.
    compare_versionsr   )number)createdrP   )r   rt   ru   )locked)r   r  Nc                       e Zd ZdgZy)VersionAdmin.Mediaz%djangocms_versioning/js/versioning.jsN)rf   rg   rh   r   rP   rd   rc   r   r    s
    56rd   r   c                 "    t         j                  S re   )r1   
VERBOSE_UIr[   r\   s     rc   has_module_permissionz"VersionAdmin.has_module_permission  s    rd   c                     t         S re   )r^  )r[   r\   r   s      rc   r   zVersionAdmin.get_changelist  s      rd   c                     t        j                  | j                  j                        }|j                  D cg c]  }t        ||       c}S c c}w )z9Adds the filters for the extra grouping fields to the UI.)r2   rS   rT   r`  rU   r{  )r[   r\   r_   ra   s       rc   get_list_filterzVersionAdmin.get_list_filter  sK    "..tzz/G/GH %::
  U3
 	
 
s   AContentrt   r   c                     t        j                  dt        d       |j                  }t	        |      }t        dt        |      |      S )zEDisplay html for the content preview url - replaced by Preview actionz(VersionAdmin.content_link is deprecated.   
stacklevelzD<a target="_top" class="js-close-sideframe" href="{url}">{label}</a>)rK  label)warningswarnDeprecationWarningrt   r?   r-   r.   )r[   r{   rt   rK  s       rc   content_linkzVersionAdmin.content_link  sD     	@BTabc++g&R#
 	
rd   r  )r   c                 V    |j                   t        k(  rt        |      rt        d      S y)z?
        Generate an locked field for Versioning Admin
        z,<span class="cms-icon cms-icon-lock"></span>r   )r   r3   rB   r.   )r[   r   s     rc   r  zVersionAdmin.locked  s'     ==E!&7&@KLLrd   c           	          |j                   t        k(  ryt        |j                        }| j	                  |dddt        d            S )Nr   r'  r)  Fr(  )r*  r,  r-  r+  )r   r3   r?   rt   r/  r   )r[   r{   r\   rK  s       rc   r1  zVersionAdmin._get_preview_link  sJ    99ckk*''I, ( 
 	
rd   c           	      L   |j                         syt        d|j                  j                   d| j                  j                  j
                   d|j                  f      }| j                  |dt        d      d|j                  j                  |j                               S )	zCHelper function to get the html link to the archive action
        r   r4  r   _archiver6  archiveArchiverQ  )can_be_archivedr+   rE  rF  rT   rG  r   r/  r   check_archiver   rz   )r[   r{   r\   r.  archive_urls        rc   _get_archive_linkzVersionAdmin._get_archive_link  s     ""$SYY(()4::+;+;+F+F*GxP&&
 ''I,**227<<@@ ( 
 	
rd   c           
      P   |j                         syt        d|j                  j                   d| j                  j                  j
                   d|j                  f      }| j                  |dt        d      dd|j                  j                  |j                         d	
      S )zCHelper function to get the html link to the publish action
        r   r4  r   _publishr6  publishPublishrA  Fr*  r+  r,  rB  r.  r-  )can_be_publishedr+   rE  rF  rT   rG  r   r/  r   check_publishr   rz   )r[   r{   r\   publish_urls       rc   _get_publish_linkzVersionAdmin._get_publish_link  s     ##%SYY(()4::+;+;+F+F*GxP&&
 ''I,**227<<@@ ( 
 	
rd   c           	      L   |j                         syt        d|j                  j                   d| j                  j                  j
                   d|j                  f      }| j                  |dt        d      d|j                  j                  |j                               S )	zEHelper function to get the html link to the unpublish action
        r   r4  r   
_unpublishr6  	unpublish	UnpublishrQ  )can_be_unpublishedr+   rE  rF  rT   rG  r   r/  r   check_unpublishr   rz   )r[   r{   r\   r.  unpublish_urls        rc   _get_unpublish_linkz VersionAdmin._get_unpublish_link
  s     %%'SYY(()4::+;+;+F+F*GzR&&
 ''K.,,44W\\BB ( 
 	
rd   c           	         |j                   j                  |j                        sy|j                  t        k(  rz|j
                  j                  |j                        j                  dd      }t        j                  j                  ||j                  t              }|j                         ryd}nd}|j
                  j                  }t!        d|j"                  j$                   d	| j&                  j"                  j(                   d
|j*                  f      }| j-                  |||dk(  rt/        d      n
t/        d      dd||      S )z@Helper function to get the html link to the edit action
        r   r   Tr8  r:  r=  r>  r4  r   r5  r6  r?  r@  rA  r  )rC  r   rz   r   r5   r_   rH  rt   rI  rF   rx   rY   r<  r3   rJ  #content_model_is_sideframe_editabler+   rE  rF  rT   rG  r   r/  r   )	r[   r{   r\   r.  rL  rM  r*  r-  edit_urls	            rc   rN  zVersionAdmin._get_edit_link  s,    &&..w||< 99	!!ooIIk$Tk*  __++- -- , F
 }}DD KKSYY(()4::+;+;+F+F*G~V&&
 ''#v~!F)1[>' ( 
 	
rd   c           	      d   |j                   t        t        fv ryt        d|j                  j
                   d| j                  j                  j                   d|j                  f      }| j                  |dt        d      d|j                  j                  |j                         xs |	      S )
zBHelper function to get the html link to the revert action
        r   r4  r   _revertr6  undoRevertrevertrQ  )r   r5   r3   r+   rE  rF  rT   rG  r   r/  r   check_revertr   rz   )r[   r{   r\   r.  
revert_urls        rc   _get_revert_linkzVersionAdmin._get_revert_linkD  s     99E**SYY(()4::+;+;+F+F*GwO&&

 ''H+))11',,??K8 ( 
 	
rd   c           	      Z   |j                   t        k7  ryt        d|j                  j                   d| j
                  j                  j                   d|j                  f      }| j                  |dt        d      d|j                  j                  |j                         xs |	      S )
zCHelper function to get the html link to the discard action
        r   r4  r   _discardr6  binDiscarddiscardrQ  )r   r3   r+   rE  rF  rT   rG  r   r/  r   check_discardr   rz   )r[   r{   r\   r.  discard_urls        rc   _get_discard_linkzVersionAdmin._get_discard_linkW  s     99SYY(()4::+;+;+F+F*GxP&&
 ''I,**227<<@@LH ( 
 	
rd   c           
         t         j                  r|j                  t        k7  st	        |      syt        d|j                  j                   d| j                  j                  j                   d|j                  f      }| j                  |dt        d      dd|j                  j                  |j                         	      S )
zB
        Generate an unlock link for the Versioning Admin
        r   r4  r   _unlockr6  unlockUnlockrA  )r*  r+  r,  rB  r.  )r1   r   r   r3   rB   r+   rE  rF  rT   rG  r   r/  r   check_unlockr   rz   )r[   r{   r\   
unlock_urls       rc   _get_unlock_linkzVersionAdmin._get_unlock_linkj  s    
 !!SYY%%7?PQT?Uvcii&9&9%:!DJJ<L<L<W<W;XX_`hkhnhngpq
''H+))11',,?? ( 
 	
rd   c                 D   |j                   j                  }t        |      sy	 t        d|j                  j
                   d|j                  j                   d|j                  j                  f      }| j                  |dt        d      d      S # t        $ r Y yw xY w)	zE
        Generate a settings button for the Versioning Admin
        r   r4  r   _changer6  r   Settings)r*  r+  r,  )r_   r   r   r+   rE  rF  rG  rt   r   r(   r/  r   )r[   r{   r\   r   settings_urls        rc   _get_settings_linkzVersionAdmin._get_settings_link|  s     55 /	",,667q9L9L9W9W8XX_`kknn&L ''J-	 ( 
 	
  		s   AB 	BBc                 "    | j                         S )z"Returns all action links as a list)get_state_actionsr   s    rc   rW  zVersionAdmin.get_actions_list  s    %%''rd   c           	         t         j                  rKddl}|j                  |j	                         d      }|d   d   dk7  rt        j                  dt        d       | j                  | j                  | j                  | j                  | j                  | j                  | j                  | j                  | j                   g	S )	zhCompatibility shim for djangocms-moderation. Do not use.
        It will be removed in a future version.r   Nr  r0      rW  zModifying get_state_actions is deprecated. VersionAdmin.get_state_actions will be removed in a future version. Use get_actions_list instead.r  )r   DEBUGinspectgetouterframescurrentframer  r  r  r1  rN  r  r  r  r  r  r  r  )r[   r  caller_frames      rc   r  zVersionAdmin.get_state_actions  s     >>"11'2F2F2H!LLAq!%77 c0Q@
 """"""$$!!""!!##

 
	
rd   zCompare versionsc                 ~   |j                  d      }|j                         dk7  r| j                  |t        d             yt	        d| j
                  j                  j                   d| j
                  j                  j                   d|d   j                  f	      }|d
|d   j                   z  }t        |      S )zN
        Redirects to a compare versions view based on a users choice
        r   r  z)Exactly two versions need to be selected.Nr4  r   _comparer   r6  z?compare_to=r0   )order_bycountmessage_userr   r+   rT   rE  rF  rG  r   r#   )r[   r\   r^   rK  s       rc   r~  zVersionAdmin.compare_versions  s     $$T* >>q gq)T'UV TZZ%%//0$**2B2B2M2M1NhW1+.."
 	hqknn-..}rd   c                     t         )zBDo not allow deleting single version objects. Use discard instead.)r   )r[   r\   r   extra_contexts       rc   delete_viewzVersionAdmin.delete_view  s    rd   deletez'Delete selected %(verbose_name_plural)s)permissionsr   c                 "   |j                  t        t        f      }|j                         r+| j	                  |t        d      t        j                         y|j                  j                  d      r| j                  |      }t        | ||      S )zM
        Redirects to a delete versions view based on a users choice
        )	state__inzYDraft or published versions cannot be deleted. First unpublish or use discard for drafts.NrA  )rY   r5   r3   rJ  r  r   r   ERRORPOSTr   get_content_querysetr   )r[   r\   r^   	forbiddens       rc   r   zVersionAdmin.delete_selected  s|     OOy%.@OA	mn
 <<F#00:HtWh77rd   c                 z    t        |j                  t              r| j                  |      }t        |   ||      S )z(Return the content objects to be deleted)
issubclassrT   rF   r  rQ   get_deleted_objects)r[   objsr\   rb   s      rc   r  z VersionAdmin.get_deleted_objects  s3    djj'*,,T2Dw*499rd   c                     | j                   j                  j                  j                  |j	                  dd            S )Nr   Tr8  rN   )rT   r`  _base_managerrY   rI  )r[   r^   s     rc   r  z!VersionAdmin.get_content_queryset  s=    zz''55<<''$'? = 
 	
rd   c           
         t        |      }t        j                  | j                  j                        }t        | j                  j                  |      | j                  j                   t        | j                  j                  || j                               t        d      j                  |j                  j                  j                              }t        |d|      S )z^Displays an intermediary page to select a grouper object
        to show versions of.
        zSelect {} to view its versions)optsr|   r+  z,djangocms_versioning/admin/grouper_form.html)r	   r2   rS   rT   r`  r  
admin_siteeach_contextrE  r9   r   formatgrouper_modelrt  r$   )r[   r\   rM   r_   r   s        rc   grouper_form_viewzVersionAdmin.grouper_form_view  s     -W5"..tzz/G/GHOO((1!!Z%djj&>&>$//Z\45<<[=V=V=\=\=i=ij	
 gMwWWrd   c           
      ,   | j                  |t        |            }|'| j                  || j                  j                  |      S |j                         sH| j                  |t        d      t        j                         t        t        |j                              S 	 |j                  |j                         |j"                  dk7  r|j                  |j$                  |t'        d| j                  j                  j(                   d| j                  j                  j*                   d|j                  j,                  f      | j/                  ||      d}t1        |d	|      S |j3                  |j                         | j                  |t        d
             t        t        |j                              S # t        $ rR}| j                  |t!        |      t        j                         t        t        |j                              cY d}~S d}~ww xY w)z\Archives the specified version and redirects back to the
        version changelist
        NzVersion cannot be archivedr  r4  r   r  r6  )object_nameversion_numberr   r  back_urlz4djangocms_versioning/admin/archive_confirmation.htmlzVersion archived)
get_objectr    _get_obj_does_not_exist_redirectrT   rE  r  r  r   r   r  r#   rC   rt   r  rz   r8   r,   r   r  r+   rF  rG  r   	back_linkr$   r  )r[   r\   r   r   er   s         rc   archive_viewzVersionAdmin.archive_view  s    //'79+=>?88))9  &&(gq)E'FW,W__=>>	?!!',,/
 >>V#&")..&&TZZ--778$**:J:J:U:U9VV^_!//,,.  !NN7G<	G OQX 
 OOGLL)gq);'<=(9::1  	?gy|X^^D,W__=>>	?s   F8 8	HAHHHc                    |j                   dk7  rt        dgt        d            S | j                  |t	        |            }|'| j                  || j                  j                  |      S |j                  j                  dd      }t        j                  dv rt        |j                        }nt        |j                        }|j                         s<| j!                  |t        d      t"        j$                         | j'                  ||      S 	 |j)                  |j*                         |j1                  |j*                         | j!                  |t        d             t        j                  dk(  r4t3        |j                  d	      r|xs |j                  j5                         }| j'                  ||      S # t,        $ rF}| j!                  |t/        |      t"        j$                         | j'                  ||      cY d}~S d}~ww xY w)
z]Publishes the specified version and redirects back to the
        version changelist
        r  $This view only supports POST method.Nnextr)  	publishedzVersion cannot be publishedzVersion publishedr  get_absolute_url)r   r"   r   r  r   r  rT   rE  r   r   r1   ON_PUBLISH_REDIRECTr?   rt   rC   r  r  r   r  _internal_redirectr  rz   r8   r,   r  rV   r  )r[   r\   r   r   requested_redirectredirect_urlr  s          rc   publish_viewzVersionAdmin.publish_view)  s   
 >>V#)!BC 
 //'79+=>?88))9  %[[__VT:##'??*7??;L+GOO<L'')gq)F'GX**+=|LL	M!!',,/ 	% 	'1%8#9: ##{2w(:;%7%]7??;[;[;]"&&'9<HH  	Mgy|X^^D**+=|LL	Ms   F: :	H	;H>H	H	c                 ~    |st        |      S 	 t        |       t        |      S # t        $ r t        |      cY S w xY w)zHelper function to check if the give URL is resolvable
        If resolvable, return the URL; otherwise, returns the fallback URL.
        )r#   r*   r(   )r[   rK  fallbacks      rc   r  zVersionAdmin._internal_redirectV  sF     H%%	&CL }  	&H%%	&s   % <<c                    | j                  |t        |            }|'| j                  || j                  j                  |      S t
        j                  dv rt        |j                        }nt        |j                        }|j                         s5| j                  |t        d      t        j                         t        |      S 	 |j!                  |j"                         |j(                  dk7  r|j                  |j*                  |t-        d| j                  j                  j.                   d| j                  j                  j0                   d|j                  j2                  f      | j5                  ||      d	}t7        t9               j:                  j=                  d
i       j?                         D cg c]  \  }}| |||      f c}}      }	|jA                  d|	i       tC        |d|      S |jE                  |j"                         | j                  |t        d             t        |      S # t$        $ r?}| j                  |t'        |      t        j                         t        |      cY d}~S d}~ww xY wc c}}w )z_Unpublishes the specified version and redirects back to the
        version changelist
        Nr  zVersion cannot be unpublishedr  r4  r   r  r6  )r  r  r   r  r  r  r  z6djangocms_versioning/admin/unpublish_confirmation.htmlzVersion unpublished)#r  r   r  rT   rE  r1   r  r?   rt   rC   r  r  r   r   r  r#   r  rz   r8   r,   r   r  r+   rF  rG  r   r  r   rG   add_to_contextr   itemsupdater$   r  )
r[   r\   r   r   r  r  r   keyfuncr  s
             rc   unpublish_viewzVersionAdmin.unpublish_viewd  s)   
 //'79+=>?88))9  ##'??*7??;L+GOO<L))+:;X^^ L))	*##GLL1
 >>V#&")..&!(TZZ--778$**:J:J:U:U9VV`a!//,,." !NN7G<	G ( &4%5#^CCR$8UW	!T $w01M NNO];<H  gll+gq)>'?@%%G  	*gy|X^^DL))	* s$   H: <J
:	J4I=7J=Jc                    |j                   t        k(  r|j                  j                  |j                        j                  dd      }t        j                  j                  |j                        }t        j                  j                  ||t              }|j                         rS|j                         }|j                  |j                         t         j"                  rt%        ||j                         |S |j'                  |j                        S |j                   t        k(  r(t         j"                  rt%        ||j                         |S y)zJHelper method to get the latest draft or create one if one does not exist.r   Tr8  r:  N)r   r5   r_   rH  rt   rI  r   rx   get_for_modelrF   rY   r3   rJ  firstrC  rz   r1   r   r;   rP  )r[   r\   r   rL  r<  rM  drafts          rc   _get_edit_redirect_versionz'VersionAdmin._get_edit_redirect_version  s    ==I% &11MMk$Tk*  '..<<W__ML__++-LPU , F }} ))',,7%%'> <<--]]e#!!#GW\\:N	 $rd   c                    |j                   dk7  rt        dgt        d            S | j                  |t	        |            }|t
        	 |j                  |j                         | j                  ||      }t        t#        |j                   |j$                  j'                  d                  S # t        $ rR}| j                  |t        |      t        j                         t        t        |j                               cY d}~S d}~ww xY w)zgRedirects to the admin change view and creates a draft version
        if no draft exists yet.
        r  r  Nforce_admin)r   r"   r   r  r   r   rC  rz   r  r8   r  r,   r   r  r#   rC   rt   r=   r   r   )r[   r\   r   r   targetr  s         rc   edit_redirect_viewzVersionAdmin.edit_redirect_view  s    
 >>V#)!BC  //'79+=>?M	?''544WgFF (9WXYY  	?gy|X^^D,W__=>>	?s   
-B/ /	D
8AD?D
D
c                    | j                  |t        |            }|t        	 |j                  |j                         |j                  j                  |j                        j                  dd      }t         j"                  j%                  ||j&                  t(              }d}|j+                         r|j-                         }|j.                  dk7  r|j                  |j0                  ||t3        d| j4                  j6                  j8                   d| j4                  j6                  j:                   d	|j                  j<                  f
      | j?                  ||      d}tA        |d|      S |r6|jB                  jE                  d      r|jG                  |j                         |r+|jB                  jE                  d      r|jI                          |jK                  |j                        }t        t        |j                              S # t
        $ rR}| j                  |t        |      t        j                         t        t        |j                              cY d}~S d}~ww xY w)z>Reverts to the specified version i.e. creates a draft from it.Nr   Tr8  r:  r  r4  r   r  r6  r  r  draft_versionr   r  r  z3djangocms_versioning/admin/revert_confirmation.htmlr  r  )&r  r   r   r  rz   r8   r  r,   r   r  r#   rC   rt   r_   rH  rI  rF   rx   rY   r<  r3   rJ  r  r   r  r+   rT   rE  rF  rG  r   r  r$   r  r   r  r  rP  )	r[   r\   r   r   r  rL  rM  r  r   s	            rc   revert_viewzVersionAdmin.revert_view  s   //'79+=>?M	?  .
 "--IIOO

+d+
& 	 '') -- ( 
 ==?"LLNM>>V#&")..!.&%TZZ--778$**:J:J:U:U9VV]^!//,,. !NN7G<
G NPW 
 !1!1)!<%%gll3!1!1)!<$$&ll7<<0G,W__=>>U  	?gy|X^^D,W__=>>	?s   H 	I-AI("I-(I-c                    | j                  |t        |            }|t        	 |j                  |j                         |j                  dk7  r|j                  |j                  ||t        d| j                   j"                  j$                   d| j                   j"                  j&                   d|j                  j(                  f      | j+                  ||      d}t-        |d|      S t        |j                        }|j.                  j1                  d	      rU|j                  j2                  }|j5                         }|d
   d   r't7        |d      }| j                  |t9        d             t        |      S # t
        $ rR}| j                  |t        |      t        j                         t        t        |j                              cY d}~S d}~ww xY w)zDiscards the specified versionNr  r4  r   r  r6  r  z4djangocms_versioning/admin/discard_confirmation.htmlr  r0   last
changelistz!The last version has been deleted)r  r   r   r  rz   r8   r  r,   r   r  r#   rC   rt   r   r  r+   rT   rE  rF  rG  r   r  r$   r  r   rb   r  r<   r   )	r[   r\   r   r   r  r   version_url
ModelClassdeleteds	            rc   discard_viewzVersionAdmin.discard_view  s   //'79+=>?M	?!!',,/
 >>V#&")..!(&%TZZ--778$**:J:J:U:U9VV]^!//,,. !NN7G<
G OQX  'w7<<I& 22Jnn&Gqz&!+JE!!'1-P+QR$$9  	?gy|X^^D,W__=>>	?s   E< <	GAGGGc                    | j                  |t        |            }|'| j                  || j                  j                  |      S t        d      dt        d      di}t        |j                        }t        |fi |}t        j                  j                  |j                        j                  d      }|||| j                  ||      d}d|j                  v r| j                  |t        |j                  d               }|4| j                  || j                  j                  |j                  d         S t        |j                        }	|j                  |t        |	fi |d       t!        |d	|      S )
zCompares two versions
        CMS_TOOLBAR_URL__DISABLEr0   CMS_TOOLBAR_URL__PERSISTr   z-number)version_listv1v1_preview_url
return_url
compare_to)v2v2_preview_urlz'djangocms_versioning/admin/compare.html)r  r   r  rT   rE  r
   r?   rt   r   rF   rx   !filter_by_content_grouping_valuesr  r  r   r  r'   )
r[   r\   r   r*  persist_paramsr+  r)  r   r.  r/  s
             rc   compare_viewzVersionAdmin.compare_view2  sp    __Wgi&89:88))9  6767
 )4+NMnM HHJJ

(9
 	
 ),.."5	
 7;;&''++l2K*LMBz<<TZZ--w{{</H  "1!< *<^*^~*^  >
 	
rd   c                 j   t         j                  s
t               |j                  dk7  rt	        dgt        d            S | j                  |t        |            }|'| j                  || j                  j                  |      S |j                  t        k7  rt        |j                  j                  d      st        t!        t        d                  S t#        |       t%        j&                  |t        d             t)        ||j                         t+        |j,                        }t/        |      S )z)
        Unlock a locked version
        r  r  z'djangocms_versioning.delete_versionlockz5You do not have permission to remove the version lockzVersion unlocked)r1   r   r   r   r"   r   r  r   r  rT   rE  r   r3   rz   rD  r!   r,   rA   r   successr7   rC   rt   r#   )r[   r\   r   r   rK  s        rc   unlock_viewzVersionAdmin.unlock_viewb  s    
 !!)O >>V#)6(A6\4]^^ //'79+=>?88))96 6 ==E!M ||$$%NO(15l3m)noo 	G$!$6"78 	/wE w/}rd   c                     | j                   j                  dd       }|r	 t        t        |      d          |xs |rt        |j                        S d S # t        $ r d }Y *w xY w)Nr   r  )r   r   r*   r   r(   rC   rt   )r\   r   r  s      rc   r  zVersionAdmin.back_link  sd    ;;??640 *1-. S,W__=SdS    s   A A"!A"c           	         |j                   sE| j                  j                  }t        t	        d|j
                   d|j                   d            S |xs i }t        j                  | j                  j                        }	 |j                  t        |j                   j                  |j                                    }|t        |rddi|d<   |j#                  |t%        d      j'                  |      	       | j                  j                  j                  }||d
<   d|j
                   d|j                   ddg}t)        |      |d<   t*        	| Y  ||      }|rV|j.                  dk(  rG	 |j0                  d   j3                  |      j5                  d      j6                  |j0                  d<   |S |S # t        t         f$ r d}Y w xY w# t8        t:        f$ r Y |S w xY w)z*Handle grouper filtering on the changelistr4  r   _grouperNr   r   z"Displaying versions of "{grouper}")grouper)r9  r+  breadcrumb_optszadmin/djangocms_versioning//z/versioning_breadcrumbs.htmlz6admin/djangocms_versioning/versioning_breadcrumbs.htmlbreadcrumb_template   clr  )r   rT   rE  r#   r+   rF  rG  r2   rS   r`  get_grouper_with_fallbacksintr   r   r   	TypeErrorr   r  r   r  r&   rQ   changelist_viewstatus_codecontext_datarR   latestrt   r   r   )
r[   r\   r  r  r_   r9  r:  breadcrumb_templatesresponserb   s
            rc   rB  zVersionAdmin.changelist_view  s   {{::##D& 0$//1B(KL  &+"..tzz/G/GH		!<<GKKOOK$B$BCDG 04d|M*+  <=DDWDU !  #jj66<<O/>M+, .o.G.G-H"--..JLH$ 
 4CCW3XM/07*7MB x++s2))$/<<WE	*  %%&67 x[ :& 	G	V '1 s%   =F9 1AG 9GGG$#G$c                    | j                   j                  j                  | j                   j                  j                  f}t	        d| j
                  j                  | j                         dj                  |       t	        d| j
                  j                  | j                         dj                  |       t	        d| j
                  j                  | j                         dj                  |       t	        d| j
                  j                  | j                         d	j                  |       t	        d
| j
                  j                  | j                         dj                  |       t	        d| j
                  j                  | j                         dj                  |       t	        d| j
                  j                  | j                         dj                  |       t	        d| j
                  j                  | j                         dj                  |       t	        d| j
                  j                  | j                          dj                  |       g	t"        | I         z   S )Nzselect/z{}_{}_grouper)r,  z<path:object_id>/archive/z{}_{}_archivez<path:object_id>/publish/z{}_{}_publishz<path:object_id>/unpublish/z{}_{}_unpublishz<path:object_id>/edit-redirect/z{}_{}_edit_redirectz<path:object_id>/revert/z{}_{}_revertz<path:object_id>/compare/z{}_{}_comparez<path:object_id>/discard/z{}_{}_discardz<path:object_id>/unlock/z{}_{}_unlock)rT   rE  rF  rG  r)   r  
admin_viewr  r  r  r  r  r  r  r2  r%  r5  rQ   get_urls)r[   inforb   s     rc   rJ  zVersionAdmin.get_urls  s)   zz))4::+;+;+F+FF**4+A+AB+_++T2
 +**4+<+<=+_++T2
 ,**4+<+<=+_++T2
 -**4+>+>?-&--t4
 1**4+B+BC1*1148
 ***4+;+;<*^**D1
 +**4+<+<=+_++T2
 +**4+<+<=+_++T2
 ***4+;+;<*^**D1S.
\ G]. .	rd   c                      y)NFrP   r  s     rc   has_add_permissionzVersionAdmin.has_add_permission  s    rd   c                 *    |yt         |   ||      S )zDisable change view accessF)rQ   r   )r[   r\   r{   rb   s      rc   r   z"VersionAdmin.has_change_permission  s    ?w,Wc::rd   c                 .   |"t         j                  xr t        |   ||      S | j                  j
                  | j                  j                     }t        t         j                  t        |   ||      |j                  ||j                        f      S re   )
r1   ALLOW_DELETING_VERSIONSrQ   has_delete_permissionr  	_registryrT   r`  r   rt   )r[   r\   r{   content_adminrb   s       rc   rQ  z"VersionAdmin.has_delete_permission  s    ;//_EG4QRY[^4__11$**2J2JK((G)'37//E
  	rd   rZ  re   )7rf   rg   rh   ri   rV  r1   r  r   r   list_display_linksr   r  r   r  r   r  r   r  r  r1  r  r  r  rN  r  r  r  r  rW  r  rB  r~  r  r   r  r  r  r  r  r  r  r  r  r  r%  r2  r5  staticmethodr  rB  rJ  rM  r   rQ  rj   rk   s   @rc   r}  r}    s    "#45G R		 ))r
	L 7 7!
 U]]iL

	

 U]]hK

$
(
$&
P
&
&
$
4(
2 U\\()( U\\J?@8	8&:

X);V+IZ:&x>Z03?j$%L.
`$L 	T 	T<|0d; rd   r}  )yr   r  r  collectionsr   urllib.parser   cms.admin.utilsr   r   r   
cms.modelsr   	cms.utilsr	   cms.utils.confr
   cms.utils.helpersr   cms.utils.urlutilsr   r   django.confr   django.contribr   r   django.contrib.admin.actionsr   django.contrib.admin.optionsr   django.contrib.admin.utilsr   django.contrib.admin.views.mainr   "django.contrib.contenttypes.modelsr   django.core.exceptionsr   r   r   	django.dbr   django.db.modelsr   r   django.db.models.functionsr   r   django.formsr   django.httpr   r    r!   r"   django.shortcutsr#   r$   django.template.loaderr%   r&   django.template.responser'   django.urlsr(   r)   r*   r+   django.utils.encodingr,   django.utils.htmlr-   django.utils.safestringr.   django.utils.translationr/   r   r   r1   r2   	constantsr3   r4   r5   r6   emailsr7   
exceptionsr8   formsr9   r   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   
indicatorsrD   rE   rF   rG   rI   rp   rr   r   r   r   r  r  r\  r^  r{  
ModelAdminr}  rP   rd   rc   <module>ry     sU      # ! U U " / * / F   * 8 B . 6 : ] ]  / 2 +  . D 5 ; ; + ) - 6   O O : ' '   B  (Y Y<5; 5;pAj$6 AjH, ,^Q:'? Q:j1)<>^ 1Bt 	tn)<>W 0J
 0Jf.F)5+;+;GY Frd   