From b908ff5821d9e52caa694319e0c473313412fe63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Mon, 11 May 2015 18:43:26 +0200 Subject: [PATCH] Enhanced flask-babel to also allow plugins to provide translated strings This way plugins can maintain their own translations of their UIs. Some monkey patching was necessary, not the cleanest solution but it should work. --- src/octoprint/server/__init__.py | 1 + src/octoprint/server/util/flask.py | 53 ++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py index 3f0d9d44..9a298328 100644 --- a/src/octoprint/server/__init__.py +++ b/src/octoprint/server/__init__.py @@ -59,6 +59,7 @@ import octoprint.slicing from . import util util.tornado.fix_ioloop_scheduling() +util.flask.enable_plugin_translations() UI_API_KEY = ''.join('%02X' % ord(z) for z in uuid.uuid4().bytes) diff --git a/src/octoprint/server/util/flask.py b/src/octoprint/server/util/flask.py index fd3174f8..5dc90cf4 100644 --- a/src/octoprint/server/util/flask.py +++ b/src/octoprint/server/util/flask.py @@ -24,6 +24,59 @@ import octoprint.users from werkzeug.contrib.cache import SimpleCache +#~~ monkey patching + +def enable_plugin_translations(): + import os + from flask import _request_ctx_stack + from babel import support + import flask.ext.babel + + import octoprint.plugin + + def fixed_get_translations(): + """Returns the correct gettext translations that should be used for + this request. This will never fail and return a dummy translation + object if used outside of the request or if a translation cannot be + found. + """ + logger = logging.getLogger(__name__) + + ctx = _request_ctx_stack.top + if ctx is None: + return None + translations = getattr(ctx, 'babel_translations', None) + if translations is None: + locale = flask.ext.babel.get_locale() + + plugins = octoprint.plugin.plugin_manager().enabled_plugins + for name, plugin in plugins.items(): + dirname = os.path.join(plugin.location, 'translations') + if not os.path.isdir(dirname): + continue + + try: + plugin_translations = support.Translations.load(dirname, [locale]) + except: + logger.exception("Error while trying to load translations for plugin {name}".format(**locals())) + else: + if translations is None: + translations = plugin_translations + else: + translations = translations.merge(plugin_translations) + + dirname = os.path.join(ctx.app.root_path, 'translations') + core_translations = support.Translations.load(dirname, [locale]) + if translations is None: + translations = core_translations + else: + translations = translations.merge(core_translations) + + ctx.babel_translations = translations + return translations + + flask.ext.babel.get_translations = fixed_get_translations + #~~ passive login helper def passive_login():