242 lines
7.8 KiB
Python
242 lines
7.8 KiB
Python
# chrono - agendas system
|
|
# Copyright (C) 2023 Entr'ouvert
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
from django import forms
|
|
from django.contrib import messages
|
|
from django.core.cache import cache
|
|
from django.shortcuts import get_object_or_404, redirect
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django.views.generic import CreateView, DeleteView, ListView, TemplateView, UpdateView
|
|
|
|
from . import hub, models
|
|
|
|
|
|
class Homepage(ListView):
|
|
template_name = 'chrono/manager_ants_hub.html'
|
|
model = models.City
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data(**kwargs)
|
|
ok = cache.get('ants-hub-ok')
|
|
if not ok:
|
|
try:
|
|
hub.ping()
|
|
except hub.AntsHubException as e:
|
|
messages.warning(self.request, _('ANTS Hub is down: "%s".') % e)
|
|
else:
|
|
messages.info(self.request, _('ANTS Hub is responding.'))
|
|
cache.set('ants-hub-ok', True, 600)
|
|
return ctx
|
|
|
|
|
|
class CityAddView(CreateView):
|
|
template_name = 'chrono/manager_ants_hub_add_form.html'
|
|
model = models.City
|
|
name = _('New city')
|
|
fields = '__all__'
|
|
|
|
|
|
class CityMixin:
|
|
def dispatch(self, request, pk):
|
|
self.city = get_object_or_404(models.City, pk=pk)
|
|
return super().dispatch(request, pk=pk)
|
|
|
|
|
|
class CityView(CityMixin, ListView):
|
|
template_name = 'chrono/manager_ants_hub_city.html'
|
|
model = models.Place
|
|
|
|
def get_queryset(self):
|
|
return super().get_queryset().filter(city=self.city)
|
|
|
|
|
|
class CityEditView(UpdateView):
|
|
template_name = 'chrono/manager_ants_hub_add_form.html'
|
|
model = models.City
|
|
fields = '__all__'
|
|
|
|
|
|
class CityDeleteView(DeleteView):
|
|
template_name = 'chrono/manager_confirm_delete.html'
|
|
model = models.City
|
|
success_url = '../../../'
|
|
|
|
|
|
class PlaceForm(forms.ModelForm):
|
|
class Meta:
|
|
model = models.Place
|
|
exclude = ['city']
|
|
|
|
|
|
class PlaceAddView(CityMixin, CreateView):
|
|
template_name = 'chrono/manager_ants_hub_add_form.html'
|
|
model = models.Place
|
|
form_class = PlaceForm
|
|
|
|
@property
|
|
def name(self):
|
|
return _('New place in %s') % self.city
|
|
|
|
def dispatch(self, request, pk):
|
|
self.city = get_object_or_404(models.City, pk=pk)
|
|
return super().dispatch(request, pk)
|
|
|
|
def get_form_kwargs(self):
|
|
kwargs = super().get_form_kwargs()
|
|
kwargs['instance'] = models.Place(city=self.city)
|
|
return kwargs
|
|
|
|
|
|
class PlaceMixin:
|
|
def dispatch(self, request, city_pk, pk):
|
|
self.place = get_object_or_404(models.Place, pk=pk, city_id=city_pk)
|
|
self.city = self.place.city
|
|
return super().dispatch(request, pk=pk)
|
|
|
|
|
|
class PlaceView(PlaceMixin, ListView):
|
|
template_name = 'chrono/manager_ants_hub_place.html'
|
|
model = models.PlaceAgenda
|
|
|
|
def get_queryset(self):
|
|
return super().get_queryset().filter(place=self.place)
|
|
|
|
|
|
class PlaceEditForm(PlaceForm):
|
|
class Meta:
|
|
model = models.Place
|
|
fields = ['name', 'address', 'zipcode', 'city_name', 'longitude', 'latitude']
|
|
|
|
|
|
class PlaceEditView(UpdateView):
|
|
template_name = 'chrono/manager_ants_hub_place_edit_form.html'
|
|
model = models.Place
|
|
fields = ['zipcode', 'city_name', 'address', 'longitude', 'latitude']
|
|
|
|
|
|
class PlaceDeleteView(DeleteView):
|
|
template_name = 'chrono/manager_confirm_delete.html'
|
|
model = models.Place
|
|
success_url = '../../../../../'
|
|
|
|
|
|
class PlaceUrlEditView(UpdateView):
|
|
template_name = 'chrono/manager_ants_hub_add_form.html'
|
|
model = models.Place
|
|
fields = ['url', 'logo_url', 'meeting_url', 'management_url', 'cancel_url']
|
|
|
|
|
|
class PlaceAgendaAddForm(forms.ModelForm):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
# hide agendas already linked to the place
|
|
self.fields['agenda'].queryset = self.fields['agenda'].queryset.exclude(
|
|
ants_place__place=self.instance.place
|
|
)
|
|
|
|
class Meta:
|
|
model = models.PlaceAgenda
|
|
exclude = ['place', 'setting']
|
|
|
|
|
|
class PlaceAgendaAddView(PlaceMixin, CreateView):
|
|
template_name = 'chrono/manager_ants_hub_add_form.html'
|
|
model = models.PlaceAgenda
|
|
form_class = PlaceAgendaAddForm
|
|
|
|
@property
|
|
def name(self):
|
|
return _('New agenda for %s') % self.place
|
|
|
|
def get_form_kwargs(self):
|
|
kwargs = super().get_form_kwargs()
|
|
kwargs['instance'] = models.PlaceAgenda(place=self.place)
|
|
return kwargs
|
|
|
|
def get_success_url(self):
|
|
return f'../../#open-place-agenda-{self.object.pk}'
|
|
|
|
|
|
class PlaceAgendaEditForm(forms.ModelForm):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.meeting_types = self.instance.agenda.meetingtype_set.order_by('label')
|
|
for meeting_type in self.instance.agenda.iter_meetingtypes():
|
|
field_meeting_type = forms.TypedMultipleChoiceField(
|
|
label=_('%s') % meeting_type.label,
|
|
choices=models.ANTSMeetingType.choices,
|
|
widget=forms.CheckboxSelectMultiple(attrs={'class': 'inline'}),
|
|
required=False,
|
|
initial=self.instance.get_meeting_type_setting(meeting_type, 'ants_meeting_type'),
|
|
)
|
|
field_meeting_type.meeting_type = meeting_type
|
|
field_meeting_type.key = 'ants_meeting_type'
|
|
field_persons_number = forms.TypedMultipleChoiceField(
|
|
label=_('%s') % meeting_type.label,
|
|
choices=models.ANTSPersonsNumber.choices,
|
|
widget=forms.CheckboxSelectMultiple(attrs={'class': 'inline'}),
|
|
required=False,
|
|
initial=self.instance.get_meeting_type_setting(meeting_type, 'ants_persons_number'),
|
|
)
|
|
field_persons_number.meeting_type = meeting_type
|
|
field_persons_number.key = 'ants_persons_number'
|
|
self.fields[f'mt_{meeting_type.slug}_1'] = field_meeting_type
|
|
self.fields[f'mt_{meeting_type.slug}_2'] = field_persons_number
|
|
|
|
def field_by_labels(self):
|
|
d = {}
|
|
for bound_field in self:
|
|
d.setdefault(bound_field.label, []).append(bound_field)
|
|
return list(d.items())
|
|
|
|
def clean(self):
|
|
for key, field in self.fields.items():
|
|
value = self.cleaned_data.get(key, [])
|
|
self.instance.set_meeting_type_setting(field.meeting_type, field.key, value)
|
|
return self.cleaned_data
|
|
|
|
class Meta:
|
|
model = models.PlaceAgenda
|
|
fields = []
|
|
|
|
|
|
class PlaceAgendaEditView(UpdateView):
|
|
template_name = 'chrono/manager_ants_hub_agenda_edit_form.html'
|
|
model = models.PlaceAgenda
|
|
form_class = PlaceAgendaEditForm
|
|
success_url = '../../../'
|
|
|
|
|
|
class PlaceAgendaDeleteView(DeleteView):
|
|
template_name = 'chrono/manager_confirm_delete.html'
|
|
model = models.PlaceAgenda
|
|
success_url = '../../../'
|
|
|
|
|
|
class Synchronize(TemplateView):
|
|
template_name = 'chrono/manager_ants_hub_synchronize.html'
|
|
|
|
def post(self, request):
|
|
self.synchronize()
|
|
messages.info(request, _('Synchronization has been launched.'))
|
|
return redirect('chrono-manager-ants-hub')
|
|
|
|
@classmethod
|
|
def synchronize(cls):
|
|
from chrono.utils.spooler import ants_hub_city_push
|
|
|
|
ants_hub_city_push.spool()
|