diff options
Diffstat (limited to 'Mailman/rules')
| -rw-r--r-- | Mailman/rules/docs/administrivia.txt | 3 | ||||
| -rw-r--r-- | Mailman/rules/docs/approve.txt | 3 | ||||
| -rw-r--r-- | Mailman/rules/docs/emergency.txt | 77 | ||||
| -rw-r--r-- | Mailman/rules/docs/implicit-dest.txt | 3 | ||||
| -rw-r--r-- | Mailman/rules/docs/loop.txt | 3 | ||||
| -rw-r--r-- | Mailman/rules/docs/max-size.txt | 3 | ||||
| -rw-r--r-- | Mailman/rules/docs/moderation.txt | 5 | ||||
| -rw-r--r-- | Mailman/rules/docs/news-moderation.txt | 3 | ||||
| -rw-r--r-- | Mailman/rules/docs/no-subject.txt | 3 | ||||
| -rw-r--r-- | Mailman/rules/docs/recipients.txt | 3 | ||||
| -rw-r--r-- | Mailman/rules/docs/rules.txt | 96 | ||||
| -rw-r--r-- | Mailman/rules/docs/suspicious.txt | 3 | ||||
| -rw-r--r-- | Mailman/rules/emergency.py | 2 |
13 files changed, 116 insertions, 91 deletions
diff --git a/Mailman/rules/docs/administrivia.txt b/Mailman/rules/docs/administrivia.txt index 0e48fdd1b..de802fa85 100644 --- a/Mailman/rules/docs/administrivia.txt +++ b/Mailman/rules/docs/administrivia.txt @@ -9,8 +9,7 @@ used to catch messages posted to the list which should have been sent to the >>> from Mailman.configuration import config >>> mlist = config.db.list_manager.create(u'_xtest@example.com') >>> mlist.administrivia = True - >>> from Mailman.app.rules import find_rule - >>> rule = find_rule('administrivia') + >>> rule = config.rules['administrivia'] >>> rule.name 'administrivia' diff --git a/Mailman/rules/docs/approve.txt b/Mailman/rules/docs/approve.txt index ea07058f8..32367a76b 100644 --- a/Mailman/rules/docs/approve.txt +++ b/Mailman/rules/docs/approve.txt @@ -20,8 +20,7 @@ which is shared among all the administrators. The 'approved' rule determines whether the message contains the proper approval or not. - >>> from Mailman.app.rules import find_rule - >>> rule = find_rule('approved') + >>> rule = config.rules['approved'] >>> rule.name 'approved' diff --git a/Mailman/rules/docs/emergency.txt b/Mailman/rules/docs/emergency.txt new file mode 100644 index 000000000..685d7bcb6 --- /dev/null +++ b/Mailman/rules/docs/emergency.txt @@ -0,0 +1,77 @@ +Emergency +========= + +When the mailing list has its emergency flag set, all messages posted to the +list are held for moderator approval. + + >>> from Mailman.app.lifecycle import create_list + >>> mlist = create_list(u'_xtest@example.com') + >>> mlist.web_page_url = u'http://www.example.com/' + >>> msg = message_from_string("""\ + ... From: aperson@example.com + ... To: _xtest@example.com + ... Subject: My first post + ... Message-ID: <first> + ... + ... An important message. + ... """) + +The emergency rule is matched as part of the built-in chain. + + >>> from Mailman.configuration import config + >>> chain = config.chains['built-in'] + +The emergency rule matches if the flag is set on the mailing list. + + >>> mlist.emergency = True + >>> chain.process(mlist, msg, {}) + +There are two messages in the virgin queue. The one addressed to the original +sender will contain a token we can use to grab the held message out of the +pending requests. + + >>> from Mailman.queue import Switchboard + >>> virginq = Switchboard(config.VIRGINQUEUE_DIR) + + >>> def get_held_message(): + ... import re + ... qfiles = [] + ... for filebase in virginq.files: + ... qmsg, qdata = virginq.dequeue(filebase) + ... virginq.finish(filebase) + ... qfiles.append(qmsg) + ... from operator import itemgetter + ... qfiles.sort(key=itemgetter('to')) + ... cookie = None + ... for line in qfiles[1].get_payload().splitlines(): + ... mo = re.search('confirm/[^/]+/(?P<cookie>.*)$', line) + ... if mo: + ... cookie = mo.group('cookie') + ... break + ... assert cookie is not None, 'No confirmation token found' + ... data = config.db.pendings.confirm(cookie) + ... requestdb = config.db.requests.get_list_requests(mlist) + ... rkey, rdata = requestdb.get_request(data['id']) + ... return config.db.message_store.get_message_by_id( + ... rdata['_mod_message_id']) + + >>> msg = get_held_message() + >>> print msg.as_string() + From: aperson@example.com + To: _xtest@example.com + Subject: My first post + Message-ID: <first> + X-Mailman-Rule-Hits: emergency + X-Mailman-Rule-Misses: approved + X-Message-ID-Hash: RXJU4JL6N2OUN3OYMXXPPSCR7P7JE2BW + <BLANKLINE> + An important message. + <BLANKLINE> + +However, if the message metadata has a 'moderator_approved' key set, then even +if the mailing list has its emergency flag set, the message still goes through +to the membership. + + >>> chain.process(mlist, msg, dict(moderator_approved=True)) + >>> len(virginq.files) + 0 diff --git a/Mailman/rules/docs/implicit-dest.txt b/Mailman/rules/docs/implicit-dest.txt index b6fed2769..5a7f06c0c 100644 --- a/Mailman/rules/docs/implicit-dest.txt +++ b/Mailman/rules/docs/implicit-dest.txt @@ -6,8 +6,7 @@ not explicitly mentioned in the set of message recipients. >>> from Mailman.configuration import config >>> mlist = config.db.list_manager.create(u'_xtest@example.com') - >>> from Mailman.app.rules import find_rule - >>> rule = find_rule('implicit-dest') + >>> rule = config.rules['implicit-dest'] >>> rule.name 'implicit-dest' diff --git a/Mailman/rules/docs/loop.txt b/Mailman/rules/docs/loop.txt index 3174805b9..8fe86cf45 100644 --- a/Mailman/rules/docs/loop.txt +++ b/Mailman/rules/docs/loop.txt @@ -6,8 +6,7 @@ X-BeenThere header with the value of the list's posting address. >>> from Mailman.configuration import config >>> mlist = config.db.list_manager.create(u'_xtest@example.com') - >>> from Mailman.app.rules import find_rule - >>> rule = find_rule('loop') + >>> rule = config.rules['loop'] >>> rule.name 'loop' diff --git a/Mailman/rules/docs/max-size.txt b/Mailman/rules/docs/max-size.txt index b477ecd2b..0d64b0cf7 100644 --- a/Mailman/rules/docs/max-size.txt +++ b/Mailman/rules/docs/max-size.txt @@ -8,8 +8,7 @@ bytes). >>> from Mailman.configuration import config >>> mlist = config.db.list_manager.create(u'_xtest@example.com') - >>> from Mailman.app.rules import find_rule - >>> rule = find_rule('max-size') + >>> rule = config.rules['max-size'] >>> rule.name 'max-size' diff --git a/Mailman/rules/docs/moderation.txt b/Mailman/rules/docs/moderation.txt index 0ce6bee6e..cab8f20d3 100644 --- a/Mailman/rules/docs/moderation.txt +++ b/Mailman/rules/docs/moderation.txt @@ -8,8 +8,7 @@ email the list without having those messages be held for approval. The >>> from Mailman.configuration import config >>> mlist = config.db.list_manager.create(u'_xtest@example.com') - >>> from Mailman.app.rules import find_rule - >>> rule = find_rule('moderation') + >>> rule = config.rules['moderation'] >>> rule.name 'moderation' @@ -50,7 +49,7 @@ Non-members There is another, related rule for matching non-members, which simply matches if the sender is /not/ a member of the mailing list. - >>> rule = find_rule('non-member') + >>> rule = config.rules['non-member'] >>> rule.name 'non-member' diff --git a/Mailman/rules/docs/news-moderation.txt b/Mailman/rules/docs/news-moderation.txt index f69fbb33d..f32919ce5 100644 --- a/Mailman/rules/docs/news-moderation.txt +++ b/Mailman/rules/docs/news-moderation.txt @@ -10,8 +10,7 @@ directly to the mailing list. >>> from Mailman.configuration import config >>> mlist = config.db.list_manager.create(u'_xtest@example.com') - >>> from Mailman.app.rules import find_rule - >>> rule = find_rule('news-moderation') + >>> rule = config.rules['news-moderation'] >>> rule.name 'news-moderation' diff --git a/Mailman/rules/docs/no-subject.txt b/Mailman/rules/docs/no-subject.txt index 3c6dc88bf..3627ac03f 100644 --- a/Mailman/rules/docs/no-subject.txt +++ b/Mailman/rules/docs/no-subject.txt @@ -6,8 +6,7 @@ the empty string when stripped. >>> from Mailman.configuration import config >>> mlist = config.db.list_manager.create(u'_xtest@example.com') - >>> from Mailman.app.rules import find_rule - >>> rule = find_rule('no-subject') + >>> rule = config.rules['no-subject'] >>> rule.name 'no-subject' diff --git a/Mailman/rules/docs/recipients.txt b/Mailman/rules/docs/recipients.txt index 98176c8bb..21d04b8ae 100644 --- a/Mailman/rules/docs/recipients.txt +++ b/Mailman/rules/docs/recipients.txt @@ -6,8 +6,7 @@ number of explicit recipients addressed by the message. >>> from Mailman.configuration import config >>> mlist = config.db.list_manager.create(u'_xtest@example.com') - >>> from Mailman.app.rules import find_rule - >>> rule = find_rule('max-recipients') + >>> rule = config.rules['max-recipients'] >>> rule.name 'max-recipients' diff --git a/Mailman/rules/docs/rules.txt b/Mailman/rules/docs/rules.txt index b9606663c..1f5b147e7 100644 --- a/Mailman/rules/docs/rules.txt +++ b/Mailman/rules/docs/rules.txt @@ -1,63 +1,41 @@ Rules ===== -The rule processor is used to determine the status of a message. Should the -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)? +Rules are applied to each message as part of a rule chain. Individual rules +simply return a boolean specifying whether the rule matches or not. Chain +links determine what happens when a rule matches. -Actually, these actions are not part of rule processing! Instead, Mailman -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 sets +All rules --------- -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'. +Rules are maintained in the configuration object as a dictionary mapping rule +names to rule objects. >>> from zope.interface.verify import verifyObject - >>> from Mailman.interfaces import IRuleSet - >>> from Mailman.rules import BuiltinRules - >>> rule_set = BuiltinRules() - >>> verifyObject(IRuleSet, rule_set) - True - -You can iterator over all the rules in a rule set. - + >>> from Mailman.configuration import config >>> from Mailman.interfaces import IRule - >>> rule = None - >>> for rule in rule_set.rules: - ... if rule.name == 'emergency': - ... break - >>> verifyObject(IRule, rule) - True - >>> rule.name - 'emergency' - >>> print rule.description - The mailing list is in emergency hold and this message was not pre-approved - by the list administrator. + >>> for rule_name in sorted(config.rules): + ... rule = config.rules[rule_name] + ... print rule_name, verifyObject(IRule, rule) + administrivia True + any True + approved True + emergency True + implicit-dest True + loop True + max-recipients True + max-size True + moderation True + news-moderation True + no-subject True + non-member True + suspicious-header True -You can ask for a rule by name. +You can get a rule by name. - >>> rule_set['emergency'].name - 'emergency' - >>> rule_set.get('emergency').name - 'emergency' - -Rule sets act like dictionaries when the rule is missing. - - >>> rule_set['no such rule'] - Traceback (most recent call last): - ... - KeyError: 'no such rule' - >>> print rule_set.get('no such rule') - None - >>> missing = object() - >>> rule_set.get('no such rule', missing) is missing + >>> rule = config.rules['emergency'] + >>> verifyObject(IRule, rule) True @@ -68,7 +46,6 @@ Individual rules can be checked to see if they match, by running the rule's `check()` method. This returns a boolean indicating whether the rule was matched or not. - >>> from Mailman.configuration import config >>> mlist = config.db.list_manager.create(u'_xtest@example.com') >>> msg = message_from_string("""\ ... From: aperson@example.com @@ -80,7 +57,6 @@ 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 = rule_set['emergency'] >>> rule.name 'emergency' >>> mlist.emergency = False @@ -89,23 +65,5 @@ administrator. >>> mlist.emergency = True >>> rule.check(mlist, msg, {}) True - >>> rule.check(mlist, msg, dict(adminapproved=True)) + >>> rule.check(mlist, msg, dict(moderator_approved=True)) False - - -Rule processing ---------------- - -Mailman has a global rule processor which will return a set of all the rule -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 - >>> process(mlist, msg, {}, emergency_only) - set(['emergency']) - >>> process(mlist, msg, dict(adminapproved=True), emergency_only) - set([]) - >>> mlist.emergency = False - >>> process(mlist, msg, {}, emergency_only) - set([]) diff --git a/Mailman/rules/docs/suspicious.txt b/Mailman/rules/docs/suspicious.txt index 8646e1b81..6b0eeda35 100644 --- a/Mailman/rules/docs/suspicious.txt +++ b/Mailman/rules/docs/suspicious.txt @@ -7,8 +7,7 @@ confusing to users, and the list attribute that controls this is misnamed. >>> from Mailman.configuration import config >>> mlist = config.db.list_manager.create(u'_xtest@example.com') - >>> from Mailman.app.rules import find_rule - >>> rule = find_rule('suspicious-header') + >>> rule = config.rules['suspicious-header'] >>> rule.name 'suspicious-header' diff --git a/Mailman/rules/emergency.py b/Mailman/rules/emergency.py index e51612940..0e6aa97b4 100644 --- a/Mailman/rules/emergency.py +++ b/Mailman/rules/emergency.py @@ -39,4 +39,4 @@ the list administrator.""") def check(self, mlist, msg, msgdata): """See `IRule`.""" - return mlist.emergency and not msgdata.get('adminapproved') + return mlist.emergency and not msgdata.get('moderator_approved') |
