mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-27 13:19:24 +01:00
Merge branch 'l10n-fr' into testing
This commit is contained in:
commit
d5ae366ceb
@ -40,7 +40,7 @@ def pluralize(s):
|
|||||||
lowered in ['bijou', 'caillou', 'chou', 'genou', 'hibou', 'joujou',
|
lowered in ['bijou', 'caillou', 'chou', 'genou', 'hibou', 'joujou',
|
||||||
'pou']:
|
'pou']:
|
||||||
return s + 'x'
|
return s + 'x'
|
||||||
elif lowered.endwith('al') and \
|
elif lowered.endswith('al') and \
|
||||||
lowered not in ['bal', 'carnaval', 'chacal', 'festival', 'récital',
|
lowered not in ['bal', 'carnaval', 'chacal', 'festival', 'récital',
|
||||||
'régal', 'cal', 'étal', 'aval', 'caracal', 'val', 'choral',
|
'régal', 'cal', 'étal', 'aval', 'caracal', 'val', 'choral',
|
||||||
'corral', 'galgal', 'gayal']:
|
'corral', 'galgal', 'gayal']:
|
||||||
@ -53,7 +53,7 @@ def pluralize(s):
|
|||||||
return s + 'x'
|
return s + 'x'
|
||||||
elif lowered == 'pare-feu':
|
elif lowered == 'pare-feu':
|
||||||
return s
|
return s
|
||||||
elif lowered.endwith('eu') and \
|
elif lowered.endswith('eu') and \
|
||||||
lowered not in ['bleu', 'pneu', 'émeu', 'enfeu']:
|
lowered not in ['bleu', 'pneu', 'émeu', 'enfeu']:
|
||||||
# Note: when 'lieu' is a fish, it has a 's' ; else, it has a 'x'
|
# Note: when 'lieu' is a fish, it has a 's' ; else, it has a 'x'
|
||||||
return s + 'x'
|
return s + 'x'
|
||||||
|
@ -23,7 +23,7 @@ msgstr "Détermine si ce plugin est activé."
|
|||||||
msgid ""
|
msgid ""
|
||||||
"Determines whether this plugin will automode\n"
|
"Determines whether this plugin will automode\n"
|
||||||
" owners."
|
" owners."
|
||||||
msgstr "Détermine si ce pluginmettra des modes automatiques sur les owners."
|
msgstr "Détermine si ce plugin mettra des modes automatiques sur les owners."
|
||||||
|
|
||||||
#: config.py:52
|
#: config.py:52
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -61,7 +61,7 @@ conf.registerChannelValue(Factoids, 'replyWhenInvalidCommand',
|
|||||||
commands by searching for a factoid; basically making the whatis
|
commands by searching for a factoid; basically making the whatis
|
||||||
unnecessary when you want all factoids for a given key.""")))
|
unnecessary when you want all factoids for a given key.""")))
|
||||||
conf.registerChannelValue(Factoids, 'format',
|
conf.registerChannelValue(Factoids, 'format',
|
||||||
FactoidFormat('$key could be $value.', _("""Determines the format of
|
FactoidFormat(_('$key could be $value.'), _("""Determines the format of
|
||||||
the response given when a factoid's value is requested. All the standard
|
the response given when a factoid's value is requested. All the standard
|
||||||
substitutes apply, in addition to "$key" for the factoid's key and "$value"
|
substitutes apply, in addition to "$key" for the factoid's key and "$value"
|
||||||
for the factoid's value.""")))
|
for the factoid's value.""")))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: Supybot-fr\n"
|
"Project-Id-Version: Supybot-fr\n"
|
||||||
"POT-Creation-Date: 2010-10-17 10:59+CEST\n"
|
"POT-Creation-Date: 2010-11-11 12:37+CET\n"
|
||||||
"PO-Revision-Date: \n"
|
"PO-Revision-Date: \n"
|
||||||
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
"Last-Translator: Valentin Lorentz <progval@gmail.com>\n"
|
||||||
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
"Language-Team: Supybot-fr <progval@gmail.com>\n"
|
||||||
@ -41,6 +41,10 @@ msgid ""
|
|||||||
" unnecessary when you want all factoids for a given key."
|
" unnecessary when you want all factoids for a given key."
|
||||||
msgstr "Détermine si le bot répondra aux commandes invalides lors de la recherche d'une factoid ; permet simplement de rendre la commande 'whatis' inutile lorsque vous voulez toutes les factoids d'un clef donnée."
|
msgstr "Détermine si le bot répondra aux commandes invalides lors de la recherche d'une factoid ; permet simplement de rendre la commande 'whatis' inutile lorsque vous voulez toutes les factoids d'un clef donnée."
|
||||||
|
|
||||||
|
#: config.py:64
|
||||||
|
msgid "$key could be $value."
|
||||||
|
msgstr "$key semble être $value."
|
||||||
|
|
||||||
#: config.py:64
|
#: config.py:64
|
||||||
msgid ""
|
msgid ""
|
||||||
"Determines the format of\n"
|
"Determines the format of\n"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"POT-Creation-Date: 2010-10-17 10:59+CEST\n"
|
"POT-Creation-Date: 2010-11-11 12:37+CET\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -44,6 +44,10 @@ msgid ""
|
|||||||
" unnecessary when you want all factoids for a given key."
|
" unnecessary when you want all factoids for a given key."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: config.py:64
|
||||||
|
msgid "$key could be $value."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: config.py:64
|
#: config.py:64
|
||||||
msgid ""
|
msgid ""
|
||||||
"Determines the format of\n"
|
"Determines the format of\n"
|
||||||
|
@ -104,5 +104,5 @@ msgstr "Il n'y a pas de note pour %r"
|
|||||||
|
|
||||||
#: plugin.py:182
|
#: plugin.py:182
|
||||||
msgid "Sent %s: <%s> %s"
|
msgid "Sent %s: <%s> %s"
|
||||||
msgstr "Envoyé le %s : "
|
msgstr "Envoyé le %s : <%s> %s"
|
||||||
|
|
||||||
|
@ -69,11 +69,11 @@ msgstr "plugin"
|
|||||||
|
|
||||||
#: plugin.py:92
|
#: plugin.py:92
|
||||||
msgid "The %q command is available in the %L %s."
|
msgid "The %q command is available in the %L %s."
|
||||||
msgstr "La commande %q est disponibles dans le(s) plugin %v."
|
msgstr "La commande %q est disponibles dans le(s) plugin(s) %L%v."
|
||||||
|
|
||||||
#: plugin.py:95
|
#: plugin.py:95
|
||||||
msgid "There is no command %q."
|
msgid "There is no command %q."
|
||||||
msgstr "Il n'y a pas de commande q."
|
msgstr "Il n'y a pas de commande %q."
|
||||||
|
|
||||||
#: plugin.py:100
|
#: plugin.py:100
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -61,6 +61,7 @@ import textwrap
|
|||||||
started = time.time()
|
started = time.time()
|
||||||
|
|
||||||
import supybot
|
import supybot
|
||||||
|
import supybot.i18n as i18n
|
||||||
import supybot.utils as utils
|
import supybot.utils as utils
|
||||||
import supybot.registry as registry
|
import supybot.registry as registry
|
||||||
import supybot.questions as questions
|
import supybot.questions as questions
|
||||||
@ -178,6 +179,7 @@ if __name__ == '__main__':
|
|||||||
docs/GETTING_STARTED and follow the instructions."""))
|
docs/GETTING_STARTED and follow the instructions."""))
|
||||||
else:
|
else:
|
||||||
registryFilename = args.pop()
|
registryFilename = args.pop()
|
||||||
|
i18n.getLocaleFromRegistryFilename(registryFilename)
|
||||||
try:
|
try:
|
||||||
# The registry *MUST* be opened before importing log or conf.
|
# The registry *MUST* be opened before importing log or conf.
|
||||||
registry.open(registryFilename)
|
registry.open(registryFilename)
|
||||||
@ -210,6 +212,7 @@ if __name__ == '__main__':
|
|||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
import supybot.conf as conf
|
import supybot.conf as conf
|
||||||
import supybot.world as world
|
import supybot.world as world
|
||||||
|
i18n.import_conf()
|
||||||
world.starting = True
|
world.starting = True
|
||||||
|
|
||||||
def closeRegistry():
|
def closeRegistry():
|
||||||
|
@ -199,7 +199,7 @@ def getFloat(irc, msg, args, state, type=_('floating point number')):
|
|||||||
|
|
||||||
def getPositiveInt(irc, msg, args, state, *L):
|
def getPositiveInt(irc, msg, args, state, *L):
|
||||||
getInt(irc, msg, args, state,
|
getInt(irc, msg, args, state,
|
||||||
p=lambda i: i>0, type=_('positive integer') *L)
|
p=lambda i: i>0, type=_('positive integer'), *L)
|
||||||
|
|
||||||
def getNonNegativeInt(irc, msg, args, state, *L):
|
def getNonNegativeInt(irc, msg, args, state, *L):
|
||||||
getInt(irc, msg, args, state,
|
getInt(irc, msg, args, state,
|
||||||
|
72
src/i18n.py
72
src/i18n.py
@ -37,6 +37,7 @@ import re
|
|||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
|
conf = None
|
||||||
# Don't import conf here ; because conf needs this module
|
# Don't import conf here ; because conf needs this module
|
||||||
|
|
||||||
WAITING_FOR_MSGID = 1
|
WAITING_FOR_MSGID = 1
|
||||||
@ -47,16 +48,26 @@ IN_MSGSTR = 4
|
|||||||
MSGID = 'msgid "'
|
MSGID = 'msgid "'
|
||||||
MSGSTR = 'msgstr "'
|
MSGSTR = 'msgstr "'
|
||||||
|
|
||||||
|
currentLocale = 'en'
|
||||||
|
|
||||||
|
def getLocaleFromRegistryFilename(filename):
|
||||||
|
"""Called by the 'supybot' script. Gets the locale name before conf is
|
||||||
|
loaded."""
|
||||||
|
global currentLocale
|
||||||
|
for line in open(filename, 'r'):
|
||||||
|
if line.startswith('supybot.language: '):
|
||||||
|
currentLocale = line[len('supybot.language: '):]
|
||||||
|
|
||||||
def import_conf():
|
def import_conf():
|
||||||
import supybot.conf as conf
|
"""Imports the conf into this module"""
|
||||||
globals().update({'conf': conf})
|
global conf
|
||||||
|
conf = __import__('supybot.conf').conf
|
||||||
conf.registerGlobalValue(conf.supybot, 'language',
|
conf.registerGlobalValue(conf.supybot, 'language',
|
||||||
conf.registry.String('en', """Determines the bot's default language.
|
conf.registry.String(currentLocale, """Determines the bot's default
|
||||||
Valid values are things like en, fr, de, etc."""))
|
language. Valid values are things like en, fr, de, etc."""))
|
||||||
for key in i18nClasses:
|
|
||||||
i18nClasses[key].loadLocale()
|
|
||||||
|
|
||||||
def getPluginDir(plugin_name):
|
def getPluginDir(plugin_name):
|
||||||
|
"""Gets the directory of the given plugin"""
|
||||||
filename = None
|
filename = None
|
||||||
try:
|
try:
|
||||||
filename = sys.modules[plugin_name].__file__
|
filename = sys.modules[plugin_name].__file__
|
||||||
@ -74,6 +85,8 @@ def getPluginDir(plugin_name):
|
|||||||
return
|
return
|
||||||
|
|
||||||
def getLocalePath(name, localeName, extension):
|
def getLocalePath(name, localeName, extension):
|
||||||
|
"""Gets the path of the locale file of the given plugin ('supybot' stands
|
||||||
|
for the core)."""
|
||||||
if name != 'supybot':
|
if name != 'supybot':
|
||||||
directory = getPluginDir(name) + 'locale'
|
directory = getPluginDir(name) + 'locale'
|
||||||
else:
|
else:
|
||||||
@ -85,7 +98,15 @@ i18nClasses = {}
|
|||||||
internationalizedCommands = {}
|
internationalizedCommands = {}
|
||||||
internationalizedFunctions = [] # No need to know there name
|
internationalizedFunctions = [] # No need to know there name
|
||||||
|
|
||||||
def reloadLocals():
|
def reloadLocalesIfRequired():
|
||||||
|
global currentLocale
|
||||||
|
if conf is None:
|
||||||
|
return
|
||||||
|
if currentLocale != conf.supybot.language():
|
||||||
|
currentLocale = conf.supybot.language()
|
||||||
|
reloadLocales()
|
||||||
|
|
||||||
|
def reloadLocales():
|
||||||
for pluginName in i18nClasses:
|
for pluginName in i18nClasses:
|
||||||
i18nClasses[pluginName].loadLocale()
|
i18nClasses[pluginName].loadLocale()
|
||||||
for commandHash in internationalizedCommands:
|
for commandHash in internationalizedCommands:
|
||||||
@ -108,17 +129,12 @@ class _PluginInternationalization:
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.currentLocaleName = None
|
self.currentLocaleName = None
|
||||||
i18nClasses.update({name: self})
|
i18nClasses.update({name: self})
|
||||||
if name != 'supybot' and not 'conf' in globals():
|
|
||||||
# if conf is loadable but not loaded
|
|
||||||
import_conf()
|
|
||||||
self.loadLocale()
|
self.loadLocale()
|
||||||
|
|
||||||
def loadLocale(self, localeName=None):
|
def loadLocale(self, localeName=None):
|
||||||
"""(Re)loads the locale used by this class."""
|
"""(Re)loads the locale used by this class."""
|
||||||
if localeName is None and 'conf' in globals():
|
if localeName is None:
|
||||||
localeName = conf.supybot.language()
|
localeName = currentLocale
|
||||||
elif localeName is None:
|
|
||||||
localeName = 'en'
|
|
||||||
self.currentLocaleName = localeName
|
self.currentLocaleName = localeName
|
||||||
|
|
||||||
self._loadL10nCode()
|
self._loadL10nCode()
|
||||||
@ -179,14 +195,16 @@ class _PluginInternationalization:
|
|||||||
self._addToDatabase(untranslated, translated)
|
self._addToDatabase(untranslated, translated)
|
||||||
|
|
||||||
def _addToDatabase(self, untranslated, translated):
|
def _addToDatabase(self, untranslated, translated):
|
||||||
untranslated = self._unescape(untranslated)
|
untranslated = self._unescape(untranslated, True)
|
||||||
translated = self._unescape(translated)
|
translated = self._unescape(translated)
|
||||||
self.translations.update({untranslated: translated})
|
self.translations.update({untranslated: translated})
|
||||||
|
|
||||||
def _unescape(self, string):
|
def _unescape(self, string, removeNewline=False):
|
||||||
import supybot.utils as utils
|
import supybot.utils as utils
|
||||||
string = str.replace(string, '\\n', '\n') # gettext escapes the \n
|
string = str.replace(string, '\\n', '\n') # gettext escapes the \n
|
||||||
string = utils.str.normalizeWhitespace(string, removeNewline=False)
|
string = str.replace(string, '\\"', '"')
|
||||||
|
string = str.replace(string, "\'", "'")
|
||||||
|
string = utils.str.normalizeWhitespace(string, removeNewline)
|
||||||
return string
|
return string
|
||||||
|
|
||||||
def __call__(self, untranslated):
|
def __call__(self, untranslated):
|
||||||
@ -195,12 +213,8 @@ class _PluginInternationalization:
|
|||||||
his is the function which is called when a plugin runs _()"""
|
his is the function which is called when a plugin runs _()"""
|
||||||
if untranslated.__class__ == internationalizedString:
|
if untranslated.__class__ == internationalizedString:
|
||||||
return untranslated._original
|
return untranslated._original
|
||||||
untranslated = self._unescape(untranslated)
|
untranslated = self._unescape(untranslated, True)
|
||||||
if not 'conf' in globals():
|
reloadLocalesIfRequired()
|
||||||
return untranslated
|
|
||||||
if self.currentLocaleName != conf.supybot.language():
|
|
||||||
# If the locale has been changed
|
|
||||||
reloadLocals()
|
|
||||||
try:
|
try:
|
||||||
string = self._translate(untranslated)
|
string = self._translate(untranslated)
|
||||||
return self._addTracker(string, untranslated)
|
return self._addTracker(string, untranslated)
|
||||||
@ -304,8 +318,14 @@ def internationalizeDocstring(obj):
|
|||||||
"""Decorates functions and internationalize their docstring.
|
"""Decorates functions and internationalize their docstring.
|
||||||
|
|
||||||
Only useful for commands (commands' docstring is displayed on IRC)"""
|
Only useful for commands (commands' docstring is displayed on IRC)"""
|
||||||
|
if obj.__doc__ == None:
|
||||||
|
return obj
|
||||||
if sys.modules[obj.__module__].__dict__.has_key('_'):
|
if sys.modules[obj.__module__].__dict__.has_key('_'):
|
||||||
internationalizedCommands.update({hash(obj): obj})
|
internationalizedCommands.update({hash(obj): obj})
|
||||||
obj.__doc__=sys.modules[obj.__module__]._.__call__(obj.__doc__)
|
try:
|
||||||
# We use _.__call__() instead of _() because of a pygettext warning.
|
obj.__doc__=sys.modules[obj.__module__]._.__call__(obj.__doc__)
|
||||||
return obj
|
# We use _.__call__() instead of _() because of a pygettext warning.
|
||||||
|
except AttributeError:
|
||||||
|
# attribute '__doc__' of 'type' objects is not writable
|
||||||
|
pass
|
||||||
|
return obj
|
||||||
|
@ -360,7 +360,6 @@ class PluginTestCase(SupyTestCase):
|
|||||||
return
|
return
|
||||||
for cb in self.irc.callbacks:
|
for cb in self.irc.callbacks:
|
||||||
name = cb.name()
|
name = cb.name()
|
||||||
print " --- " + name
|
|
||||||
if ((name in self._noTestDoc) and \
|
if ((name in self._noTestDoc) and \
|
||||||
not name.lower() in self.__class__.__name__.lower()):
|
not name.lower() in self.__class__.__name__.lower()):
|
||||||
continue
|
continue
|
||||||
@ -372,12 +371,6 @@ class PluginTestCase(SupyTestCase):
|
|||||||
attr == callbacks.canonicalName(attr):
|
attr == callbacks.canonicalName(attr):
|
||||||
self.failUnless(getattr(cb, attr, None).__doc__,
|
self.failUnless(getattr(cb, attr, None).__doc__,
|
||||||
'%s.%s has no help.' % (name, attr))
|
'%s.%s has no help.' % (name, attr))
|
||||||
def testInternationalization(self):
|
|
||||||
name = self.__class__.__module__[0:-len('.test')]
|
|
||||||
if self.__class__.__module__.startswith('supybot'):
|
|
||||||
return
|
|
||||||
self.failIf(hasattr(sys.modules[name], '_') == False,
|
|
||||||
'%s has no internationalizer.' % name)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,16 +61,10 @@ def rsplit(s, sep=None, maxsplit=-1):
|
|||||||
|
|
||||||
def normalizeWhitespace(s, removeNewline=True):
|
def normalizeWhitespace(s, removeNewline=True):
|
||||||
"""Normalizes the whitespace in a string; \s+ becomes one space."""
|
"""Normalizes the whitespace in a string; \s+ becomes one space."""
|
||||||
beginning = s.startswith(' ')
|
|
||||||
ending = s.endswith(' ')
|
|
||||||
if removeNewline:
|
if removeNewline:
|
||||||
s = ' '.join(s.split())
|
s = str.replace(s, '\n', '')
|
||||||
else:
|
while ' ' in s:
|
||||||
s = ' '.join(s.split(' '))
|
s = str.replace(s, ' ', ' ')
|
||||||
if beginning:
|
|
||||||
s = ' ' + s
|
|
||||||
if ending:
|
|
||||||
s = s + ' '
|
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def distance(s, t):
|
def distance(s, t):
|
||||||
|
Loading…
Reference in New Issue
Block a user