# -*- python -*-

# Copyright (C) 1998-2018 by the Free Software Foundation, Inc.
#
# This program 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 2
# of the License, or (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
# USA.

"""Distributed default settings for significant Mailman config variables."""

# NEVER make site configuration changes to this file.  ALWAYS make them in
# mm_cfg.py instead, in the designated area.  See the comments in that file
# for details.


import os

def seconds(s): return s
def minutes(m): return m * 60
def hours(h): return h * 60 * 60
def days(d): return d * 60 * 60 * 24

# Some convenient constants
try:
    True, False
except NameError:
    True = 1
    False = 0

Yes = yes = On = on = True
No = no = Off = off = False



#####
# General system-wide defaults
#####

# Should image logos be used?  Set this to 0 to disable image logos from "our
# sponsors" and just use textual links instead (this will also disable the
# shortcut "favicon").  Otherwise, this should contain the URL base path to
# the logo images (and must contain the trailing slash)..  If you want to
# disable Mailman's logo footer altogther, hack
# Mailman/htmlformat.py:MailmanLogo(), which also contains the hardcoded links
# and image names.
IMAGE_LOGOS = '/icons/'

# The name of the Mailman favicon
SHORTCUT_ICON = 'mm-icon.png'

# Don't change MAILMAN_URL, unless you want to point it at one of the mirrors.
MAILMAN_URL = 'http://www.gnu.org/software/mailman/index.html'
#MAILMAN_URL = 'http://www.list.org/'
#MAILMAN_URL = 'http://mailman.sf.net/'

# Mailman needs to know about (at least) two fully-qualified domain names
# (fqdn); 1) the hostname used in your urls, and 2) the hostname used in email
# addresses for your domain.  For example, if people visit your Mailman system
# with "http://www.dom.ain/mailman" then your url fqdn is "www.dom.ain", and
# if people send mail to your system via "yourlist@dom.ain" then your email
# fqdn is "dom.ain".  DEFAULT_URL_HOST controls the former, and
# DEFAULT_EMAIL_HOST controls the latter.  Mailman also needs to know how to
# map from one to the other (this is especially important if you're running
# with virtual domains).  You use "add_virtualhost(urlfqdn, emailfqdn)" to add
# new mappings.
#
# If you don't need to change DEFAULT_EMAIL_HOST and DEFAULT_URL_HOST in your
# mm_cfg.py, then you're done; the default mapping is added automatically.  If
# however you change either variable in your mm_cfg.py, then be sure to also
# include the following:
#
#     add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)
#
# because otherwise the default mappings won't be correct.
DEFAULT_EMAIL_HOST = 'localhost'
DEFAULT_URL_HOST = 'localhost'
DEFAULT_URL_PATTERN = 'http://%s/mailman/'

# DEFAULT_HOST_NAME has been replaced with DEFAULT_EMAIL_HOST, however some
# sites may have the former in their mm_cfg.py files.  If so, we'll believe
# that, otherwise we'll believe DEFAULT_EMAIL_HOST.  Same for DEFAULT_URL.
DEFAULT_HOST_NAME = None
DEFAULT_URL = None

HOME_PAGE         = 'index.html'
MAILMAN_SITE_LIST = 'mailman'

# Normally when a site administrator authenticates to a web page with the site
# password, they get a cookie which authorizes them as the list admin.  It
# makes me nervous to hand out site auth cookies because if this cookie is
# cracked or intercepted, the intruder will have access to every list on the
# site.  OTOH, it's dang handy to not have to re-authenticate to every list on
# the site.  Set this value to Yes to allow site admin cookies.
ALLOW_SITE_ADMIN_COOKIES = No

# If the following is set to a non-zero value, web authentication cookies will
# expire that many seconds following their last use.
AUTHENTICATION_COOKIE_LIFETIME = 0

# Form lifetime is set against Cross Site Request Forgery.
FORM_LIFETIME = hours(1)

# If the following is set to a non-empty string, this string in combination
# with the time, list name and the IP address of the requestor is used to
# create a hidden hash as part of the subscribe form on the listinfo page.
# This hash is checked upon form submission and the subscribe fails if it
# doesn't match.  I.e. the form posted must be first retrieved from the
# listinfo CGI by the same IP that posts it.  The subscribe also fails if
# the time the form was retrieved is more than the above FORM_LIFETIME or less
# than the below SUBSCRIBE_FORM_MIN_TIME before submission.
# Important: If you have any static subscribe forms on your web site, setting
# this option will break them.  With this option set, subscribe forms must be
# dynamically generated to include the hidden data.  See the code block
# beginning with "if mm_cfg.SUBSCRIBE_FORM_SECRET:" in Mailman/Cgi/listinfo.py
# for the details of the hidden data.
SUBSCRIBE_FORM_SECRET = None

# If SUBSCRIBE_FORM_SECRET is not None, this is the minimum time the user must
# take after retrieving the form before submitting it.  Set to 0 to skip this
# test.
SUBSCRIBE_FORM_MIN_TIME = seconds(5)

# Use a custom question-answer CAPTCHA to protect against subscription spam.
# Has no effect unless SUBSCRIBE_FORM_SECRET is set.
# Should be set to a dict mapping language keys to a list of pairs
# of questions and regexes for the answers, e.g.
# CAPTCHAS = {
#   'en': [
#     ('What is two times six?', '(12|twelve)'),
#     ('What is this mailing list software called?', '[Mm]ailman'),
#   ],
#   'de': [
#     ('Was ist 3 mal 6?', '(18|achtzehn)'),
#   ],
# }
# The regular expression must match the full string, i.e., it is implicitly
# acting as if it had "^" in the beginning and "$" at the end.
# An 'en' key must be present and is used as fall-back if there are no
# questions for the currently set language.
CAPTCHAS = None

# Use Google reCAPTCHA to protect the subscription form from spam bots.  The
# following must be set to a pair of keys issued by the reCAPTCHA service at
# https://www.google.com/recaptcha/admin
RECAPTCHA_SITE_KEY = None
RECAPTCHA_SECRET_KEY = None

# Installation wide ban list.  This is a list of email addresses and regexp
# patterns (beginning with ^) which are not allowed to subscribe to any lists
# in the installation.  This supplements the individual list's ban_list.
# For example, to ban xxx@aol.com and any @gmail.com address beginning with
# yyy, set
# GLOBAL_BAN_LIST = ['xxx@aol\.com', '^yyy.*@gmail\.com$']
GLOBAL_BAN_LIST = []

# If the following is set to Yes, and a web subscribe comes from an IPv4
# address and the IP is listed in Spamhaus SBL, CSS or XBL, the subscription
# will be blocked.  It will work with IPv6 addresses if Python's py2-ipaddress
# module is installed.  The module can be installed via pip if not included
# in your Python.
BLOCK_SPAMHAUS_LISTED_IP_SUBSCRIBE = No

# If the following is set to Yes, and a subscriber uses a domain that is
# listed in the Spamhaus DBL, the subscription will be blocked.
BLOCK_SPAMHAUS_LISTED_DBL_SUBSCRIBE = No

# Command that is used to convert text/html parts into plain text.  This
# should output results to standard output.  %(filename)s will contain the
# name of the temporary file that the program should operate on.
HTML_TO_PLAIN_TEXT_COMMAND = '/usr/local/bin/lynx -dump %(filename)s'

# A Python regular expression character class which defines the characters
# allowed in list names.  Lists cannot be created with names containing any
# character that doesn't match this class.  Do not include '/' in this list.
ACCEPTABLE_LISTNAME_CHARACTERS = '[-+_.=a-z0-9]'

# The number of characters in the longest listname in the installation.  The
# fix for LP: #1780874 truncates list names in web URLs to this length to avoid
# a content spoofing vulnerability.  If this is left at its default value of
# 0, the length of the longest listname is calculated on every web access.
# This can have performance implications in installations with a very large
# number of lists.  To use this feature to avoid the calculation, set this to
# a number equal to the length of the longest expected valid list name.
MAX_LISTNAME_LENGTH = 0

# Shall the user's real names be displayed along with their email addresses
# in list rosters?  Defaults to No to preserve prior behavior.
ROSTER_DISPLAY_REALNAME = No

# Beginning in Mailman 2.1.21, localized help and some other output from
# Mailman's bin/ commands is converted to the character set of the user's
# workstation (LC_CTYPE) if different from the character set of the language.
# This is not well tested over a wide range of locales, so if it causes
# problems, it can be disabled by setting the following to Yes.
DISABLE_COMMAND_LOCALE_CSET = No



#####
# Virtual domains
#####

# Set up your virtual host mappings here.  This is primarily used for the
# thru-the-web list creation, so its effects are currently fairly limited.
# Use add_virtualhost() call to add new mappings.  The keys are strings as
# determined by Utils.get_domain(), the values are as appropriate for
# DEFAULT_HOST_NAME.
VIRTUAL_HOSTS = {}

# When set to Yes, the listinfo and admin overviews of lists on the machine
# will be confined to only those lists whose web_page_url configuration option
# host is included within the URL by which the page is visited - only those
# "on the virtual host".  When set to No, all advertised (i.e. public) lists
# are included in the overview.
VIRTUAL_HOST_OVERVIEW = On


# Helper function; use this in your mm_cfg.py files.  If optional emailhost is
# omitted it defaults to urlhost with the first name stripped off, e.g.
#
# add_virtualhost('www.dom.ain')
# VIRTUAL_HOSTS['www.dom.ain']
# ==> 'dom.ain'
#
def add_virtualhost(urlhost, emailhost=None):
    DOT = '.'
    if emailhost is None:
        emailhost = DOT.join(urlhost.split(DOT)[1:])
    VIRTUAL_HOSTS[urlhost.lower()] = emailhost.lower()

# And set the default
add_virtualhost(DEFAULT_URL_HOST, DEFAULT_EMAIL_HOST)

# Note that you will want to run bin/fix_url.py to change the domain of an
# existing list.  bin/fix_url.py must be run within the bin/withlist script,
# like so: bin/withlist -l -r bin/fix_url.py <listname>



#####
# Spam avoidance defaults
#####

