1 # Copyright (C) 2012-2019 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)
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
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.
26 from datetime
import timedelta
27 from mailman
.core
.i18n
import _
28 from mailman
.interfaces
.action
import Action
, FilterAction
29 from mailman
.interfaces
.archiver
import ArchivePolicy
30 from mailman
.interfaces
.autorespond
import ResponseAction
31 from mailman
.interfaces
.bounce
import UnrecognizedBounceDisposition
32 from mailman
.interfaces
.digests
import DigestFrequency
33 from mailman
.interfaces
.mailinglist
import (
34 DMARCMitigateAction
, Personalization
, ReplyToMunging
, SubscriptionPolicy
)
35 from mailman
.interfaces
.nntp
import NewsgroupModeration
36 from mailman
.model
.roster
import RosterVisibility
37 from public
import public
42 """Set basic identify attributes."""
44 def apply(self
, mailing_list
):
45 # For cut-n-paste convenience.
47 mlist
.display_name
= mlist
.list_name
.capitalize()
48 mlist
.include_rfc2369_headers
= True
51 mlist
.description
= ''
53 mlist
.preferred_language
= 'en'
54 mlist
.subject_prefix
= _('[$mlist.display_name] ')
55 mlist
.encode_ascii_prefixes
= (
56 mlist
.preferred_language
.charset
!= 'us-ascii')
61 """Set basic operational attributes."""
63 def apply(self
, mailing_list
):
64 # For cut-n-paste convenience.
66 mlist
.emergency
= False
67 mlist
.personalize
= Personalization
.none
68 mlist
.default_member_action
= Action
.defer
69 mlist
.default_nonmember_action
= Action
.hold
70 mlist
.subscription_policy
= SubscriptionPolicy
.confirm
71 mlist
.unsubscription_policy
= SubscriptionPolicy
.confirm
72 mlist
.member_roster_visibility
= RosterVisibility
.moderators
73 # Notify the administrator of pending requests and membership changes.
74 mlist
.admin_immed_notify
= True
75 mlist
.admin_notify_mchanges
= False
76 mlist
.respond_to_post_requests
= True
77 mlist
.obscure_addresses
= True
78 mlist
.collapse_alternatives
= True
79 mlist
.convert_html_to_plaintext
= False
80 mlist
.filter_action
= FilterAction
.discard
81 mlist
.filter_content
= False
83 mlist
.digests_enabled
= True
84 mlist
.digest_is_default
= False
85 mlist
.digest_size_threshold
= 30 # KB
86 mlist
.digest_send_periodic
= True
87 mlist
.digest_volume_frequency
= DigestFrequency
.monthly
88 mlist
.next_digest_number
= 1
90 mlist
.dmarc_mitigate_action
= DMARCMitigateAction
.no_mitigation
91 mlist
.dmarc_mitigate_unconditionally
= False
92 mlist
.dmarc_moderation_notice
= ''
93 mlist
.dmarc_wrapped_message_text
= ''
96 mlist
.linked_newsgroup
= ''
97 mlist
.gateway_to_news
= False
98 mlist
.gateway_to_mail
= False
99 mlist
.nntp_prefix_subject_too
= True
100 # In patch #401270, this was called newsgroup_is_moderated, but the
101 # semantics weren't quite the same.
102 mlist
.newsgroup_moderation
= NewsgroupModeration
.none
105 # `topics' is a list of 4-tuples of the following form:
107 # (name, pattern, description, emptyflag)
109 # name is a required arbitrary string displayed to the user when they
110 # get to select their topics of interest
112 # pattern is a required verbose regular expression pattern which is
113 # used as IGNORECASE.
115 # description is an optional description of what this topic is
118 # emptyflag is a boolean used internally in the admin interface to
119 # signal whether a topic entry is new or not (new ones which do not
120 # have a name or pattern are not saved when the submit button is
123 mlist
.topics_enabled
= False
124 mlist
.topics_bodylines_limit
= 5
125 # This is a mapping between user "names" (i.e. addresses) and
126 # information about which topics that user is interested in. The
127 # values are a list of topic names that the user is interested in,
128 # which should match the topic names in mlist.topics above.
130 # If the user has not selected any topics of interest, then the rule
131 # is that they will get all messages, and they will not have an entry
132 # in this dictionary.
133 mlist
.topics_userinterest
= {}
134 # scrub regular delivery
135 mlist
.scrub_nondigest
= False
140 """Basic bounce processing."""
142 def apply(self
, mailing_list
):
143 # For cut-n-paste convenience.
146 mlist
.forward_unrecognized_bounces_to
= (
147 UnrecognizedBounceDisposition
.administrators
)
148 mlist
.process_bounces
= True
149 mlist
.bounce_score_threshold
= 5.0
150 mlist
.bounce_info_stale_after
= timedelta(days
=7)
151 mlist
.bounce_you_are_disabled_warnings
= 3
152 mlist
.bounce_you_are_disabled_warnings_interval
= timedelta(days
=7)
153 mlist
.bounce_notify_owner_on_disable
= True
154 mlist
.bounce_notify_owner_on_removal
= True
156 mlist
.autorespond_owner
= ResponseAction
.none
157 mlist
.autoresponse_owner_text
= ''
158 mlist
.autorespond_postings
= ResponseAction
.none
159 mlist
.autoresponse_postings_text
= ''
160 mlist
.autorespond_requests
= ResponseAction
.none
161 mlist
.autoresponse_request_text
= ''
162 mlist
.autoresponse_grace_period
= timedelta(days
=90)
163 # This holds legacy member related information. It's keyed by the
164 # member address, and the value is an object containing the bounce
165 # score, the date of the last received bounce, and a count of the
166 # notifications left to send.
167 mlist
.bounce_info
= {}
168 # New style delivery status
169 mlist
.delivery_status
= {}
170 # The processing chain that messages posted to this mailing list get
172 mlist
.posting_chain
= 'default-posting-chain'
173 # The default pipeline to send accepted messages through to the
174 # mailing list's members.
175 mlist
.posting_pipeline
= 'default-posting-pipeline'
176 # The processing chain that messages posted to this mailing list's
177 # -owner address gets processed by.
178 mlist
.owner_chain
= 'default-owner-chain'
179 # The default pipeline to send -owner email through.
180 mlist
.owner_pipeline
= 'default-owner-pipeline'
185 """Settings for public mailing lists."""
187 def apply(self
, mailing_list
):
188 # For cut-n-paste convenience.
190 mlist
.advertised
= True
191 mlist
.reply_goes_to_list
= ReplyToMunging
.no_munging
192 mlist
.reply_to_address
= ''
193 mlist
.first_strip_reply_to
= False
194 mlist
.archive_policy
= ArchivePolicy
.public
199 """Settings for private mailing lists."""
201 def apply(self
, mailing_list
):
203 mlist
.advertised
= False
204 mlist
.archive_policy
= ArchivePolicy
.private
209 """Settings for announce-only lists."""
211 def apply(self
, mailing_list
):
212 # For cut-n-paste convenience.
214 mlist
.allow_list_posts
= False
215 mlist
.send_welcome_message
= True
216 mlist
.send_goodbye_message
= True
217 mlist
.anonymous_list
= False
222 """Settings for standard discussion lists."""
224 def apply(self
, mailing_list
):
225 # For cut-n-paste convenience.
227 mlist
.allow_list_posts
= True
228 mlist
.send_welcome_message
= True
229 mlist
.send_goodbye_message
= True
230 mlist
.anonymous_list
= False
235 """Settings for basic moderation."""
237 def apply(self
, mailing_list
):
238 # For cut-n-paste convenience.
240 mlist
.max_num_recipients
= 10
241 mlist
.max_message_size
= 40 # KB
242 mlist
.require_explicit_destination
= True
243 mlist
.bounce_matching_headers
= """
244 # Lines that *start* with a '#' are comments.
245 to: friend@public.com
246 message-id: relay.comanche.denmark.eu
247 from: list@listme.com
248 from: .*@uplinkpro.com
250 mlist
.header_matches
= []
251 mlist
.administrivia
= True
253 mlist
.member_moderation_notice
= ''
254 mlist
.accept_these_nonmembers
= []
255 mlist
.hold_these_nonmembers
= []
256 mlist
.reject_these_nonmembers
= []
257 mlist
.discard_these_nonmembers
= []
258 mlist
.forward_auto_discards
= True
259 mlist
.nonmember_rejection_notice
= ''
260 # automatic discarding
261 mlist
.max_days_to_hold
= 0