diff options
Diffstat (limited to 'src/mailman/model')
| -rw-r--r-- | src/mailman/model/mailinglist.py | 107 | ||||
| -rw-r--r-- | src/mailman/model/tests/test_domain.py | 2 | ||||
| -rw-r--r-- | src/mailman/model/tests/test_listmanager.py | 5 | ||||
| -rw-r--r-- | src/mailman/model/tests/test_mailinglist.py | 102 |
4 files changed, 169 insertions, 47 deletions
diff --git a/src/mailman/model/mailinglist.py b/src/mailman/model/mailinglist.py index a0239caa9..e9601e412 100644 --- a/src/mailman/model/mailinglist.py +++ b/src/mailman/model/mailinglist.py @@ -28,8 +28,8 @@ __all__ = [ import os from storm.locals import ( - And, Bool, DateTime, Float, Int, Pickle, RawStr, Reference, ReferenceSet, - Store, TimeDelta, Unicode) + And, Bool, DateTime, Float, Int, Pickle, RawStr, Reference, Store, + TimeDelta, Unicode) from urlparse import urljoin from zope.component import getUtility from zope.event import notify @@ -47,7 +47,7 @@ from mailman.interfaces.digests import DigestFrequency from mailman.interfaces.domain import IDomainManager from mailman.interfaces.languages import ILanguageManager from mailman.interfaces.mailinglist import ( - IAcceptableAlias, IAcceptableAliasSet, IArchiverList, IListArchiverSet, + IAcceptableAlias, IAcceptableAliasSet, IListArchiver, IListArchiverSet, IMailingList, Personalization, ReplyToMunging) from mailman.interfaces.member import ( AlreadySubscribedError, MemberRole, MissingPreferredAddressError, @@ -67,19 +67,6 @@ from mailman.utilities.string import expand SPACE = ' ' UNDERSCORE = '_' -@implementer(IArchiverList) -class ArchiverList(Model): - __storm_primary__ = "mailing_list_id", "archiver_name" - mailing_list_id = Int() - archiver_name = Unicode() - archiver_enabled = Bool() - - def __init__(self, mailing_list_id, archiver_name): - self.mailing_list_id = mailing_list_id - self.archiver_name = archiver_name - self.archiver_enabled = False - - @implementer(IMailingList) @@ -91,7 +78,6 @@ class MailingList(Model): # XXX denotes attributes that should be part of the public interface but # are currently missing. - archivers = ReferenceSet(id, ArchiverList.mailing_list_id) # List identity list_name = Unicode() mail_host = Unicode() @@ -553,39 +539,68 @@ class AcceptableAliasSet: for alias in aliases: yield alias.alias -@implementer(IListArchiverSet) -class ListArchiverSet: - def __init__(self, mailing_list): - self._mailing_list = mailing_list - self.lazyAdd() - def getAll(self): - entries = Store.of(self._mailing_list).find(ArchiverList, ArchiverList.mailing_list_id == self._mailing_list.id) - all_in_config = {archiver.name for archiver in config.archivers} - ret = {} - for entry in entries: - if entry.archiver_name in all_in_config: - ret[entry.archiver_name] = int(entry.archiver_enabled) - return ret + +@implementer(IListArchiver) +class ListArchiver(Model): + """See `IListArchiver`.""" + + id = Int(primary=True) + + mailing_list_id = Int() + mailing_list = Reference(mailing_list_id, MailingList.id) + name = Unicode() + _is_enabled = Bool() + + def __init__(self, mailing_list, archiver_name, system_archiver): + self.mailing_list = mailing_list + self.name = archiver_name + self._is_enabled = system_archiver.is_enabled - def set(self, archiver, is_enabled): - bool_enabled = (int(is_enabled) != 0) - self.get(archiver).set(archiver_enabled=bool_enabled) + @property + def system_archiver(self): + for archiver in config.archivers: + if archiver.name == self.name: + return archiver + return None + + @property + def is_enabled(self): + return self.system_archiver.is_enabled and self._is_enabled - def isEnabled(self, archiverName): - return self.get(archiverName).one().archiver_enabled + @is_enabled.setter + def is_enabled(self, value): + self._is_enabled = value - def get(self, archiverName): - return Store.of(self._mailing_list).find(ArchiverList, - (ArchiverList.mailing_list_id == self._mailing_list.id) & (ArchiverList.archiver_name == archiverName)) - def lazyAdd(self): - names = [] +@implementer(IListArchiverSet) +class ListArchiverSet: + def __init__(self, mailing_list): + self._mailing_list = mailing_list + system_archivers = {} for archiver in config.archivers: - count = self.get(archiver.name).count() - names.append((archiver.name, count)) - if not count: - entry = ArchiverList(self._mailing_list.id, archiver.name) - Store.of(self._mailing_list).add(entry) - Store.of(self._mailing_list).commit() + system_archivers[archiver.name] = archiver + # Add any system enabled archivers which aren't already associated + # with the mailing list. + store = Store.of(self._mailing_list) + for archiver_name in system_archivers: + exists = store.find( + ListArchiver, + And(ListArchiver.mailing_list == mailing_list, + ListArchiver.name == archiver_name)).one() + if exists is None: + store.add(ListArchiver(mailing_list, archiver_name, + system_archivers[archiver_name])) + + @property + def archivers(self): + entries = Store.of(self._mailing_list).find( + ListArchiver, ListArchiver.mailing_list == self._mailing_list) + for entry in entries: + yield entry + def get(self, archiver_name): + return Store.of(self._mailing_list).find( + ListArchiver, + And(ListArchiver.mailing_list == self._mailing_list, + ListArchiver.name == archiver_name)).one() diff --git a/src/mailman/model/tests/test_domain.py b/src/mailman/model/tests/test_domain.py index 3d7f95615..67924d393 100644 --- a/src/mailman/model/tests/test_domain.py +++ b/src/mailman/model/tests/test_domain.py @@ -21,6 +21,8 @@ from __future__ import absolute_import, unicode_literals __metaclass__ = type __all__ = [ + 'TestDomainLifecycleEvents', + 'TestDomainManager', ] diff --git a/src/mailman/model/tests/test_listmanager.py b/src/mailman/model/tests/test_listmanager.py index 152d96b9f..b18c8e5d1 100644 --- a/src/mailman/model/tests/test_listmanager.py +++ b/src/mailman/model/tests/test_listmanager.py @@ -17,10 +17,13 @@ """Test the ListManager.""" -from __future__ import absolute_import, unicode_literals +from __future__ import absolute_import, print_function, unicode_literals __metaclass__ = type __all__ = [ + 'TestListCreation', + 'TestListLifecycleEvents', + 'TestListManager', ] diff --git a/src/mailman/model/tests/test_mailinglist.py b/src/mailman/model/tests/test_mailinglist.py new file mode 100644 index 000000000..09c4cb38f --- /dev/null +++ b/src/mailman/model/tests/test_mailinglist.py @@ -0,0 +1,102 @@ +# Copyright (C) 2013 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/>. + +"""Test MailingLists and related model objects..""" + +from __future__ import absolute_import, print_function, unicode_literals + +__metaclass__ = type +__all__ = [ + 'TestListArchiver', + 'TestDisabledListArchiver', + ] + + +import unittest + +from mailman.app.lifecycle import create_list +from mailman.config import config +from mailman.interfaces.mailinglist import IListArchiverSet +from mailman.testing.helpers import configuration +from mailman.testing.layers import ConfigLayer + + + +class TestListArchiver(unittest.TestCase): + layer = ConfigLayer + + def setUp(self): + self._mlist = create_list('ant@example.com') + self._set = IListArchiverSet(self._mlist) + + def test_list_archivers(self): + # Find the set of archivers registered for this mailing list. + self.assertEqual( + ['mail-archive', 'mhonarc', 'prototype'], + sorted(archiver.name for archiver in self._set.archivers)) + + def test_get_archiver(self): + # Use .get() to see if a mailing list has an archiver. + archiver = self._set.get('prototype') + self.assertEqual(archiver.name, 'prototype') + self.assertTrue(archiver.is_enabled) + self.assertEqual(archiver.mailing_list, self._mlist) + self.assertEqual(archiver.system_archiver.name, 'prototype') + + def test_get_archiver_no_such(self): + # Using .get() on a non-existing name returns None. + self.assertIsNone(self._set.get('no-such-archiver')) + + def test_site_disabled(self): + # Here the system configuration enables all the archivers in time for + # the archive set to be created with all list archivers enabled. But + # then the site-wide archiver gets disabled, so the list specific + # archiver will also be disabled. + archiver_set = IListArchiverSet(self._mlist) + archiver = archiver_set.get('prototype') + self.assertTrue(archiver.is_enabled) + # Disable the site-wide archiver. + archiver.system_archiver.is_enabled = False + self.assertFalse(archiver.is_enabled) + + + +class TestDisabledListArchiver(unittest.TestCase): + layer = ConfigLayer + + def setUp(self): + self._mlist = create_list('ant@example.com') + + @configuration('archiver.prototype', enable='no') + def test_enable_list_archiver(self): + # When the system configuration file disables an archiver site-wide, + # the list-specific mailing list will get initialized as not enabled. + # Create the archiver set on the fly so that it doesn't get + # initialized with a configuration that enables the prototype archiver. + archiver_set = IListArchiverSet(self._mlist) + archiver = archiver_set.get('prototype') + self.assertFalse(archiver.is_enabled) + # Enable both the list archiver and the system archiver. + archiver.is_enabled = True + config.push('enable prototype', """\ + [archiver.prototype] + enable: yes + """) + # Get the IListArchiver again. + archiver = archiver_set.get('prototype') + self.assertTrue(archiver.is_enabled) + config.pop('enable prototype') |
