From eefd06f1b88b8ecbb23a9013cd223b72ca85c20d Mon Sep 17 00:00:00 2001
From: Barry Warsaw
Date: Sun, 25 Jan 2009 13:01:41 -0500
Subject: Push the source directory into a 'src' subdirectory so that
zc.buildout works correctly regardless of how it's used.
---
mailman/web/Cgi/admin.py | 1433 ----------------------------------------------
1 file changed, 1433 deletions(-)
delete mode 100644 mailman/web/Cgi/admin.py
(limited to 'mailman/web/Cgi/admin.py')
diff --git a/mailman/web/Cgi/admin.py b/mailman/web/Cgi/admin.py
deleted file mode 100644
index e5c6ee14b..000000000
--- a/mailman/web/Cgi/admin.py
+++ /dev/null
@@ -1,1433 +0,0 @@
-# Copyright (C) 1998-2009 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman is free software: you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# GNU Mailman. If not, see
There currently are no publicly-advertised %(mailmanlink)s - mailing lists on %(hostname)s.'''), - ]) - else: - welcome.extend([ - greeting, - _('''
Below is the collection of publicly-advertised - %(mailmanlink)s mailing lists on %(hostname)s. Click on a list - name to visit the configuration pages for that list.'''), - ]) - - creatorurl = Utils.ScriptURL('create') - mailman_owner = Utils.get_site_noreply() - extra = msg and _('right ') or '' - welcome.extend([ - _('''To visit the administrators configuration page for an - unadvertised list, open a URL similar to this one, but with a '/' and - the %(extra)slist name appended. If you have the proper authority, - you can also create a new mailing list. - -
General list information can be found at '''), - Link(Utils.ScriptURL('listinfo'), - _('the mailing list overview page')), - '.', - _('
(Send questions and comments to '), - Link('mailto:%s' % mailman_owner, mailman_owner), - '.)
', - ]) - - table.AddRow([Container(*welcome)]) - table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0, colspan=2) - - if advertised: - table.AddRow([' ', ' ']) - table.AddRow([Bold(FontAttr(_('List'), size='+2')), - Bold(FontAttr(_('Description'), size='+2')) - ]) - highlight = 1 - for url, real_name, description in advertised: - table.AddRow( - [Link(url, Bold(real_name)), - description or Italic(_('[no description available]'))]) - if highlight and config.WEB_HIGHLIGHT_COLOR: - table.AddRowInfo(table.GetCurrentRowIndex(), - bgcolor=config.WEB_HIGHLIGHT_COLOR) - highlight = not highlight - - doc.AddItem(table) - doc.AddItem('
" % (varname, category, description)) - if elaboration: - doc.AddItem("%s
" % elaboration) - - if subcat: - url = '%s/%s/%s' % (mlist.GetScriptURL('admin'), category, subcat) - else: - url = '%s/%s' % (mlist.GetScriptURL('admin'), category) - form = Form(url) - valtab = Table(cellspacing=3, cellpadding=4, width='100%') - add_options_table_item(mlist, category, subcat, valtab, item, detailsp=0) - form.AddItem(valtab) - form.AddItem('
')
- form.AddItem(Center(submit_button()))
- doc.AddItem(Center(form))
-
- doc.AddItem(_("""Warning: changing this option here
- could cause other screens to be out-of-sync. Be sure to reload any other
- pages that are displaying this option for this mailing list. You can also
- """))
-
- adminurl = mlist.GetScriptURL('admin')
- if subcat:
- url = '%s/%s/%s' % (adminurl, category, subcat)
- else:
- url = '%s/%s' % (adminurl, category)
- categoryname = mlist.GetConfigCategories()[category][0]
- doc.AddItem(Link(url, _('return to the %(categoryname)s options page.')))
- doc.AddItem('')
- doc.AddItem(mlist.GetMailmanFooter())
- print doc.Format()
-
-
-
-def show_results(mlist, doc, category, subcat, cgidata):
- # Produce the results page
- adminurl = mlist.GetScriptURL('admin')
- categories = mlist.GetConfigCategories()
- label = _(categories[category][0])
-
- # Set up the document's headers
- realname = mlist.real_name
- doc.SetTitle(_('%(realname)s Administration (%(label)s)'))
- doc.AddItem(Center(Header(2, _(
- '%(realname)s mailing list administration
%(label)s Section'))))
- doc.AddItem('
') - - # The members and passwords categories are special in that they aren't - # defined in terms of gui elements. Create those pages here. - if category == 'members': - # Figure out which subcategory we should display - subcat = Utils.GetPathPieces()[-1] - if subcat not in ('list', 'add', 'remove'): - subcat = 'list' - # Add member category specific tables - form.AddItem(membership_options(mlist, subcat, cgidata, doc, form)) - form.AddItem(Center(submit_button('setmemberopts_btn'))) - # In "list" subcategory, we can also search for members - if subcat == 'list': - form.AddItem('
')
- usertable = Table(width="90%", border='2')
- # If there are more members than allowed by chunksize, then we split the
- # membership up alphabetically. Otherwise just display them all.
- chunksz = mlist.admin_member_chunksize
- # The email addresses had /better/ be ASCII, but might be encoded in the
- # database as Unicodes.
- all = [_m.encode() for _m in mlist.getMembers()]
- all.sort(lambda x, y: cmp(x.lower(), y.lower()))
- # See if the query has a regular expression
- regexp = cgidata.getvalue('findmember', '').strip()
- if regexp:
- try:
- cre = re.compile(regexp, re.IGNORECASE)
- except re.error:
- doc.addError(_('Bad regular expression: ') + regexp)
- else:
- # BAW: There's got to be a more efficient way of doing this!
- names = [mlist.getMemberName(s) or '' for s in all]
- all = [a for n, a in zip(names, all)
- if cre.search(n) or cre.search(a)]
- chunkindex = None
- bucket = None
- actionurl = None
- if len(all) < chunksz:
- members = all
- else:
- # Split them up alphabetically, and then split the alphabetical
- # listing by chunks
- buckets = {}
- for addr in all:
- members = buckets.setdefault(addr[0].lower(), [])
- members.append(addr)
- # Now figure out which bucket we want
- bucket = None
- qs = {}
- # POST methods, even if their actions have a query string, don't get
- # put into FieldStorage's keys :-(
- qsenviron = os.environ.get('QUERY_STRING')
- if qsenviron:
- qs = cgi.parse_qs(qsenviron)
- bucket = qs.get('letter', 'a')[0].lower()
- if bucket not in digits + lowercase:
- bucket = None
- if not bucket or not buckets.has_key(bucket):
- keys = buckets.keys()
- keys.sort()
- bucket = keys[0]
- members = buckets[bucket]
- action = adminurl + '/members?letter=%s' % bucket
- if len(members) <= chunksz:
- form.set_action(action)
- else:
- i, r = divmod(len(members), chunksz)
- numchunks = i + (not not r * 1)
- # Now chunk them up
- chunkindex = 0
- if qs.has_key('chunk'):
- try:
- chunkindex = int(qs['chunk'][0])
- except ValueError:
- chunkindex = 0
- if chunkindex < 0 or chunkindex > numchunks:
- chunkindex = 0
- members = members[chunkindex*chunksz:(chunkindex+1)*chunksz]
- # And set the action URL
- form.set_action(action + '&chunk=%s' % chunkindex)
- # So now members holds all the addresses we're going to display
- allcnt = len(all)
- if bucket:
- membercnt = len(members)
- usertable.AddRow([Center(Italic(_(
- '%(allcnt)s members total, %(membercnt)s shown')))])
- else:
- usertable.AddRow([Center(Italic(_('%(allcnt)s members total')))])
- usertable.AddCellInfo(usertable.GetCurrentRowIndex(),
- usertable.GetCurrentCellIndex(),
- colspan=OPTCOLUMNS,
- bgcolor=config.WEB_ADMINITEM_COLOR)
- # Add the alphabetical links
- if bucket:
- cells = []
- for letter in digits + lowercase:
- if not buckets.get(letter):
- continue
- url = adminurl + '/members?letter=%s' % letter
- if letter == bucket:
- show = Bold('[%s]' % letter.upper()).Format()
- else:
- show = letter.upper()
- cells.append(Link(url, show).Format())
- joiner = ' '*2 + '\n'
- usertable.AddRow([Center(joiner.join(cells))])
- usertable.AddCellInfo(usertable.GetCurrentRowIndex(),
- usertable.GetCurrentCellIndex(),
- colspan=OPTCOLUMNS,
- bgcolor=config.WEB_ADMINITEM_COLOR)
- usertable.AddRow([Center(h) for h in (_('unsub'),
- _('member address
member name'),
- _('mod'), _('hide'),
- _('nomail
[reason]'),
- _('ack'), _('not metoo'),
- _('nodupes'),
- _('digest'), _('plain'),
- _('language'))])
- rowindex = usertable.GetCurrentRowIndex()
- for i in range(OPTCOLUMNS):
- usertable.AddCellInfo(rowindex, i, bgcolor=config.WEB_ADMINITEM_COLOR)
- # Find the longest name in the list
- longest = 0
- if members:
- names = filter(None, [mlist.getMemberName(s) for s in members])
- # Make the name field at least as long as the longest email address
- longest = max([len(s) for s in names + members])
- # Abbreviations for delivery status details
- ds_abbrevs = {MemberAdaptor.UNKNOWN : _('?'),
- MemberAdaptor.BYUSER : _('U'),
- MemberAdaptor.BYADMIN : _('A'),
- MemberAdaptor.BYBOUNCE: _('B'),
- }
- # Now populate the rows
- for addr in members:
- link = Link(mlist.GetOptionsURL(addr, obscure=1),
- mlist.getMemberCPAddress(addr))
- fullname = mlist.getMemberName(addr)
- name = TextBox(addr + '_realname', fullname, size=longest).Format()
- cells = [Center(CheckBox(addr + '_unsub', 'off', 0).Format()),
- link.Format() + '
' +
- name +
- Hidden('user', urllib.quote(addr)).Format(),
- ]
- # Do the `mod' option
- if mlist.getMemberOption(addr, config.Moderate):
- value = 'on'
- checked = 1
- else:
- value = 'off'
- checked = 0
- box = CheckBox('%s_mod' % addr, value, checked)
- cells.append(Center(box).Format())
- for opt in ('hide', 'nomail', 'ack', 'notmetoo', 'nodupes'):
- extra = ''
- if opt == 'nomail':
- status = mlist.getDeliveryStatus(addr)
- if status == MemberAdaptor.ENABLED:
- value = 'off'
- checked = 0
- else:
- value = 'on'
- checked = 1
- extra = '[%s]' % ds_abbrevs[status]
- elif mlist.getMemberOption(addr, config.OPTINFO[opt]):
- value = 'on'
- checked = 1
- else:
- value = 'off'
- checked = 0
- box = CheckBox('%s_%s' % (addr, opt), value, checked)
- cells.append(Center(box.Format() + extra))
- # This code is less efficient than the original which did a has_key on
- # the underlying dictionary attribute. This version is slower and
- # less memory efficient. It points to a new MemberAdaptor interface
- # method.
- if addr in mlist.getRegularMemberKeys():
- cells.append(Center(CheckBox(addr + '_digest', 'off', 0).Format()))
- else:
- cells.append(Center(CheckBox(addr + '_digest', 'on', 1).Format()))
- if mlist.getMemberOption(addr, config.OPTINFO['plain']):
- value = 'on'
- checked = 1
- else:
- value = 'off'
- checked = 0
- cells.append(Center(CheckBox('%s_plain' % addr, value, checked)))
- # User's preferred language
- langpref = mlist.getMemberLanguage(addr)
- langs = mlist.language_codes
- langdescs = [_(config.languges.get_description(code))
- for code in langs]
- try:
- selected = langs.index(langpref)
- except ValueError:
- selected = 0
- cells.append(Center(SelectOptions(addr + '_language', langs,
- langdescs, selected)).Format())
- usertable.AddRow(cells)
- # Add the usertable and a legend
- legend = UnorderedList()
- legend.AddItem(
- _('unsub -- Click on this to unsubscribe the member.'))
- legend.AddItem(
- _("""mod -- The user's personal moderation flag. If this is
- set, postings from them will be moderated, otherwise they will be
- approved."""))
- legend.AddItem(
- _("""hide -- Is the member's address concealed on
- the list of subscribers?"""))
- legend.AddItem(_(
- """nomail -- Is delivery to the member disabled? If so, an
- abbreviation will be given describing the reason for the disabled
- delivery:
-
') - container.AddItem( - Link(adminurl + '/members/list', - _('Click here to hide the legend for this table.'))) - else: - container.AddItem( - Link(adminurl + '/members/list?legend=yes', - _('Click here to include the legend for this table.'))) - container.AddItem(Center(usertable)) - - # There may be additional chunks - if chunkindex is not None: - buttons = [] - url = adminurl + '/members?%sletter=%s&' % (addlegend, bucket) - footer = _('''
To view more members, click on the appropriate - range listed below:''') - chunkmembers = buckets[bucket] - last = len(chunkmembers) - for i in range(numchunks): - if i == chunkindex: - continue - start = chunkmembers[i*chunksz] - end = chunkmembers[min((i+1)*chunksz, last)-1] - link = Link(url + 'chunk=%d' % i, _('from %(start)s to %(end)s')) - buttons.append(link) - buttons = UnorderedList(*buttons) - container.AddItem(footer + buttons.Format() + '
') - return container - - - -def mass_subscribe(mlist, container): - # MASS SUBSCRIBE - GREY = config.WEB_ADMINITEM_COLOR - table = Table(width='90%') - table.AddRow([ - Label(_('Subscribe these users now or invite them?')), - RadioButtonArray('subscribe_or_invite', - (_('Subscribe'), _('Invite')), - 0, values=(0, 1)) - ]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, bgcolor=GREY) - table.AddCellInfo(table.GetCurrentRowIndex(), 1, bgcolor=GREY) - table.AddRow([ - Label(_('Send welcome messages to new subscribees?')), - RadioButtonArray('send_welcome_msg_to_this_batch', - (_('No'), _('Yes')), - mlist.send_welcome_msg, - values=(0, 1)) - ]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, bgcolor=GREY) - table.AddCellInfo(table.GetCurrentRowIndex(), 1, bgcolor=GREY) - table.AddRow([ - Label(_('Send notifications of new subscriptions to the list owner?')), - RadioButtonArray('send_notifications_to_list_owner', - (_('No'), _('Yes')), - mlist.admin_notify_mchanges, - values=(0,1)) - ]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, bgcolor=GREY) - table.AddCellInfo(table.GetCurrentRowIndex(), 1, bgcolor=GREY) - table.AddRow([Italic(_('Enter one address per line below...'))]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) - table.AddRow([Center(TextArea(name='subscribees', - rows=10, cols='70%', wrap=None))]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) - table.AddRow([Italic(Label(_('...or specify a file to upload:'))), - FileUpload('subscribees_upload', cols='50')]) - container.AddItem(Center(table)) - # Invitation text - table.AddRow([' ', ' ']) - table.AddRow([Italic(_("""Below, enter additional text to be added to the - top of your invitation or the subscription notification. Include at least - one blank line at the end..."""))]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) - table.AddRow([Center(TextArea(name='invitation', - rows=10, cols='70%', wrap=None))]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) - - - -def mass_remove(mlist, container): - # MASS UNSUBSCRIBE - GREY = config.WEB_ADMINITEM_COLOR - table = Table(width='90%') - table.AddRow([ - Label(_('Send unsubscription acknowledgement to the user?')), - RadioButtonArray('send_unsub_ack_to_this_batch', - (_('No'), _('Yes')), - 0, values=(0, 1)) - ]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, bgcolor=GREY) - table.AddCellInfo(table.GetCurrentRowIndex(), 1, bgcolor=GREY) - table.AddRow([ - Label(_('Send notifications to the list owner?')), - RadioButtonArray('send_unsub_notifications_to_list_owner', - (_('No'), _('Yes')), - mlist.admin_notify_mchanges, - values=(0, 1)) - ]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, bgcolor=GREY) - table.AddCellInfo(table.GetCurrentRowIndex(), 1, bgcolor=GREY) - table.AddRow([Italic(_('Enter one address per line below...'))]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) - table.AddRow([Center(TextArea(name='unsubscribees', - rows=10, cols='70%', wrap=None))]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) - table.AddRow([Italic(Label(_('...or specify a file to upload:'))), - FileUpload('unsubscribees_upload', cols='50')]) - container.AddItem(Center(table)) - - - -def password_inputs(mlist): - adminurl = mlist.GetScriptURL('admin') - table = Table(cellspacing=3, cellpadding=4) - table.AddRow([Center(Header(2, _('Change list ownership passwords')))]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2, - bgcolor=config.WEB_HEADER_COLOR) - table.AddRow([_("""\ -The list administrators are the people who have ultimate control over -all parameters of this mailing list. They are able to change any list -configuration variable available through these administration web pages. - -
The list moderators have more limited permissions; they are not -able to change any list configuration variable, but they are allowed to tend -to pending administration requests, including approving or rejecting held -subscription requests, and disposing of held postings. Of course, the -list administrators can also tend to pending requests. - -
In order to split the list ownership duties into administrators and -moderators, you must set a separate moderator password in the fields below, -and also provide the email addresses of the list moderators in the -general options section.""")]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) - # Set up the admin password table on the left - atable = Table(border=0, cellspacing=3, cellpadding=4, - bgcolor=config.WEB_ADMINPW_COLOR) - atable.AddRow([Label(_('Enter new administrator password:')), - PasswordBox('newpw', size=20)]) - atable.AddRow([Label(_('Confirm administrator password:')), - PasswordBox('confirmpw', size=20)]) - # Set up the moderator password table on the right - mtable = Table(border=0, cellspacing=3, cellpadding=4, - bgcolor=config.WEB_ADMINPW_COLOR) - mtable.AddRow([Label(_('Enter new moderator password:')), - PasswordBox('newmodpw', size=20)]) - mtable.AddRow([Label(_('Confirm moderator password:')), - PasswordBox('confirmmodpw', size=20)]) - # Add these tables to the overall password table - table.AddRow([atable, mtable]) - return table - - - -def submit_button(name='submit'): - table = Table(border=0, cellspacing=0, cellpadding=2) - table.AddRow([Bold(SubmitButton(name, _('Submit Your Changes')))]) - table.AddCellInfo(table.GetCurrentRowIndex(), 0, align='middle') - return table - - - -def change_options(mlist, category, subcat, cgidata, doc): - def safeint(formvar, defaultval=None): - try: - return int(cgidata.getvalue(formvar)) - except (ValueError, TypeError): - return defaultval - confirmed = 0 - # Handle changes to the list moderator password. Do this before checking - # the new admin password, since the latter will force a reauthentication. - new = cgidata.getvalue('newmodpw', '').strip() - confirm = cgidata.getvalue('confirmmodpw', '').strip() - if new or confirm: - if new == confirm: - mlist.mod_password = passwords.make_secret( - new, config.PASSWORD_SCHEME) - # No re-authentication necessary because the moderator's - # password doesn't get you into these pages. - else: - doc.addError(_('Moderator passwords did not match')) - # Handle changes to the list administrator password - new = cgidata.getvalue('newpw', '').strip() - confirm = cgidata.getvalue('confirmpw', '').strip() - if new or confirm: - if new == confirm: - mlist.password = passwords.make_secret(new, config.PASSWORD_SCHEME) - # Set new cookie - print mlist.MakeCookie(config.AuthListAdmin) - else: - doc.addError(_('Administrator passwords did not match')) - # Give the individual gui item a chance to process the form data - categories = mlist.GetConfigCategories() - label, gui = categories[category] - # BAW: We handle the membership page special... for now. - if category <> 'members': - gui.handleForm(mlist, category, subcat, cgidata, doc) - # mass subscription, removal processing for members category - subscribers = '' - subscribers += cgidata.getvalue('subscribees', '') - subscribers += cgidata.getvalue('subscribees_upload', '') - if subscribers: - entries = filter(None, [n.strip() for n in subscribers.splitlines()]) - send_welcome_msg = safeint('send_welcome_msg_to_this_batch', - mlist.send_welcome_msg) - send_admin_notif = safeint('send_notifications_to_list_owner', - mlist.admin_notify_mchanges) - # Default is to subscribe - subscribe_or_invite = safeint('subscribe_or_invite', 0) - invitation = cgidata.getvalue('invitation', '') - digest = mlist.digest_is_default - if not mlist.digestable: - digest = 0 - if not mlist.nondigestable: - digest = 1 - subscribe_errors = [] - subscribe_success = [] - # Now cruise through all the subscribees and do the deed. BAW: we - # should limit the number of "Successfully subscribed" status messages - # we display. Try uploading a file with 10k names -- it takes a while - # to render the status page. - for entry in entries: - fullname, address = parseaddr(entry) - # Canonicalize the full name - fullname = Utils.canonstr(fullname, mlist.preferred_language) - userdesc = UserDesc(address, fullname, - Utils.MakeRandomPassword(), - digest, mlist.preferred_language) - try: - if subscribe_or_invite: - if mlist.isMember(address): - raise Errors.MMAlreadyAMember - else: - mlist.InviteNewMember(userdesc, invitation) - else: - mlist.ApprovedAddMember(userdesc, send_welcome_msg, - send_admin_notif, invitation, - whence='admin mass sub') - except Errors.MMAlreadyAMember: - subscribe_errors.append((entry, _('Already a member'))) - except Errors.InvalidEmailAddress: - if userdesc.address == '': - subscribe_errors.append((_('<blank line>'), - _('Bad/Invalid email address'))) - else: - subscribe_errors.append((entry, - _('Bad/Invalid email address'))) - except Errors.MembershipIsBanned, pattern: - subscribe_errors.append( - (entry, _('Banned address (matched %(pattern)s)'))) - else: - member = Utils.uncanonstr(formataddr((fullname, address))) - subscribe_success.append(Utils.websafe(member)) - if subscribe_success: - if subscribe_or_invite: - doc.AddItem(Header(5, _('Successfully invited:'))) - else: - doc.AddItem(Header(5, _('Successfully subscribed:'))) - doc.AddItem(UnorderedList(*subscribe_success)) - doc.AddItem('
') - if subscribe_errors: - if subscribe_or_invite: - doc.AddItem(Header(5, _('Error inviting:'))) - else: - doc.AddItem(Header(5, _('Error subscribing:'))) - items = ['%s -- %s' % (x0, x1) for x0, x1 in subscribe_errors] - doc.AddItem(UnorderedList(*items)) - doc.AddItem('
') - # Unsubscriptions - removals = '' - if cgidata.has_key('unsubscribees'): - removals += cgidata['unsubscribees'].value - if cgidata.has_key('unsubscribees_upload') and \ - cgidata['unsubscribees_upload'].value: - removals += cgidata['unsubscribees_upload'].value - if removals: - names = filter(None, [n.strip() for n in removals.splitlines()]) - send_unsub_notifications = int( - cgidata['send_unsub_notifications_to_list_owner'].value) - userack = int( - cgidata['send_unsub_ack_to_this_batch'].value) - unsubscribe_errors = [] - unsubscribe_success = [] - for addr in names: - try: - mlist.ApprovedDeleteMember( - addr, whence='admin mass unsub', - admin_notif=send_unsub_notifications, - userack=userack) - unsubscribe_success.append(addr) - except Errors.NotAMemberError: - unsubscribe_errors.append(addr) - if unsubscribe_success: - doc.AddItem(Header(5, _('Successfully Unsubscribed:'))) - doc.AddItem(UnorderedList(*unsubscribe_success)) - doc.AddItem('
') - if unsubscribe_errors: - doc.AddItem(Header(3, Bold(FontAttr( - _('Cannot unsubscribe non-members:'), - color='#ff0000', size='+2')).Format())) - doc.AddItem(UnorderedList(*unsubscribe_errors)) - doc.AddItem('
') - # See if this was a moderation bit operation - if cgidata.has_key('allmodbit_btn'): - val = cgidata.getvalue('allmodbit_val') - try: - val = int(val) - except VallueError: - val = None - if val not in (0, 1): - doc.addError(_('Bad moderation flag value')) - else: - for member in mlist.getMembers(): - mlist.setMemberOption(member, config.Moderate, val) - # do the user options for members category - if cgidata.has_key('setmemberopts_btn') and cgidata.has_key('user'): - user = cgidata['user'] - if isinstance(user, list): - users = [] - for ui in range(len(user)): - users.append(urllib.unquote(user[ui].value)) - else: - users = [urllib.unquote(user.value)] - errors = [] - removes = [] - for user in users: - if cgidata.has_key('%s_unsub' % user): - try: - mlist.ApprovedDeleteMember(user, whence='member mgt page') - removes.append(user) - except Errors.NotAMemberError: - errors.append((user, _('Not subscribed'))) - continue - if not mlist.isMember(user): - doc.addError(_('Ignoring changes to deleted member: %(user)s'), - tag=_('Warning: ')) - continue - value = cgidata.has_key('%s_digest' % user) - try: - mlist.setMemberOption(user, config.Digests, value) - except (Errors.AlreadyReceivingDigests, - Errors.AlreadyReceivingRegularDeliveries, - Errors.CantDigestError, - Errors.MustDigestError): - # BAW: Hmm... - pass - - newname = cgidata.getvalue(user+'_realname', '') - newname = Utils.canonstr(newname, mlist.preferred_language) - mlist.setMemberName(user, newname) - - newlang = cgidata.getvalue(user+'_language') - oldlang = mlist.getMemberLanguage(user) - if (newlang not in config.languages.enabled_codes - and newlang <> oldlang): - # Then - mlist.setMemberLanguage(user, newlang) - - moderate = not not cgidata.getvalue(user+'_mod') - mlist.setMemberOption(user, config.Moderate, moderate) - - # Set the `nomail' flag, but only if the user isn't already - # disabled (otherwise we might change BYUSER into BYADMIN). - if cgidata.has_key('%s_nomail' % user): - if mlist.getDeliveryStatus(user) == MemberAdaptor.ENABLED: - mlist.setDeliveryStatus(user, MemberAdaptor.BYADMIN) - else: - mlist.setDeliveryStatus(user, MemberAdaptor.ENABLED) - for opt in ('hide', 'ack', 'notmetoo', 'nodupes', 'plain'): - opt_code = config.OPTINFO[opt] - if cgidata.has_key('%s_%s' % (user, opt)): - mlist.setMemberOption(user, opt_code, 1) - else: - mlist.setMemberOption(user, opt_code, 0) - # Give some feedback on who's been removed - if removes: - doc.AddItem(Header(5, _('Successfully Removed:'))) - doc.AddItem(UnorderedList(*removes)) - doc.AddItem('
') - if errors: - doc.AddItem(Header(5, _("Error Unsubscribing:"))) - items = ['%s -- %s' % (x[0], x[1]) for x in errors] - doc.AddItem(apply(UnorderedList, tuple((items)))) - doc.AddItem("
") -- cgit v1.2.3-70-g09d2