root/galaxy-central/eggs/Babel-0.9.4-py2.6.egg/babel/support.py @ 3

リビジョン 3, 12.8 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1# -*- coding: utf-8 -*-
2#
3# Copyright (C) 2007 Edgewall Software
4# All rights reserved.
5#
6# This software is licensed as described in the file COPYING, which
7# you should have received as part of this distribution. The terms
8# are also available at http://babel.edgewall.org/wiki/License.
9#
10# This software consists of voluntary contributions made by many
11# individuals. For the exact contribution history, see the revision
12# history and logs, available at http://babel.edgewall.org/log/.
13
14"""Several classes and functions that help with integrating and using Babel
15in applications.
16
17.. note: the code in this module is not used by Babel itself
18"""
19
20from datetime import date, datetime, time
21import gettext
22
23try:
24    set
25except NameError:
26    from sets import set
27
28from babel.core import Locale
29from babel.dates import format_date, format_datetime, format_time, LC_TIME
30from babel.numbers import format_number, format_decimal, format_currency, \
31                          format_percent, format_scientific, LC_NUMERIC
32from babel.util import UTC
33
34__all__ = ['Format', 'LazyProxy', 'Translations']
35__docformat__ = 'restructuredtext en'
36
37
38class Format(object):
39    """Wrapper class providing the various date and number formatting functions
40    bound to a specific locale and time-zone.
41   
42    >>> fmt = Format('en_US', UTC)
43    >>> fmt.date(date(2007, 4, 1))
44    u'Apr 1, 2007'
45    >>> fmt.decimal(1.2345)
46    u'1.234'
47    """
48
49    def __init__(self, locale, tzinfo=None):
50        """Initialize the formatter.
51       
52        :param locale: the locale identifier or `Locale` instance
53        :param tzinfo: the time-zone info (a `tzinfo` instance or `None`)
54        """
55        self.locale = Locale.parse(locale)
56        self.tzinfo = tzinfo
57
58    def date(self, date=None, format='medium'):
59        """Return a date formatted according to the given pattern.
60       
61        >>> fmt = Format('en_US')
62        >>> fmt.date(date(2007, 4, 1))
63        u'Apr 1, 2007'
64       
65        :see: `babel.dates.format_date`
66        """
67        return format_date(date, format, locale=self.locale)
68
69    def datetime(self, datetime=None, format='medium'):
70        """Return a date and time formatted according to the given pattern.
71       
72        >>> from pytz import timezone
73        >>> fmt = Format('en_US', tzinfo=timezone('US/Eastern'))
74        >>> fmt.datetime(datetime(2007, 4, 1, 15, 30))
75        u'Apr 1, 2007 11:30:00 AM'
76       
77        :see: `babel.dates.format_datetime`
78        """
79        return format_datetime(datetime, format, tzinfo=self.tzinfo,
80                               locale=self.locale)
81
82    def time(self, time=None, format='medium'):
83        """Return a time formatted according to the given pattern.
84       
85        >>> from pytz import timezone
86        >>> fmt = Format('en_US', tzinfo=timezone('US/Eastern'))
87        >>> fmt.time(datetime(2007, 4, 1, 15, 30))
88        u'11:30:00 AM'
89       
90        :see: `babel.dates.format_time`
91        """
92        return format_time(time, format, tzinfo=self.tzinfo, locale=self.locale)
93
94    def number(self, number):
95        """Return an integer number formatted for the locale.
96       
97        >>> fmt = Format('en_US')
98        >>> fmt.number(1099)
99        u'1,099'
100       
101        :see: `babel.numbers.format_number`
102        """
103        return format_number(number, locale=self.locale)
104
105    def decimal(self, number, format=None):
106        """Return a decimal number formatted for the locale.
107       
108        >>> fmt = Format('en_US')
109        >>> fmt.decimal(1.2345)
110        u'1.234'
111       
112        :see: `babel.numbers.format_decimal`
113        """
114        return format_decimal(number, format, locale=self.locale)
115
116    def currency(self, number, currency):
117        """Return a number in the given currency formatted for the locale.
118       
119        :see: `babel.numbers.format_currency`
120        """
121        return format_currency(number, currency, locale=self.locale)
122
123    def percent(self, number, format=None):
124        """Return a number formatted as percentage for the locale.
125       
126        >>> fmt = Format('en_US')
127        >>> fmt.percent(0.34)
128        u'34%'
129       
130        :see: `babel.numbers.format_percent`
131        """
132        return format_percent(number, format, locale=self.locale)
133
134    def scientific(self, number):
135        """Return a number formatted using scientific notation for the locale.
136       
137        :see: `babel.numbers.format_scientific`
138        """
139        return format_scientific(number, locale=self.locale)
140
141
142class LazyProxy(object):
143    """Class for proxy objects that delegate to a specified function to evaluate
144    the actual object.
145   
146    >>> def greeting(name='world'):
147    ...     return 'Hello, %s!' % name
148    >>> lazy_greeting = LazyProxy(greeting, name='Joe')
149    >>> print lazy_greeting
150    Hello, Joe!
151    >>> u'  ' + lazy_greeting
152    u'  Hello, Joe!'
153    >>> u'(%s)' % lazy_greeting
154    u'(Hello, Joe!)'
155   
156    This can be used, for example, to implement lazy translation functions that
157    delay the actual translation until the string is actually used. The
158    rationale for such behavior is that the locale of the user may not always
159    be available. In web applications, you only know the locale when processing
160    a request.
161   
162    The proxy implementation attempts to be as complete as possible, so that
163    the lazy objects should mostly work as expected, for example for sorting:
164   
165    >>> greetings = [
166    ...     LazyProxy(greeting, 'world'),
167    ...     LazyProxy(greeting, 'Joe'),
168    ...     LazyProxy(greeting, 'universe'),
169    ... ]
170    >>> greetings.sort()
171    >>> for greeting in greetings:
172    ...     print greeting
173    Hello, Joe!
174    Hello, universe!
175    Hello, world!
176    """
177    __slots__ = ['_func', '_args', '_kwargs', '_value']
178
179    def __init__(self, func, *args, **kwargs):
180        # Avoid triggering our own __setattr__ implementation
181        object.__setattr__(self, '_func', func)
182        object.__setattr__(self, '_args', args)
183        object.__setattr__(self, '_kwargs', kwargs)
184        object.__setattr__(self, '_value', None)
185
186    def value(self):
187        if self._value is None:
188            value = self._func(*self._args, **self._kwargs)
189            object.__setattr__(self, '_value', value)
190        return self._value
191    value = property(value)
192
193    def __contains__(self, key):
194        return key in self.value
195
196    def __nonzero__(self):
197        return bool(self.value)
198
199    def __dir__(self):
200        return dir(self.value)
201
202    def __iter__(self):
203        return iter(self.value)
204
205    def __len__(self):
206        return len(self.value)
207
208    def __str__(self):
209        return str(self.value)
210
211    def __unicode__(self):
212        return unicode(self.value)
213
214    def __add__(self, other):
215        return self.value + other
216
217    def __radd__(self, other):
218        return other + self.value
219
220    def __mod__(self, other):
221        return self.value % other
222
223    def __rmod__(self, other):
224        return other % self.value
225
226    def __mul__(self, other):
227        return self.value * other
228
229    def __rmul__(self, other):
230        return other * self.value
231
232    def __call__(self, *args, **kwargs):
233        return self.value(*args, **kwargs)
234
235    def __lt__(self, other):
236        return self.value < other
237
238    def __le__(self, other):
239        return self.value <= other
240
241    def __eq__(self, other):
242        return self.value == other
243
244    def __ne__(self, other):
245        return self.value != other
246
247    def __gt__(self, other):
248        return self.value > other
249
250    def __ge__(self, other):
251        return self.value >= other
252
253    def __delattr__(self, name):
254        delattr(self.value, name)
255
256    def __getattr__(self, name):
257        return getattr(self.value, name)
258
259    def __setattr__(self, name, value):
260        setattr(self.value, name, value)
261
262    def __delitem__(self, key):
263        del self.value[key]
264
265    def __getitem__(self, key):
266        return self.value[key]
267
268    def __setitem__(self, key, value):
269        self.value[key] = value
270
271   
272class Translations(gettext.GNUTranslations, object):
273    """An extended translation catalog class."""
274
275    DEFAULT_DOMAIN = 'messages'
276
277    def __init__(self, fileobj=None, domain=DEFAULT_DOMAIN):
278        """Initialize the translations catalog.
279
280        :param fileobj: the file-like object the translation should be read
281                        from
282        """
283        gettext.GNUTranslations.__init__(self, fp=fileobj)
284        self.files = filter(None, [getattr(fileobj, 'name', None)])
285        self.domain = domain
286        self._domains = {}
287
288    def load(cls, dirname=None, locales=None, domain=DEFAULT_DOMAIN):
289        """Load translations from the given directory.
290
291        :param dirname: the directory containing the ``MO`` files
292        :param locales: the list of locales in order of preference (items in
293                        this list can be either `Locale` objects or locale
294                        strings)
295        :param domain: the message domain
296        :return: the loaded catalog, or a ``NullTranslations`` instance if no
297                 matching translations were found
298        :rtype: `Translations`
299        """
300        if locales is not None:
301            if not isinstance(locales, (list, tuple)):
302                locales = [locales]
303            locales = [str(locale) for locale in locales]
304        if not domain:
305            domain = cls.DEFAULT_DOMAIN
306        filename = gettext.find(domain, dirname, locales)
307        if not filename:
308            return gettext.NullTranslations()
309        return cls(fileobj=open(filename, 'rb'), domain=domain)
310    load = classmethod(load)
311
312    def __repr__(self):
313        return '<%s: "%s">' % (type(self).__name__,
314                               self._info.get('project-id-version'))
315
316    def add(self, translations, merge=True):
317        """Add the given translations to the catalog.
318
319        If the domain of the translations is different than that of the
320        current catalog, they are added as a catalog that is only accessible
321        by the various ``d*gettext`` functions.
322
323        :param translations: the `Translations` instance with the messages to
324                             add
325        :param merge: whether translations for message domains that have
326                      already been added should be merged with the existing
327                      translations
328        :return: the `Translations` instance (``self``) so that `merge` calls
329                 can be easily chained
330        :rtype: `Translations`
331        """
332        domain = getattr(translations, 'domain', self.DEFAULT_DOMAIN)
333        if merge and domain == self.domain:
334            return self.merge(translations)
335
336        existing = self._domains.get(domain)
337        if merge and existing is not None:
338            existing.merge(translations)
339        else:
340            translations.add_fallback(self)
341            self._domains[domain] = translations
342
343        return self
344
345    def merge(self, translations):
346        """Merge the given translations into the catalog.
347
348        Message translations in the specified catalog override any messages
349        with the same identifier in the existing catalog.
350
351        :param translations: the `Translations` instance with the messages to
352                             merge
353        :return: the `Translations` instance (``self``) so that `merge` calls
354                 can be easily chained
355        :rtype: `Translations`
356        """
357        if isinstance(translations, gettext.GNUTranslations):
358            self._catalog.update(translations._catalog)
359            if isinstance(translations, Translations):
360                self.files.extend(translations.files)
361
362        return self
363
364    def dgettext(self, domain, message):
365        """Like ``gettext()``, but look the message up in the specified
366        domain.
367        """
368        return self._domains.get(domain, self).gettext(message)
369   
370    def ldgettext(self, domain, message):
371        """Like ``lgettext()``, but look the message up in the specified
372        domain.
373        """
374        return self._domains.get(domain, self).lgettext(message)
375   
376    def dugettext(self, domain, message):
377        """Like ``ugettext()``, but look the message up in the specified
378        domain.
379        """
380        return self._domains.get(domain, self).ugettext(message)
381   
382    def dngettext(self, domain, singular, plural, num):
383        """Like ``ngettext()``, but look the message up in the specified
384        domain.
385        """
386        return self._domains.get(domain, self).ngettext(singular, plural, num)
387   
388    def ldngettext(self, domain, singular, plural, num):
389        """Like ``lngettext()``, but look the message up in the specified
390        domain.
391        """
392        return self._domains.get(domain, self).lngettext(singular, plural, num)
393   
394    def dungettext(self, domain, singular, plural, num):
395        """Like ``ungettext()`` but look the message up in the specified
396        domain.
397        """
398        return self._domains.get(domain, self).ungettext(singular, plural, num)
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。