U
    {h?                     @   sB  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mZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZmZ d dlm Z  dd Z!G dd dej"Z#G dd dej$Z%G dd dej$Z&dd Z'G dd de
j(Z)G dd de&Z*d#dd Z+eed!d" Z,dS )$    N)Dict)apps)settings)checks)
migrationsmodelstransaction)pre_save)receiver)translation)	force_str)gettext_lazy)ParentalKey)CopyForTranslationAction)get_content_languages&get_supported_content_language_variant)pre_validate_deletec                 C   s   t | tjr| jS | S d S N)
isinstancer   Modelpk)obj r   [/var/www/dating/data/www/fatepal.com/env/lib/python3.8/site-packages/wagtail/models/i18n.pyr      s    r   c                   @   s   e Zd Zdd ZdS )LocaleManagerc                 C   s   | j t|dS )z5
        Gets a Locale from a language code.
        language_code)getr   )selfr   r   r   r   get_for_language   s    zLocaleManager.get_for_languageN)__name__
__module____qualname__r   r   r   r   r   r      s   r   c                       s   e Zd ZejdddZe Ze Z	G dd dZ
edd Zedd	 Zej fd
dZdd ZedddZdd Zeeef dddZedd Zedd Zedd Zedd ZeedddZeeddd Zeedd!d"Z  Z S )#Localed   T)
max_lengthuniquec                   @   s   e Zd ZdgZdS )zLocale.Metar   N)r    r!   r"   Zorderingr   r   r   r   Meta4   s   r'   c                 C   s   | j tjS )zV
        Returns the default Locale based on the site's LANGUAGE_CODE setting
        )objectsr   r   LANGUAGE_CODEclsr   r   r   get_default9   s    zLocale.get_defaultc              	   C   s:   z| j t W S  | jtfk
r4   |   Y S X dS )zd
        Returns the Locale that corresponds to the currently activated language in Django.
        N)r(   r   r   get_languageDoesNotExistLookupErrorr,   r*   r   r   r   
get_active@   s    zLocale.get_activec                    s   t jt| d t j||S )N)senderinstance)r   sendr#   superdelete)r   argskwargs	__class__r   r   r5   J   s    zLocale.deletec                 C   s   | j t kS r   )r   r   r   r   r   r   language_code_is_validS   s    zLocale.language_code_is_valid)returnc                 C   sH   zt  | j W S  tk
r"   Y nX z| jW S  tk
r@   Y nX | jS r   )r   r   KeyErrorlanguage_namer:   r   r   r   get_display_nameV   s    zLocale.get_display_namec                 C   s   t |  S r   )r   r?   r:   r   r   r   __str__b   s    zLocale.__str__c                 C   s   t | jS r   r   Zget_language_infor   r:   r   r   r   _get_language_infoe   s    zLocale._get_language_infoc                 C   s   t | jS r   rA   r:   r   r   r   language_infoh   s    zLocale.language_infoc                 C   s
   | j d S )aQ  
        Uses data from ``django.conf.locale`` to return the language name in
        English. For example, if the object's ``language_code`` were ``"fr"``,
        the return value would be ``"French"``.

        Raises ``KeyError`` if ``django.conf.locale`` has no information
        for the object's ``language_code`` value.
        namerC   r:   r   r   r   r>   l   s    
