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)
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
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
41 """Set basic identify attributes."""
43 def apply(self
, mailing_list
):
44 # For cut-n-paste convenience.
46 mlist
.display_name
= mlist
.list_name
.capitalize()
47 mlist
.include_rfc2369_headers
= True
50 mlist
.description
= ''
52 mlist
.preferred_language
= 'en'
53 mlist
.subject_prefix
= _('[$mlist.display_name] ')
54 mlist
.encode_ascii_prefixes
= (
55 mlist
.preferred_language
.charset
!= 'us-ascii')
60 """Set basic operational attributes."""
62 def apply(self
, mailing_list
):
63 # For cut-n-paste convenience.
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
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
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
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
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
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
133 """Basic bounce processing."""
135 def apply(self
, mailing_list
):
136 # For cut-n-paste convenience.
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
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
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'
178 """Settings for public mailing lists."""
180 def apply(self
, mailing_list
):
181 # For cut-n-paste convenience.
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
192 """Settings for announce-only lists."""
194 def apply(self
, mailing_list
):
195 # For cut-n-paste convenience.
197 mlist
.allow_list_posts
= False
198 mlist
.send_welcome_message
= True
199 mlist
.send_goodbye_message
= True
200 mlist
.anonymous_list
= False
205 """Settings for standard discussion lists."""
207 def apply(self
, mailing_list
):
208 # For cut-n-paste convenience.
210 mlist
.allow_list_posts
= True
211 mlist
.send_welcome_message
= True
212 mlist
.send_goodbye_message
= True
213 mlist
.anonymous_list
= False
218 """Settings for basic moderation."""
220 def apply(self
, mailing_list
):
221 # For cut-n-paste convenience.
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
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