Allow updating mailbox addresses
This commit is contained in:
parent
a0808896b4
commit
ddd8ecf634
|
@ -1,5 +1,4 @@
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
from itertools import groupby
|
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -178,6 +177,12 @@ class Orchestra(object):
|
||||||
raise Http404(_("No mailbox found matching the query"))
|
raise Http404(_("No mailbox found matching the query"))
|
||||||
return Mailbox.new_from_json(data_json)
|
return Mailbox.new_from_json(data_json)
|
||||||
|
|
||||||
|
def update_mailbox(self, pk, data):
|
||||||
|
path = API_PATHS.get('mailbox-detail').format_map({'pk': pk})
|
||||||
|
url = urllib.parse.urljoin(self.base_url, path)
|
||||||
|
status, response = self.request("PATCH", url=url, data=data, raise_exception=False)
|
||||||
|
return status, response
|
||||||
|
|
||||||
def retrieve_mailbox_list(self):
|
def retrieve_mailbox_list(self):
|
||||||
mailboxes = self.retrieve_service_list(Mailbox.api_name)
|
mailboxes = self.retrieve_service_list(Mailbox.api_name)
|
||||||
return [Mailbox.new_from_json(mailbox_data) for mailbox_data in mailboxes]
|
return [Mailbox.new_from_json(mailbox_data) for mailbox_data in mailboxes]
|
||||||
|
|
|
@ -94,3 +94,23 @@ class MailboxCreateForm(forms.Form):
|
||||||
"password": self.cleaned_data["password2"],
|
"password": self.cleaned_data["password2"],
|
||||||
}
|
}
|
||||||
return serialized_data
|
return serialized_data
|
||||||
|
|
||||||
|
|
||||||
|
class MailboxUpdateForm(forms.Form):
|
||||||
|
addresses = forms.MultipleChoiceField(required=False)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.instance = kwargs.pop('instance', None)
|
||||||
|
if self.instance is not None:
|
||||||
|
kwargs['initial'] = self.instance.deserialize()
|
||||||
|
|
||||||
|
addresses = kwargs.pop('addresses')
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.fields['addresses'].choices = [(addr.url, addr.full_address_name) for addr in addresses]
|
||||||
|
|
||||||
|
def serialize(self):
|
||||||
|
assert self.is_valid()
|
||||||
|
serialized_data = {
|
||||||
|
"addresses": self.cleaned_data["addresses"],
|
||||||
|
}
|
||||||
|
return serialized_data
|
||||||
|
|
|
@ -241,6 +241,7 @@ class Address(OrchestraModel):
|
||||||
"domain": None,
|
"domain": None,
|
||||||
"mailboxes": [],
|
"mailboxes": [],
|
||||||
"forward": None,
|
"forward": None,
|
||||||
|
'url': None,
|
||||||
}
|
}
|
||||||
|
|
||||||
FORWARD = 'forward'
|
FORWARD = 'forward'
|
||||||
|
@ -324,6 +325,12 @@ class Mailbox(OrchestraModel):
|
||||||
addresses = [Address.new_from_json(addr) for addr in data.get('addresses', [])]
|
addresses = [Address.new_from_json(addr) for addr in data.get('addresses', [])]
|
||||||
return super().new_from_json(data=data, addresses=addresses)
|
return super().new_from_json(data=data, addresses=addresses)
|
||||||
|
|
||||||
|
def deserialize(self):
|
||||||
|
data = {
|
||||||
|
'addresses': [addr.url for addr in self.addresses],
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
class MailinglistService(OrchestraModel):
|
class MailinglistService(OrchestraModel):
|
||||||
api_name = 'mailinglist'
|
api_name = 'mailinglist'
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<button type="submit" class="btn btn-secondary">{% trans "Save" %}</button>
|
<button type="submit" class="btn btn-secondary">{% trans "Save" %}</button>
|
||||||
{% if form.instance %}
|
{% if form.instance %}
|
||||||
<div class="float-right">
|
<div class="float-right">
|
||||||
<a class="btn btn-danger" href="{# TODO url 'musician:mailbox-delete' view.kwargs.pk #}">{% trans "Delete" %}</a>
|
<a class="btn btn-danger" href="{% url 'musician:mailbox-delete' view.kwargs.pk %}">{% trans "Delete" %}</a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endbuttons %}
|
{% endbuttons %}
|
||||||
|
|
|
@ -5,17 +5,15 @@
|
||||||
<div class="tab-pane fade show active" id="mailboxes" role="tabpanel" aria-labelledby="mailboxes-tab">
|
<div class="tab-pane fade show active" id="mailboxes" role="tabpanel" aria-labelledby="mailboxes-tab">
|
||||||
<table class="table service-list">
|
<table class="table service-list">
|
||||||
<colgroup>
|
<colgroup>
|
||||||
<col span="1" style="width: 20%;">
|
<col span="1" style="width: 25%;">
|
||||||
<col span="1" style="width: 10%;">
|
|
||||||
<col span="1" style="width: 60%;">
|
|
||||||
<col span="1" style="width: 10%;">
|
<col span="1" style="width: 10%;">
|
||||||
|
<col span="1" style="width: 65%;">
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<thead class="thead-dark">
|
<thead class="thead-dark">
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">{% trans "Name" %}</th>
|
<th scope="col">{% trans "Name" %}</th>
|
||||||
<th scope="col">{% trans "Filtering" %}</th>
|
<th scope="col">{% trans "Filtering" %}</th>
|
||||||
<th scope="col">{% trans "Addresses" %}</th>
|
<th scope="col">{% trans "Addresses" %}</th>
|
||||||
<th scope="col"></th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -23,19 +21,15 @@
|
||||||
{# <!-- Exclude (don't render) inactive mailboxes -->#}
|
{# <!-- Exclude (don't render) inactive mailboxes -->#}
|
||||||
{% if mailbox.is_active %}
|
{% if mailbox.is_active %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ mailbox.name }}</td>
|
<td><a href="{% url 'musician:mailbox-update' mailbox.id %}">{{ mailbox.name }}</a></td>
|
||||||
<td>{{ mailbox.filtering }}</td>
|
<td>{{ mailbox.filtering }}</td>
|
||||||
<td>
|
<td>
|
||||||
{% for addr in mailbox.addresses %}
|
{% for addr in mailbox.addresses %}
|
||||||
<a href="{% url 'musician:address-update' addr.data.id %}">
|
<a href="{% url 'musician:address-update' addr.data.id %}">
|
||||||
{{ addr.data.name }}@{{ addr.data.domain.name }}
|
{{ addr.full_address_name }}
|
||||||
</a><br/>
|
</a><br/>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
|
||||||
|
|
||||||
<a class="btn btn-outline-danger" href="{% url 'musician:mailbox-delete' mailbox.id %}" title="{% trans 'Delete' %}"><i class="fas fa-trash"></i></a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}{# <!-- /is_active --> #}
|
{% endif %}{# <!-- /is_active --> #}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -25,6 +25,7 @@ urlpatterns = [
|
||||||
path('address/<int:pk>/delete/', views.AddressDeleteView.as_view(), name='address-delete'),
|
path('address/<int:pk>/delete/', views.AddressDeleteView.as_view(), name='address-delete'),
|
||||||
path('mailboxes/', views.MailboxesView.as_view(), name='mailbox-list'),
|
path('mailboxes/', views.MailboxesView.as_view(), name='mailbox-list'),
|
||||||
path('mailboxes/new/', views.MailboxCreateView.as_view(), name='mailbox-create'),
|
path('mailboxes/new/', views.MailboxCreateView.as_view(), name='mailbox-create'),
|
||||||
|
path('mailboxes/<int:pk>/', views.MailboxUpdateView.as_view(), name='mailbox-update'),
|
||||||
path('mailboxes/<int:pk>/delete/', views.MailboxDeleteView.as_view(), name='mailbox-delete'),
|
path('mailboxes/<int:pk>/delete/', views.MailboxDeleteView.as_view(), name='mailbox-delete'),
|
||||||
path('mailing-lists/', views.MailingListsView.as_view(), name='mailing-lists'),
|
path('mailing-lists/', views.MailingListsView.as_view(), name='mailing-lists'),
|
||||||
path('databases/', views.DatabasesView.as_view(), name='database-list'),
|
path('databases/', views.DatabasesView.as_view(), name='database-list'),
|
||||||
|
|
|
@ -18,7 +18,7 @@ from requests.exceptions import HTTPError
|
||||||
from . import api, get_version
|
from . import api, get_version
|
||||||
from .auth import login as auth_login
|
from .auth import login as auth_login
|
||||||
from .auth import logout as auth_logout
|
from .auth import logout as auth_logout
|
||||||
from .forms import LoginForm, MailForm, MailboxCreateForm
|
from .forms import LoginForm, MailForm, MailboxCreateForm, MailboxUpdateForm
|
||||||
from .mixins import (CustomContextMixin, ExtendedPaginationMixin,
|
from .mixins import (CustomContextMixin, ExtendedPaginationMixin,
|
||||||
UserTokenRequiredMixin)
|
UserTokenRequiredMixin)
|
||||||
from .models import (Address, Bill, DatabaseService, Mailbox, MailinglistService,
|
from .models import (Address, Bill, DatabaseService, Mailbox, MailinglistService,
|
||||||
|
@ -356,6 +356,42 @@ class MailboxCreateView(CustomContextMixin, UserTokenRequiredMixin, FormView):
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
|
class MailboxUpdateView(CustomContextMixin, UserTokenRequiredMixin, FormView):
|
||||||
|
service_class = Mailbox
|
||||||
|
template_name = "musician/mailbox_form.html"
|
||||||
|
form_class = MailboxUpdateForm
|
||||||
|
success_url = reverse_lazy("musician:mailbox-list")
|
||||||
|
extra_context = {'service': service_class}
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super().get_form_kwargs()
|
||||||
|
instance = self.orchestra.retrieve_mailbox(self.kwargs['pk'])
|
||||||
|
|
||||||
|
kwargs.update({
|
||||||
|
'instance': instance,
|
||||||
|
'addresses': self.orchestra.retrieve_mail_address_list(),
|
||||||
|
})
|
||||||
|
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
serialized_data = form.serialize()
|
||||||
|
status, response = self.orchestra.update_mailbox(self.kwargs['pk'], serialized_data)
|
||||||
|
|
||||||
|
if status >= 400:
|
||||||
|
if status == 400:
|
||||||
|
# handle errors & add to form (they will be rendered)
|
||||||
|
form.add_error(field=None, error=response)
|
||||||
|
else:
|
||||||
|
logger.error("{}: {}".format(status, response[:120]))
|
||||||
|
msg = "Sorry, an error occurred while processing your request ({})".format(status)
|
||||||
|
form.add_error(field='__all__', error=msg)
|
||||||
|
|
||||||
|
return self.form_invalid(form)
|
||||||
|
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
class MailboxDeleteView(CustomContextMixin, UserTokenRequiredMixin, DeleteView):
|
class MailboxDeleteView(CustomContextMixin, UserTokenRequiredMixin, DeleteView):
|
||||||
template_name = "musician/mailbox_check_delete.html"
|
template_name = "musician/mailbox_check_delete.html"
|
||||||
success_url = reverse_lazy("musician:mailbox-list")
|
success_url = reverse_lazy("musician:mailbox-list")
|
||||||
|
|
Loading…
Reference in New Issue