From 9cdad15508bbc5a77e36edfd707dcc8c2140a340 Mon Sep 17 00:00:00 2001 From: Mark Sapiro Date: Wed, 3 Apr 2013 15:23:53 -0700 Subject: The pending (un)subscriptions waiting approval are now sorted by email address in the admindb interface as intended. (LP: 1164160) --- Mailman/Cgi/admindb.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Mailman/Cgi') diff --git a/Mailman/Cgi/admindb.py b/Mailman/Cgi/admindb.py index d1873321..dcca1389 100644 --- a/Mailman/Cgi/admindb.py +++ b/Mailman/Cgi/admindb.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2011 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -314,10 +314,10 @@ def show_pending_subs(mlist, form): for id in pendingsubs: addr = mlist.GetRecord(id)[1] byaddrs.setdefault(addr, []).append(id) - addrs = byaddrs.keys() + addrs = byaddrs.items() addrs.sort() num = 0 - for addr, ids in byaddrs.items(): + for addr, ids in addrs: # Eliminate duplicates for id in ids[1:]: mlist.HandleRequest(id, mm_cfg.DISCARD) @@ -365,10 +365,10 @@ def show_pending_unsubs(mlist, form): for id in pendingunsubs: addr = mlist.GetRecord(id) byaddrs.setdefault(addr, []).append(id) - addrs = byaddrs.keys() + addrs = byaddrs.items() addrs.sort() num = 0 - for addr, ids in byaddrs.items(): + for addr, ids in addrs: # Eliminate duplicates for id in ids[1:]: mlist.HandleRequest(id, mm_cfg.DISCARD) -- cgit v1.2.3 From 1c59d01e49d944bcffccd2154a1e8ec9f3175874 Mon Sep 17 00:00:00 2001 From: Mark Sapiro Date: Fri, 7 Jun 2013 13:52:54 -0700 Subject: - It is no longer possible to add 'invalid' addresses to the ban_list and the *_these_nonmembers filters from the check boxes on the admindb interface. (LP: #1187201) --- Mailman/Cgi/admindb.py | 54 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 15 deletions(-) (limited to 'Mailman/Cgi') diff --git a/Mailman/Cgi/admindb.py b/Mailman/Cgi/admindb.py index dcca1389..8b73ae8d 100644 --- a/Mailman/Cgi/admindb.py +++ b/Mailman/Cgi/admindb.py @@ -710,6 +710,7 @@ def show_post_requests(mlist, id, info, total, count, form): def process_form(mlist, doc, cgidata): senderactions = {} + badaddrs = [] # Sender-centric actions for k in cgidata.keys(): for prefix in ('senderaction-', 'senderpreserve-', 'senderforward-', @@ -762,20 +763,27 @@ def process_form(mlist, doc, cgidata): # Now see if this sender should be added to one of the nonmember # sender filters. if actions.get('senderfilterp', 0): + # Check for an invalid sender address. try: - which = int(actions.get('senderfilter')) - except ValueError: - # Bogus form - which = 'ignore' - if which == mm_cfg.ACCEPT: - mlist.accept_these_nonmembers.append(sender) - elif which == mm_cfg.HOLD: - mlist.hold_these_nonmembers.append(sender) - elif which == mm_cfg.REJECT: - mlist.reject_these_nonmembers.append(sender) - elif which == mm_cfg.DISCARD: - mlist.discard_these_nonmembers.append(sender) - # Otherwise, it's a bogus form, so ignore it + Utils.ValidateEmail(sender) + except Errors.EmailAddressError: + # Don't check for dups. Report it once for each checked box. + badaddrs.append(sender) + else: + try: + which = int(actions.get('senderfilter')) + except ValueError: + # Bogus form + which = 'ignore' + if which == mm_cfg.ACCEPT: + mlist.accept_these_nonmembers.append(sender) + elif which == mm_cfg.HOLD: + mlist.hold_these_nonmembers.append(sender) + elif which == mm_cfg.REJECT: + mlist.reject_these_nonmembers.append(sender) + elif which == mm_cfg.DISCARD: + mlist.discard_these_nonmembers.append(sender) + # Otherwise, it's a bogus form, so ignore it # And now see if we're to clear the member's moderation flag. if actions.get('senderclearmodp', 0): try: @@ -785,8 +793,15 @@ def process_form(mlist, doc, cgidata): pass # And should this address be banned? if actions.get('senderbanp', 0): - if sender not in mlist.ban_list: - mlist.ban_list.append(sender) + # Check for an invalid sender address. + try: + Utils.ValidateEmail(sender) + except Errors.EmailAddressError: + # Don't check for dups. Report it once for each checked box. + badaddrs.append(sender) + else: + if sender not in mlist.ban_list: + mlist.ban_list.append(sender) # Now, do message specific actions banaddrs = [] erroraddrs = [] @@ -836,6 +851,8 @@ def process_form(mlist, doc, cgidata): if cgidata.getvalue(bankey): sender = mlist.GetRecord(request_id)[1] if sender not in mlist.ban_list: + # We don't need to validate the sender. An invalid address + # can't get here. mlist.ban_list.append(sender) # Handle the request id try: @@ -854,7 +871,14 @@ def process_form(mlist, doc, cgidata): doc.AddItem(Header(2, _('Database Updated...'))) if erroraddrs: for addr in erroraddrs: + addr = Utils.websafe(addr) doc.AddItem(`addr` + _(' is already a member') + '
') if banaddrs: for addr, patt in banaddrs: + addr = Utils.websafe(addr) doc.AddItem(_('%(addr)s is banned (matched: %(patt)s)') + '
') + if badaddrs: + for addr in badaddrs: + addr = Utils.websafe(addr) + doc.AddItem(`addr` + ': ' + _('Bad/Invalid email address') + + '
') -- cgit v1.2.3 From cb2733e029d419904f0fc488f5989beb3aa3ce71 Mon Sep 17 00:00:00 2001 From: Mark Sapiro Date: Thu, 18 Jul 2013 20:21:19 -0700 Subject: Backported the held message sorting to 2.1 and made it optional. --- Mailman/Cgi/admindb.py | 69 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 18 deletions(-) (limited to 'Mailman/Cgi') diff --git a/Mailman/Cgi/admindb.py b/Mailman/Cgi/admindb.py index 8b73ae8d..fd9febe8 100644 --- a/Mailman/Cgi/admindb.py +++ b/Mailman/Cgi/admindb.py @@ -50,16 +50,35 @@ i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) EXCERPT_HEIGHT = 10 EXCERPT_WIDTH = 76 +SSENDER = 0 +SSENDERTIME = 1 +STIME = 2 +ssort = SSENDER -def helds_by_sender(mlist): +def helds_by_skey(mlist, ssort=SSENDER): heldmsgs = mlist.GetHeldMessageIds() - bysender = {} + byskey = {} for id in heldmsgs: + ptime = mlist.GetRecord(id)[0] sender = mlist.GetRecord(id)[1] - bysender.setdefault(sender, []).append(id) - return bysender + if ssort in (SSENDER, SSENDERTIME): + skey = (0, sender) + else: + skey = (ptime, sender) + byskey.setdefault(skey, []).append((ptime, id)) + # Sort groups by time + for k, v in byskey.items(): + if len(v) > 1: + v.sort() + byskey[k] = v + if ssort == SSENDERTIME: + # Rekey with time + newkey = (v[0][0], k[1]) + del byskey[k] + byskey[newkey] = v + return byskey def hacky_radio_buttons(btnname, labels, values, defaults, spacing=3): @@ -76,6 +95,7 @@ def hacky_radio_buttons(btnname, labels, values, defaults, spacing=3): def main(): + global ssort # Figure out which list is being requested parts = Utils.GetPathPieces() if not parts: @@ -253,7 +273,7 @@ def main(): raw=1, mlist=mlist)) num = show_pending_subs(mlist, form) num += show_pending_unsubs(mlist, form) - num += show_helds_overview(mlist, form) + num += show_helds_overview(mlist, form, ssort) addform = num > 0 # Finish up the document, adding buttons to the form if addform: @@ -402,20 +422,29 @@ def show_pending_unsubs(mlist, form): -def show_helds_overview(mlist, form): - # Sort the held messages by sender - bysender = helds_by_sender(mlist) - if not bysender: +def show_helds_overview(mlist, form, ssort=SSENDER): + # Sort the held messages. + byskey = helds_by_skey(mlist, ssort) + if not byskey: return 0 form.AddItem('
') form.AddItem(Center(Header(2, _('Held Messages')))) + # Add the sort sequence choices if wanted + if mm_cfg.DISPLAY_HELD_SUMMARY_SORT_BUTTONS: + form.AddItem(Center(_('Show this list grouped/sorted by'))) + form.AddItem(Center(hacky_radio_buttons( + 'summary_sort', + (_('sender/sender'), _('sender/time'), _('ungrouped/time')), + (SSENDER, SSENDERTIME, STIME), + (ssort == SSENDER, ssort == SSENDERTIME, ssort == STIME)))) # Add the by-sender overview tables admindburl = mlist.GetScriptURL('admindb', absolute=1) table = Table(border=0) form.AddItem(table) - senders = bysender.keys() - senders.sort() - for sender in senders: + skeys = byskey.keys() + skeys.sort() + for skey in skeys: + sender = skey[1] qsender = quote_plus(sender) esender = Utils.websafe(sender) senderurl = admindburl + '?sender=' + qsender @@ -499,7 +528,7 @@ def show_helds_overview(mlist, form): right.AddCellInfo(right.GetCurrentRowIndex(), 0, colspan=2) right.AddRow([' ', ' ']) counter = 1 - for id in bysender[sender]: + for ptime, id in byskey[skey]: info = mlist.GetRecord(id) ptime, sender, subject, reason, filename, msgdata = info # BAW: This is really the size of the message pickle, which should @@ -540,13 +569,14 @@ def show_helds_overview(mlist, form): def show_sender_requests(mlist, form, sender): - bysender = helds_by_sender(mlist) - if not bysender: + byskey = helds_by_skey(mlist, SSENDER) + if not byskey: return - sender_ids = bysender.get(sender) + sender_ids = byskey.get((0, sender)) if sender_ids is None: # BAW: should we print an error message? return + sender_ids = [x[1] for x in sender_ids] total = len(sender_ids) count = 1 for id in sender_ids: @@ -709,6 +739,7 @@ def show_post_requests(mlist, id, info, total, count, form): def process_form(mlist, doc, cgidata): + global ssort senderactions = {} badaddrs = [] # Sender-centric actions @@ -730,6 +761,8 @@ def process_form(mlist, doc, cgidata): discardalldefersp = cgidata.getvalue('discardalldefersp', 0) except ValueError: discardalldefersp = 0 + # Get the summary sequence + ssort = int(cgidata.getvalue('summary_sort', SSENDER)) for sender in senderactions.keys(): actions = senderactions[sender] # Handle what to do about all this sender's held messages @@ -744,8 +777,8 @@ def process_form(mlist, doc, cgidata): preserve = actions.get('senderpreserve', 0) forward = actions.get('senderforward', 0) forwardaddr = actions.get('senderforwardto', '') - bysender = helds_by_sender(mlist) - for id in bysender.get(sender, []): + byskey = helds_by_skey(mlist, SSENDER) + for ptime, id in byskey.get((0, sender), []): if id not in senderactions[sender]['message_ids']: # It arrived after the page was displayed. Skip it. continue -- cgit v1.2.3 From 1beb49523f59142b215d75343fd797b582db77b6 Mon Sep 17 00:00:00 2001 From: Mark Sapiro Date: Fri, 19 Jul 2013 14:33:57 -0700 Subject: Enable setting a default grouping/sorting for the admindb held message summary via a DISPLAY_HELD_SUMMARY_SORT_BUTTONS setting. --- Mailman/Cgi/admindb.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'Mailman/Cgi') diff --git a/Mailman/Cgi/admindb.py b/Mailman/Cgi/admindb.py index fd9febe8..d3350ea7 100644 --- a/Mailman/Cgi/admindb.py +++ b/Mailman/Cgi/admindb.py @@ -50,10 +50,13 @@ i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) EXCERPT_HEIGHT = 10 EXCERPT_WIDTH = 76 -SSENDER = 0 -SSENDERTIME = 1 -STIME = 2 -ssort = SSENDER +SSENDER = mm_cfg.SSENDER +SSENDERTIME = mm_cfg.SSENDERTIME +STIME = mm_cfg.STIME +if mm_cfg.DISPLAY_HELD_SUMMARY_SORT_BUTTONS in (SSENDERTIME, STIME): + ssort = mm_cfg.DISPLAY_HELD_SUMMARY_SORT_BUTTONS +else: + ssort = SSENDER -- cgit v1.2.3