summaryrefslogtreecommitdiff
path: root/src/mailman
diff options
context:
space:
mode:
authorBarry Warsaw2011-06-16 16:46:02 -0400
committerBarry Warsaw2011-06-16 16:46:02 -0400
commita8722b736a9070288f9bd62b8650f9e682a33ea6 (patch)
tree0d2a9342963d9b81af5cd822c571beefda29b7a2 /src/mailman
parent3c99f28d219596434e8547df95e7041e2cf21fb7 (diff)
downloadmailman-a8722b736a9070288f9bd62b8650f9e682a33ea6.tar.gz
mailman-a8722b736a9070288f9bd62b8650f9e682a33ea6.tar.zst
mailman-a8722b736a9070288f9bd62b8650f9e682a33ea6.zip
Diffstat (limited to 'src/mailman')
-rw-r--r--src/mailman/Archiver/Archiver.py6
-rw-r--r--src/mailman/bin/checkdbs.py2
-rw-r--r--src/mailman/bin/import.py313
-rw-r--r--src/mailman/commands/cli_aliases.py2
-rw-r--r--src/mailman/commands/cli_lists.py2
-rw-r--r--src/mailman/database/mailman.sql2
-rw-r--r--src/mailman/docs/NEWS.rst (renamed from src/mailman/docs/NEWS.txt)6
-rw-r--r--src/mailman/interfaces/mailinglist.py6
-rw-r--r--src/mailman/model/docs/listmanager.txt2
-rw-r--r--src/mailman/model/docs/mailinglist.txt2
-rw-r--r--src/mailman/model/listmanager.py6
-rw-r--r--src/mailman/model/mailinglist.py26
-rw-r--r--src/mailman/mta/aliases.py5
-rw-r--r--src/mailman/mta/postfix.py2
-rw-r--r--src/mailman/pipeline/decorate.py2
-rw-r--r--src/mailman/pipeline/docs/cook-headers.txt4
-rw-r--r--src/mailman/rest/configuration.py2
-rw-r--r--src/mailman/rest/docs/configuration.rst (renamed from src/mailman/rest/docs/configuration.txt)2
-rw-r--r--src/mailman/rest/docs/lists.rst (renamed from src/mailman/rest/docs/lists.txt)4
-rw-r--r--src/mailman/rest/lists.py2
-rw-r--r--src/mailman/runners/news.py4
-rw-r--r--src/mailman/styles/default.py2
-rw-r--r--src/mailman/utilities/i18n.py2
-rw-r--r--src/mailman/utilities/importer.py9
-rw-r--r--src/mailman/utilities/tests/test_import.py8
25 files changed, 62 insertions, 361 deletions
diff --git a/src/mailman/Archiver/Archiver.py b/src/mailman/Archiver/Archiver.py
index fe1dec252..5150633ac 100644
--- a/src/mailman/Archiver/Archiver.py
+++ b/src/mailman/Archiver/Archiver.py
@@ -130,8 +130,8 @@ class Archiver:
if self.archive_private:
url = self.GetScriptURL('private') + '/index.html'
else:
- domain = getUtility(IDomainManager).get(self.host_name)
- web_host = (self.host_name if domain is None else domain.url_host)
+ domain = getUtility(IDomainManager).get(self.mail_host)
+ web_host = (self.mail_host if domain is None else domain.url_host)
url = Template(config.PUBLIC_ARCHIVE_URL).safe_substitute(
listname=self.fqdn_listname,
hostname=web_host,
@@ -165,7 +165,7 @@ class Archiver:
def ExternalArchive(self, ar, txt):
cmd = Template(ar).safe_substitute(
listname=self.fqdn_listname,
- hostname=self.host_name)
+ hostname=self.mail_host)
extarch = os.popen(cmd, 'w')
extarch.write(txt)
status = extarch.close()
diff --git a/src/mailman/bin/checkdbs.py b/src/mailman/bin/checkdbs.py
index fed40a215..2f93ecc77 100644
--- a/src/mailman/bin/checkdbs.py
+++ b/src/mailman/bin/checkdbs.py
@@ -186,7 +186,7 @@ def main():
text += Utils.maketext(
'checkdbs.txt',
{'count' : count,
- 'host_name': mlist.host_name,
+ 'mail_host': mlist.mail_host,
'adminDB' : mlist.GetScriptURL('admindb',
absolute=1),
'real_name': realname,
diff --git a/src/mailman/bin/import.py b/src/mailman/bin/import.py
deleted file mode 100644
index 7ed2d830e..000000000
--- a/src/mailman/bin/import.py
+++ /dev/null
@@ -1,313 +0,0 @@
-# Copyright (C) 2006-2011 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/>.
-
-"""Import the XML representation of a mailing list."""
-
-import sys
-import optparse
-import traceback
-
-from xml.dom import minidom
-from xml.parsers.expat import ExpatError
-
-from mailman import Defaults
-from mailman import MemberAdaptor
-from mailman import passwords
-from mailman.MailList import MailList
-from mailman.core.i18n import _
-from mailman.initialize import initialize
-from mailman.interfaces.domain import BadDomainSpecificationError
-from mailman.version import MAILMAN_VERSION
-
-
-OPTS = None
-
-
-
-def nodetext(node):
- # Expect only one TEXT_NODE in the list of children
- for child in node.childNodes:
- if child.nodeType == node.TEXT_NODE:
- return child.data
- return u''
-
-
-def nodegen(node, *elements):
- for child in node.childNodes:
- if child.nodeType <> minidom.Node.ELEMENT_NODE:
- continue
- if elements and child.tagName not in elements:
- print _('Ignoring unexpected element: $node.tagName')
- else:
- yield child
-
-
-
-def parse_config(node):
- config = dict()
- for child in nodegen(node, 'option'):
- name = child.getAttribute('name')
- if not name:
- print _('Skipping unnamed option')
- continue
- vtype = child.getAttribute('type') or 'string'
- if vtype in ('email_list', 'email_list_ex', 'checkbox'):
- value = []
- for subnode in nodegen(child):
- value.append(nodetext(subnode))
- elif vtype == 'bool':
- value = nodetext(child)
- try:
- value = bool(int(value))
- except ValueError:
- value = {'true' : True,
- 'false': False,
- }.get(value.lower())
- if value is None:
- print _('Skipping bad boolean value: $value')
- continue
- elif vtype == 'radio':
- value = nodetext(child).lower()
- boolval = {'true' : True,
- 'false': False,
- }.get(value)
- if boolval is None:
- value = int(value)
- else:
- value = boolval
- elif vtype == 'number':
- value = nodetext(child)
- # First try int then float
- try:
- value = int(value)
- except ValueError:
- value = float(value)
- elif vtype in ('header_filter', 'topics'):
- value = []
- fakebltins = dict(__builtins__ = dict(True=True, False=False))
- for subnode in nodegen(child):
- reprstr = nodetext(subnode)
- # Turn the reprs back into tuples, in a safe way
- tupleval = eval(reprstr, fakebltins)
- value.append(tupleval)
- else:
- value = nodetext(child)
- # And now some special casing :(
- if name == 'new_member_options':
- value = int(nodetext(child))
- config[name] = value
- return config
-
-
-
-
-def parse_roster(node):
- members = []
- for child in nodegen(node, 'member'):
- member = dict()
- member['id'] = mid = child.getAttribute('id')
- if not mid:
- print _('Skipping member with no id')
- continue
- if OPTS.verbose:
- print _('* Processing member: $mid')
- for subnode in nodegen(child):
- attr = subnode.tagName
- if attr == 'delivery':
- value = (subnode.getAttribute('status'),
- subnode.getAttribute('delivery'))
- elif attr in ('hide', 'ack', 'notmetoo', 'nodupes', 'nomail'):
- value = {'true' : True,
- 'false': False,
- }.get(nodetext(subnode).lower(), False)
- elif attr == 'topics':
- value = []
- for subsubnode in nodegen(subnode):
- value.append(nodetext(subsubnode))
- elif attr == 'password':
- value = nodetext(subnode)
- if OPTS.reset_passwords or value == '{NONE}' or not value:
- value = passwords.make_secret(Utils.MakeRandomPassword())
- else:
- value = nodetext(subnode)
- member[attr] = value
- members.append(member)
- return members
-
-
-
-def load(fp):
- try:
- doc = minidom.parse(fp)
- except ExpatError:
- print _('Expat error in file: $fp.name')
- traceback.print_exc()
- sys.exit(1)
- doc.normalize()
- # Make sure there's only one top-level <mailman> node
- gen = nodegen(doc, 'mailman')
- top = gen.next()
- try:
- gen.next()
- except StopIteration:
- pass
- else:
- print _('Malformed XML; duplicate <mailman> nodes')
- sys.exit(1)
- all_listdata = []
- for listnode in nodegen(top, 'list'):
- listdata = dict()
- name = listnode.getAttribute('name')
- if OPTS.verbose:
- print _('Processing list: $name')
- if not name:
- print _('Ignoring malformed <list> node')
- continue
- for child in nodegen(listnode, 'configuration', 'roster'):
- if child.tagName == 'configuration':
- list_config = parse_config(child)
- else:
- assert(child.tagName == 'roster')
- list_roster = parse_roster(child)
- all_listdata.append((name, list_config, list_roster))
- return all_listdata
-
-
-
-def create(all_listdata):
- for name, list_config, list_roster in all_listdata:
- fqdn_listname = '%s@%s' % (name, list_config['host_name'])
- if Utils.list_exists(fqdn_listname):
- print _('Skipping already existing list: $fqdn_listname')
- continue
- mlist = MailList()
- try:
- if OPTS.verbose:
- print _('Creating mailing list: $fqdn_listname')
- mlist.Create(fqdn_listname, list_config['owner'][0],
- list_config['password'])
- except BadDomainSpecificationError:
- print _('List is not in a supported domain: $fqdn_listname')
- continue
- # Save the list creation, then unlock and relock the list. This is so
- # that we use normal SQLAlchemy transactions to manage all the
- # attribute and membership updates. Without this, no transaction will
- # get committed in the second Save() below and we'll lose all our
- # updates.
- mlist.Save()
- mlist.Unlock()
- mlist.Lock()
- try:
- for option, value in list_config.items():
- # XXX Here's what sucks. Some properties need to have
- # _setValue() called on the gui component, because those
- # methods do some pre-processing on the values before they're
- # applied to the MailList instance. But we don't have a good
- # way to find a category and sub-category that a particular
- # property belongs to. Plus this will probably change. So
- # for now, we'll just hard code the extra post-processing
- # here. The good news is that not all _setValue() munging
- # needs to be done -- for example, we've already converted
- # everything to dollar strings.
- if option in ('filter_mime_types', 'pass_mime_types',
- 'filter_filename_extensions',
- 'pass_filename_extensions'):
- value = value.splitlines()
- if option == 'available_languages':
- mlist.os(*value)
- else:
- setattr(mlist, option, value)
- for member in list_roster:
- mid = member['id']
- if OPTS.verbose:
- print _('* Adding member: $mid')
- status, delivery = member['delivery']
- kws = {'password' : member['password'],
- 'language' : member['language'],
- 'realname' : member['realname'],
- 'digest' : delivery <> 'regular',
- }
- mlist.addNewMember(mid, **kws)
- status = {'enabled' : MemberAdaptor.ENABLED,
- 'byuser' : MemberAdaptor.BYUSER,
- 'byadmin' : MemberAdaptor.BYADMIN,
- 'bybounce' : MemberAdaptor.BYBOUNCE,
- }.get(status, MemberAdaptor.UNKNOWN)
- mlist.setDeliveryStatus(mid, status)
- for opt in ('hide', 'ack', 'notmetoo', 'nodupes', 'nomail'):
- mlist.setMemberOption(mid,
- Defaults.OPTINFO[opt],
- member[opt])
- topics = member.get('topics')
- if topics:
- mlist.setMemberTopics(mid, topics)
- mlist.Save()
- finally:
- mlist.Unlock()
-
-
-
-def parseargs():
- parser = optparse.OptionParser(version=MAILMAN_VERSION,
- usage=_("""\
-%prog [options]
-
-Import the configuration and/or members of a mailing list in XML format. The
-imported mailing list must not already exist. All mailing lists named in the
-XML file are imported, but those that already exist are skipped unless --error
-is given."""))
- parser.add_option('-i', '--inputfile',
- metavar='FILENAME', default=None, type='string',
- help=_("""\
-Input XML from FILENAME. If not given, or if FILENAME is '-', standard input
-is used."""))
- parser.add_option('-p', '--reset-passwords',
- default=False, action='store_true', help=_("""\
-With this option, user passwords in the XML are ignored and are reset to a
-random password. If the generated passwords were not included in the input
-XML, they will always be randomly generated."""))
- parser.add_option('-v', '--verbose',
- default=False, action='store_true',
- help=_('Produce more verbose output'))
- parser.add_option('-C', '--config',
- help=_('Alternative configuration file to use'))
- opts, args = parser.parse_args()
- if args:
- parser.print_help()
- parser.error(_('Unexpected arguments'))
- return parser, opts, args
-
-
-
-def main():
- global OPTS
-
- parser, opts, args = parseargs()
- initialize(opts.config)
- OPTS = opts
-
- if opts.inputfile in (None, '-'):
- fp = sys.stdin
- else:
- fp = open(opts.inputfile, 'r')
-
- try:
- listbags = load(fp)
- create(listbags)
- finally:
- if fp is not sys.stdin:
- fp.close()
diff --git a/src/mailman/commands/cli_aliases.py b/src/mailman/commands/cli_aliases.py
index b13919121..31affc78c 100644
--- a/src/mailman/commands/cli_aliases.py
+++ b/src/mailman/commands/cli_aliases.py
@@ -126,7 +126,7 @@ class Dummy:
# First, sort mailing lists by domain.
by_domain = {}
for mlist in getUtility(IListManager).mailing_lists:
- by_domain.setdefault(mlist.host_name, []).append(mlist)
+ by_domain.setdefault(mlist.mail_host, []).append(mlist)
sort_key = attrgetter('list_name')
for domain in sorted(by_domain):
for mlist in sorted(by_domain[domain], key=sort_key):
diff --git a/src/mailman/commands/cli_lists.py b/src/mailman/commands/cli_lists.py
index 8acf0c272..a2df63031 100644
--- a/src/mailman/commands/cli_lists.py
+++ b/src/mailman/commands/cli_lists.py
@@ -92,7 +92,7 @@ class Lists:
if args.advertised and not mlist.advertised:
continue
domains = getattr(args, 'domains', None)
- if domains and mlist.host_name not in domains:
+ if domains and mlist.mail_host not in domains:
continue
mailing_lists.append(mlist)
# Maybe no mailing lists matched.
diff --git a/src/mailman/database/mailman.sql b/src/mailman/database/mailman.sql
index 7493f5d34..c6f63c6e5 100644
--- a/src/mailman/database/mailman.sql
+++ b/src/mailman/database/mailman.sql
@@ -96,7 +96,7 @@ CREATE TABLE mailinglist (
id INTEGER NOT NULL,
-- List identity
list_name TEXT,
- host_name TEXT,
+ mail_host TEXT,
list_id TEXT,
include_list_post_header BOOLEAN,
include_rfc2369_headers BOOLEAN,
diff --git a/src/mailman/docs/NEWS.txt b/src/mailman/docs/NEWS.rst
index fde7dbe4c..64948bdb3 100644
--- a/src/mailman/docs/NEWS.txt
+++ b/src/mailman/docs/NEWS.rst
@@ -20,6 +20,12 @@ Architecture
* master-qrunner.lck -> master.lck
* master-qrunner.pid -> master.pid
+REST
+----
+ * The IMailingList attribute ``host_name`` has been renamed to ``mail_host``
+ for consistency. This changes the REST API for mailing list
+ resources. (LP: #787599)
+
Commands
--------
* bin/qrunner is renamed to bin/runner.
diff --git a/src/mailman/interfaces/mailinglist.py b/src/mailman/interfaces/mailinglist.py
index 44e015435..5470f0b5f 100644
--- a/src/mailman/interfaces/mailinglist.py
+++ b/src/mailman/interfaces/mailinglist.py
@@ -71,19 +71,19 @@ class IMailingList(Interface):
posted to mylist@example.com, then the list_name is 'mylist'.
""")
- host_name = Attribute("""\
+ mail_host = Attribute("""\
The read-only domain name 'hosting' this mailing list. This is always
the domain name part of the posting email address, and it may bear no
relationship to the web url used to access this mailing list. For
example, if messages are posted to mylist@example.com, then the
- host_name is 'example.com'.
+ mail_host is 'example.com'.
""")
fqdn_listname = Attribute("""\
The read-only fully qualified name of the mailing list. This is the
guaranteed unique id for the mailing list, and it is always the
address to which messages are posted, e.g. mylist@example.com. It is
- always comprised of the list_name + '@' + host_name.
+ always comprised of the list_name + '@' + mail_host.
""")
domain = Attribute(
diff --git a/src/mailman/model/docs/listmanager.txt b/src/mailman/model/docs/listmanager.txt
index 7235049c7..b571d9680 100644
--- a/src/mailman/model/docs/listmanager.txt
+++ b/src/mailman/model/docs/listmanager.txt
@@ -26,7 +26,7 @@ list to the system.
>>> print mlist.list_name
_xtest
- >>> print mlist.host_name
+ >>> print mlist.mail_host
example.com
>>> print mlist.fqdn_listname
_xtest@example.com
diff --git a/src/mailman/model/docs/mailinglist.txt b/src/mailman/model/docs/mailinglist.txt
index 4d3250e76..895068e52 100644
--- a/src/mailman/model/docs/mailinglist.txt
+++ b/src/mailman/model/docs/mailinglist.txt
@@ -18,7 +18,7 @@ name (i.e. local part) and host name.
>>> print mlist.list_name
aardvark
- >>> print mlist.host_name
+ >>> print mlist.mail_host
example.com
diff --git a/src/mailman/model/listmanager.py b/src/mailman/model/listmanager.py
index 99c961e85..851b52618 100644
--- a/src/mailman/model/listmanager.py
+++ b/src/mailman/model/listmanager.py
@@ -50,7 +50,7 @@ class ListManager:
mlist = config.db.store.find(
MailingList,
MailingList.list_name == listname,
- MailingList.host_name == hostname).one()
+ MailingList.mail_host == hostname).one()
if mlist:
raise ListAlreadyExistsError(fqdn_listname)
mlist = MailingList(fqdn_listname)
@@ -63,7 +63,7 @@ class ListManager:
listname, at, hostname = fqdn_listname.partition('@')
mlist = config.db.store.find(MailingList,
list_name=listname,
- host_name=hostname).one()
+ mail_host=hostname).one()
if mlist is not None:
# XXX Fixme
mlist._restore()
@@ -88,7 +88,7 @@ class ListManager:
def names(self):
"""See `IListManager`."""
for mlist in config.db.store.find(MailingList):
- yield '{0}@{1}'.format(mlist.list_name, mlist.host_name)
+ yield '{0}@{1}'.format(mlist.list_name, mlist.mail_host)
# XXX 2010-02-24 barry Get rid of this.
def get_mailing_lists(self):
diff --git a/src/mailman/model/mailinglist.py b/src/mailman/model/mailinglist.py
index 2d972a24a..fe5355806 100644
--- a/src/mailman/model/mailinglist.py
+++ b/src/mailman/model/mailinglist.py
@@ -71,7 +71,7 @@ class MailingList(Model):
# List identity
list_name = Unicode()
- host_name = Unicode()
+ mail_host = Unicode()
list_id = Unicode()
include_list_post_header = Bool()
include_rfc2369_headers = Bool()
@@ -192,7 +192,7 @@ class MailingList(Model):
listname, at, hostname = fqdn_listname.partition('@')
assert hostname, 'Bad list name: {0}'.format(fqdn_listname)
self.list_name = listname
- self.host_name = hostname
+ self.mail_host = hostname
# For the pending database
self.next_request_id = 1
self._restore()
@@ -219,12 +219,12 @@ class MailingList(Model):
@property
def fqdn_listname(self):
"""See `IMailingList`."""
- return '{0}@{1}'.format(self.list_name, self.host_name)
+ return '{0}@{1}'.format(self.list_name, self.mail_host)
@property
def domain(self):
"""See `IMailingList`."""
- return getUtility(IDomainManager)[self.host_name]
+ return getUtility(IDomainManager)[self.mail_host]
@property
def scheme(self):
@@ -257,49 +257,49 @@ class MailingList(Model):
@property
def no_reply_address(self):
"""See `IMailingList`."""
- return '{0}@{1}'.format(config.mailman.noreply_address, self.host_name)
+ return '{0}@{1}'.format(config.mailman.noreply_address, self.mail_host)
@property
def owner_address(self):
"""See `IMailingList`."""
- return '{0}-owner@{1}'.format(self.list_name, self.host_name)
+ return '{0}-owner@{1}'.format(self.list_name, self.mail_host)
@property
def request_address(self):
"""See `IMailingList`."""
- return '{0}-request@{1}'.format(self.list_name, self.host_name)
+ return '{0}-request@{1}'.format(self.list_name, self.mail_host)
@property
def bounces_address(self):
"""See `IMailingList`."""
- return '{0}-bounces@{1}'.format(self.list_name, self.host_name)
+ return '{0}-bounces@{1}'.format(self.list_name, self.mail_host)
@property
def join_address(self):
"""See `IMailingList`."""
- return '{0}-join@{1}'.format(self.list_name, self.host_name)
+ return '{0}-join@{1}'.format(self.list_name, self.mail_host)
@property
def leave_address(self):
"""See `IMailingList`."""
- return '{0}-leave@{1}'.format(self.list_name, self.host_name)
+ return '{0}-leave@{1}'.format(self.list_name, self.mail_host)
@property
def subscribe_address(self):
"""See `IMailingList`."""
- return '{0}-subscribe@{1}'.format(self.list_name, self.host_name)
+ return '{0}-subscribe@{1}'.format(self.list_name, self.mail_host)
@property
def unsubscribe_address(self):
"""See `IMailingList`."""
- return '{0}-unsubscribe@{1}'.format(self.list_name, self.host_name)
+ return '{0}-unsubscribe@{1}'.format(self.list_name, self.mail_host)
def confirm_address(self, cookie):
"""See `IMailingList`."""
local_part = expand(config.mta.verp_confirm_format, dict(
address = '{0}-confirm'.format(self.list_name),
cookie = cookie))
- return '{0}@{1}'.format(local_part, self.host_name)
+ return '{0}@{1}'.format(local_part, self.mail_host)
@property
def preferred_language(self):
diff --git a/src/mailman/mta/aliases.py b/src/mailman/mta/aliases.py
index 9f2bd74e3..aad8e8c1f 100644
--- a/src/mailman/mta/aliases.py
+++ b/src/mailman/mta/aliases.py
@@ -53,9 +53,8 @@ class MailTransportAgentAliases:
# Always return
yield mlist.posting_address
for destination in sorted(SUBDESTINATIONS):
- yield '{0}-{1}@{2}'.format(mlist.list_name,
- destination,
- mlist.host_name)
+ yield '{0}-{1}@{2}'.format(
+ mlist.list_name, destination, mlist.mail_host)
def destinations(self, mlist):
"""See `IMailTransportAgentAliases`."""
diff --git a/src/mailman/mta/postfix.py b/src/mailman/mta/postfix.py
index b52ce20a6..242325b9f 100644
--- a/src/mailman/mta/postfix.py
+++ b/src/mailman/mta/postfix.py
@@ -104,7 +104,7 @@ class LMTP:
# part. For postfix we need a dummy entry for the domain.
by_domain = {}
for mlist in getUtility(IListManager).mailing_lists:
- by_domain.setdefault(mlist.host_name, []).append(mlist)
+ by_domain.setdefault(mlist.mail_host, []).append(mlist)
print >> fp, """\
# AUTOMATICALLY GENERATED BY MAILMAN ON {0}
#
diff --git a/src/mailman/pipeline/decorate.py b/src/mailman/pipeline/decorate.py
index d71e05cdc..fd3d14e3a 100644
--- a/src/mailman/pipeline/decorate.py
+++ b/src/mailman/pipeline/decorate.py
@@ -204,7 +204,7 @@ def decorate(mlist, template, extradict=None):
real_name = mlist.real_name,
list_name = mlist.list_name,
fqdn_listname = mlist.fqdn_listname,
- host_name = mlist.host_name,
+ host_name = mlist.mail_host,
listinfo_page = mlist.script_url('listinfo'),
description = mlist.description,
info = mlist.info,
diff --git a/src/mailman/pipeline/docs/cook-headers.txt b/src/mailman/pipeline/docs/cook-headers.txt
index 834b140fa..cd2acaae2 100644
--- a/src/mailman/pipeline/docs/cook-headers.txt
+++ b/src/mailman/pipeline/docs/cook-headers.txt
@@ -199,7 +199,7 @@ set the ``List-ID`` header. Start by creating a new domain.
>>> from mailman.interfaces.domain import IDomainManager
>>> from zope.component import getUtility
>>> domain = getUtility(IDomainManager).add('mail.example.net')
- >>> mlist.host_name = 'mail.example.net'
+ >>> mlist.mail_host = 'mail.example.net'
>>> process(mlist, msg, {})
>>> print msg['list-id']
@@ -210,7 +210,7 @@ set the ``List-ID`` header. Start by creating a new domain.
>>> print msg['list-id']
My test mailing list <_xtest.mail.example.net>
- >>> mlist.host_name = 'example.com'
+ >>> mlist.mail_host = 'example.com'
>>> mlist.list_id = '_xtest.example.com'
Any existing ``List-ID`` headers are removed from the original message.
diff --git a/src/mailman/rest/configuration.py b/src/mailman/rest/configuration.py
index ea180a724..0f08198ab 100644
--- a/src/mailman/rest/configuration.py
+++ b/src/mailman/rest/configuration.py
@@ -182,7 +182,7 @@ ATTRIBUTES = dict(
filter_content=GetterSetter(as_boolean),
fqdn_listname=GetterSetter(None),
generic_nonmember_action=GetterSetter(int),
- host_name=GetterSetter(None),
+ mail_host=GetterSetter(None),
include_list_post_header=GetterSetter(as_boolean),
include_rfc2369_headers=GetterSetter(as_boolean),
join_address=GetterSetter(None),
diff --git a/src/mailman/rest/docs/configuration.txt b/src/mailman/rest/docs/configuration.rst
index 1c18434d7..b21bb8e4c 100644
--- a/src/mailman/rest/docs/configuration.txt
+++ b/src/mailman/rest/docs/configuration.rst
@@ -40,7 +40,6 @@ All readable attributes for a list are available on a sub-resource.
filter_content: False
fqdn_listname: test-one@example.com
generic_nonmember_action: 1
- host_name: example.com
http_etag: "..."
include_list_post_header: True
include_rfc2369_headers: True
@@ -49,6 +48,7 @@ All readable attributes for a list are available on a sub-resource.
leave_address: test-one-leave@example.com
list_id: test-one.example.com
list_name: test-one
+ mail_host: example.com
next_digest_number: 1
no_reply_address: noreply@example.com
owner_address: test-one-owner@example.com
diff --git a/src/mailman/rest/docs/lists.txt b/src/mailman/rest/docs/lists.rst
index 32cca5fb7..fd96507c3 100644
--- a/src/mailman/rest/docs/lists.txt
+++ b/src/mailman/rest/docs/lists.rst
@@ -21,9 +21,9 @@ Create a mailing list in a domain and it's accessible via the API.
>>> dump_json('http://localhost:9001/3.0/lists')
entry 0:
fqdn_listname: test-one@example.com
- host_name: example.com
http_etag: "..."
list_name: test-one
+ mail_host: example.com
real_name: Test-one
self_link: http://localhost:9001/3.0/lists/test-one@example.com
http_etag: "..."
@@ -63,9 +63,9 @@ It is also available via the location given in the response.
>>> dump_json('http://localhost:9001/3.0/lists/test-two@example.com')
fqdn_listname: test-two@example.com
- host_name: example.com
http_etag: "..."
list_name: test-two
+ mail_host: example.com
real_name: Test-two
self_link: http://localhost:9001/3.0/lists/test-two@example.com
diff --git a/src/mailman/rest/lists.py b/src/mailman/rest/lists.py
index 388da8d9d..3edb43b00 100644
--- a/src/mailman/rest/lists.py
+++ b/src/mailman/rest/lists.py
@@ -109,7 +109,7 @@ class _ListBase(resource.Resource, CollectionMixin):
"""See `CollectionMixin`."""
return dict(
fqdn_listname=mlist.fqdn_listname,
- host_name=mlist.host_name,
+ mail_host=mlist.mail_host,
list_name=mlist.list_name,
real_name=mlist.real_name,
self_link=path_to('lists/{0}'.format(mlist.fqdn_listname)),
diff --git a/src/mailman/runners/news.py b/src/mailman/runners/news.py
index eb84f9e2d..11d3dca7a 100644
--- a/src/mailman/runners/news.py
+++ b/src/mailman/runners/news.py
@@ -43,7 +43,7 @@ mcre = re.compile(r"""
\d+. # pid
(?P<listname>[^@]+) # list's internal_name()
@ # localpart@dom.ain
- (?P<hostname>[^>]+) # list's host_name
+ (?P<hostname>[^>]+) # list's mail_host
> # trailer
""", re.VERBOSE)
@@ -134,7 +134,7 @@ def prepare_message(mlist, msg, msgdata):
mo = mcre.search(msgid)
if mo:
lname, hname = mo.group('listname', 'hostname')
- if lname == mlist.internal_name() and hname == mlist.host_name:
+ if lname == mlist.internal_name() and hname == mlist.mail_host:
hackmsgid = False
if hackmsgid:
del msg['message-id']
diff --git a/src/mailman/styles/default.py b/src/mailman/styles/default.py
index 68934e99c..eba7c7757 100644
--- a/src/mailman/styles/default.py
+++ b/src/mailman/styles/default.py
@@ -56,7 +56,7 @@ class DefaultStyle:
mlist = mailing_list
# List identity.
mlist.real_name = mlist.list_name.capitalize()
- mlist.list_id = '{0.list_name}.{0.host_name}'.format(mlist)
+ mlist.list_id = '{0.list_name}.{0.mail_host}'.format(mlist)
mlist.include_rfc2369_headers = True
mlist.include_list_post_header = True
# Most of these were ripped from the old MailList.InitVars() method.
diff --git a/src/mailman/utilities/i18n.py b/src/mailman/utilities/i18n.py
index cdc25530d..1aede4ebe 100644
--- a/src/mailman/utilities/i18n.py
+++ b/src/mailman/utilities/i18n.py
@@ -66,7 +66,7 @@ def _search(template_file, mailing_list=None, language=None):
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))
+ mailing_list.mail_host))
paths.append(os.path.join(config.LIST_DATA_DIR,
mailing_list.fqdn_listname))
paths.reverse()
diff --git a/src/mailman/utilities/importer.py b/src/mailman/utilities/importer.py
index dc672f621..6ee538554 100644
--- a/src/mailman/utilities/importer.py
+++ b/src/mailman/utilities/importer.py
@@ -39,6 +39,7 @@ def seconds_to_delta(value):
return datetime.timedelta(seconds=value)
+# Attributes in Mailman 2 which have a different type in Mailman 3.
TYPES = dict(
autorespond_owner=ResponseAction,
autorespond_postings=ResponseAction,
@@ -52,6 +53,12 @@ TYPES = dict(
)
+# Attribute names in Mailman 2 which are renamed in Mailman 3.
+NAME_MAPPINGS = dict(
+ host_name='mail_host',
+ )
+
+
def import_config_pck(mlist, config_dict):
"""Apply a config.pck configuration dictionary to a mailing list.
@@ -62,6 +69,8 @@ def import_config_pck(mlist, config_dict):
:type config_dict: dict
"""
for key, value in config_dict.items():
+ # Some attributes from Mailman 2 were renamed in Mailman 3.
+ key = NAME_MAPPINGS.get(key, key)
# Handle the simple case where the key is an attribute of the
# IMailingList and the types are the same (modulo 8-bit/unicode
# strings).
diff --git a/src/mailman/utilities/tests/test_import.py b/src/mailman/utilities/tests/test_import.py
index c54a5c0b2..b31de46cf 100644
--- a/src/mailman/utilities/tests/test_import.py
+++ b/src/mailman/utilities/tests/test_import.py
@@ -56,11 +56,11 @@ class TestBasicImport(unittest.TestCase):
self._import()
self.assertEqual(self._mlist.real_name, 'Test')
- def test_host_name(self):
- # The mlist.host_name gets set.
- self.assertEqual(self._mlist.host_name, 'example.com')
+ def test_mail_host(self):
+ # The mlist.mail_host gets set.
+ self.assertEqual(self._mlist.mail_host, 'example.com')
self._import()
- self.assertEqual(self._mlist.host_name, 'heresy.example.org')
+ self.assertEqual(self._mlist.mail_host, 'heresy.example.org')
def test_rfc2369_headers(self):
self._mlist.include_list_post_header = False