diff options
| author | Barry Warsaw | 2011-03-16 12:32:42 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2011-03-16 12:32:42 -0400 |
| commit | 526ef44e83b876a1b9467ba511ec0d3c7d987d36 (patch) | |
| tree | 3ab98e48e5199de636fdd36ee4d30cee7cc052d7 /src/mailman/utilities/i18n.py | |
| parent | fd7c113707d9df9174957d2922d2d4484826145b (diff) | |
| download | mailman-526ef44e83b876a1b9467ba511ec0d3c7d987d36.tar.gz mailman-526ef44e83b876a1b9467ba511ec0d3c7d987d36.tar.zst mailman-526ef44e83b876a1b9467ba511ec0d3c7d987d36.zip | |
Diffstat (limited to 'src/mailman/utilities/i18n.py')
| -rw-r--r-- | src/mailman/utilities/i18n.py | 128 |
1 files changed, 126 insertions, 2 deletions
diff --git a/src/mailman/utilities/i18n.py b/src/mailman/utilities/i18n.py index 45262997b..a0f49a436 100644 --- a/src/mailman/utilities/i18n.py +++ b/src/mailman/utilities/i18n.py @@ -21,14 +21,138 @@ from __future__ import absolute_import, unicode_literals __metaclass__ = type __all__ = [ + 'TemplateNotFoundError', 'find', 'make', ] +import os +import errno + +from itertools import product + +from mailman.config import config +from mailman.core.constants import system_preferences + + -def find(): - pass +class TemplateNotFoundError(Exception): + """The named template was not found.""" + + def __init__(self, template_file): + self.template_file = template_file + + + +def _search(template_file, mailing_list=None, language=None): + """Generator that provides file system search order.""" + + languages = ['en', system_preferences.preferred_language.code] + if mailing_list is not None: + languages.append(mailing_list.preferred_language.code) + if language is not None: + languages.append(language) + languages.reverse() + # File system locations to search. + paths = [config.TEMPLATE_DIR, + os.path.join(config.TEMPLATE_DIR, 'site')] + if mailing_list is not None: + paths.append(os.path.join(config.TEMPLATE_DIR, + mailing_list.host_name)) + paths.append(os.path.join(config.LIST_DATA_DIR, + mailing_list.fqdn_listname)) + paths.reverse() + for language, path in product(languages, paths): + yield os.path.join(path, language, template_file) + + + +def find(template_file, mailing_list=None, language=None): + """Locate an i18n template file. + + When something in Mailman needs a template file, it always asks for the + file through this interface. The results of the search is path to the + 'matching' template, with the search order depending on whether + `mailing_list` and `language` are provided. + + When looking for a template in a specific language, there are 4 locations + that are searched, in this order: + + * The list-specific language directory + <var_dir>/lists/<fqdn_listname>/<language> + + * The domain-specific language directory + <template_dir>/<list-host-name>/<language> + + * The site-wide language directory + <template_dir>/site/<language> + + * The global default language directory + <template_dir>/<language> + + The first match stops the search. In this way, you can specialize + templates at the desired level, or if you only use the default templates, + you don't need to change anything. NEVER modify files in + <template_dir>/<language> since Mailman will overwrite these when you + upgrade. Instead you can use <template_dir>/site. + + The <language> path component is calculated as follows, in this order: + + * The `language` parameter if given + * `mailing_list.preferred_language` if given + * The server's default language + * English ('en') + + Languages are iterated after each of the four locations are searched. So + for example, when searching for the 'foo.txt' template, where the server's + default language is 'fr', the mailing list's (test@example.com) language + is 'de' and the `language` parameter is 'it', these locations are searched + in order: + + * <var_dir>/lists/test@example.com/it/foo.txt + * <template_dir>/example.com/it/foo.txt + * <template_dir>/site/it/foo.txt + * <template_dir>/it/foo.txt + + * <var_dir>/lists/test@example.com/de/foo.txt + * <template_dir>/example.com/de/foo.txt + * <template_dir>/site/de/foo.txt + * <template_dir>/de/foo.txt + + * <var_dir>/lists/test@example.com/fr/foo.txt + * <template_dir>/example.com/fr/foo.txt + * <template_dir>/site/fr/foo.txt + * <template_dir>/fr/foo.txt + + * <var_dir>/lists/test@example.com/en/foo.txt + * <template_dir>/example.com/en/foo.txt + * <template_dir>/site/en/foo.txt + * <template_dir>/en/foo.txt + + :param template_file: The name of the template file to search for. + :type template_file: string + :param mailing_list: Optional mailing list used as the context for + searching for the template file. The list's preferred language will + influence the search, as will the list's data directory. + :type mailing_list: `IMailingList` + :param language: Optional language code, which influences the search. + :type language: string + :return: A tuple of the file system path to the first matching template, + and an open file object allowing reading of the file. + :rtype: (string, file) + :raises TemplateNotFoundError: when the template could not be found. + """ + raw_search_order = _search(template_file, mailing_list, language) + for path in raw_search_order: + try: + fp = open(path) + except IOError as error: + if error.errno != errno.ENOENT: + raise + else: + return path, fp + raise TemplateNotFoundError(template_file) def make(): |
