diff options
| -rw-r--r-- | src/mailman/queue/docs/digester.txt | 12 | ||||
| -rw-r--r-- | src/mailman/queue/docs/incoming.txt | 3 | ||||
| -rw-r--r-- | src/mailman/queue/docs/lmtp.txt | 5 | ||||
| -rw-r--r-- | src/mailman/queue/docs/news.txt | 10 | ||||
| -rw-r--r-- | src/mailman/queue/docs/outgoing.txt | 30 | ||||
| -rw-r--r-- | src/mailman/queue/docs/rest.txt | 4 | ||||
| -rw-r--r-- | src/mailman/queue/docs/runner.txt | 7 | ||||
| -rw-r--r-- | src/mailman/queue/docs/switchboard.txt | 3 |
8 files changed, 59 insertions, 15 deletions
diff --git a/src/mailman/queue/docs/digester.txt b/src/mailman/queue/docs/digester.txt index 1dbf24ec4..56aaf17c5 100644 --- a/src/mailman/queue/docs/digester.txt +++ b/src/mailman/queue/docs/digester.txt @@ -4,6 +4,7 @@ Digesting Mailman crafts and sends digests by a separate digest queue runner process. This starts by a number of messages being posted to the mailing list. +:: >>> mlist = create_list('test@example.com') >>> mlist.digest_size_threshold = 0.6 @@ -35,6 +36,7 @@ This starts by a number of messages being posted to the mailing list. The queue runner gets kicked off when a marker message gets dropped into the digest queue. The message metadata points to the mailbox file containing the messages to put in the digest. +:: >>> digestq = config.switchboards['digest'] >>> len(digestq.files) @@ -48,6 +50,7 @@ The marker message is empty. >>> print entry.msg.as_string() But the message metadata has a reference to the digest file. +:: >>> dump_msgdata(entry.msgdata) _parsemsg : False @@ -82,6 +85,7 @@ delivery. 2 The MIME digest is a multipart, and the RFC 1153 digest is the other one. +:: >>> def mime_rfc1153(messages): ... if messages[0].msg.is_multipart(): @@ -283,6 +287,7 @@ Internationalized digests When messages come in with a content-type character set different than that of the list's preferred language, recipients will get an internationalized digest. French is not enabled by default site-wide, so enable that now. +:: # Simulate the site administrator setting the default server language to # French in the configuration file. Without this, the English template @@ -324,6 +329,7 @@ The marker message is sitting in the digest queue. The digest queue runner runs a loop, placing the two digests into the virgin queue. +:: # Put the messages back in the queue for the runner to handle. >>> filebase = digestq.enqueue(entry.msg, entry.msgdata) @@ -422,6 +428,7 @@ French and Japanese characters. <BLANKLINE> The content can be decoded to see the actual digest text. +:: # We must display the repr of the decoded value because doctests cannot # handle the non-ascii characters. @@ -477,6 +484,7 @@ Digest delivery A mailing list's members can choose to receive normal delivery, plain text digests, or MIME digests. +:: >>> len(get_queue_messages('virgin')) 0 @@ -518,6 +526,7 @@ When a digest gets sent, the appropriate recipient list is chosen. The digests are sitting in the virgin queue. One of them is the MIME digest and the other is the RFC 1153 digest. +:: >>> messages = get_queue_messages('virgin') >>> len(messages) @@ -536,6 +545,7 @@ Only yperson and zperson get the RFC 1153 digests. [u'yperson@example.com', u'zperson@example.com'] Now uperson decides that they would like to start receiving digests too. +:: >>> member_1.preferences.delivery_mode = DeliveryMode.mime_digests >>> fill_digest() @@ -556,6 +566,7 @@ At this point, both uperson and wperson decide that they'd rather receive regular deliveries instead of digests. uperson would like to get any last digest that may be sent so that she doesn't miss anything. wperson does care as much and does not want to receive one last digest. +:: >>> mlist.send_one_last_digest_to( ... member_1.address, member_1.preferences.delivery_mode) @@ -576,6 +587,7 @@ as much and does not want to receive one last digest. Since uperson has received their last digest, they will not get any more of them. +:: >>> fill_digest() >>> runner.run() diff --git a/src/mailman/queue/docs/incoming.txt b/src/mailman/queue/docs/incoming.txt index 74326820f..0e1ad1fca 100644 --- a/src/mailman/queue/docs/incoming.txt +++ b/src/mailman/queue/docs/incoming.txt @@ -81,6 +81,7 @@ Held messages The list moderator sets the emergency flag on the mailing list. The built-in chain will now hold all posted messages, so nothing will show up in the pipeline queue. +::: # XXX This checks the vette log file because there is no other evidence # that this chain has done anything. @@ -111,6 +112,7 @@ Discarded messages Another possibility is that the message would get immediately discarded. The built-in chain does not have such a disposition by default, so let's craft a new chain and set it as the mailing list's start chain. +:: >>> from mailman.chains.base import Chain, Link >>> from mailman.interfaces.chain import LinkAction @@ -151,6 +153,7 @@ just create a new chain that does. The virgin queue needs to be cleared out due to artifacts from the previous tests above. +:: >>> virgin_queue = config.switchboards['virgin'] >>> ignore = get_queue_messages('virgin') diff --git a/src/mailman/queue/docs/lmtp.txt b/src/mailman/queue/docs/lmtp.txt index 549161b08..c95c6aa2b 100644 --- a/src/mailman/queue/docs/lmtp.txt +++ b/src/mailman/queue/docs/lmtp.txt @@ -7,7 +7,7 @@ support LMTP local delivery, so this is a very portable way to connect Mailman with your mail server. Our LMTP server is fairly simple though; all it does is make sure that the -message is destined for a valid endpoint, e.g. mylist-join@example.com. +message is destined for a valid endpoint, e.g. ``mylist-join@example.com``. Let's start a testable LMTP queue runner. @@ -44,6 +44,7 @@ will get a 550 error. SMTPDataError: (550, 'Requested action not taken: mailbox unavailable') Once the mailing list is created, the posting address is valid. +:: >>> create_list('mylist@example.com') <mailing list "mylist@example.com" at ...> @@ -197,6 +198,7 @@ Confirmation messages go to the command processor... version : ... ...as do join messages... +:: >>> lmtp.sendmail( ... 'anne.person@example.com', @@ -237,6 +239,7 @@ Confirmation messages go to the command processor... version : ... ...and leave messages. +:: >>> lmtp.sendmail( ... 'anne.person@example.com', diff --git a/src/mailman/queue/docs/news.txt b/src/mailman/queue/docs/news.txt index 01b554097..7261aa333 100644 --- a/src/mailman/queue/docs/news.txt +++ b/src/mailman/queue/docs/news.txt @@ -13,6 +13,7 @@ was originally written to gate to Usenet, which has its own rules). Some NNTP servers such as INN reject messages containing a set of prohibited headers, so one of the things that the news runner does is remove these prohibited headers. +:: >>> msg = message_from_string("""\ ... From: aperson@example.com @@ -49,7 +50,7 @@ prohibited headers. Some NNTP servers will reject messages where certain headers are duplicated, so the news runner must collapse or move these duplicate headers to an -X-Original-* header that the news server doesn't care about. +``X-Original-*`` header that the news server doesn't care about. >>> msg = message_from_string("""\ ... From: aperson@example.com @@ -116,8 +117,9 @@ the message. Newsgroup moderation ==================== -When the newsgroup is moderated, an Approved: header with the list's posting -address is added for the benefit of the Usenet system. +When the newsgroup is moderated, an ``Approved:`` header with the list's +posting address is added for the benefit of the Usenet system. +:: >>> from mailman.interfaces.nntp import NewsModeration >>> mlist.news_moderation = NewsModeration.open_moderated @@ -142,7 +144,7 @@ address is added for the benefit of the Usenet system. >>> print msg['approved'] _xtest@example.com -But if the newsgroup is not moderated, the Approved: header is not changed. +But if the newsgroup is not moderated, the ``Approved:`` header is not changed. >>> mlist.news_moderation = NewsModeration.none >>> msg = message_from_string("""\ diff --git a/src/mailman/queue/docs/outgoing.txt b/src/mailman/queue/docs/outgoing.txt index 73a9200ef..0af22b808 100644 --- a/src/mailman/queue/docs/outgoing.txt +++ b/src/mailman/queue/docs/outgoing.txt @@ -7,10 +7,11 @@ directly upstream SMTP server. It is this upstream SMTP server that performs final delivery to the intended recipients. Messages that appear in the outgoing queue are processed individually through -a 'delivery module', essentially a pluggable interface for determining how the +a *delivery module*, essentially a pluggable interface for determining how the recipient set will be batched, whether messages will be personalized and VERP'd, etc. The outgoing runner doesn't itself support retrying but it can move messages to the 'retry queue' for handling delivery failures. +:: >>> mlist = create_list('test@example.com') @@ -32,8 +33,9 @@ move messages to the 'retry queue' for handling delivery failures. Normally, messages would show up in the outgoing queue after the message has been processed by the rule set and pipeline. But we can simulate that here by injecting a message directly into the outgoing queue. First though, we must -call the calculate-recipients handler so that the message metadata will be +call the ``calculate-recipients`` handler so that the message metadata will be populated with the list of addresses to deliver the message to. +:: >>> msg = message_from_string("""\ ... From: aperson@example.com @@ -49,8 +51,8 @@ populated with the list of addresses to deliver the message to. >>> handler.process(mlist, msg, msgdata) >>> outgoing_queue = config.switchboards['out'] -The to-outgoing handler populates the message metadata with the destination -mailing list name. Simulate that here too. +The ``to-outgoing`` handler populates the message metadata with the +destination mailing list name. Simulate that here too. >>> ignore = outgoing_queue.enqueue( ... msg, msgdata, @@ -66,6 +68,7 @@ upstream SMTP. >>> outgoing.run() Every recipient got the same copy of the message. +:: >>> messages = list(smtpd.messages) >>> len(messages) @@ -111,6 +114,7 @@ just one. Since we've done no other configuration, the only difference in the messages is the recipient address. Specifically, the Sender header is the same for all recipients. +:: >>> from operator import itemgetter >>> def show_headers(messages): @@ -137,7 +141,8 @@ the Sender header. Forcing VERP ------------ -A handler can force VERP by setting the 'verp' key in the message metadata. +A handler can force VERP by setting the ``verp`` key in the message metadata. +:: >>> ignore = outgoing_queue.enqueue( ... msg, msgdata, @@ -164,7 +169,8 @@ The site administrator can enable VERP whenever messages are personalized. ... verp_personalized_deliveries: yes ... """) -Again, we get three individual messages, with VERP'd Sender headers. +Again, we get three individual messages, with VERP'd ``Sender`` headers. +:: >>> ignore = outgoing_queue.enqueue( ... msg, msgdata, @@ -192,6 +198,7 @@ still like to occasionally get the benefits of VERP. The site administrator can enable occasional VERPing of messages every so often, by setting a delivery interval. Every N non-personalized deliveries turns on VERP for just the next one. +:: >>> config.push('verp occasionally', """ ... [mta] @@ -204,6 +211,7 @@ the next one. The first message is sent to the list, and it is neither personalized nor VERP'd. +:: >>> ignore = outgoing_queue.enqueue( ... msg, msgdata, @@ -223,6 +231,7 @@ VERP'd. >>> transaction.commit() The second message sent to the list is also not VERP'd. +:: >>> ignore = outgoing_queue.enqueue( ... msg, msgdata, @@ -241,6 +250,7 @@ The second message sent to the list is also not VERP'd. >>> transaction.commit() The third message though is VERP'd. +:: >>> ignore = outgoing_queue.enqueue( ... msg, msgdata, @@ -260,6 +270,7 @@ The third message though is VERP'd. >>> transaction.commit() The next one is back to bulk delivery. +:: >>> ignore = outgoing_queue.enqueue( ... msg, msgdata, @@ -281,6 +292,7 @@ VERP every time If the site administrator wants to enable VERP for every delivery, even if no personalization is going on, they can set the interval to 1. +:: >>> config.push('always verp', """ ... [mta] @@ -292,6 +304,7 @@ personalization is going on, they can set the interval to 1. >>> transaction.commit() The first message is VERP'd. +:: >>> ignore = outgoing_queue.enqueue( ... msg, msgdata, @@ -311,6 +324,7 @@ The first message is VERP'd. >>> transaction.commit() As is the second message. +:: >>> ignore = outgoing_queue.enqueue( ... msg, msgdata, @@ -330,6 +344,7 @@ As is the second message. >>> transaction.commit() And the third message. +:: >>> ignore = outgoing_queue.enqueue( ... msg, msgdata, @@ -356,6 +371,7 @@ Never VERP Similarly, the site administrator can disable occasional VERP'ing of non-personalized messages by setting the interval to zero. +:: >>> config.push('never verp', """ ... [mta] @@ -367,6 +383,7 @@ non-personalized messages by setting the interval to zero. >>> transaction.commit() Neither the first message... +:: >>> ignore = outgoing_queue.enqueue( ... msg, msgdata, @@ -381,6 +398,7 @@ Neither the first message... test-bounces@example.com ...nor the second message is VERP'd. +:: >>> ignore = outgoing_queue.enqueue( ... msg, msgdata, diff --git a/src/mailman/queue/docs/rest.txt b/src/mailman/queue/docs/rest.txt index 2df4da9e4..a71915a49 100644 --- a/src/mailman/queue/docs/rest.txt +++ b/src/mailman/queue/docs/rest.txt @@ -2,7 +2,7 @@ REST server =========== -Mailman is controllable through an administrative RESTful HTTP server. +Mailman is controllable through an administrative `REST`_ HTTP server. >>> from mailman.testing import helpers >>> master = helpers.TestableMaster(helpers.wait_for_webservice) @@ -21,3 +21,5 @@ Clean up ======== >>> master.stop() + +.. _REST: http://en.wikipedia.org/wiki/REST diff --git a/src/mailman/queue/docs/runner.txt b/src/mailman/queue/docs/runner.txt index 8438f2576..39e8fede2 100644 --- a/src/mailman/queue/docs/runner.txt +++ b/src/mailman/queue/docs/runner.txt @@ -2,7 +2,7 @@ Queue runners ============= -The queue runners (qrunner) are the processes that move messages around the +The queue runners (*qrunner*) are the processes that move messages around the Mailman system. Each qrunner is responsible for a slice of the hash space in a queue directory. It processes all the files in its slice, sleeps a little while, then wakes up and runs through its queue files again. @@ -12,8 +12,8 @@ Basic architecture ================== The basic architecture of qrunner is implemented in the base class that all -runners inherit from. This base class implements a .run() method that runs -continuously in a loop until the .stop() method is called. +runners inherit from. This base class implements a ``.run()`` method that +runs continuously in a loop until the ``.stop()`` method is called. >>> mlist = create_list('_xtest@example.com') @@ -21,6 +21,7 @@ Here is a very simple derived qrunner class. Queue runners use a configuration section in the configuration files to determine run characteristics, such as the queue directory to use. Here we push a configuration section for the test runner. +:: >>> config.push('test-runner', """ ... [qrunner.test] diff --git a/src/mailman/queue/docs/switchboard.txt b/src/mailman/queue/docs/switchboard.txt index ca44b20ac..d89aa3693 100644 --- a/src/mailman/queue/docs/switchboard.txt +++ b/src/mailman/queue/docs/switchboard.txt @@ -156,6 +156,7 @@ The files can be recovered explicitly. But the files will only be recovered at most three times before they are considered defective. In order to prevent mail bombs and loops, once this maximum is reached, the files will be preserved in the 'bad' queue. +:: >>> for filebase in switchboard.files: ... msg, msgdata = switchboard.dequeue(filebase) @@ -170,7 +171,9 @@ maximum is reached, the files will be preserved in the 'bad' queue. >>> check_qfiles(bad.queue_directory) .psv: 3 + Clean up +-------- >>> for file in os.listdir(bad.queue_directory): ... os.remove(os.path.join(bad.queue_directory, file)) |
