diff options
| author | Barry Warsaw | 2010-08-12 12:58:24 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2010-08-12 12:58:24 -0400 |
| commit | 81663e54791c4e0ccbf54c89b168d8b11f05eba8 (patch) | |
| tree | c976878b745bb96fff834ae3959e38d6eef6b446 /src | |
| parent | 255c63fd28671c6b0366ef745db0b08fdfec3267 (diff) | |
| download | mailman-81663e54791c4e0ccbf54c89b168d8b11f05eba8.tar.gz mailman-81663e54791c4e0ccbf54c89b168d8b11f05eba8.tar.zst mailman-81663e54791c4e0ccbf54c89b168d8b11f05eba8.zip | |
Diffstat (limited to 'src')
| -rw-r--r-- | src/mailman/interfaces/mailinglist.py | 56 | ||||
| -rw-r--r-- | src/mailman/model/mailinglist.py | 6 | ||||
| -rw-r--r-- | src/mailman/rest/docs/configuration.txt | 81 | ||||
| -rw-r--r-- | src/mailman/rest/helpers.py | 14 | ||||
| -rw-r--r-- | src/mailman/rest/lists.py | 35 |
5 files changed, 184 insertions, 8 deletions
diff --git a/src/mailman/interfaces/mailinglist.py b/src/mailman/interfaces/mailinglist.py index 6f88ef64c..26373eb11 100644 --- a/src/mailman/interfaces/mailinglist.py +++ b/src/mailman/interfaces/mailinglist.py @@ -324,6 +324,58 @@ class IMailingList(Interface): notifications. """) + # Autoresponses. + + autoresponse_grace_period = Attribute( + """Time period (in days) between automatic responses. + + When this mailing list is set to send an auto-response for messages + sent to mailing list posts, the mailing list owners, or the `-request` + address, such reponses will not be sent to the same user more than + once during the grace period. Set to zero (or a negative value) for + no grace period (i.e. auto-respond to every message). + """) + + autorespond_owner = Attribute( + """How should the mailing list automatically respond to messages sent + to the -owner or -moderator address? + + Options are: + * No response sent + * Send a response and discard the original messge + * Send a response and continue processing the original message + """) + + autoresponse_owner_text = Attribute( + """The text sent in an autoresponse to the owner or moderator.""") + + autorespond_postings = Attribute( + """How should the mailing list automatically respond to messages sent + to the list's posting address? + + Options are: + * No response sent + * Send a response and discard the original messge + * Send a response and continue processing the original message + """) + + autoresponse_postings_text = Attribute( + """The text sent in an autoresponse to the list's posting address.""") + + autorespond_requests = Attribute( + """How should the mailing list automatically respond to messages sent + to the list's `-request` address? + + Options are: + * No response sent + * Send a response and discard the original messge + * Send a response and continue processing the original message + """) + + autoresponse_request_text = Attribute( + """The text sent in an autoresponse to the list's `-request` + address.""") + # Processing. pipeline = Attribute( @@ -386,7 +438,7 @@ class IMailingList(Interface): to a sequence to change it, or to None to empty it. Pass types are consulted after filter types, and only if `pass_types` is non-empty. """) - + filter_extensions = Attribute( """Sequence of file extensions that should be filtered out. @@ -400,7 +452,7 @@ class IMailingList(Interface): Pass extensions are consulted after filter extensions, and only if `pass_extensions` is non-empty. """) - + diff --git a/src/mailman/model/mailinglist.py b/src/mailman/model/mailinglist.py index f81b5099a..e7dec473e 100644 --- a/src/mailman/model/mailinglist.py +++ b/src/mailman/model/mailinglist.py @@ -93,9 +93,9 @@ class MailingList(Model): admin_immed_notify = Bool() admin_notify_mchanges = Bool() administrivia = Bool() - archive = Bool() - archive_private = Bool() - archive_volume_frequency = Int() + archive = Bool() # XXX + archive_private = Bool() # XXX + archive_volume_frequency = Int() # XXX # Automatic responses. autoresponse_grace_period = TimeDelta() autorespond_owner = Enum() diff --git a/src/mailman/rest/docs/configuration.txt b/src/mailman/rest/docs/configuration.txt index 874372478..54d29fead 100644 --- a/src/mailman/rest/docs/configuration.txt +++ b/src/mailman/rest/docs/configuration.txt @@ -20,6 +20,13 @@ All readable attributes for a list are available on a sub-resource. administrivia: True advertised: True anonymous_list: False + autorespond_owner: none + autorespond_postings: none + autorespond_requests: none + autoresponse_grace_period: 90d + autoresponse_owner_text: + autoresponse_postings_text: + autoresponse_request_text: bounces_address: test-one-bounces@example.com collapse_alternatives: True convert_html_to_plaintext: False @@ -65,6 +72,13 @@ writable attributes in one request. ... administrivia=False, ... advertised=False, ... anonymous_list=True, + ... autorespond_owner='respond_and_discard', + ... autorespond_postings='respond_and_continue', + ... autorespond_requests='respond_and_discard', + ... autoresponse_grace_period='45d', + ... autoresponse_owner_text='the owner', + ... autoresponse_postings_text='the mailing list', + ... autoresponse_request_text='the robot', ... real_name='Fnords', ... include_rfc2369_headers=False, ... include_list_post_header=False, @@ -89,6 +103,13 @@ These values are changed permanently. administrivia: False advertised: False anonymous_list: True + autorespond_owner: respond_and_discard + autorespond_postings: respond_and_continue + autorespond_requests: respond_and_discard + autoresponse_grace_period: 45d + autoresponse_owner_text: the owner + autoresponse_postings_text: the mailing list + autoresponse_request_text: the robot ... collapse_alternatives: False convert_html_to_plaintext: True @@ -115,6 +136,13 @@ be included. It is an error to leave one out (e.g. `pipeline`)... ... administrivia=False, ... advertised=False, ... anonymous_list=True, + ... autorespond_owner='respond_and_discard', + ... autorespond_postings='respond_and_continue', + ... autorespond_requests='respond_and_discard', + ... autoresponse_grace_period='45d', + ... autoresponse_owner_text='the owner', + ... autoresponse_postings_text='the mailing list', + ... autoresponse_request_text='the robot', ... real_name='Fnords', ... include_rfc2369_headers=False, ... include_list_post_header=False, @@ -140,6 +168,13 @@ be included. It is an error to leave one out (e.g. `pipeline`)... ... administrivia=False, ... advertised=False, ... anonymous_list=True, + ... autorespond_owner='respond_and_discard', + ... autorespond_postings='respond_and_continue', + ... autorespond_requests='respond_and_discard', + ... autoresponse_grace_period='45d', + ... autoresponse_owner_text='the owner', + ... autoresponse_postings_text='the mailing list', + ... autoresponse_request_text='the robot', ... real_name='Fnords', ... include_rfc2369_headers=False, ... include_list_post_header=False, @@ -164,6 +199,13 @@ It is also an error to spell an attribute value incorrectly... ... administrivia=False, ... advertised=False, ... anonymous_list=True, + ... autorespond_owner='respond_and_discard', + ... autorespond_postings='respond_and_continue', + ... autorespond_requests='respond_and_discard', + ... autoresponse_grace_period='45d', + ... autoresponse_owner_text='the owner', + ... autoresponse_postings_text='the mailing list', + ... autoresponse_request_text='the robot', ... real_name='Fnords', ... include_rfc2369_headers=False, ... include_list_post_header=False, @@ -178,7 +220,7 @@ It is also an error to spell an attribute value incorrectly... ... HTTPError: HTTP Error 400: Bad Request -...or to name a pipeline that doesn't exist. +...or to name a pipeline that doesn't exist... >>> dump_json('http://localhost:8001/3.0/lists/' ... 'test-one@example.com/config', @@ -187,6 +229,43 @@ It is also an error to spell an attribute value incorrectly... ... admin_notify_mchanges=True, ... advertised=False, ... anonymous_list=True, + ... autorespond_owner='respond_and_discard', + ... autorespond_postings='respond_and_continue', + ... autorespond_requests='respond_and_discard', + ... autoresponse_grace_period='45d', + ... autoresponse_owner_text='the owner', + ... autoresponse_postings_text='the mailing list', + ... autoresponse_request_text='the robot', + ... real_name='Fnords', + ... include_rfc2369_headers=False, + ... include_list_post_header=False, + ... digest_size_threshold=10.5, + ... pipeline='dummy', + ... filter_content=True, + ... convert_html_to_plaintext=True, + ... collapse_alternatives=False, + ... ), + ... 'PUT') + Traceback (most recent call last): + ... + HTTPError: HTTP Error 400: Bad Request + +...or to name an invalid auto-response enumeration value. + + >>> dump_json('http://localhost:8001/3.0/lists/' + ... 'test-one@example.com/config', + ... dict( + ... admin_immed_notify=False, + ... admin_notify_mchanges=True, + ... advertised=False, + ... anonymous_list=True, + ... autorespond_owner='do_not_respond', + ... autorespond_postings='respond_and_continue', + ... autorespond_requests='respond_and_discard', + ... autoresponse_grace_period='45d', + ... autoresponse_owner_text='the owner', + ... autoresponse_postings_text='the mailing list', + ... autoresponse_request_text='the robot', ... real_name='Fnords', ... include_rfc2369_headers=False, ... include_list_post_header=False, diff --git a/src/mailman/rest/helpers.py b/src/mailman/rest/helpers.py index 4bef720ef..c6a020f61 100644 --- a/src/mailman/rest/helpers.py +++ b/src/mailman/rest/helpers.py @@ -32,7 +32,8 @@ __all__ = [ import json import hashlib -from datetime import datetime +from datetime import datetime, timedelta +from flufl.enum import Enum from lazr.config import as_boolean from restish.http import Response from restish.resource import MethodDecorator @@ -69,6 +70,17 @@ class ExtendedEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, datetime): return obj.isoformat() + elif isinstance(obj, timedelta): + # as_timedelta() does not recognize microseconds, so convert these + # to floating seconds, but only if there are any seconds. + if obj.seconds > 0 or obj.microseconds > 0: + seconds = obj.seconds + obj.microseconds / 1000000.0 + return '{0}d{1}s'.format(obj.days, seconds) + return '{0}d'.format(obj.days) + elif hasattr(obj, 'enumclass') and issubclass(obj.enumclass, Enum): + # It's up to the decoding validator to associate this name with + # the right Enum class. + return obj.enumname return json.JSONEncoder.default(self, obj) diff --git a/src/mailman/rest/lists.py b/src/mailman/rest/lists.py index 464b3a717..26aabbf49 100644 --- a/src/mailman/rest/lists.py +++ b/src/mailman/rest/lists.py @@ -27,12 +27,17 @@ __all__ = [ ] -from lazr.config import as_boolean +import os +import sys + +from lazr.config import as_boolean, as_timedelta +from pkg_resources import resource_listdir from restish import http, resource from zope.component import getUtility from mailman.app.lifecycle import create_list, remove_list from mailman.config import config +from mailman.interfaces.autorespond import ResponseAction from mailman.interfaces.domain import BadDomainSpecificationError from mailman.interfaces.listmanager import ( IListManager, ListAlreadyExistsError) @@ -247,6 +252,14 @@ READABLE = ( # Notifications. 'admin_immed_notify', 'admin_notify_mchanges', + # Automatic responses. + 'autoresponse_grace_period', + 'autorespond_owner', + 'autoresponse_owner_text', + 'autorespond_postings', + 'autoresponse_postings_text', + 'autorespond_requests', + 'autoresponse_request_text', # Processing. 'pipeline', 'administrivia', @@ -263,6 +276,18 @@ def pipeline_validator(pipeline_name): raise ValueError('Unknown pipeline: {0}'.format(pipeline_name)) +class enum_validator: + """Convert an enum value name into an enum value.""" + + def __init__(self, enum_class): + self._enum_class = enum_class + + def __call__(self, enum_value): + # This will raise a ValueError if the enum value is unknown. Let that + # percolate up. + return self._enum_class[enum_value] + + VALIDATORS = { # Identity. 'real_name': unicode, @@ -275,6 +300,14 @@ VALIDATORS = { # Notifications. 'admin_immed_notify': as_boolean, 'admin_notify_mchanges': as_boolean, + # Automatic responses. + 'autoresponse_grace_period': as_timedelta, + 'autorespond_owner': enum_validator(ResponseAction), + 'autoresponse_owner_text': unicode, + 'autorespond_postings': enum_validator(ResponseAction), + 'autoresponse_postings_text': unicode, + 'autorespond_requests': enum_validator(ResponseAction), + 'autoresponse_request_text': unicode, # Processing. 'pipeline': pipeline_validator, 'administrivia': as_boolean, |