zLocale.language_namec                 C   s
   | j d S )u`  
        Uses data from ``django.conf.locale`` to return the language name in
        the language itself. For example, if the ``language_code`` were
        ``"fr"`` (French), the return value would be ``"français"``.

        Raises ``KeyError`` if ``django.conf.locale`` has no information
        for the object's ``language_code`` value.
        Z
name_localrE   r:   r   r   r   language_name_localx   s    
zLocale.language_name_localc                 C   s   t | jS )a  
        Uses data from ``django.conf.locale`` to return the language name in
        the currently active language. For example, if ``language_code`` were
        ``"fr"`` (French), and the active language were ``"da"`` (Danish), the
        return value would be ``"Fransk"``.

        Raises ``KeyError`` if ``django.conf.locale`` has no information
        for the object's ``language_code`` value.

        )r   gettextr>   r:   r   r   r   language_name_localized   s    zLocale.language_name_localizedc                 C   s   | j tjkS )zV
        Returns a boolean indicating whether the language is bi-directional.
        )r   r   ZLANGUAGES_BIDIr:   r   r   r   is_bidi   s    zLocale.is_bidic                 C   s.   z| j ttjkW S  tk
r(   Y dS X dS )zY
        Returns a boolean indicating whether this object is the default locale.
        FN)r   r   r   r)   r/   r:   r   r   r   
is_default   s    zLocale.is_defaultc                 C   s4   z| j tt kW S  tk
r.   | j Y S X dS )zb
        Returns a boolean indicating whether this object is the currently active locale.
        N)r   r   r   r-   r/   rJ   r:   r   r   r   	is_active   s    zLocale.is_active)!r    r!   r"   r   Z	CharFieldr   r   r(   ManagerZall_objectsr'   classmethodr,   r0   r   Zatomicr5   r;   strr?   r@   r   rB   propertyrC   r>   rF   rH   boolrI   rJ   rK   __classcell__r   r   r8   r   r#   (   s8   

	



r#   c                       s   e Zd ZejejddZeje	ej
ddeddZde_G dd dZe fd	d
Zedd Zedd ZdddZdd Zdd Zdd ZdddZdd Zedd Z  ZS ) TranslatableMixinF)defaulteditable+locale)	on_deleterelated_namerT   Zverbose_nameTc                   @   s   e Zd ZdZdgZdS )zTranslatableMixin.MetaTtranslation_keyrV   N)r    r!   r"   abstractunique_togetherr   r   r   r   r'      s   r'   c              	      s   t  jf |}|  | k}|s"|S d t fdd| jjD } | jjk}|s|s|tj	d| jj
 f d | jj| jj| jf | dd |r|r|tj	d| jj
 f d	| dd |S )
NrY   c                 3   s,   | ]$}t |tjo"t|jt kV  qd S r   )r   r   ZUniqueConstraintsetfields).0
constraintZunique_constraint_fieldsr   r   	<genexpr>   s   z*TranslatableMixin.check.<locals>.<genexpr>z4%s is missing a UniqueConstraint for the fields: %s.zjAdd models.UniqueConstraint(fields=%s, name='unique_translation_key_locale_%s_%s') to %s.Meta.constraints.zwagtailcore.E003)hintr   idzE%s should not have both UniqueConstraint and unique_together for: %s.z4Remove unique_together in favor of UniqueConstraint.)r4   checkget_translation_modelany_metaconstraintsr\   appendr   ErrorlabelZ	app_labelZ
model_namer    )r+   r7   errorsZis_translation_modelZhas_unique_constraintZhas_unique_togetherr8   ra   r   re      sL    
	

zTranslatableMixin.checkc                 C   s*   ddl m} | j}t| |r&|js&| S |S )a3  
        Finds the translation in the current active language.

        If there is no translation in the active language, self is returned.

        Note: This will not return the translation if it is in draft.
        If you want to include drafts, use the ``.localized_draft`` attribute instead.
        r   )DraftStateMixin)Zwagtail.modelsrn   localized_draftr   live)r   rn   	localizedr   r   r   rq      s
    
zTranslatableMixin.localizedc              	   C   sZ   t tdds| S zt }W n ttjfk
r:   |  Y S X |j| jkrL| S | |pX| S )a  
        Finds the translation in the current active language.

        If there is no translation in the active language, self is returned.

        Note: This will return translations that are in draft. If you want to exclude
        these, use the ``.localized`` attribute.
        ZWAGTAIL_I18N_ENABLEDF)	getattrr   r#   r0   r/   r.   rd   	locale_idget_translation_or_noner   rV   r   r   r   ro   	  s    

z!TranslatableMixin.localized_draftc                 C   s,   | j jj| jd}|dkr(|j| jd}|S )zR
        Returns a queryset containing the translations of this instance.
        )rZ   Frd   )r9   r(   filterrZ   excluderd   )r   	inclusiveZtranslationsr   r   r   get_translations   s    z"TranslatableMixin.get_translationsc                 C   s   | j ddjt|dS )z
        Finds the translation in the specified locale.

        If there is no translation in that locale, this raises a ``model.DoesNotExist`` exception.
        Try   rs   )rz   r   r   ru   r   r   r   get_translation-  s    z!TranslatableMixin.get_translationc                 C   s,   z|  |W S  | jjk
r&   Y dS X dS )z
        Finds the translation in the specified locale.

        If there is no translation in that locale, this returns None.
        N)r}   r9   r.   ru   r   r   r   rt   5  s    z)TranslatableMixin.get_translation_or_nonec                 C   s   | j ddjt|d S )zO
        Returns True if a translation exists in the specified locale.
        Tr{   r|   )rz   rw   r   existsru   r   r   r   has_translation@  s    z!TranslatableMixin.has_translationNc                 C   s   t | ||d S )z~
        Creates a copy of this instance with the specified locale.

        Note that the copy is initially unsaved.
        )exclude_fields)r   execute)r   rV   r   r   r   r   copy_for_translationH  s
    z&TranslatableMixin.copy_for_translationc                 C   sN   dd | j  D }|rF|d | }|d jj dj|djS t	
 S )z}
        Finds the default locale to use for this object.

        This will be called just before the initial save.
        c                 S   s&   g | ]}t |trt|jtr|qS r   )r   r   
issubclassrelated_modelrR   )r_   fieldr   r   r   
<listcomp>\  s   
z8TranslatableMixin.get_default_locale.<locals>.<listcomp>r   rV   rv   )rh   Z
get_fieldsZvalue_from_objectr   r(   deferZselect_relatedr   rV   r#   r,   )r   Zparental_keysZ	parent_idr   r   r   get_default_localeT  s    z$TranslatableMixin.get_default_localec                 C   s   | j djS )aX  
        Returns this model's "Translation model".

        The "Translation model" is the model that has the ``locale`` and
        ``translation_key`` fields.
        Typically this would be the current model, but it may be a
        super-class if multi-table inheritance is in use (as is the case
        for ``wagtailcore.Page``).
        rV   )rh   	get_fieldmodelr*   r   r   r   rf   o  s    z'TranslatableMixin.get_translation_model)F)N)r    r!   r"   r   	UUIDFielduuiduuid4rZ   
ForeignKeyr#   PROTECT_rV   Zwagtail_reference_index_ignorer'   rM   re   rO   rq   ro   rz   r}   rt   r   r   r   rf   rQ   r   r   r8   r   rR      s0   5



rR   c                 C   s@   | j jdd  D ]$}t |_||_|jddgd qdS )a(  
    This function populates the "translation_key", and "locale" fields on model instances that were created
    before wagtail-localize was added to the site.

    This can be called from a data migration, or instead you could use the "bootstrap_translatable_models"
    management command.
    T)Ztranslation_key__isnullrZ   rV   )Zupdate_fieldsN)	r(   rw   r   iteratorr   r   rZ   rV   save)r   rV   r2   r   r   r   bootstrap_translatable_model}  s
    	
r   c                       s   e Zd Zd fdd	Z  ZS )BootstrapTranslatableModelNc                    s:    d krt tj  fdd}dd }t || d S )Nc                    s0   |  }|  d}|jj d}t|| d S )Nzwagtailcore.Localer   )Z	get_modelr(   r   r   )r   schema_editorr   r#   rV   r   model_stringr   r   forwards  s    

z5BootstrapTranslatableModel.__init__.<locals>.forwardsc                 S   s   d S r   r   )r   r   r   r   r   	backwards  s    z6BootstrapTranslatableModel.__init__.<locals>.backwards)r   r   r)   r4   __init__)r   r   r   r   r   r8   r   r   r     s    z#BootstrapTranslatableModel.__init__)N)r    r!   r"   r   rQ   r   r   r8   r   r     s   r   c                       sV   e Zd ZdZejdddZejeej	ddddZ
e fddZG d	d
 d
Z  ZS )BootstrapTranslatableMixina  
    A version of TranslatableMixin without uniqueness constraints.

    This is to make it easy to transition existing models to being translatable.

    The process is as follows:
     - Add BootstrapTranslatableMixin to the model
     - Run makemigrations
     - Create a data migration for each app, then use the BootstrapTranslatableModel operation in
       wagtail.models on each model in that app
     - Change BootstrapTranslatableMixin to TranslatableMixin
     - Run makemigrations again
     - Migrate!
    TF)nullrT   rU   )rW   r   rX   rT   c                    s   t t| jf |S r   )r4   rR   re   )r+   r7   r8   r   r   re     s    z BootstrapTranslatableMixin.checkc                   @   s   e Zd ZdZdS )zBootstrapTranslatableMixin.MetaTN)r    r!   r"   r[   r   r   r   r   r'     s   r'   )r    r!   r"   __doc__r   r   rZ   r   r#   r   rV   rM   re   r'   rQ   r   r   r8   r   r     s       r   Fc                    sN   dd t  D }| dkrJt  |D ]} |  q$ fdd|D }|S )z
    Returns a list of all concrete models that inherit from TranslatableMixin.
    By default, this only includes models that are direct children of TranslatableMixin,
    to get all models, set the include_subclasses attribute to True.
    c                 S   s"   g | ]}t |tr|jjs|qS r   )r   rR   rh   r[   r_   r   r   r   r   r     s   
 z+get_translatable_models.<locals>.<listcomp>Fc                    s   g | ]}| kr|qS r   r   r   Zroot_translatable_modelsr   r   r     s     )r   Z
get_modelsr]   addrf   )Zinclude_subclassesZtranslatable_modelsr   r   r   r   get_translatable_models  s    
r   c                 K   s@   t |tsd S |jd k	rd S |d r2t |_d S | |_d S )Nraw)r   rR   rs   r#   r,   rV   r   )r1   r2   r7   r   r   r   set_locale_on_new_instance  s    


r   )F)-r   typingr   Zdjango.appsr   Zdjango.confr   Zdjango.corer   Z	django.dbr   r   r   Zdjango.db.models.signalsr	   Zdjango.dispatchr
   Zdjango.utilsr   Zdjango.utils.encodingr   Zdjango.utils.translationr   r   Zmodelcluster.fieldsr   Z$wagtail.actions.copy_for_translationr   Zwagtail.coreutilsr   r   Zwagtail.signalsr   r   rL   r   r   r#   rR   r   Z	RunPythonr   r   r   r   r   r   r   r   <module>   s4   
  L