# This variable contains a list of 2-tuple of the format (header, regex) which
# the Mailman/Handlers/SpamDetect.py module uses to match against the current
# message.  If the regex matches the given header in the current message, then
# it is flagged as spam.  header is case-insensitive and should not include
# the trailing colon.  regex is always matched with re.IGNORECASE.
#
# Note that the more searching done, the slower the whole process gets.  Spam
# detection is run against all messages coming to either the list, or the
# -owners address, unless the message is explicitly approved.
KNOWN_SPAMMERS = []

# The header_filter_rules in Privacy options... -> Spam filters are matched as
# normalized unicodes against normalized unicode headers.  This setting
# determines the normalization form.  It is one of 'NFC', 'NFD', 'NFKC' or
# 'NFKD'.  See
# https://docs.python.org/2/library/unicodedata.html#unicodedata.normalize
NORMALIZE_FORM = 'NFKC'



#####
# Web UI defaults
#####

# Almost all the colors used in Mailman's web interface are parameterized via
# the following variables.  This lets you easily change the color schemes for
# your preferences without having to do major surgery on the source code.
# Note that in general, the template colors are not included here since it is
# easy enough to override the default template colors via site-wide,
# vdomain-wide, or list-wide specializations.

WEB_BG_COLOR = 'white'                            # Page background
WEB_HEADER_COLOR = '#99ccff'                      # Major section headers
WEB_SUBHEADER_COLOR = '#fff0d0'                   # Minor section headers
WEB_ADMINITEM_COLOR = '#dddddd'                   # Option field background
WEB_ADMINPW_COLOR = '#99cccc'                     # Password box color
WEB_ERROR_COLOR = 'red'                           # Error message foreground
WEB_LINK_COLOR = ''                               # If true, forces LINK=
WEB_ALINK_COLOR = ''                              # If true, forces ALINK=
WEB_VLINK_COLOR = ''                              # If true, forces VLINK=
WEB_HIGHLIGHT_COLOR = '#dddddd'                   # If true, alternating rows
                                                  # in listinfo & admin display

# If you wish to include extra elements in the <HEAD> section of Mailman's
# web pages, e.g. style information or a link to a style sheet, you can set
# the following.  For example, to include a css style sheet reference, you
# can put in mm_cfg.py
# WEB_HEAD_ADD = """<LINK REL=stylesheet
#                TYPE="text/css"
#                HREF="path or URL"
#                >"""
# You can specify anything that is allowed in the <HEAD> section.  The default
# is to not add anything.  This only applies to internally generated pages.
# For pages built from templates you can create custom templates containing
# this information.
WEB_HEAD_ADD = None

# User entered data is escaped for redisplay in web responses to avoid Cross
# Site Scripting (XSS) attacks. The normal escaping replaces the characters
# <, >, & and " with the respective HTML entities &lt;, &gt;, &amp; and
# &quot;.  There are apparently some older, broken browsers that misinterpret
# certain non-ascii characters as <, > or ".  The following two settings
# control whether additional characters are escaped, and what characters are
# replaced with what.  Note that in character sets that represent some
# characters as multi-byte sequences, enabling the escaping of additional
# characters can replace part of a multi-byte sequence with an HTML entity,
# thus breaking an otherwise harmless character.
#
# Enable the replacement of additional characters when escaping strings for
# the web.
BROKEN_BROWSER_WORKAROUND = No
#
# If the above setting is Yes, the following dictionary definition determines
# what additional characters are replaced with what.
BROKEN_BROWSER_REPLACEMENTS = {'\x8b': '&#8249;',  # single left angle quote
                               '\x9b': '&#8250;',  # single right angle quote
                               '\xbc': '&#188;',   # < plus high order bit
                               '\xbe': '&#190;',   # > plus high order bit
                               '\xa2': '&#162;',   # " plus high order bit
                              }
#
# Shall the admindb held message summary display the grouping and sorting
# option radio buttons?  Set this in mm_cfg.py to one of the following:
# SSENDER -> Default to grouped and sorted by sender.
# SSENDERTIME -> Default to grouped by sender and sorted by time.
# STIME -> Default to ungrouped and sorted by time.
DISPLAY_HELD_SUMMARY_SORT_BUTTONS = No
#
# Shall the default for the admin Mass Subscription function be Invite rather
# than Subscribe?  Set to Yes in mm_cfg.py to make the default be Invite.
DEFAULT_SUBSCRIBE_OR_INVITE = No



#####
# Archive defaults
#####

# The url template for the public archives.  This will be used in several
# places, including the List-Archive: header, links to the archive on the
# list's listinfo page, and on the list's admin page.
#
# This should be a string with "%(listname)s" somewhere in it.  Mailman will
# interpolate the name of the list into this.  You can also include a
# "%(hostname)s" in the string, into which Mailman will interpolate
# the host name (usually DEFAULT_URL_HOST).
PUBLIC_ARCHIVE_URL = 'http://%(hostname)s/pipermail/%(listname)s'

# Are archives on or off by default?
DEFAULT_ARCHIVE = On

# Are archives public or private by default?
# 0=public, 1=private
DEFAULT_ARCHIVE_PRIVATE = 0

# ARCHIVE_TO_MBOX
#-1 - do not do any archiving
# 0 - do not archive to mbox, use builtin mailman html archiving only
# 1 - do not use builtin mailman html archiving, archive to mbox only
# 2 - archive to both mbox and builtin mailman html archiving.
#     See the settings below for PUBLIC_EXTERNAL_ARCHIVER and
#     PRIVATE_EXTERNAL_ARCHIVER which can be used to replace mailman's
#     builtin html archiving with an external archiver.  The flat mail
#     mbox file can be useful for searching, and is another way to
#     interface external archivers, etc.
ARCHIVE_TO_MBOX = 2

# 0 - yearly
# 1 - monthly
# 2 - quarterly
# 3 - weekly
# 4 - daily
DEFAULT_ARCHIVE_VOLUME_FREQUENCY = 1
DEFAULT_DIGEST_VOLUME_FREQUENCY = 1

# These variables control the use of an external archiver.  Normally if
# archiving is turned on (see ARCHIVE_TO_MBOX above and the list's archive*
# attributes) the internal Pipermail archiver is used.  This is the default if
# both of these variables are set to No.  When either is set, the value should
# be a shell command string which will get passed to os.popen().  This string
# can contain the following substitution strings:
#
#     %(listname)s -- gets the internal name of the list
#     %(hostname)s -- gets the email hostname for the list
#
# being archived will be substituted for this.  Please note that os.popen() is
# used.
#
# Note that if you set one of these variables, you should set both of them
# (they can be the same string).  This will mean your external archiver will
# be used regardless of whether public or private archives are selected.
PUBLIC_EXTERNAL_ARCHIVER = No
PRIVATE_EXTERNAL_ARCHIVER = No

# A filter module that converts from multipart messages to "flat" messages
# (i.e. containing a single payload).  This is required for Pipermail, and you
# may want to set it to 0 for external archivers.  You can also replace it
# with your own module as long as it contains a process() function that takes
# a MailList object and a Message object.  It should raise
# Errors.DiscardMessage if it wants to throw the message away.  Otherwise it
# should modify the Message object as necessary.
ARCHIVE_SCRUBBER = 'Mailman.Handlers.Scrubber'

# Control parameter whether Mailman.Handlers.Scrubber should use message
# attachment's filename as is indicated by the filename parameter or use
# 'attachement-xxx' instead.  The default is set True because the applications
# on PC and Mac begin to use longer non-ascii filenames.  Historically, it
# was set False in 2.1.6 for backward compatiblity but it was reset to True
# for safer operation in mailman-2.1.7.
SCRUBBER_DONT_USE_ATTACHMENT_FILENAME = True

# Use of attachment filename extension per se is may be dangerous because
# virus fakes it. You can set this True if you filter the attachment by
# filename extension
SCRUBBER_USE_ATTACHMENT_FILENAME_EXTENSION = False

# This variable defines what happens to text/html subparts.  They can be
# stripped completely, escaped, or filtered through an external program.  The
# legal values are:
# 0 - Strip out text/html parts completely, leaving a notice of the removal in
#     the message.  If the outer part is text/html, the entire message is
#     discarded.
# 1 - Remove any embedded text/html parts, leaving them as HTML-escaped
#     attachments which can be separately viewed.  Outer text/html parts are
#     simply HTML-escaped.
# 2 - Leave it inline, but HTML-escape it
# 3 - Remove text/html as attachments but don't HTML-escape them. Note: this
#     is very dangerous because it essentially means anybody can send an HTML
#     email to your site containing evil JavaScript or web bugs, or other
#     nasty things, and folks viewing your archives will be susceptible.  You
#     should only consider this option if you do heavy moderation of your list
#     postings.
#
# Note: given the current archiving code, it is not possible to leave
# text/html parts inline and un-escaped.  I wouldn't think it'd be a good idea
# to do anyway.
#
# The value can also be a string, in which case it is the name of a command to
# filter the HTML page through.  The resulting output is left in an attachment
# or as the entirety of the message when the outer part is text/html.  The
# format of the string must include a "%(filename)s" which will contain the
# name of the temporary file that the program should operate on.  It should
# write the processed message to stdout.  Set this to
# HTML_TO_PLAIN_TEXT_COMMAND to specify an HTML to plain text conversion
# program.
ARCHIVE_HTML_SANITIZER = 1

# Set this to Yes to enable gzipping of the downloadable archive .txt file.
# Note that this is /extremely/ inefficient, so an alternative is to just
# collect the messages in the associated .txt file and run a cron job every
# night to generate the txt.gz file.  See cron/nightly_gzip for details.
GZIP_ARCHIVE_TXT_FILES = No

# This sets the default `clobber date' policy for the archiver.  When a
# message is to be archived either by Pipermail or an external archiver,
# Mailman can modify the Date: header to be the date the message was received
# instead of the Date: in the original message.  This is useful if you
# typically receive messages with outrageous dates.  Set this to 0 to retain
# the date of the original message, or to 1 to always clobber the date.  Set
# it to 2 to perform `smart overrides' on the date; when the date is outside
# ARCHIVER_ALLOWABLE_SANE_DATE_SKEW (either too early or too late), then the
# received date is substituted instead.
ARCHIVER_CLOBBER_DATE_POLICY = 2
ARCHIVER_ALLOWABLE_SANE_DATE_SKEW = days(15)

