diff --git a/scripts/supybot b/scripts/supybot index ec9b7ecfe..dac2fad3c 100644 --- a/scripts/supybot +++ b/scripts/supybot @@ -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(): diff --git a/src/i18n.py b/src/i18n.py index f9e7db086..0cbd573bb 100644 --- a/src/i18n.py +++ b/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) diff --git a/src/utils/str.py b/src/utils/str.py index 23dbeff99..033547c2c 100644 --- a/src/utils/str.py +++ b/src/utils/str.py @@ -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):