summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Warsaw2007-09-20 22:39:20 -0400
committerBarry Warsaw2007-09-20 22:39:20 -0400
commit892316be3c09eec4a1f8117bfd9eb44bba1c9117 (patch)
treec6dd4f1f116bad876306923a981237d09d05fdca
parent18e07a3dc2caa61ed042515cd91833a76a596b9d (diff)
downloadmailman-892316be3c09eec4a1f8117bfd9eb44bba1c9117.tar.gz
mailman-892316be3c09eec4a1f8117bfd9eb44bba1c9117.tar.zst
mailman-892316be3c09eec4a1f8117bfd9eb44bba1c9117.zip
Get bin/add_members and bin/list_members to work again (for the most
part). Mostly this is just updating the code to use the new APIs, but there's also some other code clean up involved. There's still more to do for sure, but this is a start.
-rw-r--r--Mailman/bin/add_members.py77
-rw-r--r--Mailman/bin/list_lists.py6
-rw-r--r--Mailman/bin/list_members.py108
-rw-r--r--Mailman/bin/newlist.py8
-rw-r--r--Mailman/database/model/mailinglist.py5
-rw-r--r--TODO.txt2
6 files changed, 88 insertions, 118 deletions
diff --git a/Mailman/bin/add_members.py b/Mailman/bin/add_members.py
index e27304aaf..5d1400a9a 100644
--- a/Mailman/bin/add_members.py
+++ b/Mailman/bin/add_members.py
@@ -22,7 +22,7 @@ import sys
import optparse
from cStringIO import StringIO
-from email.Utils import parseaddr
+from email.utils import parseaddr
from Mailman import Errors
from Mailman import MailList
@@ -30,7 +30,10 @@ from Mailman import Message
from Mailman import Utils
from Mailman import Version
from Mailman import i18n
+from Mailman.app.membership import add_member
from Mailman.configuration import config
+from Mailman.constants import DeliveryMode
+from Mailman.initialize import initialize
_ = i18n._
__i18n_templates__ = True
@@ -69,13 +72,9 @@ success/failure of these subscriptions, overriding whatever the list's
help=_('Alternative configuration file to use'))
opts, args = parser.parse_args()
if not args:
- parser.print_help()
- print >> sys.stderr, _('Missing listname')
- sys.exit(1)
+ parser.error(_('Missing listname'))
if len(args) > 1:
- parser.print_help()
- print >> sys.stderr, _('Unexpected arguments')
- sys.exit(1)
+ parser.error(_('Unexpected arguments'))
if opts.welcome_msg is not None:
ch = opts.welcome_msg[0].lower()
if ch == 'y':
@@ -83,9 +82,7 @@ success/failure of these subscriptions, overriding whatever the list's
elif ch == 'n':
opts.welcome_msg = False
else:
- parser.print_help()
- print >> sys.stderr, _('Illegal value for -w: $opts.welcome_msg')
- sys.exit(1)
+ parser.error(_('Illegal value for -w: $opts.welcome_msg'))
if opts.admin_notify is not None:
ch = opts.admin_notify[0].lower()
if ch == 'y':
@@ -93,17 +90,11 @@ success/failure of these subscriptions, overriding whatever the list's
elif ch == 'n':
opts.admin_notify = False
else:
- parser.print_help()
- print >> sys.stderr, _('Illegal value for -a: $opts.admin_notify')
- sys.exit(1)
+ parser.error(_('Illegal value for -a: $opts.admin_notify'))
if opts.regular is None and opts.digest is None:
- parser.print_help()
- print >> sys.stderr, _('At least one of -r or -d is required')
- sys.exit(1)
+ parser.error(_('At least one of -r or -d is required'))
if opts.regular == '-' and opts.digest == '-':
- parser.print_help()
- print >> sys.stderr, _("-r and -d cannot both be '-'")
- sys.exit(1)
+ parser.error(_("-r and -d cannot both be '-'"))
return parser, opts, args
@@ -131,45 +122,37 @@ class Tee:
self._outfp.write(msg)
-class UserDesc:
- pass
-
-
-def addall(mlist, members, digest, ack, outfp):
+def addall(mlist, subscribers, delivery_mode, ack, admin_notify, outfp):
tee = Tee(outfp)
- for member in members:
- userdesc = UserDesc()
- userdesc.fullname, userdesc.address = parseaddr(member)
- userdesc.digest = digest
-
+ for subscriber in subscribers:
try:
- mlist.ApprovedAddMember(userdesc, ack, 0)
- except Errors.MMAlreadyAMember:
- print >> tee, _('Already a member: $member')
+ fullname, address = parseaddr(subscriber)
+ password = Utils.MakeRandomPassword()
+ add_member(mlist, address, fullname, password, delivery_mode,
+ config.DEFAULT_SERVER_LANGUAGE, ack, admin_notify)
+ except AlreadySubscribedError:
+ print >> tee, _('Already a member: $subscriber')
except Errors.InvalidEmailAddress:
if userdesc.address == '':
print >> tee, _('Bad/Invalid email address: blank line')
else:
print >> tee, _('Bad/Invalid email address: $member')
else:
- print >> tee, _('Subscribed: $member')
+ print >> tee, _('Subscribing: $subscriber')
def main():
parser, opts, args = parseargs()
- config.load(opts.config)
+ initialize(opts.config)
listname = args[0].lower().strip()
- try:
- mlist = MailList.MailList(listname)
- except Errors.MMUnknownListError:
- parser.print_help()
- print >> sys.stderr, _('No such list: $listname')
- sys.exit(1)
+ mlist = config.db.list_manager.get(listname)
+ if mlist is None:
+ parser.error(_('No such list: $listname'))
- # Set up defaults
+ # Set up defaults.
if opts.welcome_msg is None:
send_welcome_msg = mlist.send_welcome_msg
else:
@@ -195,10 +178,14 @@ def main():
s = StringIO()
if nmembers:
- addall(mlist, nmembers, False, send_welcome_msg, s)
+ addall(mlist, nmembers, DeliveryMode.regular,
+ send_welcome_msg, admin_notify, s)
if dmembers:
- addall(mlist, dmembers, True, send_welcome_msg, s)
+ addall(mlist, dmembers, DeliveryMode.mime_digests,
+ send_welcome_msg, admin_notify, s)
+
+ config.db.flush()
if admin_notify:
subject = _('$mlist.real_name subscription notification')
@@ -207,10 +194,6 @@ def main():
mlist.preferred_language)
msg.send(mlist)
- mlist.Save()
- finally:
- mlist.Unlock()
-
if __name__ == '__main__':
diff --git a/Mailman/bin/list_lists.py b/Mailman/bin/list_lists.py
index 14a57f002..145043759 100644
--- a/Mailman/bin/list_lists.py
+++ b/Mailman/bin/list_lists.py
@@ -20,6 +20,7 @@ import optparse
from Mailman import Defaults
from Mailman import MailList
from Mailman import Version
+from Mailman.configuration import config
from Mailman.i18n import _
from Mailman.initialize import initialize
@@ -68,8 +69,9 @@ def main():
mlists = []
longest = 0
- for n in sorted(config.list_manager.names):
- mlist = MailList.MailList(n, lock=False)
+ listmgr = config.db.list_manager
+ for fqdn_name in sorted(listmgr.names):
+ mlist = listmgr.get(fqdn_name)
if opts.advertised and not mlist.advertised:
continue
if opts.domains:
diff --git a/Mailman/bin/list_members.py b/Mailman/bin/list_members.py
index 22b5347ea..2e1213979 100644
--- a/Mailman/bin/list_members.py
+++ b/Mailman/bin/list_members.py
@@ -22,11 +22,12 @@ from email.Utils import formataddr
from Mailman import Errors
from Mailman import MailList
-from Mailman import MemberAdaptor
from Mailman import Utils
from Mailman import Version
from Mailman.configuration import config
+from Mailman.constants import DeliveryStatus
from Mailman.i18n import _
+from Mailman.initialize import initialize
__i18n_templates__ = True
@@ -34,11 +35,10 @@ ENC = sys.getdefaultencoding()
COMMASPACE = ', '
WHYCHOICES = {
- 'enabled' : MemberAdaptor.ENABLED,
- 'unknown' : MemberAdaptor.UNKNOWN,
- 'byuser' : MemberAdaptor.BYUSER,
- 'byadmin' : MemberAdaptor.BYADMIN,
- 'bybounce': MemberAdaptor.BYBOUNCE,
+ 'enabled' : DeliveryStatus.enabled,
+ 'byuser' : DeliveryStatus.by_user,
+ 'byadmin' : DeliveryStatus.by_moderator,
+ 'bybounce': DeliveryStatus.by_bounces,
}
KINDCHOICES = set(('mime', 'plain', 'any'))
@@ -78,10 +78,6 @@ the users who are disabled for that particular reason. WHY can also be
parser.add_option('-f', '--fullnames',
default=False, action='store_true',
help=_('Include the full names in the output'))
- parser.add_option('-p', '--preserve',
- default=False, action='store_true', help=_("""\
-Output member addresses case preserved the way they were added to the list.
-Otherwise, addresses are printed in all lowercase."""))
parser.add_option('-i', '--invalid',
default=False, action='store_true', help=_("""\
Print only the addresses in the membership list that are invalid. Ignores -r,
@@ -94,27 +90,19 @@ objects. Ignores -r, -d, -n."""))
help=_('Alternative configuration file to use'))
opts, args = parser.parse_args()
if not args:
- parser.print_help()
- print >> sys.stderr, _('Missing listname')
- sys.exit(1)
+ parser.error(_('Missing listname'))
if len(args) > 1:
- parser.print_help()
- print >> sys.stderr, _('Unexpected arguments')
- sys.exit(1)
+ parser.print_error(_('Unexpected arguments'))
if opts.digest is not None:
opts.kind = opts.digest.lower()
if opts.kind not in KINDCHOICES:
- parser.print_help()
- print >> sys.stderr, _('Invalid value for -d: $opts.digest')
- sys.exit(1)
+ parser.error(_('Invalid value for -d: $opts.digest'))
if opts.nomail is not None:
why = opts.nomail.lower()
if why == 'any':
opts.why = 'any'
elif why not in WHYCHOICES:
- parser.print_help()
- print >> sys.stderr, _('Invalid value for -n: $opts.nomail')
- sys.exit(1)
+ parser.error(_('Invalid value for -n: $opts.nomail'))
opts.why = why
if opts.regular is None and opts.digest is None:
opts.regular = opts.digest = True
@@ -123,14 +111,10 @@ objects. Ignores -r, -d, -n."""))
-def isunicode(s):
- return isinstance(s, unicode)
-
-
def safe(s):
if not s:
return ''
- if isunicode(s):
+ if isinstance(s, unicode):
return s.encode(ENC, 'replace')
return unicode(s, ENC, 'replace').encode(ENC, 'replace')
@@ -150,14 +134,14 @@ def whymatches(mlist, addr, why):
# (i.e. not enabled).
status = mlist.getDeliveryStatus(addr)
if why in (None, 'any'):
- return status <> MemberAdaptor.ENABLED
+ return status <> DeliveryStatus.enabled
return status == WHYCHOICES[why]
def main():
parser, opts, args = parseargs()
- config.load(opts.config)
+ initialize(opts.config)
listname = args[0].lower().strip()
if opts.output:
@@ -170,59 +154,53 @@ def main():
else:
fp = sys.stdout
- try:
- mlist = MailList.MailList(listname, lock=False)
- except Errors.MMListError:
+ mlist = config.db.list_manager.get(listname)
+ if mlist is None:
print >> sys.stderr, _('No such list: $listname')
sys.exit(1)
- # Get the lowercased member addresses
- rmembers = mlist.getRegularMemberKeys()
- dmembers = mlist.getDigestMemberKeys()
-
- if opts.preserve:
- # Convert to the case preserved addresses
- rmembers = mlist.getMemberCPAddresses(rmembers)
- dmembers = mlist.getMemberCPAddresses(dmembers)
+ # The regular delivery and digest members.
+ rmembers = set(mlist.regular_members.members)
+ dmembers = set(mlist.digest_members.members)
if opts.invalid or opts.unicode:
- all = rmembers + dmembers
- all.sort()
- for addr in all:
- name = opts.fullnames and mlist.getMemberName(addr) or ''
+ all = sorted(member.address.address for member in rmembers + dmembers)
+ for address in all:
+ user = config.db.user_manager.get_user(address)
+ name = (user.real_name if opts.fullnames and user else '')
showit = False
- if opts.invalid and isinvalid(addr):
+ if opts.invalid and isinvalid(address):
showit = True
- if opts.unicode and isunicode(addr):
+ if opts.unicode and isinstance(address, unicode):
showit = True
if showit:
- print >> fp, formataddr((safe(name), addr))
+ print >> fp, formataddr((safe(name), address))
return
if opts.regular:
- rmembers.sort()
- for addr in rmembers:
- name = opts.fullnames and mlist.getMemberName(addr) or ''
+ for address in sorted(member.address.address for member in rmembers):
+ user = config.db.user_manager.get_user(address)
+ name = (user.real_name if opts.fullnames and user else '')
# Filter out nomails
- if opts.nomail and not whymatches(mlist, addr, opts.why):
+ if opts.nomail and not whymatches(mlist, address, opts.why):
continue
- print >> fp, formataddr((safe(name), addr))
+ print >> fp, formataddr((safe(name), address))
if opts.digest:
- dmembers.sort()
- for addr in dmembers:
- name = opts.fullnames and mlist.getMemberName(addr) or ''
+ for address in sorted(member.address.address for member in dmembers):
+ user = config.db.user_manager.get_user(address)
+ name = (user.real_name if opts.fullnames and user else '')
# Filter out nomails
- if opts.nomail and not whymatches(mlist, addr, opts.why):
+ if opts.nomail and not whymatches(mlist, address, opts.why):
continue
# Filter out digest kinds
- if mlist.getMemberOption(addr, config.DisableMime):
- # They're getting plain text digests
- if opts.kind == 'mime':
- continue
- else:
- # They're getting MIME digests
- if opts.kind == 'plain':
- continue
- print >> fp, formataddr((safe(name), addr))
+## if mlist.getMemberOption(addr, config.DisableMime):
+## # They're getting plain text digests
+## if opts.kind == 'mime':
+## continue
+## else:
+## # They're getting MIME digests
+## if opts.kind == 'plain':
+## continue
+ print >> fp, formataddr((safe(name), address))
diff --git a/Mailman/bin/newlist.py b/Mailman/bin/newlist.py
index 3897f73dc..be594fac2 100644
--- a/Mailman/bin/newlist.py
+++ b/Mailman/bin/newlist.py
@@ -123,10 +123,10 @@ def main():
sys.stdin.readline()
if not opts.quiet:
d = dict(
- listname = listname,
- admin_url = mlist.GetScriptURL('admin', absolute=True),
- listinfo_url = mlist.GetScriptURL('listinfo', absolute=True),
- requestaddr = mlist.GetRequestEmail(),
+ listname = mlist.fqdn_listname,
+ admin_url = mlist.script_url('admin'),
+ listinfo_url = mlist.script_url('listinfo'),
+ requestaddr = mlist.request_address,
siteowner = mlist.no_reply_address,
)
text = Utils.maketext('newlist.txt', d, mlist=mlist)
diff --git a/Mailman/database/model/mailinglist.py b/Mailman/database/model/mailinglist.py
index 1b2892a46..0d12f919e 100644
--- a/Mailman/database/model/mailinglist.py
+++ b/Mailman/database/model/mailinglist.py
@@ -16,6 +16,7 @@
# USA.
import os
+import string
from elixir import *
from zope.interface import implements
@@ -25,6 +26,9 @@ from Mailman.configuration import config
from Mailman.interfaces import *
from Mailman.database.types import EnumType, TimeDeltaType
+SPACE = ' '
+UNDERSCORE = '_'
+
class MailingList(Entity):
@@ -177,6 +181,7 @@ class MailingList(Entity):
# autoresponses sent on that date.
self.hold_and_cmd_autoresponses = {}
self.full_path = os.path.join(config.LIST_DATA_DIR, fqdn_listname)
+ self.real_name = string.capwords(SPACE.join(listname.split(UNDERSCORE)))
makedirs(self.full_path)
# XXX FIXME
diff --git a/TODO.txt b/TODO.txt
index 87cffee07..e4870f511 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -13,3 +13,5 @@ Fix the roster creation cruft for mailing lists
Suss out the IDomain stuff
Remove Date: header from messagestore requirements (see list thread)
Handle moderation flag (see Mailman.app.membership)
+Eradicate MailList.Lock() and friends.
+Eradicate MemberAdapter and friends.