Update po files
[mailman-postorious.git] / src / postorius / forms / fields.py
blobda44892beae3bb42cdd850834320f7863331ed57
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2017-2021 by the Free Software Foundation, Inc.
4 # This file is part of Postorius.
6 # Postorius is free software: you can redistribute it and/or modify it under
7 # the terms of the GNU General Public License as published by the Free
8 # Software Foundation, either version 3 of the License, or (at your option)
9 # any later version.
11 # Postorius is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 # more details.
16 # You should have received a copy of the GNU General Public License along with
17 # Postorius. If not, see <http://www.gnu.org/licenses/>.
21 from django import forms
22 from django.utils.encoding import smart_text
23 from django.utils.translation import gettext_lazy as _
25 from postorius.utils import with_empty_choice
28 DELIVERY_MODE_CHOICES = (("regular", _('Regular')),
29 ("plaintext_digests", _('Plain Text Digests')),
30 ("mime_digests", _('Mime Digests')),
31 ("summary_digests", _('Summary Digests')))
34 DELIVERY_STATUS_CHOICES = (("enabled", _('Enabled')),
35 ("by_user", _('Disabled')),
36 ("by_moderator", _('Disabled by Owner')),
37 ("by_bounces", _('Disabled by Bounces')))
39 ACTION_CHOICES = (
40 ("hold", _("Hold for moderation")),
41 ("reject", _("Reject (with notification)")),
42 ("discard", _("Discard (no notification)")),
43 ("accept", _("Accept immediately (bypass other rules)")),
44 ("defer", _("Default processing")),
48 class ListOfStringsField(forms.Field):
49 widget = forms.widgets.Textarea
51 def prepare_value(self, value):
52 if isinstance(value, list):
53 value = '\n'.join(value)
54 return value
56 def to_python(self, value):
57 "Returns a list of Unicode object."
58 if value in self.empty_values:
59 return []
60 result = []
61 for line in value.splitlines():
62 line = line.strip()
63 if not line:
64 continue
65 result.append(smart_text(line))
66 return result
69 class NullBooleanRadioSelect(forms.RadioSelect):
70 """
71 This is necessary to detect that such a field has not been changed.
72 """
74 def value_from_datadict(self, data, files, name):
75 value = data.get(name, None)
76 return {'2': True,
77 True: True,
78 'True': True,
79 '3': False,
80 'False': False,
81 False: False}.get(value, None)
84 class SelectWidget(forms.Select):
85 """
86 Subclass of Django's select widget that allows disabling options.
87 """
89 def __init__(self, *args, **kwargs):
90 self._disabled_choices = []
91 super().__init__(*args, **kwargs)
93 @property
94 def disabled_choices(self):
95 return self._disabled_choices
97 @disabled_choices.setter
98 def disabled_choices(self, other):
99 self._disabled_choices = other
101 def create_option(self, name, value, *args, **kwargs):
102 option_dict = super().create_option(name, value, *args, **kwargs)
103 if value in self.disabled_choices:
104 option_dict['attrs']['disabled'] = 'disabled'
105 return option_dict
106 return option_dict
109 class SiteModelChoiceField(forms.ModelChoiceField):
111 def label_from_instance(self, obj):
112 return "%s (%s)" % (obj.name, obj.domain)
115 class MultipleChoiceForm(forms.Form):
117 class MultipleChoiceField(forms.MultipleChoiceField):
119 def validate(self, value):
120 pass
122 choices = MultipleChoiceField(
123 widget=forms.CheckboxSelectMultiple,
126 def clean_choices(self):
127 if len(self.cleaned_data['choices']) < 1:
128 raise forms.ValidationError(_('Make at least one selection'))
129 return self.cleaned_data['choices']
132 def delivery_mode_field(default=None):
134 return forms.ChoiceField(
135 widget=forms.Select(),
136 choices=with_empty_choice(DELIVERY_MODE_CHOICES),
137 required=False,
138 initial=default,
139 label=_('Delivery mode'),
140 help_text=_(
141 'If you select digests , you\'ll get posts bundled '
142 'together (usually one per day but possibly more on busy lists), '
143 'instead of singly when they\'re sent. Your mail reader may or '
144 'may not support MIME digests. In general MIME digests are '
145 'preferred, but if you have a problem reading them, select '
146 'plain text digests. '
147 'Summary Digests are currently equivalent to Mime Digests'))
150 def delivery_status_field(choices=None, widget=None):
151 if not choices:
152 choices = with_empty_choice(DELIVERY_STATUS_CHOICES)
154 if not widget:
155 widget = SelectWidget
157 return forms.ChoiceField(
158 widget=widget(),
159 choices=choices,
160 required=False,
161 label=_('Delivery status'),
162 help_text=_(
163 'Set this option to Enabled to receive messages posted to this '
164 'mailing list. Set it to Disabled if you want to stay subscribed, '
165 'but don\'t want mail delivered to you for a while (e.g. you\'re '
166 'going on vacation). If you disable mail delivery, don\'t forget '
167 'to re-enable it when you come back; it will not be automatically '
168 're-enabled.'))
171 def moderation_action_field():
172 return forms.ChoiceField(
173 widget=forms.Select(),
174 label=_('Moderation'),
175 required=False,
176 choices=[(None, _('List default'))] + list(ACTION_CHOICES),
177 help_text=_(
178 'Default action to take when this member posts to the list. \n'
179 'List default -- follow the list\'s default member action. \n'
180 'Hold -- This holds the message for approval by the list '
181 'moderators. \n'
182 'Reject -- this automatically rejects the message by sending a '
183 'bounce notice to the post\'s author. The text of the bounce '
184 'notice can be configured by you. \n'
185 'Discard -- this simply discards the message, with no notice '
186 'sent to the post\'s author. \n'
187 'Accept -- accepts any postings without any further checks. \n'
188 'Default Processing -- run additional checks and accept '
189 'the message. \n'))