# Pipermail archives contain the raw email addresses of the posting authors.
# Some view this as a goldmine for spam harvesters.  Set this to Yes to
# moderately obscure email addresses, but note that this breaks mailto: URLs
# in the archives too.
ARCHIVER_OBSCURES_EMAILADDRS = Yes

# Pipermail assumes that message bodies contain US-ASCII text.
# Change this option to define a different character set to be used as
# the default character set for the archive.  The term "character set"
# is used in MIME to refer to a method of converting a sequence of
# octets into a sequence of characters.  If you change the default
# charset, you might need to add it to VERBATIM_ENCODING below.
DEFAULT_CHARSET = None

# Most character set encodings require special HTML entity characters to be
# quoted, otherwise they won't look right in the Pipermail archives.  However
# some character sets must not quote these characters so that they can be
# rendered properly in the browsers.  The primary issue is multi-byte
# encodings where the octet 0x26 does not always represent the & character.
# This variable contains a list of such characters sets which are not
# HTML-quoted in the archives.
VERBATIM_ENCODING = ['iso-2022-jp']

# When the archive is public, should Mailman also make the raw Unix mbox file
# publically available?
PUBLIC_MBOX = No



#####
# Delivery defaults
#####

# Final delivery module for outgoing mail.  This handler is used for message
# delivery to the list via the smtpd, and to an individual user.  This value
# must be a string naming a module in the Mailman.Handlers package.
#
# WARNING: Sendmail has security holes and should be avoided.  In fact, you
# must read the Mailman/Handlers/Sendmail.py file before it will work for
# you.
#
#DELIVERY_MODULE = 'Sendmail'
DELIVERY_MODULE = 'SMTPDirect'

# Sometimes there are 'low level' smtplib failures that are difficult to
# debug.  To enable very verbose debugging info from smtplib to Mailman's
# error log, set the following to 1.  This will only work if
# DELIVERY_MODULE = 'SMTPDirect' and Python is >= 2.4.
SMTPLIB_DEBUG_LEVEL = 0

# MTA should name a module in Mailman/MTA which provides the MTA specific
# functionality for creating and removing lists.  Some MTAs like Exim can be
# configured to automatically recognize new lists, in which case the MTA
# variable should be set to None.  Use 'Manual' to print new aliases to
# standard out (or send an email to the site list owner) for manual twiddling
# of an /etc/aliases style file.  Use 'Postfix' if you are using the Postfix
# MTA -- but then also see POSTFIX_STYLE_VIRTUAL_DOMAINS.
MTA = 'Manual'

# If you set MTA='Postfix', then you also want to set the following variable,
# depending on whether you're using virtual domains in Postfix, and which
# style of virtual domain you're using.  Set this to the empty list if you're
# not using virtual domains in Postfix, or if you're using Sendmail-style
# virtual domains (where all addresses are visible in all domains).  If you're
# using Postfix-style virtual domains, where aliases should only show up in
# the virtual domain, set this variable to the list of host_name values to
# write separate virtual entries for.  I.e. if you run dom1.ain, dom2.ain, and
# dom3.ain, but only dom2 and dom3 are virtual, set this variable to the list
# ['dom2.ain', 'dom3.ain'].  Matches are done against the host_name attribute
# of the mailing lists.  See the Postfix section of the installation manual
# for details.
POSTFIX_STYLE_VIRTUAL_DOMAINS = []

# If you specify any virtual domains in the above list, Mailman will generate
# a virtual-mailman file containing virtual mappings of the form
#
# listaddress@dom2.ain   listaddress
# etc.
#
# to map the list addresses in those domains to local addresses. If you need
# mappings that specify a domain on the right hand side such as
#
# listaddress@dom2.ain   listaddress@localhost
# or
# listaddress@dom2.ain   listaddress@other.local.domain
#
# specify the desired local domain in mm_cfg.py as for example
#
# VIRTUAL_MAILMAN_LOCAL_DOMAIN = 'localhost'
# or
# VIRTUAL_MAILMAN_LOCAL_DOMAIN = 'other.local.domain'
#
# Whatever string value you set will be literally appended with an '@' to the
# listaddress local parts on the right hand side.
VIRTUAL_MAILMAN_LOCAL_DOMAIN = None

# These variables describe the program to use for regenerating the aliases.db
# and virtual-mailman.db files, respectively, from the associated plain text
# files.  The file being updated will be appended to this string (with a
# separating space), so it must be appropriate for os.system().
POSTFIX_ALIAS_CMD = '/usr/local/sbin/postalias'
POSTFIX_MAP_CMD = '/usr/local/sbin/postmap'

# Ceiling on the number of recipients that can be specified in a single SMTP
# transaction.  Set to 0 to submit the entire recipient list in one
# transaction.  Only used with the SMTPDirect DELIVERY_MODULE.
SMTP_MAX_RCPTS = 500

# Ceiling on the number of SMTP sessions to perform on a single socket
# connection.  Some MTAs have limits.  Set this to 0 to do as many as we like
# (i.e. your MTA has no limits).  Set this to some number great than 0 and
# Mailman will close the SMTP connection and re-open it after this number of
# consecutive sessions.
SMTP_MAX_SESSIONS_PER_CONNECTION = 0

# Maximum number of simultaneous subthreads that will be used for SMTP
# delivery.  After the recipients list is chunked according to SMTP_MAX_RCPTS,
# each chunk is handed off to the smptd by a separate such thread.  If your
# Python interpreter was not built for threads, this feature is disabled.  You
# can explicitly disable it in all cases by setting MAX_DELIVERY_THREADS to
# 0.  This feature is only supported with the SMTPDirect DELIVERY_MODULE.
#
# NOTE: This is an experimental feature and limited testing shows that it may
# in fact degrade performance, possibly due to Python's global interpreter
# lock.  Use with caution.
MAX_DELIVERY_THREADS = 0

# SMTP host and port, when DELIVERY_MODULE is 'SMTPDirect'.  Make sure the
# host exists and is resolvable (i.e., if it's the default of "localhost" be
# sure there's a localhost entry in your /etc/hosts file!)
SMTPHOST = 'localhost'
SMTPPORT = 0                                      # default from smtplib

# Command for direct command pipe delivery to sendmail compatible program,
# when DELIVERY_MODULE is 'Sendmail'.
SENDMAIL_CMD = '/usr/sbin/sendmail'

# SMTP authentication for DELIVERY_MODULE = 'SMTPDirect'.  To enable SASL
# authentication for SMTPDirect, set SMTP_AUTH = Yes and provide appropriate
# settings for SMTP_USER and SMTP_PASSWD.
SMTP_AUTH = No
SMTP_USER = ''
SMTP_PASSWD = ''

# If using SASL authentication (SMTP_AUTH = Yes), set the following to Yes
# to also use TLS. This has no effect if SMTP_AUTH = No.
SMTP_USE_TLS = No

# When using TLS the following should be set to the hostname that should be
# used in order to identify Mailman to the SMTP server.  By default, it
# uses DEFAULT_URL_HOST. Normally, you should not change this.
SMTP_HELO_HOST = DEFAULT_URL_HOST

# Set these variables if you need to authenticate to your NNTP server for
# Usenet posting or reading.  If no authentication is necessary, specify None
# for both variables.
NNTP_USERNAME = None
NNTP_PASSWORD = None

# Set this if you have an NNTP server you prefer gatewayed lists to use.
DEFAULT_NNTP_HOST = ''

# These variables controls how headers must be cleansed in order to be
# accepted by your NNTP server.  Some servers like INN reject messages
# containing prohibited headers, or duplicate headers.  The NNTP server may
# reject the message for other reasons, but there's little that can be
# programmatically done about that.  See Mailman/Queue/NewsRunner.py
#
# First, these headers (case ignored) are removed from the original message.
NNTP_REMOVE_HEADERS = ['nntp-posting-host', 'nntp-posting-date', 'x-trace',
                       'x-complaints-to', 'xref', 'date-received', 'posted',
                       'posting-version', 'relay-version', 'received']

# Next, these headers are left alone, unless there are duplicates in the
# original message.  Any second and subsequent headers are rewritten to the
# second named header (case preserved).
NNTP_REWRITE_DUPLICATE_HEADERS = [
    ('to', 'X-Original-To'),
    ('cc', 'X-Original-Cc'),
    ('content-transfer-encoding', 'X-Original-Content-Transfer-Encoding'),
    ('mime-version', 'X-MIME-Version'),
    ]

# Some list posts and mail to the -owner address may contain DomainKey or
# DomainKeys Identified Mail (DKIM) signature headers <http://www.dkim.org/>.
# Various list transformations to the message such as adding a list header or
# footer or scrubbing attachments or even reply-to munging can break these
# signatures.  It is generally felt that these signatures have value, even if
# broken and even if the outgoing message is resigned.  However, some sites
# may wish to remove these headers.  Possible values and meanings are:
# No, 0, False -> do not remove headers.
# Yes, 1, True -> remove headers only if we are munging the from header due
#                 to from_is_list or dmarc_moderation_action.
# 2 -> always remove headers.
# 3 -> always remove, rename and preserve original DKIM headers.
REMOVE_DKIM_HEADERS = No

# If the following is set to a non-empty string, that string is the name of a
# header that will be added to personalized and VERPed deliveries with value
# equal to the base64 encoding of the recipient's email address.  This is
# intended to enable identification of the recipient otherwise redacted from
# "spam report" feedback loop messages.  For example, if
# RCPT_BASE64_HEADER_NAME = 'X-Mailman-R-Data'
# a header like
# X-Mailman-R-Data: dXNlckBleGFtcGxlLmNvbQo=
# will be added to messages sent to user@@example.com.
RCPT_BASE64_HEADER_NAME = ''

