diff options
| author | Barry Warsaw | 2007-12-27 23:25:50 -0500 |
|---|---|---|
| committer | Barry Warsaw | 2007-12-27 23:25:50 -0500 |
| commit | 306a1ceee0aad4c623f029d8809b40f7f55b9a6f (patch) | |
| tree | a880cc16e333a785fd3cdcd469dc388407568ba2 | |
| parent | 13dea3a6736834e19ad569b5e3d70a79e096a55e (diff) | |
| download | mailman-306a1ceee0aad4c623f029d8809b40f7f55b9a6f.tar.gz mailman-306a1ceee0aad4c623f029d8809b40f7f55b9a6f.tar.zst mailman-306a1ceee0aad4c623f029d8809b40f7f55b9a6f.zip | |
| -rw-r--r-- | Mailman/app/rules.py | 23 | ||||
| -rw-r--r-- | Mailman/docs/rules.txt | 55 | ||||
| -rw-r--r-- | Mailman/interfaces/rules.py (renamed from Mailman/interfaces/rule.py) | 11 | ||||
| -rwxr-xr-x | Mailman/rules/__init__.py | 20 |
4 files changed, 52 insertions, 57 deletions
diff --git a/Mailman/app/rules.py b/Mailman/app/rules.py index 3e83eb60c..152694177 100644 --- a/Mailman/app/rules.py +++ b/Mailman/app/rules.py @@ -21,15 +21,26 @@ from Mailman.app.plugins import get_plugins -def process(mlist, msg, msgdata): +def process(mlist, msg, msgdata, rule_set=None): """Default rule processing plugin. + Rules are processed in random order so a rule should not permanently alter + a message or the message metadata. + :param msg: The message object. :param msgdata: The message metadata. + :param rule_set: The name of the rules to run. None (the default) means + to run all available rules. :return: A set of rule names that matched. """ - rule_hits = set() - for processor_class in get_plugins('mailman.rules'): - processor = processor_class() - rule_hits |= processor.process(mlist, msg, msgdata) - return rule_hits + # Collect all rules from all rule processors. + rules = set() + for rule_set_class in get_plugins('mailman.rules'): + rules |= set(rule for rule in rule_set_class().rules + if rule_set is None or rule.name in rule_set) + # Now process all rules, returning the set of rules that match. + rule_matches = set() + for rule in rules: + if rule.check(mlist, msg, msgdata): + rule_matches.add(rule.name) + return rule_matches diff --git a/Mailman/docs/rules.txt b/Mailman/docs/rules.txt index 6f7c8b680..dbf009eeb 100644 --- a/Mailman/docs/rules.txt +++ b/Mailman/docs/rules.txt @@ -6,31 +6,31 @@ message be posted to the list, or held for moderator approval? Should the message be discarded or rejected (i.e. bounced back to the original sender)? Actually, these actions are not part of rule processing! Instead, Mailman -first runs through a set of rules looking for matches. Then later, the -matched rules are prioritized and matched to an action. Action matching is -described elsewhere; this documentation describes only the rule processing -system. +first runs through the set of available and requested rules looking for +matches. Then later, the matched rules are prioritized and matched to an +action. Action matching is described elsewhere; this documentation describes +only the rule processing system. -Rule processors -=============== +Rule sets +========= -IRuleProcessor is the interface that describes a rule processor. Mailman can -be extended by plugging in additional rule processors, but it also comes with -a default rule processor, called the 'built-in rule processor'. +IRuleSet is the interface that describes a set of rules. Mailman can be +extended by plugging in additional rule sets, but it also comes with a default +rule set, called the 'built-in rule set'. >>> from zope.interface.verify import verifyObject - >>> from Mailman.interfaces import IRuleProcessor + >>> from Mailman.interfaces import IRuleSet >>> from Mailman.rules import BuiltinRules - >>> processor = BuiltinRules() - >>> verifyObject(IRuleProcessor, processor) + >>> rule_set = BuiltinRules() + >>> verifyObject(IRuleSet, rule_set) True -You can iterator over all the rules in a rule processor. +You can iterator over all the rules in a rule set. >>> from Mailman.interfaces import IRule >>> rule = None - >>> for rule in processor.rules: + >>> for rule in rule_set.rules: ... if rule.name == 'emergency': ... break >>> verifyObject(IRule, rule) @@ -43,21 +43,21 @@ You can iterator over all the rules in a rule processor. You can ask for a rule by name. - >>> processor['emergency'].name + >>> rule_set['emergency'].name 'emergency' - >>> processor.get('emergency').name + >>> rule_set.get('emergency').name 'emergency' -Processors act like dictionaries when the rule is missing. +Rule sets act like dictionaries when the rule is missing. - >>> processor['no such rule'] + >>> rule_set['no such rule'] Traceback (most recent call last): ... KeyError: 'no such rule' - >>> print processor.get('no such rule') + >>> print rule_set.get('no such rule') None >>> missing = object() - >>> processor.get('no such rule', missing) is missing + >>> rule_set.get('no such rule', missing) is missing True @@ -80,7 +80,7 @@ For example, the emergency rule just checks to see if the emergency flag is set on the mailing list, and the message has not been pre-approved by the list administrator. - >>> rule = processor['emergency'] + >>> rule = rule_set['emergency'] >>> rule.name 'emergency' >>> mlist.emergency = False @@ -97,16 +97,15 @@ Rule processing --------------- Mailman has a global rule processor which will return a set of all the rule -names that match the current message. +names that match the current message. You can limit the set of rules the +processor will check by passing in a set of requested rule names. + >>> emergency_only = set(['emergency']) >>> from Mailman.app.rules import process - >>> matches = process(mlist, msg, {}) - >>> matches & set(['emergency']) + >>> process(mlist, msg, {}, emergency_only) set(['emergency']) - >>> matches = process(mlist, msg, dict(adminapproved=True)) - >>> matches & set(['emergency']) + >>> process(mlist, msg, dict(adminapproved=True), emergency_only) set([]) >>> mlist.emergency = False - >>> matches = process(mlist, msg, {}) - >>> matches & set(['emergency']) + >>> process(mlist, msg, {}, emergency_only) set([]) diff --git a/Mailman/interfaces/rule.py b/Mailman/interfaces/rules.py index c0cf71697..5ef741852 100644 --- a/Mailman/interfaces/rule.py +++ b/Mailman/interfaces/rules.py @@ -42,18 +42,9 @@ class IRule(Interface): -class IRuleProcessor(Interface): +class IRuleSet(Interface): """A rule processor.""" - def process(mlist, msg, msgdata): - """Run all rules this processor knows about. - - :param mlist: The mailing list this message was posted to. - :param msg: The message object. - :param msgdata: The message metadata. - :return: A set of rule names that matched. - """ - rules = Attribute('The set of all rules this processor knows about') def __getitem__(rule_name): diff --git a/Mailman/rules/__init__.py b/Mailman/rules/__init__.py index b7459299b..2d2f5d0a8 100755 --- a/Mailman/rules/__init__.py +++ b/Mailman/rules/__init__.py @@ -15,7 +15,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. -"""Built in rule processor.""" +"""The built in rule set.""" __all__ = ['BuiltinRules'] __metaclass__ = type @@ -25,14 +25,15 @@ import os import sys from zope.interface import implements -from Mailman.interfaces import DuplicateRuleError, IRule, IRuleProcessor +from Mailman.interfaces import DuplicateRuleError, IRule, IRuleSet class BuiltinRules: - implements(IRuleProcessor) + implements(IRuleSet) def __init__(self): + """The set of all built-in rules.""" self._rules = {} rule_set = set() # Find all rules found in all modules inside our package. @@ -53,23 +54,16 @@ class BuiltinRules: self._rules[rule.name] = rule rule_set.add(rule) - def process(self, mlist, msg, msgdata): - """See `IRuleProcessor`.""" - hits = set() - for rule in self._rules.values(): - if rule.check(mlist, msg, msgdata): - hits.add(rule.name) - return hits - def __getitem__(self, rule_name): - """See `IRuleProcessor`.""" + """See `IRuleSet`.""" return self._rules[rule_name] def get(self, rule_name, default=None): - """See `IRuleProcessor`.""" + """See `IRuleSet`.""" return self._rules.get(rule_name, default) @property def rules(self): + """See `IRuleSet`.""" for rule in self._rules.values(): yield rule |
