1b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# -*- coding: utf-8 -*- 2b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik""" 3b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik webapp2_extras.i18n 4b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik =================== 5b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 6b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Internationalization support for webapp2. 7b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 8b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Several ideas borrowed from tipfy.i18n and Flask-Babel. 9b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 10b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :copyright: 2011 by tipfy.org. 11b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :license: Apache Sotware License, see LICENSE for details. 12b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik""" 13b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport datetime 14b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport gettext as gettext_stdlib 15b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 16b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport babel 17b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom babel import dates 18b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom babel import numbers 19b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikfrom babel import support 20b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 21b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craiktry: 22b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # Monkeypatches pytz for gae. 23b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik import pytz.gae 24b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikexcept ImportError: # pragma: no cover 25b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik pass 26b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 27b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport pytz 28b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 29b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikimport webapp2 30b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 31b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: Default configuration values for this module. Keys are: 32b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: 33b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: translations_path 34b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: Path to the translations directory. Default is `locale`. 35b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: 36b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: domains 37b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: List of gettext domains to be used. Default is ``['messages']``. 38b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: 39b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: default_locale 40b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: A locale code to be used as fallback. Default is ``'en_US'``. 41b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: 42b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: default_timezone 43b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: The application default timezone according to the Olson 44b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: database. Default is ``'UTC'``. 45b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: 46b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: locale_selector 47b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: A function that receives (store, request) and returns a locale 48b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: to be used for a request. If not defined, uses `default_locale`. 49b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: Can also be a string in dotted notation to be imported. 50b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: 51b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: timezone_selector 52b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: A function that receives (store, request) and returns a timezone 53b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: to be used for a request. If not defined, uses `default_timezone`. 54b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: Can also be a string in dotted notation to be imported. 55b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: 56b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: date_formats 57b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: Default date formats for datetime, date and time. 58b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdefault_config = { 59b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'translations_path': 'locale', 60b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'domains': ['messages'], 61b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'default_locale': 'en_US', 62b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'default_timezone': 'UTC', 63b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'locale_selector': None, 64b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'timezone_selector': None, 65b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'date_formats': { 66b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'time': 'medium', 67b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'date': 'medium', 68b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'datetime': 'medium', 69b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'time.short': None, 70b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'time.medium': None, 71b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'time.full': None, 72b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'time.long': None, 73b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'time.iso': "HH':'mm':'ss", 74b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'date.short': None, 75b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'date.medium': None, 76b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'date.full': None, 77b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'date.long': None, 78b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'date.iso': "yyyy'-'MM'-'dd", 79b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'datetime.short': None, 80b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'datetime.medium': None, 81b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'datetime.full': None, 82b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'datetime.long': None, 83b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 'datetime.iso': "yyyy'-'MM'-'dd'T'HH':'mm':'ssZ", 84b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik }, 85b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik} 86b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 87b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris CraikNullTranslations = gettext_stdlib.NullTranslations 88b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 89b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 90b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass I18nStore(object): 91b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Internalization store. 92b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 93b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Caches loaded translations and configuration to be used between requests. 94b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 95b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 96b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: Configuration key. 97b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik config_key = __name__ 98b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: A dictionary with all loaded translations. 99b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik translations = None 100b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: Path to where traslations are stored. 101b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik translations_path = None 102b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: Translation domains to merge. 103b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik domains = None 104b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: Default locale code. 105b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik default_locale = None 106b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: Default timezone code. 107b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik default_timezone = None 108b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: Dictionary of default date formats. 109b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik date_formats = None 110b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: A callable that returns the locale for a request. 111b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik locale_selector = None 112b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: A callable that returns the timezone for a request. 113b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik timezone_selector = None 114b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 115b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def __init__(self, app, config=None): 116b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Initializes the i18n store. 117b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 118b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param app: 119b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A :class:`webapp2.WSGIApplication` instance. 120b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param config: 121b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A dictionary of configuration values to be overridden. See 122b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the available keys in :data:`default_config`. 123b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 124b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik config = app.config.load_config(self.config_key, 125b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik default_values=default_config, user_values=config, 126b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik required_keys=None) 127b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.translations = {} 128b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.translations_path = config['translations_path'] 129b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.domains = config['domains'] 130b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.default_locale = config['default_locale'] 131b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.default_timezone = config['default_timezone'] 132b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.date_formats = config['date_formats'] 133b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.set_locale_selector(config['locale_selector']) 134b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.set_timezone_selector(config['timezone_selector']) 135b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 136b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def set_locale_selector(self, func): 137b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Sets the function that defines the locale for a request. 138b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 139b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param func: 140b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A callable that receives (store, request) and returns the locale 141b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for a request. 142b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 143b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if func is None: 144b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.locale_selector = self.default_locale_selector 145b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 146b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(func, basestring): 147b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik func = webapp2.import_string(func) 148b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 149b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # Functions are descriptors, so bind it to this instance with 150b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik # __get__. 151b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.locale_selector = func.__get__(self, self.__class__) 152b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 153b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def set_timezone_selector(self, func): 154b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Sets the function that defines the timezone for a request. 155b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 156b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param func: 157b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A callable that receives (store, request) and returns the timezone 158b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for a request. 159b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 160b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if func is None: 161b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.timezone_selector = self.default_timezone_selector 162b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 163b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(func, basestring): 164b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik func = webapp2.import_string(func) 165b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 166b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.timezone_selector = func.__get__(self, self.__class__) 167b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 168b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def default_locale_selector(self, request): 169b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return self.default_locale 170b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 171b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def default_timezone_selector(self, request): 172b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return self.default_timezone 173b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 174b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def get_translations(self, locale): 175b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns a translation catalog for a locale. 176b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 177b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param locale: 178b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A locale code. 179b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 180b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A ``babel.support.Translations`` instance, or 181b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``gettext.NullTranslations`` if none was found. 182b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 183b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik trans = self.translations.get(locale) 184b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if not trans: 185b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik locales = (locale, self.default_locale) 186b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik trans = self.load_translations(self.translations_path, locales, 187b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.domains) 188b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if not webapp2.get_app().debug: 189b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.translations[locale] = trans 190b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 191b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return trans 192b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 193b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def load_translations(self, dirname, locales, domains): 194b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Loads a translation catalog. 195b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 196b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param dirname: 197b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Path to where translations are stored. 198b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param locales: 199b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A list of locale codes. 200b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param domains: 201b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A list of domains to be merged. 202b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 203b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A ``babel.support.Translations`` instance, or 204b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``gettext.NullTranslations`` if none was found. 205b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 206b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik trans = None 207b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik trans_null = None 208b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for domain in domains: 209b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik _trans = support.Translations.load(dirname, locales, domain) 210b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(_trans, NullTranslations): 211b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik trans_null = _trans 212b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik continue 213b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik elif trans is None: 214b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik trans = _trans 215b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik else: 216b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik trans.merge(_trans) 217b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 218b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return trans or trans_null or NullTranslations() 219b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 220b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 221b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikclass I18n(object): 222b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Internalization provider for a single request.""" 223b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 224b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: A reference to :class:`I18nStore`. 225b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik store = None 226b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: The current locale code. 227b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik locale = None 228b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: The current translations. 229b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik translations = None 230b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: The current timezone code. 231b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik timezone = None 232b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik #: The current tzinfo object. 233b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik tzinfo = None 234b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 235b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def __init__(self, request): 236b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Initializes the i18n provider for a request. 237b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 238b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param request: 239b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A :class:`webapp2.Request` instance. 240b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 241b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.store = store = get_store(app=request.app) 242b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.set_locale(store.locale_selector(request)) 243b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.set_timezone(store.timezone_selector(request)) 244b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 245b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def set_locale(self, locale): 246b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Sets the locale code for this request. 247b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 248b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param locale: 249b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A locale code. 250b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 251b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.locale = locale 252b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.translations = self.store.get_translations(locale) 253b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 254b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def set_timezone(self, timezone): 255b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Sets the timezone code for this request. 256b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 257b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param timezone: 258b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A timezone code. 259b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 260b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.timezone = timezone 261b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik self.tzinfo = pytz.timezone(timezone) 262b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 263b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def gettext(self, string, **variables): 264b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Translates a given string according to the current locale. 265b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 266b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param string: 267b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The string to be translated. 268b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param variables: 269b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Variables to format the returned string. 270b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 271b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The translated string. 272b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 273b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if variables: 274b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return self.translations.ugettext(string) % variables 275b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 276b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return self.translations.ugettext(string) 277b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 278b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def ngettext(self, singular, plural, n, **variables): 279b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Translates a possible pluralized string according to the current 280b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik locale. 281b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 282b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param singular: 283b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The singular for of the string to be translated. 284b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param plural: 285b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The plural for of the string to be translated. 286b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param n: 287b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik An integer indicating if this is a singular or plural. If greater 288b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik than 1, it is a plural. 289b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param variables: 290b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Variables to format the returned string. 291b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 292b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The translated string. 293b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 294b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if variables: 295b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return self.translations.ungettext(singular, plural, n) % variables 296b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 297b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return self.translations.ungettext(singular, plural, n) 298b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 299b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def to_local_timezone(self, datetime): 300b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns a datetime object converted to the local timezone. 301b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 302b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param datetime: 303b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A ``datetime`` object. 304b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 305b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A ``datetime`` object normalized to a timezone. 306b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 307b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if datetime.tzinfo is None: 308b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik datetime = datetime.replace(tzinfo=pytz.UTC) 309b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 310b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return self.tzinfo.normalize(datetime.astimezone(self.tzinfo)) 311b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 312b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def to_utc(self, datetime): 313b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns a datetime object converted to UTC and without tzinfo. 314b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 315b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param datetime: 316b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A ``datetime`` object. 317b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 318b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A naive ``datetime`` object (no timezone), converted to UTC. 319b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 320b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if datetime.tzinfo is None: 321b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik datetime = self.tzinfo.localize(datetime) 322b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 323b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return datetime.astimezone(pytz.UTC).replace(tzinfo=None) 324b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 325b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def _get_format(self, key, format): 326b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """A helper for the datetime formatting functions. Returns a format 327b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik name or pattern to be used by Babel date format functions. 328b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 329b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param key: 330b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A format key to be get from config. Valid values are "date", 331b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik "datetime" or "time". 332b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param format: 333b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The format to be returned. Valid values are "short", "medium", 334b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik "long", "full" or a custom date/time pattern. 335b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 336b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A format name or pattern to be used by Babel date format functions. 337b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 338b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if format is None: 339b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik format = self.store.date_formats.get(key) 340b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 341b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if format in ('short', 'medium', 'full', 'long', 'iso'): 342b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik rv = self.store.date_formats.get('%s.%s' % (key, format)) 343b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if rv is not None: 344b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik format = rv 345b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 346b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return format 347b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 348b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def format_date(self, date=None, format=None, rebase=True): 349b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns a date formatted according to the given pattern and 350b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik following the current locale. 351b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 352b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param date: 353b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A ``date`` or ``datetime`` object. If None, the current date in 354b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik UTC is used. 355b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param format: 356b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The format to be returned. Valid values are "short", "medium", 357b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik "long", "full" or a custom date/time pattern. Example outputs: 358b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 359b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik - short: 11/10/09 360b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik - medium: Nov 10, 2009 361b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik - long: November 10, 2009 362b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik - full: Tuesday, November 10, 2009 363b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 364b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param rebase: 365b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik If True, converts the date to the current :attr:`timezone`. 366b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 367b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A formatted date in unicode. 368b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 369b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik format = self._get_format('date', format) 370b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 371b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if rebase and isinstance(date, datetime.datetime): 372b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik date = self.to_local_timezone(date) 373b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 374b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return dates.format_date(date, format, locale=self.locale) 375b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 376b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def format_datetime(self, datetime=None, format=None, rebase=True): 377b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns a date and time formatted according to the given pattern 378b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik and following the current locale and timezone. 379b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 380b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param datetime: 381b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A ``datetime`` object. If None, the current date and time in UTC 382b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik is used. 383b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param format: 384b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The format to be returned. Valid values are "short", "medium", 385b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik "long", "full" or a custom date/time pattern. Example outputs: 386b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 387b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik - short: 11/10/09 4:36 PM 388b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik - medium: Nov 10, 2009 4:36:05 PM 389b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik - long: November 10, 2009 4:36:05 PM +0000 390b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik - full: Tuesday, November 10, 2009 4:36:05 PM World (GMT) Time 391b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 392b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param rebase: 393b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik If True, converts the datetime to the current :attr:`timezone`. 394b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 395b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A formatted date and time in unicode. 396b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 397b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik format = self._get_format('datetime', format) 398b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 399b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik kwargs = {} 400b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if rebase: 401b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik kwargs['tzinfo'] = self.tzinfo 402b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 403b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return dates.format_datetime(datetime, format, locale=self.locale, 404b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik **kwargs) 405b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 406b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def format_time(self, time=None, format=None, rebase=True): 407b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns a time formatted according to the given pattern and 408b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik following the current locale and timezone. 409b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 410b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param time: 411b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A ``time`` or ``datetime`` object. If None, the current 412b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik time in UTC is used. 413b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param format: 414b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The format to be returned. Valid values are "short", "medium", 415b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik "long", "full" or a custom date/time pattern. Example outputs: 416b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 417b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik - short: 4:36 PM 418b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik - medium: 4:36:05 PM 419b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik - long: 4:36:05 PM +0000 420b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik - full: 4:36:05 PM World (GMT) Time 421b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 422b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param rebase: 423b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik If True, converts the time to the current :attr:`timezone`. 424b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 425b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A formatted time in unicode. 426b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 427b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik format = self._get_format('time', format) 428b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 429b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik kwargs = {} 430b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if rebase: 431b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik kwargs['tzinfo'] = self.tzinfo 432b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 433b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return dates.format_time(time, format, locale=self.locale, **kwargs) 434b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 435b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def format_timedelta(self, datetime_or_timedelta, granularity='second', 436b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik threshold=.85): 437b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Formats the elapsed time from the given date to now or the given 438b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik timedelta. This currently requires an unreleased development version 439b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik of Babel. 440b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 441b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param datetime_or_timedelta: 442b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A ``timedelta`` object representing the time difference to format, 443b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik or a ``datetime`` object in UTC. 444b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param granularity: 445b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Determines the smallest unit that should be displayed, the value 446b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik can be one of "year", "month", "week", "day", "hour", "minute" or 447b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik "second". 448b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param threshold: 449b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Factor that determines at which point the presentation switches to 450b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the next higher unit. 451b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 452b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A string with the elapsed time. 453b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 454b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if isinstance(datetime_or_timedelta, datetime.datetime): 455b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik datetime_or_timedelta = datetime.datetime.utcnow() - \ 456b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik datetime_or_timedelta 457b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 458b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return dates.format_timedelta(datetime_or_timedelta, granularity, 459b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik threshold=threshold, 460b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik locale=self.locale) 461b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 462b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def format_number(self, number): 463b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns the given number formatted for the current locale. Example:: 464b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 465b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_number(1099, locale='en_US') 466b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'1,099' 467b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 468b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param number: 469b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The number to format. 470b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 471b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The formatted number. 472b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 473b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return numbers.format_number(number, locale=self.locale) 474b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 475b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def format_decimal(self, number, format=None): 476b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns the given decimal number formatted for the current locale. 477b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Example:: 478b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 479b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_decimal(1.2345, locale='en_US') 480b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'1.234' 481b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_decimal(1.2346, locale='en_US') 482b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'1.235' 483b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_decimal(-1.2346, locale='en_US') 484b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'-1.235' 485b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_decimal(1.2345, locale='sv_SE') 486b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'1,234' 487b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_decimal(12345, locale='de') 488b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'12.345' 489b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 490b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The appropriate thousands grouping and the decimal separator are used 491b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik for each locale:: 492b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 493b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_decimal(12345.5, locale='en_US') 494b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'12,345.5' 495b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 496b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param number: 497b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The number to format. 498b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param format: 499b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Notation format. 500b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 501b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The formatted decimal number. 502b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 503b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return numbers.format_decimal(number, format=format, 504b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik locale=self.locale) 505b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 506b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def format_currency(self, number, currency, format=None): 507b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns a formatted currency value. Example:: 508b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 509b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_currency(1099.98, 'USD', locale='en_US') 510b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'$1,099.98' 511b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_currency(1099.98, 'USD', locale='es_CO') 512b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'US$\\xa01.099,98' 513b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_currency(1099.98, 'EUR', locale='de_DE') 514b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'1.099,98\\xa0\\u20ac' 515b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 516b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The pattern can also be specified explicitly:: 517b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 518b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_currency(1099.98, 'EUR', u'\\xa4\\xa4 #,##0.00', 519b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ... locale='en_US') 520b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'EUR 1,099.98' 521b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 522b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param number: 523b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The number to format. 524b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param currency: 525b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The currency code. 526b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param format: 527b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Notation format. 528b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 529b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The formatted currency value. 530b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 531b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return numbers.format_currency(number, currency, format=format, 532b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik locale=self.locale) 533b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 534b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def format_percent(self, number, format=None): 535b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns formatted percent value for the current locale. Example:: 536b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 537b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_percent(0.34, locale='en_US') 538b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'34%' 539b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_percent(25.1234, locale='en_US') 540b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'2,512%' 541b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_percent(25.1234, locale='sv_SE') 542b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'2\\xa0512\\xa0%' 543b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 544b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The format pattern can also be specified explicitly:: 545b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 546b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_percent(25.1234, u'#,##0\u2030', locale='en_US') 547b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'25,123\u2030' 548b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 549b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param number: 550b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The percent number to format 551b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param format: 552b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Notation format. 553b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 554b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The formatted percent number. 555b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 556b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return numbers.format_percent(number, format=format, 557b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik locale=self.locale) 558b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 559b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def format_scientific(self, number, format=None): 560b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns value formatted in scientific notation for the current 561b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik locale. Example:: 562b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 563b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_scientific(10000, locale='en_US') 564b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'1E4' 565b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 566b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The format pattern can also be specified explicitly:: 567b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 568b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> format_scientific(1234567, u'##0E00', locale='en_US') 569b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'1.23E06' 570b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 571b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param number: 572b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The number to format. 573b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param format: 574b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Notation format. 575b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 576b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Value formatted in scientific notation. 577b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 578b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return numbers.format_scientific(number, format=format, 579b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik locale=self.locale) 580b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 581b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def parse_date(self, string): 582b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Parses a date from a string. 583b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 584b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This function uses the date format for the locale as a hint to 585b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik determine the order in which the date fields appear in the string. 586b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Example:: 587b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 588b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> parse_date('4/1/04', locale='en_US') 589b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik datetime.date(2004, 4, 1) 590b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> parse_date('01.04.2004', locale='de_DE') 591b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik datetime.date(2004, 4, 1) 592b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 593b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param string: 594b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The string containing the date. 595b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 596b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The parsed date object. 597b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 598b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return dates.parse_date(string, locale=self.locale) 599b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 600b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def parse_datetime(self, string): 601b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Parses a date and time from a string. 602b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 603b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This function uses the date and time formats for the locale as a hint 604b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik to determine the order in which the time fields appear in the string. 605b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 606b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param string: 607b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The string containing the date and time. 608b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 609b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The parsed datetime object. 610b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 611b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return dates.parse_datetime(string, locale=self.locale) 612b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 613b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def parse_time(self, string): 614b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Parses a time from a string. 615b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 616b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik This function uses the time format for the locale as a hint to 617b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik determine the order in which the time fields appear in the string. 618b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Example:: 619b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 620b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> parse_time('15:30:00', locale='en_US') 621b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik datetime.time(15, 30) 622b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 623b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param string: 624b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The string containing the time. 625b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 626b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The parsed time object. 627b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 628b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return dates.parse_time(string, locale=self.locale) 629b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 630b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def parse_number(self, string): 631b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Parses localized number string into a long integer. Example:: 632b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 633b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> parse_number('1,099', locale='en_US') 634b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1099L 635b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> parse_number('1.099', locale='de_DE') 636b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1099L 637b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 638b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik When the given string cannot be parsed, an exception is raised:: 639b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 640b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> parse_number('1.099,98', locale='de') 641b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Traceback (most recent call last): 642b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ... 643b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik NumberFormatError: '1.099,98' is not a valid number 644b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 645b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param string: 646b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The string to parse. 647b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 648b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The parsed number. 649b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :raises: 650b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``NumberFormatError`` if the string can not be converted to a 651b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik number. 652b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 653b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return numbers.parse_number(string, locale=self.locale) 654b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 655b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def parse_decimal(self, string): 656b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Parses localized decimal string into a float. Example:: 657b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 658b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> parse_decimal('1,099.98', locale='en_US') 659b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1099.98 660b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> parse_decimal('1.099,98', locale='de') 661b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 1099.98 662b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 663b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik When the given string cannot be parsed, an exception is raised:: 664b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 665b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> parse_decimal('2,109,998', locale='de') 666b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Traceback (most recent call last): 667b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ... 668b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik NumberFormatError: '2,109,998' is not a valid decimal number 669b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 670b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param string: 671b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The string to parse. 672b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 673b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The parsed decimal number. 674b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :raises: 675b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik ``NumberFormatError`` if the string can not be converted to a 676b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik decimal number. 677b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 678b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return numbers.parse_decimal(string, locale=self.locale) 679b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 680b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik def get_timezone_location(self, dt_or_tzinfo): 681b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns a representation of the given timezone using "location 682b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik format". 683b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 684b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The result depends on both the local display name of the country and 685b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the city assocaited with the time zone:: 686b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 687b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> from pytz import timezone 688b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> tz = timezone('America/St_Johns') 689b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> get_timezone_location(tz, locale='de_DE') 690b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u"Kanada (St. John's)" 691b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> tz = timezone('America/Mexico_City') 692b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> get_timezone_location(tz, locale='de_DE') 693b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'Mexiko (Mexiko-Stadt)' 694b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 695b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik If the timezone is associated with a country that uses only a single 696b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik timezone, just the localized country name is returned:: 697b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 698b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> tz = timezone('Europe/Berlin') 699b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik >>> get_timezone_name(tz, locale='de_DE') 700b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik u'Deutschland' 701b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 702b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param dt_or_tzinfo: 703b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The ``datetime`` or ``tzinfo`` object that determines 704b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the timezone; if None, the current date and time in UTC is assumed. 705b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 706b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The localized timezone name using location format. 707b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 708b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return dates.get_timezone_name(dt_or_tzinfo, locale=self.locale) 709b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 710b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 711b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef gettext(string, **variables): 712b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.gettext`.""" 713b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().gettext(string, **variables) 714b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 715b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 716b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef ngettext(singular, plural, n, **variables): 717b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.ngettext`.""" 718b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().ngettext(singular, plural, n, **variables) 719b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 720b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 721b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef to_local_timezone(datetime): 722b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.to_local_timezone`.""" 723b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().to_local_timezone(datetime) 724b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 725b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 726b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef to_utc(datetime): 727b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.to_utc`.""" 728b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().to_utc(datetime) 729b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 730b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 731b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef format_date(date=None, format=None, rebase=True): 732b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.format_date`.""" 733b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().format_date(date, format, rebase) 734b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 735b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 736b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef format_datetime(datetime=None, format=None, rebase=True): 737b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.format_datetime`.""" 738b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().format_datetime(datetime, format, rebase) 739b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 740b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 741b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef format_time(time=None, format=None, rebase=True): 742b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.format_time`.""" 743b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().format_time(time, format, rebase) 744b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 745b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 746b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef format_timedelta(datetime_or_timedelta, granularity='second', 747b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik threshold=.85): 748b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.format_timedelta`.""" 749b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().format_timedelta(datetime_or_timedelta, 750b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik granularity, threshold) 751b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 752b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 753b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef format_number(number): 754b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.format_number`.""" 755b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().format_number(number) 756b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 757b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 758b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef format_decimal(number, format=None): 759b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.format_decimal`.""" 760b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().format_decimal(number, format) 761b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 762b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 763b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef format_currency(number, currency, format=None): 764b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.format_currency`.""" 765b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().format_currency(number, currency, format) 766b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 767b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 768b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef format_percent(number, format=None): 769b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.format_percent`.""" 770b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().format_percent(number, format) 771b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 772b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 773b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef format_scientific(number, format=None): 774b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.format_scientific`.""" 775b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().format_scientific(number, format) 776b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 777b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 778b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef parse_date(string): 779b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.parse_date`""" 780b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().parse_date(string) 781b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 782b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 783b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef parse_datetime(string): 784b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.parse_datetime`.""" 785b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().parse_datetime(string) 786b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 787b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 788b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef parse_time(string): 789b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.parse_time`.""" 790b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().parse_time(string) 791b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 792b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 793b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef parse_number(string): 794b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.parse_number`.""" 795b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().parse_number(string) 796b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 797b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 798b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef parse_decimal(string): 799b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.parse_decimal`.""" 800b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().parse_decimal(string) 801b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 802b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 803b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef get_timezone_location(dt_or_tzinfo): 804b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """See :meth:`I18n.get_timezone_location`.""" 805b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return get_i18n().get_timezone_location(dt_or_tzinfo) 806b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 807b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 808b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef lazy_gettext(string, **variables): 809b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """A lazy version of :func:`gettext`. 810b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 811b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param string: 812b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The string to be translated. 813b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param variables: 814b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik Variables to format the returned string. 815b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :returns: 816b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A ``babel.support.LazyProxy`` object that when accessed translates 817b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik the string. 818b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 819b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return support.LazyProxy(gettext, string, **variables) 820b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 821b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 822b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# Aliases. 823b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik_ = gettext 824b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik_lazy = lazy_gettext 825b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 826b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 827b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik# Factories ------------------------------------------------------------------- 828b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 829b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 830b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: Key used to store :class:`I18nStore` in the app registry. 831b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik_store_registry_key = 'webapp2_extras.i18n.I18nStore' 832b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik#: Key used to store :class:`I18n` in the request registry. 833b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik_i18n_registry_key = 'webapp2_extras.i18n.I18n' 834b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 835b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 836b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef get_store(factory=I18nStore, key=_store_registry_key, app=None): 837b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns an instance of :class:`I18nStore` from the app registry. 838b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 839b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik It'll try to get it from the current app registry, and if it is not 840b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik registered it'll be instantiated and registered. A second call to this 841b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik function will return the same instance. 842b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 843b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param factory: 844b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The callable used to build and register the instance if it is not yet 845b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik registered. The default is the class :class:`I18nStore` itself. 846b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param key: 847b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The key used to store the instance in the registry. A default is used 848b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if it is not set. 849b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param app: 850b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A :class:`webapp2.WSGIApplication` instance used to store the instance. 851b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The active app is used if it is not set. 852b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 853b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik app = app or webapp2.get_app() 854b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik store = app.registry.get(key) 855b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if not store: 856b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik store = app.registry[key] = factory(app) 857b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 858b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return store 859b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 860b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 861b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef set_store(store, key=_store_registry_key, app=None): 862b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Sets an instance of :class:`I18nStore` in the app registry. 863b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 864b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param store: 865b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik An instance of :class:`I18nStore`. 866b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param key: 867b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The key used to retrieve the instance from the registry. A default 868b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik is used if it is not set. 869b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param request: 870b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A :class:`webapp2.WSGIApplication` instance used to retrieve the 871b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik instance. The active app is used if it is not set. 872b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 873b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik app = app or webapp2.get_app() 874b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik app.registry[key] = store 875b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 876b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 877b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef get_i18n(factory=I18n, key=_i18n_registry_key, request=None): 878b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Returns an instance of :class:`I18n` from the request registry. 879b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 880b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik It'll try to get it from the current request registry, and if it is not 881b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik registered it'll be instantiated and registered. A second call to this 882b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik function will return the same instance. 883b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 884b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param factory: 885b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The callable used to build and register the instance if it is not yet 886b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik registered. The default is the class :class:`I18n` itself. 887b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param key: 888b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The key used to store the instance in the registry. A default is used 889b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if it is not set. 890b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param request: 891b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A :class:`webapp2.Request` instance used to store the instance. The 892b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik active request is used if it is not set. 893b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 894b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik request = request or webapp2.get_request() 895b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik i18n = request.registry.get(key) 896b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik if not i18n: 897b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik i18n = request.registry[key] = factory(request) 898b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 899b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik return i18n 900b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 901b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 902b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craikdef set_i18n(i18n, key=_i18n_registry_key, request=None): 903b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """Sets an instance of :class:`I18n` in the request registry. 904b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik 905b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param store: 906b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik An instance of :class:`I18n`. 907b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param key: 908b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik The key used to retrieve the instance from the registry. A default 909b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik is used if it is not set. 910b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik :param request: 911b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik A :class:`webapp2.Request` instance used to retrieve the instance. The 912b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik active request is used if it is not set. 913b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik """ 914b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik request = request or webapp2.get_request() 915b2cbf1594f8d6e4ba32d384cf379f62a74ed7654Chris Craik request.registry[key] = i18n 916