# All `normal' messages which are delivered to the entire list membership go
# through this pipeline of handler modules.  Lists themselves can override the
# global pipeline by defining a `pipeline' attribute.
GLOBAL_PIPELINE = [
    # These are the modules that do tasks common to all delivery paths.
    'SpamDetect',
    'Approve',
    'Replybot',
    'Moderate',
    'Hold',
    'MimeDel',
    'Scrubber',
    'Emergency',
    'Tagger',
    'CalcRecips',
    'AvoidDuplicates',
    'Cleanse',
    'CleanseDKIM',
    'CookHeaders',
    # And now we send the message to the digest mbox file, and to the arch and
    # news queues.  Runners will provide further processing of the message,
    # specific to those delivery paths.
    'ToDigest',
    'ToArchive',
    'ToUsenet',
    # Now we'll do a few extra things specific to the member delivery
    # (outgoing) path, finally leaving the message in the outgoing queue.
    'AfterDelivery',
    'Acknowledge',
    'WrapMessage',
    'ToOutgoing',
    ]

# This is the pipeline which messages sent to the -owner address go through
OWNER_PIPELINE = [
    'SpamDetect',
    'Replybot',
    'OwnerRecips',
    'ToOutgoing',
    ]


# This defines syslog() format strings for the SMTPDirect delivery module (see
# DELIVERY_MODULE above).  Valid %()s string substitutions include:
#
#     time -- the time in float seconds that it took to complete the smtp
#     hand-off of the message from Mailman to your smtpd.
#
#     size -- the size of the entire message, in bytes
#
#     #recips -- the number of actual recipients for this message.
#
#     #refused -- the number of smtp refused recipients (use this only in
#     SMTP_LOG_REFUSED).
#
#     listname -- the `internal' name of the mailing list for this posting
#
#     msg_<header> -- the value of the delivered message's given header.  If
#     the message had no such header, then "n/a" will be used.  Note though
#     that if the message had multiple such headers, then it is undefined
#     which will be used.
#
#     allmsg_<header> - Same as msg_<header> above, but if there are multiple
#     such headers in the message, they will all be printed, separated by
#     comma-space.
#
#     sender -- the "sender" of the messages, which will be the From: or
#     envelope-sender as determeined by the USE_ENVELOPE_SENDER variable
#     below.
#
# The format of the entries is a 2-tuple with the first element naming the
# file in logs/ to print the message to, and the second being a format string
# appropriate for Python's %-style string interpolation.  The file name is
# arbitrary; qfiles/<name> will be created automatically if it does not
# exist.

# The format of the message printed for every delivered message, regardless of
# whether the delivery was successful or not.  Set to None to disable the
# printing of this log message.
SMTP_LOG_EVERY_MESSAGE = (
    'smtp',
    '%(msg_message-id)s smtp to %(listname)s for %(#recips)d recips, completed in %(time).3f seconds')

# This will only be printed if there were no immediate smtp failures.
# Mutually exclusive with SMTP_LOG_REFUSED.
SMTP_LOG_SUCCESS = (
    'post',
    'post to %(listname)s from %(sender)s, size=%(size)d, message-id=%(msg_message-id)s, success')

# This will only be printed if there were any addresses which encountered an
# immediate smtp failure.  Mutually exclusive with SMTP_LOG_SUCCESS.
SMTP_LOG_REFUSED = (
    'post',
    'post to %(listname)s from %(sender)s, size=%(size)d, message-id=%(msg_message-id)s, %(#refused)d failures')

# This will be logged for each specific recipient failure.  Additional %()s
# keys are:
#
#     recipient -- the failing recipient address
#     failcode  -- the smtp failure code
#     failmsg   -- the actual smtp message, if available
SMTP_LOG_EACH_FAILURE = (
    'smtp-failure',
    'delivery to %(recipient)s failed with code %(failcode)d: %(failmsg)s')

# These variables control the format and frequency of VERP-like delivery for
# better bounce detection.  VERP is Variable Envelope Return Path, defined
# here:
#
# http://cr.yp.to/proto/verp.txt
#
# This involves encoding the address of the recipient as we (Mailman) know it
# into the envelope sender address (i.e. the SMTP `MAIL FROM:' address).
# Thus, no matter what kind of forwarding the recipient has in place, should
# it eventually bounce, we will receive an unambiguous notice of the bouncing
# address.
#
# However, we're technically only "VERP-like" because we're doing the envelope
# sender encoding in Mailman, not in the MTA.  We do require cooperation from
# the MTA, so you must be sure your MTA can be configured for extended address
# semantics.
#
# The first variable describes how to encode VERP envelopes.  It must contain
# these three string interpolations:
#
# %(bounces)s -- the list-bounces mailbox will be set here
# %(mailbox)s -- the recipient's mailbox will be set here
# %(host)s    -- the recipient's host name will be set here
#
# This example uses the default below.
#
# FQDN list address is: mylist@dom.ain
# Recipient is:         aperson@a.nother.dom
#
# The envelope sender will be mylist-bounces+aperson=a.nother.dom@dom.ain
#
# Note that your MTA /must/ be configured to deliver such an addressed message
# to mylist-bounces!
VERP_FORMAT = '%(bounces)s+%(mailbox)s=%(host)s'

# The second describes a regular expression to unambiguously decode such an
# address, which will be placed in the To: header of the bounce message by the
# bouncing MTA.  Getting this right is critical -- and tricky.  Learn your
# Python regular expressions.  It must define exactly three named groups,
# bounces, mailbox and host, with the same definition as above.  It will be
# compiled case-insensitively.
VERP_REGEXP = r'^(?P<bounces>[^+]+?)\+(?P<mailbox>[^=]+)=(?P<host>[^@]+)@.*$'

# VERP format and regexp for probe messages
VERP_PROBE_FORMAT = '%(bounces)s+%(token)s'
VERP_PROBE_REGEXP = r'^(?P<bounces>[^+]+?)\+(?P<token>[^@]+)@.*$'
# Set this Yes to activate VERP probe for disabling by bounce
VERP_PROBES = No

# A perfect opportunity for doing VERP is the password reminders, which are
# already addressed individually to each recipient.  Set this to Yes to enable
# VERPs on all password reminders.  However, because password reminders are
# sent from the site list and site list bounces aren't processed but are just
# forwarded to the site list admins, this isn't too useful.  See comments at
# lines 70-84 of Mailman/Queue/BounceRunner.py for why we don't process them.
VERP_PASSWORD_REMINDERS = No

# Another good opportunity is when regular delivery is personalized.  Here
# again, we're already incurring the performance hit for addressing each
# individual recipient.  Set this to Yes to enable VERPs on all personalized
# regular deliveries (personalized digests aren't supported yet).
VERP_PERSONALIZED_DELIVERIES = No

# And finally, we can VERP normal, non-personalized deliveries.  However,
# because it can be a significant performance hit, we allow you to decide how
# often to VERP regular deliveries.  This is the interval, in number of
# messages, to do a VERP recipient address.  The same variable controls both
# regular and digest deliveries.  Set to 0 to disable occasional VERPs, set to
# 1 to VERP every delivery, or to some number > 1 for only occasional VERPs.
VERP_DELIVERY_INTERVAL = 0

# For nicer confirmation emails, use a VERP-like format which encodes the
# confirmation cookie in the reply address.  This lets us put a more user
# friendly Subject: on the message, but requires cooperation from the MTA.
# Format is like VERP_FORMAT above, but with the following substitutions:
#
# %(addr)s -- the list-confirm mailbox will be set here
# %(cookie)s  -- the confirmation cookie will be set here
VERP_CONFIRM_FORMAT = '%(addr)s+%(cookie)s'

# This is analogous to VERP_REGEXP, but for splitting apart the
# VERP_CONFIRM_FORMAT.  MUAs have been observed that mung
# From: local_part@host
# into
# To: "local_part" <local_part@host>
# or even
# To: "local_part@host" <local_part@host>
# and may even fold the header when replying, so we skip everything up to '<'
# if any and include ($s) so dot will match the newline in a folded header.
VERP_CONFIRM_REGEXP = r'(?s)^(.*<)?(?P<addr>.+)\+(?P<cookie>[0-9a-f]{40})@.*$'

# Set this to Yes to enable VERP-like (more user friendly) confirmations
VERP_CONFIRMATIONS = No

# This is the maximum number of automatic responses sent to an address because
# of -request messages or posting hold messages.  This limit prevents response
# loops between Mailman and misconfigured remote email robots.  Mailman
# already inhibits automatic replies to any message labeled with a header
# "Precendence: bulk|list|junk".  This is a fallback safety valve so it should
# be set fairly high.  Set to 0 for no limit (probably useful only for
# debugging).
MAX_AUTORESPONSES_PER_DAY = 10

# This FreeBSD port of Mailman can utilize Postfix SMTP server's VERP ability.
# You may set VERP_STYLE = 'Postfix' to enable it.
VERP_STYLE = 'Manual'

# When using Postfix style VERP you will need the following setting.
POSTFIX_XVERP_OPTS = '+='


#####
# Backscatter mitigation
#####

# This controls whether a message to the -request address without any
# commands or a message to -confirm whose To: address doesn't match
# VERP_CONFIRM_REGEXP above is responded to or just logged.
DISCARD_MESSAGE_WITH_NO_COMMAND = Yes

# This controls how much of the original message is included in automatic
# responses to email commands.  The values are:
# 0 - Do not include any unprocessed or ignored commands.  Do not include
#     the original message.
# 1 - Do not include any unprocessed or ignored commands.  Include only the
#     headers from the original message.
# 2 - Include unprocessed and ignored commands.  Include the complete original
#     message.
#
# In order to minimize the effect of backscatter due to spam sent to
# administrative addresses, it is recommended to set this to 0, however the
# default is 2 for backwards compatibility.
RESPONSE_INCLUDE_LEVEL = 2

# This sets the default for respond_to_post_requests for new lists.  It is
# set to Yes for backwards compatibility, but it is recommended that serious
# consideration be given to setting it to No.
DEFAULT_RESPOND_TO_POST_REQUESTS = Yes



#####
# Qrunner defaults
#####

# Which queues should the qrunner master watchdog spawn?  This is a list of
# 2-tuples containing the name of the qrunner class (which must live in a
# module of the same name within the Mailman.Queue package), and the number of
# parallel processes to fork for each qrunner.  If more than one process is
# used, each will take an equal subdivision of the hash space.

