diff options
32 files changed, 467 insertions, 431 deletions
diff --git a/.bzrignore b/.bzrignore index 901a0cefd..e007ba8c3 100644 --- a/.bzrignore +++ b/.bzrignore @@ -7,6 +7,7 @@ build/ config.log config.status cron/crontab.in +mailman.egg-info misc/Elixir-0.3.0/ misc/SQLAlchemy-0.3.3/ misc/mailman diff --git a/Mailman/Archiver/Archiver.py b/Mailman/Archiver/Archiver.py index 5d57a01a9..fa8839230 100644 --- a/Mailman/Archiver/Archiver.py +++ b/Mailman/Archiver/Archiver.py @@ -33,9 +33,9 @@ from string import Template from Mailman import Mailbox from Mailman import Utils -from Mailman import mm_cfg from Mailman.SafeDict import SafeDict from Mailman.configuration import config +from Mailman.configuration import config from Mailman.i18n import _ log = logging.getLogger('mailman.error') @@ -65,11 +65,11 @@ class Archiver: # def InitVars(self): # Configurable - self.archive = mm_cfg.DEFAULT_ARCHIVE + self.archive = config.DEFAULT_ARCHIVE # 0=public, 1=private: - self.archive_private = mm_cfg.DEFAULT_ARCHIVE_PRIVATE + self.archive_private = config.DEFAULT_ARCHIVE_PRIVATE self.archive_volume_frequency = \ - mm_cfg.DEFAULT_ARCHIVE_VOLUME_FREQUENCY + config.DEFAULT_ARCHIVE_VOLUME_FREQUENCY # The archive file structure by default is: # # archives/ @@ -188,23 +188,23 @@ class Archiver: def ArchiveMail(self, msg): """Store postings in mbox and/or pipermail archive, depending.""" # Fork so archival errors won't disrupt normal list delivery - if mm_cfg.ARCHIVE_TO_MBOX == -1: + if config.ARCHIVE_TO_MBOX == -1: return # # We don't need an extra archiver lock here because we know the list # itself must be locked. - if mm_cfg.ARCHIVE_TO_MBOX in (1, 2): + if config.ARCHIVE_TO_MBOX in (1, 2): self.__archive_to_mbox(msg) - if mm_cfg.ARCHIVE_TO_MBOX == 1: + if config.ARCHIVE_TO_MBOX == 1: # Archive to mbox only. return txt = str(msg) # should we use the internal or external archiver? private_p = self.archive_private - if mm_cfg.PUBLIC_EXTERNAL_ARCHIVER and not private_p: - self.ExternalArchive(mm_cfg.PUBLIC_EXTERNAL_ARCHIVER, txt) - elif mm_cfg.PRIVATE_EXTERNAL_ARCHIVER and private_p: - self.ExternalArchive(mm_cfg.PRIVATE_EXTERNAL_ARCHIVER, txt) + if config.PUBLIC_EXTERNAL_ARCHIVER and not private_p: + self.ExternalArchive(config.PUBLIC_EXTERNAL_ARCHIVER, txt) + elif config.PRIVATE_EXTERNAL_ARCHIVER and private_p: + self.ExternalArchive(config.PRIVATE_EXTERNAL_ARCHIVER, txt) else: # use the internal archiver f = StringIO(txt) @@ -222,7 +222,7 @@ class Archiver: # for public vs private. If it doesn't exist, or some weird # permissions errors prevent us from stating the directory, it's # pointless to try to fix the perms, so we just return -scott - if mm_cfg.ARCHIVE_TO_MBOX == -1: + if config.ARCHIVE_TO_MBOX == -1: # Archiving is completely disabled, don't require the skeleton. return pubdir = os.path.join(config.PUBLIC_ARCHIVE_FILE_DIR, @@ -238,5 +238,5 @@ class Archiver: # OSError, ENOENT which should be caught and reported properly. makelink(privdir, pubdir) # Only make this link if the site has enabled public mbox files - if mm_cfg.PUBLIC_MBOX: + if config.PUBLIC_MBOX: makelink(privmbox, pubmbox) diff --git a/Mailman/Archiver/HyperArch.py b/Mailman/Archiver/HyperArch.py index 418aeb7f2..628f5da6d 100644 --- a/Mailman/Archiver/HyperArch.py +++ b/Mailman/Archiver/HyperArch.py @@ -40,16 +40,16 @@ from email.Charset import Charset from email.Errors import HeaderParseError from email.Header import decode_header, make_header -from Mailman import i18n -from Mailman import Utils from Mailman import Errors -from Mailman import mm_cfg from Mailman import LockFile from Mailman import MailList +from Mailman import Utils +from Mailman import i18n from Mailman.Archiver import HyperDatabase from Mailman.Archiver import pipermail from Mailman.Mailbox import ArchiverMailbox from Mailman.SafeDict import SafeDict +from Mailman.configuration import config log = logging.getLogger('mailman.error') @@ -57,7 +57,7 @@ log = logging.getLogger('mailman.error') _ = i18n._ gzip = None -if mm_cfg.GZIP_ARCHIVE_TXT_FILES: +if config.GZIP_ARCHIVE_TXT_FILES: try: import gzip except ImportError: @@ -187,7 +187,7 @@ def quick_maketext(templatefile, dict=None, lang=None, mlist=None): listname = mlist.fqdn_listname if lang is None: if mlist is None: - lang = mm_cfg.DEFAULT_SERVER_LANGUAGE + lang = config.DEFAULT_SERVER_LANGUAGE else: lang = mlist.preferred_language cachekey = (templatefile, lang, listname) @@ -247,7 +247,7 @@ class Article(pipermail.Article): _last_article_time = time.time() def __init__(self, message=None, sequence=0, keepHeaders=[], - lang=mm_cfg.DEFAULT_SERVER_LANGUAGE, mlist=None): + lang=config.DEFAULT_SERVER_LANGUAGE, mlist=None): self.__super_init(message, sequence, keepHeaders) self.prev = None self.next = None @@ -264,7 +264,7 @@ class Article(pipermail.Article): self._lang = lang self._mlist = mlist - if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS: + if config.ARCHIVER_OBSCURES_EMAILADDRS: # Avoid i18n side-effects. Note that the language for this # article (for this list) could be different from the site-wide # preferred language, so we need to ensure no side-effects will @@ -368,7 +368,7 @@ class Article(pipermail.Article): if hasattr(self, '_mlist'): self._lang = self._mlist.preferred_language else: - self._lang = mm_cfg.DEFAULT_SERVER_LANGUAGE + self._lang = config.DEFAULT_SERVER_LANGUAGE if not d.has_key('cenc'): self.cenc = None if not d.has_key('decoded'): @@ -400,7 +400,7 @@ class Article(pipermail.Article): if email: self.decoded['email'] = email if subject: - if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS: + if config.ARCHIVER_OBSCURES_EMAILADDRS: otrans = i18n.get_translation() try: i18n.set_language(self._lang) @@ -454,7 +454,7 @@ class Article(pipermail.Article): d["subject_html"] = self.quote(self.subject) d["subject_url"] = url_quote(self.subject) d["in_reply_to_url"] = url_quote(self.in_reply_to) - if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS: + if config.ARCHIVER_OBSCURES_EMAILADDRS: # Point the mailto url back to the list author = re.sub('@', _(' at '), self.author) emailurl = self._mlist.GetListEmail() @@ -561,7 +561,7 @@ class Article(pipermail.Article): # Coerce the body to Unicode and replace any invalid characters. if not isinstance(body, unicode): body = unicode(body, cset, 'replace') - if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS: + if config.ARCHIVER_OBSCURES_EMAILADDRS: otrans = i18n.get_translation() try: atmark = unicode(_(' at '), cset) @@ -778,7 +778,7 @@ class HyperArchive(pipermail.T): # The TOC is always in the charset of the list's preferred language d['meta'] += html_charset % Utils.GetCharSet(mlist.preferred_language) # The site can disable public access to the mbox file. - if mm_cfg.PUBLIC_MBOX: + if config.PUBLIC_MBOX: template = 'archtoc.html' else: template = 'archtocnombox.html' @@ -822,7 +822,7 @@ class HyperArchive(pipermail.T): if self._lock_file: return 1 self._lock_file = LockFile.LockFile( - os.path.join(mm_cfg.LOCK_DIR, + os.path.join(config.LOCK_DIR, self.maillist.fqdn_listname + '-arch.lock')) try: self._lock_file.lock(timeout=0.5) @@ -1035,7 +1035,7 @@ class HyperArchive(pipermail.T): def write_index_entry(self, article): subject = self.get_header("subject", article) author = self.get_header("author", article) - if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS: + if config.ARCHIVER_OBSCURES_EMAILADDRS: try: author = re.sub('@', _(' at '), author) except UnicodeError: @@ -1111,7 +1111,7 @@ class HyperArchive(pipermail.T): def update_archive(self, archive): self.__super_update_archive(archive) # only do this if the gzip module was imported globally, and - # gzip'ing was enabled via mm_cfg.GZIP_ARCHIVE_TXT_FILES. See + # gzip'ing was enabled via config.GZIP_ARCHIVE_TXT_FILES. See # above. if gzip: archz = None @@ -1208,7 +1208,7 @@ class HyperArchive(pipermail.T): if j != -1 and (j < k or k == -1): text = jr.group(1) length = len(text) - if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS: + if config.ARCHIVER_OBSCURES_EMAILADDRS: text = re.sub('@', atmark, text) URL = self.maillist.GetScriptURL( 'listinfo', absolute=1) diff --git a/Mailman/Cgi/admin.py b/Mailman/Cgi/admin.py index 553f26656..cb001317e 100644 --- a/Mailman/Cgi/admin.py +++ b/Mailman/Cgi/admin.py @@ -33,16 +33,15 @@ from Mailman import MailList from Mailman import MemberAdaptor from Mailman import Utils from Mailman import i18n -from Mailman import mm_cfg from Mailman import passwords - from Mailman.Cgi import Auth -from Mailman.htmlformat import * from Mailman.UserDesc import UserDesc +from Mailman.configuration import config +from Mailman.htmlformat import * # Set up i18n _ = i18n._ -i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) +i18n.set_language(config.DEFAULT_SERVER_LANGUAGE) NL = '\n' OPTCOLUMNS = 11 @@ -74,8 +73,8 @@ def main(): # If the user is not authenticated, we're done. cgidata = cgi.FieldStorage(keep_blank_values=1) - if not mlist.WebAuthenticate((mm_cfg.AuthListAdmin, - mm_cfg.AuthSiteAdmin), + if not mlist.WebAuthenticate((config.AuthListAdmin, + config.AuthSiteAdmin), cgidata.getvalue('adminpw', '')): if cgidata.has_key('adminpw'): # This is a re-authorization attempt @@ -98,7 +97,7 @@ def main(): # Is this a log-out request? if category == 'logout': - print mlist.ZapCookie(mm_cfg.AuthListAdmin) + print mlist.ZapCookie(config.AuthListAdmin) Auth.loginpage(mlist, 'admin', frontpage=True) return @@ -173,13 +172,13 @@ def admin_overview(msg=''): legend = _('%(hostname)s mailing lists - Admin Links') # The html `document' doc = Document() - doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) + doc.set_language(config.DEFAULT_SERVER_LANGUAGE) doc.SetTitle(legend) # The table that will hold everything table = Table(border=0, width="100%") table.AddRow([Center(Header(2, legend))]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) # Skip any mailing list that isn't advertised. advertised = [] for name in sorted(config.list_manager.names): @@ -199,7 +198,7 @@ def admin_overview(msg=''): greeting = _("Welcome!") welcome = [] - mailmanlink = Link(mm_cfg.MAILMAN_URL, _('Mailman')).Format() + mailmanlink = Link(config.MAILMAN_URL, _('Mailman')).Format() if not advertised: welcome.extend([ greeting, @@ -245,9 +244,9 @@ def admin_overview(msg=''): table.AddRow( [Link(url, Bold(real_name)), description or Italic(_('[no description available]'))]) - if highlight and mm_cfg.WEB_HIGHLIGHT_COLOR: + if highlight and config.WEB_HIGHLIGHT_COLOR: table.AddRowInfo(table.GetCurrentRowIndex(), - bgcolor=mm_cfg.WEB_HIGHLIGHT_COLOR) + bgcolor=config.WEB_HIGHLIGHT_COLOR) highlight = not highlight doc.AddItem(table) @@ -294,7 +293,7 @@ def option_help(mlist, varhelp): header = Table(width='100%') header.AddRow([Center(Header(3, legend))]) header.AddCellInfo(header.GetCurrentRowIndex(), 0, colspan=2, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) doc.SetTitle(_("Mailman %(varname)s List Option Help")) doc.AddItem(header) doc.AddItem("<b>%s</b> (%s): %s<p>" % (varname, category, description)) @@ -369,7 +368,7 @@ def show_results(mlist, doc, category, subcat, cgidata): otherlinks.AddItem(Link(mlist.GetBaseArchiveURL(), _('Go to list archives')).Format() + '<br> <br>') - if mm_cfg.OWNERS_CAN_DELETE_THEIR_OWN_LISTS: + if config.OWNERS_CAN_DELETE_THEIR_OWN_LISTS: otherlinks.AddItem(Link(mlist.GetScriptURL('rmlist'), _('Delete this mailing list')).Format() + _(' (requires confirmation)<br> <br>')) @@ -425,7 +424,7 @@ def show_results(mlist, doc, category, subcat, cgidata): label = _('Emergency moderation of all list traffic is enabled') etable.AddRow([Center( Link('?VARHELP=general/emergency', Bold(label)))]) - color = mm_cfg.WEB_ERROR_COLOR + color = config.WEB_ERROR_COLOR etable.AddCellInfo(etable.GetCurrentRowIndex(), 0, colspan=2, bgcolor=color) linktable.AddRow([etable, otherlinks]) @@ -453,7 +452,7 @@ def show_results(mlist, doc, category, subcat, cgidata): table = Table(width='100%') table.AddRow([Center(Header(2, _('Additional Member Tasks')))]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) # Add a blank separator row table.AddRow([' ', ' ']) # Add a section to set the moderation bit for all members @@ -489,7 +488,7 @@ def show_variables(mlist, category, subcat, cgidata, doc): table.AddRow([Center(Header(2, label))]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) # The very first item in the config info will be treated as a general # description if it is a string @@ -536,9 +535,9 @@ def add_options_table_item(mlist, category, subcat, table, item, detailsp=1): val = get_item_gui_value(mlist, category, kind, varname, params, extra) table.AddRow([descr, val]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, - bgcolor=mm_cfg.WEB_ADMINITEM_COLOR) + bgcolor=config.WEB_ADMINITEM_COLOR) table.AddCellInfo(table.GetCurrentRowIndex(), 1, - bgcolor=mm_cfg.WEB_ADMINITEM_COLOR) + bgcolor=config.WEB_ADMINITEM_COLOR) @@ -574,7 +573,7 @@ def get_item_gui_value(mlist, category, kind, varname, params, extra): if value is None and not varname.startswith('_'): value = getattr(mlist, varname) # Now create the widget for this value - if kind == mm_cfg.Radio or kind == mm_cfg.Toggle: + if kind == config.Radio or kind == config.Toggle: # If we are returning the option for subscribe policy and this site # doesn't allow open subscribes, then we have to alter the value of # mlist.subscribe_policy as passed to RadioButtonArray in order to @@ -587,29 +586,29 @@ def get_item_gui_value(mlist, category, kind, varname, params, extra): checked = 0 else: checked = value - if varname == 'subscribe_policy' and not mm_cfg.ALLOW_OPEN_SUBSCRIBE: + if varname == 'subscribe_policy' and not config.ALLOW_OPEN_SUBSCRIBE: checked = checked - 1 # For Radio buttons, we're going to interpret the extra stuff as a # horizontal/vertical flag. For backwards compatibility, the value 0 # means horizontal, so we use "not extra" to get the parity right. return RadioButtonArray(varname, params, checked, not extra) - elif (kind == mm_cfg.String or kind == mm_cfg.Email or - kind == mm_cfg.Host or kind == mm_cfg.Number): + elif (kind == config.String or kind == config.Email or + kind == config.Host or kind == config.Number): return TextBox(varname, value, params) - elif kind == mm_cfg.Text: + elif kind == config.Text: if params: r, c = params else: r, c = None, None return TextArea(varname, value or '', r, c) - elif kind in (mm_cfg.EmailList, mm_cfg.EmailListEx): + elif kind in (config.EmailList, config.EmailListEx): if params: r, c = params else: r, c = None, None res = NL.join(value) return TextArea(varname, res, r, c, wrap='off') - elif kind == mm_cfg.FileUpload: + elif kind == config.FileUpload: # like a text area, but also with uploading if params: r, c = params @@ -621,7 +620,7 @@ def get_item_gui_value(mlist, category, kind, varname, params, extra): container.AddItem(_('<br><em>...specify a file to upload</em><br>')) container.AddItem(FileUpload(varname+'_upload', r, c)) return container - elif kind == mm_cfg.Select: + elif kind == config.Select: if params: values, legend, selected = params else: @@ -629,7 +628,7 @@ def get_item_gui_value(mlist, category, kind, varname, params, extra): legend = [Utils.GetLanguageDescr(code) for code in codes] selected = codes.index(mlist.preferred_language) return SelectOptions(varname, values, legend, selected) - elif kind == mm_cfg.Topics: + elif kind == config.Topics: # A complex and specialized widget type that allows for setting of a # topic name, a mark button, a regexp text box, an "add after mark", # and a delete button. Yeesh! params are ignored. @@ -677,7 +676,7 @@ def get_item_gui_value(mlist, category, kind, varname, params, extra): if i == 1: makebox(i, '', '', '', empty=True) return table - elif kind == mm_cfg.HeaderFilter: + elif kind == config.HeaderFilter: # A complex and specialized widget type that allows for setting of a # spam filter rule including, a mark button, a regexp text box, an # "add after mark", up and down buttons, and a delete button. Yeesh! @@ -702,8 +701,8 @@ def get_item_gui_value(mlist, category, kind, varname, params, extra): table.AddRow([Label(_('Spam Filter Regexp:')), TextArea(reboxtag, text=pattern, rows=4, cols=30, wrap='off')]) - values = [mm_cfg.DEFER, mm_cfg.HOLD, mm_cfg.REJECT, - mm_cfg.DISCARD, mm_cfg.ACCEPT] + values = [config.DEFER, config.HOLD, config.REJECT, + config.DISCARD, config.ACCEPT] try: checked = values.index(action) except ValueError: @@ -739,9 +738,9 @@ def get_item_gui_value(mlist, category, kind, varname, params, extra): # Add one more non-deleteable widget as the first blank entry, but # only if there are no real entries. if i == 1: - makebox(i, '', mm_cfg.DEFER, empty=True) + makebox(i, '', config.DEFER, empty=True) return table - elif kind == mm_cfg.Checkbox: + elif kind == config.Checkbox: return CheckBoxArray(varname, *params) else: assert 0, 'Bad gui widget type: %s' % kind @@ -785,21 +784,21 @@ def membership_options(mlist, subcat, cgidata, doc, form): if subcat == 'add': header.AddRow([Center(Header(2, _('Mass Subscriptions')))]) header.AddCellInfo(header.GetCurrentRowIndex(), 0, colspan=2, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) container.AddItem(header) mass_subscribe(mlist, container) return container if subcat == 'remove': header.AddRow([Center(Header(2, _('Mass Removals')))]) header.AddCellInfo(header.GetCurrentRowIndex(), 0, colspan=2, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) container.AddItem(header) mass_remove(mlist, container) return container # Otherwise... header.AddRow([Center(Header(2, _('Membership List')))]) header.AddCellInfo(header.GetCurrentRowIndex(), 0, colspan=2, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) container.AddItem(header) # Add a "search for member" button table = Table(width='100%') @@ -888,7 +887,7 @@ def membership_options(mlist, subcat, cgidata, doc, form): usertable.AddCellInfo(usertable.GetCurrentRowIndex(), usertable.GetCurrentCellIndex(), colspan=OPTCOLUMNS, - bgcolor=mm_cfg.WEB_ADMINITEM_COLOR) + bgcolor=config.WEB_ADMINITEM_COLOR) # Add the alphabetical links if bucket: cells = [] @@ -906,7 +905,7 @@ def membership_options(mlist, subcat, cgidata, doc, form): usertable.AddCellInfo(usertable.GetCurrentRowIndex(), usertable.GetCurrentCellIndex(), colspan=OPTCOLUMNS, - bgcolor=mm_cfg.WEB_ADMINITEM_COLOR) + bgcolor=config.WEB_ADMINITEM_COLOR) usertable.AddRow([Center(h) for h in (_('unsub'), _('member address<br>member name'), _('mod'), _('hide'), @@ -917,7 +916,7 @@ def membership_options(mlist, subcat, cgidata, doc, form): _('language'))]) rowindex = usertable.GetCurrentRowIndex() for i in range(OPTCOLUMNS): - usertable.AddCellInfo(rowindex, i, bgcolor=mm_cfg.WEB_ADMINITEM_COLOR) + usertable.AddCellInfo(rowindex, i, bgcolor=config.WEB_ADMINITEM_COLOR) # Find the longest name in the list longest = 0 if members: @@ -942,7 +941,7 @@ def membership_options(mlist, subcat, cgidata, doc, form): Hidden('user', urllib.quote(addr)).Format(), ] # Do the `mod' option - if mlist.getMemberOption(addr, mm_cfg.Moderate): + if mlist.getMemberOption(addr, config.Moderate): value = 'on' checked = 1 else: @@ -961,7 +960,7 @@ def membership_options(mlist, subcat, cgidata, doc, form): value = 'on' checked = 1 extra = '[%s]' % ds_abbrevs[status] - elif mlist.getMemberOption(addr, mm_cfg.OPTINFO[opt]): + elif mlist.getMemberOption(addr, config.OPTINFO[opt]): value = 'on' checked = 1 else: @@ -977,7 +976,7 @@ def membership_options(mlist, subcat, cgidata, doc, form): cells.append(Center(CheckBox(addr + '_digest', 'off', 0).Format())) else: cells.append(Center(CheckBox(addr + '_digest', 'on', 1).Format())) - if mlist.getMemberOption(addr, mm_cfg.OPTINFO['plain']): + if mlist.getMemberOption(addr, config.OPTINFO['plain']): value = 'on' checked = 1 else: @@ -1079,7 +1078,7 @@ def membership_options(mlist, subcat, cgidata, doc, form): def mass_subscribe(mlist, container): # MASS SUBSCRIBE - GREY = mm_cfg.WEB_ADMINITEM_COLOR + GREY = config.WEB_ADMINITEM_COLOR table = Table(width='90%') table.AddRow([ Label(_('Subscribe these users now or invite them?')), @@ -1129,7 +1128,7 @@ def mass_subscribe(mlist, container): def mass_remove(mlist, container): # MASS UNSUBSCRIBE - GREY = mm_cfg.WEB_ADMINITEM_COLOR + GREY = config.WEB_ADMINITEM_COLOR table = Table(width='90%') table.AddRow([ Label(_('Send unsubscription acknowledgement to the user?')), @@ -1164,7 +1163,7 @@ def password_inputs(mlist): table = Table(cellspacing=3, cellpadding=4) table.AddRow([Center(Header(2, _('Change list ownership passwords')))]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) table.AddRow([_("""\ The <em>list administrators</em> are the people who have ultimate control over all parameters of this mailing list. They are able to change any list @@ -1183,14 +1182,14 @@ and also provide the email addresses of the list moderators in the 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=mm_cfg.WEB_ADMINPW_COLOR) + 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=mm_cfg.WEB_ADMINPW_COLOR) + bgcolor=config.WEB_ADMINPW_COLOR) mtable.AddRow([Label(_('Enter new moderator password:')), PasswordBox('newmodpw', size=20)]) mtable.AddRow([Label(_('Confirm moderator password:')), @@ -1235,7 +1234,7 @@ def change_options(mlist, category, subcat, cgidata, doc): if new == confirm: mlist.password = passwords.make_secret(new, config.PASSWORD_SCHEME) # Set new cookie - print mlist.MakeCookie(mm_cfg.AuthListAdmin) + 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 @@ -1363,7 +1362,7 @@ def change_options(mlist, category, subcat, cgidata, doc): doc.addError(_('Bad moderation flag value')) else: for member in mlist.getMembers(): - mlist.setMemberOption(member, mm_cfg.Moderate, val) + 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'] @@ -1389,7 +1388,7 @@ def change_options(mlist, category, subcat, cgidata, doc): continue value = cgidata.has_key('%s_digest' % user) try: - mlist.setMemberOption(user, mm_cfg.Digests, value) + mlist.setMemberOption(user, config.Digests, value) except (Errors.AlreadyReceivingDigests, Errors.AlreadyReceivingRegularDeliveries, Errors.CantDigestError, @@ -1407,7 +1406,7 @@ def change_options(mlist, category, subcat, cgidata, doc): mlist.setMemberLanguage(user, newlang) moderate = not not cgidata.getvalue(user+'_mod') - mlist.setMemberOption(user, mm_cfg.Moderate, moderate) + 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). @@ -1417,7 +1416,7 @@ def change_options(mlist, category, subcat, cgidata, doc): else: mlist.setDeliveryStatus(user, MemberAdaptor.ENABLED) for opt in ('hide', 'ack', 'notmetoo', 'nodupes', 'plain'): - opt_code = mm_cfg.OPTINFO[opt] + opt_code = config.OPTINFO[opt] if cgidata.has_key('%s_%s' % (user, opt)): mlist.setMemberOption(user, opt_code, 1) else: diff --git a/Mailman/Cgi/listinfo.py b/Mailman/Cgi/listinfo.py index 13689b767..72ef6bfa9 100644 --- a/Mailman/Cgi/listinfo.py +++ b/Mailman/Cgi/listinfo.py @@ -24,15 +24,15 @@ import cgi import logging from Mailman import Errors -from Mailman import i18n from Mailman import MailList -from Mailman import mm_cfg from Mailman import Utils +from Mailman import i18n +from Mailman.configuration import config from Mailman.htmlformat import * # Set up i18n _ = i18n._ -i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) +i18n.set_language(config.DEFAULT_SERVER_LANGUAGE) log = logging.getLogger('mailman.error') @@ -70,7 +70,7 @@ def listinfo_overview(msg=''): # Set up the document and assign it the correct language. The only one we # know about at the moment is the server's default. doc = Document() - doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) + doc.set_language(config.DEFAULT_SERVER_LANGUAGE) legend = _("%(hostname)s Mailing Lists") doc.SetTitle(legend) @@ -78,7 +78,7 @@ def listinfo_overview(msg=''): table = Table(border=0, width="100%") table.AddRow([Center(Header(2, legend))]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) # Skip any mailing lists that isn't advertised. advertised = [] @@ -98,7 +98,7 @@ def listinfo_overview(msg=''): greeting = FontAttr(_('Welcome!'), size='+2') welcome = [greeting] - mailmanlink = Link(mm_cfg.MAILMAN_URL, _('Mailman')).Format() + mailmanlink = Link(config.MAILMAN_URL, _('Mailman')).Format() if not advertised: welcome.extend( _('''<p>There currently are no publicly-advertised @@ -138,9 +138,9 @@ def listinfo_overview(msg=''): table.AddRow( [Link(url, Bold(real_name)), description or Italic(_('[no description available]'))]) - if highlight and mm_cfg.WEB_HIGHLIGHT_COLOR: + if highlight and config.WEB_HIGHLIGHT_COLOR: table.AddRowInfo(table.GetCurrentRowIndex(), - bgcolor=mm_cfg.WEB_HIGHLIGHT_COLOR) + bgcolor=config.WEB_HIGHLIGHT_COLOR) highlight = not highlight doc.AddItem(table) diff --git a/Mailman/Cgi/options.py b/Mailman/Cgi/options.py index 29f05cf7b..e7e7264a1 100644 --- a/Mailman/Cgi/options.py +++ b/Mailman/Cgi/options.py @@ -28,8 +28,8 @@ from Mailman import MailList from Mailman import MemberAdaptor from Mailman import Utils from Mailman import i18n -from Mailman import mm_cfg from Mailman import passwords +from Mailman.configuration import config from Mailman.htmlformat import * @@ -39,7 +39,7 @@ SETLANGUAGE = -1 # Set up i18n _ = i18n._ -i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) +i18n.set_language(config.DEFAULT_SERVER_LANGUAGE) log = logging.getLogger('mailman.error') mlog = logging.getLogger('mailman.mischief') @@ -48,7 +48,7 @@ mlog = logging.getLogger('mailman.mischief') def main(): doc = Document() - doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) + doc.set_language(config.DEFAULT_SERVER_LANGUAGE) parts = Utils.GetPathPieces() lenparts = parts and len(parts) @@ -222,18 +222,18 @@ def main(): # or the site admin, because they are the only ones who are allowed to # change things globally. Specifically, the list admin may not change # values globally. - if mm_cfg.ALLOW_SITE_ADMIN_COOKIES: - user_or_siteadmin_context = (mm_cfg.AuthUser, mm_cfg.AuthSiteAdmin) + if config.ALLOW_SITE_ADMIN_COOKIES: + user_or_siteadmin_context = (config.AuthUser, config.AuthSiteAdmin) else: # Site and list admins are treated equal so that list admin can pass # site admin test. :-( - user_or_siteadmin_context = (mm_cfg.AuthUser,) + user_or_siteadmin_context = (config.AuthUser,) is_user_or_siteadmin = mlist.WebAuthenticate( user_or_siteadmin_context, password, user) # Authenticate, possibly using the password supplied in the login page if not is_user_or_siteadmin and \ - not mlist.WebAuthenticate((mm_cfg.AuthListAdmin, - mm_cfg.AuthSiteAdmin), + not mlist.WebAuthenticate((config.AuthListAdmin, + config.AuthSiteAdmin), password, user): # Not authenticated, so throw up the login page again. If they tried # to authenticate via cgi (instead of cookie), then print an error @@ -254,7 +254,7 @@ def main(): # locked. if cgidata.has_key('logout'): - print mlist.ZapCookie(mm_cfg.AuthUser, user) + print mlist.ZapCookie(config.AuthUser, user) loginpage(mlist, doc, user, language) print doc.Format() return @@ -440,7 +440,7 @@ address. Upon confirmation, any other mailing list containing the address change_password(gmlist, user, pw) # Regenerate the cookie so a re-authorization isn't necessary - print mlist.MakeCookie(mm_cfg.AuthUser, user) + print mlist.MakeCookie(config.AuthUser, user) options_page(mlist, doc, user, cpuser, userlang, _('Password successfully changed.')) print doc.Format() @@ -501,15 +501,15 @@ address. Upon confirmation, any other mailing list containing the address newvals = [] # First figure out which options have changed. The item names come # from FormatOptionButton() in HTMLFormatter.py - for item, flag in (('digest', mm_cfg.Digests), - ('mime', mm_cfg.DisableMime), - ('dontreceive', mm_cfg.DontReceiveOwnPosts), - ('ackposts', mm_cfg.AcknowledgePosts), - ('disablemail', mm_cfg.DisableDelivery), - ('conceal', mm_cfg.ConcealSubscription), - ('remind', mm_cfg.SuppressPasswordReminder), - ('rcvtopic', mm_cfg.ReceiveNonmatchingTopics), - ('nodupes', mm_cfg.DontReceiveDuplicates), + for item, flag in (('digest', config.Digests), + ('mime', config.DisableMime), + ('dontreceive', config.DontReceiveOwnPosts), + ('ackposts', config.AcknowledgePosts), + ('disablemail', config.DisableDelivery), + ('conceal', config.ConcealSubscription), + ('remind', config.SuppressPasswordReminder), + ('rcvtopic', config.ReceiveNonmatchingTopics), + ('nodupes', config.DontReceiveDuplicates), ): try: newval = int(cgidata.getvalue(item)) @@ -521,7 +521,7 @@ address. Upon confirmation, any other mailing list containing the address # flags. if newval is None: continue - elif flag == mm_cfg.DisableDelivery: + elif flag == config.DisableDelivery: status = mlist.getDeliveryStatus(user) # Here, newval == 0 means enable, newval == 1 means disable if not newval and status <> MemberAdaptor.ENABLED: @@ -533,7 +533,7 @@ address. Upon confirmation, any other mailing list containing the address elif newval == mlist.getMemberOption(user, flag): continue # Should we warn about one more digest? - if flag == mm_cfg.Digests and \ + if flag == config.Digests and \ newval == 0 and mlist.getMemberOption(user, flag): digestwarn = 1 @@ -573,7 +573,7 @@ address. Upon confirmation, any other mailing list containing the address if flag == SETLANGUAGE: mlist.setMemberLanguage(user, newval) # Handle delivery status separately - elif flag == mm_cfg.DisableDelivery: + elif flag == config.DisableDelivery: mlist.setDeliveryStatus(user, newval) else: try: @@ -605,25 +605,25 @@ address. Upon confirmation, any other mailing list containing the address # Yes, this is inefficient, but the list is so small it shouldn't # make much of a difference. for flag, newval in newvals: - if flag == mm_cfg.DisableDelivery: + if flag == config.DisableDelivery: globalopts.enable = newval break if cgidata.getvalue('remind-globally'): for flag, newval in newvals: - if flag == mm_cfg.SuppressPasswordReminder: + if flag == config.SuppressPasswordReminder: globalopts.remind = newval break if cgidata.getvalue('nodupes-globally'): for flag, newval in newvals: - if flag == mm_cfg.DontReceiveDuplicates: + if flag == config.DontReceiveDuplicates: globalopts.nodupes = newval break if cgidata.getvalue('mime-globally'): for flag, newval in newvals: - if flag == mm_cfg.DisableMime: + if flag == config.DisableMime: globalopts.mime = newval break @@ -687,40 +687,40 @@ def options_page(mlist, doc, user, cpuser, userlang, message=''): replacements = mlist.GetStandardReplacements(userlang) replacements['<mm-results>'] = Bold(FontSize('+1', message)).Format() replacements['<mm-digest-radio-button>'] = mlist.FormatOptionButton( - mm_cfg.Digests, 1, user) + config.Digests, 1, user) replacements['<mm-undigest-radio-button>'] = mlist.FormatOptionButton( - mm_cfg.Digests, 0, user) + config.Digests, 0, user) replacements['<mm-plain-digests-button>'] = mlist.FormatOptionButton( - mm_cfg.DisableMime, 1, user) + config.DisableMime, 1, user) replacements['<mm-mime-digests-button>'] = mlist.FormatOptionButton( - mm_cfg.DisableMime, 0, user) + config.DisableMime, 0, user) replacements['<mm-global-mime-button>'] = ( CheckBox('mime-globally', 1, checked=0).Format()) replacements['<mm-delivery-enable-button>'] = mlist.FormatOptionButton( - mm_cfg.DisableDelivery, 0, user) + config.DisableDelivery, 0, user) replacements['<mm-delivery-disable-button>'] = mlist.FormatOptionButton( - mm_cfg.DisableDelivery, 1, user) + config.DisableDelivery, 1, user) replacements['<mm-disabled-notice>'] = mlist.FormatDisabledNotice(user) replacements['<mm-dont-ack-posts-button>'] = mlist.FormatOptionButton( - mm_cfg.AcknowledgePosts, 0, user) + config.AcknowledgePosts, 0, user) replacements['<mm-ack-posts-button>'] = mlist.FormatOptionButton( - mm_cfg.AcknowledgePosts, 1, user) + config.AcknowledgePosts, 1, user) replacements['<mm-receive-own-mail-button>'] = mlist.FormatOptionButton( - mm_cfg.DontReceiveOwnPosts, 0, user) + config.DontReceiveOwnPosts, 0, user) replacements['<mm-dont-receive-own-mail-button>'] = ( - mlist.FormatOptionButton(mm_cfg.DontReceiveOwnPosts, 1, user)) + mlist.FormatOptionButton(config.DontReceiveOwnPosts, 1, user)) replacements['<mm-dont-get-password-reminder-button>'] = ( - mlist.FormatOptionButton(mm_cfg.SuppressPasswordReminder, 1, user)) + mlist.FormatOptionButton(config.SuppressPasswordReminder, 1, user)) replacements['<mm-get-password-reminder-button>'] = ( - mlist.FormatOptionButton(mm_cfg.SuppressPasswordReminder, 0, user)) + mlist.FormatOptionButton(config.SuppressPasswordReminder, 0, user)) replacements['<mm-public-subscription-button>'] = ( - mlist.FormatOptionButton(mm_cfg.ConcealSubscription, 0, user)) + mlist.FormatOptionButton(config.ConcealSubscription, 0, user)) replacements['<mm-hide-subscription-button>'] = mlist.FormatOptionButton( - mm_cfg.ConcealSubscription, 1, user) + config.ConcealSubscription, 1, user) replacements['<mm-dont-receive-duplicates-button>'] = ( - mlist.FormatOptionButton(mm_cfg.DontReceiveDuplicates, 1, user)) + mlist.FormatOptionButton(config.DontReceiveDuplicates, 1, user)) replacements['<mm-receive-duplicates-button>'] = ( - mlist.FormatOptionButton(mm_cfg.DontReceiveDuplicates, 0, user)) + mlist.FormatOptionButton(config.DontReceiveDuplicates, 0, user)) replacements['<mm-unsubscribe-button>'] = ( mlist.FormatButton('unsub', _('Unsubscribe')) + '<br>' + CheckBox('unsubconfirm', 1, checked=0).Format() + @@ -753,7 +753,7 @@ def options_page(mlist, doc, user, cpuser, userlang, message=''): replacements['<mm-global-nodupes-button>'] = ( CheckBox('nodupes-globally', 1, checked=0).Format()) - days = int(mm_cfg.PENDING_REQUEST_LIFE / mm_cfg.days(1)) + days = int(config.PENDING_REQUEST_LIFE / config.days(1)) if days > 1: units = _('days') else: @@ -793,9 +793,9 @@ def options_page(mlist, doc, user, cpuser, userlang, message=''): topicsfield = _('<em>No topics defined</em>') replacements['<mm-topics>'] = topicsfield replacements['<mm-suppress-nonmatching-topics>'] = ( - mlist.FormatOptionButton(mm_cfg.ReceiveNonmatchingTopics, 0, user)) + mlist.FormatOptionButton(config.ReceiveNonmatchingTopics, 0, user)) replacements['<mm-receive-nonmatching-topics>'] = ( - mlist.FormatOptionButton(mm_cfg.ReceiveNonmatchingTopics, 1, user)) + mlist.FormatOptionButton(config.ReceiveNonmatchingTopics, 1, user)) if cpuser is not None: replacements['<mm-case-preserved-user>'] = _(''' @@ -827,7 +827,7 @@ def loginpage(mlist, doc, user, lang): # buttons. table.AddRow([Center(Header(2, title))]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) if len(mlist.language_codes) > 1: langform = Form(actionurl) langform.AddItem(SubmitButton('displang-button', @@ -867,7 +867,7 @@ def loginpage(mlist, doc, user, lang): # Unsubscribe section table.AddRow([Center(Header(2, _('Unsubscribe')))]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) table.AddRow([_("""By clicking on the <em>Unsubscribe</em> button, a confirmation message will be emailed to you. This message will have a @@ -879,7 +879,7 @@ def loginpage(mlist, doc, user, lang): # Password reminder section table.AddRow([Center(Header(2, _('Password reminder')))]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) table.AddRow([_("""By clicking on the <em>Remind</em> button, your password will be emailed to you.""")]) @@ -948,15 +948,15 @@ def global_options(mlist, user, globalopts): mlist.setDeliveryStatus(user, globalopts.enable) if globalopts.remind is not None: - mlist.setMemberOption(user, mm_cfg.SuppressPasswordReminder, + mlist.setMemberOption(user, config.SuppressPasswordReminder, globalopts.remind) if globalopts.nodupes is not None: - mlist.setMemberOption(user, mm_cfg.DontReceiveDuplicates, + mlist.setMemberOption(user, config.DontReceiveDuplicates, globalopts.nodupes) if globalopts.mime is not None: - mlist.setMemberOption(user, mm_cfg.DisableMime, globalopts.mime) + mlist.setMemberOption(user, config.DisableMime, globalopts.mime) mlist.Save() finally: @@ -986,7 +986,7 @@ def topic_details(mlist, doc, user, cpuser, userlang, varhelp): table = Table(border=3, width='100%') table.AddRow([Center(Bold(_('Topic filter details')))]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2, - bgcolor=mm_cfg.WEB_SUBHEADER_COLOR) + bgcolor=config.WEB_SUBHEADER_COLOR) table.AddRow([Bold(Label(_('Name:'))), Utils.websafe(name)]) table.AddRow([Bold(Label(_('Pattern (as regexp):'))), @@ -996,7 +996,7 @@ def topic_details(mlist, doc, user, cpuser, userlang, varhelp): Utils.websafe(description)]) # Make colors look nice for row in range(1, 4): - table.AddCellInfo(row, 0, bgcolor=mm_cfg.WEB_ADMINITEM_COLOR) + table.AddCellInfo(row, 0, bgcolor=config.WEB_ADMINITEM_COLOR) options_page(mlist, doc, user, cpuser, userlang, table.Format()) print doc.Format() diff --git a/Mailman/Cgi/rmlist.py b/Mailman/Cgi/rmlist.py index e7dfaa386..080d3b492 100644 --- a/Mailman/Cgi/rmlist.py +++ b/Mailman/Cgi/rmlist.py @@ -25,15 +25,15 @@ import shutil import logging from Mailman import Errors -from Mailman import i18n from Mailman import MailList -from Mailman import mm_cfg from Mailman import Utils +from Mailman import i18n +from Mailman.configuration import config from Mailman.htmlformat import * # Set up i18n _ = i18n._ -i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) +i18n.set_language(config.DEFAULT_SERVER_LANGUAGE) log = logging.getLogger('mailman.error') mlog = logging.getLogger('mailman.mischief') @@ -42,7 +42,7 @@ mlog = logging.getLogger('mailman.mischief') def main(): doc = Document() - doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) + doc.set_language(config.DEFAULT_SERVER_LANGUAGE) cgidata = cgi.FieldStorage() parts = Utils.GetPathPieces() @@ -81,7 +81,7 @@ def main(): doc.set_language(mlist.preferred_language) # Be sure the list owners are not sneaking around! - if not mm_cfg.OWNERS_CAN_DELETE_THEIR_OWN_LISTS: + if not config.OWNERS_CAN_DELETE_THEIR_OWN_LISTS: title = _("You're being a sneaky list owner!") doc.SetTitle(title) doc.AddItem( @@ -114,18 +114,18 @@ def process_request(doc, cgidata, mlist): # the list-admin, or the site-admin. Don't use WebAuthenticate here # because we want to be sure the actual typed password is valid, not some # password sitting in a cookie. - if mlist.Authenticate((mm_cfg.AuthCreator, - mm_cfg.AuthListAdmin, - mm_cfg.AuthSiteAdmin), - password) == mm_cfg.UnAuthorized: + if mlist.Authenticate((config.AuthCreator, + config.AuthListAdmin, + config.AuthSiteAdmin), + password) == config.UnAuthorized: request_deletion( doc, mlist, _('You are not authorized to delete this mailing list')) return # Do the MTA-specific list deletion tasks - if mm_cfg.MTA: - modname = 'Mailman.MTA.' + mm_cfg.MTA + if config.MTA: + modname = 'Mailman.MTA.' + config.MTA __import__(modname) sys.modules[modname].remove(mlist, cgi=1) @@ -141,7 +141,7 @@ def process_request(doc, cgidata, mlist): problems = 0 listname = mlist.internal_name() for dirtmpl in REMOVABLES: - dir = os.path.join(mm_cfg.VAR_PREFIX, dirtmpl % listname) + dir = os.path.join(config.VAR_PREFIX, dirtmpl % listname) if os.path.islink(dir): try: os.unlink(dir) @@ -163,7 +163,7 @@ def process_request(doc, cgidata, mlist): table = Table(border=0, width='100%') table.AddRow([Center(Bold(FontAttr(title, size='+1')))]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) if not problems: table.AddRow([_('''You have successfully deleted the mailing list <b>%(listname)s</b>.''')]) @@ -192,7 +192,7 @@ def request_deletion(doc, mlist, errmsg=None): table = Table(border=0, width='100%') table.AddRow([Center(Bold(FontAttr(title, size='+1')))]) table.AddCellInfo(table.GetCurrentRowIndex(), 0, - bgcolor=mm_cfg.WEB_HEADER_COLOR) + bgcolor=config.WEB_HEADER_COLOR) # Add any error message if errmsg: @@ -216,7 +216,7 @@ def request_deletion(doc, mlist, errmsg=None): <p>For your safety, you will be asked to reconfirm the list password. """)]) - GREY = mm_cfg.WEB_ADMINITEM_COLOR + GREY = config.WEB_ADMINITEM_COLOR form = Form(mlist.GetScriptURL('rmlist')) ftable = Table(border=0, cols='2', width='100%', cellspacing=3, cellpadding=4) diff --git a/Mailman/Cgi/roster.py b/Mailman/Cgi/roster.py index 41febbab0..fdeb83d31 100644 --- a/Mailman/Cgi/roster.py +++ b/Mailman/Cgi/roster.py @@ -30,15 +30,15 @@ import urllib import logging from Mailman import Errors -from Mailman import i18n from Mailman import MailList -from Mailman import mm_cfg from Mailman import Utils +from Mailman import i18n +from Mailman.configuration import config from Mailman.htmlformat import * # Set up i18n _ = i18n._ -i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) +i18n.set_language(config.DEFAULT_SERVER_LANGUAGE) log = logging.getLogger('mailman.error') @@ -80,17 +80,17 @@ def main(): # Members only addr = cgidata.getvalue('roster-email', '') password = cgidata.getvalue('roster-pw', '') - ok = mlist.WebAuthenticate((mm_cfg.AuthUser, - mm_cfg.AuthListModerator, - mm_cfg.AuthListAdmin, - mm_cfg.AuthSiteAdmin), + ok = mlist.WebAuthenticate((config.AuthUser, + config.AuthListModerator, + config.AuthListAdmin, + config.AuthSiteAdmin), password, addr) else: # Admin only, so we can ignore the address field password = cgidata.getvalue('roster-pw', '') - ok = mlist.WebAuthenticate((mm_cfg.AuthListModerator, - mm_cfg.AuthListAdmin, - mm_cfg.AuthSiteAdmin), + ok = mlist.WebAuthenticate((config.AuthListModerator, + config.AuthListAdmin, + config.AuthSiteAdmin), password) if not ok: realname = mlist.real_name @@ -117,7 +117,7 @@ def main(): def error_page(errmsg): doc = Document() - doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) + doc.set_language(config.DEFAULT_SERVER_LANGUAGE) error_page_doc(doc, errmsg) print doc.Format() diff --git a/Mailman/Cgi/subscribe.py b/Mailman/Cgi/subscribe.py index 489a26e16..3d66cac42 100644 --- a/Mailman/Cgi/subscribe.py +++ b/Mailman/Cgi/subscribe.py @@ -23,20 +23,20 @@ import sys import logging from Mailman import Errors -from Mailman import i18n from Mailman import MailList from Mailman import Message -from Mailman import mm_cfg from Mailman import Utils -from Mailman.htmlformat import * +from Mailman import i18n from Mailman.UserDesc import UserDesc +from Mailman.configuration import config +from Mailman.htmlformat import * SLASH = '/' ERRORSEP = '\n\n<p>' # Set up i18n _ = i18n._ -i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) +i18n.set_language(config.DEFAULT_SERVER_LANGUAGE) log = logging.getLogger('mailman.error') mlog = logging.getLogger('mailman.mischief') @@ -45,7 +45,7 @@ mlog = logging.getLogger('mailman.mischief') def main(): doc = Document() - doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) + doc.set_language(config.DEFAULT_SERVER_LANGUAGE) parts = Utils.GetPathPieces() if not parts: diff --git a/Mailman/Commands/cmd_confirm.py b/Mailman/Commands/cmd_confirm.py index 99d1fab39..49aa85267 100644 --- a/Mailman/Commands/cmd_confirm.py +++ b/Mailman/Commands/cmd_confirm.py @@ -21,9 +21,9 @@ supplied by a mailback confirmation notice. """ -from Mailman import mm_cfg from Mailman import Errors from Mailman import Pending +from Mailman.configuration import config from Mailman.i18n import _ STOP = 1 @@ -46,7 +46,7 @@ def process(res, args): results = mlist.ProcessConfirmation(cookie, res.msg) except Errors.MMBadConfirmation, e: # Express in approximate days - days = int(mm_cfg.PENDING_REQUEST_LIFE / mm_cfg.days(1) + 0.5) + days = int(config.PENDING_REQUEST_LIFE / config.days(1) + 0.5) res.results.append(_("""\ Invalid confirmation string. Note that confirmation strings expire approximately %(days)s days after the initial subscription request. If your diff --git a/Mailman/Commands/cmd_help.py b/Mailman/Commands/cmd_help.py index 33e908295..1afe25697 100644 --- a/Mailman/Commands/cmd_help.py +++ b/Mailman/Commands/cmd_help.py @@ -19,11 +19,11 @@ Print this help message. """ -import sys import os +import sys -from Mailman import mm_cfg from Mailman import Utils +from Mailman.configuration import config from Mailman.i18n import _ EMPTYSTRING = '' @@ -81,7 +81,7 @@ def process(res, args): helptext = Utils.maketext( 'help.txt', {'listname' : mlist.real_name, - 'version' : mm_cfg.VERSION, + 'version' : config.VERSION, 'listinfo_url': mlist.GetScriptURL('listinfo', absolute=1), 'requestaddr' : mlist.GetRequestEmail(), 'adminaddr' : mlist.GetOwnerEmail(), diff --git a/Mailman/Commands/cmd_lists.py b/Mailman/Commands/cmd_lists.py index 6d23d4745..f7c6365e3 100644 --- a/Mailman/Commands/cmd_lists.py +++ b/Mailman/Commands/cmd_lists.py @@ -20,7 +20,6 @@ See a list of the public mailing lists on this GNU Mailman server. """ -from Mailman import mm_cfg from Mailman.MailList import MailList from Mailman.configuration import config from Mailman.i18n import _ diff --git a/Mailman/Commands/cmd_password.py b/Mailman/Commands/cmd_password.py index 278dad3c0..ff9ae8762 100644 --- a/Mailman/Commands/cmd_password.py +++ b/Mailman/Commands/cmd_password.py @@ -28,7 +28,7 @@ from email.Utils import parseaddr -from Mailman import mm_cfg +from Mailman.configuration import config from Mailman.i18n import _ STOP = 1 @@ -77,7 +77,7 @@ def process(res, args): newpasswd = args[1] realname, address = parseaddr(res.msg['from']) if mlist.isMember(address): - if mlist.Authenticate((mm_cfg.AuthUser, mm_cfg.AuthListAdmin), + if mlist.Authenticate((config.AuthUser, config.AuthListAdmin), oldpasswd, address): mlist.setMemberPassword(address, newpasswd) res.results.append(_('Password successfully changed.')) @@ -103,7 +103,7 @@ current password, then try again.""")) address = args[2][8:] res.returnaddr = address if mlist.isMember(address): - if mlist.Authenticate((mm_cfg.AuthUser, mm_cfg.AuthListAdmin), + if mlist.Authenticate((config.AuthUser, config.AuthListAdmin), oldpasswd, address): mlist.setMemberPassword(address, newpasswd) res.results.append(_('Password successfully changed.')) diff --git a/Mailman/Commands/cmd_set.py b/Mailman/Commands/cmd_set.py index 549628a76..dc53be243 100644 --- a/Mailman/Commands/cmd_set.py +++ b/Mailman/Commands/cmd_set.py @@ -12,14 +12,15 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. from email.Utils import parseaddr, formatdate -from Mailman import mm_cfg from Mailman import Errors from Mailman import MemberAdaptor from Mailman import i18n +from Mailman.configuration import config def _(s): return s @@ -149,13 +150,13 @@ class SetCommands: _('You are not a member of the %(listname)s mailing list')) return STOP res.results.append(_('Your current option settings:')) - opt = mlist.getMemberOption(address, mm_cfg.AcknowledgePosts) + opt = mlist.getMemberOption(address, config.AcknowledgePosts) onoff = opt and _('on') or _('off') res.results.append(_(' ack %(onoff)s')) # Digests are a special ternary value - digestsp = mlist.getMemberOption(address, mm_cfg.Digests) + digestsp = mlist.getMemberOption(address, config.Digests) if digestsp: - plainp = mlist.getMemberOption(address, mm_cfg.DisableMime) + plainp = mlist.getMemberOption(address, config.DisableMime) if plainp: res.results.append(_(' digest plain')) else: @@ -186,18 +187,18 @@ class SetCommands: res.results.append(_(' %(status)s (%(how)s on %(date)s)')) else: res.results.append(' ' + status) - opt = mlist.getMemberOption(address, mm_cfg.DontReceiveOwnPosts) + opt = mlist.getMemberOption(address, config.DontReceiveOwnPosts) # sense is reversed onoff = (not opt) and _('on') or _('off') res.results.append(_(' myposts %(onoff)s')) - opt = mlist.getMemberOption(address, mm_cfg.ConcealSubscription) + opt = mlist.getMemberOption(address, config.ConcealSubscription) onoff = opt and _('on') or _('off') res.results.append(_(' hide %(onoff)s')) - opt = mlist.getMemberOption(address, mm_cfg.DontReceiveDuplicates) + opt = mlist.getMemberOption(address, config.DontReceiveDuplicates) # sense is reversed onoff = (not opt) and _('on') or _('off') res.results.append(_(' duplicates %(onoff)s')) - opt = mlist.getMemberOption(address, mm_cfg.SuppressPasswordReminder) + opt = mlist.getMemberOption(address, config.SuppressPasswordReminder) # sense is reversed onoff = (not opt) and _('on') or _('off') res.results.append(_(' reminders %(onoff)s')) @@ -218,8 +219,8 @@ class SetCommands: res.results.append( _('You are not a member of the %(listname)s mailing list')) return STOP - if not mlist.Authenticate((mm_cfg.AuthUser, - mm_cfg.AuthListAdmin), + if not mlist.Authenticate((config.AuthUser, + config.AuthListAdmin), password, address): res.results.append(_('You did not give the correct password')) return STOP @@ -250,7 +251,7 @@ class SetCommands: status = self._status(res, args[0]) if status < 0: return STOP - mlist.setMemberOption(self.__address, mm_cfg.AcknowledgePosts, status) + mlist.setMemberOption(self.__address, config.AcknowledgePosts, status) res.results.append(_('ack option set')) def set_digest(self, res, args): @@ -264,21 +265,21 @@ class SetCommands: arg = args[0].lower() if arg == 'off': try: - mlist.setMemberOption(self.__address, mm_cfg.Digests, 0) + mlist.setMemberOption(self.__address, config.Digests, 0) except Errors.AlreadyReceivingRegularDeliveries: pass elif arg == 'plain': try: - mlist.setMemberOption(self.__address, mm_cfg.Digests, 1) + mlist.setMemberOption(self.__address, config.Digests, 1) except Errors.AlreadyReceivingDigests: pass - mlist.setMemberOption(self.__address, mm_cfg.DisableMime, 1) + mlist.setMemberOption(self.__address, config.DisableMime, 1) elif arg == 'mime': try: - mlist.setMemberOption(self.__address, mm_cfg.Digests, 1) + mlist.setMemberOption(self.__address, config.Digests, 1) except Errors.AlreadyReceivingDigests: pass - mlist.setMemberOption(self.__address, mm_cfg.DisableMime, 0) + mlist.setMemberOption(self.__address, config.DisableMime, 0) else: res.results.append(_('Bad argument: %(arg)s')) self._usage(res) @@ -311,7 +312,7 @@ class SetCommands: if status < 0: return STOP # sense is reversed - mlist.setMemberOption(self.__address, mm_cfg.DontReceiveOwnPosts, + mlist.setMemberOption(self.__address, config.DontReceiveOwnPosts, not status) res.results.append(_('myposts option set')) @@ -322,7 +323,7 @@ class SetCommands: status = self._status(res, args[0]) if status < 0: return STOP - mlist.setMemberOption(self.__address, mm_cfg.ConcealSubscription, + mlist.setMemberOption(self.__address, config.ConcealSubscription, status) res.results.append(_('hide option set')) @@ -334,7 +335,7 @@ class SetCommands: if status < 0: return STOP # sense is reversed - mlist.setMemberOption(self.__address, mm_cfg.DontReceiveDuplicates, + mlist.setMemberOption(self.__address, config.DontReceiveDuplicates, not status) res.results.append(_('duplicates option set')) @@ -346,7 +347,7 @@ class SetCommands: if status < 0: return STOP # sense is reversed - mlist.setMemberOption(self.__address, mm_cfg.SuppressPasswordReminder, + mlist.setMemberOption(self.__address, config.SuppressPasswordReminder, not status) res.results.append(_('reminder option set')) diff --git a/Mailman/Commands/cmd_who.py b/Mailman/Commands/cmd_who.py index 8470ef9d6..ecd1786d8 100644 --- a/Mailman/Commands/cmd_who.py +++ b/Mailman/Commands/cmd_who.py @@ -17,8 +17,8 @@ from email.Utils import parseaddr -from Mailman import mm_cfg from Mailman import i18n +from Mailman.configuration import config STOP = 1 @@ -79,8 +79,8 @@ def process(res, args): # Public rosters if args: if len(args) == 1: - if mlist.Authenticate((mm_cfg.AuthListModerator, - mm_cfg.AuthListAdmin), + if mlist.Authenticate((config.AuthListModerator, + config.AuthListAdmin), args[0]): full = True else: @@ -102,15 +102,15 @@ def process(res, args): usage(res) return STOP if mlist.isMember(address) and mlist.Authenticate( - (mm_cfg.AuthUser, - mm_cfg.AuthListModerator, - mm_cfg.AuthListAdmin), + (config.AuthUser, + config.AuthListModerator, + config.AuthListAdmin), password, address): # Then ok = True if mlist.Authenticate( - (mm_cfg.AuthListModerator, - mm_cfg.AuthListAdmin), + (config.AuthListModerator, + config.AuthListAdmin), password): # Then ok = full = True @@ -119,8 +119,8 @@ def process(res, args): if len(args) <> 1: usage(res) return STOP - if mlist.Authenticate((mm_cfg.AuthListModerator, - mm_cfg.AuthListAdmin), + if mlist.Authenticate((config.AuthListModerator, + config.AuthListAdmin), args[0]): ok = full = True if not ok: @@ -137,7 +137,7 @@ def process(res, args): def addmembers(members): for member in members: if not full and mlist.getMemberOption(member, - mm_cfg.ConcealSubscription): + config.ConcealSubscription): continue realname = mlist.getMemberName(member) if realname: diff --git a/Mailman/Deliverer.py b/Mailman/Deliverer.py index 5682a4a22..e4ff15a58 100644 --- a/Mailman/Deliverer.py +++ b/Mailman/Deliverer.py @@ -23,12 +23,12 @@ import logging from email.MIMEMessage import MIMEMessage from email.MIMEText import MIMEText -from Mailman import i18n from Mailman import Errors from Mailman import Message -from Mailman import mm_cfg from Mailman import Pending from Mailman import Utils +from Mailman import i18n +from Mailman.configuration import config _ = i18n._ @@ -75,7 +75,7 @@ your membership administrative address, %(addr)s.''')) _('Welcome to the "%(realname)s" mailing list%(digmode)s'), text, pluser) msg['X-No-Archive'] = 'yes' - msg.send(self, verp=mm_cfg.VERP_PERSONALIZED_DELIVERIES) + msg.send(self, verp=config.VERP_PERSONALIZED_DELIVERIES) def SendUnsubscribeAck(self, addr, lang): realname = self.real_name @@ -83,7 +83,7 @@ your membership administrative address, %(addr)s.''')) self.GetMemberAdminEmail(addr), self.GetBouncesEmail(), _('You have been unsubscribed from the %(realname)s mailing list'), Utils.wrap(self.goodbye_msg), lang) - msg.send(self, verp=mm_cfg.VERP_PERSONALIZED_DELIVERIES) + msg.send(self, verp=config.VERP_PERSONALIZED_DELIVERIES) def MailUserPassword(self, user): listfullname = self.fqdn_listname @@ -131,7 +131,7 @@ your membership administrative address, %(addr)s.''')) msg = Message.UserNotification(recipient, adminaddr, subject, text, lang) msg['X-No-Archive'] = 'yes' - msg.send(self, verp=mm_cfg.VERP_PERSONALIZED_DELIVERIES) + msg.send(self, verp=config.VERP_PERSONALIZED_DELIVERIES) def ForwardMessage(self, msg, text=None, subject=None, tomoderators=True): # Wrap the message as an attachment @@ -206,7 +206,7 @@ is required."""))) 'bounces': self.internal_name() + '-bounces', 'token': token, } - probeaddr = '%s@%s' % ((mm_cfg.VERP_PROBE_FORMAT % probedict), + probeaddr = '%s@%s' % ((config.VERP_PROBE_FORMAT % probedict), self.host_name) # Calculate the Subject header, in the member's preferred language ulang = self.getMemberLanguage(member) diff --git a/Mailman/Gui/Archive.py b/Mailman/Gui/Archive.py index 19ab7916b..6d90484ae 100644 --- a/Mailman/Gui/Archive.py +++ b/Mailman/Gui/Archive.py @@ -15,9 +15,9 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. -from Mailman import mm_cfg -from Mailman.i18n import _ from Mailman.Gui.GUIBase import GUIBase +from Mailman.configuration import config +from Mailman.i18n import _ @@ -31,13 +31,13 @@ class Archive(GUIBase): return [ _("List traffic archival policies."), - ('archive', mm_cfg.Toggle, (_('No'), _('Yes')), 0, + ('archive', config.Toggle, (_('No'), _('Yes')), 0, _('Archive messages?')), - ('archive_private', mm_cfg.Radio, (_('public'), _('private')), 0, + ('archive_private', config.Radio, (_('public'), _('private')), 0, _('Is archive file source for public or private archival?')), - ('archive_volume_frequency', mm_cfg.Radio, + ('archive_volume_frequency', config.Radio, (_('Yearly'), _('Monthly'), _('Quarterly'), _('Weekly'), _('Daily')), 0, diff --git a/Mailman/Gui/Autoresponse.py b/Mailman/Gui/Autoresponse.py index e5eca2b76..d35878f6b 100644 --- a/Mailman/Gui/Autoresponse.py +++ b/Mailman/Gui/Autoresponse.py @@ -17,10 +17,10 @@ """Administrative GUI for the autoresponder.""" -from Mailman import mm_cfg from Mailman import Utils -from Mailman.i18n import _ from Mailman.Gui.GUIBase import GUIBase +from Mailman.configuration import config +from Mailman.i18n import _ # These are the allowable string substitution variables ALLOWEDS = ('listname', 'listurl', 'requestemail', 'adminemail', 'owneremail') @@ -34,7 +34,7 @@ class Autoresponse(GUIBase): def GetConfigInfo(self, mlist, category, subcat=None): if category <> 'autoreply': return None - WIDTH = mm_cfg.TEXTFIELDWIDTH + WIDTH = config.TEXTFIELDWIDTH return [ _("""\ @@ -52,34 +52,34 @@ the following key/value substitutions: <p>For each text field, you can either enter the text directly into the text box, or you can specify a file on your local system to upload as the text."""), - ('autorespond_postings', mm_cfg.Toggle, (_('No'), _('Yes')), 0, + ('autorespond_postings', config.Toggle, (_('No'), _('Yes')), 0, _('''Should Mailman send an auto-response to mailing list posters?''')), - ('autoresponse_postings_text', mm_cfg.FileUpload, + ('autoresponse_postings_text', config.FileUpload, (6, WIDTH), 0, _('Auto-response text to send to mailing list posters.')), - ('autorespond_admin', mm_cfg.Toggle, (_('No'), _('Yes')), 0, + ('autorespond_admin', config.Toggle, (_('No'), _('Yes')), 0, _('''Should Mailman send an auto-response to emails sent to the -owner address?''')), - ('autoresponse_admin_text', mm_cfg.FileUpload, + ('autoresponse_admin_text', config.FileUpload, (6, WIDTH), 0, _('Auto-response text to send to -owner emails.')), - ('autorespond_requests', mm_cfg.Radio, + ('autorespond_requests', config.Radio, (_('No'), _('Yes, w/discard'), _('Yes, w/forward')), 0, _('''Should Mailman send an auto-response to emails sent to the -request address? If you choose yes, decide whether you want Mailman to discard the original email, or forward it on to the system as a normal mail command.''')), - ('autoresponse_request_text', mm_cfg.FileUpload, + ('autoresponse_request_text', config.FileUpload, (6, WIDTH), 0, _('Auto-response text to send to -request emails.')), - ('autoresponse_graceperiod', mm_cfg.Number, 3, 0, + ('autoresponse_graceperiod', config.Number, 3, 0, _('''Number of days between auto-responses to either the mailing list or -request/-owner address from the same poster. Set to zero (or negative) for no grace period (i.e. auto-respond to diff --git a/Mailman/Gui/Bounce.py b/Mailman/Gui/Bounce.py index a90d2a660..0dd4bbd0d 100644 --- a/Mailman/Gui/Bounce.py +++ b/Mailman/Gui/Bounce.py @@ -15,10 +15,9 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. -from Mailman import mm_cfg -from Mailman.i18n import _ -from Mailman.mm_cfg import days from Mailman.Gui.GUIBase import GUIBase +from Mailman.configuration import config +from Mailman.i18n import _ @@ -75,14 +74,14 @@ class Bounce(GUIBase): _('Bounce detection sensitivity'), - ('bounce_processing', mm_cfg.Toggle, (_('No'), _('Yes')), 0, + ('bounce_processing', config.Toggle, (_('No'), _('Yes')), 0, _('Should Mailman perform automatic bounce processing?'), _("""By setting this value to <em>No</em>, you disable all automatic bounce processing for this list, however bounce messages will still be discarded so that the list administrator isn't inundated with them.""")), - ('bounce_score_threshold', mm_cfg.Number, 5, 0, + ('bounce_score_threshold', config.Number, 5, 0, _("""The maximum member bounce score before the member's subscription is disabled. This value can be a floating point number."""), @@ -99,25 +98,25 @@ class Bounce(GUIBase): score, above which they are automatically disabled, but not removed from the mailing list.""")), - ('bounce_info_stale_after', mm_cfg.Number, 5, 0, + ('bounce_info_stale_after', config.Number, 5, 0, _("""The number of days after which a member's bounce information is discarded, if no new bounces have been received in the interim. This value must be an integer.""")), - ('bounce_you_are_disabled_warnings', mm_cfg.Number, 5, 0, + ('bounce_you_are_disabled_warnings', config.Number, 5, 0, _("""How many <em>Your Membership Is Disabled</em> warnings a disabled member should get before their address is removed from the mailing list. Set to 0 to immediately remove an address from the list once their bounce score exceeds the threshold. This value must be an integer.""")), - ('bounce_you_are_disabled_warnings_interval', mm_cfg.Number, 5, 0, + ('bounce_you_are_disabled_warnings_interval', config.Number, 5, 0, _("""The number of days between sending the <em>Your Membership Is Disabled</em> warnings. This value must be an integer.""")), _('Notifications'), - ('bounce_unrecognized_goes_to_list_owner', mm_cfg.Toggle, + ('bounce_unrecognized_goes_to_list_owner', config.Toggle, (_('No'), _('Yes')), 0, _('''Should Mailman send you, the list owner, any bounce messages that failed to be detected by the bounce processor? <em>Yes</em> @@ -143,7 +142,7 @@ class Bounce(GUIBase): <a href="?VARHELP=autoreply/autoresponse_admin_text">autoresponse message</a> for email to the -owner and -admin address.""")), - ('bounce_notify_owner_on_disable', mm_cfg.Toggle, + ('bounce_notify_owner_on_disable', config.Toggle, (_('No'), _('Yes')), 0, _("""Should Mailman notify you, the list owner, when bounces cause a member's subscription to be disabled?"""), @@ -152,7 +151,7 @@ class Bounce(GUIBase): when a member's delivery is disabled due to excessive bounces. An attempt to notify the member will always be made.""")), - ('bounce_notify_owner_on_removal', mm_cfg.Toggle, + ('bounce_notify_owner_on_removal', config.Toggle, (_('No'), _('Yes')), 0, _("""Should Mailman notify you, the list owner, when bounces cause a member to be unsubscribed?"""), @@ -172,11 +171,11 @@ class Bounce(GUIBase): elif property == 'bounce_score_threshold': val = float(val) elif property == 'bounce_info_stale_after': - val = days(int(val)) + val = config.days(int(val)) elif property == 'bounce_you_are_disabled_warnings': val = int(val) elif property == 'bounce_you_are_disabled_warnings_interval': - val = days(int(val)) + val = config.days(int(val)) elif property == 'bounce_notify_owner_on_disable': val = int(val) elif property == 'bounce_notify_owner_on_removal': @@ -193,4 +192,4 @@ class Bounce(GUIBase): if varname not in ('bounce_info_stale_after', 'bounce_you_are_disabled_warnings_interval'): return None - return int(getattr(mlist, varname) / days(1)) + return int(getattr(mlist, varname) / config.days(1)) diff --git a/Mailman/Gui/ContentFilter.py b/Mailman/Gui/ContentFilter.py index 0744c268e..8edc0bcb1 100644 --- a/Mailman/Gui/ContentFilter.py +++ b/Mailman/Gui/ContentFilter.py @@ -17,9 +17,9 @@ """GUI component managing the content filtering options.""" -from Mailman import mm_cfg -from Mailman.i18n import _ from Mailman.Gui.GUIBase import GUIBase +from Mailman.configuration import config +from Mailman.i18n import _ NL = '\n' @@ -32,10 +32,10 @@ class ContentFilter(GUIBase): def GetConfigInfo(self, mlist, category, subcat=None): if category <> 'contentfilter': return None - WIDTH = mm_cfg.TEXTFIELDWIDTH + WIDTH = config.TEXTFIELDWIDTH actions = [_('Discard'), _('Reject'), _('Forward to List Owner')] - if mm_cfg.OWNERS_CAN_PRESERVE_FILTERED_MESSAGES: + if config.OWNERS_CAN_PRESERVE_FILTERED_MESSAGES: actions.append(_('Preserve')) return [ @@ -71,11 +71,11 @@ class ContentFilter(GUIBase): >convert_html_to_plaintext</a> is enabled and the site is configured to allow these conversions."""), - ('filter_content', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('filter_content', config.Radio, (_('No'), _('Yes')), 0, _("""Should Mailman filter the content of list traffic according to the settings below?""")), - ('filter_mime_types', mm_cfg.Text, (10, WIDTH), 0, + ('filter_mime_types', config.Text, (10, WIDTH), 0, _("""Remove message attachments that have a matching content type."""), @@ -90,7 +90,7 @@ class ContentFilter(GUIBase): <p>See also <a href="?VARHELP=contentfilter/pass_mime_types" >pass_mime_types</a> for a content type whitelist.""")), - ('pass_mime_types', mm_cfg.Text, (10, WIDTH), 0, + ('pass_mime_types', config.Text, (10, WIDTH), 0, _("""Remove message attachments that don't have a matching content type. Leave this field blank to skip this filter test."""), @@ -104,25 +104,25 @@ class ContentFilter(GUIBase): <tt>multipart</tt> to this list, any messages with attachments will be rejected by the pass filter.""")), - ('filter_filename_extensions', mm_cfg.Text, (10, WIDTH), 0, + ('filter_filename_extensions', config.Text, (10, WIDTH), 0, _("""Remove message attachments that have a matching filename extension."""),), - ('pass_filename_extensions', mm_cfg.Text, (10, WIDTH), 0, + ('pass_filename_extensions', config.Text, (10, WIDTH), 0, _("""Remove message attachments that don't have a matching filename extension. Leave this field blank to skip this filter test."""),), - ('collapse_alternatives', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('collapse_alternatives', config.Radio, (_('No'), _('Yes')), 0, _("""Should Mailman collapse multipart/alternative to its first part content?""")), - ('convert_html_to_plaintext', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('convert_html_to_plaintext', config.Radio, (_('No'), _('Yes')), 0, _("""Should Mailman convert <tt>text/html</tt> parts to plain text? This conversion happens after MIME attachments have been stripped.""")), - ('filter_action', mm_cfg.Radio, tuple(actions), 0, + ('filter_action', config.Radio, tuple(actions), 0, _("""Action to take when a message matches the content filtering rules."""), diff --git a/Mailman/Gui/Digest.py b/Mailman/Gui/Digest.py index b01e3850b..0528a267f 100644 --- a/Mailman/Gui/Digest.py +++ b/Mailman/Gui/Digest.py @@ -17,8 +17,8 @@ """Administrative GUI for digest deliveries.""" -from Mailman import mm_cfg from Mailman import Utils +from Mailman.configuration import config from Mailman.i18n import _ # Intra-package import @@ -39,62 +39,62 @@ class Digest(GUIBase): def GetConfigInfo(self, mlist, category, subcat=None): if category <> 'digest': return None - WIDTH = mm_cfg.TEXTFIELDWIDTH + WIDTH = config.TEXTFIELDWIDTH info = [ _("Batched-delivery digest characteristics."), - ('digestable', mm_cfg.Toggle, (_('No'), _('Yes')), 1, + ('digestable', config.Toggle, (_('No'), _('Yes')), 1, _('Can list members choose to receive list traffic ' 'bunched in digests?')), - ('digest_is_default', mm_cfg.Radio, + ('digest_is_default', config.Radio, (_('Regular'), _('Digest')), 0, _('Which delivery mode is the default for new users?')), - ('mime_is_default_digest', mm_cfg.Radio, + ('mime_is_default_digest', config.Radio, (_('Plain'), _('MIME')), 0, _('When receiving digests, which format is default?')), - ('digest_size_threshhold', mm_cfg.Number, 3, 0, + ('digest_size_threshhold', config.Number, 3, 0, _('How big in Kb should a digest be before it gets sent out?')), # Should offer a 'set to 0' for no size threshhold. - ('digest_send_periodic', mm_cfg.Radio, (_('No'), _('Yes')), 1, + ('digest_send_periodic', config.Radio, (_('No'), _('Yes')), 1, _('Should a digest be dispatched daily when the size threshold ' "isn't reached?")), - ('digest_header', mm_cfg.Text, (4, WIDTH), 0, + ('digest_header', config.Text, (4, WIDTH), 0, _('Header added to every digest'), _("Text attached (as an initial message, before the table" " of contents) to the top of digests. ") + Utils.maketext('headfoot.html', raw=1, mlist=mlist)), - ('digest_footer', mm_cfg.Text, (4, WIDTH), 0, + ('digest_footer', config.Text, (4, WIDTH), 0, _('Footer added to every digest'), _("Text attached (as a final message) to the bottom of digests. ") + Utils.maketext('headfoot.html', raw=1, mlist=mlist)), - ('digest_volume_frequency', mm_cfg.Radio, + ('digest_volume_frequency', config.Radio, (_('Yearly'), _('Monthly'), _('Quarterly'), _('Weekly'), _('Daily')), 0, _('How often should a new digest volume be started?'), _('''When a new digest volume is started, the volume number is incremented and the issue number is reset to 1.''')), - ('_new_volume', mm_cfg.Toggle, (_('No'), _('Yes')), 0, + ('_new_volume', config.Toggle, (_('No'), _('Yes')), 0, _('Should Mailman start a new digest volume?'), _('''Setting this option instructs Mailman to start a new volume with the next digest sent out.''')), - ('_send_digest_now', mm_cfg.Toggle, (_('No'), _('Yes')), 0, + ('_send_digest_now', config.Toggle, (_('No'), _('Yes')), 0, _('''Should Mailman send the next digest right now, if it is not empty?''')), ] -## if mm_cfg.OWNERS_CAN_ENABLE_PERSONALIZATION: +## if config.OWNERS_CAN_ENABLE_PERSONALIZATION: ## info.extend([ -## ('digest_personalize', mm_cfg.Toggle, (_('No'), _('Yes')), 1, +## ('digest_personalize', config.Toggle, (_('No'), _('Yes')), 1, ## _('''Should Mailman personalize each digest delivery? ## This is often useful for announce-only lists, but <a diff --git a/Mailman/Gui/General.py b/Mailman/Gui/General.py index 35b03d9c0..6dde9045e 100644 --- a/Mailman/Gui/General.py +++ b/Mailman/Gui/General.py @@ -19,11 +19,11 @@ import re -from Mailman import mm_cfg -from Mailman import Utils from Mailman import Errors -from Mailman.i18n import _ +from Mailman import Utils from Mailman.Gui.GUIBase import GUIBase +from Mailman.configuration import config +from Mailman.i18n import _ OPTIONS = ('hide', 'ack', 'notmetoo', 'nodupes') @@ -36,13 +36,13 @@ class General(GUIBase): def GetConfigInfo(self, mlist, category, subcat): if category <> 'general': return None - WIDTH = mm_cfg.TEXTFIELDWIDTH + WIDTH = config.TEXTFIELDWIDTH # These are for the default_options checkboxes below. - bitfields = {'hide' : mm_cfg.ConcealSubscription, - 'ack' : mm_cfg.AcknowledgePosts, - 'notmetoo' : mm_cfg.DontReceiveOwnPosts, - 'nodupes' : mm_cfg.DontReceiveDuplicates + bitfields = {'hide' : config.ConcealSubscription, + 'ack' : config.AcknowledgePosts, + 'notmetoo' : config.DontReceiveOwnPosts, + 'nodupes' : config.DontReceiveDuplicates } bitdescrs = { 'hide' : _("Conceal the member's address"), @@ -61,7 +61,7 @@ class General(GUIBase): _('General list personality'), - ('real_name', mm_cfg.String, WIDTH, 0, + ('real_name', config.String, WIDTH, 0, _('The public name of this list (make case-changes only).'), _('''The capitalization of this name can be changed to make it presentable in polite company as a proper noun, or to make an @@ -71,7 +71,7 @@ class General(GUIBase): addresses are not case sensitive, but they are sensitive to almost everything else :-)''')), - ('owner', mm_cfg.EmailList, (3, WIDTH), 0, + ('owner', config.EmailList, (3, WIDTH), 0, _("""The list administrator email addresses. Multiple administrator addresses, each on separate line is okay."""), @@ -95,7 +95,7 @@ class General(GUIBase): addresses of the list moderators</a>. Note that the field you are changing here specifies the list administrators.''')), - ('moderator', mm_cfg.EmailList, (3, WIDTH), 0, + ('moderator', config.EmailList, (3, WIDTH), 0, _("""The list moderator email addresses. Multiple moderator addresses, each on separate line is okay."""), @@ -119,7 +119,7 @@ class General(GUIBase): this section. Note that the field you are changing here specifies the list moderators.''')), - ('description', mm_cfg.String, WIDTH, 0, + ('description', config.String, WIDTH, 0, _('A terse phrase identifying this list.'), _('''This description is used when the mailing list is listed with @@ -127,7 +127,7 @@ class General(GUIBase): be as succinct as you can get it, while still identifying what the list is.''')), - ('info', mm_cfg.Text, (7, WIDTH), 0, + ('info', config.Text, (7, WIDTH), 0, _('''An introductory description - a few paragraphs - about the list. It will be included, as html, at the top of the listinfo page. Carriage returns will end a paragraph - see the details @@ -139,7 +139,7 @@ class General(GUIBase): bad html (like some unterminated HTML constructs) can prevent display of the entire listinfo page.""")), - ('subject_prefix', mm_cfg.String, WIDTH, 0, + ('subject_prefix', config.String, WIDTH, 0, _('Prefix for subject line of list postings.'), _("""This text will be prepended to subject lines of messages posted to the list, to distinguish mailing list messages in in @@ -151,19 +151,19 @@ class General(GUIBase): (listname %%05d) -> (listname 00123) """)), - ('anonymous_list', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('anonymous_list', config.Radio, (_('No'), _('Yes')), 0, _("""Hide the sender of a message, replacing it with the list address (Removes From, Sender and Reply-To fields)""")), _('''<tt>Reply-To:</tt> header munging'''), - ('first_strip_reply_to', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('first_strip_reply_to', config.Radio, (_('No'), _('Yes')), 0, _('''Should any existing <tt>Reply-To:</tt> header found in the original message be stripped? If so, this will be done regardless of whether an explict <tt>Reply-To:</tt> header is added by Mailman or not.''')), - ('reply_goes_to_list', mm_cfg.Radio, + ('reply_goes_to_list', config.Radio, (_('Poster'), _('This list'), _('Explicit address')), 0, _('''Where are replies to list messages directed? <tt>Poster</tt> is <em>strongly</em> recommended for most mailing @@ -201,7 +201,7 @@ class General(GUIBase): <tt>Reply-To:</tt> address below to point to the parallel list.""")), - ('reply_to_address', mm_cfg.Email, WIDTH, 0, + ('reply_to_address', config.Email, WIDTH, 0, _('Explicit <tt>Reply-To:</tt> header.'), # Details for reply_to_address _("""This is the address set in the <tt>Reply-To:</tt> header @@ -235,7 +235,7 @@ class General(GUIBase): _('Umbrella list settings'), - ('umbrella_list', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('umbrella_list', config.Radio, (_('No'), _('Yes')), 0, _('''Send password reminders to, eg, "-owner" address instead of directly to user.'''), @@ -246,7 +246,7 @@ class General(GUIBase): value of "umbrella_member_suffix" appended to the member's account name.""")), - ('umbrella_member_suffix', mm_cfg.String, WIDTH, 0, + ('umbrella_member_suffix', config.String, WIDTH, 0, _('''Suffix for use when this list is an umbrella for other lists, according to setting of previous "umbrella_list" setting.'''), @@ -262,14 +262,14 @@ class General(GUIBase): _('Notifications'), - ('send_reminders', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('send_reminders', config.Radio, (_('No'), _('Yes')), 0, _('''Send monthly password reminders?'''), _('''Turn this on if you want password reminders to be sent once per month to your members. Note that members may disable their own individual password reminders.''')), - ('welcome_msg', mm_cfg.Text, (4, WIDTH), 0, + ('welcome_msg', config.Text, (4, WIDTH), 0, _('''List-specific text prepended to new-subscriber welcome message'''), @@ -289,21 +289,21 @@ class General(GUIBase): <li>A blank line separates paragraphs. </ul>""")), - ('send_welcome_msg', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('send_welcome_msg', config.Radio, (_('No'), _('Yes')), 0, _('Send welcome message to newly subscribed members?'), _("""Turn this off only if you plan on subscribing people manually and don't want them to know that you did so. This option is most useful for transparently migrating lists from some other mailing list manager to Mailman.""")), - ('goodbye_msg', mm_cfg.Text, (4, WIDTH), 0, + ('goodbye_msg', config.Text, (4, WIDTH), 0, _('''Text sent to people leaving the list. If empty, no special text will be added to the unsubscribe message.''')), - ('send_goodbye_msg', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('send_goodbye_msg', config.Radio, (_('No'), _('Yes')), 0, _('Send goodbye message to members when they are unsubscribed?')), - ('admin_immed_notify', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('admin_immed_notify', config.Radio, (_('No'), _('Yes')), 0, _('''Should the list moderators get immediate notice of new requests, as well as daily notices about collected ones?'''), @@ -313,25 +313,25 @@ class General(GUIBase): another. Setting this option causes notices to be sent immediately on the arrival of new requests as well.''')), - ('admin_notify_mchanges', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('admin_notify_mchanges', config.Radio, (_('No'), _('Yes')), 0, _('''Should administrator get notices of subscribes and unsubscribes?''')), - ('respond_to_post_requests', mm_cfg.Radio, + ('respond_to_post_requests', config.Radio, (_('No'), _('Yes')), 0, _('Send mail to poster when their posting is held for approval?') ), _('Additional settings'), - ('emergency', mm_cfg.Toggle, (_('No'), _('Yes')), 0, + ('emergency', config.Toggle, (_('No'), _('Yes')), 0, _('Emergency moderation of all list traffic.'), _("""When this option is enabled, all list traffic is emergency moderated, i.e. held for moderation. Turn this option on when your list is experiencing a flamewar and you want a cooling off period.""")), - ('new_member_options', mm_cfg.Checkbox, + ('new_member_options', config.Checkbox, (opttext, optvals, 0, OPTIONS), # The description for new_member_options includes a kludge where # we add a hidden field so that even when all the checkboxes are @@ -344,7 +344,7 @@ class General(GUIBase): _("""When a new member is subscribed to this list, their initial set of options is taken from the this variable's setting.""")), - ('administrivia', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('administrivia', config.Radio, (_('No'), _('Yes')), 0, _('''(Administrivia filter) Check postings and intercept ones that seem to be administrative requests?'''), @@ -354,11 +354,11 @@ class General(GUIBase): requests queue, notifying the administrator of the new request, in the process.""")), - ('max_message_size', mm_cfg.Number, 7, 0, + ('max_message_size', config.Number, 7, 0, _('''Maximum length in kilobytes (KB) of a message body. Use 0 for no limit.''')), - ('host_name', mm_cfg.Host, WIDTH, 0, + ('host_name', config.Host, WIDTH, 0, _('Host name this list prefers for email.'), _("""The "host_name" is the preferred name for email to @@ -369,9 +369,9 @@ class General(GUIBase): ] - if mm_cfg.ALLOW_RFC2369_OVERRIDES: + if config.ALLOW_RFC2369_OVERRIDES: rtn.append( - ('include_rfc2369_headers', mm_cfg.Radio, + ('include_rfc2369_headers', config.Radio, (_('No'), _('Yes')), 0, _("""Should messages from this mailing list include the <a href="http://www.faqs.org/rfcs/rfc2369.html">RFC 2369</a> @@ -394,7 +394,7 @@ class General(GUIBase): ) # Suppression of List-Post: headers rtn.append( - ('include_list_post_header', mm_cfg.Radio, + ('include_list_post_header', config.Radio, (_('No'), _('Yes')), 0, _('Should postings include the <tt>List-Post:</tt> header?'), _("""The <tt>List-Post:</tt> header is one of the headers @@ -411,7 +411,7 @@ class General(GUIBase): # Discard held messages after this number of days rtn.append( - ('max_days_to_hold', mm_cfg.Number, 7, 0, + ('max_days_to_hold', config.Number, 7, 0, _("""Discard held messages older than this number of days. Use 0 for no automatic discarding.""")) ) @@ -428,7 +428,7 @@ class General(GUIBase): elif property == 'new_member_options': newopts = 0 for opt in OPTIONS: - bitfield = mm_cfg.OPTINFO[opt] + bitfield = config.OPTINFO[opt] if opt in val: newopts |= bitfield mlist.new_member_options = newopts diff --git a/Mailman/Gui/Language.py b/Mailman/Gui/Language.py index c29894fde..32029577d 100644 --- a/Mailman/Gui/Language.py +++ b/Mailman/Gui/Language.py @@ -21,8 +21,8 @@ import codecs from Mailman import Utils from Mailman import i18n -from Mailman import mm_cfg from Mailman.Gui.GUIBase import GUIBase +from Mailman.configuration import config _ = i18n._ @@ -53,7 +53,7 @@ class Language(GUIBase): except LookupError: return 0 - all = [key for key in mm_cfg.LC_DESCRIPTIONS.keys() + all = [key for key in config.LC_DESCRIPTIONS.keys() if checkcodec(Utils.GetCharSet(key))] all.sort() checked = [L in langs for L in all] @@ -62,7 +62,7 @@ class Language(GUIBase): return [ _('Natural language (internationalization) options.'), - ('preferred_language', mm_cfg.Select, + ('preferred_language', config.Select, (langs, langnames, langi), 0, _('Default language for this list.'), @@ -74,7 +74,7 @@ class Language(GUIBase): applies to both web-based and email-based messages, but not to email posted by list members.''')), - ('available_languages', mm_cfg.Checkbox, + ('available_languages', config.Checkbox, (allnames, checked, 0, all), 0, _('Languages supported by this list.'), @@ -83,7 +83,7 @@ class Language(GUIBase): <a href="?VARHELP=language/preferred_language">default language</a> must be included.''')), - ('encode_ascii_prefixes', mm_cfg.Radio, + ('encode_ascii_prefixes', config.Radio, (_('Never'), _('Always'), _('As needed')), 0, _("""Encode the <a href="?VARHELP=general/subject_prefix">subject diff --git a/Mailman/Gui/Privacy.py b/Mailman/Gui/Privacy.py index da41e93e2..3d218a2df 100644 --- a/Mailman/Gui/Privacy.py +++ b/Mailman/Gui/Privacy.py @@ -19,10 +19,10 @@ import re -from Mailman import mm_cfg from Mailman import Utils -from Mailman.i18n import _ from Mailman.Gui.GUIBase import GUIBase +from Mailman.configuration import config +from Mailman.i18n import _ @@ -45,9 +45,9 @@ class Privacy(GUIBase): # Pre-calculate some stuff. Technically, we shouldn't do the # sub_cfentry calculation here, but it's too ugly to indent it any # further, and besides, that'll mess up i18n catalogs. - WIDTH = mm_cfg.TEXTFIELDWIDTH - if mm_cfg.ALLOW_OPEN_SUBSCRIBE: - sub_cfentry = ('subscribe_policy', mm_cfg.Radio, + WIDTH = config.TEXTFIELDWIDTH + if config.ALLOW_OPEN_SUBSCRIBE: + sub_cfentry = ('subscribe_policy', config.Radio, # choices (_('None'), _('Confirm'), @@ -71,7 +71,7 @@ class Privacy(GUIBase): from creating subscriptions for others without their consent.''')) else: - sub_cfentry = ('subscribe_policy', mm_cfg.Radio, + sub_cfentry = ('subscribe_policy', config.Radio, # choices (_('Confirm'), _('Require approval'), @@ -101,13 +101,13 @@ class Privacy(GUIBase): separate archive-related privacy settings."""), _('Subscribing'), - ('advertised', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('advertised', config.Radio, (_('No'), _('Yes')), 0, _('''Advertise this list when people ask what lists are on this machine?''')), sub_cfentry, - ('subscribe_auto_approval', mm_cfg.EmailListEx, (10, WIDTH), 1, + ('subscribe_auto_approval', config.EmailListEx, (10, WIDTH), 1, _("""List of addresses (or regexps) whose subscriptions do not require approval."""), @@ -116,7 +116,7 @@ class Privacy(GUIBase): addresses one per line. You may begin a line with a ^ character to designate a (case insensitive) regular expression match.""")), - ('unsubscribe_policy', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('unsubscribe_policy', config.Radio, (_('No'), _('Yes')), 0, _("""Is the list moderator's approval required for unsubscription requests? (<em>No</em> is recommended)"""), @@ -132,7 +132,7 @@ class Privacy(GUIBase): are required to be members of.""")), _('Ban list'), - ('ban_list', mm_cfg.EmailListEx, (10, WIDTH), 1, + ('ban_list', config.EmailListEx, (10, WIDTH), 1, _("""List of addresses which are banned from membership in this mailing list."""), @@ -142,14 +142,14 @@ class Privacy(GUIBase): designate a regular expression match.""")), _("Membership exposure"), - ('private_roster', mm_cfg.Radio, + ('private_roster', config.Radio, (_('Anyone'), _('List members'), _('List admin only')), 0, _('Who can view subscription list?'), _('''When set, the list of subscribers is protected by member or admin password authentication.''')), - ('obscure_addresses', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('obscure_addresses', config.Radio, (_('No'), _('Yes')), 0, _("""Show member addresses so they're not directly recognizable as email addresses?"""), _("""Setting this option causes member email addresses to be @@ -197,7 +197,7 @@ class Privacy(GUIBase): _('Member filters'), - ('default_member_moderation', mm_cfg.Radio, (_('No'), _('Yes')), + ('default_member_moderation', config.Radio, (_('No'), _('Yes')), 0, _('By default, should new list member postings be moderated?'), _("""Each list member has a <em>moderation flag</em> which says @@ -215,7 +215,7 @@ class Privacy(GUIBase): <a href="%(adminurl)s/members">membership management screens</a>.""")), - ('member_moderation_action', mm_cfg.Radio, + ('member_moderation_action', config.Radio, (_('Hold'), _('Reject'), _('Discard')), 0, _("""Action to take when a moderated member posts to the list."""), @@ -232,7 +232,7 @@ class Privacy(GUIBase): no notice sent to the post's author. </ul>""")), - ('member_moderation_notice', mm_cfg.Text, (10, WIDTH), 1, + ('member_moderation_notice', config.Text, (10, WIDTH), 1, _("""Text to include in any <a href="?VARHELP/privacy/sender/member_moderation_action" >rejection notice</a> to @@ -240,7 +240,7 @@ class Privacy(GUIBase): _('Non-member filters'), - ('accept_these_nonmembers', mm_cfg.EmailListEx, (10, WIDTH), 1, + ('accept_these_nonmembers', config.EmailListEx, (10, WIDTH), 1, _("""List of non-member addresses whose postings should be automatically accepted."""), @@ -249,7 +249,7 @@ class Privacy(GUIBase): addresses one per line; start the line with a ^ character to designate a regular expression match.""")), - ('hold_these_nonmembers', mm_cfg.EmailListEx, (10, WIDTH), 1, + ('hold_these_nonmembers', config.EmailListEx, (10, WIDTH), 1, _("""List of non-member addresses whose postings will be immediately held for moderation."""), @@ -260,7 +260,7 @@ class Privacy(GUIBase): line; start the line with a ^ character to designate a regular expression match.""")), - ('reject_these_nonmembers', mm_cfg.EmailListEx, (10, WIDTH), 1, + ('reject_these_nonmembers', config.EmailListEx, (10, WIDTH), 1, _("""List of non-member addresses whose postings will be automatically rejected."""), @@ -275,7 +275,7 @@ class Privacy(GUIBase): <p>Add member addresses one per line; start the line with a ^ character to designate a regular expression match.""")), - ('discard_these_nonmembers', mm_cfg.EmailListEx, (10, WIDTH), 1, + ('discard_these_nonmembers', config.EmailListEx, (10, WIDTH), 1, _("""List of non-member addresses whose postings will be automatically discarded."""), @@ -289,7 +289,7 @@ class Privacy(GUIBase): <p>Add member addresses one per line; start the line with a ^ character to designate a regular expression match.""")), - ('generic_nonmember_action', mm_cfg.Radio, + ('generic_nonmember_action', config.Radio, (_('Accept'), _('Hold'), _('Reject'), _('Discard')), 0, _("""Action to take for postings from non-members for which no explicit action is defined."""), @@ -305,11 +305,11 @@ class Privacy(GUIBase): >discarded</a> addresses. If no match is found, then this action is taken.""")), - ('forward_auto_discards', mm_cfg.Radio, (_('No'), _('Yes')), 0, + ('forward_auto_discards', config.Radio, (_('No'), _('Yes')), 0, _("""Should messages from non-members, which are automatically discarded, be forwarded to the list moderator?""")), - ('nonmember_rejection_notice', mm_cfg.Text, (10, WIDTH), 1, + ('nonmember_rejection_notice', config.Text, (10, WIDTH), 1, _("""Text to include in any rejection notice to be sent to non-members who post to this list. This notice can include the list's owner address by %%(listowner)s and replaces the @@ -323,7 +323,7 @@ class Privacy(GUIBase): _('Recipient filters'), - ('require_explicit_destination', mm_cfg.Radio, + ('require_explicit_destination', config.Radio, (_('No'), _('Yes')), 0, _("""Must posts have list named in destination (to, cc) field (or be among the acceptable alias names, specified below)?"""), @@ -345,7 +345,7 @@ class Privacy(GUIBase): </ol>""")), - ('acceptable_aliases', mm_cfg.Text, (4, WIDTH), 0, + ('acceptable_aliases', config.Text, (4, WIDTH), 0, _("""Alias names (regexps) which qualify as explicit to or cc destination names for this list."""), @@ -366,7 +366,7 @@ class Privacy(GUIBase): release, the pattern will always be matched against the entire recipient address.""")), - ('max_num_recipients', mm_cfg.Number, 5, 0, + ('max_num_recipients', config.Number, 5, 0, _('Ceiling on acceptable number of recipients for a posting.'), _('''If a posting has this number, or more, of recipients, it is @@ -381,7 +381,7 @@ class Privacy(GUIBase): _('Header filters'), - ('header_filter_rules', mm_cfg.HeaderFilter, 0, 0, + ('header_filter_rules', config.HeaderFilter, 0, 0, _('Filter rules to match against the headers of a message.'), _("""Each header filter rule has two parts, a list of regular @@ -403,7 +403,7 @@ class Privacy(GUIBase): _('Legacy anti-spam filters'), - ('bounce_matching_headers', mm_cfg.Text, (6, WIDTH), 0, + ('bounce_matching_headers', config.Text, (6, WIDTH), 0, _('Hold posts with header value matching a specified regexp.'), _("""Use this option to prohibit posts according to specific header values. The target value is a regular-expression for @@ -436,7 +436,7 @@ class Privacy(GUIBase): # For subscribe_policy when ALLOW_OPEN_SUBSCRIBE is true, we need to # add one to the value because the page didn't present an open list as # an option. - if property == 'subscribe_policy' and not mm_cfg.ALLOW_OPEN_SUBSCRIBE: + if property == 'subscribe_policy' and not config.ALLOW_OPEN_SUBSCRIBE: val += 1 setattr(mlist, property, val) @@ -476,7 +476,7 @@ class Privacy(GUIBase): # We'll get a TypeError when the actiontag is missing and the # .getvalue() call returns None. except (ValueError, TypeError): - action = mm_cfg.DEFER + action = config.DEFER if pattern is None: # We came to the end of the boxes break @@ -503,12 +503,12 @@ class Privacy(GUIBase): where = cgidata.getvalue(wheretag) if where == 'before': # Add a new empty rule box before the current one - rules.append(('', mm_cfg.DEFER, True)) + rules.append(('', config.DEFER, True)) rules.append((pattern, action, False)) # Default is to add it after... else: rules.append((pattern, action, False)) - rules.append(('', mm_cfg.DEFER, True)) + rules.append(('', config.DEFER, True)) # Was this an up movement? elif cgidata.has_key(uptag): # As long as this one isn't the first rule, move it up diff --git a/Mailman/Gui/Topics.py b/Mailman/Gui/Topics.py index 29613f3dd..731460a10 100644 --- a/Mailman/Gui/Topics.py +++ b/Mailman/Gui/Topics.py @@ -17,10 +17,10 @@ import re -from Mailman import mm_cfg from Mailman import Utils -from Mailman.i18n import _ from Mailman.Gui.GUIBase import GUIBase +from Mailman.configuration import config +from Mailman.i18n import _ OR = '|' @@ -33,12 +33,12 @@ class Topics(GUIBase): def GetConfigInfo(self, mlist, category, subcat=None): if category <> 'topics': return None - WIDTH = mm_cfg.TEXTFIELDWIDTH + WIDTH = config.TEXTFIELDWIDTH return [ _('List topic keywords'), - ('topics_enabled', mm_cfg.Radio, (_('Disabled'), _('Enabled')), 0, + ('topics_enabled', config.Radio, (_('Disabled'), _('Enabled')), 0, _('''Should the topic filter be enabled or disabled?'''), _("""The topic filter categorizes each incoming email message @@ -61,7 +61,7 @@ class Topics(GUIBase): href="?VARHELP=topics/topics_bodylines_limit">topics_bodylines_limit</a> configuration variable.""")), - ('topics_bodylines_limit', mm_cfg.Number, 5, 0, + ('topics_bodylines_limit', config.Number, 5, 0, _('How many body lines should the topic matcher scan?'), _("""The topic matcher will scan this many lines of the message @@ -74,7 +74,7 @@ class Topics(GUIBase): until a non-header-like line is encountered. """)), - ('topics', mm_cfg.Topics, 0, 0, + ('topics', config.Topics, 0, 0, _('Topic keywords, one per line, to match against each message.'), _("""Each topic keyword is actually a regular expression, which is diff --git a/Mailman/Gui/Usenet.py b/Mailman/Gui/Usenet.py index eddde6a02..0463fb3b2 100644 --- a/Mailman/Gui/Usenet.py +++ b/Mailman/Gui/Usenet.py @@ -15,9 +15,9 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. -from Mailman import mm_cfg -from Mailman.i18n import _ from Mailman.Gui.GUIBase import GUIBase +from Mailman.configuration import config +from Mailman.i18n import _ @@ -29,7 +29,7 @@ class Usenet(GUIBase): if category <> 'gateway': return None - WIDTH = mm_cfg.TEXTFIELDWIDTH + WIDTH = config.TEXTFIELDWIDTH VERTICAL = 1 return [ @@ -37,7 +37,7 @@ class Usenet(GUIBase): _('News server settings'), - ('nntp_host', mm_cfg.String, WIDTH, 0, + ('nntp_host', config.String, WIDTH, 0, _('The hostname of the machine your news server is running on.'), _('''This value may be either the name of your news server, or optionally of the format name:port, where port is a port number. @@ -47,20 +47,20 @@ class Usenet(GUIBase): recognize the machine this mailing list runs on as a machine capable of reading and posting news.''')), - ('linked_newsgroup', mm_cfg.String, WIDTH, 0, + ('linked_newsgroup', config.String, WIDTH, 0, _('The name of the Usenet group to gateway to and/or from.')), - ('gateway_to_news', mm_cfg.Toggle, (_('No'), _('Yes')), 0, + ('gateway_to_news', config.Toggle, (_('No'), _('Yes')), 0, _('''Should new posts to the mailing list be sent to the newsgroup?''')), - ('gateway_to_mail', mm_cfg.Toggle, (_('No'), _('Yes')), 0, + ('gateway_to_mail', config.Toggle, (_('No'), _('Yes')), 0, _('''Should new posts to the newsgroup be sent to the mailing list?''')), _('Forwarding options'), - ('news_moderation', mm_cfg.Radio, + ('news_moderation', config.Radio, (_('None'), _('Open list, moderated group'), _('Moderated')), VERTICAL, @@ -91,7 +91,7 @@ class Usenet(GUIBase): Mailman moderation facilities, but to add an <tt>Approved</tt> header to all messages that are gatewayed to Usenet.""")), - ('news_prefix_subject_too', mm_cfg.Toggle, (_('No'), _('Yes')), 0, + ('news_prefix_subject_too', config.Toggle, (_('No'), _('Yes')), 0, _('Prefix <tt>Subject:</tt> headers on postings gated to news?'), _("""Mailman prefixes <tt>Subject:</tt> headers with <a href="?VARHELP=general/subject_prefix">text you can @@ -103,7 +103,7 @@ class Usenet(GUIBase): _('Mass catch up'), - ('_mass_catchup', mm_cfg.Toggle, (_('No'), _('Yes')), 0, + ('_mass_catchup', config.Toggle, (_('No'), _('Yes')), 0, _('Should Mailman perform a <em>catchup</em> on the newsgroup?'), _('''When you tell Mailman to perform a catchup on the newsgroup, this means that you want to start gating messages to the mailing diff --git a/Mailman/Mailbox.py b/Mailman/Mailbox.py index 12eea2bdb..9b3474c2b 100644 --- a/Mailman/Mailbox.py +++ b/Mailman/Mailbox.py @@ -25,8 +25,8 @@ from email.Errors import MessageParseError from email.Generator import Generator from email.Parser import Parser -from Mailman import mm_cfg from Mailman.Message import Message +from Mailman.configuration import config @@ -90,9 +90,9 @@ class ArchiverMailbox(Mailbox): # scrub() method, giving the scrubber module a chance to do its thing # before the message is archived. def __init__(self, fp, mlist): - if mm_cfg.ARCHIVE_SCRUBBER: - __import__(mm_cfg.ARCHIVE_SCRUBBER) - self._scrubber = sys.modules[mm_cfg.ARCHIVE_SCRUBBER].process + if config.ARCHIVE_SCRUBBER: + __import__(config.ARCHIVE_SCRUBBER) + self._scrubber = sys.modules[config.ARCHIVE_SCRUBBER].process else: self._scrubber = None self._mlist = mlist diff --git a/Mailman/Post.py b/Mailman/Post.py index cfb53c5da..719c3e68b 100644 --- a/Mailman/Post.py +++ b/Mailman/Post.py @@ -19,14 +19,14 @@ import sys -from Mailman import mm_cfg from Mailman.Queue.sbcache import get_switchboard +from Mailman.configuration import config def inject(listname, msg, recips=None, qdir=None): if qdir is None: - qdir = mm_cfg.INQUEUE_DIR + qdir = config.INQUEUE_DIR queue = get_switchboard(qdir) kws = {'listname' : listname, 'tolist' : 1, diff --git a/Mailman/bin/make_instance.py b/Mailman/bin/make_instance.py index 756199cea..435b0863a 100644 --- a/Mailman/bin/make_instance.py +++ b/Mailman/bin/make_instance.py @@ -22,27 +22,36 @@ import grp import pwd import sys import optparse +import setuptools from string import Template import Mailman from Mailman.Version import MAILMAN_VERSION -from Mailman.i18n import _ + +# Until an instance is actually created, this module won't be importable +# because the Defaults.py module won't have been created yet. +try: + from Mailman.i18n import _ +except ImportError: + def _(s): return s __i18n_templates__ = True SPACE = ' ' +DEFAULT_RUNTIME_DIR = '/var/mailman' def parseargs(): - parser = optparse.OptionParser(MAILMAN_VERSION, usage=_("""\ + parser = optparse.OptionParser(version=MAILMAN_VERSION, + usage=_("""\ %prog [options] Create a Mailman instance by generating all the necessary basic configuration support and intervening directories. """)) parser.add_option('-r', '--runtime-dir', - type='string', default='/var/mailman', help=_("""\ -The top-level run-time data directory. All supporting run-time data will be + type='string', default=DEFAULT_RUNTIME_DIR, help=_("""\ +The top-level runtime data directory. All supporting runtime data will be placed in subdirectories of this directory. It will be created if necessary, although this might require superuser privileges.""")) parser.add_option('-p', '--permchecks', @@ -50,11 +59,11 @@ although this might require superuser privileges.""")) Perform permission checks on the runtime directory.""")) parser.add_option('-u', '--user', type='string', default=None, help=_("""\ -The user id or name to use for the run-time directory. If not specified, the +The user id or name to use for the runtime environment. If not specified, the current user is used.""")) parser.add_option('-g', '--group', type='string', default=None, help=_("""\ -The group id or name to use for the run-time directory. If not specified, the +The group id or name to use for the runtime environment. If not specified, the current group is used.""")) parser.add_option('-l', '--language', default=[], type='string', action='append', help=_("""\ @@ -67,8 +76,7 @@ Enable the given language. Use 'all' to enable all supported languages.""")) -def main(): - parser, opts, args = parseargs() +def instantiate(user=None, group=None, runtime_dir=None): # Create the Defaults.py file using substitutions. in_file_path = os.path.join(os.path.dirname(Mailman.__file__), 'Defaults.py.in') @@ -76,42 +84,48 @@ def main(): with open(in_file_path) as fp: raw = Template(fp.read()) # Figure out which user name and group name to use. - if opts.user is None: + if user is None: uid = os.getuid() else: try: - uid = int(opts.user) + uid = int(user) except ValueError: try: - uid = pwd.getpwnam(opts.user).pw_uid + uid = pwd.getpwnam(user).pw_uid except KeyError: - parser.print_error(_('Unknown user: $opts.user')) + parser.print_error(_('Unknown user: $user')) try: - user_name = pwd.getpwuid(uid) + user_name = pwd.getpwuid(uid).pw_name except KeyError: - parser.print_error(_('Unknown user: $opts.user')) - if opts.group is None: + parser.print_error(_('Unknown user: $user')) + if group is None: gid = os.getgid() else: try: - gid = int(opts.group) + gid = int(group) except ValueError: try: - gid = grp.getgrnam(opts.group).gr_gid + gid = grp.getgrnam(group).gr_gid except KeyError: - parser.print_error(_('Unknown group: $opts.group')) + parser.print_error(_('Unknown group: $group')) try: - group_name = grp.getgrgid(gid) + group_name = grp.getgrgid(gid).gr_name except KeyError: - parser.print_error(_('Unknown group: $opts.group')) + parser.print_error(_('Unknown group: $group')) # Process the .in file and write it to Defaults.py. - processed = raw.safe_substitute(runtime_dir=opts.runtime_dir, + processed = raw.safe_substitute(runtime_dir=runtime_dir, user_name=user_name, group_name=group_name) with open(out_file_path, 'w') as fp: fp.write(processed) # XXX Do --permchecks # XXX Do --language + + + +def main(): + parser, opts, args = parseargs() + instantiate(opts.user, opts.group, opts.runtime_dir) diff --git a/Mailman/configuration.py b/Mailman/configuration.py index 1943b3495..a8ecdae84 100644 --- a/Mailman/configuration.py +++ b/Mailman/configuration.py @@ -71,6 +71,7 @@ class Configuration(object): self.add_qrunner(name) # Attempt our first choice path = os.path.abspath(os.path.expanduser(filename)) + print 'path:', path try: execfile(path, ns, ns) self.filename = path diff --git a/Mailman/versions.py b/Mailman/versions.py index d0e548d6c..8052db346 100644 --- a/Mailman/versions.py +++ b/Mailman/versions.py @@ -35,10 +35,10 @@ run again until another version change is detected. import email import logging -from Mailman import mm_cfg from Mailman import Message from Mailman import Utils from Mailman.MemberAdaptor import UNKNOWN +from Mailman.configuration import config log = logging.getLogger('mailman.error') @@ -101,7 +101,7 @@ def UpdateOldVars(l, stored_state): # Migrate to 2.1b3, baw 13-Oct-2001 # Basic defaults for new variables if not hasattr(l, 'default_member_moderation'): - l.default_member_moderation = mm_cfg.DEFAULT_DEFAULT_MEMBER_MODERATION + l.default_member_moderation = config.DEFAULT_DEFAULT_MEMBER_MODERATION if not hasattr(l, 'accept_these_nonmembers'): l.accept_these_nonmembers = [] if not hasattr(l, 'hold_these_nonmembers'): @@ -111,9 +111,9 @@ def UpdateOldVars(l, stored_state): if not hasattr(l, 'discard_these_nonmembers'): l.discard_these_nonmembers = [] if not hasattr(l, 'forward_auto_discards'): - l.forward_auto_discards = mm_cfg.DEFAULT_FORWARD_AUTO_DISCARDS + l.forward_auto_discards = config.DEFAULT_FORWARD_AUTO_DISCARDS if not hasattr(l, 'generic_nonmember_action'): - l.generic_nonmember_action = mm_cfg.DEFAULT_GENERIC_NONMEMBER_ACTION + l.generic_nonmember_action = config.DEFAULT_GENERIC_NONMEMBER_ACTION # Now convert what we can... Note that the interaction between the # MM2.0.x attributes `moderated', `member_posting_only', and `posters' is # so confusing, it makes my brain really ache. Which is why they go away @@ -177,7 +177,7 @@ def UpdateOldVars(l, stored_state): if not l.isMember(addr): l.accept_these_nonmembers.append(addr) for member in l.getMembers(): - l.setMemberOption(member, mm_cfg.Moderate, + l.setMemberOption(member, config.Moderate, # reset for explicitly named members member not in l.posters) l.generic_nonmember_action = 1 @@ -187,12 +187,12 @@ def UpdateOldVars(l, stored_state): if not l.isMember(addr): l.accept_these_nonmembers.append(addr) for member in l.getMembers(): - l.setMemberOption(member, mm_cfg.Moderate, 0) + l.setMemberOption(member, config.Moderate, 0) l.generic_nonmember_action = 1 l.default_member_moderation = 0 elif not l.posters: for member in l.getMembers(): - l.setMemberOption(member, mm_cfg.Moderate, 0) + l.setMemberOption(member, config.Moderate, 0) l.generic_nonmember_action = 0 l.default_member_moderation = 0 else: @@ -200,7 +200,7 @@ def UpdateOldVars(l, stored_state): if not l.isMember(addr): l.accept_these_nonmembers.append(addr) for member in l.getMembers(): - l.setMemberOption(member, mm_cfg.Moderate, + l.setMemberOption(member, config.Moderate, # reset for explicitly named members member not in l.posters) l.generic_nonmember_action = 1 @@ -216,14 +216,14 @@ def UpdateOldVars(l, stored_state): forbiddens = l.forbidden_posters for addr in forbiddens: if l.isMember(addr): - l.setMemberOption(addr, mm_cfg.Moderate, 1) + l.setMemberOption(addr, config.Moderate, 1) else: l.hold_these_nonmembers.append(addr) del l.forbidden_posters # Migrate to 1.0b6, klm 10/22/1998: PreferStored('reminders_to_admins', 'umbrella_list', - mm_cfg.DEFAULT_UMBRELLA_LIST) + config.DEFAULT_UMBRELLA_LIST) # Migrate up to 1.0b5: PreferStored('auto_subscribe', 'open_subscribe') @@ -234,7 +234,7 @@ def UpdateOldVars(l, stored_state): PreferStored('automatically_remove', 'automatic_bounce_action') if hasattr(l, "open_subscribe"): if l.open_subscribe: - if mm_cfg.ALLOW_OPEN_SUBSCRIBE: + if config.ALLOW_OPEN_SUBSCRIBE: l.subscribe_policy = 0 else: l.subscribe_policy = 1 @@ -242,10 +242,10 @@ def UpdateOldVars(l, stored_state): l.subscribe_policy = 2 # admin approval delattr(l, "open_subscribe") if not hasattr(l, "administrivia"): - setattr(l, "administrivia", mm_cfg.DEFAULT_ADMINISTRIVIA) + setattr(l, "administrivia", config.DEFAULT_ADMINISTRIVIA) if not hasattr(l, "admin_member_chunksize"): setattr(l, "admin_member_chunksize", - mm_cfg.DEFAULT_ADMIN_MEMBER_CHUNKSIZE) + config.DEFAULT_ADMIN_MEMBER_CHUNKSIZE) # # this attribute was added then deleted, so there are a number of # cases to take care of @@ -282,7 +282,7 @@ def UpdateOldVars(l, stored_state): # if not hasattr(l, "admin_notify_mchanges"): setattr(l, "admin_notify_mchanges", - mm_cfg.DEFAULT_ADMIN_NOTIFY_MCHANGES) + config.DEFAULT_ADMIN_NOTIFY_MCHANGES) # # Convert the members and digest_members addresses so that the keys of # both these are always lowercased, but if there is a case difference, the @@ -336,10 +336,10 @@ def NewVars(l): add_only_if_missing('postings_responses', {}) add_only_if_missing('admin_responses', {}) add_only_if_missing('reply_goes_to_list', '') - add_only_if_missing('preferred_language', mm_cfg.DEFAULT_SERVER_LANGUAGE) + add_only_if_missing('preferred_language', config.DEFAULT_SERVER_LANGUAGE) add_only_if_missing('available_languages', []) add_only_if_missing('digest_volume_frequency', - mm_cfg.DEFAULT_DIGEST_VOLUME_FREQUENCY) + config.DEFAULT_DIGEST_VOLUME_FREQUENCY) add_only_if_missing('digest_last_sent_at', 0) add_only_if_missing('mod_password', None) add_only_if_missing('moderator', []) @@ -350,46 +350,46 @@ def NewVars(l): add_only_if_missing('usernames', {}) add_only_if_missing('personalize', 0) add_only_if_missing('first_strip_reply_to', - mm_cfg.DEFAULT_FIRST_STRIP_REPLY_TO) + config.DEFAULT_FIRST_STRIP_REPLY_TO) add_only_if_missing('subscribe_auto_approval', - mm_cfg.DEFAULT_SUBSCRIBE_AUTO_APPROVAL) + config.DEFAULT_SUBSCRIBE_AUTO_APPROVAL) add_only_if_missing('unsubscribe_policy', - mm_cfg.DEFAULT_UNSUBSCRIBE_POLICY) - add_only_if_missing('send_goodbye_msg', mm_cfg.DEFAULT_SEND_GOODBYE_MSG) + config.DEFAULT_UNSUBSCRIBE_POLICY) + add_only_if_missing('send_goodbye_msg', config.DEFAULT_SEND_GOODBYE_MSG) add_only_if_missing('include_rfc2369_headers', 1) add_only_if_missing('include_list_post_header', 1) add_only_if_missing('bounce_score_threshold', - mm_cfg.DEFAULT_BOUNCE_SCORE_THRESHOLD) + config.DEFAULT_BOUNCE_SCORE_THRESHOLD) add_only_if_missing('bounce_info_stale_after', - mm_cfg.DEFAULT_BOUNCE_INFO_STALE_AFTER) + config.DEFAULT_BOUNCE_INFO_STALE_AFTER) add_only_if_missing('bounce_you_are_disabled_warnings', - mm_cfg.DEFAULT_BOUNCE_YOU_ARE_DISABLED_WARNINGS) + config.DEFAULT_BOUNCE_YOU_ARE_DISABLED_WARNINGS) add_only_if_missing( 'bounce_you_are_disabled_warnings_interval', - mm_cfg.DEFAULT_BOUNCE_YOU_ARE_DISABLED_WARNINGS_INTERVAL) + config.DEFAULT_BOUNCE_YOU_ARE_DISABLED_WARNINGS_INTERVAL) add_only_if_missing( 'bounce_unrecognized_goes_to_list_owner', - mm_cfg.DEFAULT_BOUNCE_UNRECOGNIZED_GOES_TO_LIST_OWNER) + config.DEFAULT_BOUNCE_UNRECOGNIZED_GOES_TO_LIST_OWNER) add_only_if_missing( 'bounce_notify_owner_on_disable', - mm_cfg.DEFAULT_BOUNCE_NOTIFY_OWNER_ON_DISABLE) + config.DEFAULT_BOUNCE_NOTIFY_OWNER_ON_DISABLE) add_only_if_missing( 'bounce_notify_owner_on_removal', - mm_cfg.DEFAULT_BOUNCE_NOTIFY_OWNER_ON_REMOVAL) + config.DEFAULT_BOUNCE_NOTIFY_OWNER_ON_REMOVAL) add_only_if_missing('ban_list', []) - add_only_if_missing('filter_mime_types', mm_cfg.DEFAULT_FILTER_MIME_TYPES) - add_only_if_missing('pass_mime_types', mm_cfg.DEFAULT_PASS_MIME_TYPES) - add_only_if_missing('filter_content', mm_cfg.DEFAULT_FILTER_CONTENT) + add_only_if_missing('filter_mime_types', config.DEFAULT_FILTER_MIME_TYPES) + add_only_if_missing('pass_mime_types', config.DEFAULT_PASS_MIME_TYPES) + add_only_if_missing('filter_content', config.DEFAULT_FILTER_CONTENT) add_only_if_missing('convert_html_to_plaintext', - mm_cfg.DEFAULT_CONVERT_HTML_TO_PLAINTEXT) - add_only_if_missing('filter_action', mm_cfg.DEFAULT_FILTER_ACTION) + config.DEFAULT_CONVERT_HTML_TO_PLAINTEXT) + add_only_if_missing('filter_action', config.DEFAULT_FILTER_ACTION) add_only_if_missing('delivery_status', {}) - # This really ought to default to mm_cfg.HOLD, but that doesn't work with + # This really ought to default to config.HOLD, but that doesn't work with # the current GUI description model. So, 0==Hold, 1==Reject, 2==Discard add_only_if_missing('member_moderation_action', 0) add_only_if_missing('member_moderation_notice', '') add_only_if_missing('new_member_options', - mm_cfg.DEFAULT_NEW_MEMBER_OPTIONS) + config.DEFAULT_NEW_MEMBER_OPTIONS) # Emergency moderation flag add_only_if_missing('emergency', 0) add_only_if_missing('hold_and_cmd_autoresponses', {}) @@ -406,14 +406,14 @@ def NewVars(l): add_only_if_missing('scrub_nondigest', 0) # ContentFilter by file extensions add_only_if_missing('filter_filename_extensions', - mm_cfg.DEFAULT_FILTER_FILENAME_EXTENSIONS) + config.DEFAULT_FILTER_FILENAME_EXTENSIONS) add_only_if_missing('pass_filename_extensions', []) # automatic discard add_only_if_missing('max_days_to_hold', 0) add_only_if_missing('nonmember_rejection_notice', '') # multipart/alternative collapse add_only_if_missing('collapse_alternatives', - mm_cfg.DEFAULT_COLLAPSE_ALTERNATIVES) + config.DEFAULT_COLLAPSE_ALTERNATIVES) @@ -463,10 +463,10 @@ def CanonicalizeUserOptions(l): # member address. This is likely caused by an earlier bug. del l.user_options[k] continue - if l.getMemberOption(k, mm_cfg.DisableDelivery): + if l.getMemberOption(k, config.DisableDelivery): # Convert this flag into a legacy disable l.setDeliveryStatus(k, UNKNOWN) - l.setMemberOption(k, mm_cfg.DisableDelivery, 0) + l.setMemberOption(k, config.DisableDelivery, 0) l.useropts_version = 1 @@ -509,7 +509,7 @@ def NewRequestsDatabase(l): # See the note above; the same holds true. for ign, ign, digest, addr, password in v: l.HoldSubscription(addr, '', password, digest, - mm_cfg.DEFAULT_SERVER_LANGUAGE) + config.DEFAULT_SERVER_LANGUAGE) del r[k] else: log.error("""\ @@ -30,6 +30,16 @@ if sys.hexversion < 0x20500f0: +scripts = ['%(script)s = Mailman.bin.%(script)s:main' % dict(script=script) + for script in ( + 'make_instance', + 'testall', + 'withlist', + ) + ] + + + setup( name = 'mailman', version = __version__, @@ -45,6 +55,18 @@ Any other spelling is incorrect.""", url = 'http://www.list.org', keywords = 'email', packages = find_packages(), + # Executable scripts + entry_points = { + 'console_scripts': scripts, + }, + # Third-party requirements. + install_requires = [ + 'Elixir', + 'SQLAlchemy', + 'munepy', + 'wsgiref', + 'zope.interface', + ], # Optionally use 'nose' for unit test sniffing. extras_require = { 'nose': ['nose'], |
