mirror of https://github.com/Mikaela/Limnoria.git
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',
|
||||
'pou']:
|
||||
return s + 'x'
|
||||
elif lowered.endwith('al') and \
|
||||
elif lowered.endswith('al') and \
|
||||
lowered not in ['bal', 'carnaval', 'chacal', 'festival', 'récital',
|
||||
'régal', 'cal', 'étal', 'aval', 'caracal', 'val', 'choral',
|
||||
'corral', 'galgal', 'gayal']:
|
||||
|
@ -53,7 +53,7 @@ def pluralize(s):
|
|||
return s + 'x'
|
||||
elif lowered == 'pare-feu':
|
||||
return s
|
||||
elif lowered.endwith('eu') and \
|
||||
elif lowered.endswith('eu') and \
|
||||
lowered not in ['bleu', 'pneu', 'émeu', 'enfeu']:
|
||||
# Note: when 'lieu' is a fish, it has a 's' ; else, it has a 'x'
|
||||
return s + 'x'
|
||||
|
|
|
@ -61,7 +61,7 @@ conf.registerChannelValue(Factoids, 'replyWhenInvalidCommand',
|
|||
commands by searching for a factoid; basically making the whatis
|
||||
unnecessary when you want all factoids for a given key.""")))
|
||||
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
|
||||
substitutes apply, in addition to "$key" for the factoid's key and "$value"
|
||||
for the factoid's value.""")))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"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"
|
||||
"Last-Translator: Valentin Lorentz <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."
|
||||
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
|
||||
msgid ""
|
||||
"Determines the format of\n"
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"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"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -44,6 +44,10 @@ msgid ""
|
|||
" unnecessary when you want all factoids for a given key."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:64
|
||||
msgid "$key could be $value."
|
||||
msgstr ""
|
||||
|
||||
#: config.py:64
|
||||
msgid ""
|
||||
"Determines the format of\n"
|
||||
|
|
|
@ -104,5 +104,5 @@ msgstr "Il n'y a pas de note pour %r"
|
|||
|
||||
#: plugin.py:182
|
||||
msgid "Sent %s: <%s> %s"
|
||||
msgstr "Envoyé le %s : "
|
||||
msgstr "Envoyé le %s : <%s> %s"
|
||||
|
||||
|
|
|
@ -69,11 +69,11 @@ msgstr "plugin"
|
|||
|
||||
#: plugin.py:92
|
||||
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
|
||||
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
|
||||
msgid ""
|
||||
|
|
|
@ -61,6 +61,7 @@ import textwrap
|
|||
started = time.time()
|
||||
|
||||
import supybot
|
||||
import supybot.i18n as i18n
|
||||
import supybot.utils as utils
|
||||
import supybot.registry as registry
|
||||
import supybot.questions as questions
|
||||
|
@ -178,6 +179,7 @@ if __name__ == '__main__':
|
|||
docs/GETTING_STARTED and follow the instructions."""))
|
||||
else:
|
||||
registryFilename = args.pop()
|
||||
i18n.getLocaleFromRegistryFilename(registryFilename)
|
||||
try:
|
||||
# The registry *MUST* be opened before importing log or conf.
|
||||
registry.open(registryFilename)
|
||||
|
@ -210,6 +212,7 @@ if __name__ == '__main__':
|
|||
sys.exit(-1)
|
||||
import supybot.conf as conf
|
||||
import supybot.world as world
|
||||
i18n.import_conf()
|
||||
world.starting = True
|
||||
|
||||
def closeRegistry():
|
||||
|
|
|
@ -199,7 +199,7 @@ def getFloat(irc, msg, args, state, type=_('floating point number')):
|
|||
|
||||
def getPositiveInt(irc, msg, args, state, *L):
|
||||
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):
|
||||
getInt(irc, msg, args, state,
|
||||
|
|
66
src/i18n.py
66
src/i18n.py
|
@ -37,6 +37,7 @@ import re
|
|||
import sys
|
||||
import time
|
||||
import threading
|
||||
conf = None
|
||||
# Don't import conf here ; because conf needs this module
|
||||
|
||||
WAITING_FOR_MSGID = 1
|
||||
|
@ -47,16 +48,26 @@ IN_MSGSTR = 4
|
|||
MSGID = 'msgid "'
|
||||
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():
|
||||
import supybot.conf as conf
|
||||
globals().update({'conf': conf})
|
||||
"""Imports the conf into this module"""
|
||||
global conf
|
||||
conf = __import__('supybot.conf').conf
|
||||
conf.registerGlobalValue(conf.supybot, 'language',
|
||||
conf.registry.String('en', """Determines the bot's default language.
|
||||
Valid values are things like en, fr, de, etc."""))
|
||||
for key in i18nClasses:
|
||||
i18nClasses[key].loadLocale()
|
||||
conf.registry.String(currentLocale, """Determines the bot's default
|
||||
language. Valid values are things like en, fr, de, etc."""))
|
||||
|
||||
def getPluginDir(plugin_name):
|
||||
"""Gets the directory of the given plugin"""
|
||||
filename = None
|
||||
try:
|
||||
filename = sys.modules[plugin_name].__file__
|
||||
|
@ -74,6 +85,8 @@ def getPluginDir(plugin_name):
|
|||
return
|
||||
|
||||
def getLocalePath(name, localeName, extension):
|
||||
"""Gets the path of the locale file of the given plugin ('supybot' stands
|
||||
for the core)."""
|
||||
if name != 'supybot':
|
||||
directory = getPluginDir(name) + 'locale'
|
||||
else:
|
||||
|
@ -85,7 +98,15 @@ i18nClasses = {}
|
|||
internationalizedCommands = {}
|
||||
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:
|
||||
i18nClasses[pluginName].loadLocale()
|
||||
for commandHash in internationalizedCommands:
|
||||
|
@ -108,17 +129,12 @@ class _PluginInternationalization:
|
|||
self.name = name
|
||||
self.currentLocaleName = None
|
||||
i18nClasses.update({name: self})
|
||||
if name != 'supybot' and not 'conf' in globals():
|
||||
# if conf is loadable but not loaded
|
||||
import_conf()
|
||||
self.loadLocale()
|
||||
|
||||
def loadLocale(self, localeName=None):
|
||||
"""(Re)loads the locale used by this class."""
|
||||
if localeName is None and 'conf' in globals():
|
||||
localeName = conf.supybot.language()
|
||||
elif localeName is None:
|
||||
localeName = 'en'
|
||||
if localeName is None:
|
||||
localeName = currentLocale
|
||||
self.currentLocaleName = localeName
|
||||
|
||||
self._loadL10nCode()
|
||||
|
@ -179,14 +195,16 @@ class _PluginInternationalization:
|
|||
self._addToDatabase(untranslated, translated)
|
||||
|
||||
def _addToDatabase(self, untranslated, translated):
|
||||
untranslated = self._unescape(untranslated)
|
||||
untranslated = self._unescape(untranslated, True)
|
||||
translated = self._unescape(translated)
|
||||
self.translations.update({untranslated: translated})
|
||||
|
||||
def _unescape(self, string):
|
||||
def _unescape(self, string, removeNewline=False):
|
||||
import supybot.utils as utils
|
||||
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
|
||||
|
||||
def __call__(self, untranslated):
|
||||
|
@ -195,12 +213,8 @@ class _PluginInternationalization:
|
|||
his is the function which is called when a plugin runs _()"""
|
||||
if untranslated.__class__ == internationalizedString:
|
||||
return untranslated._original
|
||||
untranslated = self._unescape(untranslated)
|
||||
if not 'conf' in globals():
|
||||
return untranslated
|
||||
if self.currentLocaleName != conf.supybot.language():
|
||||
# If the locale has been changed
|
||||
reloadLocals()
|
||||
untranslated = self._unescape(untranslated, True)
|
||||
reloadLocalesIfRequired()
|
||||
try:
|
||||
string = self._translate(untranslated)
|
||||
return self._addTracker(string, untranslated)
|
||||
|
@ -304,8 +318,14 @@ def internationalizeDocstring(obj):
|
|||
"""Decorates functions and internationalize their docstring.
|
||||
|
||||
Only useful for commands (commands' docstring is displayed on IRC)"""
|
||||
if obj.__doc__ == None:
|
||||
return obj
|
||||
if sys.modules[obj.__module__].__dict__.has_key('_'):
|
||||
internationalizedCommands.update({hash(obj): obj})
|
||||
try:
|
||||
obj.__doc__=sys.modules[obj.__module__]._.__call__(obj.__doc__)
|
||||
# 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
|
||||
for cb in self.irc.callbacks:
|
||||
name = cb.name()
|
||||
print " --- " + name
|
||||
if ((name in self._noTestDoc) and \
|
||||
not name.lower() in self.__class__.__name__.lower()):
|
||||
continue
|
||||
|
@ -372,12 +371,6 @@ class PluginTestCase(SupyTestCase):
|
|||
attr == callbacks.canonicalName(attr):
|
||||
self.failUnless(getattr(cb, attr, None).__doc__,
|
||||
'%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):
|
||||
"""Normalizes the whitespace in a string; \s+ becomes one space."""
|
||||
beginning = s.startswith(' ')
|
||||
ending = s.endswith(' ')
|
||||
if removeNewline:
|
||||
s = ' '.join(s.split())
|
||||
else:
|
||||
s = ' '.join(s.split(' '))
|
||||
if beginning:
|
||||
s = ' ' + s
|
||||
if ending:
|
||||
s = s + ' '
|
||||
s = str.replace(s, '\n', '')
|
||||
while ' ' in s:
|
||||
s = str.replace(s, ' ', ' ')
|
||||
return s
|
||||
|
||||
def distance(s, t):
|
||||
|
|
Loading…
Reference in New Issue