o
    h?                     @   s6  d dl Z d dlmZ d dlmZ d dlmZ d dlmZm	Z	m
Z
 d dlmZ 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)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 N)
isinstancer   Modelpk)obj r   S/var/www/html/ndineBlogger/venv/lib/python3.10/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defddZdd Zdeeef fddZedd Zedd Zedd Zedd ZedefddZedefdd Zedef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!   orderingr   r   r   r   Meta3   s    r'   c                 C   s   | j tjS )z[
        Returns the default Locale based on the site's ``LANGUAGE_CODE`` setting.
        )objectsr   r   LANGUAGE_CODEclsr   r   r   get_default8   s   zLocale.get_defaultc              	   C   s4   z	| j t W S  | jtfy   |   Y S w )zd
        Returns the Locale that corresponds to the currently activated language in Django.
        )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|i |S )N)senderinstance)r   sendr"   superdelete)r   argskwargs	__class__r   r   r5   I   s   zLocale.deletec                 C   s   | j t v S r   )r   r   r   r   r   r   language_code_is_validR      zLocale.language_code_is_validreturnc                 C   sB   zt  | j W S  ty   Y nw z| jW S  ty    Y | jS w r   )r   r   KeyErrorlanguage_namer:   r   r   r   get_display_nameU   s   zLocale.get_display_namec                 C   s   t |  S r   )r   r@   r:   r   r   r   __str__a   r<   zLocale.__str__c                 C      t | jS r   r
   get_language_infor   r:   r   r   r   _get_language_infod   r<   zLocale._get_language_infoc                 C   rB   r   rC   r:   r   r   r   language_infog   s   zLocale.language_infoc                 C   
   | 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rF   r:   r   r   r   r?   k      

zLocale.language_namec                 C   rG   )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.
        
name_localrI   r:   r   r   r   language_name_localw   rJ   zLocale.language_name_localc                 C   rB   )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v S )zV
        Returns a boolean indicating whether the language is bi-directional.
        )r   r   LANGUAGES_BIDIr:   r   r   r   is_bidi   s   zLocale.is_bidic                 C   s(   z	| j ttjkW S  ty   Y dS w )zY
        Returns a boolean indicating whether this object is the default locale.
        F)r   r   r   r)   r/   r:   r   r   r   
is_default   s   zLocale.is_defaultc                 C   s.   z
| j tt kW S  ty   | j Y S w )zb
        Returns a boolean indicating whether this object is the currently active locale.
        )r   r   r
   r-   r/   rQ   r:   r   r   r   	is_active   s   
zLocale.is_active)!r   r    r!   r   	CharFieldr   r   r(   Managerall_objectsr'   classmethodr,   r0   r   atomicr5   r;   strr@   rA   dictrE   propertyrF   r?   rL   rN   boolrP   rQ   rR   __classcell__r   r   r8   r   r"   '   s:    

	



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_namer_   verbose_nameTc                   @   s   e Zd ZdZdgZdS )zTranslatableMixin.MetaTtranslation_keyra   N)r   r    r!   abstractunique_togetherr   r   r   r   r'      s    
r'   c              	      s   t  jd
i |}|  | u }|s|S d t fdd| jjD } | jjv }|sI|sI|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 )Nre   c                 3   s.    | ]}t |tjot|jt kV  qd S r   )r   r   UniqueConstraintsetfields).0
constraint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.r   )r4   checkget_translation_modelany_metaconstraintsrh   appendr   Errorlabel	app_label
model_namer   )r+   r7   errorsis_translation_modelhas_unique_constrainthas_unique_togetherr8   rn   r   rs      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)wagtail.modelsr   localized_draftr   live)r   r   	localizedr   r   r   r      s
   
zTranslatableMixin.localizedc              	   C   sX   t tdds| S zt }W n ttjfy   |  Y S w |j| jkr%| S | |p+| 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.
        WAGTAIL_I18N_ENABLEDF)	getattrr   r"   r0   r/   r.   rr   	locale_idget_translation_or_noner   ra   r   r   r   r     s   
z!TranslatableMixin.localized_draftc                 C   s,   | j jj| jd}|du r|j| jd}|S )zR
        Returns a queryset containing the translations of this instance.
        )rf   Frr   )r9   r(   filterrf   excluderr   )r   	inclusive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r   r   )r   r   r   r   r   r   r   get_translation,  s   z!TranslatableMixin.get_translationc                 C   s&   z|  |W S  | jjy   Y dS w )z
        Finds the translation in the specified locale.

        If there is no translation in that locale, this returns ``None``.
        N)r   r9   r.   r   r   r   r   r   4  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   )r   r   r   existsr   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   ra   r   r   r   r   copy_for_translationG  s   z&TranslatableMixin.copy_for_translationc                 C   sN   dd | j  D }|r#|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_modelr]   )rl   fieldr   r   r   
<listcomp>[  s    
z8TranslatableMixin.get_default_locale.<locals>.<listcomp>r   ra   r   )rv   
get_fieldsvalue_from_objectr   r(   deferselect_relatedr   ra   r"   r,   )r   parental_keys	parent_idr   r   r   get_default_localeS  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``).
        ra   )rv   	get_fieldmodelr*   r   r   r   rt   n  s   z'TranslatableMixin.get_translation_modelFr   )r   r    r!   r   	UUIDFielduuiduuid4rf   
ForeignKeyr"   PROTECT_ra   wagtail_reference_index_ignorer'   rV   rs   rZ   r   r   r   r   r   r   r   r   rt   r\   r   r   r8   r   r]      s2    5



r]   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)translation_key__isnullrf   ra   )update_fieldsN)	r(   r   r   iteratorr   r   rf   ra   save)r   ra   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 u r	t tj  fdd}dd }t || d S )Nc                    s0   |  }|  d}|jj d}t|| d S )Nzwagtailcore.Localer   )	get_modelr(   r   r   )r   schema_editorr   r"   ra   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__r   )r   r    r!   r   r\   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)nullr_   r`   )rb   r   rc   r_   c                    s   t t| jdi |S )Nr   )r4   r]   rs   )r+   r7   r8   r   r   rs     s   z BootstrapTranslatableMixin.checkc                   @   s   e Zd ZdZdS )zBootstrapTranslatableMixin.MetaTN)r   r    r!   rg   r   r   r   r   r'     s    r'   )r   r    r!   __doc__r   r   rf   r   r"   r   ra   rV   rs   r'   r\   r   r   r8   r   r     s    r   Fc                    sN   dd t  D }| du r%t  |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   r]   rv   rg   rl   r   r   r   r   r     s    z+get_translatable_models.<locals>.<listcomp>Fc                    s   g | ]}| v r|qS r   r   r   root_translatable_modelsr   r   r     s    )r   
get_modelsrj   addrt   )include_subclassestranslatable_modelsr   r   r   r   get_translatable_models  s   
r   c                 K   s@   t |tsd S |jd urd S |d rt |_d S | |_d S )Nraw)r   r]   r   r"   r,   ra   r   )r1   r2   r7   r   r   r   set_locale_on_new_instance  s   


r   r   )+r   django.appsr   django.confr   django.corer   	django.dbr   r   r   django.db.models.signalsr   django.dispatchr	   django.utilsr
   django.utils.encodingr   django.utils.translationr   r   modelcluster.fieldsr   $wagtail.actions.copy_for_translationr   wagtail.coreutilsr   r   wagtail.signalsr   r   rT   r   r   r"   r]   r   	RunPythonr   r   r   r   r   r   r   r   <module>   s4    
  L
