diff options
| -rw-r--r-- | Mailman/Gui/Archive.py | 42 | ||||
| -rw-r--r-- | Mailman/Gui/Autoresponse.py | 80 | ||||
| -rw-r--r-- | Mailman/Gui/Bounce.py | 54 | ||||
| -rw-r--r-- | Mailman/Gui/Digest.py | 81 | ||||
| -rw-r--r-- | Mailman/Gui/General.py | 316 | ||||
| -rw-r--r-- | Mailman/Gui/Makefile.in | 69 | ||||
| -rw-r--r-- | Mailman/Gui/Membership.py | 34 | ||||
| -rw-r--r-- | Mailman/Gui/NonDigest.py | 52 | ||||
| -rw-r--r-- | Mailman/Gui/Privacy.py | 224 | ||||
| -rw-r--r-- | Mailman/Gui/Topics.py | 146 | ||||
| -rw-r--r-- | Mailman/Gui/Usenet.py | 60 | ||||
| -rw-r--r-- | Mailman/Gui/__init__.py | 26 |
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 <br> - 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 <-> 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 |
