diff options
| author | Barry Warsaw | 2009-01-25 13:01:41 -0500 |
|---|---|---|
| committer | Barry Warsaw | 2009-01-25 13:01:41 -0500 |
| commit | eefd06f1b88b8ecbb23a9013cd223b72ca85c20d (patch) | |
| tree | 72c947fe16fce0e07e996ee74020b26585d7e846 /src/mailman/styles | |
| parent | 07871212f74498abd56bef3919bf3e029eb8b930 (diff) | |
| download | mailman-eefd06f1b88b8ecbb23a9013cd223b72ca85c20d.tar.gz mailman-eefd06f1b88b8ecbb23a9013cd223b72ca85c20d.tar.zst mailman-eefd06f1b88b8ecbb23a9013cd223b72ca85c20d.zip | |
Diffstat (limited to 'src/mailman/styles')
| -rw-r--r-- | src/mailman/styles/__init__.py | 0 | ||||
| -rw-r--r-- | src/mailman/styles/default.py | 250 | ||||
| -rw-r--r-- | src/mailman/styles/manager.py | 94 |
3 files changed, 344 insertions, 0 deletions
diff --git a/src/mailman/styles/__init__.py b/src/mailman/styles/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/mailman/styles/__init__.py diff --git a/src/mailman/styles/default.py b/src/mailman/styles/default.py new file mode 100644 index 000000000..296ebbff1 --- /dev/null +++ b/src/mailman/styles/default.py @@ -0,0 +1,250 @@ +# Copyright (C) 2007-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/>. + +"""Application of list styles to new and existing lists.""" + +from __future__ import absolute_import, unicode_literals + +__metaclass__ = type +__all__ = [ + 'DefaultStyle', + ] + +# XXX Styles need to be reconciled with lazr.config. + +import datetime + +from zope.interface import implements + +from mailman import Utils +from mailman.i18n import _ +from mailman.interfaces import Action, NewsModeration +from mailman.interfaces.mailinglist import Personalization, ReplyToMunging +from mailman.interfaces.styles import IStyle + + + +class DefaultStyle: + """The default (i.e. legacy) style.""" + + implements(IStyle) + + name = 'default' + priority = 0 # the lowest priority style + + def apply(self, mailing_list): + """See `IStyle`.""" + # For cut-n-paste convenience. + mlist = mailing_list + # Most of these were ripped from the old MailList.InitVars() method. + mlist.volume = 1 + mlist.post_id = 1 + mlist.new_member_options = 256 + # This stuff is configurable + mlist.real_name = mlist.list_name.capitalize() + mlist.respond_to_post_requests = True + mlist.advertised = True + mlist.max_num_recipients = 10 + mlist.max_message_size = 40 # KB + mlist.reply_goes_to_list = ReplyToMunging.no_munging + mlist.reply_to_address = '' + mlist.first_strip_reply_to = False + mlist.admin_immed_notify = True + mlist.admin_notify_mchanges = False + mlist.require_explicit_destination = True + mlist.acceptable_aliases = '' + mlist.send_reminders = True + mlist.send_welcome_msg = True + mlist.send_goodbye_msg = True + mlist.bounce_matching_headers = """ +# Lines that *start* with a '#' are comments. +to: friend@public.com +message-id: relay.comanche.denmark.eu +from: list@listme.com +from: .*@uplinkpro.com +""" + mlist.header_matches = [] + mlist.anonymous_list = False + mlist.description = '' + mlist.info = '' + mlist.welcome_msg = '' + mlist.goodbye_msg = '' + mlist.subscribe_policy = 1 + mlist.subscribe_auto_approval = [] + mlist.unsubscribe_policy = 0 + mlist.private_roster = 1 + mlist.obscure_addresses = True + mlist.admin_member_chunksize = 30 + mlist.administrivia = True + mlist.preferred_language = 'en' + mlist.include_rfc2369_headers = True + mlist.include_list_post_header = True + mlist.filter_mime_types = [] + mlist.pass_mime_types = [ + 'multipart/mixed', + 'multipart/alternative', + 'text/plain', + ] + mlist.filter_filename_extensions = [ + 'exe', 'bat', 'cmd', 'com', 'pif', 'scr', 'vbs', 'cpl', + ] + mlist.pass_filename_extensions = [] + mlist.filter_content = False + mlist.collapse_alternatives = True + mlist.convert_html_to_plaintext = True + mlist.filter_action = 0 + # Digest related variables + mlist.digestable = True + mlist.digest_is_default = False + mlist.mime_is_default_digest = False + mlist.digest_size_threshold = 30 # KB + mlist.digest_send_periodic = True + mlist.digest_header = '' + mlist.digest_footer = """\ +_______________________________________________ +$real_name mailing list +$fqdn_listname +${listinfo_page} +""" + mlist.digest_volume_frequency = 1 + mlist.one_last_digest = {} + mlist.next_digest_number = 1 + mlist.nondigestable = True + mlist.personalize = Personalization.none + # New sender-centric moderation (privacy) options + mlist.default_member_moderation = False + # Archiver + mlist.archive = True + mlist.archive_private = 0 + mlist.archive_volume_frequency = 1 + mlist.emergency = False + mlist.member_moderation_action = Action.hold + mlist.member_moderation_notice = '' + mlist.accept_these_nonmembers = [] + mlist.hold_these_nonmembers = [] + mlist.reject_these_nonmembers = [] + mlist.discard_these_nonmembers = [] + mlist.forward_auto_discards = True + mlist.generic_nonmember_action = 1 + mlist.nonmember_rejection_notice = '' + # Ban lists + mlist.ban_list = [] + # Max autoresponses per day. A mapping between addresses and a + # 2-tuple of the date of the last autoresponse and the number of + # autoresponses sent on that date. + mlist.hold_and_cmd_autoresponses = {} + mlist.subject_prefix = _('[$mlist.real_name] ') + mlist.msg_header = '' + mlist.msg_footer = """\ +_______________________________________________ +$real_name mailing list +$fqdn_listname +${listinfo_page} +""" + # Set this to Never if the list's preferred language uses us-ascii, + # otherwise set it to As Needed + if Utils.GetCharSet(mlist.preferred_language) == 'us-ascii': + mlist.encode_ascii_prefixes = 0 + else: + mlist.encode_ascii_prefixes = 2 + # scrub regular delivery + mlist.scrub_nondigest = False + # automatic discarding + mlist.max_days_to_hold = 0 + # Autoresponder + mlist.autorespond_postings = False + mlist.autorespond_admin = False + # this value can be + # 0 - no autoresponse on the -request line + # 1 - autorespond, but discard the original message + # 2 - autorespond, and forward the message on to be processed + mlist.autorespond_requests = 0 + mlist.autoresponse_postings_text = '' + mlist.autoresponse_admin_text = '' + mlist.autoresponse_request_text = '' + mlist.autoresponse_graceperiod = datetime.timedelta(days=90) + mlist.postings_responses = {} + mlist.admin_responses = {} + mlist.request_responses = {} + # Bounces + mlist.bounce_processing = True + mlist.bounce_score_threshold = 5.0 + mlist.bounce_info_stale_after = datetime.timedelta(days=7) + mlist.bounce_you_are_disabled_warnings = 3 + mlist.bounce_you_are_disabled_warnings_interval = ( + datetime.timedelta(days=7)) + mlist.bounce_unrecognized_goes_to_list_owner = True + mlist.bounce_notify_owner_on_disable = True + mlist.bounce_notify_owner_on_removal = True + # This holds legacy member related information. It's keyed by the + # member address, and the value is an object containing the bounce + # score, the date of the last received bounce, and a count of the + # notifications left to send. + mlist.bounce_info = {} + # New style delivery status + mlist.delivery_status = {} + # NNTP gateway + mlist.nntp_host = '' + mlist.linked_newsgroup = '' + mlist.gateway_to_news = False + mlist.gateway_to_mail = False + mlist.news_prefix_subject_too = True + # In patch #401270, this was called newsgroup_is_moderated, but the + # semantics weren't quite the same. + mlist.news_moderation = NewsModeration.none + # Topics + # + # `topics' is a list of 4-tuples of the following form: + # + # (name, pattern, description, emptyflag) + # + # name is a required arbitrary string displayed to the user when they + # get to select their topics of interest + # + # pattern is a required verbose regular expression pattern which is + # used as IGNORECASE. + # + # description is an optional description of what this topic is + # supposed to match + # + # emptyflag is a boolean used internally in the admin interface to + # signal whether a topic entry is new or not (new ones which do not + # have a name or pattern are not saved when the submit button is + # pressed). + mlist.topics = [] + mlist.topics_enabled = False + mlist.topics_bodylines_limit = 5 + # This is a mapping between user "names" (i.e. addresses) and + # information about which topics that user is interested in. The + # values are a list of topic names that the user is interested in, + # which should match the topic names in mlist.topics above. + # + # If the user has not selected any topics of interest, then the rule + # is that they will get all messages, and they will not have an entry + # in this dictionary. + mlist.topics_userinterest = {} + # The processing chain that messages coming into this list get + # processed by. + mlist.start_chain = 'built-in' + # The default pipeline to send accepted messages through. + mlist.pipeline = 'built-in' + + def match(self, mailing_list, styles): + """See `IStyle`.""" + # If no other styles have matched, then the default style matches. + if len(styles) == 0: + styles.append(self) diff --git a/src/mailman/styles/manager.py b/src/mailman/styles/manager.py new file mode 100644 index 000000000..cf3d07711 --- /dev/null +++ b/src/mailman/styles/manager.py @@ -0,0 +1,94 @@ +# Copyright (C) 2007-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/>. + +"""Style manager.""" + +from __future__ import absolute_import, unicode_literals + +__metaclass__ = type +__all__ = [ + 'StyleManager', + ] + + +import sys + +from operator import attrgetter +from zope.interface import implements +from zope.interface.verify import verifyObject + +from mailman.interfaces.styles import ( + DuplicateStyleError, IStyle, IStyleManager) + + + +class StyleManager: + """The built-in style manager.""" + + implements(IStyleManager) + + def __init__(self): + """Install all styles from the configuration files.""" + self._styles = {} + + def populate(self): + self._styles.clear() + # Avoid circular imports. + from mailman.config import config + # Install all the styles described by the configuration files. + for section in config.style_configs: + class_path = section['class'] + module_name, class_name = class_path.rsplit('.', 1) + __import__(module_name) + style = getattr(sys.modules[module_name], class_name)() + assert section.name.startswith('style'), ( + 'Bad style section name: %s' % section.name) + style.name = section.name[6:] + style.priority = int(section.priority) + self.register(style) + + def get(self, name): + """See `IStyleManager`.""" + return self._styles.get(name) + + def lookup(self, mailing_list): + """See `IStyleManager`.""" + matched_styles = [] + for style in self.styles: + style.match(mailing_list, matched_styles) + for style in matched_styles: + yield style + + @property + def styles(self): + """See `IStyleManager`.""" + for style in sorted(self._styles.values(), + key=attrgetter('priority'), + reverse=True): + yield style + + def register(self, style): + """See `IStyleManager`.""" + verifyObject(IStyle, style) + if style.name in self._styles: + raise DuplicateStyleError(style.name) + self._styles[style.name] = style + + def unregister(self, style): + """See `IStyleManager`.""" + # Let KeyErrors percolate up. + del self._styles[style.name] |