# BAW: Eventually we may support weighted hash spaces.
# BAW: Although not enforced, the # of slices must be a power of 2

QRUNNERS = [
    ('ArchRunner',     1), # messages for the archiver
    ('BounceRunner',   1), # for processing the qfile/bounces directory
    ('CommandRunner',  1), # commands and bounces from the outside world
    ('IncomingRunner', 1), # posts from the outside world
    ('NewsRunner',     1), # outgoing messages to the nntpd
    ('OutgoingRunner', 1), # outgoing messages to the smtpd
    ('VirginRunner',   1), # internally crafted (virgin birth) messages
    ('RetryRunner',    1), # retry temporarily failed deliveries
    ]

# Set this to Yes to use the `Maildir' delivery option.  If you change this
# you will need to re-run bin/genaliases for MTAs that don't use list
# auto-detection.
#
# WARNING: If you want to use Maildir delivery, you /must/ start Mailman's
# qrunner as root, or you will get permission problems.
#
# NOTE: Maildir delivery is experimental for Mailman 2.1.
USE_MAILDIR = No
# NOTE: If you set USE_MAILDIR = Yes, add the following line to your mm_cfg.py
# file (uncommented of course!)
# QRUNNERS.append(('MaildirRunner', 1))

# After processing every file in the qrunner's slice, how long should the
# runner sleep for before checking the queue directory again for new files?
# This can be a fraction of a second, or zero to check immediately
# (essentially busy-loop as fast as possible).
QRUNNER_SLEEP_TIME = seconds(1)

# When a message that is unparsable (by the email package) is received, what
# should we do with it?  The most common cause of unparsable messages is
# broken MIME encapsulation, and the most common cause of that is viruses like
# Nimda.  Set this variable to No to discard such messages, or to Yes to store
# them in qfiles/bad subdirectory.
QRUNNER_SAVE_BAD_MESSAGES = Yes

# Depending on the above setting, the queue entries with messages which can't
# be parsed may be saved in qfiles/bad.  Certain other exceptions which occur
# during unpickling of a queue entry also cause the entry to be saved in
# qfiles/bad.  Various exceptions which occur during message processing cause
# the message to be shunted (saved in qfiles/shunt) where they can be
# reprocessed with bin/unshunt after the underlying problem is fixed.  The
# cull_bad_shunt cron job normally runs daily to remove and possibly archive
# stale entries in qfiles/bad and qfiles/shunt.  The following settings
# control this.

# The length of time after which a qfiles/bad or qfiles/shunt file is
# considered to be stale.  Set to zero to disable culling of qfiles/bad and
# qfiles/shunt entries.
BAD_SHUNT_STALE_AFTER = days(7)

# The pathname of a directory (searchable and writable by the Mailman cron
# user) to which the culled qfiles/bad and qfiles/shunt entries will be
# moved.  Set to None to simply delete the culled entries.
BAD_SHUNT_ARCHIVE_DIRECTORY = None

# This flag causes Mailman to fsync() its data files after writing and
# flushing its contents.  While this ensures the data is written to disk,
# avoiding data loss, it may be a performance killer.  Note that this flag
# affects both message pickles and MailList config.pck files.
SYNC_AFTER_WRITE = No

# This is the name used for the mailmanctl master lock file. In a clustered
# load sharing environment with a shared 'locks' directory, it is desirable
# to have separate locks for each host mailmanctl. This can be used to enable
# that.
MASTER_LOCK_FILE = 'master-qrunner'



#####
# General defaults
#####

# The default language for this server.  Whenever we can't figure out the list
# context or user context, we'll fall back to using this language.  See
# LC_DESCRIPTIONS below for legal values.
DEFAULT_SERVER_LANGUAGE = 'en'

# When allowing only members to post to a mailing list, how is the sender of
# the message determined?  If this variable is set to Yes, then first the
# message's envelope sender is used, with a fallback to the sender if there is
# no envelope sender.  Set this variable to No to always use the sender.
#
# The envelope sender is set by the SMTP delivery and is thus less easily
# spoofed than the sender, which is typically just taken from the From: header
# and thus easily spoofed by the end-user.  However, sometimes the envelope
# sender isn't set correctly and this will manifest itself by postings being
# held for approval even if they appear to come from a list member.  If you
# are having this problem, set this variable to No, but understand that some
# spoofed messages may get through.
USE_ENVELOPE_SENDER = No

# Membership tests for posting purposes are usually performed by looking at a
# set of headers, passing the test if any of their values match a member of
# the list.  Headers are checked in the order given in this variable.  The
# value None means use the From_ (envelope sender) header.  Field names are
# case insensitive.
SENDER_HEADERS = ('from', None, 'reply-to', 'sender')

# How many members to display at a time on the admin cgi to unsubscribe them
# or change their options?
DEFAULT_ADMIN_MEMBER_CHUNKSIZE = 30

# how many bytes of a held message post should be displayed in the admindb web
# page?  Use a negative number to indicate the entire message, regardless of
# size (though this will slow down rendering those pages).
ADMINDB_PAGE_TEXT_LIMIT = 4096

# Set this variable to Yes to allow list owners to delete their own mailing
# lists.  You may not want to give them this power, in which case, setting
# this variable to No instead requires list removal to be done by the site
# administrator, via the command line script bin/rmlist.
OWNERS_CAN_DELETE_THEIR_OWN_LISTS = No

# Set this variable to Yes to allow list owners to set the "personalized"
# flags on their mailing lists.  Turning these on tells Mailman to send
# separate email messages to each user instead of batching them together for
# delivery to the MTA.  This gives each member a more personalized message,
# but can have a heavy impact on the performance of your system.
OWNERS_CAN_ENABLE_PERSONALIZATION = No

# Set this variable to Yes to allow list owners to change a member's password
# from the member's options page.  Do not do this if list owners aren't all
# trustworthy as it allows a list owner to change a member's password and then
# log in as the member and make global changes.
OWNERS_CAN_CHANGE_MEMBER_PASSWORDS = No

# Should held messages be saved on disk as Python pickles or as plain text?
# The former is more efficient since we don't need to go through the
# parse/generate roundtrip each time, but the latter might be preferred if you
# want to edit the held message on disk.
HOLD_MESSAGES_AS_PICKLES = Yes

# This variable controls the order in which list-specific category options are
# presented in the admin cgi page.
ADMIN_CATEGORIES = [
    # First column
    'general', 'passwords', 'language', 'members', 'nondigest', 'digest',
    # Second column
    'privacy', 'bounce', 'archive', 'gateway', 'autoreply',
    'contentfilter', 'topics',
    ]

# See "Bitfield for user options" below; make this a sum of those options, to
# make all new members of lists start with those options flagged.  We assume
# by default that people don't want to receive two copies of posts.  Note
# however that the member moderation flag's initial value is controlled by the
# list's config variable default_member_moderation.
DEFAULT_NEW_MEMBER_OPTIONS = 256

# Specify the type of passwords to use, when Mailman generates the passwords
# itself, as would be the case for membership requests where the user did not
# fill in a password, or during list creation, when auto-generation of admin
# passwords was selected.
#
# Set this value to Yes for classic Mailman user-friendly(er) passwords.
# These generate semi-pronounceable passwords which are easier to remember.
# Set this value to No to use more cryptographically secure, but harder to
# remember, passwords -- if your operating system and Python version support
# the necessary feature (specifically that /dev/urandom be available).
USER_FRIENDLY_PASSWORDS = Yes
# This value specifies the default lengths of member and list admin passwords
MEMBER_PASSWORD_LENGTH = 8
ADMIN_PASSWORD_LENGTH = 10

# The following headers are always removed from posts to anonymous lists as
# they can reveal the identity of the poster or at least the poster's domain.
#
# From:, Reply-To:, Sender:, Return-Path:, X-Originating-Email:, Received:,
# Message-ID: and X-Envelope-From:.
#
# In addition, Return-Receipt-To:, Disposition-Notification-To:,
# X-Confirm-Reading-To: and X-Pmrqc: headers are removed from all posts as
# they can be used to fish for list membership in addition to possibly
# revealing sender information.
#
# In addition to the above removals, all other headers except those matching
# regular expressions in the following setting are also removed. The default
# setting below keeps all non X- headers, those X- headers added by Mailman
# and any X-Spam- headers.
ANONYMOUS_LIST_KEEP_HEADERS = ['^(?!x-)', '^x-mailman-',
                               '^x-content-filtered-by:', '^x-topics:',
                               '^x-ack:', '^x-beenthere:',
                               '^x-list-administrivia:', '^x-spam-',
                              ]
#
# It is possible to mailbomb a third party by repeatrdly posting the subscribe
# form.  You can prevent this by setting the following to Yes which will refuse
# pending a subscription confirmation when one is already pending.  The down
# side to this is if a subscriber loses or doesn't receive the confirmation
# request email, she has to wait PENDING_REQUEST_LIFE (default 3 days) before
# she can request another.  This setting also applies to repeated unsubscribes.
REFUSE_SECOND_PENDING = No
# Mailbombing of a list member of a list with private rosters can occur with
# repeated subscribe attempts resulting in repeated user warnings.  Set the
# following to No to supress the user warnings.
WARN_MEMBER_OF_SUBSCRIBE = Yes



#####
# List defaults.  NOTE: Changing these values does NOT change the
# configuration of an existing list.  It only defines the default for new
# lists you subsequently create.
#####

# Should a list, by default be advertised?  What is the default maximum number
# of explicit recipients allowed?  What is the default maximum message size
# allowed?
DEFAULT_LIST_ADVERTISED = Yes
DEFAULT_MAX_NUM_RECIPIENTS = 10
DEFAULT_MAX_MESSAGE_SIZE = 40           # KB

# These format strings will be expanded w.r.t. the dictionary for the
# mailing list instance.
DEFAULT_SUBJECT_PREFIX  = "[%(real_name)s] "
# DEFAULT_SUBJECT_PREFIX = "[%(real_name)s %%d]" # for numbering
DEFAULT_MSG_HEADER = ""
DEFAULT_MSG_FOOTER = """-- 
%(real_name)s mailing list
%(real_name)s@%(host_name)s
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
"""

