summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbwarsaw2001-07-19 06:28:54 +0000
committerbwarsaw2001-07-19 06:28:54 +0000
commit9bc05f949e59ad9cf18c2498f782a4b2308e4638 (patch)
tree10f6aa2589ebdd819fdbdcd2aa1f5c8597e31680
parent682de59eda6ccc5f2e0268d5be36e93731d77cf1 (diff)
downloadmailman-9bc05f949e59ad9cf18c2498f782a4b2308e4638.tar.gz
mailman-9bc05f949e59ad9cf18c2498f782a4b2308e4638.tar.zst
mailman-9bc05f949e59ad9cf18c2498f782a4b2308e4638.zip
-rw-r--r--Mailman/Gui/Archive.py42
-rw-r--r--Mailman/Gui/Autoresponse.py80
-rw-r--r--Mailman/Gui/Bounce.py54
-rw-r--r--Mailman/Gui/Digest.py81
-rw-r--r--Mailman/Gui/General.py316
-rw-r--r--Mailman/Gui/Makefile.in69
-rw-r--r--Mailman/Gui/Membership.py34
-rw-r--r--Mailman/Gui/NonDigest.py52
-rw-r--r--Mailman/Gui/Privacy.py224
-rw-r--r--Mailman/Gui/Topics.py146
-rw-r--r--Mailman/Gui/Usenet.py60
-rw-r--r--Mailman/Gui/__init__.py26
12 files changed, 1184 insertions, 0 deletions
diff --git a/Mailman/Gui/Archive.py b/Mailman/Gui/Archive.py
new file mode 100644
index 000000000..b605b99b5
--- /dev/null
+++ b/Mailman/Gui/Archive.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2001 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+from Mailman import mm_cfg
+from Mailman.i18n import _
+
+
+
+class Archive:
+ def GetConfigCategory(self):
+ return 'archive', _('Archiving Options')
+
+ def GetConfigInfo(self, mlist):
+ return [
+ _("List traffic archival policies."),
+
+ ('archive', mm_cfg.Toggle, (_('No'), _('Yes')), 0,
+ _('Archive messages?')),
+
+ ('archive_private', mm_cfg.Radio, (_('public'), _('private')), 0,
+ _('Is archive file source for public or private archival?')),
+
+ ('archive_volume_frequency', mm_cfg.Radio,
+ (_('Yearly'), _('Monthly'), _('Quarterly'),
+ _('Weekly'), _('Daily')),
+ 0,
+ _('How often should a new archive volume be started?')),
+ ]
+
diff --git a/Mailman/Gui/Autoresponse.py b/Mailman/Gui/Autoresponse.py
new file mode 100644
index 000000000..b19eff28f
--- /dev/null
+++ b/Mailman/Gui/Autoresponse.py
@@ -0,0 +1,80 @@
+# Copyright (C) 2001 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+"""Administrative GUI for the autoresponder."""
+
+from Mailman import mm_cfg
+from Mailman.i18n import _
+
+
+
+class Autoresponse:
+ def GetConfigCategory(self):
+ return 'autoreply', _('Auto-responder')
+
+ def GetConfigInfo(self, mlist):
+ WIDTH = mm_cfg.TEXTFIELDWIDTH
+
+ return [
+ _("""\
+Auto-responder characteristics.<p>
+
+In the text fields below, Python %(string)s interpolation is performed with
+the following key/value substitutions:
+<p><ul>
+ <li><b>%(listname)s</b> - <em>gets the name of the mailing list</em>
+ <li><b>%(listurl)s</b> - <em>gets the list's listinfo URL</em>
+ <li><b>%(requestemail)s</b> - <em>gets the list's -request address</em>
+ <li><b>%(adminemail)s</b> - <em>gets the list's -admin address</em>
+ <li><b>%(owneremail)s</b> - <em>gets the list's -owner address</em>
+</ul>
+
+<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,
+ _('''Should Mailman send an auto-response to mailing list
+ posters?''')),
+
+ ('autoresponse_postings_text', mm_cfg.FileUpload,
+ (6, WIDTH), 0,
+ _('Auto-response text to send to mailing list posters.')),
+
+ ('autorespond_admin', mm_cfg.Toggle, ('No', 'Yes'), 0,
+ _('''Should Mailman send an auto-response to emails sent to the
+ -admin and -owner addresses?''')),
+
+ ('autoresponse_admin_text', mm_cfg.FileUpload,
+ (6, WIDTH), 0,
+ _('Auto-response text to send to -admin and -owner emails.')),
+
+ ('autorespond_requests', mm_cfg.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,
+ (6, WIDTH), 0,
+ _('Auto-response text to send to -request emails.')),
+
+ ('autoresponse_graceperiod', mm_cfg.Number, 3, 0,
+ _('''Number of days between auto-responses to either the mailing
+ list or -admin/-owner address from the same poster. Set to zero
+ (or negative) for no grace period (i.e. auto-respond to every
+ message).''')),
+ ]
diff --git a/Mailman/Gui/Bounce.py b/Mailman/Gui/Bounce.py
new file mode 100644
index 000000000..54d56647c
--- /dev/null
+++ b/Mailman/Gui/Bounce.py
@@ -0,0 +1,54 @@
+# Copyright (C) 2001 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+from Mailman import mm_cfg
+from Mailman.i18n import _
+
+
+
+class Bounce:
+ def GetConfigCategory(self):
+ return 'bounce', _('Bounce detection')
+
+ def GetConfigInfo(self, mlist):
+ return [
+ _('''Policies regarding systematic processing of bounce messages,
+ to help automate recognition and handling of defunct
+ addresses.'''),
+
+ ('bounce_processing', mm_cfg.Toggle, (_('No'), _('Yes')), 0,
+ _('Try to figure out error messages automatically?')),
+
+ ('minimum_removal_date', mm_cfg.Number, 3, 0,
+ _('''Minimum number of days an address has been non-fatally bad
+ before we take action''')),
+
+ ('minimum_post_count_before_bounce_action', mm_cfg.Number, 3, 0,
+ _('''Minimum number of posts to the list since members first
+ bounce before we consider removing them from the list''')),
+
+ ('max_posts_between_bounces', mm_cfg.Number, 3, 0,
+ _('''Maximum number of messages your list gets in an hour. (Yes,
+ bounce detection finds this info useful)''')),
+
+ ('automatic_bounce_action', mm_cfg.Radio,
+ (_("Do nothing"),
+ _("Disable and notify me"),
+ _("Disable and DON'T notify me"),
+ _("Remove and notify me")),
+ 0,
+ _("Action when critical or excessive bounces are detected."))
+ ]
diff --git a/Mailman/Gui/Digest.py b/Mailman/Gui/Digest.py
new file mode 100644
index 000000000..053e8ef52
--- /dev/null
+++ b/Mailman/Gui/Digest.py
@@ -0,0 +1,81 @@
+# Copyright (C) 1998,1999,2000,2001 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+"""Administrative GUI for digest deliveries."""
+
+from Mailman import mm_cfg
+from Mailman import Utils
+from Mailman.i18n import _
+
+
+
+class Digest:
+ def GetConfigCategory(self):
+ return 'digest', _('Digest options')
+
+ def GetConfigInfo(self, mlist):
+ WIDTH = mm_cfg.TEXTFIELDWIDTH
+
+ return [
+ _("Batched-delivery digest characteristics."),
+
+ ('digestable', mm_cfg.Toggle, (_('No'), _('Yes')), 1,
+ _('Can list members choose to receive list traffic '
+ 'bunched in digests?')),
+
+ ('digest_is_default', mm_cfg.Radio,
+ (_('Regular'), _('Digest')), 0,
+ _('Which delivery mode is the default for new users?')),
+
+ ('mime_is_default_digest', mm_cfg.Radio,
+ (_('Plain'), _('MIME')), 0,
+ _('When receiving digests, which format is default?')),
+
+ ('digest_size_threshhold', mm_cfg.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,
+ _('Should a digest be dispatched daily when the size threshold '
+ "isn't reached?")),
+
+ ('digest_header', mm_cfg.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,
+ _('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,
+ (_('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,
+ _('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,
+ _('''Should Mailman send the next digest right now, if it is not
+ empty?''')),
+ ]
diff --git a/Mailman/Gui/General.py b/Mailman/Gui/General.py
new file mode 100644
index 000000000..bb08a3957
--- /dev/null
+++ b/Mailman/Gui/General.py
@@ -0,0 +1,316 @@
+# Copyright (C) 2001 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+"""MailList mixin class managing the general options.
+"""
+
+from Mailman import mm_cfg
+from Mailman import Utils
+from Mailman.i18n import _
+
+
+
+class General:
+ def GetConfigCategory(self):
+ return 'general', _('General Options')
+
+ def GetConfigInfo(self, mlist):
+ WIDTH = mm_cfg.TEXTFIELDWIDTH
+
+ # Set things up for the language choices
+ langs = mlist.GetAvailableLanguages()
+ langnames = [_(Utils.GetLanguageDescr(L)) for L in langs]
+ try:
+ langi = langs.index(mlist.preferred_language)
+ except ValueError:
+ # Someone must have deleted the list's preferred language. Could
+ # be other trouble lurking!
+ langi = 0
+
+ # XXX: Should this text be migrated into the templates dir?
+ return [
+ _("Fundamental list characteristics, including descriptive"
+ " info and basic behaviors."),
+
+ ('real_name', mm_cfg.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
+ acronym part all upper case, etc. However, the name will be
+ advertised as the email address (e.g., in subscribe confirmation
+ notices), so it should <em>not</em> be otherwise altered. (Email
+ addresses are not case sensitive, but they are sensitive to
+ almost everything else :-)''')),
+
+ ('owner', mm_cfg.EmailList, (3, WIDTH), 0,
+ _("""The list administrator email addresses. Multiple
+ administrator addresses, each on separate line is okay."""),
+
+ _("""There are two ownership roles associated with each mailing
+ list. 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 configuration variable available
+ through these administration web pages.
+
+ <p>The <em>list moderators</em> have more limited permissions;
+ they are not able to change any list configuration variable, but
+ they are allowed to tend to pending administration requests,
+ including approving or rejecting held subscription requests, and
+ disposing of held postings. Of course, the <em>list
+ administrators</em> can also tend to pending requests.
+
+ <p>In order to split the list ownership duties into
+ administrators and moderators, you must set a separate moderator
+ password in the section below, and also provide the email
+ addresses of the list moderators in this section. Note that the
+ field you are changing here specifies the list
+ administators.""")),
+
+ ('moderator', mm_cfg.EmailList, (3, WIDTH), 0,
+ _("""The list moderator email addresses. Multiple
+ moderator addresses, each on separate line is okay."""),
+
+ _("""There are two ownership roles associated with each mailing
+ list. 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 configuration variable available
+ through these administration web pages.
+
+ <p>The <em>list moderators</em> have more limited permissions;
+ they are not able to change any list configuration variable, but
+ they are allowed to tend to pending administration requests,
+ including approving or rejecting held subscription requests, and
+ disposing of held postings. Of course, the <em>list
+ administrators</em> can also tend to pending requests.
+
+ <p>In order to split the list ownership duties into
+ administrators and moderators, you must set a separate moderator
+ password in the section below, and also provide the email
+ addresses of the list moderators in this section. Note that the
+ field you are changing here specifies the list moderators.""")),
+
+ ('preferred_language', mm_cfg.Select,
+ (langs, langnames, langi),
+ 0,
+ _('Default language for this list.'),
+ _('''All messages not related to an specific user will be
+ displayed in this language.''')),
+
+ ('description', mm_cfg.String, WIDTH, 0,
+ _('A terse phrase identifying this list.'),
+
+ _('''This description is used when the mailing list is listed with
+ other mailing lists, or in headers, and so forth. It should
+ be as succinct as you can get it, while still identifying what
+ the list is.''')),
+
+ ('info', mm_cfg.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
+ for more info.'''),
+ _("""The text will be treated as html <em>except</em> that
+ newlines will be translated to &lt;br&gt; - so you can use links,
+ preformatted text, etc, but don't put in carriage returns except
+ where you mean to separate paragraphs. And review your changes -
+ bad html (like some unterminated HTML constructs) can prevent
+ display of the entire listinfo page.""")),
+
+ ('subject_prefix', mm_cfg.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
+ mailbox summaries. Brevity is premium here, it's ok to shorten
+ long mailing list names to something more concise, as long as it
+ still identifies the mailing list.""")),
+
+ ('welcome_msg', mm_cfg.Text, (4, WIDTH), 0,
+ _('''List-specific text prepended to new-subscriber welcome
+ message'''),
+
+ _("""This value, if any, will be added to the front of the
+ new-subscriber welcome message. The rest of the welcome message
+ already describes the important addresses and URLs for the
+ mailing list, so you don't need to include any of that kind of
+ stuff here. This should just contain mission-specific kinds of
+ things, like etiquette policies or team orientation, or that kind
+ of thing.
+
+ <p>Note that this text will be wrapped, according to the
+ following rules:
+ <ul><li>Each paragraph is filled so that no line is longer than
+ 70 characters.
+ <li>Any line that begins with whitespace is not filled.
+ <li>A blank line separates paragraphs.
+ </ul>""")),
+
+ ('goodbye_msg', mm_cfg.Text, (4, WIDTH), 0,
+ _('''Text sent to people leaving the list. If empty, no special
+ text will be added to the unsubscribe message.''')),
+
+ ('reply_goes_to_list', mm_cfg.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
+ lists.'''),
+
+ # Details for reply_goes_to_list
+ _("""This option controls what Mailman does to the
+ <tt>Reply-To:</tt> header in messages flowing through this
+ mailing list. When set to <em>Poster</em>, no <tt>Reply-To:</tt>
+ header is added by Mailman, although if one is present in the
+ original message, it is not stripped. Setting this value to
+ either <em>This list</em> or <em>Explicit address</em> causes
+ Mailman to insert a specific <tt>Reply-To:</tt> header in all
+ messages, overriding the header in the original message if
+ necessary (<em>Explicit address</em> inserts the value of <a
+ href="?VARHELP=general/reply_to_address">reply_to_address</a>).
+
+ <p>There are many reasons not to introduce or override the
+ <tt>Reply-To:</tt> header. One is that some posters depend on
+ their own <tt>Reply-To:</tt> settings to convey their valid
+ return address. Another is that modifying <tt>Reply-To:</tt>
+ makes it much more difficult to send private replies. See <a
+ href="http://www.unicom.com/pw/reply-to-harmful.html">`Reply-To'
+ Munging Considered Harmful</a> for a general discussion of this
+ issue. See <a
+ href="http://www.metasystema.org/essays/reply-to-useful.mhtml">Reply-To
+ Munging Considered Useful</a> for a dissenting opinion.
+
+ <p>Some mailing lists have restricted posting privileges, with a
+ parallel list devoted to discussions. Examples are `patches' or
+ `checkin' lists, where software changes are posted by a revision
+ control system, but discussion about the changes occurs on a
+ developers mailing list. To support these types of mailing
+ lists, select <tt>Explicit address</tt> and set the
+ <tt>Reply-To:</tt> address below to point to the parallel
+ list.""")),
+
+ ('reply_to_address', mm_cfg.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
+ when the <a
+ href="?VARHELP=general/reply_goes_to_list">reply_goes_to_list</a>
+ option is set to <em>Explicit address</em>.
+
+ <p>There are many reasons not to introduce or override the
+ <tt>Reply-To:</tt> header. One is that some posters depend on
+ their own <tt>Reply-To:</tt> settings to convey their valid
+ return address. Another is that modifying <tt>Reply-To:</tt>
+ makes it much more difficult to send private replies. See <a
+ href="http://www.unicom.com/pw/reply-to-harmful.html">`Reply-To'
+ Munging Considered Harmful</a> for a general discussion of this
+ issue. See <a
+ href="http://www.metasystema.org/essays/reply-to-useful.mhtml">Reply-To
+ Munging Considered Useful</a> for a dissenting opinion.
+
+ <p>Some mailing lists have restricted posting privileges, with a
+ parallel list devoted to discussions. Examples are `patches' or
+ `checkin' lists, where software changes are posted by a revision
+ control system, but discussion about the changes occurs on a
+ developers mailing list. To support these types of mailing
+ lists, specify the explicit <tt>Reply-To:</tt> address here. You
+ must also specify <tt>Explicit address</tt> in the
+ <tt>reply_goes_to_list</tt>
+ variable.
+
+ <p>Note that if the original message contains a
+ <tt>Reply-To:</tt> header, it will not be changed.""")),
+
+ ('administrivia', mm_cfg.Radio, (_('No'), _('Yes')), 0,
+ _('''(Administrivia filter) Check postings and intercept ones
+ that seem to be administrative requests?'''),
+
+ _("""Administrivia tests will check postings to see whether it's
+ really meant as an administrative request (like subscribe,
+ unsubscribe, etc), and will add it to the the administrative
+ requests queue, notifying the administrator of the new request,
+ in the process.""")),
+
+ ('umbrella_list', mm_cfg.Radio, (_('No'), _('Yes')), 0,
+ _('''Send password reminders to, eg, "-owner" address instead of
+ directly to user.'''),
+
+ _("""Set this to yes when this list is intended to cascade only
+ to other mailing lists. When set, meta notices like
+ confirmations and password reminders will be directed to an
+ address derived from the member\'s address - it will have the
+ value of "umbrella_member_suffix" appended to the member's
+ account name.""")),
+
+ ('umbrella_member_suffix', mm_cfg.String, WIDTH, 0,
+ _('''Suffix for use when this list is an umbrella for other
+ lists, according to setting of previous "umbrella_list"
+ setting.'''),
+
+ _("""When "umbrella_list" is set to indicate that this list has
+ other mailing lists as members, then administrative notices like
+ confirmations and password reminders need to not be sent to the
+ member list addresses, but rather to the owner of those member
+ lists. In that case, the value of this setting is appended to
+ the member's account name for such notices. `-owner' is the
+ typical choice. This setting has no effect when "umbrella_list"
+ is "No".""")),
+
+ ('send_reminders', mm_cfg.Radio, (_('No'), _('Yes')), 0,
+ _('''Send monthly password reminders or no? Overrides the
+ previous option.''')),
+
+ ('send_welcome_msg', mm_cfg.Radio, (_('No'), _('Yes')), 0,
+ _('Send welcome message when people subscribe?'),
+ _("""Turn this on 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.""")),
+
+ ('admin_immed_notify', mm_cfg.Radio, (_('No'), _('Yes')), 0,
+ _('''Should administrator get immediate notice of new requests,
+ as well as daily notices about collected ones?'''),
+
+ _('''List admins are sent daily reminders of pending admin
+ approval requests, like subscriptions to a moderated list or
+ postings that are being held for one reason or 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,
+ _('''Should administrator get notices of subscribes and
+ unsubscribes?''')),
+
+ ('dont_respond_to_post_requests', mm_cfg.Radio,
+ (_('Yes'), _('No')), 0,
+ _('Send mail to poster when their posting is held for approval?'),
+
+ _("""Approval notices are sent when mail triggers certain of the
+ limits <em>except</em> routine list moderation and spam filters,
+ for which notices are <em>not</em> sent. This option overrides
+ ever sending the notice.""")),
+
+ ('max_message_size', mm_cfg.Number, 7, 0,
+ _('''Maximum length in Kb of a message body. Use 0 for no
+ limit.''')),
+
+ ('host_name', mm_cfg.Host, WIDTH, 0,
+ _('Host name this list prefers for email.'),
+
+ _("""The "host_name" is the preferred name for email to
+ mailman-related addresses on this host, and generally should be
+ the mail host's exchanger address, if any. This setting can be
+ useful for selecting among alternative names of a host that has
+ multiple addresses.""")),
+
+ ]
diff --git a/Mailman/Gui/Makefile.in b/Mailman/Gui/Makefile.in
new file mode 100644
index 000000000..6f4781762
--- /dev/null
+++ b/Mailman/Gui/Makefile.in
@@ -0,0 +1,69 @@
+# Copyright (C) 2000 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# NOTE: Makefile.in is converted into Makefile by the configure script
+# in the parent directory. Once configure has run, you can recreate
+# the Makefile by running just config.status.
+
+# Variables set by configure
+
+VPATH= @srcdir@
+srcdir= @srcdir@
+bindir= @bindir@
+prefix= @prefix@
+exec_prefix= @exec_prefix@
+
+CC= @CC@
+CHMOD= @CHMOD@
+INSTALL= @INSTALL@
+
+DEFS= @DEFS@
+
+# Customizable but not set by configure
+
+OPT= @OPT@
+CFLAGS= $(OPT) $(DEFS)
+PACKAGEDIR= $(prefix)/Mailman/Gui
+SHELL= /bin/sh
+
+MODULES= *.py
+
+# Modes for directories and executables created by the install
+# process. Default to group-writable directories but
+# user-only-writable for executables.
+DIRMODE= 775
+EXEMODE= 755
+FILEMODE= 644
+INSTALL_PROGRAM=$(INSTALL) -m $(EXEMODE)
+
+
+# Rules
+
+all:
+
+install:
+ for f in $(MODULES); \
+ do \
+ $(INSTALL) -m $(FILEMODE) $$f $(PACKAGEDIR); \
+ done
+
+finish:
+
+clean:
+
+distclean:
+ -rm *.pyc
+ -rm Makefile
diff --git a/Mailman/Gui/Membership.py b/Mailman/Gui/Membership.py
new file mode 100644
index 000000000..a688faaa3
--- /dev/null
+++ b/Mailman/Gui/Membership.py
@@ -0,0 +1,34 @@
+# Copyright (C) 2001 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+"""MailList mixin class managing the membership pseudo-options.
+"""
+
+from Mailman.i18n import _
+
+
+
+class Membership:
+ def GetConfigCategory(self):
+ return 'members', _('Membership Management')
+
+ def GetConfigSubCategories(self, category):
+ if category == 'members':
+ return [('list', _('Membership List')),
+ ('add', _('Mass Subscription')),
+ ('remove', _('Mass Removal')),
+ ]
+ return None
diff --git a/Mailman/Gui/NonDigest.py b/Mailman/Gui/NonDigest.py
new file mode 100644
index 000000000..e6c4c4525
--- /dev/null
+++ b/Mailman/Gui/NonDigest.py
@@ -0,0 +1,52 @@
+# Copyright (C) 2001 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+"""MailList mixin class managing the non-digest delivery options.
+"""
+
+from Mailman import mm_cfg
+from Mailman import Utils
+from Mailman.i18n import _
+
+
+
+class NonDigest:
+ def GetConfigCategory(self):
+ return 'nondigest', _('Non-digest delivery options')
+
+ def GetConfigInfo(self, mlist):
+ WIDTH = mm_cfg.TEXTFIELDWIDTH
+
+ return [
+ _("Policies concerning immediately delivered list traffic."),
+
+ ('nondigestable', mm_cfg.Toggle, (_('No'), _('Yes')), 1,
+ _("""Can subscribers choose to receive mail immediately, rather
+ than in batched digests?""")),
+
+ ('msg_header', mm_cfg.Text, (4, WIDTH), 0,
+ _('Header added to mail sent to regular list members'),
+ _('''Text prepended to the top of every immediately-delivery
+ message. ''') + Utils.maketext('headfoot.html',
+ mlist=mlist, raw=1)),
+
+ ('msg_footer', mm_cfg.Text, (4, WIDTH), 0,
+ _('Footer added to mail sent to regular list members'),
+ _('''Text appended to the bottom of every immediately-delivery
+ message. ''') + Utils.maketext('headfoot.html',
+ mlist=mlist, raw=1)),
+ ]
+
diff --git a/Mailman/Gui/Privacy.py b/Mailman/Gui/Privacy.py
new file mode 100644
index 000000000..3f98c9676
--- /dev/null
+++ b/Mailman/Gui/Privacy.py
@@ -0,0 +1,224 @@
+# Copyright (C) 2001 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+"""MailList mixin class managing the privacy options.
+"""
+
+from Mailman import mm_cfg
+from Mailman.i18n import _
+
+
+
+class Privacy:
+ def GetConfigCategory(self):
+ return 'privacy', _('Privacy Options')
+
+ def GetConfigInfo(self, mlist):
+ WIDTH = mm_cfg.TEXTFIELDWIDTH
+
+ if mm_cfg.ALLOW_OPEN_SUBSCRIBE:
+ sub_cfentry = ('subscribe_policy', mm_cfg.Radio,
+ # choices
+ (_('none'),
+ _('confirm'),
+ _('require approval'),
+ _('confirm+approval')),
+ 0,
+ _('What steps are required for subscription?<br>'),
+ _('''None - no verification steps (<em>Not
+ Recommended </em>)<br>
+ confirm (*) - email confirmation step required <br>
+ require approval - require list administrator
+ approval for subscriptions <br>
+ confirm+approval - both confirm and approve
+
+ <p>(*) when someone requests a subscription,
+ Mailman sends them a notice with a unique
+ subscription request number that they must reply to
+ in order to subscribe.<br>
+
+ This prevents mischievous (or malicious) people
+ from creating subscriptions for others without
+ their consent.'''))
+ else:
+ sub_cfentry = ('subscribe_policy', mm_cfg.Radio,
+ # choices
+ (_('confirm'),
+ _('require approval'),
+ _('confirm+approval')),
+ 1,
+ _('What steps are required for subscription?<br>'),
+ _('''confirm (*) - email confirmation required <br>
+ require approval - require list administrator
+ approval for subscriptions <br>
+ confirm+approval - both confirm and approve
+
+ <p>(*) when someone requests a subscription,
+ Mailman sends them a notice with a unique
+ subscription request number that they must reply to
+ in order to subscribe.<br> This prevents
+ mischievous (or malicious) people from creating
+ subscriptions for others without their consent.'''))
+
+ # some helpful values
+ adminurl = self.GetScriptURL('admin')
+
+ return [
+ _("""List access policies, including anti-spam measures, covering
+ members and outsiders. See also the <a
+ href="%(admin)s/archive">Archival Options section</a> for separate
+ archive-privacy settings."""),
+
+ _('Subscribing'),
+ ('advertised', mm_cfg.Radio, (_('No'), _('Yes')), 0,
+ _('''Advertise this list when people ask what lists are on this
+ machine?''')),
+
+ sub_cfentry,
+
+ _("Membership exposure"),
+ ('private_roster', mm_cfg.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,
+ _("""Show member addrs so they're not directly recognizable as
+ email addrs?"""),
+ _("""Setting this option causes member email addresses to be
+ transformed when they are presented on list web pages (both in
+ text and as links), so they're not trivially recognizable as
+ email addresses. The intention is to to prevent the addresses
+ from being snarfed up by automated web scanners for use by
+ spammers.""")),
+
+ _("General posting filters"),
+ ('moderated', mm_cfg.Radio, (_('No'), _('Yes')), 0,
+ _('Must posts be approved by an administrator?')),
+
+ ('member_posting_only', mm_cfg.Radio, (_('No'), _('Yes')), 0,
+ _("""Restrict posting privilege to list members?
+ (<i>member_posting_only</i>)"""),
+
+ _("""Use this option if you want to restrict posting to list
+ members. If you want list members to be able to post, plus a
+ handful of other posters, see the <i> posters </i> setting
+ below.""")),
+
+ ('posters', mm_cfg.EmailList, (5, WIDTH), 1,
+ _('''Addresses of members accepted for posting to this list
+ without implicit approval requirement. (See "Restrict ... to list
+ members" for whether or not this is in addition to allowing
+ posting by list members'''),
+
+ _("""Adding entries here will have one of two effects, according
+ to whether another option restricts posting to members.
+
+ <ul>
+ <li>If <i>member_posting_only</i> is 'yes', then entries
+ added here will have posting privilege in addition to list
+ members.
+
+ <li>If <i>member_posting_only</i> is 'no', then <em>only</em>
+ the posters listed here will be able to post without admin
+ approval.
+
+ </ul>""")),
+
+ _("Spam-specific posting filters"),
+
+ ('require_explicit_destination', mm_cfg.Radio,
+ (_('No'), _('Yes')), 0,
+ _("""Must posts have list named in destination (to, cc) field
+ (or be among the acceptable alias names, specified below)?"""),
+
+ _("""Many (in fact, most) spams do not explicitly name their
+ myriad destinations in the explicit destination addresses - in
+ fact often the To: field has a totally bogus address for
+ obfuscation. The constraint applies only to the stuff in the
+ address before the '@' sign, but still catches all such spams.
+
+ <p>The cost is that the list will not accept unhindered any
+ postings relayed from other addresses, unless
+
+ <ol>
+ <li>The relaying address has the same name, or
+
+ <li>The relaying address name is included on the options that
+ specifies acceptable aliases for the list.
+
+ </ol>""")),
+
+ ('acceptable_aliases', mm_cfg.Text, (4, WIDTH), 0,
+ _("""Alias names (regexps) which qualify as explicit to or cc
+ destination names for this list."""),
+
+ _("""Alternate addresses that are acceptable when
+ `require_explicit_destination' is enabled. This option takes a
+ list of regular expressions, one per line, which is matched
+ against every recipient address in the message. The matching is
+ performed with Python's re.match() function, meaning they are
+ anchored to the start of the string.
+
+ <p>For backwards compatibility with Mailman 1.1, if the regexp
+ does not contain an `@', then the pattern is matched against just
+ the local part of the recipient address. If that match fails, or
+ if the pattern does contain an `@', then the pattern is matched
+ against the entire recipient address.
+
+ <p>Matching against the local part is deprecated; in a future
+ release, the pattern will always be matched against the entire
+ recipient address.""")),
+
+ ('max_num_recipients', mm_cfg.Number, 5, 0,
+ _('Ceiling on acceptable number of recipients for a posting.'),
+
+ _('''If a posting has this number, or more, of recipients, it is
+ held for admin approval. Use 0 for no ceiling.''')),
+
+ ('forbidden_posters', mm_cfg.EmailList, (5, WIDTH), 1,
+ _('Addresses whose postings are always held for approval.'),
+ _('''Email addresses whose posts should always be held for
+ approval, no matter what other options you have set. See also
+ the subsequent option which applies to arbitrary content of
+ arbitrary headers.''')),
+
+ ('bounce_matching_headers', mm_cfg.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
+ matching against the specified header. The match is done
+ disregarding letter case. Lines beginning with '#' are ignored
+ as comments.
+
+ <p>For example:<pre>to: .*@public.com </pre> says to hold all
+ postings with a <em>To:</em> mail header containing '@public.com'
+ anywhere among the addresses.
+
+ <p>Note that leading whitespace is trimmed from the regexp. This
+ can be circumvented in a number of ways, e.g. by escaping or
+ bracketing it.
+
+ <p> See also the <em>forbidden_posters</em> option for a related
+ mechanism.""")),
+
+ ('anonymous_list', mm_cfg.Radio, (_('No'), _('Yes')), 0,
+ _("""Hide the sender of a message, replacing it with the list
+ address (Removes From, Sender and Reply-To fields)""")),
+ ]
+
diff --git a/Mailman/Gui/Topics.py b/Mailman/Gui/Topics.py
new file mode 100644
index 000000000..251403d1c
--- /dev/null
+++ b/Mailman/Gui/Topics.py
@@ -0,0 +1,146 @@
+# Copyright (C) 2001 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+from Mailman import mm_cfg
+from Mailman.i18n import _
+from Mailman.Logging.Syslog import syslog
+
+
+
+class Topics:
+ def GetConfigCategory(self):
+ return 'topics', _('Topic filters')
+
+ def GetConfigInfo(self, mlist):
+ WIDTH = mm_cfg.TEXTFIELDWIDTH
+
+ return [
+ _('List topic keywords'),
+
+ ('topics_enabled', mm_cfg.Radio, (_('Disabled'), _('Enabled')), 0,
+ _('''Should the topic filter be enabled or disabled?'''),
+
+ _("""The topic filter categorizes each incoming email message
+ according to <a
+ href="http://www.python.org/doc/current/lib/module-re.html">regular
+ expression filters</a> you specify below. If the message's
+ <code>Subject:</code> or <code>Keywords:</code> header contains a
+ match against a topic filter, the message is logically placed
+ into a topic <em>bucket</em>. Each user can then choose to only
+ receive messages from the mailing list for a particular topic
+ bucket (or buckets). Any message not categorized in a topic
+ bucket registered with the user is not delivered to the list.
+
+ <p>Note that this feature only works with regular delivery, not
+ digest delivery.
+
+ <p>The body of the message can also be optionally scanned for
+ <code>Subject:</code> and <code>Keyword:</code> headers, as
+ specified by the <a
+ href="?VARHELP=topics/topics_bodylines_limit">topics_bodylines_limit</a>
+ configuration variable.""")),
+
+ ('topics_bodylines_limit', mm_cfg.Number, 5, 0,
+ _('How many body lines should the topic matcher scan?'),
+
+ _("""The topic matcher will scan this many lines of the message
+ body looking for topic keyword matches. Body scanning stops when
+ either this many lines have been looked at, or a non-header-like
+ body line is encountered. By setting this value to zero, no body
+ lines will be scanned (i.e. only the <code>Keywords:</code> and
+ <code>Subject:</code> headers will be scanned). By setting this
+ value to a negative number, then all body lines will be scanned
+ until a non-header-like line is encountered.
+ """)),
+
+ ('topics', mm_cfg.Topics, 0, 0,
+ _('Topic keywords, one per line, to match against each message.'),
+
+ _("""Each topic keyword is actually a regular expression, which is
+ matched against certain parts of a mail message, specifically the
+ <code>Keywords:</code> and <code>Subject:</code> message headers.
+ Note that the first few lines of the body of the message can also
+ contain a <code>Keywords:</code> and <code>Subject:</code>
+ "header" on which matching is also performed.""")),
+
+ ]
+
+ def HandleForm(self, mlist, cgidata, doc):
+ topics = []
+ # We start i at 1 and keep going until we no longer find items keyed
+ # with the marked tags.
+ i = 1
+ while 1:
+ deltag = 'topic_delete_%02d' % i
+ boxtag = 'topic_box_%02d' % i
+ reboxtag = 'topic_rebox_%02d' % i
+ desctag = 'topic_desc_%02d' % i
+ wheretag = 'topic_where_%02d' % i
+ addtag = 'topic_add_%02d' % i
+ newtag = 'topic_new_%02d' % i
+
+ i += 1
+ # Was this a delete? If so, we can just ignore this entry
+ if cgidata.has_key(deltag):
+ continue
+
+ # Get the data for the current box
+ name = cgidata.getvalue(boxtag)
+ pattern = cgidata.getvalue(reboxtag)
+ desc = cgidata.getvalue(desctag)
+
+ if name is None:
+ # We came to the end of the boxes
+ break
+
+ if cgidata.has_key(newtag) and (not name or not pattern):
+ # This new entry is incomplete. BAW: we should probably warn
+ # about it instead of just dropping it from sight.
+ continue
+
+ # Was this an add item?
+ if cgidata.has_key(addtag):
+ # Where should the new one be added?
+ where = cgidata.getvalue(wheretag)
+ if where == 'before':
+ # Add a new empty topics box before the current one
+ topics.append(('', '', '', 1))
+ topics.append((name, pattern, desc, 0))
+ # Default is to add it after...
+ else:
+ topics.append((name, pattern, desc, 0))
+ topics.append(('', '', '', 1))
+ # Otherwise, just retain this one in the list
+ else:
+ topics.append((name, pattern, desc, 0))
+
+ # Add these topics to the mailing list object, and deal with other
+ # options.
+ mlist.topics = topics
+ try:
+ mlist.topics_enabled = int(cgidata.getvalue(
+ 'topics_enabled',
+ mlist.topics_enabled))
+ except ValueError:
+ # BAW: should really print a warning
+ pass
+ try:
+ mlist.topics_bodylines_limit = int(cgidata.getvalue(
+ 'topics_bodylines_limit',
+ mlist.topics_bodylines_limit))
+ except ValueError:
+ # BAW: should really print a warning
+ pass
diff --git a/Mailman/Gui/Usenet.py b/Mailman/Gui/Usenet.py
new file mode 100644
index 000000000..65d3da4db
--- /dev/null
+++ b/Mailman/Gui/Usenet.py
@@ -0,0 +1,60 @@
+# Copyright (C) 2001 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+from Mailman import mm_cfg
+from Mailman.i18n import _
+
+
+
+class Usenet:
+ def GetConfigCategory(self):
+ return 'gateway', _('Mail &lt;-&gt; News Gateways')
+
+ def GetConfigInfo(self, mlist):
+ WIDTH = mm_cfg.TEXTFIELDWIDTH
+
+ return [
+ _('Mail-to-News and News-to-Mail gateway services.'),
+
+ ('nntp_host', mm_cfg.String, WIDTH, 0,
+ _('''The Internet address of the machine your News server is
+ running on.'''),
+ _('''The News server is not part of Mailman proper. You have to
+ already have access to a NNTP server, and that NNTP server has to
+ recognize the machine this mailing list runs on as a machine
+ capable of reading and posting news.''')),
+
+ ('linked_newsgroup', mm_cfg.String, WIDTH, 0,
+ _('The name of the Usenet group to gateway to and/or from.')),
+
+ ('gateway_to_news', mm_cfg.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,
+ _('''Should new posts to the newsgroup be sent to the mailing
+ list?''')),
+
+ ('_mass_catchup', mm_cfg.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
+ list with the next new message found. All earlier messages on
+ the newsgroup will be ignored. This is as if you were reading
+ the newsgroup yourself, and you marked all current messages as
+ <em>read</em>. By catching up, your mailing list members will
+ not see any of the earlier messages.'''))
+ ]
diff --git a/Mailman/Gui/__init__.py b/Mailman/Gui/__init__.py
new file mode 100644
index 000000000..fca749a6d
--- /dev/null
+++ b/Mailman/Gui/__init__.py
@@ -0,0 +1,26 @@
+# Copyright (C) 2001 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+from Archive import Archive
+from Autoresponse import Autoresponse
+from Bounce import Bounce
+from Digest import Digest
+from General import General
+from Membership import Membership
+from NonDigest import NonDigest
+from Privacy import Privacy
+from Topics import Topics
+from Usenet import Usenet