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
@ -102,6 +115,8 @@ class PluginInternationalization:
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'),
'ru') # ru is the mode, not the beginning 'ru') # ru is the mode, not the beginning
@ -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):
if self.name != 'supybot':
return
try:
execfile(self._getL10nCodePath())
except IOError: # File doesn't exist
pass
functions = locals()
functions.pop('self')
self._l10nFunctions = functions
def _getL10nCodePath(self):
if self.name != 'supybot':
return
return getLocalePath('supybot', self.currentLocaleName, 'py') return getLocalePath('supybot', self.currentLocaleName, 'py')
def getPluralizers(self, pluralize, depluralize): def localizeFunction(self, name):
# This should be used only by src/utils/str.py if self.name != 'supybot':
try: return
execfile(self._getL10nCode()) if hasattr(self, '_l10nFunctions') and self._l10nFunctions.has_key(name):
except IOError: return self._l10nFunctions[name]
pass
return (pluralize, depluralize)
def getOrdinal(self, ordinal): def internationalizeFunction(self, name):
# This should be used only by src/utils/str.py if self.name != 'supybot':
try: return
execfile(self._getL10nCode()) class FunctionInternationalizer:
except IOError: def __init__(self, parent, name):
pass self._parent = parent
return ordinal self._name = name
def __call__(self, obj):
obj = internationalizedFunction(self._parent, self._name, obj)
obj.loadLocale()
return obj
return FunctionInternationalizer(self, name)
def getBeAndHas(self, be, has): 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 (be, has) internationalizedFunctions.append(self)
def loadLocale(self):
self.__call__ = self._internationalizer.localizeFunction(self._name)
if self.__call__ == None:
self.restore()
def restore(self):
self.__call__ = self._origin
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'):