summaryrefslogtreecommitdiff
path: root/src/mailman/model/mailinglist.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/model/mailinglist.py')
-rw-r--r--src/mailman/model/mailinglist.py74
1 files changed, 71 insertions, 3 deletions
diff --git a/src/mailman/model/mailinglist.py b/src/mailman/model/mailinglist.py
index f04c534e1..0a5b20dd8 100644
--- a/src/mailman/model/mailinglist.py
+++ b/src/mailman/model/mailinglist.py
@@ -37,8 +37,9 @@ 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, IListArchiver, IListArchiverSet,
- IMailingList, Personalization, ReplyToMunging, SubscriptionPolicy)
+ IAcceptableAlias, IAcceptableAliasSet, IHeaderMatch, IHeaderMatchSet,
+ IListArchiver, IListArchiverSet, IMailingList, Personalization,
+ ReplyToMunging, SubscriptionPolicy)
from mailman.interfaces.member import (
AlreadySubscribedError, MemberRole, MissingPreferredAddressError,
SubscriptionEvent)
@@ -57,6 +58,7 @@ from sqlalchemy import (
LargeBinary, PickleType, Unicode)
from sqlalchemy.event import listen
from sqlalchemy.orm import relationship
+from sqlalchemy.orm.exc import NoResultFound
from urllib.parse import urljoin
from zope.component import getUtility
from zope.event import notify
@@ -149,7 +151,6 @@ class MailingList(Model):
gateway_to_mail = Column(Boolean)
gateway_to_news = Column(Boolean)
goodbye_message_uri = Column(Unicode)
- header_matches = Column(PickleType)
header_uri = Column(Unicode)
hold_these_nonmembers = Column(PickleType)
info = Column(Unicode)
@@ -621,3 +622,70 @@ class ListArchiverSet:
return store.query(ListArchiver).filter(
ListArchiver.mailing_list == self._mailing_list,
ListArchiver.name == archiver_name).first()
+
+
+
+@implementer(IHeaderMatch)
+class HeaderMatch(Model):
+ """See `IHeaderMatch`."""
+
+ __tablename__ = 'headermatch'
+
+ id = Column(Integer, primary_key=True)
+
+ mailing_list_id = Column(Integer, ForeignKey('mailinglist.id'))
+ mailing_list = relationship('MailingList', backref='header_matches')
+
+ header = Column(Unicode)
+ pattern = Column(Unicode)
+ chain = Column(Unicode, nullable=True)
+
+
+
+@implementer(IHeaderMatchSet)
+class HeaderMatchSet:
+ """See `IHeaderMatchSet`."""
+
+ def __init__(self, mailing_list):
+ self._mailing_list = mailing_list
+
+ @dbconnection
+ def clear(self, store):
+ """See `IHeaderMatchSet`."""
+ store.query(HeaderMatch).filter(
+ HeaderMatch.mailing_list == self._mailing_list).delete()
+
+ @dbconnection
+ def add(self, store, header, pattern, chain=None):
+ header = header.lower()
+ existing = store.query(HeaderMatch).filter(
+ HeaderMatch.mailing_list == self._mailing_list,
+ HeaderMatch.header == header,
+ HeaderMatch.pattern == pattern).count()
+ if existing > 0:
+ raise ValueError('Pattern already exists')
+ header_match = HeaderMatch(
+ mailing_list=self._mailing_list,
+ header=header, pattern=pattern, chain=chain)
+ store.add(header_match)
+
+ @dbconnection
+ def remove(self, store, header, pattern):
+ header = header.lower()
+ # Don't just filter and use delete(), or the MailingList.header_matches
+ # collection will not be updated:
+ # http://docs.sqlalchemy.org/en/rel_1_0/orm/collections.html#dynamic-relationship-loaders
+ try:
+ existing = store.query(HeaderMatch).filter(
+ HeaderMatch.mailing_list == self._mailing_list,
+ HeaderMatch.header == header,
+ HeaderMatch.pattern == pattern).one()
+ except NoResultFound:
+ raise ValueError('Pattern does not exist')
+ else:
+ self._mailing_list.header_matches.remove(existing)
+
+ @dbconnection
+ def __iter__(self, store):
+ yield from store.query(HeaderMatch).filter(
+ HeaderMatch.mailing_list == self._mailing_list)