# Where to put subject prefix for 'Re:' messages:
#
#     old style: Re: [prefix] test
#     new style: [prefix 123] Re: test ... (number is optional)
#
# Old style is default for backward compatibility.  New style is forced if a
# list owner set %d (numbering) in prefix.  If the site owner had applied new
# style patch (from SF patch area) before, he/she may want to set this No in
# mm_cfg.py.
OLD_STYLE_PREFIXING = Yes

# Scrub regular delivery
DEFAULT_SCRUB_NONDIGEST = False

# Mail command processor will ignore mail command lines after designated max.
DEFAULT_MAIL_COMMANDS_MAX_LINES = 25

# Is the list owner notified of admin requests immediately by mail, as well as
# by daily pending-request reminder?
DEFAULT_ADMIN_IMMED_NOTIFY = Yes

# Is the list owner notified of subscribes/unsubscribes?
DEFAULT_ADMIN_NOTIFY_MCHANGES = No

# Discard held messages after this days
DEFAULT_MAX_DAYS_TO_HOLD = 0

# Should list members, by default, have their posts be moderated?
DEFAULT_DEFAULT_MEMBER_MODERATION = No

# Should non-member posts which are auto-discarded also be forwarded to the
# moderators?
DEFAULT_FORWARD_AUTO_DISCARDS = Yes

# Shall dmarc_moderation_action be applied to messages From: domains with
# a DMARC policy of quarantine as well as reject?  This sets the default for
# the list setting that controls it.
DEFAULT_DMARC_QUARANTINE_MODERATION_ACTION = Yes

# Default action for posts whose From: address domain has a DMARC policy of
# reject or quarantine.  See DEFAULT_FROM_IS_LIST below.  Whatever is set as
# the default here precludes the list owner from setting a lower value, however
# an existing list won't be changed until the first time "Submit Your Changes"
# is pressed on the list's Privacy options... -> Sender filters page.
# 0 = Accept
# 1 = Munge From
# 2 = Wrap Message
# 3 = Reject
# 4 = Discard
DEFAULT_DMARC_MODERATION_ACTION = 0

# Domain owners can publish DMARC p=none policy in order to request that
# reports of DMARC failures be sent but special action not be taken on
# messages From: their domain that fail DMARC.  This can result in over
# estimation of the number of messages that would be quarantined or rejected
# with a stronger DMARC policy if such a policy would result in message
# modification because dmarc_moderation_action is 1 or 2.  Thus, there is
# a list setting to apply dmarc_moderaction_action of 1 or 2 to messages
# From: domains with DMARC p=none.  Setting this to Yes is only effective if
# dmarc_quarantine_moderaction_action is also Yes.  The following is the
# default for this setting for new lists.
DEFAULT_DMARC_NONE_MODERATION_ACTION = No

# Default for text to be added to a separate text/plain part preceding the
# message/rfc822 part containing the original message when
# dmarc_moderation_action is Wrap Message.
DEFAULT_DMARC_WRAPPED_MESSAGE_TEXT = ''

# Parameters for DMARC DNS lookups. If you are seeing 'DNSException:
# Unable to query DMARC policy ...' entries in your error log, you may need
# to adjust these.
# The time to wait for a response from a name server before timeout.
DMARC_RESOLVER_TIMEOUT = seconds(3)
# The total time to spend trying to get an answer to the question.
DMARC_RESOLVER_LIFETIME = seconds(5)

# A URL from which to retrieve the data for the algorithm that computes
# Organizational Domains for DMARC policy lookup purposes.  This can be
# anything handled by the Python urllib2.urlopen function.  See
# https://publicsuffix.org/list/ for info.
DMARC_ORGANIZATIONAL_DOMAIN_DATA_URL = \
'https://publicsuffix.org/list/public_suffix_list.dat'

# Should the list server auto-moderate members who post too frequently
# This is intended to stop people who join a list and then use a bot to
# send many spam messages in a short interval.  These are default settings
# for new lists.  See the web admin Privacy options -> Sender filters page
# and the Details for member_verbosity_threshold and member_verbosity_interval
# links for more information.
# DEFAULT_MEMBER_VERBOSITY_INTERVAL = number of seconds to track posts
# DEFAULT_MEMBER_VERBOSITY_THRESHOLD = number of allowed posts per interval
#                                     (0 to disable).
DEFAULT_MEMBER_VERBOSITY_INTERVAL = 300
DEFAULT_MEMBER_VERBOSITY_THRESHOLD = 0

# This controls how often to clean old post time entries from the dictionary
# used to implement the member verbosity feature. This is a compromise between
# using resources for cleaning and allowing the dictionary to grow very large.
# The setting is the number of passes through the code before the dictionary
# is cleaned.
VERBOSE_CLEAN_LIMIT = 1000

# What domains should be considered equivalent when testing list membership
# for posting/moderation.
# If two poster addresses with the same local part but
# different domains are to be considered equivalents for list
# membership tests, the domains are put in the list's equivalent_domains.
# This provides a default value for new lists.
# The format is one or more groups of equivalent domains.  Within a group,
# the domains are separated by commas and multiple groups are
# separated by semicolons. White space is ignored.
# For example:
#
#    'example.com,mail.example.com;mac.com,me.com,icloud.com'
#
# In this example, if user@example.com is a list member,
# a post from user@mail.example.com will be treated as if it is
# from user@example.com for list membership/moderation purposes,
# and likewise, if user@me.com is a list member, posts from
# user@mac.com or user@icloud.com will be treated as if from
# user@me.com.
DEFAULT_EQUIVALENT_DOMAINS = ''

# What should happen to non-member posts which are do not match explicit
# non-member actions?
# 0 = Accept
# 1 = Hold
# 2 = Reject
# 3 = Discard
DEFAULT_GENERIC_NONMEMBER_ACTION = 1

# Bounce if 'To:', 'Cc:', or 'Resent-To:' fields don't explicitly name list?
# This is an anti-spam measure
DEFAULT_REQUIRE_EXPLICIT_DESTINATION = Yes

# Alternate names acceptable as explicit destinations for this list.
DEFAULT_ACCEPTABLE_ALIASES ="""
"""
# For mailing lists that have only other mailing lists for members:
DEFAULT_UMBRELLA_LIST = No

# For umbrella lists, the suffix for the account part of address for
# administrative notices (subscription confirmations, password reminders):
DEFAULT_UMBRELLA_MEMBER_ADMIN_SUFFIX = "-owner"

# Exclude/include (sibling) lists for non-digest delivery.
DEFAULT_REGULAR_EXCLUDE_LISTS = []
DEFAULT_REGULAR_INCLUDE_LISTS = []
DEFAULT_REGULAR_EXCLUDE_IGNORE = True
ALLOW_CROSS_DOMAIN_SIBLING = False

# This variable controls whether monthly password reminders are sent.
DEFAULT_SEND_REMINDERS = Yes

# Send welcome messages to new users?
DEFAULT_SEND_WELCOME_MSG = Yes

# Send goodbye messages to unsubscribed members?
DEFAULT_SEND_GOODBYE_MSG = Yes

# The following is a three way setting.  It sets the default for the list's
# from_is_list policy which is applied to all posts except those for which a
# dmarc_moderation_action other than accept applies.
# 0 -> Do not rewrite the From: or wrap the message.
# 1 -> Rewrite the From: header of posts replacing the posters address with
#      that of the list.  Also see REMOVE_DKIM_HEADERS above.
# 2 -> Do not modify the From: of the message, but wrap the message in an outer
#      message From the list address.
DEFAULT_FROM_IS_LIST = 0

# Wipe sender information, and make it look like the list-admin
# address sends all messages
DEFAULT_ANONYMOUS_LIST = No

