summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAurélien Bompard2013-10-08 15:45:36 +0200
committerAurélien Bompard2013-10-08 15:45:36 +0200
commit228e1c57fb79411381fc0da3bcbd69fbaf3cbf9a (patch)
tree451129a6eec5280f662290d40ad019f45236c00b /src
parent004915c1fa7eaa8957101d41eeef0c48ff621eeb (diff)
downloadmailman-228e1c57fb79411381fc0da3bcbd69fbaf3cbf9a.tar.gz
mailman-228e1c57fb79411381fc0da3bcbd69fbaf3cbf9a.tar.zst
mailman-228e1c57fb79411381fc0da3bcbd69fbaf3cbf9a.zip
Diffstat (limited to 'src')
-rw-r--r--src/mailman/commands/cli_import.py8
-rw-r--r--src/mailman/utilities/importer.py34
-rw-r--r--src/mailman/utilities/tests/test_import.py39
3 files changed, 76 insertions, 5 deletions
diff --git a/src/mailman/commands/cli_import.py b/src/mailman/commands/cli_import.py
index c8145429d..880457334 100644
--- a/src/mailman/commands/cli_import.py
+++ b/src/mailman/commands/cli_import.py
@@ -35,7 +35,7 @@ from mailman.core.i18n import _
from mailman.database.transaction import transactional
from mailman.interfaces.command import ICLISubCommand
from mailman.interfaces.listmanager import IListManager
-from mailman.utilities.importer import import_config_pck
+from mailman.utilities.importer import import_config_pck, Import21Error
@@ -93,4 +93,8 @@ class Import21:
print(_('Ignoring non-dictionary: {0!r}').format(
config_dict), file=sys.stderr)
continue
- import_config_pck(mlist, config_dict)
+ try:
+ import_config_pck(mlist, config_dict)
+ except Import21Error, e:
+ print(e, file=sys.stderr)
+ sys.exit(1)
diff --git a/src/mailman/utilities/importer.py b/src/mailman/utilities/importer.py
index 9ada4c75e..dcdc0e4c3 100644
--- a/src/mailman/utilities/importer.py
+++ b/src/mailman/utilities/importer.py
@@ -22,6 +22,7 @@ from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
'import_config_pck',
+ 'ImportError',
]
@@ -31,6 +32,7 @@ import os
from urllib2 import URLError
from mailman.config import config
+from mailman.core.errors import MailmanError
from mailman.interfaces.action import FilterAction, Action
from mailman.interfaces.autorespond import ResponseAction
from mailman.interfaces.digests import DigestFrequency
@@ -42,12 +44,17 @@ from mailman.interfaces.mailinglist import IAcceptableAliasSet
from mailman.interfaces.bounce import UnrecognizedBounceDisposition
from mailman.interfaces.usermanager import IUserManager
from mailman.interfaces.member import DeliveryMode, DeliveryStatus, MemberRole
+from mailman.interfaces.languages import ILanguageManager
from mailman.handlers.decorate import decorate, decorate_template
from mailman.utilities.i18n import search
from zope.component import getUtility
+class Import21Error(MailmanError):
+ pass
+
+
def seconds_to_delta(value):
return datetime.timedelta(seconds=value)
@@ -107,6 +114,26 @@ def nonmember_action_mapping(value):
def unicode_to_string(value):
return str(value) if value is not None else None
+
+def check_language_code(code):
+ if code is None:
+ return None
+ code = unicode(code)
+ if code not in getUtility(ILanguageManager):
+ msg = """Missing language: {0}
+You must add a section describing this language in your mailman.cfg file.
+This section should look like this:
+[language.{1}]
+# The English name for the language.
+description: CHANGE ME
+# And the default character set for the language.
+charset: utf-8
+# Whether the language is enabled or not.
+enabled: yes
+""".format(code, code[:2])
+ raise Import21Error(msg)
+ return code
+
# Attributes in Mailman 2 which have a different type in Mailman 3.
TYPES = dict(
@@ -129,6 +156,7 @@ TYPES = dict(
default_member_action=member_action_mapping,
default_nonmember_action=nonmember_action_mapping,
moderator_password=unicode_to_string,
+ preferred_language=check_language_code,
)
@@ -180,7 +208,9 @@ def import_config_pck(mlist, config_dict):
# Handle the simple case where the key is an attribute of the
# IMailingList and the types are the same (modulo 8-bit/unicode
# strings).
- if hasattr(mlist, key):
+ # When attributes raise an exception, hasattr may think they don't
+ # exist (see python issue 9666). Add them here.
+ if hasattr(mlist, key) or key in ("preferred_language", ):
if isinstance(value, str):
for encoding in ("ascii", "utf-8"):
try:
@@ -346,7 +376,7 @@ def import_roster(mlist, config_dict, members, role):
pass
if email in config_dict.get("language", {}):
member.preferences.preferred_language = \
- unicode(config_dict["language"][email])
+ check_language_code(config_dict["language"][email])
# if the user already exists, display_name and password will be
# overwritten
if email in config_dict.get("usernames", {}):
diff --git a/src/mailman/utilities/tests/test_import.py b/src/mailman/utilities/tests/test_import.py
index 2e6a4c0be..2cd737f08 100644
--- a/src/mailman/utilities/tests/test_import.py
+++ b/src/mailman/utilities/tests/test_import.py
@@ -31,7 +31,7 @@ from datetime import timedelta, datetime
from mailman.app.lifecycle import create_list, remove_list
from mailman.testing.layers import ConfigLayer
-from mailman.utilities.importer import import_config_pck
+from mailman.utilities.importer import import_config_pck, Import21Error
from mailman.interfaces.archiver import ArchivePolicy
from mailman.interfaces.action import Action, FilterAction
from mailman.interfaces.bounce import UnrecognizedBounceDisposition
@@ -226,6 +226,32 @@ class TestBasicImport(unittest.TestCase):
unicode(self._pckdict[b"info"], "ascii", "replace"),
"We don't fall back to replacing non-ascii chars")
+ def test_preferred_language(self):
+ self._pckdict[b"preferred_language"] = b'ja'
+ english = getUtility(ILanguageManager).get('en')
+ japanese = getUtility(ILanguageManager).get('ja')
+ self.assertEqual(self._mlist.preferred_language, english)
+ self._import()
+ self.assertEqual(self._mlist.preferred_language, japanese)
+
+ def test_preferred_language_unknown_previous(self):
+ # when the previous language is unknown, it should not fail
+ self._mlist._preferred_language = 'xx' # non-existant
+ self._import()
+ english = getUtility(ILanguageManager).get('en')
+ self.assertEqual(self._mlist.preferred_language, english)
+
+ def test_new_language(self):
+ self._pckdict[b"preferred_language"] = b'xx_XX'
+ try:
+ self._import()
+ except Import21Error, e:
+ # check the message
+ self.assertTrue("xx_XX" in str(e))
+ self.assertTrue("[language.xx]" in str(e))
+ else:
+ self.fail("Import21Error was not raised")
+
class TestArchiveImport(unittest.TestCase):
@@ -549,6 +575,17 @@ class TestRosterImport(unittest.TestCase):
self.assertEqual(member.preferred_language.code,
self._pckdict["language"][addr])
+ def test_new_language(self):
+ self._pckdict[b"language"][b"anne@example.com"] = b'xx_XX'
+ try:
+ import_config_pck(self._mlist, self._pckdict)
+ except Import21Error, e:
+ # check the message
+ self.assertTrue("xx_XX" in str(e))
+ self.assertTrue("[language.xx]" in str(e))
+ else:
+ self.fail("Import21Error was not raised")
+
def test_username(self):
import_config_pck(self._mlist, self._pckdict)
for name in ("anne", "bob", "cindy", "dave"):