Charles Gregory wrote: >On Wed, 5 Aug 2009, Mark Sapiro wrote: >>> Is there NO way to get a reminder notice to come FROM the >>> list/list-owner, even given the obvious issue with possible multiple >>> lists? >> It's a simple change. Just send one reminder per list. > >How can I set that? (mm 2.1.5)
The attached mailpasswds.patch.txt file contains a patch to Mailman's cron/mailpasswds that will send individual reminders from each list the the list's members. It should apply directly to mailman 2.1.5's mailpasswds with only 'fuzz' in the first hunk because of the @PYTHON@ vs. /path/to/python difference, but the resultant patched file should be good. -- Mark Sapiro <m...@msapiro.net> The highway is for gamblers, San Francisco Bay Area, California better use your sense - B. Dylan
--- cron/mailpasswds 2009-05-21 12:40:18.359375000 -0700 +++ /cygdrive/f/test-mailman/cron/mailpasswds 2009-08-05 17:29:29.000000000 -0700 @@ -1,6 +1,6 @@ #! @PYTHON@ # -# Copyright (C) 1998-2003 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2009 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 @@ -109,118 +109,65 @@ if listnames is None: listnames = Utils.list_names() - # This is the list that all the reminders will look like they come from, - # but with the host name coerced to the virtual host we're processing. - try: - sitelist = MailList.MailList(mm_cfg.MAILMAN_SITE_LIST, lock=0) - except Errors.MMUnknownListError: - # Do it this way for I18n's _() - sitelistname = mm_cfg.MAILMAN_SITE_LIST - print >> sys.stderr, _('Site list is missing: %(sitelistname)s') - syslog('error', 'Site list is missing: %s', mm_cfg.MAILMAN_SITE_LIST) - sys.exit(1) - - # Group lists by host_name if VIRTUAL_HOST_OVERVIEW is true, otherwise - # there's only one key in this dictionary: mm_cfg.DEFAULT_EMAIL_HOST. The - # values are lists of the unlocked MailList instances. - byhost = {} for listname in listnames: mlist = MailList.MailList(listname, lock=0) if not mlist.send_reminders: continue - if mm_cfg.VIRTUAL_HOST_OVERVIEW: - host = mlist.host_name - else: - # See the note in Defaults.py concerning DEFAULT_HOST_NAME - # vs. DEFAULT_EMAIL_HOST. - host = mm_cfg.DEFAULT_HOST_NAME or mm_cfg.DEFAULT_EMAIL_HOST - byhost.setdefault(host, []).append(mlist) - - # Now for each virtual host, collate the user information. Each user - # entry has the form (listaddr, password, optionsurl) - for host in byhost.keys(): - # Site owner is `mail...@dom.ain' + host = mlist.host_name userinfo = {} - for mlist in byhost[host]: - listaddr = mlist.GetListEmail() - for member in mlist.getMembers(): - # The user may have disabled reminders for this list - if mlist.getMemberOption(member, - mm_cfg.SuppressPasswordReminder): - continue - # Group by the lower-cased address, since Mailman always - # treates per...@dom.ain the same as per...@dom.ain. - try: - password = mlist.getMemberPassword(member) - except Errors.NotAMemberError: - # Here's a member with no passwords, which I think was - # possible in older versions of Mailman. Log this and - # move on. - syslog('error', 'password-less member %s for list %s', - member, mlist.internal_name()) - continue - optionsurl = mlist.GetOptionsURL(member) - lang = mlist.getMemberLanguage(member) - info = (listaddr, password, optionsurl, lang) - userinfo.setdefault(member, []).append(info) - # Now that we've collected user information for this host, send each + listaddr = mlist.GetListEmail() + for member in mlist.getMembers(): + # The user may have disabled reminders for this list + if mlist.getMemberOption(member, + mm_cfg.SuppressPasswordReminder): + continue + # Group by the lower-cased address, since Mailman always + # treates per...@dom.ain the same as per...@dom.ain. + try: + password = mlist.getMemberPassword(member) + except Errors.NotAMemberError: + # Here's a member with no passwords, which I think was + # possible in older versions of Mailman. Log this and + # move on. + syslog('error', 'password-less member %s for list %s', + member, mlist.internal_name()) + continue + optionsurl = mlist.GetOptionsURL(member) + lang = mlist.getMemberLanguage(member) + userinfo[member] = (listaddr, password, optionsurl, lang) + # Now that we've collected user information for this list, send each # user the password reminder. for addr in userinfo.keys(): - # If the person is on more than one list, it is possible that they - # have different preferred languages, and there's no good way to - # know which one they want their password reminder in. Pick the - # most popular, and break the tie randomly. - # - # Also, we need an example -request address for cronpass.txt and - # again, there's no clear winner. Just take the first one in this - # case. - table = [] - langs = {} - for listaddr, password, optionsurl, lang in userinfo[addr]: - langs[lang] = langs.get(lang, 0) + 1 - # If the list address is really long, break it across two - # lines. - if len(listaddr) > 39: - fmt = '%s\n %-10s\n%s\n' - else: - fmt = '%-40s %-10s\n%s\n' - table.append(fmt % (listaddr, password, optionsurl)) - # Figure out which language to use - langcnt = 0 - poplang = None - for lang, cnt in langs.items(): - if cnt > langcnt: - poplang = lang - langcnt = cnt - enc = Utils.GetCharSet(poplang) + listaddr, password, optionsurl, lang = userinfo[addr] + # If the list address is really long, break it across two + # lines. + fmt = 'List: %s\nPassword: %s\nURL: %s\n' + table = fmt % (listaddr, password, optionsurl) + enc = Utils.GetCharSet(lang) # Now we're finally ready to send the email! - siteowner = Utils.get_site_email(host, 'owner') - sitereq = Utils.get_site_email(host, 'request') - sitebounce = Utils.get_site_email(host, 'bounces') + listowner = mlist.GetOwnerEmail() + listreq = mlist.GetRequestEmail() + listbounce = mlist.GetBouncesEmail() text = Utils.maketext( 'cronpass.txt', {'hostname': host, 'useraddr': addr, - 'exreq' : sitereq, - 'owner' : siteowner, - }, lang=poplang) + 'exreq' : listreq, + 'owner' : listowner, + }, lang=lang) # Coerce everything to Unicode text = tounicode(text, enc) - table = [tounicode(_t, enc) for _t in table] + table = tounicode(table, enc) # Translate the message and headers to user's suggested lang otrans = i18n.get_translation() try: - i18n.set_language(poplang) - # Craft table header after language was set - header = '%-40s %-10s\n%-40s %-10s' % ( - _('List'), _('Password // URL'), '----', '--------') - header = tounicode(header, enc) + i18n.set_language(lang) # Add the table to the end so it doesn't get wrapped/filled - text += (header + '\n' + NL.join(table)) + text += table msg = Message.UserNotification( - addr, siteowner, + addr, listowner, _('%(host)s mailing list memberships reminder'), - text.encode(enc, 'replace'), poplang) + text.encode(enc, 'replace'), lang) # Note that text must be encoded into 'enc' because unicode # cause error within email module in some language (Japanese). finally: @@ -230,8 +177,7 @@ # list, but we also want to be sure that the apparent host name is # the current virtual host. Look in CookHeaders.py for why this # trick works. Blarg. - msg.send(sitelist, **{'errorsto': sitebounce, - '_nolist' : 1, + msg.send(mlist, **{'errorsto': listbounce, 'verp' : mm_cfg.VERP_PASSWORD_REMINDERS, })
------------------------------------------------------ Mailman-Users mailing list Mailman-Users@python.org http://mail.python.org/mailman/listinfo/mailman-users Mailman FAQ: http://wiki.list.org/x/AgA3 Searchable Archives: http://www.mail-archive.com/mailman-users%40python.org/ Unsubscribe: http://mail.python.org/mailman/options/mailman-users/archive%40jab.org Security Policy: http://wiki.list.org/x/QIA9