diff options
| author | Barry Warsaw | 2009-07-16 22:36:06 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2009-07-16 22:36:06 -0400 |
| commit | 1bfc7f302f2730a679b2a4a103c2978d8e7c70ae (patch) | |
| tree | 3d69d43841dcf838e9778d2e83cc3e58a7b9ed20 /src/mailman/database | |
| parent | ac3af23142c9b2417759f90837d68e15866b6793 (diff) | |
| download | mailman-1bfc7f302f2730a679b2a4a103c2978d8e7c70ae.tar.gz mailman-1bfc7f302f2730a679b2a4a103c2978d8e7c70ae.tar.zst mailman-1bfc7f302f2730a679b2a4a103c2978d8e7c70ae.zip | |
Wow. Put domains into the database.
Add an IDomainManager and a global domain manager which can be gotten by
adapting the global config object.
Add an IDomainCollection interface for exposing the domain manager onto the
API.
Diffstat (limited to 'src/mailman/database')
| -rw-r--r-- | src/mailman/database/domain.py | 163 | ||||
| -rw-r--r-- | src/mailman/database/mailinglist.py | 5 | ||||
| -rw-r--r-- | src/mailman/database/mailman.sql | 20 | ||||
| -rw-r--r-- | src/mailman/database/member.py | 4 |
4 files changed, 183 insertions, 9 deletions
diff --git a/src/mailman/database/domain.py b/src/mailman/database/domain.py new file mode 100644 index 000000000..a729cb8e2 --- /dev/null +++ b/src/mailman/database/domain.py @@ -0,0 +1,163 @@ +# Copyright (C) 2008-2009 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/>. + +"""Domains.""" + +from __future__ import unicode_literals + +__metaclass__ = type +__all__ = [ + 'Domain', + 'DomainManager', + ] + +from urlparse import urljoin, urlparse +from storm.locals import Int, Unicode +from zope.interface import implements + +from mailman.core.errors import BadDomainSpecificationError +from mailman.database.model import Model +from mailman.interfaces.domain import IDomain, IDomainManager + + + +class Domain(Model): + """Domains.""" + + implements(IDomain) + + id = Int(primary=True) + + email_host = Unicode() + base_url = Unicode() + description = Unicode() + contact_address = Unicode() + + def __init__(self, email_host, + description=None, + base_url=None, + contact_address=None): + """Create and register a domain. + + :param email_host: The host name for the email interface. + :type email_host: string + :param description: An optional description of the domain. + :type description: string + :param base_url: The optional base url for the domain, including + scheme. If not given, it will be constructed from the + `email_host` using the http protocol. + :type base_url: string + :param contact_address: The email address to contact a human for this + domain. If not given, postmaster@`email_host` will be used. + :type contact_address: string + """ + self.email_host = email_host + self.base_url = (base_url + if base_url is not None + else 'http://' + email_host) + self.description = description + self.contact_address = (contact_address + if contact_address is not None + else 'postmaster@' + email_host) + + @property + def url_host(self): + # pylint: disable-msg=E1101 + # no netloc member; yes it does + return urlparse(self.base_url).netloc + + def confirm_address(self, token=''): + """See `IDomain`.""" + return 'confirm-{0}@{1}'.format(token, self.email_host) + + def confirm_url(self, token=''): + """See `IDomain`.""" + return urljoin(self.base_url, 'confirm/' + token) + + def __repr__(self): + """repr(a_domain)""" + if self.description is None: + return ('<Domain {0.email_host}, base_url: {0.base_url}, ' + 'contact_address: {0.contact_address}>').format(self) + else: + return ('<Domain {0.email_host}, {0.description}, ' + 'base_url: {0.base_url}, ' + 'contact_address: {0.contact_address}>').format(self) + + + +class DomainManager: + """Domain manager.""" + + implements(IDomainManager) + + def __init__(self, config): + """Create a domain manager. + + :param config: The configuration object. + :type config: `IConfiguration` + """ + self.config = config + self.store = config.db.store + + def add(self, email_host, + description=None, + base_url=None, + contact_address=None): + """See `IDomainManager`.""" + # Be sure the email_host is not already registered. This is probably + # a constraint that should (also) be maintained in the database. + if self.get(email_host) is not None: + raise BadDomainSpecificationError( + 'Duplicate email host: %s' % email_host) + domain = Domain(email_host, description, base_url, contact_address) + self.store.add(domain) + return domain + + def remove(self, email_host): + domain = self[email_host] + self.store.remove(domain) + return domain + + def get(self, email_host, default=None): + """See `IDomainManager`.""" + domains = self.store.find(Domain, email_host=email_host) + if domains.count() < 1: + return default + assert domains.count() == 1, ( + 'Too many matching domains: %s' % email_host) + return domains.one() + + def __getitem__(self, email_host): + """See `IDomainManager`.""" + missing = object() + domain = self.get(email_host, missing) + if domain is missing: + raise KeyError(email_host) + return domain + + def __len__(self): + return self.store.find(Domain).count() + + def __iter__(self): + """See `IDomainManager`.""" + for domain in self.store.find(Domain): + yield domain + + def __contains__(self, email_host): + """See `IDomainManager`.""" + return self.store.find(Domain, email_host=email_host).count() > 0 diff --git a/src/mailman/database/mailinglist.py b/src/mailman/database/mailinglist.py index f08adfd8b..5384e9895 100644 --- a/src/mailman/database/mailinglist.py +++ b/src/mailman/database/mailinglist.py @@ -40,6 +40,7 @@ from mailman.database.digests import OneLastDigest from mailman.database.mime import ContentFilter from mailman.database.model import Model from mailman.database.types import Enum +from mailman.interfaces.domain import IDomainManager from mailman.interfaces.mailinglist import ( IAcceptableAlias, IAcceptableAliasSet, IMailingList, Personalization) from mailman.interfaces.mime import FilterType @@ -210,12 +211,12 @@ class MailingList(Model): @property def web_host(self): """See `IMailingList`.""" - return config.domains[self.host_name] + return IDomainManager(config)[self.host_name] def script_url(self, target, context=None): """See `IMailingList`.""" # Find the domain for this mailing list. - domain = config.domains[self.host_name] + domain = IDomainManager(config)[self.host_name] # XXX Handle the case for when context is not None; those would be # relative URLs. return urljoin(domain.base_url, target + '/' + self.fqdn_listname) diff --git a/src/mailman/database/mailman.sql b/src/mailman/database/mailman.sql index fa772416f..84a906fb1 100644 --- a/src/mailman/database/mailman.sql +++ b/src/mailman/database/mailman.sql @@ -67,11 +67,21 @@ CREATE TABLE contentfilter ( CREATE INDEX ix_contentfilter_mailing_list_id ON contentfilter (mailing_list_id); +CREATE TABLE domain ( + id INTEGER NOT NULL, + email_host TEXT, + base_url TEXT, + description TEXT, + contact_address TEXT, + PRIMARY KEY (id) + ); + CREATE TABLE language ( - id INTEGER NOT NULL, - code TEXT, - PRIMARY KEY (id) -); + id INTEGER NOT NULL, + code TEXT, + PRIMARY KEY (id) + ); + CREATE TABLE mailinglist ( id INTEGER NOT NULL, -- List identity @@ -80,7 +90,7 @@ CREATE TABLE mailinglist ( list_id TEXT, include_list_post_header BOOLEAN, include_rfc2369_headers BOOLEAN, - -- Attributes not directly modifiable via the web u/i + -- Attributes not directly modifiable via the web u/i created_at TIMESTAMP, admin_member_chunksize INTEGER, next_request_id INTEGER, diff --git a/src/mailman/database/member.py b/src/mailman/database/member.py index 22bf042f6..4a158a11e 100644 --- a/src/mailman/database/member.py +++ b/src/mailman/database/member.py @@ -28,7 +28,7 @@ from storm.locals import * from zope.interface import implements from mailman.config import config -from mailman.constants import SystemDefaultPreferences +from mailman.constants import system_preferences from mailman.database.model import Model from mailman.database.types import Enum from mailman.interfaces.member import IMember @@ -69,7 +69,7 @@ class Member(Model): pref = getattr(self.address.user.preferences, preference) if pref is not None: return pref - return getattr(SystemDefaultPreferences, preference) + return getattr(system_preferences, preference) @property def acknowledge_posts(self): |
