diff options
| author | Barry Warsaw | 2008-01-01 13:49:27 -0500 |
|---|---|---|
| committer | Barry Warsaw | 2008-01-01 13:49:27 -0500 |
| commit | adae635a4ca147937019fdd91aebd95a2769b9ca (patch) | |
| tree | 7cdae81b4b7715781e889f32bbd0dbba80609367 /Mailman/docs | |
| parent | 5b4bb22feca4d520afef44d1c472807e020d17b5 (diff) | |
| download | mailman-adae635a4ca147937019fdd91aebd95a2769b9ca.tar.gz mailman-adae635a4ca147937019fdd91aebd95a2769b9ca.tar.zst mailman-adae635a4ca147937019fdd91aebd95a2769b9ca.zip | |
Extended test_documentation.py to be able to find doctests in subdirectories
called 'docs' anywhere under the Mailman package. Change the rule API to
return rule classes not instances. Added the ChainJump enum, though this will
likely change soon.
Diffstat (limited to 'Mailman/docs')
| -rw-r--r-- | Mailman/docs/administrivia.txt | 101 | ||||
| -rw-r--r-- | Mailman/docs/approve.txt | 474 | ||||
| -rw-r--r-- | Mailman/docs/implicit-dest.txt | 77 | ||||
| -rw-r--r-- | Mailman/docs/loop.txt | 50 | ||||
| -rw-r--r-- | Mailman/docs/max-size.txt | 41 | ||||
| -rw-r--r-- | Mailman/docs/moderation.txt | 71 | ||||
| -rw-r--r-- | Mailman/docs/news-moderation.txt | 38 | ||||
| -rw-r--r-- | Mailman/docs/no-subject.txt | 35 | ||||
| -rw-r--r-- | Mailman/docs/recipients.txt | 42 | ||||
| -rw-r--r-- | Mailman/docs/rules.txt | 111 | ||||
| -rw-r--r-- | Mailman/docs/suspicious.txt | 37 |
11 files changed, 0 insertions, 1077 deletions
diff --git a/Mailman/docs/administrivia.txt b/Mailman/docs/administrivia.txt deleted file mode 100644 index 0e48fdd1b..000000000 --- a/Mailman/docs/administrivia.txt +++ /dev/null @@ -1,101 +0,0 @@ -Administrivia -============= - -The 'administrivia' rule matches when the message contains some common email -commands in the Subject header or first few lines of the payload. This is -used to catch messages posted to the list which should have been sent to the --request robot address. - - >>> 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.name - 'administrivia' - -For example, if the Subject header contains the word 'unsubscribe', the rule -matches. - - >>> msg_1 = message_from_string(u"""\ - ... From: aperson@example.com - ... Subject: unsubscribe - ... - ... """) - >>> rule.check(mlist, msg_1, {}) - True - -Similarly, if the body of the message contains the word 'subscribe' in the -first few lines of text, the rule matches. - - >>> msg_2 = message_from_string(u"""\ - ... From: aperson@example.com - ... Subject: I wish to join your list - ... - ... subscribe - ... """) - >>> rule.check(mlist, msg_2, {}) - True - -In both cases, administrivia checking can be disabled. - - >>> mlist.administrivia = False - >>> rule.check(mlist, msg_1, {}) - False - >>> rule.check(mlist, msg_2, {}) - False - -To make the administrivia heuristics a little more robust, the rule actually -looks for a minimum and maximum number of arguments, so that it really does -seem like a mis-addressed email command. In this case, the 'confirm' command -requires at least one argument. We don't give that here so the rule will not -match. - - >>> mlist.administrivia = True - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... Subject: confirm - ... - ... """) - >>> rule.check(mlist, msg, {}) - False - -But a real 'confirm' message will match. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... Subject: confirm 12345 - ... - ... """) - >>> rule.check(mlist, msg, {}) - True - -We don't show all the other possible email commands, but you get the idea. - - -Non-administrivia ------------------ - -Of course, messages that don't contain administrivia, don't match the rule. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... Subject: examine - ... - ... persuade - ... """) - >>> rule.check(mlist, msg, {}) - False - -Also, only text/plain parts are checked for administrivia, so any email -commands in other content type subparts are ignored. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... Subject: some administrivia - ... Content-Type: text/x-special - ... - ... subscribe - ... """) - >>> rule.check(mlist, msg, {}) - False diff --git a/Mailman/docs/approve.txt b/Mailman/docs/approve.txt deleted file mode 100644 index ea07058f8..000000000 --- a/Mailman/docs/approve.txt +++ /dev/null @@ -1,474 +0,0 @@ -Pre-approved postings -===================== - -Messages can contain a pre-approval, which is used to bypass the message -approval queue. This has several use cases: - -- A list administrator can send an emergency message to the mailing list from - an unregistered address, say if they are away from their normal email. - -- An automated script can be programmed to send a message to an otherwise - moderated list. - -In order to support this, a mailing list can be given a 'moderator password' -which is shared among all the administrators. - - >>> from Mailman.configuration import config - >>> mlist = config.db.list_manager.create(u'_xtest@example.com') - >>> mlist.moderator_password = u'abcxyz' - -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.name - 'approved' - - -No approval ------------ - -If the message has no Approve or Approved header, then the rule does not -match. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... - ... An important message. - ... """) - >>> rule.check(mlist, msg, {}) - False - -If the message has an Approve or Approved header with a value that does not -match the moderator password, then the rule does not match. However, the -header is still removed. - - >>> msg['Approve'] = u'12345' - >>> rule.check(mlist, msg, {}) - False - >>> print msg['approve'] - None - - >>> del msg['approve'] - >>> msg['Approved'] = u'12345' - >>> rule.check(mlist, msg, {}) - False - >>> print msg['approved'] - None - - >>> del msg['approved'] - - -Using an approval header ------------------------- - -If the moderator password is given in an Approve header, then the rule -matches, and the Approve header is stripped. - - >>> msg['Approve'] = u'abcxyz' - >>> rule.check(mlist, msg, {}) - True - >>> print msg['approve'] - None - -Similarly, for the Approved header. - - >>> msg['Approved'] = u'abcxyz' - >>> rule.check(mlist, msg, {}) - True - >>> print msg['approved'] - None - - -Using a pseudo-header ---------------------- - -Different mail user agents have varying degrees to which they support custom -headers like Approve and Approved. For this reason, Mailman also supports -using a 'pseudo-header', which is really just the first non-whitespace line in -the payload of the message. If this pseudo-header looks like a matching -Approve or Approved header, the message is similarly allowed to pass. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... - ... Approve: abcxyz - ... An important message. - ... """) - >>> rule.check(mlist, msg, {}) - True - -The pseudo-header is removed. - - >>> print msg.as_string() - From: aperson@example.com - Content-Transfer-Encoding: 7bit - MIME-Version: 1.0 - Content-Type: text/plain; charset="us-ascii" - <BLANKLINE> - An important message. - <BLANKLINE> - -Similarly for the Approved header. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... - ... Approved: abcxyz - ... An important message. - ... """) - >>> rule.check(mlist, msg, {}) - True - - >>> print msg.as_string() - From: aperson@example.com - Content-Transfer-Encoding: 7bit - MIME-Version: 1.0 - Content-Type: text/plain; charset="us-ascii" - <BLANKLINE> - An important message. - <BLANKLINE> - -As before, a mismatch in the pseudo-header does not approve the message, but -the pseudo-header line is still removed. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... - ... Approve: 123456 - ... An important message. - ... """) - >>> rule.check(mlist, msg, {}) - False - - >>> print msg.as_string() - From: aperson@example.com - Content-Transfer-Encoding: 7bit - MIME-Version: 1.0 - Content-Type: text/plain; charset="us-ascii" - <BLANKLINE> - An important message. - <BLANKLINE> - -Similarly for the Approved header. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... - ... Approved: 123456 - ... An important message. - ... """) - >>> rule.check(mlist, msg, {}) - False - - >>> print msg.as_string() - From: aperson@example.com - Content-Transfer-Encoding: 7bit - MIME-Version: 1.0 - Content-Type: text/plain; charset="us-ascii" - <BLANKLINE> - An important message. - <BLANKLINE> - - -MIME multipart support ----------------------- - -Mailman searches for the pseudo-header as the first non-whitespace line in the -first text/plain message part of the message. This allows the feature to be -used with MIME documents. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... MIME-Version: 1.0 - ... Content-Type: multipart/mixed; boundary="AAA" - ... - ... --AAA - ... Content-Type: application/x-ignore - ... - ... Approve: 123456 - ... The above line will be ignored. - ... - ... --AAA - ... Content-Type: text/plain - ... - ... Approve: abcxyz - ... An important message. - ... --AAA-- - ... """) - >>> rule.check(mlist, msg, {}) - True - -Like before, the pseudo-header is removed, but only from the text parts. - - >>> print msg.as_string() - From: aperson@example.com - MIME-Version: 1.0 - Content-Type: multipart/mixed; boundary="AAA" - <BLANKLINE> - --AAA - Content-Type: application/x-ignore - <BLANKLINE> - Approve: 123456 - The above line will be ignored. - <BLANKLINE> - --AAA - Content-Transfer-Encoding: 7bit - MIME-Version: 1.0 - Content-Type: text/plain; charset="us-ascii" - <BLANKLINE> - An important message. - --AAA-- - <BLANKLINE> - -The same goes for the Approved message. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... MIME-Version: 1.0 - ... Content-Type: multipart/mixed; boundary="AAA" - ... - ... --AAA - ... Content-Type: application/x-ignore - ... - ... Approved: 123456 - ... The above line will be ignored. - ... - ... --AAA - ... Content-Type: text/plain - ... - ... Approved: abcxyz - ... An important message. - ... --AAA-- - ... """) - >>> rule.check(mlist, msg, {}) - True - -And the header is removed. - - >>> print msg.as_string() - From: aperson@example.com - MIME-Version: 1.0 - Content-Type: multipart/mixed; boundary="AAA" - <BLANKLINE> - --AAA - Content-Type: application/x-ignore - <BLANKLINE> - Approved: 123456 - The above line will be ignored. - <BLANKLINE> - --AAA - Content-Transfer-Encoding: 7bit - MIME-Version: 1.0 - Content-Type: text/plain; charset="us-ascii" - <BLANKLINE> - An important message. - --AAA-- - <BLANKLINE> - -Here, the correct password is in the non-text/plain part, so it is ignored. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... MIME-Version: 1.0 - ... Content-Type: multipart/mixed; boundary="AAA" - ... - ... --AAA - ... Content-Type: application/x-ignore - ... - ... Approve: abcxyz - ... The above line will be ignored. - ... - ... --AAA - ... Content-Type: text/plain - ... - ... Approve: 123456 - ... An important message. - ... --AAA-- - ... """) - >>> rule.check(mlist, msg, {}) - False - -And yet the pseudo-header is still stripped. - - >>> print msg.as_string() - From: aperson@example.com - MIME-Version: 1.0 - Content-Type: multipart/mixed; boundary="AAA" - <BLANKLINE> - --AAA - Content-Type: application/x-ignore - <BLANKLINE> - Approve: abcxyz - The above line will be ignored. - <BLANKLINE> - --AAA - Content-Transfer-Encoding: 7bit - MIME-Version: 1.0 - Content-Type: text/plain; charset="us-ascii" - <BLANKLINE> - An important message. - --AAA-- - -As before, the same goes for the Approved header. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... MIME-Version: 1.0 - ... Content-Type: multipart/mixed; boundary="AAA" - ... - ... --AAA - ... Content-Type: application/x-ignore - ... - ... Approved: abcxyz - ... The above line will be ignored. - ... - ... --AAA - ... Content-Type: text/plain - ... - ... Approved: 123456 - ... An important message. - ... --AAA-- - ... """) - >>> rule.check(mlist, msg, {}) - False - -And the pseudo-header is removed. - - >>> print msg.as_string() - From: aperson@example.com - MIME-Version: 1.0 - Content-Type: multipart/mixed; boundary="AAA" - <BLANKLINE> - --AAA - Content-Type: application/x-ignore - <BLANKLINE> - Approved: abcxyz - The above line will be ignored. - <BLANKLINE> - --AAA - Content-Transfer-Encoding: 7bit - MIME-Version: 1.0 - Content-Type: text/plain; charset="us-ascii" - <BLANKLINE> - An important message. - --AAA-- - - -Stripping text/html parts -------------------------- - -Because some mail readers will include both a text/plain part and a text/html -alternative, the 'approved' rule has to search the alternatives and strip -anything that looks like an Approve or Approved headers. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... MIME-Version: 1.0 - ... Content-Type: multipart/mixed; boundary="AAA" - ... - ... --AAA - ... Content-Type: text/html - ... - ... <html> - ... <head></head> - ... <body> - ... <b>Approved: abcxyz</b> - ... <p>The above line will be ignored. - ... </body> - ... </html> - ... - ... --AAA - ... Content-Type: text/plain - ... - ... Approved: abcxyz - ... An important message. - ... --AAA-- - ... """) - >>> rule.check(mlist, msg, {}) - True - -And the header-like text in the text/html part was stripped. - - >>> print msg.as_string() - From: aperson@example.com - MIME-Version: 1.0 - Content-Type: multipart/mixed; boundary="AAA" - <BLANKLINE> - --AAA - Content-Transfer-Encoding: 7bit - MIME-Version: 1.0 - Content-Type: text/html; charset="us-ascii" - <BLANKLINE> - <html> - <head></head> - <body> - <b></b> - <p>The above line will be ignored. - </body> - </html> - <BLANKLINE> - --AAA - Content-Transfer-Encoding: 7bit - MIME-Version: 1.0 - Content-Type: text/plain; charset="us-ascii" - <BLANKLINE> - An important message. - --AAA-- - <BLANKLINE> - -This is true even if the rule does not match. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... MIME-Version: 1.0 - ... Content-Type: multipart/mixed; boundary="AAA" - ... - ... --AAA - ... Content-Type: text/html - ... - ... <html> - ... <head></head> - ... <body> - ... <b>Approve: 123456</b> - ... <p>The above line will be ignored. - ... </body> - ... </html> - ... - ... --AAA - ... Content-Type: text/plain - ... - ... Approve: 123456 - ... An important message. - ... --AAA-- - ... """) - >>> rule.check(mlist, msg, {}) - False - - >>> print msg.as_string() - From: aperson@example.com - MIME-Version: 1.0 - Content-Type: multipart/mixed; boundary="AAA" - <BLANKLINE> - --AAA - Content-Transfer-Encoding: 7bit - MIME-Version: 1.0 - Content-Type: text/html; charset="us-ascii" - <BLANKLINE> - <html> - <head></head> - <body> - <b></b> - <p>The above line will be ignored. - </body> - </html> - <BLANKLINE> - --AAA - Content-Transfer-Encoding: 7bit - MIME-Version: 1.0 - Content-Type: text/plain; charset="us-ascii" - <BLANKLINE> - An important message. - --AAA-- - <BLANKLINE> diff --git a/Mailman/docs/implicit-dest.txt b/Mailman/docs/implicit-dest.txt deleted file mode 100644 index b6fed2769..000000000 --- a/Mailman/docs/implicit-dest.txt +++ /dev/null @@ -1,77 +0,0 @@ -Implicit destination -==================== - -The 'implicit-dest' rule matches when the mailing list's posting address is -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.name - 'implicit-dest' - -This rule matches messages that have implicit destination, meaning that the -mailing list's posting address isn't included in the explicit recipients. - - >>> mlist.require_explicit_destination = True - >>> mlist.acceptable_aliases = u'' - >>> msg = message_from_string(u"""\ - ... From: aperson@example.org - ... Subject: An implicit message - ... - ... """) - >>> rule.check(mlist, msg, {}) - True - -You can disable implicit destination checks for the mailing list. - - >>> mlist.require_explicit_destination = False - >>> rule.check(mlist, msg, {}) - False - -Even with some recipients, if the posting address is not included, the rule -will match. - - >>> mlist.require_explicit_destination = True - >>> msg['To'] = 'myfriend@example.com' - >>> rule.check(mlist, msg, {}) - True - -Add the posting address as a recipient and the rule will no longer match. - - >>> msg['Cc'] = '_xtest@example.com' - >>> rule.check(mlist, msg, {}) - False - -Alternatively, if one of the acceptable aliases is in the recipients list, -then the rule will not match. - - >>> del msg['cc'] - >>> rule.check(mlist, msg, {}) - True - >>> mlist.acceptable_aliases = u'myfriend@example.com' - >>> rule.check(mlist, msg, {}) - False - -A message gated from NNTP will obviously have an implicit destination. Such -gated messages will not be held for implicit destination because it's assumed -that Mailman pulled it from the appropriate news group. - - >>> rule.check(mlist, msg, dict(fromusenet=True)) - False - - -Alias patterns --------------- - -It's also possible to specify an alias pattern, i.e. a regular expression to -match against the recipients. For example, we can say that if there is a -recipient in the example.net domain, then the rule does not match. - - >>> mlist.acceptable_aliases = u'^.*@example.net' - >>> rule.check(mlist, msg, {}) - True - >>> msg['To'] = 'you@example.net' - >>> rule.check(mlist, msg, {}) - False diff --git a/Mailman/docs/loop.txt b/Mailman/docs/loop.txt deleted file mode 100644 index 3174805b9..000000000 --- a/Mailman/docs/loop.txt +++ /dev/null @@ -1,50 +0,0 @@ -Posting loops -============= - -To avoid a posting loop, Mailman has a rule to check for the existence of an -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.name - 'loop' - -The header could be missing, in which case the rule does not match. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... - ... An important message. - ... """) - >>> rule.check(mlist, msg, {}) - False - -The header could be present, but not match the list's posting address. - - >>> msg['X-BeenThere'] = u'not-this-list@example.com' - >>> rule.check(mlist, msg, {}) - False - -If the header is present and does match the posting address, the rule -matches. - - >>> del msg['x-beenthere'] - >>> msg['X-BeenThere'] = mlist.posting_address - >>> rule.check(mlist, msg, {}) - True - -Even if there are multiple X-BeenThere headers, as long as one with the -posting address exists, the rule matches. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... X-BeenThere: not-this-list@example.com - ... X-BeenThere: _xtest@example.com - ... X-BeenThere: foo@example.com - ... - ... An important message. - ... """) - >>> rule.check(mlist, msg, {}) - True diff --git a/Mailman/docs/max-size.txt b/Mailman/docs/max-size.txt deleted file mode 100644 index b477ecd2b..000000000 --- a/Mailman/docs/max-size.txt +++ /dev/null @@ -1,41 +0,0 @@ -Message size -============ - -The 'message-size' rule matches when the posted message is bigger than a -specified maximum. Generally this is used to prevent huge attachments from -getting posted to the list. This value is calculated in terms of KB (1024 -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.name - 'max-size' - -For example, setting the maximum message size to 1 means that any message -bigger than that will match the rule. - - >>> mlist.max_message_size = 1 # 1024 bytes - >>> one_line = u'x' * 79 - >>> big_body = u'\n'.join([one_line] * 15) - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... To: _xtest@example.com - ... - ... """ + big_body) - >>> rule.check(mlist, msg, {}) - True - -Setting the maximum message size to zero means no size check is performed. - - >>> mlist.max_message_size = 0 - >>> rule.check(mlist, msg, {}) - False - -Of course, if the maximum size is larger than the message's size, then it's -still okay. - - >>> mlist.max_message_size = msg.original_size/1024.0 + 1 - >>> rule.check(mlist, msg, {}) - False diff --git a/Mailman/docs/moderation.txt b/Mailman/docs/moderation.txt deleted file mode 100644 index 0ce6bee6e..000000000 --- a/Mailman/docs/moderation.txt +++ /dev/null @@ -1,71 +0,0 @@ -Member moderation -================= - -Each user has a moderation flag. When set, and the list is set to moderate -postings, then only members with a cleared moderation flag will be able to -email the list without having those messages be held for approval. The -'moderation' rule determines whether the message should be moderated or not. - - >>> 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.name - 'moderation' - -In the simplest case, the sender is not a member of the mailing list, so the -moderation rule can't match. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.org - ... To: _xtest@example.com - ... Subject: A posted message - ... - ... """) - >>> rule.check(mlist, msg, {}) - False - -Let's add the message author as a non-moderated member. - - >>> user = config.db.user_manager.create_user( - ... u'aperson@example.org', u'Anne Person') - >>> address = list(user.addresses)[0] - >>> from Mailman.interfaces import MemberRole - >>> member = address.subscribe(mlist, MemberRole.member) - >>> member.is_moderated - False - >>> rule.check(mlist, msg, {}) - False - -Once the member's moderation flag is set though, the rule matches. - - >>> member.is_moderated = True - >>> rule.check(mlist, msg, {}) - True - - -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.name - 'non-member' - -If the sender is a member of this mailing list, the rule does not match. - - >>> rule.check(mlist, msg, {}) - False - -But if the sender is not a member of this mailing list, the rule matches. - - >>> msg = message_from_string(u"""\ - ... From: bperson@example.org - ... To: _xtest@example.com - ... Subject: A posted message - ... - ... """) - >>> rule.check(mlist, msg, {}) - True diff --git a/Mailman/docs/news-moderation.txt b/Mailman/docs/news-moderation.txt deleted file mode 100644 index f69fbb33d..000000000 --- a/Mailman/docs/news-moderation.txt +++ /dev/null @@ -1,38 +0,0 @@ -Newsgroup moderation -==================== - -The 'news-moderation' rule matches all messages posted to mailing lists that -gateway to a moderated newsgroup. The reason for this is that such messages -must get forwarded on to the newsgroup moderator. From there it will get -posted to the newsgroup, and from there, gated to the mailing list. It's a -circuitous route, but it works nonetheless by holding all messages posted -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.name - 'news-moderation' - -Set the list configuraiton variable to enable newsgroup moderation. - - >>> from Mailman.interfaces import NewsModeration - >>> mlist.news_moderation = NewsModeration.moderated - -And now all messages will match the rule. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.org - ... Subject: An announcment - ... - ... Great things are happening. - ... """) - >>> rule.check(mlist, msg, {}) - True - -When moderation is turned off, the rule does not match. - - >>> mlist.news_moderation = NewsModeration.none - >>> rule.check(mlist, msg, {}) - False diff --git a/Mailman/docs/no-subject.txt b/Mailman/docs/no-subject.txt deleted file mode 100644 index 3c6dc88bf..000000000 --- a/Mailman/docs/no-subject.txt +++ /dev/null @@ -1,35 +0,0 @@ -No Subject header -================= - -This rule matches if the message has no Subject header, or if the header is -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.name - 'no-subject' - -A message with a non-empty subject does not match the rule. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.org - ... To: _xtest@example.com - ... Subject: A posted message - ... - ... """) - >>> rule.check(mlist, msg, {}) - False - -Delete the Subject header and the rule matches. - - >>> del msg['subject'] - >>> rule.check(mlist, msg, {}) - True - -Even a Subject header with only whitespace still matches the rule. - - >>> msg['Subject'] = u' ' - >>> rule.check(mlist, msg, {}) - True diff --git a/Mailman/docs/recipients.txt b/Mailman/docs/recipients.txt deleted file mode 100644 index 98176c8bb..000000000 --- a/Mailman/docs/recipients.txt +++ /dev/null @@ -1,42 +0,0 @@ -Maximum number of recipients -============================ - -The 'max-recipients' rule matches when there are more than the maximum allowed -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.name - 'max-recipients' - -In this case, we'll create a message with 5 recipients. These include all -addresses in the To and CC headers. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... To: _xtest@example.com, bperson@example.com - ... Cc: cperson@example.com - ... Cc: dperson@example.com (Dan Person) - ... To: Elly Q. Person <eperson@example.com> - ... - ... Hey folks! - ... """) - -For backward compatibility, the message must have fewer than the maximum -number of explicit recipients. - - >>> mlist.max_num_recipients = 5 - >>> rule.check(mlist, msg, {}) - True - - >>> mlist.max_num_recipients = 6 - >>> rule.check(mlist, msg, {}) - False - -Zero means any number of recipients are allowed. - - >>> mlist.max_num_recipients = 0 - >>> rule.check(mlist, msg, {}) - False diff --git a/Mailman/docs/rules.txt b/Mailman/docs/rules.txt deleted file mode 100644 index dbf009eeb..000000000 --- a/Mailman/docs/rules.txt +++ /dev/null @@ -1,111 +0,0 @@ -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)? - -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 -========= - -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 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.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. - -You can ask for 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 - True - - -Rule checks ------------ - -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 - ... - ... An important message. - ... """) - -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 - >>> rule.check(mlist, msg, {}) - False - >>> mlist.emergency = True - >>> rule.check(mlist, msg, {}) - True - >>> rule.check(mlist, msg, dict(adminapproved=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/docs/suspicious.txt b/Mailman/docs/suspicious.txt deleted file mode 100644 index 8646e1b81..000000000 --- a/Mailman/docs/suspicious.txt +++ /dev/null @@ -1,37 +0,0 @@ -Suspicious headers -================== - -Suspicious headers are a way for Mailman to hold messages that match a -particular regular expression. This mostly historical feature is fairly -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.name - 'suspicious-header' - -Set the so-called suspicious header configuration variable. - - >>> mlist.bounce_matching_headers = u'From: .*person@(blah.)?example.com' - >>> msg = message_from_string(u"""\ - ... From: aperson@example.com - ... To: _xtest@example.com - ... Subject: An implicit message - ... - ... """) - >>> rule.check(mlist, msg, {}) - True - -But if the header doesn't match the regular expression, the rule won't match. -This one comes from a .org address. - - >>> msg = message_from_string(u"""\ - ... From: aperson@example.org - ... To: _xtest@example.com - ... Subject: An implicit message - ... - ... """) - >>> rule.check(mlist, msg, {}) - False |
