summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mailman/Utils.py2
-rw-r--r--src/mailman/config/config.py13
-rw-r--r--src/mailman/docs/languages.txt109
-rw-r--r--src/mailman/interfaces/languages.py72
-rw-r--r--src/mailman/languages.py67
-rw-r--r--src/mailman/languages/__init__.py0
-rw-r--r--src/mailman/languages/manager.py70
-rw-r--r--src/mailman/queue/docs/digester.txt2
8 files changed, 162 insertions, 173 deletions
diff --git a/src/mailman/Utils.py b/src/mailman/Utils.py
index 509537b1e..74582a7ad 100644
--- a/src/mailman/Utils.py
+++ b/src/mailman/Utils.py
@@ -488,7 +488,7 @@ def maketext(templatefile, dict=None, raw=False, lang=None, mlist=None):
# XXX Replace this with direct calls. For now, existing uses of GetCharSet()
# are too numerous to change.
def GetCharSet(lang):
- return config.languages.get_charset(lang)
+ return config.languages[lang].charset
diff --git a/src/mailman/config/config.py b/src/mailman/config/config.py
index fa359a6f5..4af4ada4e 100644
--- a/src/mailman/config/config.py
+++ b/src/mailman/config/config.py
@@ -37,7 +37,7 @@ from pkg_resources import resource_string
from mailman import version
from mailman.core import errors
from mailman.domain import Domain
-from mailman.languages import LanguageManager
+from mailman.languages.manager import LanguageManager
from mailman.styles.manager import StyleManager
from mailman.utilities.filesystem import makedirs
@@ -147,11 +147,12 @@ class Configuration(object):
# Set up all the languages.
languages = self._config.getByCategory('language', [])
for language in languages:
- code = language.name.split('.')[1]
- self.languages.add_language(code, language.description,
- language.charset, language.enabled)
- # Always enable the server default language, which must be defined.
- self.languages.enable_language(self._config.mailman.default_language)
+ if language.enabled:
+ code = language.name.split('.')[1]
+ self.languages.add_language(
+ code, language.charset, language.description)
+ # The default language must always be available.
+ assert self._config.mailman.default_language in self.languages
self.ensure_directories_exist()
self.style_manager.populate()
diff --git a/src/mailman/docs/languages.txt b/src/mailman/docs/languages.txt
index 775b933e8..a429345a5 100644
--- a/src/mailman/docs/languages.txt
+++ b/src/mailman/docs/languages.txt
@@ -5,33 +5,20 @@ Mailman is multilingual. A language manager handles the known set of
languages at run time, as well as enabling those languages for use in a
running Mailman instance.
- >>> from zope.interface.verify import verifyObject
>>> from mailman.interfaces.languages import ILanguageManager
- >>> from mailman.languages import LanguageManager
+ >>> from mailman.languages.manager import LanguageManager
+ >>> from zope.interface.verify import verifyObject
>>> mgr = LanguageManager()
>>> verifyObject(ILanguageManager, mgr)
True
-A language manager keeps track of the languages it knows about as well as the
-languages which are enabled. By default, none are known or enabled.
+A language manager keeps track of the languages it knows about.
- >>> sorted(mgr.known_codes)
+ >>> list(mgr.codes)
[]
- >>> sorted(mgr.enabled_codes)
+ >>> list(mgr.languages)
[]
-The language manager also keeps track of information for each known language,
-but you obviously can't get information for an unknown language.
-
- >>> mgr.get_description('en')
- Traceback (most recent call last):
- ...
- KeyError: 'en'
- >>> mgr.get_charset('en')
- Traceback (most recent call last):
- ...
- KeyError: 'en'
-
Adding languages
----------------
@@ -40,65 +27,59 @@ Adding a new language requires three pieces of information, the 2-character
language code, the English description of the language, and the character set
used by the language.
- >>> mgr.add_language('en', 'English', 'us-ascii')
- >>> mgr.add_language('it', 'Italian', 'iso-8859-1')
+ >>> mgr.add_language('en', 'us-ascii', 'English')
+ >>> mgr.add_language('it', 'iso-8859-1', 'Italian')
-By default, added languages are also enabled.
+And you can get information for all known languages.
- >>> sorted(mgr.known_codes)
- ['en', 'it']
- >>> sorted(mgr.enabled_codes)
- ['en', 'it']
+ >>> print mgr['en'].description
+ English
+ >>> print mgr['en'].charset
+ us-ascii
+ >>> print mgr['it'].description
+ Italian
+ >>> print mgr['it'].charset
+ iso-8859-1
-And you can get information for all known languages.
- >>> mgr.get_description('en')
- 'English'
- >>> mgr.get_charset('en')
- 'us-ascii'
- >>> mgr.get_description('it')
- 'Italian'
- >>> mgr.get_charset('it')
- 'iso-8859-1'
+Other iterations
+----------------
-You can also add a language without enabling it.
+You can iterate over all the known language codes.
- >>> mgr.add_language('pl', 'Polish', 'iso-8859-2', enable=False)
- >>> sorted(mgr.known_codes)
+ >>> mgr.add_language('pl', 'iso-8859-2', 'Polish')
+ >>> sorted(mgr.codes)
['en', 'it', 'pl']
- >>> sorted(mgr.enabled_codes)
- ['en', 'it']
-You can get language data for disabled languages.
+You can iterate over all the known languages.
- >>> mgr.get_description('pl')
- 'Polish'
- >>> mgr.get_charset('pl')
- 'iso-8859-2'
+ >>> from operator import attrgetter
+ >>> languages = sorted((language for language in mgr.languages),
+ ... key=attrgetter('code'))
+ >>> for language in languages:
+ ... print language.code, language.charset, language.description
+ en us-ascii English
+ it iso-8859-1 Italian
+ pl iso-8859-2 Polish
-And of course you can enable a known language.
+You can ask whether a particular language code is known.
- >>> mgr.enable_language('pl')
- >>> sorted(mgr.enabled_codes)
- ['en', 'it', 'pl']
+ >>> 'it' in mgr
+ True
+ >>> 'xx' in mgr
+ False
-But you cannot enable languages that the manager does not know about.
+You can get a particular language by its code.
- >>> mgr.enable_language('xx')
+ >>> print mgr['it'].description
+ Italian
+ >>> print mgr['xx'].code
Traceback (most recent call last):
...
KeyError: 'xx'
-
-
-Other iterations
-----------------
-
-You can iterate over the descriptions (names) of all enabled languages.
-
- >>> sorted(mgr.enabled_names)
- ['English', 'Italian', 'Polish']
-
-You can ask whether a particular language code is enabled.
-
- >>> 'it' in mgr.enabled_codes
- True
+ >>> print mgr.get('it').description
+ Italian
+ >>> print mgr.get('xx')
+ None
+ >>> print mgr.get('xx', 'missing')
+ missing
diff --git a/src/mailman/interfaces/languages.py b/src/mailman/interfaces/languages.py
index 272cf4372..a41a6e80e 100644
--- a/src/mailman/interfaces/languages.py
+++ b/src/mailman/interfaces/languages.py
@@ -30,60 +30,66 @@ from zope.interface import Interface, Attribute
+class ILanguage(Interface):
+ """The representation of a language."""
+
+ code = Attribute('The 2-character language code.')
+
+ charset = Attribute('The character set or encoding for this language.')
+
+ description = Attribute("The language's description.")
+
+
+
class ILanguageManager(Interface):
"""A language manager.
Current, disabling languages is not supported.
"""
- def add_language(code, description, charset, enable=True):
+ def add_language(code, charset, description):
"""Teach the language manager about a language.
:param code: The short two-character language code for the
language. If the language manager already knows about this code,
the old language binding is lost.
- :param description: The English description of the language,
- e.g. 'English' or 'French'.
+ :type code: string
:param charset: The character set that the language uses,
e.g. 'us-ascii', 'iso-8859-1', or 'utf-8'
- :param enable: Enable the language at the same time.
+ :type charset: string
+ :param description: The English description of the language,
+ e.g. 'English' or 'French'.
+ :type description: string
"""
- def enable_language(code):
- """Enable a language that the manager already knows about.
+ codes = Attribute('An iterator over all known codes.')
- :raises KeyError: when the manager does not know about the given
- language code.
- """
+ languages = Attribute('An iterator of all the languages.')
- def get_description(code):
- """Return the language description for the given code.
+ def __getitem__(code):
+ """Return the language associated with the language code.
- :param code: The two letter language code to look up.
- :returns: The English description of the language.
- :raises KeyError: when the code has not been added.
+ :param code: The 2-letter language code.
+ :type code: string
+ :return: The language instance.
+ :rtype: `ILanguage`
+ :raises KeyError: if code is not associated with a known language.
"""
- def get_charset(code):
- """Return the character set for the given code.
+ def get(code, default=None):
+ """Return the language associated with the language code.
- :param code: The two letter language code to look up.
- :returns: The character set of the language.
- :raises KeyError: when the code has not been added.
+ :param code: The 2-letter language code.
+ :type code: string
+ :param default: The value to return if the code is not known.
+ :type default: anything
+ :return: The language instance or `default`.
+ :rtype: `ILanguage` or `default`
"""
- known_codes = Attribute(
- """An iterator over all known codes.""")
-
- enabled_codes = Attribute(
- """An iterator over all enabled codes.""")
-
- enabled_names = Attribute(
- """An iterator over all enabled language names.""")
-
+ def __contains__(code):
+ """True if the language code is known.
-
-class ILanguage(Interface):
- """The representation of a language."""
-
- code = Attribute("""The 2-character language code.""")
+ :return: A flag indicating whether the language code is known or not.
+ :rtype: bool
+ """
diff --git a/src/mailman/languages.py b/src/mailman/languages.py
deleted file mode 100644
index 7e093bc62..000000000
--- a/src/mailman/languages.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (C) 2007-2009 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman 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.
-#
-# GNU Mailman 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
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Language manager."""
-
-from __future__ import unicode_literals
-
-__metaclass__ = type
-__all__ = [
- 'LanguageManager',
- ]
-
-from zope.interface import implements
-from mailman.interfaces.languages import ILanguageManager
-
-
-
-class LanguageManager:
- implements(ILanguageManager)
-
- def __init__(self):
- self._language_data = {}
- self._enabled = set()
-
- def add_language(self, code, description, charset, enable=True):
- self._language_data[code] = (description, charset)
- if enable:
- self._enabled.add(code)
-
- def enable_language(self, code):
- if code not in self._language_data:
- raise KeyError(code)
- self._enabled.add(code)
-
- def get_description(self, code):
- return self._language_data[code][0]
-
- def get_charset(self, code):
- return self._language_data[code][1]
-
- @property
- def known_codes(self):
- return iter(self._language_data)
-
- @property
- def enabled_codes(self):
- return iter(self._enabled)
-
- @property
- def enabled_names(self):
- for code in self._enabled:
- description, charset = self._language_data[code]
- yield description
diff --git a/src/mailman/languages/__init__.py b/src/mailman/languages/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/mailman/languages/__init__.py
diff --git a/src/mailman/languages/manager.py b/src/mailman/languages/manager.py
new file mode 100644
index 000000000..a5a3d02f2
--- /dev/null
+++ b/src/mailman/languages/manager.py
@@ -0,0 +1,70 @@
+# Copyright (C) 2007-2009 by the Free Software Foundation, Inc.
+#
+# This file is part of GNU Mailman.
+#
+# GNU Mailman 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.
+#
+# GNU Mailman 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
+# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
+
+"""Language manager."""
+
+from __future__ import absolute_import, unicode_literals
+
+__metaclass__ = type
+__all__ = [
+ 'LanguageManager',
+ ]
+
+from zope.interface import implements
+
+from mailman.interfaces.languages import ILanguageManager
+from mailman.languages.language import Language
+
+
+
+class LanguageManager:
+ """Language manager."""
+
+ implements(ILanguageManager)
+
+ def __init__(self):
+ # Mapping from 2-letter code to Language instance.
+ self._languages = {}
+
+ def add_language(self, code, charset, description):
+ """See `ILanguageManager`."""
+ if code in self._languages:
+ raise ValueError('Language code already registered: ' + code)
+ language = Language(code, charset, description)
+ self._languages[code] = language
+
+ @property
+ def codes(self):
+ """See `ILanguageManager`."""
+ return iter(self._languages)
+
+ @property
+ def languages(self):
+ """See `ILanguageManager`."""
+ return iter(self._languages.values())
+
+ def get(self, code, default=None):
+ """See `ILanguageManager`."""
+ return self._languages.get(code, default)
+
+ def __getitem__(self, code):
+ """See `ILanguageManager`."""
+ return self._languages[code]
+
+ def __contains__(self, code):
+ """See `ILanguageManager`."""
+ return code in self._languages
diff --git a/src/mailman/queue/docs/digester.txt b/src/mailman/queue/docs/digester.txt
index c9aa79a06..57e80317c 100644
--- a/src/mailman/queue/docs/digester.txt
+++ b/src/mailman/queue/docs/digester.txt
@@ -274,8 +274,6 @@ When messages come in with a content-type character set different than that of
the list's preferred language, recipients will get an internationalized
digest. French is not enabled by default site-wide, so enable that now.
- >>> config.languages.enable_language('fr')
-
# Simulate the site administrator setting the default server language to
# French in the configuration file. Without this, the English template
# will be found and the masthead won't be translated.