# {header-name: regexp} spam filtering - we include some for example sake.
DEFAULT_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
"""

# Mailman can be configured to "munge" Reply-To: headers for any passing
# messages.  One the one hand, there are a lot of good reasons not to munge
# Reply-To: but on the other, people really seem to want this feature.  See
# the help for reply_goes_to_list in the web UI for links discussing the
# issue.
# 0 - Reply-To: not munged
# 1 - Reply-To: set back to the list
# 2 - Reply-To: set to an explicit value (reply_to_address)
DEFAULT_REPLY_GOES_TO_LIST = 0

# Mailman can be configured to strip any existing Reply-To: header, or simply
# extend any existing Reply-To: with one based on the above setting.
DEFAULT_FIRST_STRIP_REPLY_TO = No

# SUBSCRIBE POLICY
# 0 - open list (only when ALLOW_OPEN_SUBSCRIBE is set to 1) **
# 1 - confirmation required for subscribes
# 2 - admin approval required for subscribes
# 3 - both confirmation and admin approval required
#
# ** please do not choose option 0 if you are not allowing open
# subscribes (next variable)
DEFAULT_SUBSCRIBE_POLICY = 1

# Does this site allow completely unchecked subscriptions?
ALLOW_OPEN_SUBSCRIBE = No

# This is the default list of addresses and regular expressions (beginning
# with ^) that are exempt from approval if SUBSCRIBE_POLICY is 2 or 3.
DEFAULT_SUBSCRIBE_AUTO_APPROVAL = []

# The default policy for unsubscriptions.  0 (unmoderated unsubscribes) is
# highly recommended!
# 0 - unmoderated unsubscribes
# 1 - unsubscribes require approval
DEFAULT_UNSUBSCRIBE_POLICY = 0

# Private_roster == 0: anyone can see, 1: members only, 2: admin only.
DEFAULT_PRIVATE_ROSTER = 1

# When exposing members, make them unrecognizable as email addrs, so
# web-spiders can't pick up addrs for spam purposes.
DEFAULT_OBSCURE_ADDRESSES = Yes

# RFC 2369 defines List-* headers which are added to every message sent
# through to the mailing list membership.  These are a very useful aid to end
# users and should always be added.  However, not all MUAs are compliant and
# if a list's membership has many such users, they may clamor for these
# headers to be suppressed.  By setting this variable to Yes, list owners will
# be given the option to suppress these headers.  By setting it to No, list
# owners will not be given the option to suppress these headers (although some
# header suppression may still take place, i.e. for announce-only lists, or
# lists with no archives).
ALLOW_RFC2369_OVERRIDES = Yes

# RFC 2822 suggests that not adding a Sender header when Mailman is the agent
# responsible for the actual transmission is a breach of the RFC.  However,
# some MUAs (notably Outlook) tend to display the Sender header instead of the
# From details, confusing users and actually losing the original sender when
# forwarding mail.  By setting this variable to Yes, list owners will be
# given the option to avoid setting this header.
ALLOW_SENDER_OVERRIDES = Yes

# Defaults for content filtering on mailing lists.  DEFAULT_FILTER_CONTENT is
# a flag which if set to true, turns on content filtering.
DEFAULT_FILTER_CONTENT = No

# DEFAULT_FILTER_MIME_TYPES is a list of MIME types to be removed.  This is a
# list of strings of the format "maintype/subtype" or simply "maintype".
# E.g. "text/html" strips all html attachments while "image" strips all image
# types regardless of subtype (jpeg, gif, etc.).
DEFAULT_FILTER_MIME_TYPES = []

# DEFAULT_PASS_MIME_TYPES is a list of MIME types to be passed through.
# Format is the same as DEFAULT_FILTER_MIME_TYPES
DEFAULT_PASS_MIME_TYPES = ['multipart',
                           'message/rfc822',
                           'application/pgp-signature',
                           'text/plain',
                          ]

# DEFAULT_FILTER_FILENAME_EXTENSIONS is a list of filename extensions to be
# removed. It is useful because many viruses fake their content-type as
# harmless ones while keep their extension as executable and expect to be
# executed when victims 'open' them.
DEFAULT_FILTER_FILENAME_EXTENSIONS = [
    'exe', 'bat', 'cmd', 'com', 'pif', 'scr', 'vbs', 'cpl'
    ]

# DEFAULT_PASS_FILENAME_EXTENSIONS is a list of filename extensions to be
# passed through. Format is the same as DEFAULT_FILTER_FILENAME_EXTENSIONS.
DEFAULT_PASS_FILENAME_EXTENSIONS = []

# Replace multipart/alternative with its first alternative.
DEFAULT_COLLAPSE_ALTERNATIVES = Yes

# Whether text/html should be converted to text/plain after content filtering
# is performed.  Conversion is done according to HTML_TO_PLAIN_TEXT_COMMAND
DEFAULT_CONVERT_HTML_TO_PLAINTEXT = Yes

# Default action to take on filtered messages.
# 0 = Discard, 1 = Reject, 2 = Forward, 3 = Preserve
DEFAULT_FILTER_ACTION = 0

# Whether to allow list owners to preserve content filtered messages to a
# special queue on the disk.
OWNERS_CAN_PRESERVE_FILTERED_MESSAGES = Yes

# Check for administrivia in messages sent to the main list?
DEFAULT_ADMINISTRIVIA = Yes

# The process which avoids sending a list copy of a message to a member who
# is also directly addressed in To: or Cc: can drop the address from Cc: to
# avoid growing a long Cc: list in long threads.  This can be undesirable as
# it can break DKIM signatures and possibly cause confusion.  To avoid changes
# to Cc: headers, set the list's drop_cc to No.
DEFAULT_DROP_CC = Yes



#####
# Digestification defaults.  Same caveat applies here as with list defaults.
#####

# Will list be available in non-digested form?
DEFAULT_NONDIGESTABLE = Yes

# Will list be available in digested form?
DEFAULT_DIGESTABLE = Yes
DEFAULT_DIGEST_HEADER = ""
DEFAULT_DIGEST_FOOTER = """%(real_name)s mailing list
%(real_name)s@%(host_name)s
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s
"""

DEFAULT_DIGEST_IS_DEFAULT = No
DEFAULT_MIME_IS_DEFAULT_DIGEST = No
DEFAULT_DIGEST_SIZE_THRESHHOLD = 30     # KB
DEFAULT_DIGEST_SEND_PERIODIC = Yes

# Headers which should be kept in both RFC 1153 (plain) and MIME digests.  RFC
# 1153 also specifies these headers in this exact order, so order matters.
MIME_DIGEST_KEEP_HEADERS = [
    'Date', 'From', 'To', 'Cc', 'Subject', 'Message-ID', 'Keywords',
    # I believe we should also keep these headers though.
    'In-Reply-To', 'References', 'Content-Type', 'MIME-Version',
    'Content-Transfer-Encoding', 'Precedence', 'Reply-To', 'List-Post',
    # Mailman 2.0 adds these headers
    'Message',
    ]

# The order in this list controls the order of the RFC 1153 digest headers.
# Also, any headers in this list will be kept in the MIME digest even if they
# don't appear in the MIME list above.  Finally, headers appearing in both
# lists must be casewise the same or duplication can result in the digest.
PLAIN_DIGEST_KEEP_HEADERS = [
    'Message',
    # RFC 1153 headers in order
    'Date', 'From', 'To', 'Cc', 'Subject', 'Message-ID', 'Keywords',
    'Content-Type',
    ]



#####
# Bounce processing defaults.  Same caveat applies here as with list defaults.
#####

# Should we do any bounced mail response at all?
DEFAULT_BOUNCE_PROCESSING = Yes

# How often should the bounce qrunner process queued detected bounces?
REGISTER_BOUNCES_EVERY = minutes(15)

# Bounce processing works like this: when a bounce from a member is received,
# we look up the `bounce info' for this member. If there is no bounce info,
# this is the first bounce we've received from this member.  In that case, we
# record today's date, and initialize the bounce score (see below for initial
# value).
#
# If there is existing bounce info for this member, we look at the last bounce
# receive date.  If this date is farther away from today than the `bounce
# expiration interval', we throw away all the old data and initialize the
# bounce score as if this were the first bounce from the member.
#
# Otherwise, we increment the bounce score.  If we can determine whether the
# bounce was soft or hard (i.e. transient or fatal), then we use a score value
# of 0.5 for soft bounces and 1.0 for hard bounces.  Note that we only score
# one bounce per day.  If the bounce score is then greater than the `bounce
# threshold' we disable the member's address.
#
# After disabling the address, we can send warning messages to the member,
# providing a confirmation cookie/url for them to use to re-enable their
# delivery.  After a configurable period of time, we'll delete the address.
# When we delete the address due to bouncing, we'll send one last message to
# the member.

# Bounce scores greater than this value get disabled.
DEFAULT_BOUNCE_SCORE_THRESHOLD = 5.0

# Bounce information older than this interval is considered stale, and is
# discarded.
DEFAULT_BOUNCE_INFO_STALE_AFTER = days(7)

# The number of notifications to send to the disabled/removed member before we
# remove them from the list.  A value of 0 means we remove the address
# immediately (with one last notification).  Note that the first one is sent
# upon change of status to disabled.
DEFAULT_BOUNCE_YOU_ARE_DISABLED_WARNINGS = 3

# The interval of time between disabled warnings.
DEFAULT_BOUNCE_YOU_ARE_DISABLED_WARNINGS_INTERVAL = days(7)

# Does the list owner get messages to the -bounces (and -admin) address that
# failed to match by the bounce detector?
DEFAULT_BOUNCE_UNRECOGNIZED_GOES_TO_LIST_OWNER = Yes

# Does the list owner get a copy of every recognized bounce that increments
# the score for a list member but doesn't result in a disable or probe?
DEFAULT_BOUNCE_NOTIFY_OWNER_ON_BOUNCE_INCREMENT = No

# Notifications on bounce actions.  The first specifies whether the list owner
# should get a notification when a member is disabled due to bouncing, while
# the second specifies whether the owner should get one when the member is
# removed due to bouncing.
DEFAULT_BOUNCE_NOTIFY_OWNER_ON_DISABLE = Yes
DEFAULT_BOUNCE_NOTIFY_OWNER_ON_REMOVAL = Yes



#####
# General time limits
#####

# Default length of time a pending request is live before it is evicted from
# the pending database.
PENDING_REQUEST_LIFE = days(3)

# How long should messages which have delivery failures continue to be
# retried?  After this period of time, a message that has failed recipients
# will be dequeued and those recipients will never receive the message.
DELIVERY_RETRY_PERIOD = days(5)

# How long should we wait before we retry a temporary delivery failure?
# Because RetryRunner sleeps for 15 minutes between processes of its queue,
# whatever is put here is effectively rounded up to the next integer multiple
# of 15 minutes.
DELIVERY_RETRY_WAIT = hours(1)



#####
# Lock management defaults
#####

# These variables control certain aspects of lock acquisition and retention.
# They should be tuned as appropriate for your environment.  All variables are
# specified in units of floating point seconds.  YOU MAY NEED TO TUNE THESE
# VARIABLES DEPENDING ON THE SIZE OF YOUR LISTS, THE PERFORMANCE OF YOUR
# HARDWARE, NETWORK AND GENERAL MAIL HANDLING CAPABILITIES, ETC.

# Set this to On to turn on MailList object lock debugging messages, which
# will be written to logs/locks.  If you think you're having lock problems, or
# just want to tune the locks for your system, turn on lock debugging.
LIST_LOCK_DEBUGGING = Off

# This variable specifies how long the lock will be retained for a specific
# operation on a mailing list.  Watch your logs/lock file and if you see a lot
# of lock breakages, you might need to bump this up.  However if you set this
# too high, a faulty script (or incorrect use of bin/withlist) can prevent the
# list from being used until the lifetime expires.  This is probably one of
# the most crucial tuning variables in the system.
LIST_LOCK_LIFETIME = hours(5)

# This variable specifies how long an attempt will be made to acquire a list
# lock by the incoming qrunner process.  If the lock acquisition times out,
# the message will be re-queued for later delivery.
LIST_LOCK_TIMEOUT = seconds(10)

# Set this to On to turn on lock debugging messages for the pending requests
# database, which will be written to logs/locks.  If you think you're having
# lock problems, or just want to tune the locks for your system, turn on lock
# debugging.
PENDINGDB_LOCK_DEBUGGING = Off



#####
# Nothing below here is user configurable.  Most of these values are in this
# file for internal system convenience.  Don't change any of them or override
# any of them in your mm_cfg.py file!
#####

# These directories are used to find various important files in the Mailman
# installation.  PREFIX and EXEC_PREFIX are set by configure and should point
# to the installation directory of the Mailman package.
PYTHON          = '/usr/local/bin/python2.7'
PREFIX          = '/usr/local/mailman'
EXEC_PREFIX     = '${prefix}'
VAR_PREFIX      = '/usr/local/mailman'

# Work around a bogus autoconf 2.12 bug
if EXEC_PREFIX == '${prefix}':
    EXEC_PREFIX = PREFIX

# CGI extension, change using configure script
CGIEXT = ''

# Group id that group-owns the Mailman installation
MAILMAN_USER = 'mailman'
MAILMAN_GROUP = 'mailman'

# Enumeration for Mailman cgi widget types
Toggle      = 1
Radio       = 2
String      = 3
Text        = 4
Email       = 5
EmailList   = 6
Host        = 7
Number      = 8
FileUpload  = 9
Select      = 10
Topics      = 11
Checkbox    = 12
# An "extended email list".  Contents must be an email address or a ^-prefixed
# regular expression.  Used in the sender moderation text boxes.
EmailListEx = 13
# Extended spam filter widget
HeaderFilter  = 14

# Actions
DEFER = 0
APPROVE = 1
REJECT = 2
DISCARD = 3
SUBSCRIBE = 4
UNSUBSCRIBE = 5
ACCEPT = 6
HOLD = 7

# admindb summary sort button settings.  All must evaluate to True.
SSENDER = 1
SSENDERTIME = 2
STIME = 3

# Standard text field width
TEXTFIELDWIDTH = 40

# Bitfield for user options.  See DEFAULT_NEW_MEMBER_OPTIONS above to set
# defaults for all new lists.
Digests             = 0 # handled by other mechanism, doesn't need a flag.
DisableDelivery     = 1 # Obsolete; use set/getDeliveryStatus()
DontReceiveOwnPosts = 2 # Non-digesters only
AcknowledgePosts    = 4
DisableMime         = 8 # Digesters only
ConcealSubscription = 16
SuppressPasswordReminder = 32
ReceiveNonmatchingTopics = 64
Moderate = 128
DontReceiveDuplicates = 256

# A mapping between short option tags and their flag
OPTINFO = {'hide'    : ConcealSubscription,
           'nomail'  : DisableDelivery,
           'ack'     : AcknowledgePosts,
           'notmetoo': DontReceiveOwnPosts,
           'digest'  : 0,
           'plain'   : DisableMime,
           'noremind': SuppressPasswordReminder,
           'nmtopics': ReceiveNonmatchingTopics,
           'mod'     : Moderate,
           'nodupes' : DontReceiveDuplicates
           }

# Authentication contexts.
#
# Mailman defines the following roles:

# - User, a normal user who has no permissions except to change their personal
#   option settings
# - List creator, someone who can create and delete lists, but cannot
#   (necessarily) configure the list.
# - List poster, someone who can pre-approve her/his own posts to the list by
#   including an Approved: or X-Approved: header or first body line pseudo-
#   header containing the poster password. The list admin and moderator
#   passwords can also be used for this purpose, but the poster password can
#   only be used for this and nothing else.
# - List moderator, someone who can tend to pending requests such as
#   subscription requests, or held messages
# - List administrator, someone who has total control over a list, can
#   configure it, modify user options for members of the list, subscribe and
#   unsubscribe members, etc.
# - Site administrator, someone who has total control over the entire site and
#   can do any of the tasks mentioned above.  This person usually also has
#   command line access.

UnAuthorized = 0
AuthUser = 1          # Joe Shmoe User
AuthCreator = 2       # List Creator / Destroyer
AuthListAdmin = 3     # List Administrator (total control over list)
AuthListModerator = 4 # List Moderator (can only handle held requests)
AuthSiteAdmin = 5     # Site Administrator (total control over everything)
AuthListPoster = 6    # List poster (Approved: <pw> header in posts only)

# Useful directories
LIST_DATA_DIR   = os.path.join(VAR_PREFIX, 'lists')
LOG_DIR         = os.path.join(VAR_PREFIX, 'logs')
LOCK_DIR        = os.path.join(VAR_PREFIX, 'locks')
DATA_DIR        = os.path.join(VAR_PREFIX, 'data')
SPAM_DIR        = os.path.join(VAR_PREFIX, 'spam')
WRAPPER_DIR     = os.path.join(EXEC_PREFIX, 'mail')
BIN_DIR         = os.path.join(PREFIX, 'bin')
SCRIPTS_DIR     = os.path.join(PREFIX, 'scripts')
TEMPLATE_DIR    = os.path.join(PREFIX, 'templates')
MESSAGES_DIR    = os.path.join(PREFIX, 'messages')
PUBLIC_ARCHIVE_FILE_DIR  = os.path.join(VAR_PREFIX, 'archives', 'public')
PRIVATE_ARCHIVE_FILE_DIR = os.path.join(VAR_PREFIX, 'archives', 'private')

# Directories used by the qrunner subsystem
QUEUE_DIR       = os.path.join(VAR_PREFIX, 'qfiles')
INQUEUE_DIR     = os.path.join(QUEUE_DIR, 'in')
OUTQUEUE_DIR    = os.path.join(QUEUE_DIR, 'out')
CMDQUEUE_DIR    = os.path.join(QUEUE_DIR, 'commands')
BOUNCEQUEUE_DIR = os.path.join(QUEUE_DIR, 'bounces')
NEWSQUEUE_DIR   = os.path.join(QUEUE_DIR, 'news')
ARCHQUEUE_DIR   = os.path.join(QUEUE_DIR, 'archive')
SHUNTQUEUE_DIR  = os.path.join(QUEUE_DIR, 'shunt')
VIRGINQUEUE_DIR = os.path.join(QUEUE_DIR, 'virgin')
BADQUEUE_DIR    = os.path.join(QUEUE_DIR, 'bad')
RETRYQUEUE_DIR  = os.path.join(QUEUE_DIR, 'retry')
MAILDIR_DIR     = os.path.join(QUEUE_DIR, 'maildir')

# Other useful files
PIDFILE = os.path.join(DATA_DIR, 'master-qrunner.pid')
SITE_PW_FILE = os.path.join(DATA_DIR, 'adm.pw')
LISTCREATOR_PW_FILE = os.path.join(DATA_DIR, 'creator.pw')

# Import a bunch of version numbers
from Version import *

# Vgg: Language descriptions and charsets dictionary, any new supported
# language must have a corresponding entry here. Key is the name of the
# directories that hold the localized texts. Data are tuples with first
# element being the description, as described in the catalogs, and second
# element is the language charset.  I have chosen code from /usr/share/locale
# in my GNU/Linux. :-)
def _(s):
    return s

LC_DESCRIPTIONS = {}

def add_language(code, description, charset, direction='ltr'):
    LC_DESCRIPTIONS[code] = (description, charset, direction)

add_language('ar',    _('Arabic'),              'utf-8',       'rtl')
add_language('ast',   _('Asturian'),            'iso-8859-1',  'ltr')
add_language('ca',    _('Catalan'),             'utf-8',       'ltr')
add_language('cs',    _('Czech'),               'iso-8859-2',  'ltr')
add_language('da',    _('Danish'),              'iso-8859-1',  'ltr')
add_language('de',    _('German'),              'iso-8859-1',  'ltr')
add_language('en',    _('English (USA)'),       'us-ascii',    'ltr')
add_language('eo',    _('Esperanto'),           'utf-8',       'ltr')
add_language('es',    _('Spanish (Spain)'),     'iso-8859-1',  'ltr')
add_language('et',    _('Estonian'),            'iso-8859-15', 'ltr')
add_language('eu',    _('Euskara'),             'iso-8859-15', 'ltr') # Basque
add_language('fa',    _('Persian'),             'utf-8',       'rtl')
add_language('fi',    _('Finnish'),             'iso-8859-1',  'ltr')
add_language('fr',    _('French'),              'iso-8859-1',  'ltr')
add_language('gl',    _('Galician'),            'utf-8',       'ltr')
add_language('el',    _('Greek'),               'iso-8859-7',  'ltr')
add_language('he',    _('Hebrew'),              'utf-8',       'rtl')
add_language('hr',    _('Croatian'),            'iso-8859-2',  'ltr')
add_language('hu',    _('Hungarian'),           'iso-8859-2',  'ltr')
add_language('ia',    _('Interlingua'),         'iso-8859-15', 'ltr')
add_language('it',    _('Italian'),             'iso-8859-1',  'ltr')
add_language('ja',    _('Japanese'),            'euc-jp',      'ltr')
add_language('ko',    _('Korean'),              'euc-kr',      'ltr')
add_language('lt',    _('Lithuanian'),          'iso-8859-13', 'ltr')
add_language('nl',    _('Dutch'),               'iso-8859-1',  'ltr')
add_language('no',    _('Norwegian'),           'iso-8859-1',  'ltr')
add_language('pl',    _('Polish'),              'iso-8859-2',  'ltr')
add_language('pt',    _('Portuguese'),          'iso-8859-1',  'ltr')
add_language('pt_BR', _('Portuguese (Brazil)'), 'iso-8859-1',  'ltr')
add_language('ro',    _('Romanian'),            'utf-8',       'ltr')
add_language('ru',    _('Russian'),             'utf-8',       'ltr')
add_language('sk',    _('Slovak'),              'utf-8',       'ltr')
add_language('sl',    _('Slovenian'),           'iso-8859-2',  'ltr')
add_language('sr',    _('Serbian'),             'utf-8',       'ltr')
add_language('sv',    _('Swedish'),             'iso-8859-1',  'ltr')
add_language('tr',    _('Turkish'),             'iso-8859-9',  'ltr')
add_language('uk',    _('Ukrainian'),           'utf-8',       'ltr')
add_language('vi',    _('Vietnamese'),          'utf-8',       'ltr')
add_language('zh_CN', _('Chinese (China)'),     'utf-8',       'ltr')
add_language('zh_TW', _('Chinese (Taiwan)'),    'utf-8',       'ltr')

del _
