diff options
Diffstat (limited to 'src/web/Gui/Topics.py')
| -rw-r--r-- | src/web/Gui/Topics.py | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/web/Gui/Topics.py b/src/web/Gui/Topics.py new file mode 100644 index 000000000..00df988be --- /dev/null +++ b/src/web/Gui/Topics.py @@ -0,0 +1,162 @@ +# Copyright (C) 2001-2009 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +import re + +from Mailman import Utils +from Mailman.Gui.GUIBase import GUIBase +from Mailman.configuration import config +from Mailman.i18n import _ + +OR = '|' + + + +class Topics(GUIBase): + def GetConfigCategory(self): + return 'topics', _('Topics') + + def GetConfigInfo(self, mlist, category, subcat=None): + if category <> 'topics': + return None + WIDTH = config.TEXTFIELDWIDTH + + return [ + _('List topic keywords'), + + ('topics_enabled', config.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>Keywords:</code> headers, as + specified by the <a + href="?VARHELP=topics/topics_bodylines_limit">topics_bodylines_limit</a> + configuration variable.""")), + + ('topics_bodylines_limit', config.Number, 5, 0, + _('How many body lines should the topic matcher scan?'), + + _("""The topic matcher will scan this many lines of the message + 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', config.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, category, subcat, cgidata, doc): + # MAS: Did we come from the authentication page? + if not cgidata.has_key('topic_box_01'): + return + topics = [] + # We start i at 1 and keep going until we no longer find items keyed + # with the marked tags. + i = 1 + while True: + 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. + doc.addError(_("""Topic specifications require both a name and + a pattern. Incomplete topics will be ignored.""")) + continue + # Make sure the pattern was a legal regular expression + name = Utils.websafe(name) + try: + orpattern = OR.join(pattern.splitlines()) + re.compile(orpattern) + except (re.error, TypeError): + safepattern = Utils.websafe(orpattern) + doc.addError(_("""The topic pattern '%(safepattern)s' is not a + legal regular expression. It will be discarded.""")) + 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(('', '', '', True)) + topics.append((name, pattern, desc, False)) + # Default is to add it after... + else: + topics.append((name, pattern, desc, False)) + topics.append(('', '', '', True)) + # Otherwise, just retain this one in the list + else: + topics.append((name, pattern, desc, False)) + # 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 |
