def get_pending_mail(userdesc, perms, mlist, id, raw=0): """ Get informations about a given mail moderation. @mlist @lock @admin """ ptime, sender, subject, reason, filename, msgdata = mlist.GetRecord(int(id)) fpath = os.path.join(mm_cfg.DATA_DIR, filename) size = os.path.getsize(fpath) msg = readMessage(fpath) if raw: return quote(str(msg)) results_plain = [] results_html = [] for part in typed_subpart_iterator(msg, 'text', 'plain'): c = part.get_payload() if c is not None: results_plain.append (c) results_plain = map(lambda x: quote(x), results_plain) for part in typed_subpart_iterator(msg, 'text', 'html'): c = part.get_payload() if c is not None: results_html.append (c) results_html = map(lambda x: quote(x), results_html) return {'id' : id, 'sender': quote(sender, True), 'size' : size, 'subj' : quote(subject, True), 'stamp' : ptime, 'parts_plain' : results_plain, 'parts_html': results_html }
def show_post_requests(mlist, id, info, total, count, form): # Mailman.ListAdmin.__handlepost no longer tests for pre 2.0beta3 ptime, sender, subject, reason, filename, msgdata = info form.AddItem('<hr>') # Header shown on each held posting (including count of total) msg = _('Posting Held for Approval') if total <> 1: msg += _(' (%(count)d of %(total)d)') form.AddItem(Center(Header(2, msg))) # We need to get the headers and part of the textual body of the message # being held. The best way to do this is to use the email Parser to get # an actual object, which will be easier to deal with. We probably could # just do raw reads on the file. try: msg = readMessage(os.path.join(mm_cfg.DATA_DIR, filename)) except IOError, e: if e.errno <> errno.ENOENT: raise form.AddItem(_('<em>Message with id #%(id)d was lost.')) form.AddItem('<p>') # BAW: kludge to remove id from requests.db. try: mlist.HandleRequest(id, mm_cfg.DISCARD) except Errors.LostHeldMessage: pass return
def get_pending_ops(userdesc, perms, mlist): """ Get the list of operation waiting for an action from the owners. @mlist @lock @admin """ subs = [] seen = [] dosave = False for id in mlist.GetSubscriptionIds(): time, addr, fullname, passwd, digest, lang = mlist.GetRecord(id) if addr in seen: mlist.HandleRequest(id, mm_cfg.DISCARD) dosave = True continue seen.append(addr) try: login = re.match("^[^.]*\.[^.]*\.\d\d\d\d$", addr.split('@')[0]).group() subs.append({ 'id': id, 'name': quote(fullname), 'addr': addr, 'login': login }) except: subs.append({'id': id, 'name': quote(fullname), 'addr': addr}) helds = [] for id in mlist.GetHeldMessageIds(): ptime, sender, subject, reason, filename, msgdata = mlist.GetRecord(id) fpath = os.path.join(mm_cfg.DATA_DIR, filename) try: size = os.path.getsize(fpath) except OSError, e: if e.errno <> errno.ENOENT: raise continue try: msg = readMessage(fpath) fromX = msg.has_key("X-Org-Mail") except: pass helds.append({ 'id': id, 'sender': quote(sender, True), 'size': size, 'subj': quote(subject, True), 'stamp': ptime, 'fromx': fromX })
def get_pending_ops(userdesc, perms, mlist): """ Get the list of operation waiting for an action from the owners. @mlist @lock @admin """ subs = [] seen = [] dosave = False for id in mlist.GetSubscriptionIds(): time, addr, fullname, passwd, digest, lang = mlist.GetRecord(id) if addr in seen: mlist.HandleRequest(id, mm_cfg.DISCARD) dosave = True continue seen.append(addr) try: login = re.match("^[^.]*\.[^.]*\.\d\d\d\d$", addr.split('@')[0]).group() subs.append({'id': id, 'name': quote(fullname), 'addr': addr, 'login': login }) except: subs.append({'id': id, 'name': quote(fullname), 'addr': addr }) helds = [] for id in mlist.GetHeldMessageIds(): ptime, sender, subject, reason, filename, msgdata = mlist.GetRecord(id) fpath = os.path.join(mm_cfg.DATA_DIR, filename) try: size = os.path.getsize(fpath) except OSError, e: if e.errno <> errno.ENOENT: raise continue try: msg = readMessage(fpath) fromX = msg.has_key("X-Org-Mail") except: pass helds.append({ 'id' : id, 'sender': quote(sender, True), 'size' : size, 'subj' : quote(subject, True), 'stamp' : ptime, 'fromx' : fromX })
def show_post_requests(mlist, id, info, total, count, form): # Mailman.ListAdmin.__handlepost no longer tests for pre 2.0beta3 ptime, sender, subject, reason, filename, msgdata = info form.AddItem('<hr>') # Header shown on each held posting (including count of total) msg = _('Posting Held for Approval') if total != 1: msg += _(' (%(count)d of %(total)d)') form.AddItem(Center(Header(2, msg))) # We need to get the headers and part of the textual body of the message # being held. The best way to do this is to use the email.parser to get # an actual object, which will be easier to deal with. We probably could # just do raw reads on the file. try: msg = readMessage(os.path.join(mm_cfg.DATA_DIR, filename)) except IOError as e: if e.errno != errno.ENOENT: raise form.AddItem(_('<em>Message with id #%(id)d was lost.')) form.AddItem('<p>') # BAW: kludge to remove id from requests.db. try: mlist.HandleRequest(id, mm_cfg.DISCARD) except Errors.LostHeldMessage: pass return except email.errors.MessageParseError: form.AddItem(_('<em>Message with id #%(id)d is corrupted.')) # BAW: Should we really delete this, or shuttle it off for site admin # to look more closely at? form.AddItem('<p>') # BAW: kludge to remove id from requests.db. try: mlist.HandleRequest(id, mm_cfg.DISCARD) except Errors.LostHeldMessage: pass return # Get the header text and the message body excerpt lines = [] chars = 0 # A negative value means, include the entire message regardless of size limit = mm_cfg.ADMINDB_PAGE_TEXT_LIMIT for line in email.iterators.body_line_iterator(msg, decode=True): lines.append(line) chars += len(line) if chars >= limit > 0: break # We may have gone over the limit on the last line, but keep the full line # anyway to avoid losing part of a multibyte character. body = EMPTYSTRING.join(lines) # Get message charset and try encode in list charset # We get it from the first text part. # We need to replace invalid characters here or we can throw an uncaught # exception in doc.Format(). for part in msg.walk(): if part.get_content_maintype() == 'text': # Watchout for charset= with no value. mcset = part.get_content_charset() or 'us-ascii' break else: mcset = 'us-ascii' lcset = Utils.GetCharSet(mlist.preferred_language) if mcset != lcset: try: body = str(body, mcset, 'replace') except (LookupError, UnicodeError, ValueError): pass hdrtxt = NL.join(['%s: %s' % (k, v) for k, v in list(msg.items())]) hdrtxt = Utils.websafe(hdrtxt) # Okay, we've reconstituted the message just fine. Now for the fun part! t = Table(cellspacing=0, cellpadding=0, width='100%') t.AddRow([Bold(_('From:')), sender]) row, col = t.GetCurrentRowIndex(), t.GetCurrentCellIndex() t.AddCellInfo(row, col-1, align='right') t.AddRow([Bold(_('Subject:')), Utils.websafe(Utils.oneline(subject, lcset))]) t.AddCellInfo(row+1, col-1, align='right') t.AddRow([Bold(_('Reason:')), _(reason)]) t.AddCellInfo(row+2, col-1, align='right') when = msgdata.get('received_time') if when: t.AddRow([Bold(_('Received:')), time.ctime(when)]) t.AddCellInfo(row+3, col-1, align='right') buttons = hacky_radio_buttons(id, (_('Defer'), _('Approve'), _('Reject'), _('Discard')), (mm_cfg.DEFER, mm_cfg.APPROVE, mm_cfg.REJECT, mm_cfg.DISCARD), (1, 0, 0, 0), spacing=5) t.AddRow([Bold(_('Action:')), buttons]) t.AddCellInfo(t.GetCurrentRowIndex(), col-1, align='right') t.AddRow([' ', '<label>' + CheckBox('preserve-%d' % id, 'on', 0).Format() + ' ' + _('Preserve message for site administrator') + '</label>' ]) t.AddRow([' ', '<label>' + CheckBox('forward-%d' % id, 'on', 0).Format() + ' ' + _('Additionally, forward this message to: ') + '</label>' + TextBox('forward-addr-%d' % id, size=47, value=mlist.GetOwnerEmail()).Format() ]) notice = msgdata.get('rejection_notice', _('[No explanation given]')) t.AddRow([ Bold(_('If you reject this post,<br>please explain (optional):')), TextArea('comment-%d' % id, rows=4, cols=EXCERPT_WIDTH, text = Utils.wrap(_(notice), column=80)) ]) row, col = t.GetCurrentRowIndex(), t.GetCurrentCellIndex() t.AddCellInfo(row, col-1, align='right') t.AddRow([Bold(_('Message Headers:')), TextArea('headers-%d' % id, hdrtxt, rows=EXCERPT_HEIGHT, cols=EXCERPT_WIDTH, readonly=1)]) row, col = t.GetCurrentRowIndex(), t.GetCurrentCellIndex() t.AddCellInfo(row, col-1, align='right') t.AddRow([Bold(_('Message Excerpt:')), TextArea('fulltext-%d' % id, Utils.websafe(body), rows=EXCERPT_HEIGHT, cols=EXCERPT_WIDTH, readonly=1)]) t.AddCellInfo(row+1, col-1, align='right') form.AddItem(t) form.AddItem('<p>')