New template system. Closes #249
[mailman.git] / src / mailman / styles / base.py
blob6620e85f27551e966ea7ac8bb476ab4fe7c8d44a
1 # Copyright (C) 2012-2016 by the Free Software Foundation, Inc.
3 # This file is part of GNU Mailman.
5 # GNU Mailman is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free
7 # Software Foundation, either version 3 of the License, or (at your option)
8 # any later version.
10 # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 # more details.
15 # You should have received a copy of the GNU General Public License along with
16 # GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
18 """Building blocks for styles.
20 Use these to compose higher level styles. Their apply() methods deliberately
21 have no super() upcall. You need to explicitly call all base class apply()
22 methods in your compositional derived class.
23 """
26 from datetime import timedelta
27 from mailman import public
28 from mailman.core.i18n import _
29 from mailman.interfaces.action import Action, FilterAction
30 from mailman.interfaces.archiver import ArchivePolicy
31 from mailman.interfaces.autorespond import ResponseAction
32 from mailman.interfaces.bounce import UnrecognizedBounceDisposition
33 from mailman.interfaces.digests import DigestFrequency
34 from mailman.interfaces.mailinglist import (
35 Personalization, ReplyToMunging, SubscriptionPolicy)
36 from mailman.interfaces.nntp import NewsgroupModeration
39 @public
40 class Identity:
41 """Set basic identify attributes."""
43 def apply(self, mailing_list):
44 # For cut-n-paste convenience.
45 mlist = mailing_list
46 mlist.display_name = mlist.list_name.capitalize()
47 mlist.include_rfc2369_headers = True
48 mlist.volume = 1
49 mlist.post_id = 1
50 mlist.description = ''
51 mlist.info = ''
52 mlist.preferred_language = 'en'
53 mlist.subject_prefix = _('[$mlist.display_name] ')
54 mlist.encode_ascii_prefixes = (
55 mlist.preferred_language.charset != 'us-ascii')
58 @public
59 class BasicOperation:
60 """Set basic operational attributes."""
62 def apply(self, mailing_list):
63 # For cut-n-paste convenience.
64 mlist = mailing_list
65 mlist.emergency = False
66 mlist.personalize = Personalization.none
67 mlist.default_member_action = Action.defer
68 mlist.default_nonmember_action = Action.hold
69 mlist.subscription_policy = SubscriptionPolicy.confirm
70 # Notify the administrator of pending requests and membership changes.
71 mlist.admin_immed_notify = True
72 mlist.admin_notify_mchanges = False
73 mlist.respond_to_post_requests = True
74 mlist.obscure_addresses = True
75 mlist.collapse_alternatives = True
76 mlist.convert_html_to_plaintext = False
77 mlist.filter_action = FilterAction.discard
78 mlist.filter_content = False
79 # Digests.
80 mlist.digests_enabled = True
81 mlist.digest_is_default = False
82 mlist.mime_is_default_digest = False
83 mlist.digest_size_threshold = 30 # KB
84 mlist.digest_send_periodic = True
85 mlist.digest_volume_frequency = DigestFrequency.monthly
86 mlist.next_digest_number = 1
87 # NNTP gateway
88 mlist.nntp_host = ''
89 mlist.linked_newsgroup = ''
90 mlist.gateway_to_news = False
91 mlist.gateway_to_mail = False
92 mlist.nntp_prefix_subject_too = True
93 # In patch #401270, this was called newsgroup_is_moderated, but the
94 # semantics weren't quite the same.
95 mlist.newsgroup_moderation = NewsgroupModeration.none
96 # Topics
98 # `topics' is a list of 4-tuples of the following form:
100 # (name, pattern, description, emptyflag)
102 # name is a required arbitrary string displayed to the user when they
103 # get to select their topics of interest
105 # pattern is a required verbose regular expression pattern which is
106 # used as IGNORECASE.
108 # description is an optional description of what this topic is
109 # supposed to match
111 # emptyflag is a boolean used internally in the admin interface to
112 # signal whether a topic entry is new or not (new ones which do not
113 # have a name or pattern are not saved when the submit button is
114 # pressed).
115 mlist.topics = []
116 mlist.topics_enabled = False
117 mlist.topics_bodylines_limit = 5
118 # This is a mapping between user "names" (i.e. addresses) and
119 # information about which topics that user is interested in. The
120 # values are a list of topic names that the user is interested in,
121 # which should match the topic names in mlist.topics above.
123 # If the user has not selected any topics of interest, then the rule
124 # is that they will get all messages, and they will not have an entry
125 # in this dictionary.
126 mlist.topics_userinterest = {}
127 # scrub regular delivery
128 mlist.scrub_nondigest = False
131 @public
132 class Bounces:
133 """Basic bounce processing."""
135 def apply(self, mailing_list):
136 # For cut-n-paste convenience.
137 mlist = mailing_list
138 # Bounces
139 mlist.forward_unrecognized_bounces_to = (
140 UnrecognizedBounceDisposition.administrators)
141 mlist.process_bounces = True
142 mlist.bounce_score_threshold = 5.0
143 mlist.bounce_info_stale_after = timedelta(days=7)
144 mlist.bounce_you_are_disabled_warnings = 3
145 mlist.bounce_you_are_disabled_warnings_interval = timedelta(days=7)
146 mlist.bounce_notify_owner_on_disable = True
147 mlist.bounce_notify_owner_on_removal = True
148 # Autoresponder
149 mlist.autorespond_owner = ResponseAction.none
150 mlist.autoresponse_owner_text = ''
151 mlist.autorespond_postings = ResponseAction.none
152 mlist.autoresponse_postings_text = ''
153 mlist.autorespond_requests = ResponseAction.none
154 mlist.autoresponse_request_text = ''
155 mlist.autoresponse_grace_period = timedelta(days=90)
156 # This holds legacy member related information. It's keyed by the
157 # member address, and the value is an object containing the bounce
158 # score, the date of the last received bounce, and a count of the
159 # notifications left to send.
160 mlist.bounce_info = {}
161 # New style delivery status
162 mlist.delivery_status = {}
163 # The processing chain that messages posted to this mailing list get
164 # processed by.
165 mlist.posting_chain = 'default-posting-chain'
166 # The default pipeline to send accepted messages through to the
167 # mailing list's members.
168 mlist.posting_pipeline = 'default-posting-pipeline'
169 # The processing chain that messages posted to this mailing list's
170 # -owner address gets processed by.
171 mlist.owner_chain = 'default-owner-chain'
172 # The default pipeline to send -owner email through.
173 mlist.owner_pipeline = 'default-owner-pipeline'
176 @public
177 class Public:
178 """Settings for public mailing lists."""
180 def apply(self, mailing_list):
181 # For cut-n-paste convenience.
182 mlist = mailing_list
183 mlist.advertised = True
184 mlist.reply_goes_to_list = ReplyToMunging.no_munging
185 mlist.reply_to_address = ''
186 mlist.first_strip_reply_to = False
187 mlist.archive_policy = ArchivePolicy.public
190 @public
191 class Announcement:
192 """Settings for announce-only lists."""
194 def apply(self, mailing_list):
195 # For cut-n-paste convenience.
196 mlist = mailing_list
197 mlist.allow_list_posts = False
198 mlist.send_welcome_message = True
199 mlist.send_goodbye_message = True
200 mlist.anonymous_list = False
203 @public
204 class Discussion:
205 """Settings for standard discussion lists."""
207 def apply(self, mailing_list):
208 # For cut-n-paste convenience.
209 mlist = mailing_list
210 mlist.allow_list_posts = True
211 mlist.send_welcome_message = True
212 mlist.send_goodbye_message = True
213 mlist.anonymous_list = False
216 @public
217 class Moderation:
218 """Settings for basic moderation."""
220 def apply(self, mailing_list):
221 # For cut-n-paste convenience.
222 mlist = mailing_list
223 mlist.max_num_recipients = 10
224 mlist.max_message_size = 40 # KB
225 mlist.require_explicit_destination = True
226 mlist.bounce_matching_headers = """
227 # Lines that *start* with a '#' are comments.
228 to: friend@public.com
229 message-id: relay.comanche.denmark.eu
230 from: list@listme.com
231 from: .*@uplinkpro.com
233 mlist.header_matches = []
234 mlist.administrivia = True
235 # Member moderation.
236 mlist.member_moderation_notice = ''
237 mlist.accept_these_nonmembers = []
238 mlist.hold_these_nonmembers = []
239 mlist.reject_these_nonmembers = []
240 mlist.discard_these_nonmembers = []
241 mlist.forward_auto_discards = True
242 mlist.nonmember_rejection_notice = ''
243 # automatic discarding
244 mlist.max_days_to_hold = 0