From: Michael Tremer Date: Mon, 26 Oct 2015 15:49:12 +0000 (+0100) Subject: Add code to localise graph templates X-Git-Tag: 004~32 X-Git-Url: http://git.ipfire.org/?p=collecty.git;a=commitdiff_plain;h=429ba5063a678ea008e23340a755759844771e85 Add code to localise graph templates Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 0b7e299..34a26d2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -79,6 +79,7 @@ collecty_PYTHON = \ src/collecty/daemon.py \ src/collecty/errors.py \ src/collecty/i18n.py \ + src/collecty/locales.py \ src/collecty/logger.py collectydir = $(pythondir)/collecty diff --git a/src/collecty/daemon.py b/src/collecty/daemon.py index eb64571..27c587f 100644 --- a/src/collecty/daemon.py +++ b/src/collecty/daemon.py @@ -29,6 +29,7 @@ import threading import time from . import bus +from . import locales from . import plugins from .constants import * @@ -80,6 +81,8 @@ class Collecty(object): log.debug(_("Collecty successfully initialized with %s plugins") \ % len(self.plugins)) + log.debug(_("Supported locales: %s") % ", ".join(locales.get_supported_locales())) + def add_plugin(self, plugin_class): # Try initialising a new plugin. If that fails, we will log the # error and try to go on. diff --git a/src/collecty/locales.py b/src/collecty/locales.py new file mode 100644 index 0000000..199ab49 --- /dev/null +++ b/src/collecty/locales.py @@ -0,0 +1,124 @@ +#!/usr/bin/python3 +############################################################################### +# # +# collecty - A system statistics collection daemon for IPFire # +# Copyright (C) 2015 IPFire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +import gettext +import os + +from .constants import * +from .i18n import TEXTDOMAIN + +import logging +log = logging.getLogger("collecty.locale") +log.propagate = 1 + +class Locale(object): + def __init__(self, lang): + self.lang = lang + + def translate(self, message, plural_message=None, count=None): + if plural_message is not None: + assert count is not None + + # Replace the message by the plural message if + # we are using plural. + if count > 1: + message = plural_message + + return message + + +class GettextLocale(Locale): + def __init__(self, lang, translation): + Locale.__init__(self, lang) + + self.translation = translation + + # Bind gettext functions + self.gettext = self.translation.gettext + self.ngettext = self.translation.ngettext + + def translate(self, message, plural_message=None, count=None): + if plural_message is not None: + assert count is not None + return self.ngettext(message, plural_message, count) + + return self.gettext(message) + + +def _find_all_locales(domain, directory): + locales = { + DEFAULT_LOCALE : Locale(DEFAULT_LOCALE), + } + + for lang in os.listdir(directory): + if lang.startswith("."): + continue + + filename = os.path.join(directory, lang, "LC_MESSAGES", + "%s.mo" % domain) + + # Check if a translation file exists and go on if not + if not os.path.exists(filename): + continue + + try: + translation = gettext.translation(domain, + directory, languages=[lang]) + except Exception as e: + log.error("Cound not load translation for %s: %s" \ + % (lang, e)) + continue + + locales[lang] = GettextLocale(lang, translation) + + log.debug("Loaded translations: %s" % ", ".join(locales.keys())) + + return locales + +_locales = _find_all_locales(TEXTDOMAIN, "/usr/share/locale") + +def get_supported_locales(): + return list(_locales.keys()) + +def get_closest(*langs): + for lang in langs: + if not lang: + continue + + lang = lang.replace("-", "_") + parts = lang.split("_") + + if len(parts) > 2: + continue + + elif len(parts) == 2: + parts[0] = parts[0].lower() + parts[1] = parts[1].upper() + lang = "_".join(parts) + + for l in (lang, parts[0]): + try: + return _locales[l] + except KeyError: + pass + +def get(*langs): + return get_closest(*langs) or _locale.get(DEFAULT_LOCALE, None) diff --git a/src/collecty/plugins/base.py b/src/collecty/plugins/base.py index ecf1af7..c9e815c 100644 --- a/src/collecty/plugins/base.py +++ b/src/collecty/plugins/base.py @@ -29,6 +29,7 @@ import threading import time import unicodedata +from .. import locales from ..constants import * from ..i18n import _ @@ -230,15 +231,17 @@ class Plugin(object, metaclass=PluginRegistration): return object - def get_template(self, template_name, object_id): + def get_template(self, template_name, object_id, locale=None, timezone=None): for template in self.templates: if not template.name == template_name: continue - return template(self, object_id) + return template(self, object_id, locale=locale, timezone=timezone) - def generate_graph(self, template_name, object_id="default", **kwargs): - template = self.get_template(template_name, object_id=object_id) + def generate_graph(self, template_name, object_id="default", + timezone=None, locale=None, **kwargs): + template = self.get_template(template_name, object_id=object_id, + timezone=timezone, locale=locale) if not template: raise RuntimeError("Could not find template %s" % template_name) @@ -436,9 +439,13 @@ class GraphTemplate(object): height = GRAPH_DEFAULT_HEIGHT width = GRAPH_DEFAULT_WIDTH - def __init__(self, plugin, object_id): + def __init__(self, plugin, object_id, locale=None, timezone=None): self.plugin = plugin + # Save localisation parameters + self.locale = locales.get(locale) + self.timezone = timezone + # Get all required RRD objects self.object_id = object_id @@ -521,7 +528,7 @@ class GraphTemplate(object): return files - def generate_graph(self, interval=None, timezone=None, locale=None, **kwargs): + def generate_graph(self, interval=None, **kwargs): args = self._make_command_line(interval, **kwargs) self.log.info(_("Generating graph %s") % self) @@ -540,7 +547,7 @@ class GraphTemplate(object): # Convert arguments to string args = [str(e) for e in args] - with Environment(timezone, locale): + with Environment(self.timezone, self.locale.lang): graph = rrdtool.graphv("-", *args) return graph.get("image")