Internationalize src/utils/str.py and modify src/i18n.py to fit this changes

This commit is contained in:
Valentin Lorentz 2010-10-30 21:10:49 +02:00
parent 5150c4ef60
commit 3ea8115095
2 changed files with 69 additions and 32 deletions

View File

@ -75,16 +75,29 @@ def getLocalePath(name, localeName, extension):
directory = ansi.__file__[0:-len('ansi.pyc')] + 'locale' directory = ansi.__file__[0:-len('ansi.pyc')] + 'locale'
return '%s/%s.%s' % (directory, localeName, extension) return '%s/%s.%s' % (directory, localeName, extension)
i18nSupybot = None
i18nClasses = {} i18nClasses = {}
internationalizedCommands = {} internationalizedCommands = {}
internationalizedFunctions = []
def reloadLocals(): def reloadLocals():
for pluginName in i18nClasses: for pluginName in i18nClasses:
i18nClasses[pluginName].loadLocale() i18nClasses[pluginName].loadLocale()
for commandHash in internationalizedCommands: for commandHash in internationalizedCommands:
internationalizeDocstring(internationalizedCommands[commandHash]) internationalizeDocstring(internationalizedCommands[commandHash])
for function in internationalizedFunctions:
function.loadLocale()
class PluginInternationalization: def PluginInternationalization(name='supybot'):
global i18nSupybot
if name != 'supybot':
return _PluginInternationalization(name)
elif i18nSupybot == None:
i18nSupybot = _PluginInternationalization('supybot')
return i18nSupybot
class _PluginInternationalization:
"""Internationalization managment for a plugin.""" """Internationalization managment for a plugin."""
def __init__(self, name='supybot'): def __init__(self, name='supybot'):
self.name = name self.name = name
@ -101,6 +114,8 @@ class PluginInternationalization:
elif localeName is None: elif localeName is None:
localeName = 'en' localeName = 'en'
self.currentLocaleName = localeName self.currentLocaleName = localeName
self._loadL10nCode()
try: try:
translationFile = open(getLocalePath(self.name, localeName, 'po'), translationFile = open(getLocalePath(self.name, localeName, 'po'),
@ -158,7 +173,7 @@ class PluginInternationalization:
self._parse(translated)}) self._parse(translated)})
def _parse(self, string): def _parse(self, string):
return str.replace(string, '\\n', '\n') # Replace \\n by \n return str.replace(string, '\\n', '\n')
def __call__(self, untranslated, *args): def __call__(self, untranslated, *args):
if not 'conf' in globals(): if not 'conf' in globals():
@ -181,32 +196,55 @@ class PluginInternationalization:
except KeyError: except KeyError:
return untranslated % args return untranslated % args
def _getL10nCode(self): def _loadL10nCode(self):
return getLocalePath('supybot', self.currentLocaleName, 'py') if self.name != 'supybot':
return
def getPluralizers(self, pluralize, depluralize):
# This should be used only by src/utils/str.py
try: try:
execfile(self._getL10nCode()) execfile(self._getL10nCodePath())
except IOError: except IOError: # File doesn't exist
pass pass
return (pluralize, depluralize)
functions = locals()
functions.pop('self')
self._l10nFunctions = functions
def _getL10nCodePath(self):
if self.name != 'supybot':
return
return getLocalePath('supybot', self.currentLocaleName, 'py')
def localizeFunction(self, name):
if self.name != 'supybot':
return
if hasattr(self, '_l10nFunctions') and self._l10nFunctions.has_key(name):
return self._l10nFunctions[name]
def internationalizeFunction(self, name):
if self.name != 'supybot':
return
class FunctionInternationalizer:
def __init__(self, parent, name):
self._parent = parent
self._name = name
def __call__(self, obj):
obj = internationalizedFunction(self._parent, self._name, obj)
obj.loadLocale()
return obj
return FunctionInternationalizer(self, name)
def getOrdinal(self, ordinal): class internationalizedFunction:
# This should be used only by src/utils/str.py def __init__(self, internationalizer, name, function):
try: self._internationalizer = internationalizer
execfile(self._getL10nCode()) self._name = name
except IOError: self.__call__ = function
pass self._origin = function
return ordinal internationalizedFunctions.append(self)
def loadLocale(self):
def getBeAndHas(self, be, has): self.__call__ = self._internationalizer.localizeFunction(self._name)
# This should be used only by src/utils/str.py if self.__call__ == None:
try: self.restore()
execfile(self._getL10nCode()) def restore(self):
except IOError: self.__call__ = self._origin
pass
return (be, has)
def internationalizeDocstring(obj): def internationalizeDocstring(obj):
if sys.modules[obj.__module__].__dict__.has_key('_'): if sys.modules[obj.__module__].__dict__.has_key('_'):

