summaryrefslogtreecommitdiff
path: root/src/mailman/commands/cli_import.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/commands/cli_import.py')
-rw-r--r--src/mailman/commands/cli_import.py88
1 files changed, 86 insertions, 2 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