diff options
| author | Barry Warsaw | 2008-02-27 01:26:18 -0500 |
|---|---|---|
| committer | Barry Warsaw | 2008-02-27 01:26:18 -0500 |
| commit | a1c73f6c305c7f74987d99855ba59d8fa823c253 (patch) | |
| tree | 65696889450862357c9e05c8e9a589f1bdc074ac /Mailman/chains/headers.py | |
| parent | 3f31f8cce369529d177cfb5a7c66346ec1e12130 (diff) | |
| download | mailman-a1c73f6c305c7f74987d99855ba59d8fa823c253.tar.gz mailman-a1c73f6c305c7f74987d99855ba59d8fa823c253.tar.zst mailman-a1c73f6c305c7f74987d99855ba59d8fa823c253.zip | |
Diffstat (limited to 'Mailman/chains/headers.py')
| -rw-r--r-- | Mailman/chains/headers.py | 151 |
1 files changed, 0 insertions, 151 deletions
diff --git a/Mailman/chains/headers.py b/Mailman/chains/headers.py deleted file mode 100644 index 06dfafeda..000000000 --- a/Mailman/chains/headers.py +++ /dev/null @@ -1,151 +0,0 @@ -# Copyright (C) 2007-2008 by the Free Software Foundation, Inc. -# -# This program 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 2 -# of the License, or (at your option) any later version. -# -# This program 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 this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, -# USA. - -"""The header-matching chain.""" - -__all__ = ['HeaderMatchChain'] -__metaclass__ = type - - -import re -import logging -import itertools - -from zope.interface import implements - -from Mailman.interfaces import IChainIterator, IRule, LinkAction -from Mailman.chains.base import Chain, Link -from Mailman.i18n import _ -from Mailman.configuration import config - - -log = logging.getLogger('mailman.vette') - - - -def make_link(entry): - """Create a Link object. - - :param entry: a 2- or 3-tuple describing a link. If a 2-tuple, it is a - header and a pattern, and a default chain of 'hold' will be used. If - a 3-tuple, the third item is the chain name to use. - :return: an ILink. - """ - if len(entry) == 2: - header, pattern = entry - chain_name = 'hold' - elif len(entry) == 3: - header, pattern, chain_name = entry - # We don't assert that the chain exists here because the jump - # chain may not yet have been created. - else: - raise AssertionError('Bad link description: %s' % entry) - rule = HeaderMatchRule(header, pattern) - chain = config.chains[chain_name] - return Link(rule, LinkAction.jump, chain) - - - -class HeaderMatchRule: - """Header matching rule used by header-match chain.""" - implements(IRule) - - # Sequential rule counter. - _count = 1 - - def __init__(self, header, pattern): - self._header = header - self._pattern = pattern - self.name = 'header-match-%002d' % HeaderMatchRule._count - HeaderMatchRule._count += 1 - self.description = u'%s: %s' % (header, pattern) - # XXX I think we should do better here, somehow recording that a - # particular header matched a particular pattern, but that gets ugly - # with RFC 2822 headers. It also doesn't match well with the rule - # name concept. For now, we just record the rather useless numeric - # rule name. I suppose we could do the better hit recording in the - # check() method, and set self.record = False. - self.record = True - - def check(self, mlist, msg, msgdata): - """See `IRule`.""" - for value in msg.get_all(self._header, []): - if re.search(self._pattern, value, re.IGNORECASE): - return True - return False - - - -class HeaderMatchChain(Chain): - """Default header matching chain. - - This could be extended by header match rules in the database. - """ - - def __init__(self): - super(HeaderMatchChain, self).__init__( - 'header-match', _('The built-in header matching chain')) - # The header match rules are not global, so don't register them. - # These are the only rules that the header match chain can execute. - self._links = [] - # Initialize header check rules with those from the global - # HEADER_MATCHES variable. - for entry in config.HEADER_MATCHES: - self._links.append(make_link(entry)) - # Keep track of how many global header matching rules we've seen. - # This is so the flush() method will only delete those that were added - # via extend() or append_link(). - self._permanent_link_count = len(self._links) - - def extend(self, header, pattern, chain_name='hold'): - """Extend the existing header matches. - - :param header: The case-insensitive header field name. - :param pattern: The pattern to match the header's value again. The - match is not anchored and is done case-insensitively. - :param chain: Option chain to jump to if the pattern matches any of - the named header values. If not given, the 'hold' chain is used. - """ - self._links.append(make_link((header, pattern, chain_name))) - - def flush(self): - """See `IMutableChain`.""" - del self._links[self._permanent_link_count:] - - def get_links(self, mlist, msg, msgdata): - """See `IChain`.""" - list_iterator = HeaderMatchIterator(mlist) - return itertools.chain(iter(self._links), iter(list_iterator)) - - def __iter__(self): - for link in self._links: - yield link - - - -class HeaderMatchIterator: - """An iterator of both the global and list-specific chain links.""" - - implements(IChainIterator) - - def __init__(self, mlist): - self._mlist = mlist - - def __iter__(self): - """See `IChainIterator`.""" - for entry in self._mlist.header_matches: - yield make_link(entry) |