View File

@ -43,7 +43,7 @@ from iter import all, any
from structures import TwoWayDictionary from structures import TwoWayDictionary
from supybot.i18n import PluginInternationalization from supybot.i18n import PluginInternationalization
_ = PluginInternationalization() internationalizeFunction=PluginInternationalization().internationalizeFunction
curry = new.instancemethod curry = new.instancemethod
chars = string.maketrans('', '') chars = string.maketrans('', '')
@ -256,6 +256,7 @@ def matchCase(s1, s2):
L[i] = L[i].upper() L[i] = L[i].upper()
return ''.join(L) return ''.join(L)
@internationalizeFunction('pluralize')
def pluralize(s): def pluralize(s):
"""Returns the plural of s. Put any exceptions to the general English """Returns the plural of s. Put any exceptions to the general English
rule of appending 's' in the plurals dictionary. rule of appending 's' in the plurals dictionary.
@ -278,6 +279,7 @@ def pluralize(s):
else: else:
return matchCase(s, s+'s') return matchCase(s, s+'s')
@internationalizeFunction('depluralize')
def depluralize(s): def depluralize(s):
"""Returns the singular of s.""" """Returns the singular of s."""
_depluralizeRegex = re.compile('[%s]ies' % consonants) _depluralizeRegex = re.compile('[%s]ies' % consonants)
@ -294,8 +296,6 @@ def depluralize(s):
else: else:
return s # Don't know what to do. return s # Don't know what to do.
pluralize, depluralize = _.getPluralizers(pluralize, depluralize)
def nItems(n, item, between=None): def nItems(n, item, between=None):
"""Works like this: """Works like this:
@ -332,6 +332,7 @@ def nItems(n, item, between=None):
else: else:
return format('%s %s %s', n, between, item) return format('%s %s %s', n, between, item)
@internationalizeFunction('ordinal')
def ordinal(i): def ordinal(i):
"""Returns i + the ordinal indicator for the number. """Returns i + the ordinal indicator for the number.
@ -350,8 +351,7 @@ def ordinal(i):
ord = 'rd' ord = 'rd'
return '%s%s' % (i, ord) return '%s%s' % (i, ord)
ordinal = _.getOrdinal(ordinal) @internationalizeFunction('be')
def be(i): def be(i):
"""Returns the form of the verb 'to be' based on the number i.""" """Returns the form of the verb 'to be' based on the number i."""
if i == 1: if i == 1:
@ -359,6 +359,7 @@ def be(i):
else: else:
return 'are' return 'are'
@internationalizeFunction('has')
def has(i): def has(i):
"""Returns the form of the verb 'to have' based on the number i.""" """Returns the form of the verb 'to have' based on the number i."""
if i == 1: if i == 1:
@ -366,8 +367,6 @@ def has(i):
else: else:
return 'have' return 'have'
be, has = _.getBeAndHas(be, has)
def toBool(s): def toBool(s):
s = s.strip().lower() s = s.strip().lower()
if s in ('true', 'on', 'enable', 'enabled', '1'): if s in ('true', 'on', 'enable', 'enabled', '1'):