Folks,
I've been doing a bit of hacking on Mailman. The issue is that if you set member_moderation_action to be Reject instead of Hold, you can supply a nice little bit of text in member_moderation_notice, or you can let the system supply a standard text for you.
My problem is that I want to leave member_moderation_action set to Hold, and set the generic_nonmember_action to be Reject, but still supply my own text.
Let's look at how these two are handled differently. First, member_moderation_action, has the following lines in Mailman/Handlers/Moderate.py, starting at line 59:
if mlist.getMemberOption(sender, mm_cfg.Moderate): # Note that for member_moderation_action, 0==Hold, 1=Reject, # 2==Discard if mlist.member_moderation_action == 0: # Hold. BAW: WIBNI we could add the member_moderation_notice # to the notice sent back to the sender? msgdata['sender'] = sender Hold.hold_for_approval(mlist, msg, msgdata, ModeratedMemberPost) elif mlist.member_moderation_action == 1: # Reject text = mlist.member_moderation_notice if text: text = Utils.wrap(text) else: # Use the default RejectMessage notice string text = None raise Errors.RejectMessage, text elif mlist.member_moderation_action == 2: # Discard. BAW: Again, it would be nice if we could send a # discard notice to the sender raise Errors.DiscardMessage else: assert 0, 'bad member_moderation_action' # Should we do anything explict to mark this message as getting past # this point? No, because further pipeline handlers will need to do # their own thing.
Okay, I don't know Python, but I can kinda follow that. Notice how the value of "text" is modified depending on whether or not member_moderation_notice is empty or not, and how this code directly raises the error instead of calling a subroutine.
Now, let's consider what happens with generic_nonmember_action. We have the following lines in Mailman/Handlers/Moderate.py, starting at line 101:
# Okay, so the sender wasn't specified explicitly by any of the non-member # moderation configuration variables. Handle by way of generic non-member # action. assert 0 <= mlist.generic_nonmember_action <= 4 if mlist.generic_nonmember_action == 0: # Accept return elif mlist.generic_nonmember_action == 1: Hold.hold_for_approval(mlist, msg, msgdata, Hold.NonMemberPost) elif mlist.generic_nonmember_action == 2: do_reject(mlist) elif mlist.generic_nonmember_action == 3: do_discard(mlist, msg)
Note how this does very little other than decide which subroutine to call, then call it. No check is made for member_moderation_notice, nor is any specific rejection text supplied. Let's take a look at do_reject(), starting at line 136:
def do_reject(mlist):
listowner = mlist.GetOwnerEmail()
raise Errors.RejectMessage, Utils.wrap(_("""\
You are not allowed to post to this mailing list, and your message has been
automatically rejected. If you think that your messages are being rejected in
error, contact the mailing list owner at %(listowner)s."""))This creates a hard-coded message with a %()s substitution, and sends that out.
Now, am I missing something here, or should we not be calling do_reject() in each of these cases and having just the one canonical "raise Errors.RejectMessage", and passing this routine a string to be used as the rejection notice, or allowing it to decide to fill one in for us in the case that we provide "None"?
Okay, so I modified do_reject to at least check the value of member_moderation_notice and to use that text, if it is non-empty. Here's what I've now got:
def do_reject(mlist): listowner = mlist.GetOwnerEmail() text = mlist.member_moderation_notice if text: text = Utils.wrap(text) else: # Use the default RejectMessage notice string text = Utils.wrap(_("""\ You are not allowed to post to this mailing list, and your message has been automatically rejected. If you think that your messages are being rejected in error, contact the mailing list owner at %(listowner)s.""")) # Reject this sucker raise Errors.RejectMessage, text
This works. Well, mostly. I'd be submitting this as a patch and working on getting this put into production, if it worked completely. I know that what we should really have is a separate generic_nonmember_notice and have the routine check that instead, but I would be willing to take this as a small but significant improvement in the meanwhile.
Problem is, while we can provide a %()s substitution ourselves in the text we feed to Utils.wrap, I can't do the same thing from member_moderation_notice. Instead, it simply outputs the literal string, and gives me "<" and ">" as opposed to the real less-than/greater-than symbols that I want to use around the URLs.
I'm stumped. I don't even know what to search for in the archives of the mailman-users and mailman-developers lists.
Can anyone here lend me a clue?
-- Brad Knowles, <[EMAIL PROTECTED]>
"Those who would give up essential Liberty, to purchase a little temporary Safety, deserve neither Liberty nor Safety."
-- Benjamin Franklin (1706-1790), reply of the Pennsylvania
Assembly to the Governor, November 11, 1755SAGE member since 1995. See <http://www.sage.org/> for more info. _______________________________________________ Mailman-Developers mailing list [email protected] http://mail.python.org/mailman/listinfo/mailman-developers Unsubscribe: http://mail.python.org/mailman/options/mailman-developers/archive%40jab.org
