o xgU@sdZddlZddlZddlZddlZddlZddlZddlm Z ddl m Z ddl m Z ddlmZddlmZddlmZdd lmZdd lmZdd lmZmZd d lmZmZiae Zda dZ!dZ"edej#Z$edej%Z&edZ'eeddZ(GdddZ)Gdddej*Z+ddZ,ddZ-ddZ.dd Z/d!d"Z0d#d$Z1d%d&Z2d'd(Zd)d*Z3d+d,Z4d-d.Z5d/d0Z6d1d2Z7d3d4Z8ej9d5d6d7d8Z:e9d9d:Z;ej9d5d6dFdd?Z=dFd@dAZ>ej9d5d6dBdCZ?dDdEZ@dS)GzTranslation helper functions.N)Local)apps)settings) LANG_INFO)AppRegistryNotReady)setting_changed)receiver)_lazy_re_compile)SafeData mark_safe) to_language to_localeia ([A-Za-z]{1,8}(?:-[A-Za-z0-9]{1,8})*|\*) # "en", "en-au", "x-y-z", "es-419", "*" (?:\s*;\s*q=(0(?:\.\d{,3})?|1(?:\.0{,3})?))? # Optional "q=1.00", "q=0.8" (?:\s*,\s*|$) # Multiple accepts per header. z3^[a-z]{1,8}(?:-[a-z0-9]{1,8})*(?:@[a-z0-9]{1,20})?$z^/(\w+([@-]\w+)?)(/|$)cKs,|ddvrtttdSdS)zy Reset global state when LANGUAGES setting has been changed, as some languages should no longer be accepted. setting) LANGUAGES LANGUAGE_CODEN)check_for_language cache_clear get_languagesget_supported_language_variant)kwargsrE/usr/lib/python3/dist-packages/django/utils/translation/trans_real.py reset_cache7s  rc@s\eZdZdZdddZddZddZd d Zd d Zd dZ ddZ dddZ ddZ dS)TranslationCatalogz Simulate a dict for DjangoTranslation._catalog so as multiple catalogs with different plural equations are kept separate. NcCs:|r|jgnig|_|r|jg|_dSddg|_dS)NcS t|dkSNr intnrrrJ z-TranslationCatalog.__init__..)_catalogcopy _catalogsplural_plurals)selftransrrr__init__Hs"zTranslationCatalog.__init__c Cs4|jD]}z||WStyYqwt|N)r&KeyError)r)keycatrrr __getitem__Ls  zTranslationCatalog.__getitem__cCs||jd|<dSNr)r&)r)r.valuerrr __setitem__TszTranslationCatalog.__setitem__cstfdd|jDS)Nc3s|]}|vVqdSr,r).0r/r.rr Xsz2TranslationCatalog.__contains__..)anyr&)r)r.rr5r __contains__WszTranslationCatalog.__contains__cc |jD] }|EdHqdSr,)r&itemsr)r/rrrr:Z zTranslationCatalog.itemsccr9r,)r&keysr;rrrr=^r<zTranslationCatalog.keyscCs`t|j|jD]\}}|jj|jkr||jdSq|jd|j|jd|jdSr1) zipr&r(r'__code__updater$insertr%)r)r*r/r'rrrr@bs zTranslationCatalog.updatecCs2t}|jD]}|||}||ur|Sq|Sr,)objectr&get)r)r.defaultmissingr/resultrrrrCls  zTranslationCatalog.getcCs>t|j|jD]\}}||||f}|dur|Sqtr,)r>r&r(rCr-)r)msgidnumr/r'tmsgrrrr'ts zTranslationCatalog.pluralr,) __name__ __module__ __qualname____doc__r+r0r3r8r:r=r@rCr'rrrrrCs  rc@sreZdZdZdZdddZddZdd d Zd d Zd dZ ddZ dddZ ddZ ddZ ddZddZdS)DjangoTranslationa] Set up the GNUTranslations context with regard to output charset. This translation object will be constructed out of multiple GNUTranslations objects by merging their catalogs. It will construct an object for the requested language and add a fallback to the default language, if it's different from the requested language. djangoNcCstj||dur ||_||_t||_t||_d|_ dd|_ |jdkr7|dur3t dt d}||rI|D] }||}||q;n|||jtjkrh|jdkrh|j durhtdtj|||j durxt|_ dSdS)z8Create a GNUTranslations() using many locale directoriesNcSrrrr rrrr"r#z,DjangoTranslation.__init__..rOz.localedirs is ignored when domain is 'django'.z3No translation files found for default language %s.)gettext_moduleGNUTranslationsr+domain_DjangoTranslation__languager _DjangoTranslation__to_languager_DjangoTranslation__localer$r'warningswarnRuntimeWarning_init_translation_catalog_new_gnu_transmerge _add_installed_apps_translations_add_local_translationsrrOSError _add_fallbackr)r)languagerR localedirs localedir translationrrrr+s4            zDjangoTranslation.__init__cCs d|jS)NzrSr)rrr__repr__s zDjangoTranslation.__repr__TcCstj|j||jg|dS)z Return a mergeable gettext.GNUTranslations instance. A convenience wrapper. By default gettext uses 'fallback=False'. Using param `use_null_fallback` to avoid confusion with any other references to 'fallback'. )rRrb languagesfallback)rPrcrRrU)r)rbuse_null_fallbackrrrrZs z DjangoTranslation._new_gnu_transcCs<tjtjj}tjtj|d}| |}| |dS)z7Create a base catalog using global django translations.localeN) sysmodulesrrK__file__ospathjoindirnamerZr[)r) settingsfilerbrcrrrrYs z+DjangoTranslation._init_translation_catalogcCsjz ttt}Wn tytdw|D]}tj|jd}tj|r2| |}| |qdS)z+Merge translations from each installed app.zThe translation infrastructure cannot be initialized before the apps registry is ready. Check that you don't make non-lazy gettext calls at import time.rjN) reversedlistrget_app_configsrrnrorpexistsrZr[)r) app_configs app_configrbrcrrrr\s    z2DjangoTranslation._add_installed_apps_translationscCs(ttjD] }||}||qdS)z+Merge translations defined in LOCALE_PATHS.N)rsr LOCALE_PATHSrZr[)r)rbrcrrrr]s  z)DjangoTranslation._add_local_translationscCsR|jtjks |jdrdS|jdkrttj}n ttj|j|d}||dS)z=Set the GNUTranslations() fallback with the default language.enNrO)rRra)rSrr startswithrRrcrN add_fallback)r)radefault_translationrrrr_s   zDjangoTranslation._add_fallbackcCs`t|ddsdS|jdur|j|_|j|_t||_n|j||jr.||jdSdS)z,Merge another translation into this catalog.r$N) getattrr$r'_infor%rr@ _fallbackr|)r)otherrrrr[s     zDjangoTranslation.mergecC|jS)z Return the translation language.rdrerrrr`zDjangoTranslation.languagecCr)z%Return the translation language name.)rTrerrrr rzDjangoTranslation.to_languagecCsZz |j||}W|Sty,|jr|j|||YS|dkr'|}Y|S|}Y|Swr)r$r'r-rngettext)r)msgid1msgid2r!rIrrrrs zDjangoTranslation.ngettext)NN)Tr,)rJrKrLrMrRr+rfrZrYr\r]r_r[r`r rrrrrrN|s %   rNcCs|tvr t|t|<t|S)zE Return a translation object in the default 'django' domain. ) _translationsrNr`rrrrc s rccCs|sdSt|t_dS)z Fetch the translation object for a given language and install it as the current translation object for the current thread. N)rc_activer2rrrractivatesrcCsttdr t`dSdS)zz Uninstall the active translation object so that further _() calls resolve to the default translation object. r2N)hasattrrr2rrrr deactivate s rcCstt_ddtj_dS)z Make the active translation object a NullTranslations() instance. This is useful when we want delayed translations to appear as the original string for some reason. cWsdSr,r)argsrrrr"0sz deactivate_all..N)rPNullTranslationsrr2r rrrrdeactivate_all)s rcCs<ttdd}|durz|WStyYtjSwtjS)z'Return the currently selected language.r2N)r~rr AttributeErrorrrtrrr get_language3s   rcCs,t}|dur dStdd}|tjvS)zw Return selected language's BiDi layout. * False = left-to-right layout * True = right-to-left layout NF-r)rsplitrLANGUAGES_BIDI)lang base_langrrrget_language_bidi?s  rcCs.ttdd}|dur |StdurttjatS)z Return the current active catalog for further processing. This can be used if you need to modify the catalog or want to access the whole message catalog instead of just translating one string. r2Nr~r_defaultrcrrrrrrcatalogNs  rcCs`|dddd}|rtpttjattdt}||}nt|d}t |t r.t |S|S)z Translate the 'message' string. It uses the current thread to find the translation object to use. If no current translation is activated, the message will be run through the default translation object. z   r2) replacerrcrrr~rgettexttype isinstancer r )message eol_messagetranslation_objectrFrrrr^s    rcCs<d|t|f}t|}t|vr|}|St|trt|}|SNz%s%s%s)CONTEXT_SEPARATORrrr r )contextr msg_with_ctxtrFrrrpgettextxs rcCs|S)z Mark strings for translation but don't translate them now. This can be used to store strings in global variables that should stay in the base language (because they might be used externally) and will be translated later. r)rrrr gettext_noopsrcCsJttdd}|durt|||||Stdurttjatt||||S)Nr2r)singularr'numbertranslation_functionrrrr do_ntranslates  rcCst|||dS)zg Return a string of the translation of either the singular or plural, based on the number. r)r)rr'rrrrrsrcCs>d|t|fd|t|f|f}t|}t|vrt|||}|Sr)rr)rrr'rmsgs_with_ctxtrFrrr npgettexts   rcCshtjtjtjtjjd}g}t D]}tj|jd}tj |r+| |q|gtj |S)zB Return a list of paths to user-provides languages files. rj)rnrorprqrkrlrrKrmrrurvappendry) globalpath app_pathsrx locale_pathrrrall_locale_pathss   ri)maxsizecs.dus ts dStfddtDS)a Check whether there is a global language file for the given language code. This is used to decide whether a user-provided language is available. lru_cache should have a maxsize to prevent from memory exhaustion attacks, as the provided language codes are taken from the HTTP request. See also . NFc3s(|]}td|tgduVqdS)rON)rPfindr)r4ro lang_coderrr6s  z%check_for_language..)language_code_researchr7rrrrrrs   rcCs ttjS)zN Cache of settings.LANGUAGES in a dictionary for easy lookups by key. )dictrrrrrrrs rFcCs|rjt|tkr |s|ddt}dkr|d|}ntd|g}z |t|dWn ty7Ynw|dd}||t }|D]}||vrWt |rW|SqI|sj|D] }| |dri|Sq\t |)a} Return the language code that's listed in supported languages, possibly selecting a more generic variant. Raise LookupError if nothing is found. If `strict` is False (the default), look for a country-specific variant when neither the language code nor its generic variant is found. The language code is truncated to a maximum length to avoid potential denial of service attacks. lru_cache should have a maxsize to prevent from memory exhaustion attacks, as the provided language codes are taken from the HTTP request. See also . rrNz/'lang_code' exceeds the maximum accepted lengthrh) lenLANGUAGE_CODE_MAX_LENGTHrfind ValueErrorextendrr-rrrrr{ LookupError)rstrictindexpossible_lang_codesgeneric_lang_codesupported_lang_codescodesupported_coderrrrs4   rcCs>t|}|s dS|d}zt||dWStyYdSw)z Return the language code if there's a valid language code found in `path`. If `strict` is False (the default), look for a country-specific variant when neither the language code nor its generic variant is found. Nr )r)language_code_prefix_rematchrr)ror regex_matchrrrrget_language_from_paths  rc Cs|r t|j}|dur |S|jtj}|dur#|tvr#t|r#|Szt|WSt y1Ynw|j dd}t |D] \}}|dkrGnt |sMq=zt|WSt y]Yq=wzttjWSt yptjYSw)a Analyze the request to find what language the user wants the system to show. Only languages listed in settings.LANGUAGES are taken into account. If the user requests a sublanguage where we have a main language, we send out the main language. If check_path is True, the URL path prefix will be checked for a language code, otherwise this is skipped for backwards compatibility. NHTTP_ACCEPT_LANGUAGEr*)r path_infoCOOKIESrCrLANGUAGE_COOKIE_NAMErrrrMETAparse_accept_lang_headerrrr)request check_pathraccept accept_langunusedrrrget_language_from_requests8        rcCsg}t|}|drdStdt|ddD]"}|||d\}}}|r+dS|r2t|}nd}|||fq|jddd d t|S) z Parse the lang_string, which is the body of an HTTP Accept-Language header, and return a tuple of (lang, q-value), ordered by 'q' values. Return an empty tuple if there are any format errors in lang_string. rrr g?cSs|dSrr)krrrr"Wsz+_parse_accept_lang_header..T)r.reverse) accept_language_rerlowerrangerfloatrsorttuple) lang_stringrFpiecesifirstrpriorityrrr_parse_accept_lang_headerBs rcCs>t|tkr t|S|ddt}|dkrt|d|SdS)a Parse the value of the Accept-Language header up to a maximum length. The value of the header is truncated to a maximum length to avoid potential denial of service and memory exhaustion attacks. Excessive memory could be used if the raw value is very large as it would be cached due to the use of `functools.lru_cache()` to avoid repetitive parsing of common header values. ,rNr)rrrr)rrrrrr[s r)F)ArM functoolsrrPrnrerkrV asgiref.localr django.appsr django.confrdjango.conf.localerdjango.core.exceptionsrdjango.core.signalsrdjango.dispatchrdjango.utils.regex_helperr django.utils.safestringr r rr rrrrrrVERBOSEr IGNORECASErrrrrQrNrcrrrrrrrrrrrr lru_cacherrrrrrrrrrrsx          9              0  +