Translated using Weblate (Albanian)
[mailman-postorious.git] / src / postorius / views / template.py
blobf53e38e070fde53f6864ba08e9fb1846df74373e
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2018-2023 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/>.
20 from django.conf import settings
21 from django.core.exceptions import MultipleObjectsReturned
22 from django.db import IntegrityError
23 from django.http import Http404, HttpResponse, HttpResponseBadRequest
24 from django.shortcuts import redirect
25 from django.urls import reverse
26 from django.views.decorators.http import require_safe
27 from django.views.generic import CreateView, DeleteView, ListView, UpdateView
29 from postorius.auth.mixins import DomainOwnerMixin, ListOwnerMixin
30 from postorius.forms.list_forms import TemplateUpdateForm
31 from postorius.models import Domain, EmailTemplate, List
34 def _clean_with_no_strip(field, data):
35 """Clean Django's CharField field without strip=True.
37 :param field: Instance of the Charfield.
38 :param data: The un-cleaned data from the form.
39 :returns: Cleaned data.
40 """
41 field.strip = False
42 return field.clean(data)
45 class ListContextMixin:
46 def get_context_data(self, *args, **kwargs):
47 context = super().get_context_data(*args, **kwargs)
48 context['list'] = List.objects.get_or_404(
49 fqdn_listname=self.kwargs['list_id']
51 return context
54 class ListTemplateIndexView(ListOwnerMixin, ListContextMixin, ListView):
56 model = EmailTemplate
57 template_name = 'postorius/lists/template_list.html'
59 def get_queryset(self):
60 return EmailTemplate.objects.filter(identifier=self.kwargs['list_id'])
63 class ListTemplateCreateView(ListOwnerMixin, ListContextMixin, CreateView):
65 template_name = 'postorius/lists/template_add.html'
66 model = EmailTemplate
67 fields = ['name', 'data']
69 def get_success_url(self):
70 return reverse('list_template_list', args=(self.kwargs['list_id'],))
72 def form_valid(self, form):
73 formdata = form.cleaned_data
74 formdata['data'] = _clean_with_no_strip(
75 form.fields['data'], form.data['data']
77 formdata['identifier'] = self.kwargs['list_id']
78 formdata['context'] = 'list'
79 email_template = EmailTemplate(**formdata)
80 # Try to save the model. Some of the unique constraints that we have
81 # depend on the mailing_list attribute added above. So, even though
82 # we check for form validity, the save can fail.
83 try:
84 email_template.save()
85 except IntegrityError as e:
86 form.add_error('name', str(e))
87 form.add_error(
88 'name',
89 'You already have this template set. '
90 'Use edit instead of creating a new one.',
92 return self.form_invalid(form)
93 return redirect(self.get_success_url())
96 class ListTemplateUpdateView(ListOwnerMixin, ListContextMixin, UpdateView):
98 template_name = 'postorius/lists/template_update.html'
99 model = EmailTemplate
100 form_class = TemplateUpdateForm
102 def get_success_url(self):
103 return reverse('list_template_list', args=(self.kwargs['list_id'],))
106 class ListTemplateDeleteView(ListOwnerMixin, ListContextMixin, DeleteView):
108 template_name = 'postorius/lists/template_delete.html'
109 model = EmailTemplate
111 def get_success_url(self):
112 return reverse('list_template_list', args=(self.kwargs['list_id'],))
115 class DomainContextMixin:
116 def get_context_data(self, *args, **kwargs):
117 context = super().get_context_data(*args, **kwargs)
118 context['domain'] = Domain.objects.get_or_404(
119 mail_host=self.kwargs['domain']
121 return context
124 class DomainTemplateIndexView(DomainOwnerMixin, DomainContextMixin, ListView):
126 model = EmailTemplate
127 template_name = 'postorius/domain/template_index.html'
128 header = 'Index'
130 def get_queryset(self):
131 return EmailTemplate.objects.filter(identifier=self.kwargs['domain'])
134 class DomainTemplateCreateView(
135 DomainOwnerMixin, DomainContextMixin, CreateView
138 model = EmailTemplate
139 template_name = 'postorius/domain/template_add.html'
140 fields = ['name', 'data']
141 header = 'New Template'
143 def get_success_url(self):
144 return reverse('domain_template_list', args=(self.kwargs['domain'],))
146 def form_valid(self, form):
147 formdata = form.cleaned_data
148 formdata['data'] = _clean_with_no_strip(
149 form.fields['data'], form.data['data']
151 formdata['identifier'] = self.kwargs['domain']
152 formdata['context'] = 'domain'
153 template = EmailTemplate(**formdata)
154 # Try to save the model. Some of the unique constraints that we have
155 # depend on the mailing_list attribute added above. So, even though we
156 # check for form validity, the save can fail.
157 try:
158 template.save()
159 except IntegrityError as e:
160 form.add_error('name', str(e))
161 form.add_error(
162 'name',
163 'You already have this template set.'
164 'Use edit instead of creating a new one.',
166 return self.form_invalid(form)
167 return redirect(self.get_success_url())
170 class DomainTemplateUpdateView(
171 DomainOwnerMixin, DomainContextMixin, UpdateView
174 model = EmailTemplate
175 template_name = 'postorius/domain/template_add.html'
176 form_class = TemplateUpdateForm
177 header = 'Edit Template'
179 def get_success_url(self):
180 return reverse('domain_template_list', args=(self.kwargs['domain'],))
183 class DomainTemplateDeleteView(
184 DomainOwnerMixin, DomainContextMixin, DeleteView
187 template_name = 'postorius/domain/template_delete.html'
188 model = EmailTemplate
190 def get_success_url(self):
191 return reverse('domain_template_list', args=(self.kwargs['domain'],))
194 @require_safe
195 def get_template_data(request, context, identifier, name):
196 # At this point, the request should be authenticated and it's method should
197 # be GET. We just need to find the correct template and return it's
198 # content, if it exists, return a 404 otherwise.
199 if context not in ('list', 'domain'):
200 return HttpResponseBadRequest(
201 'context should be either "list" or "domain"'
203 data = dict(name=name, identifier=identifier, context=context)
204 # Depending on the context, populate the right identifier.
205 try:
206 template = EmailTemplate.objects.get(**data)
207 except EmailTemplate.DoesNotExist:
208 raise Http404('Template is not defined.')
209 except MultipleObjectsReturned:
210 raise HttpResponseBadRequest('Multiple Templates exist')
212 content_type = 'text/plain'
213 if settings.DEFAULT_CHARSET:
214 content_type += '; charset=' + settings.DEFAULT_CHARSET
215 return HttpResponse(template.data, content_type=content_type)