o k`=@sbdZddlZddlZddlmZmZddlmZddlm Z gdZ ddZ d d Z d d Z d dZZe ZddZddZedZddZddZddZddZddZddZd d!Zdd"lmZGd#d$d$eZd%Zzgdd&l m!Z!m"Z"dd'l#m$Z$m%Z%Gd(d)d)e&Z'e'Z(d*d!Ze(jZeZ)e(j*Z*e(j+Z+e(j,Z,e(j-Z-e-Z.e(j/Z/e(j0Z0e0Z1e(j2Z2d+dZdJd,d-Z3d.d/Z4d0d1Z5dJd2d3Z6d4d5Z7d6d7Z8d8d9Z9d:d;Z:dd/Z4d?d1Z5dJd@d3Z6dAd5Z7dBd7Z8dCd9Z9dDd;Z:YnwdEdFZdS)Kz,Utilities for text translation with gettext.N) ThreadLocal threading)tag)cleandoc)gettextngettext gettext_noop ngettext_nooptgettext tgettext_noop tngettexttngettext_noopcCs(|rz||WStyY|Sw|SN)KeyErrorstringkwargsr7/usr/lib/python3/dist-packages/trac/util/translation.pysafefmts  rcKs t||Sr)rrrrrr% rcKt|fi|Sr)rdomainrrrrr dgettext_noop(rcCs|Srr)rrrr+rcK&|dkr|n|}|d|t||SNnum) setdefaultrsingularpluralr!rrrrrr .  r cKt|||fi|Sr)r rr$r%r!rrrrdngettext_noop3r)z#%\((\w+)\)(?:s|[\d]*d|\d*.?\d*[fg])cCs<t|}tdt|dD] }|||d||<q t|S)Nr z???) _param_resplitrangelengetr)transr trans_eltsirrr _tag_kwargs7s r4cKs|rt||S|Sr)r4rrrrr =r cKrr)r rrrrdtgettext_noop@rr6cKrr)r"r4r#rrrr Cr&r cKr'r)r r(rrrdtngettext_noopHr*r7cCdSrrrenv_path locale_dirrrr add_domainKr<c sH|r t|dts |d}ttttttttddd fdd|DS)NrcSr8rr)r:r;rrrrZrz"domain_functions..) r_N_rr tag_r tagn_r<csg|]}|qSrr.0s _functionsrr \$domain_functions..) isinstancestr s_gettextr_noopr r r rsymbolsrrErdomain_functionsNs rP)NullTranslationsc@s eZdZdZddZddZdS)NullTranslationsBabelz9NullTranslations doesn't have the domain related methods.cCs ||Sr)r)selfrrrrr dugettextdrzNullTranslationsBabel.dugettextcCs||||Sr)r)rSrr$r%r!rrr dungettextgz NullTranslationsBabel.dungettextN)__name__ __module__ __qualname____doc__rTrUrrrrrRas rRF)LocaleUnknownLocaleError) LazyProxy Translationsc@seZdZdZddZddZd'ddZd'd d Zd d Zd dZ e ddZ e ddZ ddZ ddZddZddZddZddZdd Zd!d"Zd#d$Zd%d&ZdS)(TranslationsProxyaDelegate Translations calls to the currently active Translations. If there's none, wrap those calls in LazyProxy objects. Activation is controlled by `activate` and `deactivate` methods. However, if retrieving the locale information is costly, it's also possible to enable activation on demand only, by providing a callable to `make_activable`. cCs0tddd|_t|_i|_t|_d|_dS)N)args translationsF) r_currentrR_null_translations_plugin_domainsrRLock_plugin_domains_lock_activate_failedrSrrr__init__{s   zTranslationsProxy.__init__cCsB|j|j|i}|||<WddS1swYdSr)rfrdr")rSrr: locales_dirdomainsrrrr<s "zTranslationsProxy.add_domainNcCs||f|j_dSr)rbr`rS get_localer:rrrmake_activablerz TranslationsProxy.make_activablec Csztdd}Wn tyd|_YdSwt||pd}t|ts'|j}nA||t||p0dd|rh|j |j |i}t | }Wdn1sQwY|D]\}}||t|||qX||j_d|_dS)NtraclocaleTen_UStraciniF) pkg_resourcesresource_filename Exceptionrgr^loadrJrc_addrfrdr0listitemsrbra)rSrpr:r;trkrdirnamerrractivates.    zTranslationsProxy.activatecCsd|j_|jjd}|j_|Sr)rbr`rarSrzrrr deactivateszTranslationsProxy.deactivatecCs|r||j_dSdSr)rbrar}rrr reactivates zTranslationsProxy.reactivatecCs|jjp|jSr)rbrarcrhrrractiveszTranslationsProxy.activecCs@|jjdur|jj\}}d|j_||||jjdup|jSr)rbr`r|rargrlrrrisactives   zTranslationsProxy.isactivecCst|tr ||dSdSr)rJr^add)rSrzrarrrrws zTranslationsProxy._addcCs t|j|Sr)getattrr)rSnamerrr __getattr__s zTranslationsProxy.__getattr__c $fdd}jst|S|S)NcstjSr)rrrrrrSrrr_gettextr5z+TranslationsProxy.gettext.._gettextrr])rSrrrrrrrszTranslationsProxy.gettextc &fdd}jst|S|S)NcstjSr)rrrTrrrrSrrr _dgettextr*z-TranslationsProxy.dgettext.._dgettextr)rSrrrrrrrdgettextszTranslationsProxy.dgettextc <dfdd}jst|S|S)Nr!cj}t|Sr)rrrr1rr!r%rSr$rr _ngettext z-TranslationsProxy.ngettext.._ngettextcopyr"rr])rSr$r%r!rrrrrr  zTranslationsProxy.ngettextc s>dfdd}jst|S|S)Nr!csj}t|Sr)rrUrrrrr!r%rSr$rr _dngettexts z/TranslationsProxy.dngettext.._dngettextr)rSrr$r%r!rrrrr dngettexts  zTranslationsProxy.dngettextc r)Ncsj}r t|S|Sr)rrr4rrrr _tgettexts z-TranslationsProxy.tgettext.._tgettextr)rSrrrrrrr szTranslationsProxy.tgettextc r)Ncs j}rt|S|Sr)rrTr4rrrr _dtgettextsz/TranslationsProxy.dtgettext.._dtgettextr)rSrrrrrrr dtgettextszTranslationsProxy.dtgettextc r)Nr!crr)rrr4rrrr _tngettextrz/TranslationsProxy.tngettext.._tngettextr)rSr$r%r!rrrrrr rzTranslationsProxy.tngettextc s2fdd}jst|S|S)Ncs8j}d|vrjdrt|S|S)Nz%(num))r!)rrUupdater4rrrr _dtngettexts z1TranslationsProxy.dtngettext.._dtngettext)rrr])rSrr$r%r!rrrrr dtngettexts zTranslationsProxy.dtngettextr)rWrXrYrZrir<rnr|r~rpropertyrrrwrrrrrr rr rrrrrr_ps,         r_c s^|r t|dts |d}ttjtjtjtjtjtjtjdfddfdd|DS)aqPrepare partial instantiations of domain translation functions. :param domain: domain used for partial instantiation :param symbols: remaining parameters are the name of commonly used translation function which will be bound to the domain Note: the symbols can also be given as an iterable in the 2nd argument. r)rr>rr r@r rAr<csdkrtSfddS)Nr?csg|Ri|Srr)r`kw)rFrsymbolrrr'sz6domain_functions..wrapdomain..)rMr)rFrrr wrapdomain$sz$domain_functions..wrapdomaincsg|]}|qSrrrB)rrrrG(rHrI) rJrK s_dgettextrarrrrr<rNr)rFrrrrPs  cCst|||dSr)rar<r9rrrr<6r5cCst||dSr)rar|rpr:rrrr|9rr|cCstS)zSDeactivate translations. :return: the current Translations, if any )rar~rrrrr~<sr~cCs t|S)zxReactivate previously deactivated translations. :param t: the Translations, as returned by `deactivate` )rarrzrrrrBs rcCst||dS)zDefer activation of translations. :param get_locale: a callable returning a Babel Locale object :param env_path: the environment to use for looking up catalogs N)rarnrmr:rrrrnHsrncCtSrrarrrrget_translationsOr=rcCs4zddtddD}|WStygYSw)ziReturn a list of locale identifiers of the locales for which translations are available. cSs(g|]}d|vrtdd|r|qS).roz!locale/%s/LC_MESSAGES/messages.mo)rsresource_exists)rCr{rrrrGWsz)get_available_locales..rorp)rsresource_listdirru)localesrrrget_available_localesRs  rcCsddd}t}d|vr|dt||||}|r0t||vr0|jd|_t||vs0J|S)NcSsdd|DS)NcSsg|] }|r|ddqS)-r>)replace)rCidrrrrGbsz.normalize..r) locale_idsrrr normalizearVz(get_negotiated_locale..normalizerq)rappendr[ negotiaterK_datascript)preferred_localesravailable_localesrprrrget_negotiated_locale`s  rc Cs,z t|}W|jSttfyYdSw)zb"Return locale name from locale identifier, or `None` if identifier is not valid. N)r[parser\ ValueError display_name) locale_idrprrrget_locale_namess  rTcCr8rrrrrrr|r=cCr8rrrrrrr~r=cCr8rrrrrrrr=cCr8rrrrrrrnr=cCrrrrrrrrr=cCsgSrrrrrrrr=cCr8rr)rrrrrr=cCr8rr)rrrrrr=cKs d|}t||fi|S)zoRetrieves translations for "squeezed" messages, in a domain. See `s_gettext` for additional details.  )joinr-r)rmsgidrrrrrsrcKsd|}t|fi|S)aRetrieves translations for "squeezed" messages (in default domain). Squeezed messages are text blocks in which white-space has been simplified during extraction (see `trac.dist.extract_html`). The catalog contain msgid with minimal whitespace. As a consequence, the msgid have to be normalized as well at retrieval time (i.e. here). This typically happens for trans blocks and gettext functions in Jinja2 templates, as well as all the text extracted from legacy Genshi templates. r)rr-r)rrrrrrLsrL)r>rrrrr@r)?rZrsretrac.util.concurrencyrrtrac.util.htmlrtrac.util.textr__all__rrrr?rM cleandoc_r r)compiler,r4r r6r r7r<rPrrQrR has_babelbabelr[r\ babel.supportr]r^objectr_rar>rrrr r@rr rArr|r~rrnrrrr ImportErrorrrL functionsrrrrs              '