summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mailman/commands/cli_import.py88
-rw-r--r--src/mailman/commands/docs/import.txt26
-rw-r--r--src/mailman/interfaces/digests.py10
-rw-r--r--src/mailman/interfaces/mailinglist.py8
-rw-r--r--src/mailman/pipeline/to_digest.py2
-rw-r--r--src/mailman/styles/default.py4
-rw-r--r--src/mailman/testing/config.pckbin0 -> 4111 bytes
7 files changed, 125 insertions, 13 deletions
diff --git a/src/mailman/commands/cli_import.py b/src/mailman/commands/cli_import.py
index 74bd59aea..b9183fb82 100644
--- a/src/mailman/commands/cli_import.py
+++ b/src/mailman/commands/cli_import.py
@@ -25,12 +25,41 @@ __all__ = [
]
+import sys
+import cPickle
+import datetime
+
from zope.component import getUtility
from zope.interface import implements
+from mailman.config import config
from mailman.core.i18n import _
+from mailman.interfaces.action import Action
+from mailman.interfaces.autorespond import ResponseAction
from mailman.interfaces.command import ICLISubCommand
+from mailman.interfaces.digests import DigestFrequency
from mailman.interfaces.listmanager import IListManager
+from mailman.interfaces.mailinglist import Personalization, ReplyToMunging
+from mailman.interfaces.nntp import NewsModeration
+
+
+
+def seconds_to_delta(value):
+ return datetime.timedelta(seconds=value)
+
+
+TYPES = dict(
+ autorespond_owner=ResponseAction,
+ autorespond_postings=ResponseAction,
+ autorespond_requests=ResponseAction,
+ bounce_info_stale_after=seconds_to_delta,
+ bounce_you_are_disabled_warnings_interval=seconds_to_delta,
+ digest_volume_frequency=DigestFrequency,
+ member_moderation_action=Action,
+ news_moderation=NewsModeration,
+ personalize=Personalization,
+ reply_goes_to_list=ReplyToMunging,
+ )
@@ -44,12 +73,15 @@ class Import21:
def add(self, parser, command_parser):
"""See `ICLISubCommand`."""
self.parser = parser
- # Required positional argument.
+ # Required positional arguments.
command_parser.add_argument(
'listname', metavar='LISTNAME', nargs=1,
help=_("""\
The 'fully qualified list name', i.e. the posting address of the
mailing list to inject the message into."""))
+ command_parser.add_argument(
+ 'pickle_file', metavar='FILENAME', nargs=1,
+ help=_('The path to the config.pck file to import.'))
def process(self, args):
"""See `ICLISubCommand`."""
@@ -64,4 +96,56 @@ class Import21:
if mlist is None:
self.parser.error(_('No such list: $fqdn_listname'))
return
-
+ if args.pickle_file is None:
+ self.parser.error(_('config.pck file is required'))
+ return
+ assert len(args.pickle_file) == 1, (
+ 'Unexpected positional arguments: %s' % args.pickle_file)
+ filename = args.pickle_file[0]
+ with open(filename) as fp:
+ while True:
+ try:
+ config_dict = cPickle.load(fp)
+ except EOFError:
+ break
+ except cPickle.UnpicklingError:
+ self.parser.error(
+ _('Not a Mailman 2.1 configuration file: $filename'))
+ return
+ else:
+ if not isinstance(config_dict, dict):
+ print >> sys.stderr, _(
+ 'Ignoring non-dictionary: {0!r}').format(
+ config_dict)
+ continue
+ import_config(mlist, config_dict, args)
+ # Commit the changes to the database.
+ config.db.commit()
+
+
+
+def import_config(mlist, config_dict, args):
+ """Apply a configuration dictionary to a mailing list.
+
+ :param mlist: The mailing list.
+ :type mlist: IMailingList
+ :param config_dict: The Mailman 2.1 configuration dictionary.
+ :type config_dict: dict
+ :param args: Command line arguments.
+ """
+ for key, value in config_dict.items():
+ # 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):
+ if isinstance(value, str):
+ value = unicode(value, 'ascii')
+ # Some types require conversion.
+ converter = TYPES.get(key)
+ if converter is not None:
+ value = converter(value)
+ try:
+ setattr(mlist, key, value)
+ except TypeError as error:
+ print >> sys.stderr, 'Type conversion error:', key
+ raise
diff --git a/src/mailman/commands/docs/import.txt b/src/mailman/commands/docs/import.txt
index c2a438e06..61db46c37 100644
--- a/src/mailman/commands/docs/import.txt
+++ b/src/mailman/commands/docs/import.txt
@@ -10,6 +10,7 @@ that into an existing mailing list in Mailman 3.0.
>>> class FakeArgs:
... listname = None
+ ... pickle_file = None
>>> class FakeParser:
... def error(self, message):
@@ -24,3 +25,28 @@ You must specify the mailing list you are importing into, and it must exist.
>>> FakeArgs.listname = ['import@example.com']
>>> command.process(FakeArgs)
No such list: import@example.com
+
+When the mailing list exists, you must specify a real pickle file to import
+from.
+
+ >>> mlist = create_list('import@example.com')
+ >>> command.process(FakeArgs)
+ config.pck file is required
+
+ >>> FakeArgs.pickle_file = [__file__]
+ >>> command.process(FakeArgs)
+ Not a Mailman 2.1 configuration file: .../import.txt
+
+Now we can import the test pickle file. As a simple illustration of the
+import, the mailing list's 'real name' has changed.
+
+ >>> from pkg_resources import resource_filename
+ >>> FakeArgs.pickle_file = [
+ ... resource_filename('mailman.testing', 'config.pck')]
+
+ >>> print mlist.real_name
+ Import
+
+ >>> command.process(FakeArgs)
+ >>> print mlist.real_name
+ Test
diff --git a/src/mailman/interfaces/digests.py b/src/mailman/interfaces/digests.py
index 98d037e09..9c224d4b5 100644
--- a/src/mailman/interfaces/digests.py
+++ b/src/mailman/interfaces/digests.py
@@ -25,10 +25,20 @@ __all__ = [
]
+from munepy import Enum
from zope.interface import Interface, Attribute
+class DigestFrequency(Enum):
+ yearly = 0
+ monthly = 1
+ quarterly = 2
+ weekly = 3
+ daily = 4
+
+
+
class IOneLastDigest(Interface):
"""Users who should receive one last digest."""
diff --git a/src/mailman/interfaces/mailinglist.py b/src/mailman/interfaces/mailinglist.py
index 2e2083e72..6367a7d1d 100644
--- a/src/mailman/interfaces/mailinglist.py
+++ b/src/mailman/interfaces/mailinglist.py
@@ -56,14 +56,6 @@ class ReplyToMunging(Enum):
explicit_header = 2
-class DigestFrequency(Enum):
- yearly = 0
- monthly = 1
- quarterly = 2
- weekly = 3
- daily = 4
-
-
class IMailingList(Interface):
"""A mailing list."""
diff --git a/src/mailman/pipeline/to_digest.py b/src/mailman/pipeline/to_digest.py
index 53b6d3a27..4690328ae 100644
--- a/src/mailman/pipeline/to_digest.py
+++ b/src/mailman/pipeline/to_digest.py
@@ -33,8 +33,8 @@ from zope.interface import implements
from mailman.config import config
from mailman.core.i18n import _
from mailman.email.message import Message
+from mailman.interfaces.digests import DigestFrequency
from mailman.interfaces.handler import IHandler
-from mailman.interfaces.mailinglist import DigestFrequency
from mailman.utilities.mailbox import Mailbox
diff --git a/src/mailman/styles/default.py b/src/mailman/styles/default.py
index e876d0a07..4caa01424 100644
--- a/src/mailman/styles/default.py
+++ b/src/mailman/styles/default.py
@@ -33,9 +33,9 @@ from zope.interface import implements
from mailman.config import config
from mailman.core.i18n import _
from mailman.interfaces.action import Action
+from mailman.interfaces.digests import DigestFrequency
from mailman.interfaces.autorespond import ResponseAction
-from mailman.interfaces.mailinglist import (
- DigestFrequency, Personalization, ReplyToMunging)
+from mailman.interfaces.mailinglist import Personalization, ReplyToMunging
from mailman.interfaces.nntp import NewsModeration
from mailman.interfaces.styles import IStyle
diff --git a/src/mailman/testing/config.pck b/src/mailman/testing/config.pck
new file mode 100644
index 000000000..68a76cd8e
--- /dev/null
+++ b/src/mailman/testing/config.pck
Binary files differ